1use std::io::{Cursor, Error};
7
8use bytes::{Buf, BytesMut};
9
10use crate::nineteen::header::decode_header;
11use crate::packet::ensure_packet_size;
12use crate::packet::motion::{Motion, MotionPacket};
13use crate::types::{CornerProperty, Property3D};
14
15pub const PACKET_SIZE: usize = 1343;
17
18pub fn decode_motion(cursor: &mut Cursor<&mut BytesMut>) -> Result<MotionPacket, Error> {
23 ensure_packet_size(PACKET_SIZE, cursor)?;
24
25 let header = decode_header(cursor)?;
26 let mut cars = Vec::with_capacity(20);
27
28 for _ in 0..20 {
29 cars.push(Motion::new(
30 decode_position(cursor),
31 decode_velocity(cursor),
32 decode_forward_direction(cursor),
33 decode_right_direction(cursor),
34 decode_g_force(cursor),
35 cursor.get_f32_le(),
36 cursor.get_f32_le(),
37 cursor.get_f32_le(),
38 ))
39 }
40
41 Ok(MotionPacket::new(
42 header,
43 cars,
44 decode_suspension_position(cursor),
45 decode_suspension_velocity(cursor),
46 decode_suspension_acceleration(cursor),
47 decode_wheel_speed(cursor),
48 decode_wheel_slip(cursor),
49 decode_local_velocity(cursor),
50 decode_angular_velocity(cursor),
51 decode_angular_acceleration(cursor),
52 cursor.get_f32_le(),
53 ))
54}
55
56fn decode_position(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
58 Property3D::new(
59 cursor.get_f32_le(),
60 cursor.get_f32_le(),
61 cursor.get_f32_le(),
62 )
63}
64
65fn decode_velocity(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
67 Property3D::new(
68 cursor.get_f32_le(),
69 cursor.get_f32_le(),
70 cursor.get_f32_le(),
71 )
72}
73
74fn decode_forward_direction(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<i16> {
76 Property3D::new(
77 cursor.get_i16_le(),
78 cursor.get_i16_le(),
79 cursor.get_i16_le(),
80 )
81}
82
83fn decode_right_direction(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<i16> {
85 Property3D::new(
86 cursor.get_i16_le(),
87 cursor.get_i16_le(),
88 cursor.get_i16_le(),
89 )
90}
91
92fn decode_g_force(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
94 Property3D::new(
95 cursor.get_f32_le(),
96 cursor.get_f32_le(),
97 cursor.get_f32_le(),
98 )
99}
100
101fn decode_suspension_position(cursor: &mut Cursor<&mut BytesMut>) -> CornerProperty<f32> {
103 CornerProperty::new(
104 cursor.get_f32_le(),
105 cursor.get_f32_le(),
106 cursor.get_f32_le(),
107 cursor.get_f32_le(),
108 )
109}
110
111fn decode_suspension_velocity(cursor: &mut Cursor<&mut BytesMut>) -> CornerProperty<f32> {
113 CornerProperty::new(
114 cursor.get_f32_le(),
115 cursor.get_f32_le(),
116 cursor.get_f32_le(),
117 cursor.get_f32_le(),
118 )
119}
120
121fn decode_suspension_acceleration(cursor: &mut Cursor<&mut BytesMut>) -> CornerProperty<f32> {
123 CornerProperty::new(
124 cursor.get_f32_le(),
125 cursor.get_f32_le(),
126 cursor.get_f32_le(),
127 cursor.get_f32_le(),
128 )
129}
130
131fn decode_wheel_speed(cursor: &mut Cursor<&mut BytesMut>) -> CornerProperty<f32> {
133 CornerProperty::new(
134 cursor.get_f32_le(),
135 cursor.get_f32_le(),
136 cursor.get_f32_le(),
137 cursor.get_f32_le(),
138 )
139}
140
141fn decode_wheel_slip(cursor: &mut Cursor<&mut BytesMut>) -> CornerProperty<f32> {
143 CornerProperty::new(
144 cursor.get_f32_le(),
145 cursor.get_f32_le(),
146 cursor.get_f32_le(),
147 cursor.get_f32_le(),
148 )
149}
150
151fn decode_local_velocity(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
153 Property3D::new(
154 cursor.get_f32_le(),
155 cursor.get_f32_le(),
156 cursor.get_f32_le(),
157 )
158}
159
160fn decode_angular_velocity(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
162 Property3D::new(
163 cursor.get_f32_le(),
164 cursor.get_f32_le(),
165 cursor.get_f32_le(),
166 )
167}
168fn decode_angular_acceleration(cursor: &mut Cursor<&mut BytesMut>) -> Property3D<f32> {
170 Property3D::new(
171 cursor.get_f32_le(),
172 cursor.get_f32_le(),
173 cursor.get_f32_le(),
174 )
175}
176
177#[cfg(test)]
178mod tests {
179 use std::io::Cursor;
180
181 use assert_approx_eq::assert_approx_eq;
182 use bytes::{BufMut, BytesMut};
183
184 use crate::nineteen::motion::{decode_motion, PACKET_SIZE};
185
186 fn put_packet_header(mut bytes: BytesMut) -> BytesMut {
187 bytes.put_u16_le(2019);
188 bytes.put_u8(1);
189 bytes.put_u8(2);
190 bytes.put_u8(3);
191 bytes.put_u8(0);
192 bytes.put_u64_le(u64::max_value());
193 bytes.put_f32_le(1.0);
194 bytes.put_u32_le(u32::max_value());
195 bytes.put_u8(0);
196
197 bytes
198 }
199
200 #[test]
201 fn decode_motion_with_error() {
202 let mut bytes = BytesMut::with_capacity(0);
203 let mut cursor = Cursor::new(&mut bytes);
204
205 let packet = decode_motion(&mut cursor);
206 assert!(packet.is_err());
207 }
208
209 #[test]
210 fn decode_motion_with_success() {
211 let mut bytes = BytesMut::with_capacity(PACKET_SIZE);
212 bytes = put_packet_header(bytes);
213
214 bytes.put_f32_le(1.0);
215 bytes.put_f32_le(2.0);
216 bytes.put_f32_le(3.0);
217 bytes.put_f32_le(4.0);
218 bytes.put_f32_le(5.0);
219 bytes.put_f32_le(6.0);
220 bytes.put_i16_le(7);
221 bytes.put_i16_le(8);
222 bytes.put_i16_le(9);
223 bytes.put_i16_le(10);
224 bytes.put_i16_le(11);
225 bytes.put_i16_le(12);
226 bytes.put_f32_le(13.0);
227 bytes.put_f32_le(14.0);
228 bytes.put_f32_le(15.0);
229 bytes.put_f32_le(16.0);
230 bytes.put_f32_le(17.0);
231 bytes.put_f32_le(18.0);
232
233 let padding = vec![0u8; 1140];
234 bytes.put(padding.as_slice());
235
236 bytes.put_f32_le(19.0);
237 bytes.put_f32_le(20.0);
238 bytes.put_f32_le(21.0);
239 bytes.put_f32_le(22.0);
240 bytes.put_f32_le(23.0);
241 bytes.put_f32_le(24.0);
242 bytes.put_f32_le(25.0);
243 bytes.put_f32_le(26.0);
244 bytes.put_f32_le(27.0);
245 bytes.put_f32_le(28.0);
246 bytes.put_f32_le(29.0);
247 bytes.put_f32_le(30.0);
248 bytes.put_f32_le(31.0);
249 bytes.put_f32_le(32.0);
250 bytes.put_f32_le(33.0);
251 bytes.put_f32_le(34.0);
252 bytes.put_f32_le(35.0);
253 bytes.put_f32_le(36.0);
254 bytes.put_f32_le(37.0);
255 bytes.put_f32_le(38.0);
256 bytes.put_f32_le(39.0);
257 bytes.put_f32_le(40.0);
258 bytes.put_f32_le(41.0);
259 bytes.put_f32_le(42.0);
260 bytes.put_f32_le(43.0);
261 bytes.put_f32_le(44.0);
262 bytes.put_f32_le(45.0);
263 bytes.put_f32_le(46.0);
264 bytes.put_f32_le(47.0);
265 bytes.put_f32_le(48.0);
266
267 let mut cursor = Cursor::new(&mut bytes);
268 let packet = decode_motion(&mut cursor).unwrap();
269
270 let motion = packet.cars()[0];
271 assert_approx_eq!(1.0, motion.position().x());
272 assert_approx_eq!(4.0, motion.velocity().x());
273 assert_eq!(7, motion.forward_direction().x());
274 assert_eq!(10, motion.right_direction().x());
275 assert_approx_eq!(13.0, motion.g_force().x());
276 assert_approx_eq!(16.0, motion.yaw());
277 assert_approx_eq!(17.0, motion.pitch());
278 assert_approx_eq!(18.0, motion.roll());
279 assert_approx_eq!(19.0, packet.suspension_position().front_left());
280 assert_approx_eq!(23.0, packet.suspension_velocity().front_left());
281 assert_approx_eq!(27.0, packet.suspension_acceleration().front_left());
282 assert_approx_eq!(31.0, packet.wheel_speed().front_left());
283 assert_approx_eq!(35.0, packet.wheel_slip().front_left());
284 assert_approx_eq!(39.0, packet.local_velocity().x());
285 assert_approx_eq!(42.0, packet.angular_velocity().x());
286 assert_approx_eq!(45.0, packet.angular_acceleration().x());
287 assert_approx_eq!(48.0, packet.front_wheels_angle());
288 }
289}