Main MRPT website > C++ reference for MRPT 1.5.7
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-2017, 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 programmatically, 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  */
110  class HWDRIVERS_IMPEXP CGPSInterface : public mrpt::utils::COutputLogger, public CGenericSensor
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
138  PARSERS getParser() const;
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);
162  bool isEnabledSetupCommandsAppendCRLF() const;
163 
164  void enableAppendMsgTypeToSensorLabel(bool enable) { m_sensorLabelAppendMsgType = enable; }
165 
166  /** If set to non-empty, RAW GPS serial data will be also dumped to a separate file. */
167  void setRawDumpFilePrefix(const std::string &filePrefix) { m_raw_dump_file_prefix=filePrefix; }
168  std::string getRawDumpFilePrefix() const { return m_raw_dump_file_prefix; }
169 
170  /** Send a custom data block to the GNSS device right now. Can be used to change its behavior online as needed.
171  \return false on communication error */
172  bool sendCustomCommand(const void* data, const size_t datalen);
173  /** @} */
174 
175  inline bool isAIMConfigured() { return m_topcon_AIMConfigured; }
176 
177  /** Parses one line of NMEA data from a GPS receiver, and writes the recognized fields (if any) into an observation object.
178  * Recognized frame types are those listed for the `NMEA` parser in the documentation of CGPSInterface
179  * \return true if some new data field has been correctly parsed and inserted into out_obs
180  */
181  static bool parse_NMEA(const std::string &cmd_line, mrpt::obs::CObservationGPS &out_obs, const bool verbose=false);
182 
183  /** Gets the latest GGA command or an empty string if no newer GGA command was received since the last call to this method.
184  * \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.
185  */
186  std::string getLastGGA(bool reset=true);
187 
188  typedef bool (CGPSInterface::*ptr_parser_t)(size_t &out_minimum_rx_buf_to_decide);
189 
190  /** @name Parser implementations: each method must try to parse the first bytes in the
191  * incoming buffer, and return false if the available data does not match the expected format, so we must skip 1 byte and try again.
192  * @{ */
193  bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide);
194  bool implement_parser_NOVATEL_OEM6(size_t &out_minimum_rx_buf_to_decide);
195  /** @} */
196 
197  protected:
198  /** Implements custom messages to be sent to the GPS unit just after connection and before normal use.
199  * Returns false or raise an exception if something goes wrong. */
200  bool OnConnectionEstablished();
201  bool OnConnectionShutdown(); //!< Like OnConnectionEstablished() for sending optional shutdown commands
202 
203  bool legacy_topcon_setup_commands();
204 
205  mrpt::utils::CStream *m_data_stream; //!< Typically a CSerialPort created by this class, but may be set externally.
208 
211 
212  /** See the class documentation at the top for expected parameters */
213  void loadConfig_sensorSpecific(
214  const mrpt::utils::CConfigFileBase &configSource,
215  const std::string &iniSection );
216 
217  /** If not empty, will send a cmd "set,/par/pos/pd/port,...". Example value: "/dev/ser/b" */
218  void setJAVAD_rtk_src_port( const std::string &s) { m_JAVAD_rtk_src_port = s; }
219 
220  /** Only used when "m_JAVAD_rtk_src_port" is not empty */
221  void setJAVAD_rtk_src_baud(unsigned int baud) { m_JAVAD_rtk_src_baud = baud; }
222 
223  /** Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK corrections: "cmr", "rtcm", "rtcm3", etc. */
224  void setJAVAD_rtk_format(const std::string &s) {m_JAVAD_rtk_format=s;}
225 
226  /** Set Advanced Input Mode for the primary port.
227  This can be used to send RTK corrections to the device using the same port that it's used for the commands.
228  The RTK correction stream must be re-packaged into a special frame with prefix ">>" */
229  bool setJAVAD_AIM_mode();
230 
231  /** Unset Advanced Input Mode for the primary port and use it only as a command port. */
232  bool unsetJAVAD_AIM_mode();
233 
234  private:
235  mrpt::utils::circular_buffer<uint8_t> m_rx_buffer; //!< Auxiliary buffer for readings
246  std::vector<std::string> m_setup_cmds;
247  std::vector<std::string> m_shutdown_cmds;
248 
249  /** \name Legacy support for TopCon RTK configuration
250  * @{ */
251  std::string m_JAVAD_rtk_src_port; //!< If not empty, will send a cmd "set,/par/pos/pd/port,...". Example value: "/dev/ser/b"
252  unsigned int m_JAVAD_rtk_src_baud; //!< Only used when "m_JAVAD_rtk_src_port" is not empty
253  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.
254 
255  bool m_topcon_useAIMMode; //!< Use this mode for receive RTK corrections from a external source through the primary port
256  bool m_topcon_AIMConfigured; //!< Indicates if the AIM has been properly set up.
257  double m_topcon_data_period; //!< The period in seconds which the data should be provided by the GPS
258  void JAVAD_sendMessage(const char*str, bool waitForAnswer = true); //!< Private auxiliary method. Raises exception on error.
259  /** @} */
260 
261  /** Returns true if the COM port is already open, or try to open it in other case.
262  * \return true if everything goes OK, or false if there are problems opening the port. */
263  bool tryToOpenTheCOM();
264 
265  void parseBuffer(); //!< Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
266 
267  void flushParsedMessagesNow(); //!< Queue out now the messages in \a m_just_parsed_messages, leaving it empty
268  mrpt::obs::CObservationGPS m_just_parsed_messages; //!< A private copy of the last received gps datum
269  std::string m_last_GGA; //!< Used in getLastGGA()
270  }; // end class
271  } // end namespace
272 
273  // Specializations MUST occur at the same namespace:
274  namespace utils
275  {
276  template <>
277  struct TEnumTypeFiller<hwdrivers::CGPSInterface::PARSERS>
278  {
280  static void fill(bimap<enum_t,std::string> &m_map)
281  {
282  m_map.insert(hwdrivers::CGPSInterface::NONE, "NONE");
283  m_map.insert(hwdrivers::CGPSInterface::AUTO, "AUTO");
284  m_map.insert(hwdrivers::CGPSInterface::NMEA, "NMEA");
285  m_map.insert(hwdrivers::CGPSInterface::NOVATEL_OEM6, "NOVATEL_OEM6");
286  }
287  };
288  }
289 } // end namespace
290 
291 #endif
A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabbe...
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:30
This class provides simple critical sections functionality.
mrpt::utils::CStream * m_data_stream
Typically a CSerialPort created by this class, but may be set externally.
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 setJAVAD_rtk_src_baud(unsigned int baud)
Only used when "m_JAVAD_rtk_src_port" is not empty.
static void fill(bimap< enum_t, std::string > &m_map)
mrpt::obs::CObservationGPS m_just_parsed_messages
A private copy of the last received gps datum.
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
Only specializations of this class are defined for each enum type of interest.
Definition: TEnumType.h:23
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,...". Example value: "/dev/ser/b".
GLdouble s
Definition: glext.h:3602
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 class allows loading and storing values and vectors of different types from a configuration text...
std::string getRawDumpFilePrefix() const
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
This CStream derived class allow using a file as a write-only, binary stream.
int const JOCTET unsigned int datalen
Definition: mrpt_jpeglib.h:947
A bidirectional version of std::map, declared as bimap<KEY,VALUE> and which actually contains two std...
Definition: bimap.h:28
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.
mrpt::utils::circular_buffer< uint8_t > m_rx_buffer
Auxiliary buffer for readings.
GLsizei const GLchar ** string
Definition: glext.h:3919
std::vector< std::string > m_setup_cmds
#define DEFINE_GENERIC_SENSOR(class_name)
This declaration must be inserted in all CGenericSensor classes definition, within the class declarat...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
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:72
mrpt::utils::CFileOutputStream m_raw_output_file
GLboolean reset
Definition: glext.h:3535
double m_topcon_data_period
The period in seconds which the data should be provided by the GPS.
void insert(const KEY &k, const VALUE &v)
Insert a new pair KEY<->VALUE in the bi-map.
Definition: bimap.h:69
mrpt::system::TTimeStamp m_last_timestamp
mrpt::synch::CCriticalSection * m_data_stream_cs
std::vector< std::string > m_shutdown_cmds
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3520
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 setRawDumpFilePrefix(const std::string &filePrefix)
If set to non-empty, RAW GPS serial data will be also dumped to a separate file.
void enableAppendMsgTypeToSensorLabel(bool enable)



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019