1use crate::{TelemetryEvent, TelemetryPacket};
2use std::error::Error;
3
4use byteorder::{ByteOrder, LittleEndian};
5
6pub struct DirtRally2 {
9 pub car: Car,
10 pub session: Session,
11 pub motion: Motion,
12}
13
14impl TelemetryEvent for DirtRally2 {
15 fn from_packet(packet: &TelemetryPacket) -> Result<DirtRally2, Box<dyn Error>> {
16 if packet.len() < 256 {
17 return Err(Box::from("Packet size is less than 256 bytes, please set extradata=3 on hardware_settings_config.xml"));
18 }
19 Ok(DirtRally2 {
20 car: Car::from_packet(&packet)?,
21 session: Session::from_packet(&packet)?,
22 motion: Motion::from_packet(&packet)?,
23 })
24 }
25}
26
27pub struct Session {
28 pub position: f32,
29 pub location: Coordinate,
30 pub track: Track,
31 pub lap_info: Lap,
32}
33
34pub struct Car {
35 pub speed: f32,
36 pub gear: Gear,
37 pub wheels: (Wheel, Wheel, Wheel, Wheel), pub throttle: f32,
39 pub steer: f32,
40 pub brake: f32,
41 pub clutch: f32,
42 pub rpms: f32,
43}
44
45#[derive(Debug)]
46pub enum Gear {
47 Reverse,
48 Neutral,
49 First,
50 Second,
51 Third,
52 Fourth,
53 Fifth,
54 Sixth,
55 Seventh,
56 Eigth,
57 Ninth,
58}
59
60pub struct Motion {
61 pub velocity: Coordinate,
62 pub roll_vector: Coordinate,
63 pub pitch_vector: Coordinate,
64 pub g_force_lateral: f32,
65 pub g_force_longitudinal: f32,
66}
67
68pub struct Wheel {
69 pub suspension_position: f32,
70 pub suspension_velocity: f32,
71 pub wheel_velocity: f32,
72 pub brake_temperature: f32,
73}
74
75pub struct Track {
76 pub time: f32,
77 pub distance: f32,
78 pub length: f32,
79}
80
81pub struct Lap {
82 pub current_lap: f32,
83 pub total_laps: f32,
84 pub last_lap_time: f32,
85 pub current_lap_time: f32,
86 pub current_lap_distance: f32,
87}
88
89type Coordinate = (f32, f32, f32); impl Car {
92 fn from_packet(packet: &TelemetryPacket) -> Result<Car, Box<dyn Error>> {
93 Ok(Car {
94 speed: LittleEndian::read_f32(&packet[28..32]),
95 throttle: LittleEndian::read_f32(&packet[116..120]),
96 steer: LittleEndian::read_f32(&packet[120..124]),
97 brake: LittleEndian::read_f32(&packet[124..128]),
98 clutch: LittleEndian::read_f32(&packet[128..132]),
99 rpms: LittleEndian::read_f32(&packet[148..152]),
100 gear: Gear::from_f32(LittleEndian::read_f32(&packet[132..136]))?,
101 wheels: (
102 Wheel {
103 suspension_position: LittleEndian::read_f32(&packet[68..72]),
105 suspension_velocity: LittleEndian::read_f32(&packet[84..88]),
106 wheel_velocity: LittleEndian::read_f32(&packet[100..104]),
107 brake_temperature: LittleEndian::read_f32(&packet[204..208]),
108 },
109 Wheel {
110 suspension_position: LittleEndian::read_f32(&packet[72..76]),
112 suspension_velocity: LittleEndian::read_f32(&packet[88..92]),
113 wheel_velocity: LittleEndian::read_f32(&packet[104..108]),
114 brake_temperature: LittleEndian::read_f32(&packet[208..212]),
115 },
116 Wheel {
117 suspension_position: LittleEndian::read_f32(&packet[76..80]),
119 suspension_velocity: LittleEndian::read_f32(&packet[92..96]),
120 wheel_velocity: LittleEndian::read_f32(&packet[108..112]),
121 brake_temperature: LittleEndian::read_f32(&packet[212..216]),
122 },
123 Wheel {
124 suspension_position: LittleEndian::read_f32(&packet[80..84]),
126 suspension_velocity: LittleEndian::read_f32(&packet[96..100]),
127 wheel_velocity: LittleEndian::read_f32(&packet[112..116]),
128 brake_temperature: LittleEndian::read_f32(&packet[216..220]),
129 },
130 ),
131 })
132 }
133}
134
135impl Session {
136 fn from_packet(packet: &TelemetryPacket) -> Result<Session, Box<dyn Error>> {
137 Ok(Session {
138 location: (
139 LittleEndian::read_f32(&packet[16..20]),
140 LittleEndian::read_f32(&packet[20..24]),
141 LittleEndian::read_f32(&packet[24..28]),
142 ),
143 position: LittleEndian::read_f32(&packet[156..160]),
144 track: Track::from_packet(&packet)?,
145 lap_info: Lap::from_packet(&packet)?,
146 })
147 }
148}
149
150impl Motion {
151 fn from_packet(packet: &TelemetryPacket) -> Result<Motion, Box<dyn Error>> {
152 Ok(Motion {
153 g_force_lateral: LittleEndian::read_f32(&packet[136..140]),
154 g_force_longitudinal: LittleEndian::read_f32(&packet[140..144]),
155 pitch_vector: (
156 LittleEndian::read_f32(&packet[56..60]),
157 LittleEndian::read_f32(&packet[60..64]),
158 LittleEndian::read_f32(&packet[64..68]),
159 ),
160 roll_vector: (
161 LittleEndian::read_f32(&packet[44..48]),
162 LittleEndian::read_f32(&packet[48..52]),
163 LittleEndian::read_f32(&packet[52..56]),
164 ),
165 velocity: (
166 LittleEndian::read_f32(&packet[32..36]),
167 LittleEndian::read_f32(&packet[36..40]),
168 LittleEndian::read_f32(&packet[40..44]),
169 ),
170 })
171 }
172}
173
174impl Lap {
175 fn from_packet(packet: &TelemetryPacket) -> Result<Lap, Box<dyn Error>> {
176 Ok(Lap {
177 current_lap_time: LittleEndian::read_f32(&packet[4..8]),
178 current_lap_distance: LittleEndian::read_f32(&packet[8..12]),
179 current_lap: LittleEndian::read_f32(&packet[144..148]),
180 total_laps: LittleEndian::read_f32(&packet[240..244]),
181 last_lap_time: LittleEndian::read_f32(&packet[248..252]),
182 })
183 }
184}
185
186impl Track {
187 fn from_packet(packet: &TelemetryPacket) -> Result<Track, Box<dyn Error>> {
188 Ok(Track {
189 distance: LittleEndian::read_f32(&packet[12..16]),
190 time: LittleEndian::read_f32(&packet[0..4]),
191 length: LittleEndian::read_f32(&packet[244..248]),
192 })
193 }
194}
195
196impl Gear {
197 fn from_f32(f: f32) -> Result<Gear, Box<dyn Error>> {
198 if f < 0.0 {
199 return Ok(Gear::Reverse);
200 }
201
202 if f >= 0.0 && f < 1.0 {
203 return Ok(Gear::Neutral);
204 }
205
206 if f >= 1.0 && f < 2.0 {
207 return Ok(Gear::First);
208 }
209
210 if f >= 2.0 && f < 3.0 {
211 return Ok(Gear::Second);
212 }
213
214 if f >= 3.0 && f < 4.0 {
215 return Ok(Gear::Third);
216 }
217
218 if f >= 4.0 && f < 5.0 {
219 return Ok(Gear::Fourth);
220 }
221
222 if f >= 5.0 && f < 6.0 {
223 return Ok(Gear::Fifth);
224 }
225
226 if f >= 6.0 && f < 7.0 {
227 return Ok(Gear::Sixth);
228 }
229
230 if f >= 7.0 && f < 8.0 {
231 return Ok(Gear::Seventh);
232 }
233
234 if f >= 8.0 && f < 9.0 {
235 return Ok(Gear::Eigth);
236 }
237
238 if f >= 9.0 {
239 return Ok(Gear::Ninth);
240 }
241
242 Err(Box::from("unknown gear"))
243 }
244}