dis_rust/entity_information/
entity_state_pdu.rs1use std::any::Any;
10
11use bytes::{BytesMut, BufMut, Buf};
12use serde::{Serialize, Deserialize};
13
14use crate::common::{entity_id_record::{EntityIDRecord}, entity_type_record::{Country, EntityTypeRecord, Kind}, euler_angles_record::EulerAnglesRecord, linear_velocity_record::LinearVelocityRecord, pdu::PDU, pdu_header_record::{PDUHeaderRecord, PDUType, ProtocolFamily}, world_coordinate_record::WorldCoordinateRecord, dis_error::DISError};
15
16use super::{entity_appearance_record::EntityAppearanceRecord, dead_reckoning_parameters_record::DeadReckoningParametersRecord, entity_marking_record::EntityMarkingRecord, entity_capabilities_record::{EntityCapabilitiesRecord}};
17
18#[derive(Clone, Debug,)]
19pub struct EntityStatePDU {
21 pub pdu_header_record: PDUHeaderRecord,
22 pub entity_id_record: EntityIDRecord,
23 pub force_id_field: ForceID,
24 pub number_of_articulation_parameters_field: u8,
25 pub entity_type_record: EntityTypeRecord,
26 pub alternative_entity_type_record: EntityTypeRecord,
27 pub entity_linear_velocity_record: LinearVelocityRecord,
28 pub entity_location_record: WorldCoordinateRecord,
29 pub entity_orientation_record: EulerAnglesRecord,
30 pub entity_appearance_record: EntityAppearanceRecord,
31 pub dead_reckoning_parameters_record: DeadReckoningParametersRecord,
32 pub entity_marking_record: EntityMarkingRecord,
33 pub entity_capabilities_record: EntityCapabilitiesRecord,
34 pub articulation_parameter_record: f32 }
36
37impl EntityStatePDU {
38 pub fn default() -> Self {
41 EntityStatePDU {
42 pdu_header_record: PDUHeaderRecord::default(PDUType::EntityState, ProtocolFamily::EntityInformation, 864/8), entity_id_record: EntityIDRecord::default(2),
44 force_id_field: ForceID::Other,
45 number_of_articulation_parameters_field: 0,
46 entity_type_record: EntityTypeRecord{
47 kind_field: Kind::Munition,
48 domain_field: 1,
49 country_field: Country::Other,
50 category_field: 3,
51 subcategory_field: 0,
52 specific_field: 0,
53 extra_field: 0},
54 alternative_entity_type_record: EntityTypeRecord{
55 kind_field: Kind::Munition,
56 domain_field: 1,
57 country_field: Country::Other,
58 category_field: 0,
59 subcategory_field: 0,
60 specific_field: 0,
61 extra_field: 0},
62 entity_linear_velocity_record: LinearVelocityRecord::new(0.0, 0.0, 0.0),
63 entity_location_record: WorldCoordinateRecord::new(0.0, 0.0, 0.0),
64 entity_orientation_record: EulerAnglesRecord::new(0.0, 0.0, 0.0),
65 entity_appearance_record: EntityAppearanceRecord::default(),
66 dead_reckoning_parameters_record: DeadReckoningParametersRecord::default(),
67 entity_marking_record: EntityMarkingRecord::default("".to_string()),
68 entity_capabilities_record: EntityCapabilitiesRecord::default(),
69 articulation_parameter_record: 0.0 }
71 }
72}
73
74impl PDU for EntityStatePDU {
75 fn deserialise(mut buffer: BytesMut) -> Result<EntityStatePDU, DISError> {
77 let pdu_header = PDUHeaderRecord::decode(&mut buffer);
78 if pdu_header.pdu_type == PDUType::EntityState {
79 let entity_id = EntityIDRecord::decode(&mut buffer);
80 let force_id = ForceID::decode(&mut buffer);
81 let articulation_params = &buffer.get_u8();
82 let entity_type = EntityTypeRecord::decode(&mut buffer);
83 let alt_entity_type = EntityTypeRecord::decode(&mut buffer);
84 let linear_velocity = LinearVelocityRecord::decode(&mut buffer);
85 let world_coordinate = WorldCoordinateRecord::decode(&mut buffer);
86 let orientation = EulerAnglesRecord::decode(&mut buffer);
87 let appearance = EntityAppearanceRecord::decode(&mut buffer);
88 let dead_reckoning = DeadReckoningParametersRecord::decode(&mut buffer);
89 let entity_marking = EntityMarkingRecord::decode(&mut buffer);
90 let entity_capabilities = EntityCapabilitiesRecord::decode(&mut buffer);
91
92 return Ok(EntityStatePDU {
93 pdu_header_record: pdu_header,
94 entity_id_record: entity_id,
95 force_id_field: force_id,
96 number_of_articulation_parameters_field: *articulation_params,
97 entity_type_record: entity_type,
98 alternative_entity_type_record: alt_entity_type,
99 entity_linear_velocity_record: linear_velocity,
100 entity_location_record: world_coordinate,
101 entity_orientation_record: orientation,
102 entity_appearance_record: appearance,
103 dead_reckoning_parameters_record: dead_reckoning,
104 entity_marking_record: entity_marking,
105 entity_capabilities_record: entity_capabilities,
106 articulation_parameter_record: 0.0,
107 })
108 } else {
109 Err(DISError::InvalidDISHeader)
110 }
111 }
112
113 fn serialise(&self, buf: &mut BytesMut) {
116 self.pdu_header_record.serialize(buf);
117 self.entity_id_record.serialize(buf);
118 buf.put_u8(self.force_id_field as u8);
119 buf.put_u8(self.number_of_articulation_parameters_field as u8);
120 self.entity_type_record.serialize(buf);
121 self.alternative_entity_type_record.serialize(buf);
122 self.entity_linear_velocity_record.serialize(buf);
123 self.entity_location_record.serialize(buf);
124 self.entity_orientation_record.serialize(buf);
125 self.entity_appearance_record.serialize(buf);
126 self.dead_reckoning_parameters_record.serialize(buf);
127 self.entity_marking_record.serialize(buf);
128 self.entity_capabilities_record.serialize(buf);
129 }
130
131 fn as_any(&self) -> &dyn Any {
132 self
133 }
134
135 fn deserialise_without_header(mut buffer: BytesMut, pdu_header: PDUHeaderRecord) -> Result<Self, DISError> where Self: Sized {
136 let entity_id = EntityIDRecord::decode(&mut buffer);
137 let force_id = ForceID::decode(&mut buffer);
138 let articulation_params = &buffer.get_u8();
139 let entity_type = EntityTypeRecord::decode(&mut buffer);
140 let alt_entity_type = EntityTypeRecord::decode(&mut buffer);
141 let linear_velocity = LinearVelocityRecord::decode(&mut buffer);
142 let world_coordinate = WorldCoordinateRecord::decode(&mut buffer);
143 let orientation = EulerAnglesRecord::decode(&mut buffer);
144 let appearance = EntityAppearanceRecord::decode(&mut buffer);
145 let dead_reckoning = DeadReckoningParametersRecord::decode(&mut buffer);
146 let entity_marking = EntityMarkingRecord::decode(&mut buffer);
147 let entity_capabilities = EntityCapabilitiesRecord::decode(&mut buffer);
148
149 return Ok(EntityStatePDU {
150 pdu_header_record: pdu_header,
151 entity_id_record: entity_id,
152 force_id_field: force_id,
153 number_of_articulation_parameters_field: *articulation_params,
154 entity_type_record: entity_type,
155 alternative_entity_type_record: alt_entity_type,
156 entity_linear_velocity_record: linear_velocity,
157 entity_location_record: world_coordinate,
158 entity_orientation_record: orientation,
159 entity_appearance_record: appearance,
160 dead_reckoning_parameters_record: dead_reckoning,
161 entity_marking_record: entity_marking,
162 entity_capabilities_record: entity_capabilities,
163 articulation_parameter_record: 0.0,
164 })
165 }
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
169pub enum ForceID {
171 Other = 0,
172 Friendly = 1,
173 Opposing = 2,
174 Neutral = 3
175}
176
177impl ForceID {
178 pub fn decode(buf: &mut BytesMut) -> ForceID {
179 match buf.get_u8() {
180 1 => ForceID::Friendly,
181 2 => ForceID::Opposing,
182 3 => ForceID::Neutral,
183 _ => ForceID::Other,
184 }
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 use bytes::BytesMut;
191
192 use crate::{common::{pdu_header_record::{PDUHeaderRecord, PDUType, ProtocolFamily}, pdu::PDU}, entity_information::entity_state_pdu::EntityStatePDU};
193
194 #[test]
195 fn header_creation() {
196 let entity_state_pdu = EntityStatePDU::default();
197 let header = PDUHeaderRecord::default(PDUType::EntityState, ProtocolFamily::EntityInformation, 864/8);
198 assert_eq!(header.protocol_version, entity_state_pdu.pdu_header_record.protocol_version);
199 assert_eq!(header.exercise_id, entity_state_pdu.pdu_header_record.exercise_id);
200 assert_eq!(header.pdu_type, entity_state_pdu.pdu_header_record.pdu_type);
201 assert_eq!(header.protocol_family, entity_state_pdu.pdu_header_record.protocol_family);
202 assert_eq!(header.timestamp, entity_state_pdu.pdu_header_record.timestamp);
203 assert_eq!(header.length, entity_state_pdu.pdu_header_record.length);
204 assert_eq!(header.padding, entity_state_pdu .pdu_header_record.padding);
205 }
206
207 #[test]
208 fn header_deserialise() {
209 let entity_state_pdu = EntityStatePDU::default();
210 let mut buffer = BytesMut::new();
211 entity_state_pdu.serialise(&mut buffer);
212
213 let new_entity_state_pdu = EntityStatePDU::deserialise(buffer).unwrap();
214 assert_eq!(new_entity_state_pdu.pdu_header_record, entity_state_pdu.pdu_header_record);
215 }
216}