rtcm_rs/df/dfs/
df_msg1059_biases.rs1use crate::df::bit_value::*;
2use crate::df::{assembler::Assembler, parser::Parser};
3use crate::msg::GpsSigId;
4use crate::msg::SAT_CAP_1059;
5use crate::rtcm_error::RtcmError;
6#[cfg(feature = "test_gen")]
7use crate::source_repr::SourceRepr;
8use crate::util::DataVec;
9#[cfg(feature = "serde")]
10use crate::{Deserialize, Serialize};
11
12#[derive(Default, Clone, Debug, PartialEq)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "sd"))]
14pub struct Msg1059CodeBias {
15 pub satellite_id: u8,
16 pub signal_id: GpsSigId,
17 pub bias_m: f32,
18}
19
20#[cfg(feature = "test_gen")]
21impl SourceRepr for Msg1059CodeBias {
22 fn to_source(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23 use core::fmt::Write;
24 write!(
25 f,
26 "Msg1059CodeBias {{ satellite_id: {}, signal_id: gps::",
27 self.satellite_id
28 )?;
29 self.signal_id.to_source(f)?;
30 write!(f, ", bias_m: ")?;
31 self.bias_m.to_source(f)?;
32 f.write_char('}')
33 }
34}
35
36pub mod export_types {
37 pub use super::Msg1059CodeBias;
38}
39
40pub type DataType = DataVec<Msg1059CodeBias, SAT_CAP_1059>;
41
42macro_rules! sig_mappings {
43 [
44 $( $num:literal => $band:literal|$attr:literal ),+
45 ] => {
46 fn to_sig(id: u8) -> Option<GpsSigId> {
47 match id {
48 $(
49 $num => Some(GpsSigId::new($band,$attr)),
50 )+
51 _ => None,
52 }
53 }
54 fn to_id(sig: GpsSigId) -> Option<u8> {
55 match (sig.band(), sig.attribute()) {
56 $(
57 ($band, $attr) => Some($num),
58 )+
59 _ => None,
60 }
61 }
62 };
63}
64
65sig_mappings![
66 0 => 1|'C',
67 1 => 1|'P',
68 2 => 1|'W',
69 5 => 2|'C',
70 6 => 2|'D',
71 7 => 2|'S',
72 8 => 2|'L',
73 9 => 2|'X',
74 10 => 2|'P',
75 11 => 2|'W',
76 14 => 5|'I',
77 15 => 5|'Q'
78];
79
80#[allow(unused)]
81pub fn encode(asm: &mut Assembler, value: &DataType) -> Result<(), RtcmError> {
82 let mut sat_mask: u64 = 0;
83 let mut sat_num: u8 = 0;
84 for bias in value.iter() {
85 if bias.satellite_id <= 63 {
86 let sat = 1 << bias.satellite_id;
87 if sat_mask & sat == 0 {
88 sat_mask |= 1 << bias.satellite_id;
89 sat_num += 1;
90 }
91 } else {
92 return Err(RtcmError::OutOfRange);
93 }
94 }
95 asm.put::<U8>(sat_num, 6)?;
97
98 for s in 0..=63u8 {
99 if sat_mask & (1 << s) != 0 {
100 asm.put::<U8>(s, 6)?;
101 let num_biases: u8 = value
102 .iter()
103 .filter(|b| b.satellite_id == s && to_id(b.signal_id).is_some())
104 .count() as u8;
105 asm.put::<U8>(num_biases, 5)?;
106 let mut bias_mask: u32 = 0;
107 for bias in value.iter().filter(|b| b.satellite_id == s) {
108 if let Some(sig_id) = to_id(bias.signal_id) {
109 asm.put::<U8>(sig_id, 5)?;
110 let mut bias = bias.bias_m;
111 bias /= 0.01;
112 let bias = if bias > 0.0 { bias + 0.5 } else { bias - 0.5 } as i16;
113 asm.put::<I16>(bias, 14)?;
114 }
115 }
116 }
117 }
118 Ok(())
119}
120
121#[allow(unused)]
122pub fn decode(par: &mut Parser) -> Result<DataType, RtcmError> {
123 let mut value = DataVec::<Msg1059CodeBias, SAT_CAP_1059>::new();
124 let sat_num = par.parse::<U8>(6)?;
125 for _ in 0..sat_num {
126 let satellite_id = par.parse::<U8>(6)?;
127 let bias_num = par.parse::<U8>(5)?;
128 for _ in 0..bias_num {
129 if let Some(signal_id) = to_sig(par.parse::<U8>(5)?) {
130 let bias = par.parse::<I16>(14)? as f32;
131 value.push(Msg1059CodeBias {
132 satellite_id,
133 signal_id,
134 bias_m: bias * 0.01,
135 });
136 }
137 }
138 }
139 Ok(value)
140}
141
142#[cfg(feature = "test_gen")]
143use crate::val_gen::ValGen;
144#[cfg(feature = "test_gen")]
145#[allow(unused)]
146pub fn generate<FR, LR, RR>(
147 asm: &mut Assembler,
148 val_gen: &mut ValGen<FR, LR, RR>,
149) -> Result<(), RtcmError>
150where
151 FR: rand::Rng,
152 LR: rand::Rng,
153 RR: rand::Rng,
154{
155 let sat_num = val_gen.len_rng.gen::<u8>() % 64;
156 let is_max = val_gen.len_rng.gen::<u64>() == u64::MAX;
157 asm.put::<U8>(sat_num, 6)?;
158 for s in 1..=sat_num {
159 asm.put::<U8>(s, 6)?;
160 let num_biases: u8 = if s == 63 { 18 } else { 6 };
161 asm.put::<U8>(num_biases, 5)?;
162 let mut sig_id = val_gen.rng_rng.gen::<u8>() % 16;
163 for _ in 0..num_biases {
164 while to_sig(sig_id).is_none() {
165 sig_id += 1;
166 sig_id %= 16;
167 }
168 asm.put::<U8>(sig_id, 5)?;
169 let bias = val_gen.field_rng.gen::<i16>();
170 asm.put::<I16>(bias, 14)?;
171 sig_id += 1;
172 sig_id %= 16;
173 }
174 }
175 Ok(())
176}