Go to the documentation of this file.
53 m_data_stream(nullptr),
55 m_data_stream_cs(nullptr),
56 m_data_stream_is_external(false),
60 m_raw_dump_file_prefix(),
63 m_sensorLabelAppendMsgType(true),
64 m_GPS_comsWork(false),
66 m_custom_cmds_delay(0.1),
67 m_custom_cmds_append_CRLF(true),
69 m_JAVAD_rtk_src_port(),
70 m_JAVAD_rtk_src_baud(0),
71 m_JAVAD_rtk_format(
"cmr"),
72 m_topcon_useAIMMode(false),
73 m_topcon_AIMConfigured(false),
74 m_topcon_data_period(0.2)
87 iniSection,
"parser",
m_parser,
false );
116 for (
int i = 1;
true; i++)
121 if (sLine.empty())
break;
126 for (
int i = 1;
true; i++)
131 if (sLine.empty())
break;
136 configSource.
read_float(iniSection,
"pose_x", 0),
137 configSource.
read_float(iniSection,
"pose_y", 0),
138 configSource.
read_float(iniSection,
"pose_z", 0),
227 "Cannot change serial port name: an external stream has been "
228 "already bound manually.")
234 if (serial && serial->isOpen())
236 "Cannot change serial port name when it is already open")
265 if (serial->isOpen())
return true;
268 cout <<
"[CGPSInterface] Opening " <<
m_COMname <<
" @ "
276 serial->setTimeouts(1, 0, 1, 1, 1);
286 catch (std::exception& e)
288 std::cerr <<
"[CGPSInterface::tryToOpenTheCOM] Error opening or "
289 "configuring serial port:"
322 const size_t to_read =
332 nRead = stream_tcpip->
readAsync(buf, to_read, 100, 10);
334 else if (stream_serial)
336 nRead = stream_serial->
Read(buf, to_read);
353 string sFilePostfix =
"_";
355 "%04u-%02u-%02u_%02uh%02um%02us", (
unsigned int)parts.
year,
356 (
unsigned int)parts.
month, (
unsigned int)parts.
day,
357 (
unsigned int)parts.
hour, (
unsigned int)parts.
minute,
358 (
unsigned int)parts.
second);
359 const string sFileName =
365 std::cout <<
"[CGPSInterface] Creating RAW dump file: `"
366 << sFileName <<
"`\n";
374 catch (std::exception&)
378 "[CGPSInterface::doProcess] Error reading stream of data: Closing "
383 stream_serial->
close();
395 bool do_append_obs =
false;
405 cout <<
"[CGPSInterface] Initial timestamp: "
413 if (tdif >= 0 && tdif < 7500 )
418 cout <<
"[CGPSInterface] Warning: The initial timestamp "
419 "seems to be wrong! : "
427 if (time_diff < 0 || time_diff > 300)
434 cout <<
"[CGPSInterface ] Bad timestamp difference" << endl;
441 cout <<
"[CGPSInterface] WARNING: According to the "
442 "timestamps, we probably skipped one frame!"
500 throw std::runtime_error(
"[CGPSInterface] Unknown parser!");
508 if (!(*this.*parser_ptr)(min_bytes))
521 const std::list<CGPSInterface::ptr_parser_t>& all_parsers =
524 size_t global_min_bytes_max = 0;
527 bool all_parsers_want_to_skip =
true;
530 it != all_parsers.end(); ++it)
533 size_t this_parser_min_bytes;
534 if ((*this.*parser_ptr)(this_parser_min_bytes))
535 all_parsers_want_to_skip =
false;
555 const size_t len = strlen(str);
557 if (!stream_serial)
return;
563 written = stream_serial->
Write(str,
len);
566 if (
m_verbose) std::cout <<
"[CGPSInterface] TX: " << str;
569 throw std::runtime_error(
570 format(
"Error sending command: '%s'", str).c_str());
571 std::this_thread::sleep_for(5ms);
573 if (!waitForAnswer)
return;
575 std::this_thread::sleep_for(200ms);
580 while (bad_counter < 10)
585 written = stream_serial->
Write(str,
len);
586 nRead = stream_serial->
Read(buf,
sizeof(buf));
589 if (
m_verbose) std::cout <<
"[CGPSInterface] RX: " << buf << std::endl;
592 throw std::runtime_error(
594 "ERROR: Invalid response '%s' for command '%s'", buf, str));
596 if (nRead >= 3 && buf[0] ==
'R' && buf[1] ==
'E')
601 throw std::runtime_error(
602 format(
"ERROR: Invalid response '%s' for command '%s'", buf, str));
609 if (stream_serial && !stream_serial->
isOpen())
return false;
615 cout <<
"[CGPSInterface] TX shutdown command: `"
630 std::this_thread::sleep_for(
631 std::chrono::duration<double, std::milli>(
667 cout <<
"[CGPSInterface] TX setup command: `" <<
m_setup_cmds[i]
678 catch (std::exception& e)
680 std::cerr <<
"[CGPSInterface::OnConnectionEstablished] Error "
681 "sending setup cmds: "
682 << e.what() << std::endl;
685 std::this_thread::sleep_for(
686 std::chrono::duration<double, std::milli>(
689 std::this_thread::sleep_for(
702 std::this_thread::sleep_for(500ms);
704 std::this_thread::sleep_for(1000ms);
735 "%%set,/par/cur/term/jps/0,{nscmd,37,n,\"\"}\r\n");
748 "%%%%set,/par/cur/term/jps/1,{cmr,-1,y,%s}\r\n",
754 "%%%%set,/par%s/imode,cmr\r\n",
762 "%%%%set,/par/cur/term/jps/1,{rtcm,-1,y,%s}\r\n",
768 "%%%%set,/par%s/imode,rtcm\r\n",
776 "%%%%set,/par/cur/term/jps/1,{rtcm3,-1,y,%s}\r\n",
782 "%%%%set,/par%s/imode,rtcm3\r\n",
788 cout <<
"Unknown RTK corrections format. Only supported: CMR, RTCM "
816 std::this_thread::sleep_for(500ms);
818 std::this_thread::sleep_for(1000ms);
829 if (
m_verbose) cout <<
"[CGPSInterface] Configure RTK options" << endl;
833 const int elevation_mask = 5;
836 format(
"%%%%set,/par/lock/elm,%i\r\n", elevation_mask)
839 "%%set,/par/base/mode/,off\r\n");
849 "%%set,/par/pos/pd/qcheck,off\r\n");
851 "%%set,/par/pos/mode/cur,pd\r\n");
853 "%%set,/par/pos/pd/textr,10\r\n");
855 "%%set,/par/pos/pd/inuse,-1\r\n");
896 if (
m_verbose) cout <<
"[CGPSInterface] Using Advanced Input Mode";
898 if (
m_verbose) cout <<
"... done" << endl;
909 cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon "
910 "commands sent successfully with AIM."
916 cout <<
"[CGPSInterface::OnConnectionEstablished] JAVAD/TopCon "
917 "commands sent successfully."
934 catch (std::exception& e)
936 std::cerr <<
"[CGPSInterface::sendCustomCommand] Error sending cmd: "
937 << e.what() << std::endl;
std::vector< std::string > m_setup_cmds
A TCP socket that can be connected to a TCP server, implementing MRPT's CStream interface for passing...
bool isOpen() const
Returns if port has been correctly open.
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
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.
mrpt::poses::CPose3D sensorPose
The sensor pose on the robot/vehicle.
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...
bool m_data_stream_is_external
void flushParsedMessagesNow()
Queue out now the messages in m_just_parsed_messages, leaving it empty.
void close()
Close the port.
const Scalar * const_iterator
size_t Write(const void *Buffer, size_t Count) override
Introduces a pure virtual method responsible for writing to the stream.
bool isGPS_connected()
Returns true if communications work, i.e.
bool open(const std::string &fileName, bool append=false)
Open the given file for write.
std::string getSerialPortName() const
Get the serial port to use (COM1, ttyUSB0, etc).
std::mutex * m_data_stream_cs
double getSetupCommandsDelay() const
A class capable of reading GPS/GNSS/GNSS+IMU receiver data, from a serial port or from any input stre...
CGPSInterface()
Default ctor.
bool m_topcon_AIMConfigured
Indicates if the AIM has been properly set up.
bool strCmp(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case sensitive)
bool m_custom_cmds_append_CRLF
double read_double(const std::string §ion, const std::string &name, double defaultValue, bool failIfNotFound=false) const
void enableSetupCommandsAppendCRLF(const bool enable)
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...
void parseBuffer()
Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
size_t Read(void *Buffer, size_t Count)
Implements the virtual method responsible for reading from the stream - Unlike CStream::ReadBuffer,...
std::string timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM.
bool unsetJAVAD_AIM_mode()
Unset Advanced Input Mode for the primary port and use it only as a command port.
unsigned int m_JAVAD_rtk_src_baud
Only used when "m_JAVAD_rtk_src_port" is not empty.
mrpt::io::CStream * m_data_stream
Typically a CSerialPort created by this class, but may be set externally.
bool setJAVAD_AIM_mode()
Set Advanced Input Mode for the primary port.
double second
Minute (0-59)
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
A communications serial port built as an implementation of a utils::CStream.
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
Contains classes for various device interfaces.
Serial and networking devices and utilities.
size_t Write(const void *Buffer, size_t Count) override
Introduces a pure virtual method responsible for writing to the stream.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool legacy_topcon_setup_commands()
message_list_t messages
The main piece of data in this class: a list of GNNS messages.
double m_topcon_data_period
The period in seconds which the data should be provided by the GPS.
bool tryToOpenTheCOM()
Returns true if the COM port is already open, or try to open it in other case.
#define THROW_EXCEPTION(msg)
void purgeBuffers()
Purge tx and rx buffers.
#define ASSERT_(f)
Defines an assertion mechanism.
This namespace contains representation of robot actions and observations.
bool(CGPSInterface::*)(size_t &out_minimum_rx_buf_to_decide) ptr_parser_t
void setSerialPortName(const std::string &COM_port)
Set the serial port to use (COM1, ttyUSB0, etc).
mrpt::containers::circular_buffer< uint8_t > m_rx_buffer
Auxiliary buffer for readings.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
void setParser(PARSERS parser)
Select the parser for incomming data, among the options enumerated in CGPSInterface.
virtual size_t Read(void *Buffer, size_t Count)=0
Introduces a pure virtual method responsible for reading from the stream.
const std::vector< std::string > & getShutdownCommands() const
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
std::string m_last_GGA
Used in getLastGGA()
static const TParsersRegistry & getInstance()
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
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.
std::vector< std::string > m_shutdown_cmds
std::string m_raw_dump_file_prefix
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
bool OnConnectionEstablished()
Implements custom messages to be sent to the GPS unit just after connection and before normal use.
bool m_topcon_useAIMMode
Use this mode for receive RTK corrections from a external source through the primary port.
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.
void setSetupCommandsDelay(const double delay_secs)
PARSERS getParser() const
GLsizei GLsizei GLenum GLenum const GLvoid * data
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
void swap(CObservationGPS &o)
This class allows loading and storing values and vectors of different types from a configuration text...
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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 setSetupCommands(const std::vector< std::string > &cmds)
std::list< CGPSInterface::ptr_parser_t > all_parsers
double m_custom_cmds_delay
#define MRPT_LOG_ERROR(_STRING)
void JAVAD_sendMessage(const char *str, bool waitForAnswer=true)
Private auxiliary method.
mrpt::io::CFileOutputStream m_raw_output_file
internal_msg_test_proxy< gnss::NMEA_RMC > has_RMC_datum
Evaluates as a bool; true if the corresponding field exists in messages.
virtual size_t Write(const void *Buffer, size_t Count)=0
Introduces a pure virtual method responsible for writing to the stream.
bool OnConnectionShutdown()
Like OnConnectionEstablished() for sending optional shutdown commands.
poses::CPose3D m_sensorPose
bool fileOpenCorrectly() const
Returns true if the file was open without errors.
std::shared_ptr< CObservationGPS > Ptr
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
void appendObservation(const mrpt::serialization::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
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.
mrpt::obs::CObservationGPS m_just_parsed_messages
A private copy of the last received gps datum.
std::string m_sensorLabel
See CGenericSensor.
float read_float(const std::string §ion, const std::string &name, float 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...
T pop()
Retrieve an element from the buffer.
bool implement_parser_NOVATEL_OEM6(size_t &out_minimum_rx_buf_to_decide)
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error.
Versatile class for consistent logging and management of output messages.
const std::vector< std::string > & getSetupCommands() const
bool m_sensorLabelAppendMsgType
bool sendCustomCommand(const void *data, const size_t datalen)
Send a custom data block to the GNSS device right now.
bool isEnabledSetupCommandsAppendCRLF() const
std::string m_JAVAD_rtk_src_port
If not empty, will send a cmd "set,/par/pos/pd/port,...".
void clear()
Empties this observation, clearing the container messages.
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...
uint8_t minute
Hour (0-23)
GLsizei const GLchar ** string
std::string trim(const std::string &str)
Removes leading and trailing spaces.
bool implement_parser_NMEA(size_t &out_minimum_rx_buf_to_decide)
PARSERS
Read about parser selection in the documentation for CGPSInterface.
mrpt::system::TTimeStamp m_last_timestamp
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
internal_msg_test_proxy< gnss::NMEA_GGA > has_GGA_datum
Evaluates as a bool; true if the corresponding field exists in messages.
std::string m_JAVAD_rtk_format
Only used when "m_JAVAD_rtk_src_port" is not empty: format of RTK corrections: "cmr",...
void setShutdownCommands(const std::vector< std::string > &cmds)
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
virtual ~CGPSInterface()
Dtor.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation,...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
double DEG2RAD(const double x)
Degrees to radians.
Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST | |