27 #define RET_ERROR(msg)                                                   \    29         cout << "[" << __CURRENT_FUNCTION_NAME__ << "] " << msg << endl; \    41     if (n >= 
'0' && n <= 
'9')
    45         if (n >= 
'A' && n <= 
'F')
    46         return (n - 
'A' + 10);
    54 CCANBusReader::CCANBusReader()
    89     bool thereIsObservation;
    93     if (thereIsObservation)
    96         cout << 
"No frame received" << endl;
   103     bool& outThereIsObservation,
   106     outThereIsObservation = 
false;
   107     hardwareError = 
false;
   111         hardwareError = 
true;
   118     uint8_t out_prio, out_pdu_format, out_pdu_spec, out_src_address,
   121     vector<uint8_t> out_data;
   122     vector<char> out_raw_frame;
   124             out_prio, out_pdu_format, out_pdu_spec, out_src_address,
   125             out_data_length, out_pgn, out_data, out_raw_frame))
   141     outObservation.
m_pgn = out_pgn;
   143     outObservation.
m_data.resize(out_data.size());
   144     for (
size_t k = 0; k < out_data.size(); ++k)
   145         outObservation.
m_data[k] = out_data[k];
   146     outObservation.
m_raw_frame.resize(out_raw_frame.size());
   147     for (
size_t k = 0; k < out_raw_frame.size(); ++k)
   151     outThereIsObservation = 
true;
   159     const std::string& iniSection)
   186     if (err_msg) *err_msg = 
"";
   199                 throw std::logic_error(
   200                     "ERROR: No serial port attached with bindIO, neither it "   201                     "set with 'setSerialPort'");
   206         bool just_open = 
false;
   224         if (!just_open) 
return true;
   231         cout << 
"Setting up serial comms in port " << 
m_com_port;
   233         cout << 
" ... done" << endl;
   239         cout << 
"Setting up CAN BUS Speed at: " << 
m_canbus_speed << endl;
   240         for (
int nTry = 0; nTry < 250000 ; nTry++)
   242         if (!res) 
return false;
   243         cout << 
" ... done" << endl;
   247         cout << 
"Opening CAN BUS and starting to receive." << endl;
   248         for (
int nTry = 0; nTry < 250000 ; nTry++)
   250         if (!res) 
return false;
   251         cout << 
" ... done" << endl;
   263     catch (
const std::exception& e)
   266             "[CCANBusReader] Error trying to open CANBusReader at port ";
   268         if (err_msg) *err_msg = s;
   281     unsigned char cmd[2];
   323     unsigned char cmd[1];
   332     unsigned char cmd[1];
   343     unsigned char cmd[1];
   351     unsigned char cmd[2];
   360     unsigned char cmd[1];
   370     uint8_t& out_prio, uint8_t& out_pdu_format, uint8_t& out_pdu_spec,
   371     uint8_t& out_src_address, uint8_t& out_data_length, uint16_t& out_pgn,
   372     vector<uint8_t>& out_data, vector<char>& out_raw_frame)
   374     size_t nRead, nBytesToRead;
   375     size_t nFrameBytes = 0;
   377     unsigned char buf[40];
   380     for (
unsigned char& k : buf) k = 0;
   383     while (nFrameBytes < (lengthField = (10U + dlc + 1U)))
   386         if (lengthField > 30)
   388             cout << 
"#" << int(dlc) << 
" ";
   390             for (
unsigned char& k : buf) k = 0;
   394         if (nFrameBytes < 10)
   400             nBytesToRead = (lengthField)-nFrameBytes;
   412         catch (
const std::exception& e)
   416                 "[waitContinuousSampleFrame] Disconnecting due to comms error: "   421         if (!nRead) 
