57 m_raw_dump_file_prefix(),
62 m_JAVAD_rtk_src_port(),
64 m_JAVAD_rtk_format(
"cmr")
77 iniSection,
"parser",
m_parser,
false );
106 for (
int i = 1;
true; i++)
111 if (sLine.empty())
break;
116 for (
int i = 1;
true; i++)
121 if (sLine.empty())
break;
126 configSource.
read_float(iniSection,
"pose_x", 0),
127 configSource.
read_float(iniSection,
"pose_y", 0),
128 configSource.
read_float(iniSection,
"pose_z", 0),
218 "Cannot change serial port name: an external stream has been " 219 "already bound manually.");
225 if (serial && serial->isOpen())
227 "Cannot change serial port name when it is already open");
256 if (serial->isOpen())
return true;
259 cout <<
"[CGPSInterface] Opening " <<
m_COMname <<
" @ " 267 serial->setTimeouts(1, 0, 1, 1, 1);
277 catch (
const std::exception& e)
279 std::cerr <<
"[CGPSInterface::tryToOpenTheCOM] Error opening or " 280 "configuring serial port:" 312 const size_t to_read =
322 nRead = stream_tcpip->readAsync(buf, to_read, 100, 10);
324 else if (stream_serial)
326 nRead = stream_serial->Read(buf, to_read);
343 string sFilePostfix =
"_";
345 "%04u-%02u-%02u_%02uh%02um%02us", (
unsigned int)parts.
year,
346 (
unsigned int)parts.
month, (
unsigned int)parts.
day,
347 (
unsigned int)parts.
hour, (
unsigned int)parts.
minute,
348 (
unsigned int)parts.
second);
349 const string sFileName =
355 std::cout <<
"[CGPSInterface] Creating RAW dump file: `" 356 << sFileName <<
"`\n";
364 catch (std::exception&)
368 "[CGPSInterface::doProcess] Error reading stream of data: Closing " 373 stream_serial->close();
385 bool do_append_obs =
false;
395 cout <<
"[CGPSInterface] Initial timestamp: " 403 if (tdif >= 0 && tdif < 7500 )
408 cout <<
"[CGPSInterface] Warning: The initial timestamp " 409 "seems to be wrong! : " 417 if (time_diff < 0 || time_diff > 300)
424 cout <<
"[CGPSInterface ] Bad timestamp difference" << endl;
431 cout <<
"[CGPSInterface] WARNING: According to the " 432 "timestamps, we probably skipped one frame!" 490 throw std::runtime_error(
"[CGPSInterface] Unknown parser!");
498 if (!(*this.*parser_ptr)(min_bytes))
511 const std::list<CGPSInterface::ptr_parser_t>& all_parsers =
514 size_t global_min_bytes_max = 0;
517 bool all_parsers_want_to_skip =
true;
518 for (
auto all_parser : all_parsers)
520 parser_ptr = all_parser;
521 size_t this_parser_min_bytes;
522 if ((*this.*parser_ptr)(this_parser_min_bytes))
523 all_parsers_want_to_skip =
false;
543 const size_t len = strlen(str);
545 if (!stream_serial)
return;
551 written = stream_serial->Write(str,
len);
554 if (
m_verbose) std::cout <<
"[CGPSInterface] TX: " << str;
557 throw std::runtime_error(
558 format(
"Error sending command: '%s'", str).c_str());
559 std::this_thread::sleep_for(5ms);
561 if (!waitForAnswer)
return;
563 std::this_thread::sleep_for(200ms);
568 while (bad_counter < 10)
573 written = stream_serial->Write(str,
len);
574 nRead = stream_serial->Read(buf,
sizeof(buf));
577 if (
m_verbose) std::cout <<
"[CGPSInterface] RX: " << buf << std::endl;
580 throw std::runtime_error(
format(
581 "ERROR: Invalid response '%s' for command '%s'", buf, str));
583 if (nRead >= 3 && buf[0] ==
'R' && buf[1] ==
'E')
588 throw std::runtime_error(
589 format(
"ERROR: Invalid response '%s' for command '%s'", buf, str));
596 if (stream_serial && !stream_serial->isOpen())
return false;
602 cout <<
"[CGPSInterface] TX shutdown command: `" << m_shutdown_cmd
617 std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(
643 stream_serial->purgeBuffers();
653 cout <<
"[CGPSInterface] TX setup command: `" << m_setup_cmd
664 catch (
const std::exception& e)
666 std::cerr <<
"[CGPSInterface::OnConnectionEstablished] Error " 667 "sending setup cmds: " 668 << e.what() << std::endl;
671 std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(
674 std::this_thread::sleep_for(
687 std::this_thread::sleep_for(500ms);
689 std::this_thread::sleep_for(1000ms);
696 stream_serial->purgeBuffers();
720 "%%set,/par/cur/term/jps/0,{nscmd,37,n,\"\"}\r\n");
733 "%%%%set,/par/cur/term/jps/1,{cmr,-1,y,%s}\r\n",
738 "%%%%set,/par%s/imode,cmr\r\n",
746 "%%%%set,/par/cur/term/jps/1,{rtcm,-1,y,%s}\r\n",
751 "%%%%set,/par%s/imode,rtcm\r\n",
759 "%%%%set,/par/cur/term/jps/1,{rtcm3,-1,y,%s}\r\n",
764 "%%%%set,/par%s/imode,rtcm3\r\n",
770 cout <<
"Unknown RTK corrections format. Only supported: CMR, RTCM " 798 std::this_thread::sleep_for(500ms);
800 std::this_thread::sleep_for(1000ms);
807 stream_serial->purgeBuffers();
811 if (
m_verbose) cout <<
"[CGPSInterface] Configure RTK options" << endl;
815 const int elevation_mask = 5;
818 format(
"%%%%set,/par/lock/elm,%i\r\n", elevation_mask)
821 "%%set,/par/base/mode/,off\r\n");
831 "%%set,/par/pos/pd/qcheck,off\r\n");
833 "%%set,/par/pos/mode/cur,pd\r\n");
835 "%%set,/par/pos/pd/textr,10\r\n");
837 "%%set,/par/pos/pd/inuse,-1\r\n");
857 "%%%%set,/par%s/rate,%u\r\n",
865 "%%%%set,/par%s/imode,%s\r\n",
878 if (
m_verbose) cout <<
"[CGPSInterface] Using Advanced Input Mode";
880 if (
m_verbose) cout <<
"... done" << endl;
891 cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon " 892 "commands sent successfully with AIM." 898 cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon " 899 "commands sent successfully." 916 catch (
const std::exception& e)
918 std::cerr <<
"[CGPSInterface::sendCustomCommand] Error sending cmd: " 919 << e.what() << std::endl;
PARSERS getParser() const
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error...
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...
static const TParsersRegistry & getInstance()
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...
double m_custom_cmds_delay
void JAVAD_sendMessage(const char *str, bool waitForAnswer=true)
Private auxiliary method.
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 appendObservation(const mrpt::serialization::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
A communications serial port built as an implementation of a utils::CStream.
poses::CPose3D m_sensorPose
#define THROW_EXCEPTION(msg)
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 m_sensorLabelAppendMsgType
bool OnConnectionShutdown()
Like OnConnectionEstablished() for sending optional shutdown commands.
std::string m_sensorLabel
See CGenericSensor.
double DEG2RAD(const double x)
Degrees to radians.
std::mutex * m_data_stream_cs
void swap(CObservationGPS &o)
virtual size_t Read(void *Buffer, size_t Count)=0
Introduces a pure virtual method responsible for reading from the stream.
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. ...
CGPSInterface()
Default ctor.
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
bool(CGPSInterface::*)(size_t &out_minimum_rx_buf_to_decide) ptr_parser_t
bool strCmp(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case sensitive)
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
void enableSetupCommandsAppendCRLF(const bool enable)
std::string 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 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.
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,...".
std::list< CGPSInterface::ptr_parser_t > all_parsers
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
bool isEnabledSetupCommandsAppendCRLF() const
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
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...
#define ASSERT_(f)
Defines an assertion mechanism.
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
This class allows loading and storing values and vectors of different types from a configuration text...
T pop()
Retrieve an element from the buffer.
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
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...
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)
Versatile class for consistent logging and management of output messages.
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
void setSetupCommands(const std::vector< std::string > &cmds)
~CGPSInterface() override
Dtor.
void setSetupCommandsDelay(const double delay_secs)
This namespace contains representation of robot actions and observations.
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)
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
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:
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
std::vector< std::string > m_setup_cmds
void clear()
Empties this observation, clearing the container messages.
bool fileOpenCorrectly() const
Returns true if the file was open without errors.
bool m_custom_cmds_append_CRLF
bool m_data_stream_is_external
bool open(const std::string &fileName, bool append=false)
Open the given file for write.
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters.
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.
uint8_t minute
Hour (0-23)
mrpt::io::CFileOutputStream m_raw_output_file
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.
#define MRPT_LOG_ERROR(_STRING)
virtual size_t Write(const void *Buffer, size_t Count)=0
Introduces a pure virtual method responsible for writing to the stream.
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
bool setJAVAD_AIM_mode()
Set Advanced Input Mode for the primary port.
size_t Write(const void *Buffer, size_t Count) override
Introduces a pure virtual method responsible for writing to the stream.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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()
A TCP socket that can be connected to a TCP server, implementing MRPT's CStream interface for passing...
mrpt::io::CStream * m_data_stream
Typically a CSerialPort created by this class, but may be set externally.
std::mutex m_data_stream_mine_cs
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 trim(const std::string &str)
Removes leading and trailing spaces.
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
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.
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...
Serial and networking devices and utilities.
mrpt::system::TTimeStamp m_last_timestamp
std::vector< std::string > m_shutdown_cmds
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.
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
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
double getSetupCommandsDelay() const
void setShutdownCommands(const std::vector< std::string > &cmds)
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.