rtcm_rs/df/dfs/
df_msg1065_biases.rs

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