MRPT  2.0.4
CGPSInterface_unittest.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include <gtest/gtest.h>
12 #include <mrpt/io/CMemoryStream.h>
13 
14 using namespace mrpt;
15 using namespace mrpt::hwdrivers;
16 using namespace mrpt::obs;
17 using namespace std;
18 
19 // Example cmds:
20 // https://www.sparkfun.com/datasheets/GPS/NMEA%20Reference%20Manual-Rev2.1-Dec07.pdf
21 
22 TEST(CGPSInterface, parse_NMEA_GGA)
23 {
24  // Test with a correct frame:
25  {
26  const char* test_cmd =
27  "$GPGGA,101830.00,3649.76162994,N,00224.53709052,W,2,08,1.1,9.3,M,"
28  "47.4,M,5.0,0120*58";
30  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
31  EXPECT_TRUE(parse_ret) << "Failed parse of: " << test_cmd << endl;
32 
33  const gnss::Message_NMEA_GGA* msg =
35  EXPECT_TRUE(msg != nullptr);
36  if (!msg) return;
38  msg->fields.latitude_degrees, 36 + 49.76162994 / 60.0, 1e-10);
40  msg->fields.longitude_degrees, -(002 + 24.53709052 / 60.0), 1e-10);
41  EXPECT_NEAR(msg->fields.altitude_meters, 9.3, 1e-10);
42  }
43  // Test with an empty frame:
44  {
45  const char* test_cmd = "$GPGGA,,,,,,0,,,,M,,M,,*6";
47  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
48  EXPECT_FALSE(parse_ret);
49  }
50 }
51 
52 TEST(CGPSInterface, parse_NMEA_RMC)
53 {
54  const char* test_cmd =
55  "$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598, ,*10";
57  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
58  EXPECT_TRUE(parse_ret) << "Failed parse of: " << test_cmd << endl;
59 
60  const gnss::Message_NMEA_RMC* msg =
62 
63  EXPECT_TRUE(msg != nullptr);
64  if (!msg) return;
65  EXPECT_NEAR(msg->fields.latitude_degrees, 37 + 23.2475 / 60.0, 1e-10);
66  EXPECT_NEAR(msg->fields.longitude_degrees, -(121 + 58.3416 / 60.0), 1e-10);
67 }
68 
69 TEST(CGPSInterface, parse_NMEA_GLL)
70 {
71  const char* test_cmd = "$GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41";
73  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
74  EXPECT_TRUE(parse_ret) << "Failed parse of: " << test_cmd << endl;
75 
76  const gnss::Message_NMEA_GLL* msg =
78 
79  EXPECT_TRUE(msg != nullptr);
80  if (!msg) return;
81  EXPECT_NEAR(msg->fields.latitude_degrees, 37 + 23.2475 / 60.0, 1e-10);
82  EXPECT_NEAR(msg->fields.longitude_degrees, -(121 + 58.3416 / 60.0), 1e-10);
83 }
84 
85 TEST(CGPSInterface, parse_NMEA_VTG)
86 {
87  const char* test_cmd = "$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48";
89  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
90  EXPECT_TRUE(parse_ret) << "Failed parse of: " << test_cmd << endl;
91 
92  const gnss::Message_NMEA_VTG* msg =
94 
95  EXPECT_TRUE(msg != nullptr);
96  if (!msg) return;
97  EXPECT_NEAR(msg->fields.true_track, 54.7, 1e-6);
98  EXPECT_NEAR(msg->fields.magnetic_track, 34.4, 1e-6);
99  EXPECT_NEAR(msg->fields.ground_speed_knots, 5.5, 1e-6);
100  EXPECT_NEAR(msg->fields.ground_speed_kmh, 10.2, 1e-6);
101 }
102 
103 TEST(CGPSInterface, parse_NMEA_ZDA)
104 {
105  const char* test_cmd = "$GPZDA,181813,14,10,2003,00,00*4F";
107  const bool parse_ret = CGPSInterface::parse_NMEA(test_cmd, obsGPS);
108  EXPECT_TRUE(parse_ret) << "Failed parse of: " << test_cmd << endl;
109 
110  const gnss::Message_NMEA_ZDA* msg =
112 
113  EXPECT_TRUE(msg != nullptr);
114  if (!msg) return;
115  EXPECT_TRUE(msg->fields.date_day == 14);
116  EXPECT_TRUE(msg->fields.date_month == 10);
117  EXPECT_TRUE(msg->fields.date_year == 2003);
118  EXPECT_TRUE(msg->fields.UTCTime.hour == 18);
119  EXPECT_TRUE(msg->fields.UTCTime.minute == 18);
120  EXPECT_TRUE(msg->fields.UTCTime.sec == 13.0);
121  // Replaced from EXPECT_EQ() to avoid a "bus error" in a gtest template
122  // under armhf.
123 }
124 
125 TEST(CGPSInterface, parse_NMEA_ZDA_stream)
126 {
127  auto buf = std::make_shared<mrpt::io::CMemoryStream>();
128  {
129  const std::string s("$GPZDA,181813,14,10,2003,00,00*4F\n");
130  buf->Write(s.c_str(), s.size());
131  buf->Seek(0);
132  }
133 
134  CGPSInterface gps;
135  gps.bindStream(buf);
136 
137  gps.initialize();
138  gps.doProcess();
139 
141  gps.getObservations(obss);
142 
143  EXPECT_EQ(obss.size(), 1U);
144 
145  auto obsGPS = mrpt::ptr_cast<CObservationGPS>::from(obss.begin()->second);
146 
147  const gnss::Message_NMEA_ZDA* msg =
148  obsGPS->getMsgByClassPtr<gnss::Message_NMEA_ZDA>();
149 
150  EXPECT_TRUE(msg != nullptr);
151  if (!msg) return;
152  EXPECT_TRUE(msg->fields.date_day == 14);
153  EXPECT_TRUE(msg->fields.date_month == 10);
154  EXPECT_TRUE(msg->fields.date_year == 2003);
155  EXPECT_TRUE(msg->fields.UTCTime.hour == 18);
156  EXPECT_TRUE(msg->fields.UTCTime.minute == 18);
157  EXPECT_TRUE(msg->fields.UTCTime.sec == 13.0);
158  // Replaced from EXPECT_EQ() to avoid a "bus error" in a gtest template
159  // under armhf.
160 }
161 
162 TEST(CGPSInterface, parse_NOVATEL6_stream)
163 {
164  auto buf = std::make_shared<mrpt::io::CMemoryStream>();
165  {
166  const uint8_t sample_novatel6_gps[] = {
167  0xaa, 0x44, 0x12, 0x1c, 0x2a, 0x00, 0x00, 0xa0, 0x48, 0x00, 0x00,
168  0x00, 0x5a, 0xb4, 0x59, 0x07, 0x10, 0x4a, 0xb7, 0x16, 0x00, 0x00,
169  0x00, 0x00, 0xf6, 0xb1, 0x4a, 0x34, 0x00, 0x00, 0x00, 0x00, 0x38,
170  0x00, 0x00, 0x00, 0x97, 0x2b, 0x45, 0xa9, 0xc8, 0x6a, 0x42, 0x40,
171  0xfc, 0x54, 0x43, 0x6f, 0x11, 0x18, 0x03, 0xc0, 0x00, 0x00, 0x20,
172  0x8f, 0xe8, 0x0e, 0x1c, 0x40, 0x66, 0x66, 0x48, 0x42, 0x3d, 0x00,
173  0x00, 0x00, 0x1d, 0x9b, 0x96, 0x3c, 0x2c, 0xd5, 0x9c, 0x3c, 0xd1,
174  0x39, 0xa8, 0x3c, 0x35, 0x35, 0x35, 0x00, 0x00, 0x00, 0x60, 0x41,
175  0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x0e, 0x0d, 0x00, 0x00, 0x00,
176  0x33, 0x82, 0xba, 0x79, 0xe5, 0xaa, 0x44, 0x13, 0x58, 0xfc, 0x01,
177  0x59, 0x07, 0x10, 0x4a, 0xb7, 0x16, 0x59, 0x07, 0x00, 0x00, 0x33,
178  0x33, 0x33, 0x33, 0xdb, 0x42, 0x17, 0x41, 0xa7, 0xf0, 0xaf, 0xa5,
179  0xc8, 0x6a, 0x42, 0x40, 0xa2, 0xad, 0xac, 0x28, 0x12, 0x18, 0x03,
180  0xc0, 0x00, 0x00, 0x8a, 0x8b, 0x52, 0x8d, 0x4c, 0x40, 0x10, 0xe2,
181  0xdb, 0x3c, 0x4b, 0xbd, 0x82, 0xbf, 0x52, 0x23, 0x1e, 0x50, 0x08,
182  0xf1, 0x9b, 0xbf, 0xd4, 0xa6, 0xd1, 0x7c, 0xcd, 0x16, 0xc8, 0x3f,
183  0x31, 0x27, 0xe1, 0x16, 0xa2, 0x6b, 0x10, 0x40, 0xc7, 0x1c, 0xc7,
184  0x39, 0x6a, 0x9c, 0x00, 0x40, 0xa0, 0x3c, 0x9f, 0x79, 0xca, 0xdd,
185  0x63, 0x40, 0x03, 0x00, 0x00, 0x00, 0x27, 0xbb, 0xff, 0xf8, 0xaa,
186  0x44, 0x12, 0x1c, 0x2a, 0x00, 0x00, 0xa0, 0x48, 0x00, 0x00, 0x00,
187  0x5a, 0xb4, 0x59, 0x07, 0x42, 0x4a, 0xb7, 0x16, 0x00, 0x00, 0x00,
188  0x00, 0xf6, 0xb1, 0x4a, 0x34, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,
189  0x00, 0x00, 0xf0, 0x23, 0x3c, 0xa9, 0xc8, 0x6a, 0x42, 0x40, 0xdd,
190  0x10, 0x6c, 0x71, 0x11, 0x18, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x03,
191  0xa7, 0x18, 0x1c, 0x40, 0x66, 0x66, 0x48, 0x42, 0x3d, 0x00, 0x00,
192  0x00, 0x32, 0x9b, 0x96, 0x3c, 0x82, 0xd4, 0x9c, 0x3c, 0x5d, 0x3a,
193  0xa8, 0x3c, 0x35, 0x35, 0x35, 0x00, 0x00, 0x00, 0x60, 0x41, 0x00,
194  0x00, 0x00, 0x00, 0x0f, 0x0e, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x33,
195  0xcb, 0x95, 0xa0, 0x9b, 0xaa, 0x44, 0x13, 0x58, 0xfc, 0x01, 0x59,
196  0x07, 0x42, 0x4a, 0xb7, 0x16, 0x59, 0x07, 0x00, 0x00, 0x67, 0x66,
197  0x66, 0x66, 0xdb, 0x42, 0x17, 0x41, 0xe6, 0xae, 0xa1, 0xa5, 0xc8,
198  0x6a, 0x42, 0x40, 0x26, 0x1e, 0x82, 0x2b, 0x12, 0x18, 0x03, 0xc0,
199  0x00, 0x00, 0x62, 0xb6, 0x8b, 0x8e, 0x4c, 0x40, 0x10, 0x63, 0x42,
200  0x19, 0x38, 0x19, 0x7a, 0xbf, 0x1e, 0xa9, 0x79, 0x02, 0x24, 0x6c,
201  0x9d, 0xbf, 0x52, 0x13, 0x38, 0xa4, 0x35, 0x2c, 0xc8, 0x3f, 0xa9,
202  0x3b, 0x21, 0x59, 0xe0, 0xa0, 0x10, 0x40, 0x51, 0xd1, 0x8c, 0x50,
203  0x0b, 0xa0, 0x00, 0x40, 0x16, 0x40, 0x94, 0xbe, 0xc2, 0xdd, 0x63,
204  0x40, 0x03, 0x00, 0x00, 0x00, 0x20, 0x4d, 0xe7, 0xa2, 0xaa, 0x44,
205  0x12, 0x1c, 0x2a, 0x00, 0x00, 0xa0, 0x48, 0x00, 0x00, 0x00, 0x5a,
206  0xb4, 0x59, 0x07, 0x74, 0x4a, 0xb7, 0x16, 0x00, 0x00, 0x00, 0x00,
207  0xf6, 0xb1, 0x4a, 0x34, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
208  0x00, 0xaa, 0x41, 0x32, 0xa9, 0xc8, 0x6a, 0x42, 0x40, 0xff, 0x59,
209  0xa8, 0x73, 0x11, 0x18, 0x03, 0xc0, 0x00, 0x00, 0xa0, 0xd6, 0x6b,
210  0x22, 0x1c, 0x40, 0x66, 0x66, 0x48, 0x42, 0x3d, 0x00, 0x00, 0x00,
211  0x92, 0x9b, 0x96, 0x3c, 0x70, 0xd3, 0x9c, 0x3c, 0x06, 0x3b, 0xa8,
212  0x3c, 0x35, 0x35, 0x35, 0x00};
213  const unsigned int sample_novatel6_gps_len = 500;
214  buf->Write(sample_novatel6_gps, sample_novatel6_gps_len);
215  buf->Seek(0);
216  }
217 
218  CGPSInterface gps;
219  gps.bindStream(buf);
220 
221  gps.initialize();
222  gps.doProcess();
223 
225  gps.getObservations(obss);
226 
227  EXPECT_EQ(obss.size(), 4U);
228  if (obss.empty()) return;
229 
230  auto itObs = obss.begin();
231  auto obsGPS1 = mrpt::ptr_cast<CObservationGPS>::from(itObs->second);
232  ++itObs;
233  auto obsGPS2 = mrpt::ptr_cast<CObservationGPS>::from(itObs->second);
234 
235  EXPECT_TRUE(obsGPS1);
236  EXPECT_TRUE(obsGPS2);
237 
238  const auto* msg1 =
239  obsGPS1->getMsgByClassPtr<gnss::Message_NV_OEM6_BESTPOS>();
240  EXPECT_TRUE(msg1 != nullptr);
241  if (!msg1) return;
242  EXPECT_TRUE(msg1->fields.num_sats_tracked == 15);
243 
244  const auto* msg2 =
245  obsGPS2->getMsgByClassPtr<gnss::Message_NV_OEM6_INSPVAS>();
246  EXPECT_TRUE(msg2 != nullptr);
247  if (!msg2) return;
248  EXPECT_NEAR(msg2->fields.roll, 4.10511, 1e-4);
249 }
250 
251 TEST(CGPSInterface, parse_NMEA_stream)
252 {
253  auto buf = std::make_shared<mrpt::io::CMemoryStream>();
254  {
255  // Data captured with a uBlox8 (University of Almeria, 2020)
256  const uint8_t sample_nmea_gps[] = {
257  0x31, 0x33, 0x2c, 0x32, 0x34, 0x2c, 0x33, 0x30, 0x2c, 0x32, 0x36,
258  0x34, 0x2c, 0x33, 0x30, 0x2c, 0x32, 0x38, 0x2c, 0x34, 0x35, 0x2c,
259  0x30, 0x36, 0x30, 0x2c, 0x31, 0x37, 0x2c, 0x33, 0x30, 0x2c, 0x31,
260  0x38, 0x2c, 0x30, 0x35, 0x39, 0x2c, 0x33, 0x31, 0x2c, 0x33, 0x36,
261  0x2c, 0x33, 0x34, 0x2c, 0x31, 0x33, 0x32, 0x2c, 0x2a, 0x37, 0x37,
262  0x0a, 0x24, 0x47, 0x50, 0x47, 0x53, 0x56, 0x2c, 0x34, 0x2c, 0x34,
263  0x2c, 0x31, 0x33, 0x2c, 0x34, 0x39, 0x2c, 0x34, 0x37, 0x2c, 0x31,
264  0x36, 0x38, 0x2c, 0x2a, 0x34, 0x41, 0x0a, 0x24, 0x47, 0x4c, 0x47,
265  0x53, 0x56, 0x2c, 0x32, 0x2c, 0x31, 0x2c, 0x30, 0x36, 0x2c, 0x36,
266  0x36, 0x2c, 0x34, 0x32, 0x2c, 0x31, 0x34, 0x30, 0x2c, 0x2c, 0x36,
267  0x37, 0x2c, 0x37, 0x39, 0x2c, 0x33, 0x34, 0x37, 0x2c, 0x31, 0x30,
268  0x2c, 0x36, 0x38, 0x2c, 0x32, 0x35, 0x2c, 0x33, 0x32, 0x38, 0x2c,
269  0x32, 0x36, 0x2c, 0x37, 0x36, 0x2c, 0x32, 0x35, 0x2c, 0x30, 0x33,
270  0x34, 0x2c, 0x31, 0x31, 0x2a, 0x36, 0x38, 0x0a, 0x24, 0x47, 0x4c,
271  0x47, 0x53, 0x56, 0x2c, 0x32, 0x2c, 0x32, 0x2c, 0x30, 0x36, 0x2c,
272  0x37, 0x37, 0x2c, 0x37, 0x36, 0x2c, 0x33, 0x34, 0x33, 0x2c, 0x2c,
273  0x37, 0x38, 0x2c, 0x33, 0x39, 0x2c, 0x32, 0x33, 0x32, 0x2c, 0x31,
274  0x38, 0x2a, 0x36, 0x39, 0x0a, 0x24, 0x47, 0x4e, 0x47, 0x53, 0x54,
275  0x2c, 0x31, 0x30, 0x30, 0x33, 0x35, 0x34, 0x2e, 0x34, 0x30, 0x2c,
276  0x32, 0x35, 0x2c, 0x2c, 0x2c, 0x2c, 0x34, 0x35, 0x2c, 0x32, 0x30,
277  0x2c, 0x36, 0x31, 0x2a, 0x36, 0x33, 0x0a, 0xb5, 0x62, 0x01, 0x01,
278  0x14, 0x00, 0xb8, 0x9b, 0xc2, 0x16, 0xc1, 0x84, 0x70, 0x1e, 0x24,
279  0x55, 0xb8, 0xfe, 0xb0, 0xee, 0xa9, 0x16, 0x8e, 0x19, 0x00, 0x00,
280  0x47, 0xb2, 0xb5, 0x62, 0x01, 0x12, 0x24, 0x00, 0xb8, 0x9b, 0xc2,
281  0x16, 0xee, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xea, 0xff,
282  0xff, 0xff, 0x1d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x99,
283  0xa6, 0x14, 0x02, 0x08, 0x01, 0x00, 0x00, 0x80, 0xa8, 0x12, 0x01,
284  0xf3, 0xeb, 0x24, 0x47, 0x4e, 0x52, 0x4d, 0x43, 0x2c, 0x31, 0x30,
285  0x30, 0x33, 0x35, 0x34, 0x2e, 0x36, 0x30, 0x2c, 0x41, 0x2c, 0x33,
286  0x36, 0x34, 0x39, 0x2e, 0x37, 0x38, 0x39, 0x32, 0x39, 0x2c, 0x4e,
287  0x2c, 0x30, 0x30, 0x32, 0x32, 0x34, 0x2e, 0x34, 0x36, 0x38, 0x36,
288  0x33, 0x2c, 0x57, 0x2c, 0x30, 0x2e, 0x33, 0x37, 0x38, 0x2c, 0x33,
289  0x34, 0x39, 0x2e, 0x30, 0x38, 0x2c, 0x32, 0x37, 0x30, 0x32, 0x32,
290  0x30, 0x2c, 0x2c, 0x2c, 0x41, 0x2a, 0x36, 0x36, 0x0a, 0x24, 0x47,
291  0x4e, 0x47, 0x4e, 0x53, 0x2c, 0x31, 0x30, 0x30, 0x33, 0x35, 0x34,
292  0x2e, 0x36, 0x30, 0x2c, 0x33, 0x36, 0x34, 0x39, 0x2e, 0x37, 0x38,
293  0x39, 0x32, 0x39, 0x2c, 0x4e, 0x2c, 0x30, 0x30, 0x32, 0x32, 0x34,
294  0x2e, 0x34, 0x36, 0x38, 0x36, 0x33, 0x2c, 0x57, 0x2c, 0x41, 0x4e,
295  0x2c, 0x30, 0x34, 0x2c, 0x32, 0x2e, 0x33, 0x31, 0x2c, 0x35, 0x35,
296  0x2e, 0x34, 0x2c, 0x34, 0x36, 0x2e, 0x32, 0x2c, 0x2c, 0x2a, 0x34,
297  0x45, 0x0a, 0x24, 0x47, 0x4e, 0x47, 0x53, 0x41, 0x2c, 0x4d, 0x2c,
298  0x33, 0x2c, 0x31, 0x35, 0x2c, 0x32, 0x34, 0x2c, 0x33, 0x30, 0x2c,
299  0x31, 0x37, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
300  0x34, 0x2e, 0x32, 0x31, 0x2c, 0x32, 0x2e, 0x33, 0x31, 0x2c, 0x33,
301  0x2e, 0x35, 0x32, 0x2a, 0x31, 0x34, 0x0a, 0x24, 0x47, 0x4e, 0x47,
302  0x53, 0x41, 0x2c, 0x4d, 0x2c, 0x33, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
303  0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x34, 0x2e, 0x32,
304  0x31, 0x2c, 0x32, 0x2e, 0x33, 0x31, 0x2c, 0x33, 0x2e, 0x35, 0x32,
305  0x2a, 0x31, 0x33, 0x0a, 0x24, 0x47, 0x50, 0x47, 0x53, 0x56, 0x2c,
306  0x34, 0x2c, 0x31, 0x2c, 0x31, 0x33, 0x2c, 0x30, 0x35, 0x2c, 0x33,
307  0x36, 0x2c, 0x31, 0x38, 0x32, 0x2c, 0x32, 0x30, 0x2c, 0x31, 0x32,
308  0x2c, 0x30, 0x33, 0x2c, 0x32, 0x30, 0x32, 0x2c, 0x2c, 0x31, 0x33,
309  0x2c, 0x36, 0x39, 0x2c, 0x30, 0x34, 0x36, 0x2c, 0x31, 0x32, 0x2c,
310  0x31, 0x35, 0x2c, 0x36, 0x31, 0x2c, 0x33, 0x32, 0x31, 0x2c, 0x32,
311  0x39, 0x2a, 0x37, 0x33, 0x0a, 0x24, 0x47, 0x50, 0x47, 0x53, 0x56,
312  0x2c, 0x34, 0x2c, 0x32, 0x2c, 0x31, 0x33, 0x2c, 0x31, 0x37, 0x2c,
313  0x31, 0x31, 0x2c, 0x31, 0x30, 0x38, 0x2c, 0x32, 0x38, 0x2c, 0x31,
314  0x39, 0x2c, 0x30, 0x34, 0x2c, 0x31, 0x33, 0x31, 0x2c, 0x31, 0x36,
315  0x2c, 0x32, 0x30, 0x2c, 0x31, 0x33, 0x2c, 0x33, 0x31, 0x38, 0x2c,
316  0x31, 0x37, 0x2c, 0x32, 0x31, 0x2c, 0x30, 0x33, 0x2c, 0x32, 0x38,
317  0x38, 0x2c, 0x2a, 0x37, 0x45, 0x0a, 0x24, 0x47, 0x50, 0x47, 0x53,
318  0x56, 0x2c, 0x34, 0x2c, 0x33, 0x2c, 0x31, 0x33, 0x2c, 0x32, 0x34,
319  0x2c, 0x33, 0x30, 0x2c, 0x32, 0x36, 0x34, 0x2c, 0x33, 0x30, 0x2c,
320  0x32, 0x38, 0x2c, 0x34, 0x35, 0x2c, 0x30, 0x36, 0x30, 0x2c, 0x31,
321  0x37, 0x2c, 0x33, 0x30, 0x2c, 0x31, 0x38, 0x2c, 0x30, 0x35, 0x39,
322  0x2c, 0x33, 0x31, 0x2c, 0x33, 0x36, 0x2c, 0x33, 0x34, 0x2c, 0x31,
323  0x33, 0x32, 0x2c, 0x2a, 0x37, 0x37, 0x0a, 0x24, 0x47, 0x50, 0x47,
324  0x53, 0x56, 0x2c, 0x34, 0x2c, 0x34, 0x2c, 0x31, 0x33, 0x2c, 0x34,
325  0x39, 0x2c, 0x34, 0x37, 0x2c, 0x31, 0x36, 0x38, 0x2c, 0x2a, 0x34,
326  0x41, 0x0a, 0x24, 0x47, 0x4c, 0x47, 0x53, 0x56, 0x2c, 0x32, 0x2c,
327  0x31, 0x2c, 0x30, 0x36, 0x2c, 0x36, 0x36, 0x2c, 0x34, 0x32, 0x2c,
328  0x31, 0x34, 0x30, 0x2c, 0x2c, 0x36, 0x37, 0x2c, 0x37, 0x39, 0x2c,
329  0x33, 0x34, 0x37, 0x2c, 0x31, 0x31, 0x2c, 0x36, 0x38, 0x2c, 0x32,
330  0x35, 0x2c, 0x33, 0x32, 0x38, 0x2c, 0x32, 0x36, 0x2c, 0x37, 0x36,
331  0x2c, 0x32, 0x35, 0x2c, 0x30, 0x33, 0x34, 0x2c, 0x31, 0x31, 0x2a,
332  0x36, 0x39, 0x0a, 0x24, 0x47, 0x4c, 0x47, 0x53, 0x56, 0x2c, 0x32,
333  0x2c, 0x32, 0x2c, 0x30, 0x36, 0x2c, 0x37, 0x37, 0x2c, 0x37, 0x36,
334  0x2c, 0x33, 0x34, 0x33, 0x2c, 0x2c, 0x37, 0x38, 0x2c, 0x33, 0x39,
335  0x2c, 0x32, 0x33, 0x32, 0x2c, 0x31, 0x38, 0x2a, 0x36, 0x39, 0x0a,
336  0x24, 0x47, 0x4e, 0x47, 0x53, 0x54, 0x2c, 0x31, 0x30, 0x30, 0x33,
337  0x35, 0x34, 0x2e, 0x36, 0x30, 0x2c, 0x32, 0x35, 0x2c, 0x2c, 0x2c,
338  0x2c, 0x33, 0x36, 0x2c, 0x31, 0x37, 0x2c, 0x35, 0x32, 0x2a, 0x36,
339  0x31, 0x0a, 0xb5, 0x62, 0x01, 0x01, 0x14, 0x00, 0x80, 0x9c, 0xc2,
340  0x16, 0xc6, 0x84, 0x70, 0x1e, 0x22, 0x55, 0xb8, 0xfe, 0xaf, 0xee,
341  0xa9, 0x16, 0x90, 0x19, 0x00, 0x00, 0x14, 0x9d, 0xb5, 0x62, 0x01,
342  0x12, 0x24, 0x00, 0x80, 0x9c, 0xc2, 0x16, 0xee, 0xff, 0xff, 0xff,
343  0xf9, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff, 0x1d, 0x00, 0x00,
344  0x00, 0x13, 0x00, 0x00, 0x00, 0x99, 0xa6, 0x14, 0x02, 0x14, 0x02,
345  0x00, 0x00, 0x80, 0xa8, 0x12, 0x01, 0xc9, 0x95, 0x24, 0x47, 0x4e,
346  0x52, 0x4d, 0x43, 0x2c, 0x31, 0x30, 0x30, 0x33, 0x35, 0x34, 0x2e,
347  0x38, 0x30, 0x2c, 0x56, 0x2c, 0x33, 0x36, 0x34, 0x39, 0x2e};
348  const unsigned int sample_nmea_gps_len = 1000;
349  buf->Write(sample_nmea_gps, sample_nmea_gps_len);
350  buf->Seek(0);
351  }
352 
353  CGPSInterface gps;
354  gps.bindStream(buf);
355 
356  gps.initialize();
357  gps.doProcess();
358 
360  gps.getObservations(obss);
361 
362  EXPECT_EQ(obss.size(), 3U);
363  if (obss.empty()) return;
364 
365  auto itObs = obss.begin();
366  auto obsGPS1 = mrpt::ptr_cast<CObservationGPS>::from(itObs->second);
367  ++itObs;
368  auto obsGPS2 = mrpt::ptr_cast<CObservationGPS>::from(itObs->second);
369  ++itObs;
370  auto obsGPS3 = mrpt::ptr_cast<CObservationGPS>::from(itObs->second);
371 
372  EXPECT_TRUE(obsGPS1);
373  EXPECT_TRUE(obsGPS2);
374  EXPECT_TRUE(obsGPS3);
375 
376  const auto* msg1 = obsGPS1->getMsgByClassPtr<gnss::Message_NMEA_GSA>();
377  EXPECT_TRUE(msg1 != nullptr);
378  if (!msg1) return;
379  EXPECT_EQ(msg1->fields.PRNs[0][0], '1');
380  EXPECT_EQ(msg1->fields.PRNs[0][1], '5');
381  EXPECT_NEAR(msg1->fields.HDOP, 2.31, 0.1);
382 
383  const auto* msg2 = obsGPS2->getMsgByClassPtr<gnss::Message_NMEA_GSA>();
384  EXPECT_TRUE(msg2 != nullptr);
385 
386  const auto* msg3 = obsGPS3->getMsgByClassPtr<gnss::Message_NMEA_RMC>();
387  EXPECT_TRUE(msg3 != nullptr);
388  if (!msg3) return;
389  EXPECT_NEAR(msg3->fields.longitude_degrees, -2.407810500, 0.0001);
390  EXPECT_NEAR(msg3->fields.latitude_degrees, 36.829821500, 0.0001);
391 }
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
content_t fields
Message content, accesible by individual fields.
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial port or from any input stre...
MSG_CLASS * getMsgByClassPtr()
Like CObservationGPS::getMsgByClass() but returns a nullptr pointer if message is not found...
EXPECT_TRUE(mrpt::system::fileExists(ini_fil))
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
TEST(CGPSInterface, parse_NMEA_GGA)
content_t fields
Message content, accesible by individual fields.
Contains classes for various device interfaces.
void getObservations(TListObservations &lstObjects)
Returns a list of enqueued objects, emptying it (thread-safe).
content_t fields
Message content, accesible by individual fields.
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
STL namespace.
double altitude_meters
The measured altitude, in meters (A).
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
content_t fields
Message content, accesible by individual fields.
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
This namespace contains representation of robot actions and observations.
static bool parse_NMEA(const std::string &cmd_line, mrpt::obs::CObservationGPS &out_obs, const bool verbose=false)
Parses one line of NMEA data from a GPS receiver, and writes the recognized fields (if any) into an o...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::multimap< mrpt::system::TTimeStamp, mrpt::serialization::CSerializable::Ptr > TListObservations
EXPECT_EQ(out.image_pair_was_used.size(), NUM_IMGS)
content_t fields
Message content, accesible by individual fields.
virtual void initialize()
This method can or cannot be implemented in the derived class, depending on the need for it...
static CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
Definition: CObject.h:356
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
EXPECT_NEAR(out.cam_params.rightCameraPose.x, 0.1194, 0.005)
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
void bindStream(const std::shared_ptr< mrpt::io::CStream > &external_stream, const std::shared_ptr< std::mutex > &csOptionalExternalStream=std::shared_ptr< std::mutex >())
This enforces the use of a given user stream, instead of trying to open the serial port set in this c...



Page generated by Doxygen 1.8.14 for MRPT 2.0.4 Git: 33de1d0ad Sat Jun 20 11:02:42 2020 +0200 at sáb jun 20 17:35:17 CEST 2020