Earlier Work Link to heading
This is a new version of the C++ datalogger available in EASports WRC C++ datalogger, but now built in rust 🦀
Why did I do it Link to heading
I created this app because I will be working in a newer version of the sim rally shifter and required an interface that can receive the UDP packet from the network and handle it. Also I wanted to do it in rust. The only thing that this application should do at the moment is to receive the UDP packet and break it into a struct with the data split into different variables.
Code Walkthrough Link to heading
Theres nothing much to it, in the main
function we initialize the UDP packet and read it continuously.
The function parse_packet
parses the entire packet and writes into the struct elements.
Inside parse_packet
there are some anonymous functions to convert the buffer into normal variable types.
Here is the entire code, also available in Github:
1use core::str;
2use std::net::UdpSocket;
3use std::io;
4
5#[warn(dead_code)]
6#[derive(Debug)]
7struct TelemetryData {
8 packet_4cc: u32,
9 packet_uid: u64,
10 shiftlights_fraction: f32,
11 shiftlights_rpm_start: f32,
12 shiftlights_rpm_end: f32,
13 shiftlights_rpm_valid: bool,
14 vehicle_gear_index: u8,
15 vehicle_gear_index_neutral: u8,
16 vehicle_gear_index_reverse: u8,
17 vehicle_gear_maximum: u8,
18 vehicle_speed: f32,
19 vehicle_transmission_speed: f32,
20 vehicle_position_x: f32,
21 vehicle_position_y: f32,
22 vehicle_position_z: f32,
23 vehicle_velocity_x: f32,
24 vehicle_velocity_y: f32,
25 vehicle_velocity_z: f32,
26 vehicle_acceleration_x: f32,
27 vehicle_acceleration_y: f32,
28 vehicle_acceleration_z: f32,
29 vehicle_left_direction_x: f32,
30 vehicle_left_direction_y: f32,
31 vehicle_left_direction_z: f32,
32 vehicle_forward_direction_x: f32,
33 vehicle_forward_direction_y: f32,
34 vehicle_forward_direction_z: f32,
35 vehicle_up_direction_x: f32,
36 vehicle_up_direction_y: f32,
37 vehicle_up_direction_z: f32,
38 vehicle_hub_position_bl: f32,
39 vehicle_hub_position_br: f32,
40 vehicle_hub_position_fl: f32,
41 vehicle_hub_position_fr: f32,
42 vehicle_hub_velocity_bl: f32,
43 vehicle_hub_velocity_br: f32,
44 vehicle_hub_velocity_fl: f32,
45 vehicle_hub_velocity_fr: f32,
46 vehicle_cp_forward_speed_bl: f32,
47 vehicle_cp_forward_speed_br: f32,
48 vehicle_cp_forward_speed_fl: f32,
49 vehicle_cp_forward_speed_fr: f32,
50 vehicle_brake_temperature_bl: f32,
51 vehicle_brake_temperature_br: f32,
52 vehicle_brake_temperature_fl: f32,
53 vehicle_brake_temperature_fr: f32,
54 vehicle_engine_rpm_max: f32,
55 vehicle_engine_rpm_idle: f32,
56 vehicle_engine_rpm_current: f32,
57 vehicle_throttle: f32,
58 vehicle_brake: f32,
59 vehicle_clutch: f32,
60 vehicle_steering: f32,
61 vehicle_handbrake: bool,
62 game_total_time: f32,
63 game_delta_time: f32,
64 game_frame_count: u32,
65 stage_current_time: f32,
66 stage_current_distance: f32,
67 stage_length: f32,
68}
69
70fn main() -> io::Result<()>{
71 let mut addr = String::new();
72 println!("Please input the IP and the port");
73 io::stdin().read_line(&mut addr)?;
74
75 addr.pop(); //pop out \n
76 addr.pop(); //pop out \r
77
78 let socket = UdpSocket::bind(addr.clone()).expect("cannot bind to address");
79 println!("Listening on socket {}",addr);
80
81 let mut buf = [0u8;1024];
82
83 loop {
84 match socket.recv_from(&mut buf) {
85 Ok((size,src)) => {
86 //println!("Received {} bytes from {}",size,src);
87 if let Ok(packet) = parse_packet(&buf[..size]) {
88 println!("Id: {:?}", packet.packet_uid);
89 println!("Gear Index: {:?}", packet.vehicle_gear_index);
90 } else {
91 println!("Failed to parse the packet");
92 }
93 }
94 Err(e) => {
95 eprintln!("Error receiving data: {}",e);
96 }
97 }
98 }
99
100}
101
102
103fn parse_packet(buffer: &[u8]) -> Result<TelemetryData, &'static str> {
104 let mut offset = 0;
105
106 let read_u32 = |buf: &[u8]| -> Result<u32,&'static str>{
107 buf.try_into()
108 .map(u32::from_le_bytes)
109 .map_err(|_| "Invalid u32")
110 };
111 let read_u64 = |buf: &[u8]| -> Result<u64, &'static str> {
112 buf.try_into()
113 .map(u64::from_le_bytes)
114 .map_err(|_| "Invalid u64")
115 };
116 let read_f32 = |buf: &[u8]| -> Result<f32, &'static str> {
117 buf.try_into()
118 .map(f32::from_le_bytes)
119 .map_err(|_| "Invalid f32")
120 };
121 let read_bool = |buf: &[u8]| -> Result<bool, &'static str> { Ok(buf[0] != 0) };
122 let read_u8 = |buf: &[u8]| -> Result<u8, &'static str> { Ok(buf[0]) };
123
124 if buffer.len() < 4 {
125 return Err("Buffer too small");
126 }
127 //TODO:: Fix offsets
128 let packet_4cc = read_u32(&buffer[offset..offset + 4])?;
129 offset += 4;
130 let packet_uid= read_u64(&buffer[offset..offset + 8])?;
131 offset += 8;
132 let shiftlights_fraction= read_f32(&buffer[offset..offset + 4])?;
133 offset += 4;
134 let shiftlights_rpm_start= read_f32(&buffer[offset..offset + 4])?;
135 offset += 4;
136 let shiftlights_rpm_end= read_f32(&buffer[offset..offset + 4])?;
137 offset += 4;
138 let shiftlights_rpm_valid= read_bool(&buffer[offset..offset + 1])?;
139 offset += 1;
140 let vehicle_gear_index= read_u8(&buffer[offset..offset + 1])?;
141 offset += 1;
142 let vehicle_gear_index_neutral= read_u8(&buffer[offset..offset + 1])?;
143 offset += 1;
144 let vehicle_gear_index_reverse= read_u8(&buffer[offset..offset + 1])?;
145 offset += 1;
146 let vehicle_gear_maximum= read_u8(&buffer[offset..offset + 1])?;
147 offset += 1;
148 let vehicle_speed= read_f32(&buffer[offset..offset + 4])?;
149 offset += 4;
150 let vehicle_transmission_speed= read_f32(&buffer[offset..offset + 4])?;
151 offset += 4;
152 let vehicle_position_x= read_f32(&buffer[offset..offset + 4])?;
153 offset += 4;
154 let vehicle_position_y= read_f32(&buffer[offset..offset + 4])?;
155 offset += 4;
156 let vehicle_position_z= read_f32(&buffer[offset..offset + 4])?;
157 offset += 4;
158 let vehicle_velocity_x= read_f32(&buffer[offset..offset + 4])?;
159 offset += 4;
160 let vehicle_velocity_y= read_f32(&buffer[offset..offset + 4])?;
161 offset += 4;
162 let vehicle_velocity_z= read_f32(&buffer[offset..offset + 4])?;
163 offset += 4;
164 let vehicle_acceleration_x= read_f32(&buffer[offset..offset + 4])?;
165 offset += 4;
166 let vehicle_acceleration_y= read_f32(&buffer[offset..offset + 4])?;
167 offset += 4;
168 let vehicle_acceleration_z= read_f32(&buffer[offset..offset + 4])?;
169 offset += 4;
170 let vehicle_left_direction_x= read_f32(&buffer[offset..offset + 4])?;
171 offset += 4;
172 let vehicle_left_direction_y= read_f32(&buffer[offset..offset + 4])?;
173 offset += 4;
174 let vehicle_left_direction_z= read_f32(&buffer[offset..offset + 4])?;
175 offset += 4;
176 let vehicle_forward_direction_x= read_f32(&buffer[offset..offset + 4])?;
177 offset += 4;
178 let vehicle_forward_direction_y= read_f32(&buffer[offset..offset + 4])?;
179 offset += 4;
180 let vehicle_forward_direction_z= read_f32(&buffer[offset..offset + 4])?;
181 offset += 4;
182 let vehicle_up_direction_x= read_f32(&buffer[offset..offset + 4])?;
183 offset += 4;
184 let vehicle_up_direction_y= read_f32(&buffer[offset..offset + 4])?;
185 offset += 4;
186 let vehicle_up_direction_z= read_f32(&buffer[offset..offset + 4])?;
187 offset += 4;
188 let vehicle_hub_position_bl= read_f32(&buffer[offset..offset + 4])?;
189 offset += 4;
190 let vehicle_hub_position_br= read_f32(&buffer[offset..offset + 4])?;
191 offset += 4;
192 let vehicle_hub_position_fl= read_f32(&buffer[offset..offset + 4])?;
193 offset += 4;
194 let vehicle_hub_position_fr= read_f32(&buffer[offset..offset + 4])?;
195 offset += 4;
196 let vehicle_hub_velocity_bl= read_f32(&buffer[offset..offset + 4])?;
197 offset += 4;
198 let vehicle_hub_velocity_br= read_f32(&buffer[offset..offset + 4])?;
199 offset += 4;
200 let vehicle_hub_velocity_fl= read_f32(&buffer[offset..offset + 4])?;
201 offset += 4;
202 let vehicle_hub_velocity_fr= read_f32(&buffer[offset..offset + 4])?;
203 offset += 4;
204 let vehicle_cp_forward_speed_bl= read_f32(&buffer[offset..offset + 4])?;
205 offset += 4;
206 let vehicle_cp_forward_speed_br= read_f32(&buffer[offset..offset + 4])?;
207 offset += 4;
208 let vehicle_cp_forward_speed_fl= read_f32(&buffer[offset..offset + 4])?;
209 offset += 4;
210 let vehicle_cp_forward_speed_fr= read_f32(&buffer[offset..offset + 4])?;
211 offset += 4;
212 let vehicle_brake_temperature_bl= read_f32(&buffer[offset..offset + 4])?;
213 offset += 4;
214 let vehicle_brake_temperature_br= read_f32(&buffer[offset..offset + 4])?;
215 offset += 4;
216 let vehicle_brake_temperature_fl= read_f32(&buffer[offset..offset + 4])?;
217 offset += 4;
218 let vehicle_brake_temperature_fr= read_f32(&buffer[offset..offset + 4])?;
219 offset += 4;
220 let vehicle_engine_rpm_max= read_f32(&buffer[offset..offset + 4])?;
221 offset += 4;
222 let vehicle_engine_rpm_idle= read_f32(&buffer[offset..offset + 4])?;
223 offset += 4;
224 let vehicle_engine_rpm_current= read_f32(&buffer[offset..offset + 4])?;
225 offset += 4;
226 let vehicle_throttle= read_f32(&buffer[offset..offset + 4])?;
227 offset += 4;
228 let vehicle_brake= read_f32(&buffer[offset..offset + 4])?;
229 offset += 4;
230 let vehicle_clutch= read_f32(&buffer[offset..offset + 4])?;
231 offset += 4;
232 let vehicle_steering= read_f32(&buffer[offset..offset + 4])?;
233 offset += 4;
234 let vehicle_handbrake= read_bool(&buffer[offset..offset + 1])?;
235 offset += 1;
236 let game_total_time= read_f32(&buffer[offset..offset + 4])?;
237 offset += 4;
238 let game_delta_time= read_f32(&buffer[offset..offset + 4])?;
239 offset += 4;
240 let game_frame_count= read_u32(&buffer[offset..offset + 4])?;
241 offset += 4;
242 let stage_current_time= read_f32(&buffer[offset..offset + 4])?;
243 offset += 4;
244 let stage_current_distance= read_f32(&buffer[offset..offset + 4])?;
245 offset += 4;
246 let stage_length= read_f32(&buffer[offset..offset + 4])?;
247
248
249 let packet = TelemetryData {
250 packet_4cc,
251 packet_uid,
252 shiftlights_fraction,
253 shiftlights_rpm_start,
254 shiftlights_rpm_end,
255 shiftlights_rpm_valid,
256 vehicle_gear_index,
257 vehicle_gear_index_neutral,
258 vehicle_gear_index_reverse,
259 vehicle_gear_maximum,
260 vehicle_speed,
261 vehicle_transmission_speed,
262 vehicle_position_x,
263 vehicle_position_y,
264 vehicle_position_z,
265 vehicle_velocity_x,
266 vehicle_velocity_y,
267 vehicle_velocity_z,
268 vehicle_acceleration_x,
269 vehicle_acceleration_y,
270 vehicle_acceleration_z,
271 vehicle_left_direction_x,
272 vehicle_left_direction_y,
273 vehicle_left_direction_z,
274 vehicle_forward_direction_x,
275 vehicle_forward_direction_y,
276 vehicle_forward_direction_z,
277 vehicle_up_direction_x,
278 vehicle_up_direction_y,
279 vehicle_up_direction_z,
280 vehicle_hub_position_bl,
281 vehicle_hub_position_br,
282 vehicle_hub_position_fl,
283 vehicle_hub_position_fr,
284 vehicle_hub_velocity_bl,
285 vehicle_hub_velocity_br,
286 vehicle_hub_velocity_fl,
287 vehicle_hub_velocity_fr,
288 vehicle_cp_forward_speed_bl,
289 vehicle_cp_forward_speed_br,
290 vehicle_cp_forward_speed_fl,
291 vehicle_cp_forward_speed_fr,
292 vehicle_brake_temperature_bl,
293 vehicle_brake_temperature_br,
294 vehicle_brake_temperature_fl,
295 vehicle_brake_temperature_fr,
296 vehicle_engine_rpm_max,
297 vehicle_engine_rpm_idle,
298 vehicle_engine_rpm_current,
299 vehicle_throttle,
300 vehicle_brake,
301 vehicle_clutch,
302 vehicle_steering,
303 vehicle_handbrake,
304 game_total_time,
305 game_delta_time,
306 game_frame_count,
307 stage_current_time,
308 stage_current_distance,
309 stage_length,
310 };
311
312 Ok(packet)
313
314}
If you like my projects please consider supporting my hobby by buying me a coffee☕ 😄