blackbox_log/frame/gps/
mod.rs1mod def;
2
3use alloc::vec::Vec;
4
5pub use self::def::*;
6use super::Unit;
7use crate::filter::AppliedFilter;
8use crate::units::prelude::*;
9use crate::{units, Headers};
10
11#[derive(Debug, Clone)]
13pub struct GpsFrame<'data, 'headers, 'parser> {
14 headers: &'headers Headers<'data>,
15 raw: RawGpsFrame,
16 filter: &'parser AppliedFilter,
17}
18
19impl super::seal::Sealed for GpsFrame<'_, '_, '_> {}
20
21impl super::Frame for GpsFrame<'_, '_, '_> {
22 type Value = GpsValue;
23
24 #[inline]
25 fn len(&self) -> usize {
26 self.filter.len()
27 }
28
29 fn get_raw(&self, index: usize) -> Option<u32> {
30 let index = self.filter.get(index)?;
31 Some(self.raw.values[index])
32 }
33
34 fn get(&self, index: usize) -> Option<Self::Value> {
35 let frame_def = self.headers.gps_frame_def().unwrap();
36 let index = self.filter.get(index)?;
37
38 let def = &frame_def.fields[index];
39 let raw = self.raw.values[index];
40
41 let value = match def.unit {
42 GpsUnit::Coordinate => {
43 assert!(def.signed);
44 let value = raw.cast_signed();
45
46 GpsValue::Coordinate(f64::from(value) / 10000000.)
47 }
48 GpsUnit::Altitude => {
49 let altitude = if def.signed {
50 raw.cast_signed().into()
51 } else {
52 raw.into()
53 };
54
55 GpsValue::Altitude(Length::new::<meter>(altitude))
56 }
57 GpsUnit::Velocity => {
58 assert!(!def.signed);
59 GpsValue::Velocity(units::new::velocity(raw))
60 }
61 GpsUnit::Heading => {
62 assert!(!def.signed);
63 GpsValue::Heading(f64::from(raw) / 10.)
64 }
65 GpsUnit::Unitless => GpsValue::new_unitless(raw, def.signed),
66 };
67
68 Some(value)
69 }
70}
71
72impl<'data, 'headers, 'parser> GpsFrame<'data, 'headers, 'parser> {
73 pub(crate) fn new(
74 headers: &'headers Headers<'data>,
75 raw: RawGpsFrame,
76 filter: &'parser AppliedFilter,
77 ) -> Self {
78 Self {
79 headers,
80 raw,
81 filter,
82 }
83 }
84
85 pub fn time(&self) -> Time {
87 units::new::time(self.raw.time)
88 }
89
90 pub fn time_raw(&self) -> u64 {
95 self.raw.time
96 }
97}
98
99#[derive(Debug, Clone)]
100pub(crate) struct RawGpsFrame {
101 pub(crate) time: u64,
102 pub(crate) values: Vec<u32>,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq)]
106pub enum GpsValue {
107 Coordinate(f64),
108 Altitude(Length),
109 Velocity(Velocity),
110 Heading(f64),
111 Unsigned(u32),
112 Signed(i32),
113}
114
115impl GpsValue {
116 const fn new_unitless(value: u32, signed: bool) -> Self {
117 if signed {
118 Self::Signed(value.cast_signed())
119 } else {
120 Self::Unsigned(value)
121 }
122 }
123}
124
125impl From<GpsValue> for super::Value {
126 fn from(value: GpsValue) -> Self {
127 match value {
128 GpsValue::Coordinate(c) => Self::GpsCoordinate(c),
129 GpsValue::Altitude(a) => Self::Altitude(a),
130 GpsValue::Velocity(v) => Self::Velocity(v),
131 GpsValue::Heading(h) => Self::GpsHeading(h),
132 GpsValue::Unsigned(x) => Self::Unsigned(x),
133 GpsValue::Signed(x) => Self::Signed(x),
134 }
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
139pub enum GpsUnit {
140 Coordinate,
141 Altitude,
142 Velocity,
143 Heading,
144 Unitless,
145}
146
147impl From<GpsUnit> for Unit {
148 fn from(unit: GpsUnit) -> Self {
149 match unit {
150 GpsUnit::Coordinate => Self::GpsCoordinate,
151 GpsUnit::Altitude => Self::Altitude,
152 GpsUnit::Velocity => Self::Velocity,
153 GpsUnit::Heading => Self::GpsHeading,
154 GpsUnit::Unitless => Self::Unitless,
155 }
156 }
157}