50 mrpt::utils::COutputLogger(
"CGPSInterface"),
52 m_data_stream_cs(NULL),
53 m_data_stream_is_external(false),
55 m_rx_buffer (0x10000),
57 m_raw_dump_file_prefix(),
60 m_sensorLabelAppendMsgType (true),
61 m_GPS_comsWork (false),
63 m_custom_cmds_delay (0.1),
64 m_custom_cmds_append_CRLF(true),
66 m_JAVAD_rtk_src_port (),
67 m_JAVAD_rtk_src_baud (0),
68 m_JAVAD_rtk_format (
"cmr"),
69 m_topcon_useAIMMode ( false ),
70 m_topcon_AIMConfigured ( false ),
71 m_topcon_data_period ( 0.2 )
86 #ifdef MRPT_OS_WINDOWS 103 for (
int i=1;
true; i++)
113 for (
int i=1;
true; i++)
123 configSource.
read_float(iniSection,
"pose_x",0),
124 configSource.
read_float(iniSection,
"pose_y",0),
125 configSource.
read_float(iniSection,
"pose_z",0),
199 THROW_EXCEPTION(
"Cannot change serial port name: an external stream has been already bound manually.")
205 if (serial && serial->
isOpen())
206 THROW_EXCEPTION(
"Cannot change serial port name when it is already open")
257 catch (std::exception &e)
259 std::cerr <<
"[CGPSInterface::tryToOpenTheCOM] Error opening or configuring serial port:" << std::endl << e.what();
300 nRead = stream_tcpip->
readAsync( buf, to_read, 100, 10 );
302 else if (stream_serial) {
303 nRead = stream_serial->
Read(buf,to_read);
317 string sFilePostfix =
"_";
318 sFilePostfix +=
format(
"%04u-%02u-%02u_%02uh%02um%02us",(
unsigned int)parts.
year, (
unsigned int)parts.
month, (
unsigned int)parts.
day, (
unsigned int)parts.
hour, (
unsigned int)parts.
minute, (
unsigned int)parts.
second );
321 if (
m_verbose) std::cout <<
"[CGPSInterface] Creating RAW dump file: `" << sFileName <<
"`\n";
328 catch (std::exception &)
331 MRPT_LOG_ERROR(
"[CGPSInterface::doProcess] Error reading stream of data: Closing communications\n");
334 stream_serial->
close();
346 bool do_append_obs =
false;
358 if( tdif >= 0 && tdif < 7500 )
361 {
if (
m_verbose) cout <<
"[CGPSInterface] Warning: The initial timestamp seems to be wrong! : " << tdif << endl;}
366 if( time_diff < 0 || time_diff > 300 )
367 {
if (
m_verbose) cout <<
"[CGPSInterface ] Bad timestamp difference" << endl;
return; }
370 {
if (
m_verbose) cout <<
"[CGPSInterface] WARNING: According to the timestamps, we probably skipped one frame!" << endl; }
392 CObservationGPSPtr newObs = CObservationGPS::Create();
418 throw std::runtime_error(
"[CGPSInterface] Unknown parser!");
426 if (!(*this.*parser_ptr)(min_bytes))
439 size_t global_min_bytes_max=0;
442 bool all_parsers_want_to_skip =
true;
446 size_t this_parser_min_bytes;
447 if ((*this.*parser_ptr)(this_parser_min_bytes))
448 all_parsers_want_to_skip =
false;
452 if (all_parsers_want_to_skip)
467 const size_t len = strlen(str);
469 if (!stream_serial)
return;
475 written = stream_serial->
Write(str,
len);
479 std::cout <<
"[CGPSInterface] TX: " << str;
482 throw std::runtime_error(
format(
"Error sending command: '%s'",str).c_str());
485 if (!waitForAnswer)
return;
492 while(bad_counter < 10)
497 written = stream_serial->
Write(str,
len);
498 nRead = stream_serial->
Read(buf,
sizeof(buf));
502 std::cout <<
"[CGPSInterface] RX: " << buf << std::endl;
505 throw std::runtime_error(
format(
"ERROR: Invalid response '%s' for command '%s'",buf,str));
507 if (nRead>=3 && buf[0]==
'R' && buf[1]==
'E')
512 throw std::runtime_error(
format(
"ERROR: Invalid response '%s' for command '%s'",buf,str));
519 if (stream_serial && !stream_serial->
isOpen())
526 cout <<
"[CGPSInterface] TX shutdown command: `" <<
m_shutdown_cmds[i] <<
"`\n";
571 cout <<
"[CGPSInterface] TX setup command: `" <<
m_setup_cmds[i] <<
"`\n";
580 }
catch (std::exception &e) {
581 std::cerr <<
"[CGPSInterface::OnConnectionEstablished] Error sending setup cmds: " << e.what() << std::endl;
647 cout <<
"Unknown RTK corrections format. Only supported: CMR, RTCM or RTCM3" << endl;
685 cout <<
"[CGPSInterface] Configure RTK options" << endl;
689 const int elevation_mask = 5;
722 if (
m_verbose) cout <<
"[CGPSInterface] Using Advanced Input Mode";
724 if (
m_verbose) cout <<
"... done" << endl;
730 {
if (
m_verbose) cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon commands sent successfully with AIM." << endl;}
732 {
if (
m_verbose) cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon commands sent successfully." << endl;}
746 catch (std::exception &e)
748 std::cerr <<
"[CGPSInterface::sendCustomCommand] Error sending cmd: " << e.what() << std::endl;
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
bool fileOpenCorrectly()
Returns true if the file was open without errors.
PARSERS getParser() const
size_t ReadBuffer(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer.
void BASE_IMPEXP 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...
static const TParsersRegistry & getInstance()
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 acquiring a CCriticalSection at its constructor, and releasing it at destructor.
A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial port or from any input stre...
double m_custom_cmds_delay
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void JAVAD_sendMessage(const char *str, bool waitForAnswer=true)
Private auxiliary method. Raises exception on error.
void doProcess()
Queue out now the messages in m_just_parsed_messages, leaving it empty.
bool isOpen() const
Returns if port has been correctly open.
poses::CPose3D m_sensorPose
A communications serial port built as an implementation of a utils::CStream.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
void setTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
Changes the timeouts of the port, in milliseconds.
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
bool isGPS_connected()
Returns true if communications work, i.e. if some message has been received.
mrpt::obs::CObservationGPS m_just_parsed_messages
A private copy of the last received gps datum.
const std::vector< std::string > & getSetupCommands() const
bool m_sensorLabelAppendMsgType
bool OnConnectionShutdown()
Like OnConnectionEstablished() for sending optional shutdown commands.
std::string m_sensorLabel
See CGenericSensor.
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error...
#define THROW_EXCEPTION(msg)
void swap(CObservationGPS &o)
message_list_t messages
The main piece of data in this class: a list of GNNS messages.
bool unsetJAVAD_AIM_mode()
Unset Advanced Input Mode for the primary port and use it only as a command port. ...
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
CGPSInterface()
Default ctor.
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
bool open(const std::string &fileName, bool append=false)
Open the given file for write.
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
bool(CGPSInterface::* ptr_parser_t)(size_t &out_minimum_rx_buf_to_decide)
bool BASE_IMPEXP strCmp(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case sensitive)
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
void enableSetupCommandsAppendCRLF(const bool enable)
size_t Write(const void *Buffer, size_t Count)
Implements the virtual method responsible for writing to the stream.
std::string BASE_IMPEXP timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM.
void parseBuffer()
Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
std::string BASE_IMPEXP fileNameStripInvalidChars(const std::string &filename, const char replacement_to_invalid_chars='_')
Replace invalid filename chars by underscores ('_') or any other user-given char. ...
bool sendCustomCommand(const void *data, const size_t datalen)
Send a custom data block to the GNSS device right now.
const Scalar * const_iterator
std::string m_raw_dump_file_prefix
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,...". Example value: "/dev/ser/b".
std::list< CGPSInterface::ptr_parser_t > all_parsers
size_t readAsync(void *Buffer, const size_t Count, const int timeoutStart_ms=-1, const int timeoutBetween_ms=-1)
A method for reading from the socket with an optional timeout.
bool isEnabledSetupCommandsAppendCRLF() const
This class allows loading and storing values and vectors of different types from a configuration text...
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
internal_msg_test_proxy< gnss::NMEA_RMC > has_RMC_datum
Evaluates as a bool; true if the corresponding field exists in messages.
bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide)
void BASE_IMPEXP sleep(int time_ms) MRPT_NO_THROWS
An OS-independent method for sending the current thread to "sleep" for a given period of time...
void setConfig(int baudRate, int parity=0, int bits=8, int nStopBits=1, bool enableFlowControl=false)
Changes the configuration of the port.
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
int const JOCTET unsigned int datalen
void setSetupCommands(const std::vector< std::string > &cmds)
void setSetupCommandsDelay(const double delay_secs)
This namespace contains representation of robot actions and observations.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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)
virtual ~CGPSInterface()
Dtor.
mrpt::utils::circular_buffer< uint8_t > m_rx_buffer
Auxiliary buffer for readings.
This namespace provides multitask, synchronization utilities.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLsizei const GLchar ** string
bool OnConnectionEstablished()
Implements custom messages to be sent to the GPS unit just after connection and before normal use...
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
ENUMTYPE read_enum(const std::string §ion, 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...
std::vector< std::string > m_setup_cmds
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
void close()
Close the port.
T pop()
Retrieve an element from the buffer.
void clear()
Empties this observation, clearing the container messages.
bool m_custom_cmds_append_CRLF
bool m_data_stream_is_external
double second
Minute (0-59)
std::string getSerialPortName() const
Get the serial port to use (COM1, ttyUSB0, etc).
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp. Where available, this should contain the accurate satellite-based time...
uint8_t minute
Hour (0-23)
void purgeBuffers()
Purge tx and rx buffers.
void open()
Open the port.
internal_msg_test_proxy< gnss::NMEA_GGA > has_GGA_datum
Evaluates as a bool; true if the corresponding field exists in messages.
mrpt::poses::CPose3D sensorPose
The sensor pose on the robot/vehicle.
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...
int BASE_IMPEXP _strcmpi(const char *str1, const char *str2) MRPT_NO_THROWS
An OS-independent version of strcmpi.
bool setJAVAD_AIM_mode()
Set Advanced Input Mode for the primary port.
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
mrpt::utils::CFileOutputStream m_raw_output_file
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...
bool legacy_topcon_setup_commands()
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
void appendObservation(const mrpt::utils::CSerializablePtr &obj)
Like appendObservations() but for just one observation.
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...
std::string BASE_IMPEXP trim(const std::string &str)
Removes leading and trailing spaces.
A TCP socket that can be connected to a TCP server, implementing MRPT's CStream interface for passing...
#define MRPT_LOG_ERROR(_STRING)
double m_topcon_data_period
The period in seconds which the data should be provided by the GPS.
double BASE_IMPEXP 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...
mrpt::system::TTimeStamp m_last_timestamp
mrpt::synch::CCriticalSection * m_data_stream_cs
std::vector< std::string > m_shutdown_cmds
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
GLsizei GLsizei GLenum GLenum const GLvoid * data
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.
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...
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
size_t Read(void *Buffer, size_t Count)
Implements the virtual method responsible for reading from the stream - Unlike CStream::ReadBuffer, this method will not raise an exception on zero bytes read, as long as there is not any fatal error in the communications.
double getSetupCommandsDelay() const
void setShutdownCommands(const std::vector< std::string > &cmds)