Skip to main content

nmea_parser/gnss/
vbw.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 super::*;
18
19/// VBW - Dual Ground/Water Speed
20#[derive(Clone, Debug, PartialEq, Serialize)]
21pub struct VbwData {
22    /// Navigation system
23    pub source: NavigationSystem,
24
25    /// Longitudinal water speed, knots     
26    pub lon_water_speed_knots: Option<f64>,
27
28    /// Transverse water speed, knots
29    pub tr_water_speed_knots: Option<f64>,
30
31    /// Water speed status
32    pub water_speed_valid: Option<bool>,
33
34    /// Longitudinal ground speed, knots     
35    pub lon_ground_speed_knots: Option<f64>,
36
37    /// Transverse ground speed, knots
38    pub tr_ground_speed_knots: Option<f64>,
39
40    /// Ground speed status
41    pub ground_speed_valid: Option<bool>,
42}
43
44// -------------------------------------------------------------------------------------------------
45
46/// xxVBW: Dual Ground/Water Speed
47pub(crate) fn handle(
48    sentence: &str,
49    nav_system: NavigationSystem,
50) -> Result<ParsedMessage, ParseError> {
51    let split: Vec<&str> = sentence.split(',').collect();
52
53    Ok(ParsedMessage::Vbw(VbwData {
54        source: nav_system,
55        lon_water_speed_knots: pick_number_field(&split, 1)?,
56        tr_water_speed_knots: pick_number_field(&split, 2)?,
57        water_speed_valid: {
58            match *split.get(3).unwrap_or(&"") {
59                "A" => Some(true),
60                "" => None,
61                _ => Some(false),
62            }
63        },
64        lon_ground_speed_knots: pick_number_field(&split, 4)?,
65        tr_ground_speed_knots: pick_number_field(&split, 5)?,
66        ground_speed_valid: {
67            match *split.get(6).unwrap_or(&"") {
68                "A" => Some(true),
69                "" => None,
70                _ => Some(false),
71            }
72        },
73    }))
74}
75
76// -------------------------------------------------------------------------------------------------
77
78#[cfg(test)]
79mod test {
80    use super::*;
81
82    #[test]
83    fn test_parse_cpvbw() {
84        match NmeaParser::new().parse_sentence("$GPVBW,2.0,1.5,A,2.1,1.6,X") {
85            Ok(ps) => match ps {
86                ParsedMessage::Vbw(vbw) => {
87                    assert_eq!(vbw.source, NavigationSystem::Gps);
88                    assert::close(vbw.lon_water_speed_knots.unwrap_or(0.0), 2.0, 0.1);
89                    assert::close(vbw.tr_water_speed_knots.unwrap_or(0.0), 1.5, 0.1);
90                    assert_eq!(vbw.water_speed_valid, Some(true));
91                    assert::close(vbw.lon_ground_speed_knots.unwrap_or(0.0), 2.1, 0.1);
92                    assert::close(vbw.tr_ground_speed_knots.unwrap_or(0.0), 1.6, 0.1);
93                    assert_eq!(vbw.ground_speed_valid, Some(false));
94                }
95                ParsedMessage::Incomplete => {
96                    assert!(false);
97                }
98                _ => {
99                    assert!(false);
100                }
101            },
102            Err(e) => {
103                assert_eq!(e.to_string(), "OK");
104            }
105        }
106    }
107}