MRPT  2.0.3
CGPSInterface.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 "hwdrivers-precomp.h" // Precompiled headers
11 
14 #include <mrpt/system/filesystem.h>
15 #include <mrpt/system/os.h>
16 
17 #include <iostream>
18 #include <list>
19 #include <mutex>
20 #include <thread>
21 
22 using namespace mrpt::hwdrivers;
23 using namespace mrpt::obs;
24 using namespace mrpt::system;
25 using namespace mrpt::comms;
26 using namespace std;
27 
29 
31 {
32  std::list<CGPSInterface::ptr_parser_t> all_parsers;
33 
34  static const TParsersRegistry& getInstance()
35  {
36  static TParsersRegistry reg;
37  return reg;
38  }
39 
40  private:
42  {
43  all_parsers.push_back(&CGPSInterface::implement_parser_NMEA);
44  all_parsers.push_back(&CGPSInterface::implement_parser_NOVATEL_OEM6);
45  }
46 };
47 
48 /* -----------------------------------------------------
49  Constructor
50  ----------------------------------------------------- */
52  : mrpt::system::COutputLogger("CGPSInterface"),
53  m_customInit(),
54  m_rx_buffer(0x10000),
55  m_raw_dump_file_prefix(),
56  m_COMname(),
57  m_last_timestamp(INVALID_TIMESTAMP),
58  m_JAVAD_rtk_src_port(),
59  m_JAVAD_rtk_format("cmr")
60 {
61  m_sensorLabel = "GPS";
62 }
63 
64 /* -----------------------------------------------------
65  loadConfig_sensorSpecific
66  ----------------------------------------------------- */
68  const mrpt::config::CConfigFileBase& configSource,
69  const std::string& iniSection)
70 {
72  iniSection, "parser", m_parser, false /*Allow default values*/);
73  m_raw_dump_file_prefix = configSource.read_string(
74  iniSection, "raw_dump_file_prefix", m_raw_dump_file_prefix,
75  false /*Allow default values*/);
76 
77 #ifdef _WIN32
78  m_COMname =
79  configSource.read_string(iniSection, "COM_port_WIN", m_COMname, true);
80 #else
81  m_COMname =
82  configSource.read_string(iniSection, "COM_port_LIN", m_COMname, true);
83 #endif
84 
85  m_COMbauds =
86  configSource.read_int(iniSection, "baudRate", m_COMbauds, true);
88  iniSection, "sensor_label_append_msg_type", m_sensorLabelAppendMsgType);
89 
90  // legacy custom cmds:
91  m_customInit =
92  configSource.read_string(iniSection, "customInit", m_customInit, false);
93 
94  // new custom cmds:
95  m_custom_cmds_delay = configSource.read_float(
96  iniSection, "custom_cmds_delay", m_custom_cmds_delay);
97  m_custom_cmds_append_CRLF = configSource.read_bool(
98  iniSection, "custom_cmds_append_CRLF", m_custom_cmds_append_CRLF);
99  // Load as many strings as found on the way:
100  m_setup_cmds.clear();
101  for (int i = 1; true; i++)
102  {
103  std::string sLine = configSource.read_string(
104  iniSection, mrpt::format("setup_cmd%i", i), std::string());
105  sLine = mrpt::system::trim(sLine);
106  if (sLine.empty()) break;
107  m_setup_cmds.push_back(sLine);
108  }
109 
110  m_shutdown_cmds.clear();
111  for (int i = 1; true; i++)
112  {
113  std::string sLine = configSource.read_string(
114  iniSection, mrpt::format("shutdown_cmd%i", i), std::string());
115  sLine = mrpt::system::trim(sLine);
116  if (sLine.empty()) break;
117  m_shutdown_cmds.push_back(sLine);
118  }
119 
121  configSource.read_float(iniSection, "pose_x", 0),
122  configSource.read_float(iniSection, "pose_y", 0),
123  configSource.read_float(iniSection, "pose_z", 0),
124  DEG2RAD(configSource.read_float(iniSection, "pose_yaw", 0)),
125  DEG2RAD(configSource.read_float(iniSection, "pose_pitch", 0)),
126  DEG2RAD(configSource.read_float(iniSection, "pose_roll", 0)));
127 
128  m_JAVAD_rtk_src_port = configSource.read_string(
129  iniSection, "JAVAD_rtk_src_port", m_JAVAD_rtk_src_port);
130  m_JAVAD_rtk_src_baud = configSource.read_int(
131  iniSection, "JAVAD_rtk_src_baud", m_JAVAD_rtk_src_baud);
132  m_JAVAD_rtk_format = configSource.read_string(
133  iniSection, "JAVAD_rtk_format", m_JAVAD_rtk_format);
134 
135  m_topcon_useAIMMode = configSource.read_bool(
136  iniSection, "JAVAD_useAIMMode", m_topcon_useAIMMode);
138  1.0 / configSource.read_double(
139  iniSection, "outputRate", m_topcon_data_period);
140 }
141 
143 
145 {
146  m_parser = parser;
147 }
150  const std::shared_ptr<mrpt::io::CStream>& external_stream,
151  const std::shared_ptr<std::mutex>& csOptionalExternalStream)
152 {
154  m_data_stream = external_stream;
155  m_data_stream_cs = csOptionalExternalStream ? csOptionalExternalStream
157 }
158 void CGPSInterface::setSetupCommandsDelay(const double delay_secs)
159 {
160  m_custom_cmds_delay = delay_secs;
161 }
163 {
164  return m_custom_cmds_delay;
165 }
166 void CGPSInterface::setSetupCommands(const std::vector<std::string>& cmds)
167 {
168  m_setup_cmds = cmds;
169 }
170 const std::vector<std::string>& CGPSInterface::getSetupCommands() const
171 {
172  return m_setup_cmds;
173 }
174 void CGPSInterface::setShutdownCommands(const std::vector<std::string>& cmds)
175 {
176  m_shutdown_cmds = cmds;
177 }
178 const std::vector<std::string>& CGPSInterface::getShutdownCommands() const
179 {
180  return m_shutdown_cmds;
181 }
183 {
184  m_custom_cmds_append_CRLF = enable;
185 }
187 {
189 }
190 
191 /* -----------------------------------------------------
192  setSerialPortName
193 ----------------------------------------------------- */
194 void CGPSInterface::setSerialPortName(const std::string& COM_port)
195 {
196  // Dont allow changing the serial port if:
199  "Cannot change serial port name: an external stream has been "
200  "already bound manually.");
201 
202  if (m_data_stream)
203  {
204  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
205  auto serial =
206  dynamic_cast<mrpt::comms::CSerialPort*>(m_data_stream.get());
207  if (serial && serial->isOpen())
209  "Cannot change serial port name when it is already open");
210  }
211 
212  // OK:
213  m_COMname = COM_port;
214 }
215 
216 /* -----------------------------------------------------
217  getSerialPortName
218 ----------------------------------------------------- */
219 std::string CGPSInterface::getSerialPortName() const { return m_COMname; }
220 /* -----------------------------------------------------
221  tryToOpenTheCOM
222 ----------------------------------------------------- */
224 {
225  // If this is the first use of the COM port, create it:
226  if (!m_data_stream)
227  {
228  m_data_stream = std::make_shared<mrpt::comms::CSerialPort>();
231  }
232 
233  auto serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
234  if (serial)
235  {
236  {
237  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
238  if (serial->isOpen()) return true; // Already open
239 
240  if (m_verbose)
241  cout << "[CGPSInterface] Opening " << m_COMname << " @ "
242  << m_COMbauds << endl;
243  }
244  try
245  {
246  serial->open(m_COMname);
247  // Config:
248  serial->setConfig(m_COMbauds, 0, 8, 1);
249  serial->setTimeouts(1, 0, 1, 1, 1);
250 
251  // Do extra initialization?
253  {
254  serial->close();
255  return false;
256  }
257  return true; // All OK
258  }
259  catch (const std::exception& e)
260  {
261  std::cerr << "[CGPSInterface::tryToOpenTheCOM] Error opening or "
262  "configuring serial port:"
263  << std::endl
264  << e.what();
265  serial->close();
266  return false;
267  }
268  } // end of this is a serial port
269 
270  return true; // All OK
271 }
272 
273 /* -----------------------------------------------------
274  isGPS_connected
275 ----------------------------------------------------- */
277 /* -----------------------------------------------------
278  doProcess
279 ----------------------------------------------------- */
281 {
282  // Is the COM open?
283  if (!tryToOpenTheCOM())
284  {
285  m_state = ssError;
286  THROW_EXCEPTION("Could not open the input stream");
287  }
288  ASSERT_(m_data_stream != nullptr);
289  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
290  auto* stream_tcpip = dynamic_cast<CClientTCPSocket*>(m_data_stream.get());
291 
292  // Read as many bytes as available:
293  uint8_t buf[0x1000];
294  const size_t to_read =
295  std::min(m_rx_buffer.available() - 1, sizeof(buf) - 1);
296  try
297  {
298  size_t nRead = 0;
299  if (to_read > 0)
300  {
301  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
302  if (stream_tcpip)
303  {
304  nRead = stream_tcpip->readAsync(buf, to_read, 100, 10);
305  }
306  else if (stream_serial)
307  {
308  nRead = stream_serial->Read(buf, to_read);
309  }
310  else
311  {
312  nRead = m_data_stream->Read(buf, to_read);
313  }
314  }
315 
316  if (nRead) m_rx_buffer.push_many(buf, nRead);
317 
318  // Also dump to raw file:
319  if (!m_raw_dump_file_prefix.empty() &&
321  {
322  // 1st time open:
324  mrpt::system::timestampToParts(now(), parts, true);
325  string sFilePostfix = "_";
326  sFilePostfix += format(
327  "%04u-%02u-%02u_%02uh%02um%02us", (unsigned int)parts.year,
328  (unsigned int)parts.month, (unsigned int)parts.day,
329  (unsigned int)parts.hour, (unsigned int)parts.minute,
330  (unsigned int)parts.second);
331  const string sFileName =
334  string(".gps");
335 
336  if (m_verbose)
337  std::cout << "[CGPSInterface] Creating RAW dump file: `"
338  << sFileName << "`\n";
339  m_raw_output_file.open(sFileName);
340  }
341  if (nRead && m_raw_output_file.fileOpenCorrectly())
342  {
343  m_raw_output_file.Write(buf, nRead);
344  }
345  }
346  catch (std::exception&)
347  {
348  // ERROR:
350  "[CGPSInterface::doProcess] Error reading stream of data: Closing "
351  "communications\n");
352  if (stream_serial)
353  {
354  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
355  stream_serial->close();
356  }
357  m_GPS_comsWork = false;
358  return;
359  }
360 
361  // Try to parse incomming data as messages:
362  parseBuffer();
363 
364  // Decide whether to push out a new observation in old legacy mode.
365  if (!m_customInit.empty())
366  { // "Advanced" (RTK,mmGPS) device (kept for backwards-compatibility)
367  bool do_append_obs = false;
368  // FAMD
369  // Append observation if:
370  // 0. the timestamp seems to be correct!
371  // 1. it contains both synched GGA and RMC data
372  // 2. it contains only GGA or RMC but the next one is not synched with
373  // it
375  {
376  if (m_verbose)
377  cout << "[CGPSInterface] Initial timestamp: "
380  << endl;
381  // Check if the initial timestamp seems to be OK (not a spurio one)
382  TTimeStamp tmNow = mrpt::system::now();
383  const double tdif = mrpt::system::timeDifference(
385  if (tdif >= 0 && tdif < 7500 /*Up to two hours*/)
387  else
388  {
389  if (m_verbose)
390  cout << "[CGPSInterface] Warning: The initial timestamp "
391  "seems to be wrong! : "
392  << tdif << endl;
393  }
394  } // end-if
395  else
396  {
397  const double time_diff = mrpt::system::timeDifference(
399  if (time_diff < 0 || time_diff > 300) // Assert that the current
400  // timestamp is after the
401  // previous one and not more
402  // than 5 minutes later ->
403  // remove spurious
404  {
405  if (m_verbose)
406  cout << "[CGPSInterface ] Bad timestamp difference" << endl;
407  return;
408  }
409 
410  if (time_diff - m_topcon_data_period > 0.25 * m_topcon_data_period)
411  {
412  if (m_verbose)
413  cout << "[CGPSInterface] WARNING: According to the "
414  "timestamps, we probably skipped one frame!"
415  << endl;
416  }
417 
418  // a. These GPS data have both synched RMC and GGA data
419  // don't append observation until we have both data
420  do_append_obs =
423  } // end-else
424 
425  if (do_append_obs) flushParsedMessagesNow();
426  }
427 }
428 
429 /** Queue out now the messages in \a m_just_parsed_messages, leaving it empty */
430 
432 {
433  // Generic observation data:
438  else
440  // Add observation to the output queue:
441  CObservationGPS::Ptr newObs = std::make_shared<CObservationGPS>();
442  m_just_parsed_messages.swap(*newObs);
446 
447  // And this means the comms works:
448  m_GPS_comsWork = true;
449  m_state = ssWorking;
450 }
451 
452 /* -----------------------------------------------------
453  parseBuffer
454 ----------------------------------------------------- */
456 {
457  if (m_parser == CGPSInterface::NONE) return; // Dont try to parse data
458 
459  // Only one parser selected?
460  ptr_parser_t parser_ptr = nullptr;
461  switch (m_parser)
462  {
463  case CGPSInterface::NMEA:
465  break;
468  break;
469  case CGPSInterface::AUTO:
470  break; // Leave it as NULL
471  default:
472  throw std::runtime_error("[CGPSInterface] Unknown parser!");
473  };
474  if (parser_ptr)
475  {
476  // Use only one parser ----------
477  size_t min_bytes;
478  do
479  {
480  if (!(*this.*parser_ptr)(min_bytes))
481  {
482  if (m_rx_buffer.size() != 0)
483  m_rx_buffer.pop(); // Not the start of a frame, skip 1 byte
484  }
485  if (m_customInit.empty() /* If we are not in old legacy mode */ &&
488  } while (m_rx_buffer.size() >= min_bytes);
489  } // end one parser mode ----------
490  else
491  {
492  // AUTO mode --------
493  const std::list<CGPSInterface::ptr_parser_t>& all_parsers =
495 
496  size_t global_min_bytes_max = 0;
497  do
498  {
499  bool all_parsers_want_to_skip = true;
500  for (auto all_parser : all_parsers)
501  {
502  parser_ptr = all_parser;
503  size_t this_parser_min_bytes;
504  if ((*this.*parser_ptr)(this_parser_min_bytes))
505  all_parsers_want_to_skip = false;
506  mrpt::keep_max(global_min_bytes_max, this_parser_min_bytes);
507  }
508 
509  if (all_parsers_want_to_skip && m_rx_buffer.size() != 0)
510  m_rx_buffer.pop(); // Not the start of a frame, skip 1 byte
511 
512  if (m_customInit.empty() /* If we are not in old legacy mode */ &&
515  } while (m_rx_buffer.size() >= global_min_bytes_max);
516  } // end AUTO mode ----
517 }
518 
519 /* -----------------------------------------------------
520  JAVAD_sendMessage
521 ----------------------------------------------------- */
522 void CGPSInterface::JAVAD_sendMessage(const char* str, bool waitForAnswer)
523 {
524  if (!str) return;
525  const size_t len = strlen(str);
526  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
527  if (!stream_serial) return;
528 
529  size_t written;
530 
531  {
532  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
533  written = stream_serial->Write(str, len);
534  }
535 
536  if (m_verbose) std::cout << "[CGPSInterface] TX: " << str;
537 
538  if (written != len)
539  throw std::runtime_error(
540  format("Error sending command: '%s'", str).c_str());
541  std::this_thread::sleep_for(5ms);
542 
543  if (!waitForAnswer) return;
544 
545  std::this_thread::sleep_for(200ms);
546  char buf[200];
547  buf[0] = '\0';
548 
549  int bad_counter = 0;
550  while (bad_counter < 10)
551  {
552  size_t nRead;
553  {
554  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
555  written = stream_serial->Write(str, len);
556  nRead = stream_serial->Read(buf, sizeof(buf));
557  }
558 
559  if (m_verbose) std::cout << "[CGPSInterface] RX: " << buf << std::endl;
560 
561  if (nRead < 3)
562  throw std::runtime_error(format(
563  "ERROR: Invalid response '%s' for command '%s'", buf, str));
564 
565  if (nRead >= 3 && buf[0] == 'R' && buf[1] == 'E')
566  return; // Ok!
567  else
568  ++bad_counter;
569  }
570  throw std::runtime_error(
571  format("ERROR: Invalid response '%s' for command '%s'", buf, str));
572 }
573 
575 {
576  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
577 
578  if (stream_serial && !stream_serial->isOpen()) return false;
579 
580  // Send commands:
581  for (const auto& m_shutdown_cmd : m_shutdown_cmds)
582  {
583  if (m_verbose)
584  cout << "[CGPSInterface] TX shutdown command: `" << m_shutdown_cmd
585  << "`\n";
586 
587  std::string sTx = m_shutdown_cmd;
588  if (m_custom_cmds_append_CRLF) sTx += std::string("\r\n");
589  try
590  {
591  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
592  m_data_stream->Write(&sTx[0], sTx.size());
593  }
594  catch (...)
595  {
596  return false; // On any I/O error
597  }
598 
599  std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(
600  m_custom_cmds_delay * 1000));
601  }
602  return true;
603 }
604 
605 /* -----------------------------------------------------
606  OnConnectionEstablished
607 ----------------------------------------------------- */
609 {
610  m_last_GGA.clear(); // On comms reset, empty this cache
612 
613  // Legacy behavior:
614  if (!os::_strcmpi(m_customInit.c_str(), "JAVAD") ||
615  !os::_strcmpi(m_customInit.c_str(), "TOPCON"))
616  {
618  }
619 
620  // Purge input:
621  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
622  if (stream_serial)
623  {
624  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
625  stream_serial->purgeBuffers();
626  }
627 
628  // New behavior: Send generic commands set-up by the user in the config
629  // file.
630 
631  // Send commands:
632  for (const auto& m_setup_cmd : m_setup_cmds)
633  {
634  if (m_verbose)
635  cout << "[CGPSInterface] TX setup command: `" << m_setup_cmd
636  << "`\n";
637 
638  std::string sTx = m_setup_cmd;
639  if (m_custom_cmds_append_CRLF) sTx += std::string("\r\n");
640 
641  try
642  {
643  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
644  m_data_stream->Write(&sTx[0], sTx.size());
645  }
646  catch (const std::exception& e)
647  {
648  std::cerr << "[CGPSInterface::OnConnectionEstablished] Error "
649  "sending setup cmds: "
650  << e.what() << std::endl;
651  return false;
652  }
653  std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(
654  m_custom_cmds_delay * 1000));
655  }
656  std::this_thread::sleep_for(
657  std::chrono::duration<double, std::milli>(m_custom_cmds_delay * 1000));
658  return true;
659 }
660 
662 {
663  MRPT_START
664  if (!os::_strcmpi(m_customInit.c_str(), "JAVAD") ||
665  !os::_strcmpi(m_customInit.c_str(), "TOPCON"))
666  {
667  // Stop messaging:
668  JAVAD_sendMessage("%%dm\r\n", false);
669  std::this_thread::sleep_for(500ms);
670  JAVAD_sendMessage("%%dm\r\n", false);
671  std::this_thread::sleep_for(1000ms);
672 
673  // Purge input:
674  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
675  if (stream_serial)
676  {
677  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
678  stream_serial->purgeBuffers();
679  }
680 
681  JAVAD_sendMessage("%%set,/par/cur/term/imode,cmd\r\n"); // set the
682  // current port
683  // in command
684  // mode
685  return true;
686  }
687  else
688  return true;
689  MRPT_END
690 } // end-unsetJAVAD_AIM_mode
691 
693 {
694  MRPT_START
695  if (!os::_strcmpi(m_customInit.c_str(), "JAVAD") ||
696  !os::_strcmpi(m_customInit.c_str(), "TOPCON"))
697  {
699  format("%%%%set,/par%s/imode,cmd\r\n", m_JAVAD_rtk_src_port.c_str())
700  .c_str()); // set the port in command mode
702  "%%set,/par/cur/term/jps/0,{nscmd,37,n,\"\"}\r\n"); // any command
703  // starting
704  // with % will
705  // be treated
706  // as normal
707 
708  ASSERT_(!m_JAVAD_rtk_format.empty());
709  cout << "Formato de correcciones para GR3: " << m_JAVAD_rtk_format
710  << endl;
711  if (m_JAVAD_rtk_format == "cmr")
712  {
714  format(
715  "%%%%set,/par/cur/term/jps/1,{cmr,-1,y,%s}\r\n",
716  m_JAVAD_rtk_src_port.c_str())
717  .c_str()); // set corrections type CMR or CMR+
718  JAVAD_sendMessage("%%set,/par/cur/term/jps/2,{none,-1,n,\"\"}\r\n");
720  "%%%%set,/par%s/imode,cmr\r\n",
721  m_JAVAD_rtk_src_port.c_str())
722  .c_str());
723  }
724  else if (m_JAVAD_rtk_format == "rtcm")
725  {
727  format(
728  "%%%%set,/par/cur/term/jps/1,{rtcm,-1,y,%s}\r\n",
729  m_JAVAD_rtk_src_port.c_str())
730  .c_str()); // set corrections type RTCM
731  JAVAD_sendMessage("%%set,/par/cur/term/jps/2,{none,-1,n,\"\"}\r\n");
733  "%%%%set,/par%s/imode,rtcm\r\n",
734  m_JAVAD_rtk_src_port.c_str())
735  .c_str());
736  }
737  else if (m_JAVAD_rtk_format == "rtcm3")
738  {
740  format(
741  "%%%%set,/par/cur/term/jps/1,{rtcm3,-1,y,%s}\r\n",
742  m_JAVAD_rtk_src_port.c_str())
743  .c_str()); // set corrections type RTCM 3.x
744  JAVAD_sendMessage("%%set,/par/cur/term/jps/2,{none,-1,n,\"\"}\r\n");
746  "%%%%set,/par%s/imode,rtcm3\r\n",
747  m_JAVAD_rtk_src_port.c_str())
748  .c_str());
749  }
750  else
751  {
752  cout << "Unknown RTK corrections format. Only supported: CMR, RTCM "
753  "or RTCM3"
754  << endl;
755  return false;
756  }
757  JAVAD_sendMessage("%%set,/par/cur/term/imode,jps\r\n"); // sets current
758  // port into
759  // "JPS" mode
760 
761  return true;
762 
763  } // end-if
764  else
765  return true;
766  MRPT_END
767 } // end-setJAVAD_AIM_mode
768 
769 std::string CGPSInterface::getLastGGA(bool reset)
770 {
771  std::string ret = m_last_GGA;
772  if (reset) m_last_GGA.clear();
773  return ret;
774 }
775 
777 {
778  // Stop messaging:
779  JAVAD_sendMessage("%%dm\r\n", false);
780  std::this_thread::sleep_for(500ms);
781  JAVAD_sendMessage("%%dm\r\n", false);
782  std::this_thread::sleep_for(1000ms);
783 
784  // Purge input:
785  auto* stream_serial = dynamic_cast<CSerialPort*>(m_data_stream.get());
786  if (stream_serial)
787  {
788  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
789  stream_serial->purgeBuffers();
790  }
791 
792  // Configure RTK mode and source:
793  if (m_verbose) cout << "[CGPSInterface] Configure RTK options" << endl;
794 
795  if (!m_JAVAD_rtk_src_port.empty())
796  {
797  const int elevation_mask = 5; // Degs
798 
800  format("%%%%set,/par/lock/elm,%i\r\n", elevation_mask)
801  .c_str()); // Set elevation mask to track satellites
803  "%%set,/par/base/mode/,off\r\n"); // Set Base Mode off
804  JAVAD_sendMessage("%%set,/par/pos/pd/period,1.0\r\n"); // Differential
805  // Correction
806  // Interval
807  // JAVAD_sendMessage("%%set,hd/mode,off\r\n"); // fixed distance to rtk
808  // base: Off
809  // JAVAD_sendMessage("%%set,/par/pos/pd/hd/mode,off\r\n"); // fixed
810  // distance to rtk base: Off <-- Not working with TopCon GR3! (option
811  // disabled)
813  "%%set,/par/pos/pd/qcheck,off\r\n"); // Set Quality Checks Off
815  "%%set,/par/pos/mode/cur,pd\r\n"); // Pos Mode Phase Diff
817  "%%set,/par/pos/pd/textr,10\r\n"); // RTK Extrapolation Limit
819  "%%set,/par/pos/pd/inuse,-1\r\n"); // Set Rovers Reference Station
820  JAVAD_sendMessage("%%set,/par/pos/pd/nrs/mode,y\r\n"); // Enable
821  // Nearest
822  // Reference
823  // Station Mode
824  JAVAD_sendMessage("%%set,/par/pos/pd/mode,extrap\r\n"); // Enable
825  // EXTRAPOLATED
826  // mode in RTK
827  // corrections
828 
829  // Set Differential Correction Source
831  format(
832  "%%%%set,/par/pos/pd/port,%s\r\n", m_JAVAD_rtk_src_port.c_str())
833  .c_str());
834 
835  // Set port bauds:
839  "%%%%set,/par%s/rate,%u\r\n",
840  m_JAVAD_rtk_src_port.c_str(),
842  .c_str());
843 
844  // Set Input Mode: CMR,RTCM,...
845  if (!m_topcon_useAIMMode && !m_JAVAD_rtk_format.empty())
847  "%%%%set,/par%s/imode,%s\r\n",
848  m_JAVAD_rtk_src_port.c_str(),
849  m_JAVAD_rtk_format.c_str())
850  .c_str());
851  }
852 
853  // Start NMEA messaging:
854  // JAVAD_sendMessage("%%em,,/msg/nmea/GGA:0.2\r\n");
855  // JAVAD_sendMessage("%%em,,/msg/nmea/RMC:0.2\r\n");
856  // JAVAD_sendMessage("%%em,,/msg/jps/PS:0.2\r\n");
857 
859  {
860  if (m_verbose) cout << "[CGPSInterface] Using Advanced Input Mode";
862  if (m_verbose) cout << "... done" << endl;
863  }
865  format("%%%%em,,/msg/nmea/GGA:%.1f\r\n", m_topcon_data_period).c_str());
867  format("%%%%em,,/msg/nmea/RMC:%.1f\r\n", m_topcon_data_period)
868  .c_str()); // FAMD: 10 Hz
869 
871  {
872  if (m_verbose)
873  cout << "[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon "
874  "commands sent successfully with AIM."
875  << endl;
876  }
877  else
878  {
879  if (m_verbose)
880  cout << "[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon "
881  "commands sent successfully."
882  << endl;
883  }
884 
885  return true;
886 }
887 
888 /** Send a custom data block to the GNSS device right now. Can be used to change
889  * its behavior online as needed. */
890 bool CGPSInterface::sendCustomCommand(const void* data, const size_t datalen)
891 {
892  try
893  {
894  std::lock_guard<std::mutex> lock(*m_data_stream_cs);
895  m_data_stream->Write(data, datalen);
896  return true;
897  }
898  catch (const std::exception& e)
899  {
900  std::cerr << "[CGPSInterface::sendCustomCommand] Error sending cmd: "
901  << e.what() << std::endl;
902  return false;
903  }
904 }
os.h
mrpt::hwdrivers::CGPSInterface::m_setup_cmds
std::vector< std::string > m_setup_cmds
Definition: CGPSInterface.h:323
filesystem.h
CClientTCPSocket.h
mrpt::comms::CClientTCPSocket
A TCP socket that can be connected to a TCP server, implementing MRPT's CStream interface for passing...
Definition: CClientTCPSocket.h:34
mrpt::obs::CObservation::sensorLabel
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:62
mrpt::system::timeDifference
double timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds
Definition: datetime.h:123
mrpt::opengl::internal::data
static struct FontData data
Definition: gltext.cpp:144
mrpt::obs::CObservationGPS::sensorPose
mrpt::poses::CPose3D sensorPose
The sensor pose on the robot/vehicle.
Definition: CObservationGPS.h:78
mrpt::hwdrivers::CGPSInterface::m_data_stream_is_external
bool m_data_stream_is_external
Definition: CGPSInterface.h:273
mrpt::hwdrivers::CGPSInterface::flushParsedMessagesNow
void flushParsedMessagesNow()
Queue out now the messages in m_just_parsed_messages, leaving it empty.
Definition: CGPSInterface.cpp:431
mrpt::hwdrivers::CGPSInterface::~CGPSInterface
~CGPSInterface() override
Dtor.
Definition: CGPSInterface.cpp:142
mrpt::io::CFileOutputStream::Write
size_t Write(const void *Buffer, size_t Count) override
Introduces a pure virtual method responsible for writing to the stream.
Definition: CFileOutputStream.cpp:55
mrpt::hwdrivers::CGPSInterface::isGPS_connected
bool isGPS_connected()
Returns true if communications work, i.e.
Definition: CGPSInterface.cpp:276
mrpt::io::CFileOutputStream::open
bool open(const std::string &fileName, bool append=false)
Open the given file for write.
Definition: CFileOutputStream.cpp:31
mrpt::hwdrivers::CGPSInterface::getSerialPortName
std::string getSerialPortName() const
Get the serial port to use (COM1, ttyUSB0, etc).
Definition: CGPSInterface.cpp:219
INVALID_TIMESTAMP
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:43
mrpt::hwdrivers::CGPSInterface::m_data_stream_cs
std::shared_ptr< std::mutex > m_data_stream_cs
Definition: CGPSInterface.h:270
mrpt::hwdrivers::CGPSInterface::getSetupCommandsDelay
double getSetupCommandsDelay() const
Definition: CGPSInterface.cpp:162
mrpt::hwdrivers::CGPSInterface
A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial port or from any input stre...
Definition: CGPSInterface.h:142
mrpt::hwdrivers::CGPSInterface::CGPSInterface
CGPSInterface()
Default ctor.
Definition: CGPSInterface.cpp:51
mrpt::hwdrivers::CGPSInterface::m_topcon_AIMConfigured
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
Definition: CGPSInterface.h:341
mrpt::system::strCmp
bool strCmp(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case sensitive)
Definition: string_utils.cpp:299
mrpt::hwdrivers::CGPSInterface::m_custom_cmds_append_CRLF
bool m_custom_cmds_append_CRLF
Definition: CGPSInterface.h:322
mrpt::obs::CObservationGPS::has_GGA_datum
bool has_GGA_datum() const
true if the corresponding field exists in messages.
Definition: CObservationGPS.h:219
mrpt::config::CConfigFileBase::read_double
double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound=false) const
Definition: CConfigFileBase.cpp:106
mrpt::hwdrivers::CGPSInterface::NONE
@ NONE
Definition: CGPSInterface.h:150
mrpt::hwdrivers::CGPSInterface::enableSetupCommandsAppendCRLF
void enableSetupCommandsAppendCRLF(const bool enable)
Definition: CGPSInterface.cpp:182
mrpt::hwdrivers::CGPSInterface::NMEA
@ NMEA
Definition: CGPSInterface.h:152
mrpt::poses::CPose3D::setFromValues
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
Definition: CPose3D.cpp:265
mrpt::hwdrivers::CGPSInterface::parseBuffer
void parseBuffer()
Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
Definition: CGPSInterface.cpp:455
mrpt::system::TTimeParts::hour
uint8_t hour
Day (1-31)
Definition: datetime.h:54
mrpt::system::timeToString
std::string timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM.
Definition: datetime.cpp:244
mrpt::hwdrivers::CGPSInterface::unsetJAVAD_AIM_mode
bool unsetJAVAD_AIM_mode()
Unset Advanced Input Mode for the primary port and use it only as a command port.
Definition: CGPSInterface.cpp:661
mrpt::hwdrivers::CGPSInterface::m_JAVAD_rtk_src_baud
unsigned int m_JAVAD_rtk_src_baud
Only used when "m_JAVAD_rtk_src_port" is not empty.
Definition: CGPSInterface.h:332
mrpt::hwdrivers::CGPSInterface::setJAVAD_AIM_mode
bool setJAVAD_AIM_mode()
Set Advanced Input Mode for the primary port.
Definition: CGPSInterface.cpp:692
TParsersRegistry::TParsersRegistry
TParsersRegistry()
Definition: CGPSInterface.cpp:41
mrpt::system::TTimeParts::second
double second
Minute (0-59)
Definition: datetime.h:56
mrpt::system::now
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
mrpt::comms::CSerialPort
A communications serial port built as an implementation of a utils::CStream.
Definition: CSerialPort.h:41
mrpt::hwdrivers::CGenericSensor::ssWorking
@ ssWorking
Definition: CGenericSensor.h:87
mrpt::config::CConfigFileBase::read_bool
bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
Definition: CConfigFileBase.cpp:155
mrpt::hwdrivers
Contains classes for various device interfaces.
Definition: C2DRangeFinderAbstract.h:19
mrpt::system::TTimeParts::year
uint16_t year
Definition: datetime.h:51
mrpt::hwdrivers::CGenericSensor::ssError
@ ssError
Definition: CGenericSensor.h:88
mrpt::comms
Serial and networking devices and utilities.
Definition: CClientTCPSocket.h:21
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: BaseAppDataSource.h:15
mrpt::hwdrivers::CGPSInterface::legacy_topcon_setup_commands
bool legacy_topcon_setup_commands()
Definition: CGPSInterface.cpp:776
mrpt::obs::CObservationGPS::messages
message_list_t messages
The main piece of data in this class: a list of GNNS messages.
Definition: CObservationGPS.h:92
mrpt::hwdrivers::CGPSInterface::m_topcon_data_period
double m_topcon_data_period
The period in seconds which the data should be provided by the GPS.
Definition: CGPSInterface.h:343
mrpt::hwdrivers::CGPSInterface::tryToOpenTheCOM
bool tryToOpenTheCOM()
Returns true if the COM port is already open, or try to open it in other case.
Definition: CGPSInterface.cpp:223
THROW_EXCEPTION
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
ASSERT_
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
mrpt::hwdrivers::CGenericSensor::m_state
TSensorState m_state
Definition: CGenericSensor.h:148
mrpt::obs
This namespace contains representation of robot actions and observations.
Definition: CParticleFilter.h:17
mrpt::hwdrivers::CGPSInterface::ptr_parser_t
bool(CGPSInterface::*)(size_t &out_minimum_rx_buf_to_decide) ptr_parser_t
Definition: CGPSInterface.h:246
mrpt::hwdrivers::CGPSInterface::setSerialPortName
void setSerialPortName(const std::string &COM_port)
Set the serial port to use (COM1, ttyUSB0, etc).
Definition: CGPSInterface.cpp:194
mrpt::hwdrivers::CGPSInterface::m_rx_buffer
mrpt::containers::circular_buffer< uint8_t > m_rx_buffer
Auxiliary buffer for readings.
Definition: CGPSInterface.h:312
mrpt::obs::CObservation::timestamp
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Definition: CObservation.h:60
mrpt::hwdrivers::CGPSInterface::NOVATEL_OEM6
@ NOVATEL_OEM6
Definition: CGPSInterface.h:153
mrpt::hwdrivers::CGPSInterface::setParser
void setParser(PARSERS parser)
Select the parser for incomming data, among the options enumerated in CGPSInterface.
Definition: CGPSInterface.cpp:144
mrpt::hwdrivers::CGPSInterface::getShutdownCommands
const std::vector< std::string > & getShutdownCommands() const
Definition: CGPSInterface.cpp:178
mrpt::config::CConfigFileBase::read_string
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
Definition: CConfigFileBase.cpp:171
mrpt::system::TTimeParts
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
Definition: datetime.h:49
mrpt::hwdrivers::CGPSInterface::m_last_GGA
std::string m_last_GGA
Used in getLastGGA()
Definition: CGPSInterface.h:364
TParsersRegistry::getInstance
static const TParsersRegistry & getInstance()
Definition: CGPSInterface.cpp:34
mrpt::hwdrivers::CGPSInterface::m_GPS_comsWork
bool m_GPS_comsWork
Definition: CGPSInterface.h:318
mrpt::system::fileNameStripInvalidChars
std::string fileNameStripInvalidChars(const std::string &filename, const char replacement_to_invalid_chars='_')
Replace invalid filename chars by underscores ('_') or any other user-given char.
Definition: filesystem.cpp:329
mrpt::hwdrivers::CGPSInterface::m_shutdown_cmds
std::vector< std::string > m_shutdown_cmds
Definition: CGPSInterface.h:324
mrpt::hwdrivers::CGPSInterface::m_raw_dump_file_prefix
std::string m_raw_dump_file_prefix
Definition: CGPSInterface.h:314
mrpt::obs::CObservationGPS::Ptr
std::shared_ptr< mrpt::obs ::CObservationGPS > Ptr
Definition: CObservationGPS.h:69
mrpt::hwdrivers::CGPSInterface::m_COMname
std::string m_COMname
Definition: CGPSInterface.h:315
mrpt::config::CConfigFileBase::read_int
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
Definition: CConfigFileBase.cpp:130
mrpt::hwdrivers::CGPSInterface::OnConnectionEstablished
bool OnConnectionEstablished()
Implements custom messages to be sent to the GPS unit just after connection and before normal use.
Definition: CGPSInterface.cpp:608
mrpt::system::TTimeParts::day
uint8_t day
Month (1-12)
Definition: datetime.h:53
mrpt::hwdrivers::CGPSInterface::m_topcon_useAIMMode
bool m_topcon_useAIMMode
Use this mode for receive RTK corrections from a external source through the primary port.
Definition: CGPSInterface.h:339
TParsersRegistry
Definition: CGPSInterface.cpp:30
mrpt::system::timestampToParts
void timestampToParts(TTimeStamp t, TTimeParts &p, bool localTime=false)
Gets the individual parts of a date/time (days, hours, minutes, seconds) - UTC time or local time.
Definition: datetime.cpp:50
mrpt::hwdrivers::CGPSInterface::setSetupCommandsDelay
void setSetupCommandsDelay(const double delay_secs)
Definition: CGPSInterface.cpp:158
mrpt::hwdrivers::CGPSInterface::getParser
PARSERS getParser() const
Definition: CGPSInterface.cpp:148
mrpt::hwdrivers::CGPSInterface::bindStream
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...
Definition: CGPSInterface.cpp:149
mrpt::hwdrivers::CGPSInterface::loadConfig_sensorSpecific
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters.
Definition: CGPSInterface.cpp:67
mrpt::hwdrivers::CGenericSensor::m_verbose
bool m_verbose
Definition: CGenericSensor.h:149
mrpt::hwdrivers::CGPSInterface::AUTO
@ AUTO
Definition: CGPSInterface.h:151
mrpt::containers::circular_buffer::size
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
Definition: circular_buffer.h:143
MRPT_START
#define MRPT_START
Definition: exceptions.h:241
mrpt::obs::CObservationGPS::swap
void swap(CObservationGPS &o)
Definition: CObservationGPS.cpp:25
mrpt::config::CConfigFileBase
This class allows loading and storing values and vectors of different types from a configuration text...
Definition: config/CConfigFileBase.h:44
mrpt::hwdrivers::CGPSInterface::setSetupCommands
void setSetupCommands(const std::vector< std::string > &cmds)
Definition: CGPSInterface.cpp:166
mrpt::obs::CObservationGPS::has_RMC_datum
bool has_RMC_datum() const
true if the corresponding field exists in messages.
Definition: CObservationGPS.h:224
TParsersRegistry::all_parsers
std::list< CGPSInterface::ptr_parser_t > all_parsers
Definition: CGPSInterface.cpp:32
mrpt::hwdrivers::CGPSInterface::m_custom_cmds_delay
double m_custom_cmds_delay
Definition: CGPSInterface.h:321
MRPT_LOG_ERROR
#define MRPT_LOG_ERROR(_STRING)
Definition: system/COutputLogger.h:433
mrpt::hwdrivers::CGPSInterface::JAVAD_sendMessage
void JAVAD_sendMessage(const char *str, bool waitForAnswer=true)
Private auxiliary method.
Definition: CGPSInterface.cpp:522
mrpt::hwdrivers::CGPSInterface::m_raw_output_file
mrpt::io::CFileOutputStream m_raw_output_file
Definition: CGPSInterface.h:320
mrpt::hwdrivers::CGPSInterface::OnConnectionShutdown
bool OnConnectionShutdown()
Like OnConnectionEstablished() for sending optional shutdown commands.
Definition: CGPSInterface.cpp:574
mrpt::hwdrivers::CGPSInterface::m_sensorPose
poses::CPose3D m_sensorPose
Definition: CGPSInterface.h:275
mrpt::io::CFileOutputStream::fileOpenCorrectly
bool fileOpenCorrectly() const
Returns true if the file was open without errors.
Definition: CFileOutputStream.cpp:111
mrpt::system::TTimeStamp
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
Definition: datetime.h:40
mrpt::hwdrivers::CGenericSensor::appendObservation
void appendObservation(const mrpt::serialization::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
Definition: CGenericSensor.h:180
mrpt::keep_max
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value.
Definition: core/include/mrpt/core/bits_math.h:152
mrpt::hwdrivers::CGPSInterface::m_just_parsed_messages
mrpt::obs::CObservationGPS m_just_parsed_messages
A private copy of the last received gps datum.
Definition: CGPSInterface.h:362
mrpt::hwdrivers::CGenericSensor::m_sensorLabel
std::string m_sensorLabel
See CGenericSensor.
Definition: CGenericSensor.h:141
mrpt::config::CConfigFileBase::read_float
float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound=false) const
Definition: CConfigFileBase.cpp:118
mrpt::hwdrivers::CGPSInterface::m_data_stream
std::shared_ptr< mrpt::io::CStream > m_data_stream
Typically a CSerialPort created by this class, but may be set externally.
Definition: CGPSInterface.h:269
mrpt::config::CConfigFileBase::read_enum
ENUMTYPE read_enum(const std::string &section, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound=false) const
Reads an "enum" value, where the value in the config file can be either a numerical value or the symb...
Definition: config/CConfigFileBase.h:269
mrpt::containers::circular_buffer::pop
T pop()
Retrieve an element from the buffer.
Definition: circular_buffer.h:73
mrpt::DEG2RAD
constexpr double DEG2RAD(const double x)
Degrees to radians
Definition: core/include/mrpt/core/bits_math.h:47
mrpt::hwdrivers::CGPSInterface::implement_parser_NOVATEL_OEM6
bool implement_parser_NOVATEL_OEM6(size_t &out_minimum_rx_buf_to_decide)
Definition: CGPSInterface_parser_NOVATEL_OEM6.cpp:23
mrpt::hwdrivers::CGPSInterface::m_parser
PARSERS m_parser
Definition: CGPSInterface.h:313
mrpt::containers::circular_buffer::push_many
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
Definition: circular_buffer.h:65
IMPLEMENTS_GENERIC_SENSOR
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
Definition: CGenericSensor.h:314
mrpt::containers::circular_buffer::available
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error.
Definition: circular_buffer.h:158
mrpt::system::COutputLogger
Versatile class for consistent logging and management of output messages.
Definition: system/COutputLogger.h:117
mrpt::hwdrivers::CGPSInterface::getSetupCommands
const std::vector< std::string > & getSetupCommands() const
Definition: CGPSInterface.cpp:170
mrpt::hwdrivers::CGPSInterface::m_sensorLabelAppendMsgType
bool m_sensorLabelAppendMsgType
Definition: CGPSInterface.h:317
mrpt::hwdrivers::CGPSInterface::m_customInit
std::string m_customInit
Definition: CGPSInterface.h:276
mrpt::hwdrivers::CGPSInterface::sendCustomCommand
bool sendCustomCommand(const void *data, const size_t datalen)
Send a custom data block to the GNSS device right now.
Definition: CGPSInterface.cpp:890
mrpt::system::TTimeParts::month
uint8_t month
The year.
Definition: datetime.h:52
MRPT_END
#define MRPT_END
Definition: exceptions.h:245
mrpt::hwdrivers::CGPSInterface::isEnabledSetupCommandsAppendCRLF
bool isEnabledSetupCommandsAppendCRLF() const
Definition: CGPSInterface.cpp:186
mrpt::hwdrivers::CGPSInterface::m_JAVAD_rtk_src_port
std::string m_JAVAD_rtk_src_port
If not empty, will send a cmd "set,/par/pos/pd/port,...".
Definition: CGPSInterface.h:330
mrpt::obs::CObservationGPS::clear
void clear()
Empties this observation, clearing the container messages.
Definition: CObservationGPS.cpp:270
mrpt::hwdrivers::CGPSInterface::getLastGGA
std::string getLastGGA(bool reset=true)
Gets the latest GGA command or an empty string if no newer GGA command was received since the last ca...
Definition: CGPSInterface.cpp:769
mrpt::system::TTimeParts::minute
uint8_t minute
Hour (0-23)
Definition: datetime.h:55
mrpt::system::trim
std::string trim(const std::string &str)
Removes leading and trailing spaces.
Definition: string_utils.cpp:270
mrpt::hwdrivers::CGPSInterface::implement_parser_NMEA
bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide)
Definition: CGPSInterface_parser_NMEA.cpp:24
mrpt::hwdrivers::CGPSInterface::PARSERS
PARSERS
Read about parser selection in the documentation for CGPSInterface.
Definition: CGPSInterface.h:148
mrpt::hwdrivers::CGPSInterface::m_last_timestamp
mrpt::system::TTimeStamp m_last_timestamp
Definition: CGPSInterface.h:319
mrpt::system::os::_strcmpi
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
Definition: os.cpp:320
mrpt::hwdrivers::CGPSInterface::m_JAVAD_rtk_format
std::string m_JAVAD_rtk_format
Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK corrections: "cmr",...
Definition: CGPSInterface.h:335
mrpt::hwdrivers::CGPSInterface::m_COMbauds
int m_COMbauds
Definition: CGPSInterface.h:316
CGPSInterface.h
mrpt::hwdrivers::CGPSInterface::setShutdownCommands
void setShutdownCommands(const std::vector< std::string > &cmds)
Definition: CGPSInterface.cpp:174
mrpt::format
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
mrpt::hwdrivers::CGPSInterface::doProcess
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
Definition: CGPSInterface.cpp:280
mrpt::system
Definition: backtrace.h:14
hwdrivers-precomp.h
mrpt::hwdrivers::CGPSInterface::m_data_stream_mine_cs
std::shared_ptr< std::mutex > m_data_stream_mine_cs
Definition: CGPSInterface.h:271



Page generated by Doxygen 1.8.17 for MRPT 2.0.3 at Fri May 15 23:51:15 UTC 2020