rtcm_rs/df/dfs/
df_msg1065_biases.rs1use crate::df::bit_value::*;
2use crate::df::{assembler::Assembler, parser::Parser};
3use crate::msg::GloSigId;
4use crate::msg::SAT_CAP_1065;
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 Msg1065CodeBias {
15 pub satellite_id: u8,
16 pub signal_id: GloSigId,
17 pub bias_m: f32,
18}
19
20#[cfg(feature = "test_gen")]
21impl SourceRepr for Msg1065CodeBias {
22 fn to_source(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23 use core::fmt::Write;
24 write!(
25 f,
26 "Msg1065CodeBias {{ satellite_id: {}, signal_id: glo::",
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::Msg1065CodeBias;
38}
39
40pub type DataType = DataVec<Msg1065CodeBias, SAT_CAP_1065>;
41
42macro_rules! sig_mappings {
43 [
44 $( $num:literal => $band:literal|$attr:literal ),+
45 ] => {
46 fn to_sig(id: u8) -> Option<GloSigId> {
47 match id {
48 $(
49 $num => Some(GloSigId::new($band,$attr)),
50 )+
51 _ => None,
52 }
53 }
54 fn to_id(sig: GloSigId) -> 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 => 2|'C',
69 3 => 2|'P'
70];
71
72#[allow(unused)]
73pub fn encode(asm: &mut Assembler, value: &DataType) -> Result<(), RtcmError> {
74 let mut sat_mask: u32 = 0;
75 let mut sat_num: u8 = 0;
76 for bias in value.iter() {
77 if bias.satellite_id <= 31 {
78 let sat = 1 << bias.satellite_id;
79 if sat_mask & sat == 0 {
80 sat_mask |= 1 << bias.satellite_id;
81 sat_num += 1;
82 }
83 } else {
84 return Err(RtcmError::OutOfRange);
85 }
86 }
87 asm.put::<U8>(sat_num, 6)?;
89
90 for s in 0..=31u8 {
91 if sat_mask & (1 << s) != 0 {
92 asm.put::<U8>(s, 5)?;
93 let num_biases: u8 = value
94 .iter()
95 .filter(|b| b.satellite_id == s && to_id(b.signal_id).is_some())
96 .count() as u8;
97 asm.put::<U8>(num_biases, 5)?;
98 let mut bias_mask: u32 = 0;
99 for bias in value.iter().filter(|b| b.satellite_id == s) {
100 if let Some(sig_id) = to_id(bias.signal_id) {
101 asm.put::<U8>(sig_id, 5)?;
102 let mut bias = bias.bias_m;
103 bias /= 0.01;
104 let bias = if bias > 0.0 { bias + 0.5 } else { bias - 0.5 } as i16;
105 asm.put::<I16>(bias, 14)?;
106 }
107 }
108 }
109 }
110 Ok(())
111}
112
113#[allow(unused)]
114pub fn decode(par: &mut Parser) -> Result<DataType, RtcmError> {
115 let mut value = DataVec::<Msg1065CodeBias, SAT_CAP_1065>::new();
116 let sat_num = par.parse::<U8>(6)?;
117 for _ in 0..sat_num {
118 let satellite_id = par.parse::<U8>(5)?;
119 let bias_num = par.parse::<U8>(5)?;
120 for _ in 0..bias_num {
121 if let Some(signal_id) = to_sig(par.parse::<U8>(5)?) {
122 let bias = par.parse::<I16>(14)? as f32;
123 value.push(Msg1065CodeBias {
124 satellite_id,
125 signal_id,
126 bias_m: bias * 0.01,
127 });
128 }
129 }
130 }
131 Ok(value)
132}
133
134#[cfg(feature = "test_gen")]
135use crate::val_gen::ValGen;
136#[cfg(feature = "test_gen")]
137#[allow(unused)]
138pub fn generate<FR, LR, RR>(
139 asm: &mut Assembler,
140 val_gen: &mut ValGen<FR, LR, RR>,
141) -> Result<(), RtcmError>
142where
143 FR: rand::Rng,
144 LR: rand::Rng,
145 RR: rand::Rng,
146{
147 let sat_num = val_gen.len_rng.gen::<u8>() % 32;
148 let is_max = val_gen.len_rng.gen::<u64>() == u64::MAX;
149 asm.put::<U8>(sat_num, 6)?;
150 for s in 1..=sat_num {
151 asm.put::<U8>(s, 5)?;
152 let num_biases: u8 = if s == 31 { 18 } else { 12 };
153 asm.put::<U8>(num_biases, 5)?;
154 let mut sig_id = val_gen.rng_rng.gen::<u8>() % 16;
155 for _ in 0..num_biases {
156 while to_sig(sig_id).is_none() {
157 sig_id += 1;
158 sig_id %= 16;
159 }
160 asm.put::<U8>(sig_id, 5)?;
161 let bias = val_gen.field_rng.gen::<i16>();
162 asm.put::<I16>(bias, 14)?;
163 sig_id += 1;
164 sig_id %= 16;
165 }
166 }
167 Ok(())
168}