nmea_parser/gnss/
alm.rs

1/*
2Copyright 2020 Timo Saarinen
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17use serde::Serialize;
18
19use super::*;
20
21/// ALM - GPS Almanac Data
22#[derive(Clone, Debug, PartialEq, Serialize)]
23pub struct AlmData {
24    /// Navigation system
25    pub source: NavigationSystem,
26
27    /// Satellite PRN number (1-32)
28    pub prn: Option<u8>,
29
30    /// GPS week number (0-1023).
31    pub week_number: Option<u16>,
32
33    /// Satellite health (bits 17-24)
34    pub health_bits: Option<u8>,
35
36    /// Eccentricity
37    pub eccentricity: Option<u16>,
38
39    /// Reference time of almanac (TOA)
40    pub reference_time: Option<u8>,
41
42    /// Satellite inclination angle (sigma)
43    pub sigma: Option<u16>,
44
45    /// Rate of right ascension (omega dot)
46    pub omega_dot: Option<u16>,
47
48    /// Square root of semi-major axis (root a)
49    pub root_a: Option<u32>,
50
51    /// Argument of perigee (omega)
52    pub omega: Option<u32>,
53
54    /// Ascending node longitude (omega I)
55    pub omega_o: Option<u32>,
56
57    /// Mean anomaly (mo)
58    pub mo: Option<u32>,
59
60    /// Clock parameter 0 (af0)
61    pub af0: Option<u16>,
62
63    /// Clock parameter 1 (af0)
64    pub af1: Option<u16>,
65}
66
67// -------------------------------------------------------------------------------------------------
68
69/// xxALM: Global Positioning System Fix Data
70pub(crate) fn handle(
71    sentence: &str,
72    nav_system: NavigationSystem,
73) -> Result<ParsedMessage, ParseError> {
74    let split: Vec<&str> = sentence.split(',').collect();
75
76    Ok(ParsedMessage::Alm(AlmData {
77        source: nav_system,
78        prn: pick_hex_field(&split, 3)?,
79        week_number: { pick_hex_field::<u16>(&split, 4)?.map(|wk| wk & 0x3ff) },
80        health_bits: pick_hex_field(&split, 5)?,
81        eccentricity: pick_hex_field(&split, 6)?,
82        reference_time: pick_hex_field(&split, 7)?,
83        sigma: pick_hex_field(&split, 8)?,
84        omega_dot: pick_hex_field(&split, 9)?,
85        root_a: pick_hex_field(&split, 10)?,
86        omega: pick_hex_field(&split, 11)?,
87        omega_o: pick_hex_field(&split, 12)?,
88        mo: pick_hex_field(&split, 13)?,
89        af0: pick_hex_field(&split, 14)?,
90        af1: pick_hex_field(&split, 15)?,
91    }))
92}
93
94// -------------------------------------------------------------------------------------------------
95
96#[cfg(test)]
97mod test {
98    use super::*;
99
100    #[test]
101    fn test_parse_cpalm() {
102        match NmeaParser::new().parse_sentence(
103            "$GPALM,31,1,02,1617,00,50F6,0F,FD98,FD39,A10CF3,81389B,423632,BD913C,148,001*",
104        ) {
105            Ok(ps) => match ps {
106                ParsedMessage::Alm(alm) => {
107                    assert_eq!(alm.source, NavigationSystem::Gps);
108                    assert_eq!(alm.prn, Some(2));
109                    assert_eq!(alm.week_number, Some(535));
110                    assert_eq!(alm.health_bits, Some(0));
111                    assert_eq!(alm.eccentricity, Some(0x50F6));
112                    assert_eq!(alm.reference_time, Some(0x0f));
113                    assert_eq!(alm.sigma, Some(0xfd98));
114                    assert_eq!(alm.omega_dot, Some(0xfd39));
115                    assert_eq!(alm.root_a, Some(0xa10cf3));
116                    assert_eq!(alm.omega, Some(0x81389b));
117                    assert_eq!(alm.omega_o, Some(0x423632));
118                    assert_eq!(alm.mo, Some(0xbd913c));
119                    assert_eq!(alm.af0, Some(0x148));
120                    assert_eq!(alm.af1, Some(0x001));
121                }
122                ParsedMessage::Incomplete => {
123                    assert!(false);
124                }
125                _ => {
126                    assert!(false);
127                }
128            },
129            Err(e) => {
130                assert_eq!(e.to_string(), "OK");
131            }
132        }
133    }
134}