1pub static PARAM_PACKET_SIZE: usize = 2048;
2
3use crate::math::FlightFloat;
4
5pub const ADC_MAX_CHANNELS: usize = 21;
6pub const RC_PACKET_CHANNELS: usize = 24;
7
8#[derive(Debug, Clone, Copy, Default)]
9pub enum RangeType {
10 #[default]
11 Sonar,
12 Lidar,
13}
14
15#[derive(Debug, Clone, Copy, Default)]
16pub enum GNSSFixType {
17 #[default]
18 NoFix,
19 DeadReckoningOnly,
20 TwoD,
21 ThreeD,
22 GnssPlusDeadReckoning,
23 TimeFixOnly,
24}
25
26impl GNSSFixType {
27 pub fn from_u8(value: u8) -> Self {
28 match value {
29 0 => GNSSFixType::NoFix,
30 1 => GNSSFixType::DeadReckoningOnly,
31 2 => GNSSFixType::TwoD,
32 3 => GNSSFixType::ThreeD,
33 4 => GNSSFixType::GnssPlusDeadReckoning,
34 5 => GNSSFixType::TimeFixOnly,
35 _ => GNSSFixType::NoFix, }
37 }
38}
39
40#[derive(Debug, Clone, Copy, Default)]
41pub struct RosflightPacketHeader {
42 pub timestamp: u64,
44 pub status: u16,
45}
46
47#[derive(Debug, Clone, Copy, Default)]
48pub struct AdcPacket {
49 pub header: RosflightPacketHeader,
50 pub temperature: f32,
51 pub v_bku: f32,
52 pub v_ref: f32,
53 pub volts: [f32; ADC_MAX_CHANNELS],
54}
55
56#[derive(Debug, Clone, Copy, Default)]
57pub struct BatteryPacket {
58 pub header: RosflightPacketHeader,
59 pub voltage: f32,
60 pub current: f32,
61}
62
63#[derive(Debug, Clone, Copy, Default)]
64pub struct ImuPacket<R: FlightFloat> {
65 pub header: RosflightPacketHeader,
66 pub accel: [R; 3],
67 pub gyro: [R; 3],
68 pub temperature: f32,
69 pub seq: u32,
70}
71
72impl<R: FlightFloat> ImuPacket<R> {
73 pub fn cast<T: FlightFloat>(self) -> ImuPacket<T> {
74 ImuPacket {
75 header: self.header,
76 accel: [
77 <T as FlightFloat>::from_flight_float(self.accel[0]),
78 <T as FlightFloat>::from_flight_float(self.accel[1]),
79 <T as FlightFloat>::from_flight_float(self.accel[2]),
80 ],
81 gyro: [
82 <T as FlightFloat>::from_flight_float(self.gyro[0]),
83 <T as FlightFloat>::from_flight_float(self.gyro[1]),
84 <T as FlightFloat>::from_flight_float(self.gyro[2]),
85 ],
86 temperature: self.temperature,
87 seq: self.seq,
88 }
89 }
90}
91
92#[derive(Debug, Clone, Copy, Default)]
93pub struct BaroPacket {
94 pub header: RosflightPacketHeader,
95 pub pressure: f32,
96 pub temperature: f32,
97 pub altitude: f32,
98}
99
100#[derive(Debug, Clone, Copy, Default)]
101pub struct PitotPacket {
102 pub header: RosflightPacketHeader,
103 pub differential_pressure: f32,
104 pub temperature: f32,
105 pub indicated_airspeed: f32,
106}
107
108#[derive(Debug, Clone, Copy, Default)]
109pub struct MagPacket {
110 pub header: RosflightPacketHeader,
111 pub flux: [f32; 3],
112 pub temperature: f32,
113}
114
115#[derive(Debug, Clone, Copy, Default)]
116pub struct RcPacket {
117 pub header: RosflightPacketHeader,
118 pub n_chan: u32,
119 pub chan: [f32; RC_PACKET_CHANNELS],
120 pub lol: bool,
121}
122
123#[derive(Debug, Clone, Copy, Default)]
124pub struct RangePacket {
125 pub header: RosflightPacketHeader,
126 pub range: f32,
127 pub min_range: f32,
128 pub max_range: f32,
129 pub range_type: RangeType,
130}
131
132#[derive(Debug, Clone, Copy, Default)]
133pub struct GNSSPacket {
134 pub header: RosflightPacketHeader, pub unix_seconds: i64, pub unix_nanos: i32,
137 pub lat: f64, pub lon: f64, pub height: f32, pub vel_n: f32, pub vel_e: f32, pub vel_d: f32, pub h_acc: f32, pub v_acc: f32, pub s_acc: f32, pub month: u8, pub year: u16, pub day: u8, pub hour: u8, pub min: u8, pub sec: u8, pub nano: i32, pub fix_type: GNSSFixType,
154 pub num_sats: u8, pub mag_dec: f32, pub time_correction: u64,
157}
158
159#[derive(Debug, Clone, Copy, Default)]
160pub struct PpsPacket {
161 pub header: RosflightPacketHeader,
162}
163
164#[derive(Debug, Clone, Copy, Default)]
165pub struct AttitudePacket {
166 pub header: RosflightPacketHeader,
167 pub q: [f32; 4],
168 pub rate: [f32; 3],
169}
170
171#[derive(Debug, Clone, Copy)]
172pub struct ParamPacket {
173 pub header: RosflightPacketHeader,
174 pub values: [u8; PARAM_PACKET_SIZE],
175}
176
177impl Default for ParamPacket {
178 fn default() -> Self {
179 Self {
180 header: RosflightPacketHeader::default(),
181 values: [0u8; PARAM_PACKET_SIZE],
182 }
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn imu_packet_cast_preserves_values_across_flight_float_types() {
192 let packet = ImuPacket::<f32> {
193 header: RosflightPacketHeader {
194 timestamp: 42,
195 status: 7,
196 },
197 accel: [1.0, -2.0, 3.5],
198 gyro: [0.1, -0.2, 0.3],
199 temperature: 24.0,
200 seq: 9,
201 };
202
203 let widened = packet.cast::<f64>();
204 assert_eq!(widened.header.timestamp, packet.header.timestamp);
205 assert_eq!(widened.header.status, packet.header.status);
206 assert_eq!(widened.accel, [1.0, -2.0, 3.5]);
207 assert_eq!(
208 widened.gyro,
209 [0.1_f32 as f64, -0.2_f32 as f64, 0.3_f32 as f64]
210 );
211 assert_eq!(widened.temperature, 24.0);
212 assert_eq!(widened.seq, 9);
213 }
214}