23 #define RET_ERROR(msg) { cout << "[" << __CURRENT_FUNCTION_NAME__ <<"] " << msg << endl; return false; }
33 if (
n >=
'0' &&
n <=
'9')
37 if (
n >=
'A' &&
n <=
'F')
46 CCANBusReader::CCANBusReader() :
47 mrpt::utils::COutputLogger(
"CCANBusReader"),
49 m_mySerialPort( NULL ),
50 m_com_baudRate(57600),
53 m_canbus_speed(250000),
54 m_canreader_timestamp(false),
55 m_CANBusChannel_isOpen(false)
85 bool thereIsObservation;
89 if( thereIsObservation )
92 cout <<
"No frame received" << endl;
99 bool &outThereIsObservation,
101 bool &hardwareError )
103 outThereIsObservation =
false;
104 hardwareError =
false;
108 hardwareError =
true;
115 uint8_t out_prio,out_pdu_format,out_pdu_spec,out_src_address,out_data_length;
117 vector<uint8_t> out_data;
118 vector<char> out_raw_frame;
143 outObservation.
m_pgn = out_pgn;
145 outObservation.
m_data.resize( out_data.size() );
146 for(
uint8_t k = 0; k < out_data.size(); ++k)
147 outObservation.
m_data[k] = out_data[k];
148 outObservation.
m_raw_frame.resize( out_raw_frame.size() );
149 for(
uint8_t k = 0; k < out_raw_frame.size(); ++k)
153 outThereIsObservation =
true;
175 #ifdef MRPT_OS_WINDOWS
191 if (err_msg) *err_msg=
"";
203 throw std::logic_error(
"ERROR: No serial port attached with bindIO, neither it set with 'setSerialPort'");
207 bool just_open =
false;
234 cout <<
"Setting up serial comms in port " <<
m_com_port;
236 cout <<
" ... done" << endl;
242 cout <<
"Setting up CAN BUS Speed at: " <<
m_canbus_speed << endl;
243 for (
int nTry=0;nTry<250000;nTry++)
246 if(!
res)
return false;
247 cout <<
" ... done" << endl;
250 cout <<
"Opening CAN BUS and starting to receive." << endl;
251 for (
int nTry=0;nTry<250000;nTry++)
254 if(!
res)
return false;
255 cout <<
" ... done" << endl;
267 catch(std::exception &e)
269 std::string s =
"[CCANBusReader] Error trying to open CANBusReader at port ";
271 if (err_msg) *err_msg=
s;
284 unsigned char cmd[2];
289 case 10000: cmd[1] =
'0';
break;
290 case 20000: cmd[1] =
'1';
break;
291 case 50000: cmd[1] =
'2';
break;
292 case 100000: cmd[1] =
'3';
break;
293 case 125000: cmd[1] =
'4';
break;
294 case 250000: cmd[1] =
'5';
break;
295 case 500000: cmd[1] =
'6';
break;
296 case 800000: cmd[1] =
'7';
break;
297 case 1000000: cmd[1] =
'8';
break;
298 default:
RET_ERROR(
"Incorrect CAN Bus speed");
break;
306 unsigned char cmd[1];
315 unsigned char cmd[1];
326 unsigned char cmd[1];
334 unsigned char cmd[2];
343 unsigned char cmd[1];
359 vector<uint8_t> &out_data,
360 vector<char> &out_raw_frame)
365 size_t nRead,nBytesToRead;
366 size_t nFrameBytes = 0;
368 unsigned char buf[40];
371 for(
uint8_t k = 0; k < 40; ++k) buf[k]=0;
374 while( nFrameBytes < (lengthField=(10U+dlc+1U) ) )
379 cout <<
"#" << int(dlc) <<
" ";
381 for(
uint8_t k = 0; k < 40; ++k) buf[k]=0;
385 if (nFrameBytes < 10)
391 nBytesToRead = (lengthField) - nFrameBytes;
402 catch (std::exception &e)
405 MRPT_LOG_ERROR_STREAM(
"[waitContinuousSampleFrame] Disconnecting due to comms error: " << e.what());
412 if (nRead<nBytesToRead)
417 if (nFrameBytes>0 || (nFrameBytes == 0 && buf[0]==0x54 ))
422 for(
uint8_t k = 0; k < 40; ++k) buf[k]=0;
429 out_raw_frame.resize(nFrameBytes);
430 for(
uint8_t k = 0; k < nFrameBytes; ++k)
433 out_raw_frame[k] = buf[k];
436 out_prio = (aux[1] << 2) | (aux[2] >> 2);
437 out_pdu_format = (aux[3] << 4) | aux[4];
438 out_pdu_spec = (aux[5] << 4) | aux[6];
439 out_src_address = (aux[7] << 4) | aux[8];
440 out_data_length = aux[9];
442 out_data.resize(out_data_length);
443 for(
uint8_t k = 0, k2 = 0; k < 2*out_data_length; k+=2, k2++)
444 out_data[k2] = (aux[10+k] << 4) | aux[11+k];
446 if( buf[nFrameBytes-1] != 0x0D )
448 cout <<
format(
"[CCANBusReader::waitContinuousSampleFrame] expected 0x0D ending flag, 0x%X found instead", buf[nFrameBytes]) << endl;
465 cerr << err_str << endl;
466 throw std::logic_error(err_str);
481 int detected_rate = 0;
486 int rates[] = {0, 9600,38400,57600,500000};
494 for (
size_t i=0;!detected_rate && i<
sizeof(rates)/
sizeof(rates[0]);i++)
504 cout << endl <<
"Closing CAN Channel " << endl;
505 for (
int nTry=0;nTry<250000;nTry++)
508 cout <<
" ... done" << endl;
514 for (
int nTry=0;nTry<250000 && !detected_rate;nTry++)
521 detected_rate = rates[i];
580 cout << int(
b) << endl;
585 }
while(tictac.
Tac()<timeout_ms*1e-3 );
601 unsigned int nBytes=0;
605 const double maxTime = timeout*1e-3;
613 if ( nBytes > 0 || (nBytes == 0 &&
b ==
'V') )
620 if (tictac.
Tac()>=maxTime)
622 cout <<
"Version timeout" << endl;
630 printf(
"[CCANBusReader::waitForVersion] Error: expected 0x0D final byte, received %x\n",
m_received_frame_buffer[nBytes-1]);
634 if( printOutVersion )
637 for(
uint8_t k = 0; k < nBytes; ++k)
650 unsigned int nBytes=0;
654 const double maxTime = timeout*1e-3;
656 while( nBytes<10 || (nBytes<(10U+dlc+1U)) )
661 if( nBytes>1 || (!nBytes &&
b==0x54 ) )
670 if (tictac.
Tac()>=maxTime)
676 printf(
"[CCANBusReader::waitIncomingFrame] Error: expected 0x0D as final flag, received %x\n",
m_received_frame_buffer[10U+dlc]);
682 for (
unsigned int i=0;i<nBytes;i++)
695 ASSERT_(
sizeof(cmd_full)>cmd_len);
701 memcpy(cmd_full,cmd,cmd_len);
702 cmd_full[cmd_len] = 0x0D;
704 const size_t toWrite = cmd_len+1;
708 for (
unsigned int i=0;i<toWrite;i++)
709 printf(
"%02X ",cmd_full[i]);
719 cout <<
"[CCANBusReader::SendCommandToCANReader] Error writing data to serial port." << endl;
char hexCharToInt(char n)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
#define MRPT_LOG_ERROR_STREAM(__CONTENTS)
This "software driver" implements the communication protocol for interfacing a SICK LMS 2XX laser sca...
bool tryToOpenComms(std::string *err_msg=NULL)
Tries to open the com port and setup all the LMS protocol. Returns true if OK or already open.
bool waitIncomingFrame(uint16_t timeout)
CSerialPort * m_mySerialPort
Will be !=NULL only if I created it, so I must destroy it at the end.
bool CANBusCloseChannel()
Closes the CAN Channel.
bool waitForVersion(uint16_t timeout, bool printOutVersion=false)
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,...
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
bool sendCANBusReaderSpeed()
Sends the specified speed to the CAN Converter.
uint8_t m_received_frame_buffer[2000]
int m_com_baudRate
Baudrate: 9600, 38400, 500000.
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)
virtual ~CCANBusReader()
Destructor
bool CANBusOpenChannel()
Opens the CAN Channel.
void initialize()
Set-up communication with the laser.
bool waitACK(uint16_t timeout_ms)
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
void setBaudRate(int baud)
Changes the serial port baud rate (call prior to 'doProcess'); valid values are 9600,...
bool queryVersion(bool printOutVersion=false)
bool m_canreader_timestamp
std::string m_com_port
If set to non-empty, the serial port will be attempted to be opened automatically when this class is ...
unsigned int m_nTries_connect
Default = 1.
unsigned int m_nTries_current
bool sendCommandToCANReader(const uint8_t *cmd, const uint16_t cmd_len, bool wait=true)
bool m_CANBusChannel_isOpen
void appendObservation(const mrpt::utils::CSerializablePtr &obj)
Like appendObservations() but for just one observation.
std::string m_sensorLabel
See CGenericSensor.
A communications serial port built as an implementation of a utils::CStream.
bool isOpen() const
Returns if port has been correctly open.
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).
void open()
Open the port.
void setConfig(int baudRate, int parity=0, int bits=8, int nStopBits=1, bool enableFlowControl=false)
Changes the configuration of the port.
size_t Write(const void *Buffer, size_t Count)
Implements the virtual method responsible for writing to the stream.
size_t Read(void *Buffer, size_t Count)
Implements the virtual method responsible for reading from the stream - Unlike CStream::ReadBuffer,...
void purgeBuffers()
Purge tx and rx buffers.
void setTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
Changes the timeouts of the port, in milliseconds.
This class stores a message from a CAN BUS with the protocol J1939.
uint8_t m_src_address
The address of the source node within this frame.
uint16_t m_pgn
The Parameter Group Number within this frame.
std::vector< uint8_t > m_data
The data within this frame (0-8 bytes)
uint8_t m_pdu_format
PDU Format.
uint8_t m_pdu_spec
PDU Specific.
static CObservationCANBusJ1939Ptr Create()
uint8_t m_priority
The priority.
std::vector< char > m_raw_frame
The ASCII frame.
uint8_t m_data_length
Data length
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp. Where available, this should contain the accurate satellite-based time...
This class allows loading and storing values and vectors of different types from a configuration text...
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This class implements a high-performance stopwatch.
double Tac()
Stops the stopwatch.
void Tic()
Starts the stopwatch.
GLsizei const GLchar ** string
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
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.
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
Contains classes for various device interfaces.
This namespace contains representation of robot actions and observations.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
unsigned __int16 uint16_t