common: Implement TimeAndPos::distance_cm().
[gps-watch.git] / test / gps_test.rs
1 /*
2  * Copyright (c) 2020 Tilman Sauerbeck (tilman at code-monkey de)
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 use common::fixed15_49;
25 use common::gps;
26
27 type Fixed = fixed15_49::Fixed15_49;
28
29 // Verifies that a single RMC message with position, date and time
30 // does not suffice for getting a valid TimeAndPos result.
31 #[test]
32 fn process_rmc_only() {
33     let input = b"\
34 $GPRMC,110338.000,,1234.5678,N,12345.6789,E,\
35 ,,011116*45";
36
37     let mut input_iter = input.iter();
38
39     let mut tap = gps::TimeAndPos::new();
40     let mut gps = gps::Gps::new();
41
42     let has_fix = gps.update(&mut tap, || {
43         input_iter.next().and_then(|&b| Some(b))
44     });
45
46     assert_eq!(false, has_fix);
47 }
48
49 // Verifies that a single GGA message with position and time
50 // does not suffice for getting a valid TimeAndPos result.
51 #[test]
52 fn process_gga_only() {
53     let input = b"\
54 $GPGGA,110338.000,1234.5678,N,12345.6789,E,\
55 1,04,2.4,190.3,M,48.0,M,,0000*58";
56     let mut input_iter = input.iter();
57
58     let mut tap = gps::TimeAndPos::new();
59     let mut gps = gps::Gps::new();
60
61     let has_fix = gps.update(&mut tap, || {
62         input_iter.next().and_then(|&b| Some(b))
63     });
64
65     assert_eq!(false, has_fix);
66 }
67
68 // Verifies that a GGA message received after a RMC message
69 // does suffice for getting a valid TimeAndPos result.
70 #[test]
71 fn process_rmc_and_gga() {
72     let input = b"\
73 $GPRMC,110338.000,,1234.5678,N,12345.6789,E,\
74 ,,011116*45\
75 $GPGGA,110338.000,1234.5678,N,12345.6789,E,\
76 1,04,2.4,190.3,M,48.0,M,,0000*58";
77     let mut input_iter = input.iter();
78
79     let mut tap = gps::TimeAndPos::new();
80     let mut gps = gps::Gps::new();
81
82     let has_fix = gps.update(&mut tap, || {
83         input_iter.next().and_then(|&b| Some(b))
84     });
85
86     assert_eq!(true, has_fix);
87     assert_eq!(1477998218, tap.unix_time);
88     assert_eq!(7545678, tap.latitude);
89     assert_eq!(74256789, tap.longitude);
90     assert_eq!(0.21949487565883447, tap.latitude_rad.to_f32());
91     assert_eq!(2.160042433347846, tap.longitude_rad.to_f32());
92 }
93
94 #[test]
95 fn distance_cm0() {
96     let tap0 = gps::TimeAndPos {
97         system_time: 0,
98         unix_time: 0,
99         latitude: 0,
100         longitude: 0,
101         latitude_rad: Fixed::from_f32(49.02541333).to_radians(),
102         longitude_rad: Fixed::from_f32(8.79440167).to_radians(),
103     };
104
105     let tap1 = gps::TimeAndPos {
106         system_time: 1,
107         unix_time: 1,
108         latitude: 0,
109         longitude: 0,
110         latitude_rad: Fixed::from_f32(49.02541000).to_radians(),
111         longitude_rad: Fixed::from_f32(8.79443667).to_radians(),
112     };
113
114     assert_eq!(349, tap1.distance_cm(&tap0));
115 }