MRPT  1.9.9
CGPSInterface.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #ifndef CGPSInterface_H
11 #define CGPSInterface_H
12 
14 #include <mrpt/poses/CPoint3D.h>
15 #include <mrpt/comms/CSerialPort.h>
21 #include <mrpt/obs/obs_frwds.h>
22 
23 namespace mrpt::hwdrivers
24 {
25 /** A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial
26  * port or from any input stream,
27  * and \b parsing the ASCII/binary stream into indivual messages \b stored in
28  * mrpt::obs::CObservationGPS objects.
29  *
30  * Typical input streams are serial ports or raw GPS log files. By default, the
31  * serial port selected by CGPSInterface::setSerialPortName()
32  * or as set in the configuration file will be open upon call to
33  * CGenericSensor::initialize().
34  * Alternatively, an external stream can be bound with
35  * CGPSInterface::bindStream() before calling CGenericSensor::initialize().
36  * This feature can be used to parse commands from a file, a TCP/IP stream, a
37  * memory block, etc.
38  *
39  * The parsers in the enum type CGPSInterface::PARSERS are supported as
40  * parameter `parser` in the
41  * configuration file below or in method CGPSInterface::setParser():
42  * - `NONE`: Do not try to parse the messages into CObservation's. Only useful
43  * if combined with `raw_dump_file_prefix`
44  * - `AUTO`: Try to automatically identify the format of incomming data.
45  * - `NMEA` (NMEA 0183, ASCII messages): Default parser. Supported frames:
46  * GGA, RMC,... See full list of messages in children of
47  * mrpt::obs::gnss::gnss_message
48  * - `NOVATEL_OEM6` (Novatel OEM6, binary frames): Supported frames:
49  * BESTPOS,... Note that receiving a correct IONUTC msg is required for a
50  * correct timestamping of subsequent frames. See full list of messages in
51  * children of mrpt::obs::gnss::gnss_message
52  *
53  * See available parameters below, and an example config file for
54  * rawlog-grabber
55  * [here](https://github.com/MRPT/mrpt/blob/master/share/mrpt/config_files/rawlog-grabber/gps.ini)
56  *
57  * \code
58  * PARAMETERS IN THE ".INI"-LIKE CONFIGURATION STRINGS:
59  * -------------------------------------------------------
60  * [supplied_section_name]
61  *
62  * # Serial port configuration:
63  * COM_port_WIN = COM3
64  * COM_port_LIN = ttyUSB0
65  * baudRate = 4800 // The baudrate of the communications (typ. 4800 or
66  * 9600 bauds)
67  *
68  * # (Default:true) Whether to append the GNNS message type to CObservation
69  * `sensorLabel` field
70  * sensor_label_append_msg_type = true
71  *
72  * # Select a parser for GNSS data:
73  * # Up-to-date list of supported parsers available in
74  * http://reference.mrpt.org/devel/classmrpt_1_1hwdrivers_1_1_c_g_p_s_interface.html
75  * parser = AUTO
76  *
77  * # If uncommented and non-empty, raw binary/ascii data received from the
78  * serial port will be also dumped
79  * # into a file named after this prefix, plus date/time and extension `.gps`.
80  * #raw_dump_file_prefix = RAWGPS
81  *
82  * # 3D position (and orientation, for GNSS+IMUs) of the sensed point (antenna
83  * phase center) relative to the vehicle/robot frame:
84  * pose_x = 0 // (meters)
85  * pose_y = 0
86  * pose_z = 0
87  * pose_yaw = 0 // (deg)
88  * pose_pitch = 0
89  * pose_roll = 0
90  *
91  * # Optional: list of custom commands to be sent to the GNSS receiver to set
92  * it up.
93  * # An arbitrary number of commands can be defined, but their names must be
94  * "setup_cmd%d" starting at "1".
95  * # Commands will be sent by index order. Binary commands instead of ASCII
96  * strings can be set programmatically, not from a config file.
97  * # custom_cmds_delay = 0.1 // (Default=0.1) Delay in seconds between
98  * consecutive set-up commands
99  * # custom_cmds_append_CRLF = true // (Default:true) Append "\r\n" to each
100  * command
101  * # setup_cmd1 = XXXXX
102  * # setup_cmd2 = XXXXX
103  * # setup_cmd3 = XXXXX
104  *
105  * # Optional: list of commands to be sent upon disconnection (e.g. object
106  * destructor)
107  * # shutdown_cmd1 = XXXX
108  * # shutdown_cmd2 = XXXX
109  *
110  * \endcode
111  *
112  * Note that the `customInit` field, supported in MRPT <1.4.0 will be still
113  * parsed and obeyed, but since it has been superseded
114  * by the new mechanism to establish set-up commands, it is no further
115  * documented here.
116  *
117  * The next picture summarizes existing MRPT classes related to GPS / GNSS
118  * devices (CGPSInterface, CNTRIPEmitter, CGPS_NTRIP):
119  *
120  * <div align=center> <img src="mrpt_gps_classes_usage.png"> </div>
121  *
122  * <b>VERSIONS HISTORY:</b>
123  * - 09/JUN/2006: First version (JLBC)
124  * - 04/JUN/2008: Added virtual methods for device-specific initialization
125  * commands.
126  * - 10/JUN/2008: Converted into CGenericSensor class (there are no inhirited
127  * classes anymore).
128  * - 07/DEC/2012: Added public static method to parse NMEA strings.
129  * - 17/JUN/2014: Added GGA feedback.
130  * - 01/FEB/2016: API changed for MTPT 1.4.0
131  *
132  * \note Verbose debug info will be dumped to cout if the environment variable
133  * "MRPT_HWDRIVERS_VERBOSE" is set to "1", or if you call
134  * CGenericSensor::enableVerbose(true)
135  * \note
136  * \note <b>[API changed in MRPT 1.4.0]</b> mrpt::hwdrivers::CGPSInterface API
137  * clean-up and made more generic so any stream can be used to parse GNSS
138  * messages, not only serial ports.
139  *
140  * \sa CGPS_NTRIP, CNTRIPEmitter, mrpt::obs::CObservationGPS
141  * \ingroup mrpt_hwdrivers_grp
142  */
144 {
146 
147  public:
148  /** Read about parser selection in the documentation for CGPSInterface */
149  enum PARSERS
150  {
151  NONE = -2,
152  AUTO = -1,
153  NMEA = 0,
155  };
156 
157  /** Default ctor */
158  CGPSInterface();
159  /** Dtor */
160  virtual ~CGPSInterface();
161 
162  void doProcess(); // See docs in parent class
163 
164  /** Returns true if communications work, i.e. if some message has been
165  * received. */
166  bool isGPS_connected();
167  /** Returns true if the last message from the GPS indicates that the signal
168  * from sats has been acquired. */
169  bool isGPS_signalAcquired();
170 
171  /** \name Set-up and configuration
172  * @{ */
173  /** Set the serial port to use (COM1, ttyUSB0, etc). */
174  void setSerialPortName(const std::string& COM_port);
175  /** Get the serial port to use (COM1, ttyUSB0, etc). */
177 
178  /** Select the parser for incomming data, among the options enumerated in \a
179  * CGPSInterface */
180  void setParser(PARSERS parser);
181  PARSERS getParser() const;
182 
183  // void setExternCOM( CSerialPort *outPort, std::mutex *csOutPort ); //
184  // Replaced by bindStream() in MRPT 1.4.0
185 
186  /** This enforces the use of a given user stream, instead of trying to open
187  * the serial port set in this class parameters.
188  * \param[in] csExternalStream If not NULL, read/write operations to the
189  * stream will be guarded by this critical section.
190  * The stream object is not deleted. It is the user responsibility to keep
191  * that object allocated during the entire life of this object.
192  * \note Call before CGenericSensor::initialize()
193  */
194  void bindStream(
195  mrpt::io::CStream* external_stream,
196  std::mutex* csOptionalExternalStream = nullptr);
197 
198  bool useExternCOM() const { return m_data_stream_is_external; }
200  void setSetupCommandsDelay(const double delay_secs);
201  double getSetupCommandsDelay() const;
202 
203  void setSetupCommands(const std::vector<std::string>& cmds);
204  const std::vector<std::string>& getSetupCommands() const;
205 
206  void setShutdownCommands(const std::vector<std::string>& cmds);
207  const std::vector<std::string>& getShutdownCommands() const;
208 
209  void enableSetupCommandsAppendCRLF(const bool enable);
211 
213  {
215  }
216 
217  /** If set to non-empty, RAW GPS serial data will be also dumped to a
218  * separate file. */
219  void setRawDumpFilePrefix(const std::string& filePrefix)
220  {
221  m_raw_dump_file_prefix = filePrefix;
222  }
224  /** Send a custom data block to the GNSS device right now. Can be used to
225  change its behavior online as needed.
226  \return false on communication error */
227  bool sendCustomCommand(const void* data, const size_t datalen);
228  /** @} */
229 
230  inline bool isAIMConfigured() { return m_topcon_AIMConfigured; }
231  /** Parses one line of NMEA data from a GPS receiver, and writes the
232  * recognized fields (if any) into an observation object.
233  * Recognized frame types are those listed for the `NMEA` parser in the
234  * documentation of CGPSInterface
235  * \return true if some new data field has been correctly parsed and
236  * inserted into out_obs
237  */
238  static bool parse_NMEA(
239  const std::string& cmd_line, mrpt::obs::CObservationGPS& out_obs,
240  const bool verbose = false);
241 
242  /** Gets the latest GGA command or an empty string if no newer GGA command
243  * was received since the last call to this method.
244  * \param[in] reset If set to true, will empty the GGA cache so next calls
245  * will return an empty string if no new frame is received.
246  */
247  std::string getLastGGA(bool reset = true);
248 
249  using ptr_parser_t =
250  bool (CGPSInterface::*)(size_t& out_minimum_rx_buf_to_decide);
251 
252  /** @name Parser implementations: each method must try to parse the first
253  * bytes in the
254  * incoming buffer, and return false if the available data does not match
255  * the expected format, so we must skip 1 byte and try again.
256  * @{ */
257  bool implement_parser_NMEA(size_t& out_minimum_rx_buf_to_decide);
258  bool implement_parser_NOVATEL_OEM6(size_t& out_minimum_rx_buf_to_decide);
259  /** @} */
260 
261  protected:
262  /** Implements custom messages to be sent to the GPS unit just after
263  * connection and before normal use.
264  * Returns false or raise an exception if something goes wrong. */
266  /** Like OnConnectionEstablished() for sending optional shutdown commands */
267  bool OnConnectionShutdown();
268 
270 
271  /** Typically a CSerialPort created by this class, but may be set
272  * externally. */
274  std::mutex* m_data_stream_cs;
277 
280 
281  /** See the class documentation at the top for expected parameters */
283  const mrpt::config::CConfigFileBase& configSource,
284  const std::string& iniSection);
285 
286  /** If not empty, will send a cmd "set,/par/pos/pd/port,...". Example value:
287  * "/dev/ser/b" */
289  {
291  }
292 
293  /** Only used when "m_JAVAD_rtk_src_port" is not empty */
294  void setJAVAD_rtk_src_baud(unsigned int baud)
295  {
296  m_JAVAD_rtk_src_baud = baud;
297  }
298 
299  /** Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK
300  * corrections: "cmr", "rtcm", "rtcm3", etc. */
302  /** Set Advanced Input Mode for the primary port.
303  This can be used to send RTK corrections to the device using the same
304  port that it's used for the commands.
305  The RTK correction stream must be re-packaged into a special frame with
306  prefix ">>" */
307  bool setJAVAD_AIM_mode();
308 
309  /** Unset Advanced Input Mode for the primary port and use it only as a
310  * command port. */
311  bool unsetJAVAD_AIM_mode();
312 
313  private:
314  /** Auxiliary buffer for readings */
326  std::vector<std::string> m_setup_cmds;
327  std::vector<std::string> m_shutdown_cmds;
328 
329  /** \name Legacy support for TopCon RTK configuration
330  * @{ */
331  /** If not empty, will send a cmd "set,/par/pos/pd/port,...". Example value:
332  * "/dev/ser/b" */
334  /** Only used when "m_JAVAD_rtk_src_port" is not empty */
335  unsigned int m_JAVAD_rtk_src_baud;
336  /** Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK
337  * corrections: "cmr", "rtcm", "rtcm3", etc. */
339 
340  /** Use this mode for receive RTK corrections from a external source through
341  * the primary port */
343  /** Indicates if the AIM has been properly set up. */
345  /** The period in seconds which the data should be provided by the GPS */
347  /** Private auxiliary method. Raises exception on error. */
348  void JAVAD_sendMessage(const char* str, bool waitForAnswer = true);
349  /** @} */
350 
351  /** Returns true if the COM port is already open, or try to open it in other
352  * case.
353  * \return true if everything goes OK, or false if there are problems
354  * opening the port. */
355  bool tryToOpenTheCOM();
356 
357  /** Process data in "m_buffer" to extract GPS messages, and remove them from
358  * the buffer. */
359  void parseBuffer();
360 
361  /** Queue out now the messages in \a m_just_parsed_messages, leaving it
362  * empty */
363  void flushParsedMessagesNow();
364  /** A private copy of the last received gps datum */
366  /** Used in getLastGGA() */
368 }; // end class
369 }
371 using namespace mrpt::hwdrivers;
375 MRPT_FILL_ENUM_MEMBER(CGPSInterface, NOVATEL_OEM6);
377 
378 #endif
379 
380 
A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabbe...
PARSERS
Read about parser selection in the documentation for CGPSInterface.
A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial port or from any input stre...
void JAVAD_sendMessage(const char *str, bool waitForAnswer=true)
Private auxiliary method.
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
void bindStream(mrpt::io::CStream *external_stream, std::mutex *csOptionalExternalStream=nullptr)
This enforces the use of a given user stream, instead of trying to open the serial port set in this c...
void setJAVAD_rtk_src_baud(unsigned int baud)
Only used when "m_JAVAD_rtk_src_port" is not empty.
bool isGPS_connected()
Returns true if communications work, i.e.
mrpt::obs::CObservationGPS m_just_parsed_messages
A private copy of the last received gps datum.
const std::vector< std::string > & getSetupCommands() const
bool OnConnectionShutdown()
Like OnConnectionEstablished() for sending optional shutdown commands.
bool unsetJAVAD_AIM_mode()
Unset Advanced Input Mode for the primary port and use it only as a command port. ...
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
Contains classes for various device interfaces.
bool(CGPSInterface::*)(size_t &out_minimum_rx_buf_to_decide) ptr_parser_t
void enableSetupCommandsAppendCRLF(const bool enable)
void parseBuffer()
Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
bool sendCustomCommand(const void *data, const size_t datalen)
Send a custom data block to the GNSS device right now.
bool tryToOpenTheCOM()
Returns true if the COM port is already open, or try to open it in other case.
unsigned int m_JAVAD_rtk_src_baud
Only used when "m_JAVAD_rtk_src_port" is not empty.
std::string m_JAVAD_rtk_src_port
If not empty, will send a cmd "set,/par/pos/pd/port,...".
GLdouble s
Definition: glext.h:3676
void setJAVAD_rtk_format(const std::string &s)
Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK corrections: "cmr", "rtcm", "rtcm3", etc.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: io/CStream.h:28
bool isEnabledSetupCommandsAppendCRLF() const
std::string getRawDumpFilePrefix() const
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
This class allows loading and storing values and vectors of different types from a configuration text...
bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide)
Versatile class for consistent logging and management of output messages.
void setSetupCommands(const std::vector< std::string > &cmds)
void setSetupCommandsDelay(const double delay_secs)
std::string m_JAVAD_rtk_format
Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK corrections: "cmr", "rtcm", "rtcm3", etc.
bool implement_parser_NOVATEL_OEM6(size_t &out_minimum_rx_buf_to_decide)
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
#define MRPT_ENUM_TYPE_END()
Definition: TEnumType.h:78
This CStream derived class allow using a file as a write-only, binary stream.
GLsizei const GLchar ** string
Definition: glext.h:4101
bool OnConnectionEstablished()
Implements custom messages to be sent to the GPS unit just after connection and before normal use...
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...
std::vector< std::string > m_setup_cmds
std::string getSerialPortName() const
Get the serial port to use (COM1, ttyUSB0, etc).
#define DEFINE_GENERIC_SENSOR(class_name)
This declaration must be inserted in all CGenericSensor classes definition, within the class declarat...
mrpt::io::CFileOutputStream m_raw_output_file
void setJAVAD_rtk_src_port(const std::string &s)
If not empty, will send a cmd "set,/par/pos/pd/port,...".
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
bool isGPS_signalAcquired()
Returns true if the last message from the GPS indicates that the signal from sats has been acquired...
bool setJAVAD_AIM_mode()
Set Advanced Input Mode for the primary port.
GLboolean reset
Definition: glext.h:3582
mrpt::io::CStream * m_data_stream
Typically a CSerialPort created by this class, but may be set externally.
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...
double m_topcon_data_period
The period in seconds which the data should be provided by the GPS.
mrpt::containers::circular_buffer< uint8_t > m_rx_buffer
Auxiliary buffer for readings.
mrpt::system::TTimeStamp m_last_timestamp
std::vector< std::string > m_shutdown_cmds
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
#define MRPT_ENUM_TYPE_BEGIN(_ENUM_TYPE_WITH_NS)
Definition: TEnumType.h:62
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3546
std::string m_last_GGA
Used in getLastGGA()
bool m_topcon_useAIMMode
Use this mode for receive RTK corrections from a external source through the primary port...
void flushParsedMessagesNow()
Queue out now the messages in m_just_parsed_messages, leaving it empty.
MRPT_FILL_ENUM_MEMBER(CGPSInterface, NONE)
void setRawDumpFilePrefix(const std::string &filePrefix)
If set to non-empty, RAW GPS serial data will be also dumped to a separate file.
void setSerialPortName(const std::string &COM_port)
Set the serial port to use (COM1, ttyUSB0, etc).
void setParser(PARSERS parser)
Select the parser for incomming data, among the options enumerated in CGPSInterface.
const std::vector< std::string > & getShutdownCommands() const
void enableAppendMsgTypeToSensorLabel(bool enable)
void setShutdownCommands(const std::vector< std::string > &cmds)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020