return false;
   423         if (nRead < nBytesToRead) std::this_thread::sleep_for(30ms);
   427         if (nFrameBytes > 0 || (nFrameBytes == 0 && buf[0] == 0x54 ))
   428             nFrameBytes += nRead;
   432             for (
unsigned char& k : buf) k = 0;
   439     out_raw_frame.resize(nFrameBytes);
   440     for (uint8_t k = 0; k < nFrameBytes; ++k)
   443         out_raw_frame[k] = buf[k];
   446     out_prio = (aux[1] << 2) | (aux[2] >> 2);
   447     out_pdu_format = (aux[3] << 4) | aux[4];
   448     out_pdu_spec = (aux[5] << 4) | aux[6];
   449     out_src_address = (aux[7] << 4) | aux[8];
   450     out_data_length = aux[9];
   451     out_pgn = uint16_t(out_pdu_format) << 8 | uint16_t(out_pdu_spec);
   452     out_data.resize(out_data_length);
   453     for (uint8_t k = 0, k2 = 0; k < 2 * out_data_length; k += 2, k2++)
   454         out_data[k2] = (aux[10 + k] << 4) | aux[11 + k];
   456     if (buf[nFrameBytes - 1] != 0x0D)
   459                     "[CCANBusReader::waitContinuousSampleFrame] expected 0x0D "   460                     "ending flag, 0x%X found instead",
   479         cerr << err_str << endl;
   480         throw std::logic_error(err_str);
   496     int detected_rate = 0;
   501         int rates[] = {0, 9600, 38400, 57600, 500000};
   510              !detected_rate && i < 
sizeof(rates) / 
sizeof(rates[0]); i++)
   515             std::this_thread::sleep_for(100ms);
   520             cout << endl << 
"Closing CAN Channel " << endl;
   521             for (
int nTry = 0; nTry < 250000 ; nTry++)
   523             cout << 
" ... done" << endl;
   526             std::this_thread::sleep_for(100ms);
   529             for (
int nTry = 0; nTry < 250000  && !detected_rate; nTry++)
   536                     detected_rate = rates[i];
   539                 std::this_thread::sleep_for(20ms);
   546             std::this_thread::sleep_for(5000ms);
   556     std::this_thread::sleep_for(500ms);
   572     uint16_t cmd_len = 1;
   592                 cout << int(b) << endl;
   596     } 
while (tictac.
Tac() < timeout_ms * 1e-3);
   609     unsigned int nBytes = 0;
   613     const double maxTime = timeout * 1e-3;
   623             if (nBytes > 0 || (nBytes == 0 && b == 
'V'))
   630         if (tictac.
Tac() >= maxTime)
   632             cout << 
"Version timeout" << endl;
   641             "[CCANBusReader::waitForVersion] Error: expected 0x0D final byte, "   650         for (uint8_t k = 0; k < nBytes; ++k)
   660     unsigned int nBytes = 0;
   664     const double maxTime = timeout * 1e-3;
   666     while (nBytes < 10 || (nBytes < (10U + dlc + 1U )))
   671             if (nBytes > 1 || (!nBytes && b == 0x54 ))
   686         if (tictac.
Tac() >= maxTime) 
return false;  
   692             "[CCANBusReader::waitIncomingFrame] Error: expected 0x0D as final "   693             "flag, received %x\n",
   700     for (
unsigned int i=0;i<nBytes;i++)
   710     const uint8_t* cmd, 
const uint16_t cmd_len, [[maybe_unused]] 
bool wait)
   712     uint8_t cmd_full[1024];
   713     ASSERT_(
sizeof(cmd_full) > cmd_len);
   716     memcpy(cmd_full, cmd, cmd_len);
   717     cmd_full[cmd_len] = 0x0D;  
   719     const size_t toWrite = cmd_len + 1;
   723     for (
unsigned int i = 0; i < toWrite; i++) printf(
"%02X ", cmd_full[i]);
   733         cout << 
"[CCANBusReader::SendCommandToCANReader] Error writing data to " double Tac() noexcept
Stops the stopwatch. 
 
size_t Read(void *Buffer, size_t Count) override
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. 
 
bool sendCANBusReaderSpeed()
Sends the specified speed to the CAN Converter. 
 
bool m_canreader_timestamp
 
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. 
 
