rtcm_rs/df/dfs/
df_msg1059_biases.rs

1use 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    //encode satellite length
96    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}