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



Page generated by Doxygen 1.9.1 for MRPT 1.4.0 SVN: at Mon Apr 18 03:56:21 UTC 2022