bool waitACK(uint16_t timeout_ms)
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
char hexCharToInt(char n)
 
std::string m_sensorLabel
See CGenericSensor. 
 
bool waitContinuousSampleFrame(uint8_t &out_prio, uint8_t &out_pdu_format, uint8_t &out_pdu_spec, uint8_t &out_src_address, uint8_t &out_data_length, uint16_t &out_pgn, std::vector< uint8_t > &out_data, std::vector< char > &out_raw_frame)
 
This class stores a message from a CAN BUS with the protocol J1939. 
 
void doProcessSimple(bool &outThereIsObservation, mrpt::obs::CObservationCANBusJ1939 &outObservation, bool &hardwareError)
Specific laser scanner "software drivers" must process here new data from the I/O stream...
 
A high-performance stopwatch, with typical resolution of nanoseconds. 
 
void open()
Open the port. 
 
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime. 
 
Contains classes for various device interfaces. 
 
bool waitIncomingFrame(uint16_t timeout)
 
void setBaudRate(int baud)
Changes the serial port baud rate (call prior to 'doProcess'); valid values are 9600,38400 and 500000. 
 
void setConfig(int baudRate, int parity=0, int bits=8, int nStopBits=1, bool enableFlowControl=false)
Changes the configuration of the port. 
 
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
 
uint8_t m_priority
The priority. 
 
#define ASSERT_(f)
Defines an assertion mechanism. 
 
bool CANBusCloseChannel()
Closes the CAN Channel. 
 
This class allows loading and storing values and vectors of different types from a configuration text...
 
bool waitForVersion(uint16_t timeout, bool printOutVersion=false)
 
uint8_t m_pdu_spec
PDU Specific. 
 
Versatile class for consistent logging and management of output messages. 
 
void setSerialPortName(const std::string &COM_name)
Sets the serial port to open (it is an error to try to change this while open yet). 
 
This "software driver" implements the communication protocol for interfacing a SICK LMS 2XX laser sca...
 
bool isOpen() const
Returns if port has been correctly open. 
 
This namespace contains representation of robot actions and observations. 
 
size_t Write(const void *Buffer, size_t Count) override
Introduces a pure virtual method responsible for writing to the stream. 
 
void initialize() override
Set-up communication with the laser. 
 
void purgeBuffers()
Purge tx and rx buffers. 
 
uint8_t m_received_frame_buffer[2000]
 
bool tryToOpenComms(std::string *err_msg=nullptr)
Tries to open the com port and setup all the LMS protocol. 
 
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files: 
 
void setTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
Changes the timeouts of the port, in milliseconds. 
 
~CCANBusReader() override
Destructor. 
 
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. 
 
bool sendCommandToCANReader(const uint8_t *cmd, const uint16_t cmd_len, bool wait=true)
 
unsigned int m_nTries_current
 
bool m_CANBusChannel_isOpen
 
uint8_t m_pdu_format
PDU Format. 
 
static Ptr Create(Args &&... args)
 
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
 
std::vector< char > m_raw_frame
The ASCII frame. 
 
mrpt::comms::CSerialPort * m_mySerialPort
Will be !=nullptr only if I created it, so I must destroy it at the end. 
 
uint16_t m_pgn
The Parameter Group Number within this frame. 
 
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters. 
 
std::string m_com_port
If set to non-empty, the serial port will be attempted to be opened automatically when this class is ...
 
int m_com_baudRate
Baudrate: 9600, 38400, 500000. 
 
uint8_t m_src_address
The address of the source node within this frame. 
 
void Tic() noexcept
Starts the stopwatch. 
 
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz) 
 
#define MRPT_LOG_ERROR_STREAM(__CONTENTS)
 
std::vector< uint8_t > m_data
The data within this frame (0-8 bytes) 
 
uint8_t m_data_length
Data length. 
 
bool CANBusOpenChannel()
Opens the CAN Channel. 
 
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy". 
 
bool queryVersion(bool printOutVersion=false)
 
unsigned int m_nTries_connect
Default = 1.