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;
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".
bool sendCANBusReaderSpeed()
Sends the specified speed to the CAN Converter.
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.
bool isOpen() const
Returns if port has been correctly open.
bool m_canreader_timestamp
unsigned __int16 uint16_t
A communications serial port built as an implementation of a utils::CStream.
bool waitACK(uint16_t timeout_ms)
void setTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
Changes the timeouts of the port, in milliseconds.
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...
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
CSerialPort * m_mySerialPort
Will be !=NULL only if I created it, so I must destroy it at the end.
bool waitIncomingFrame(uint16_t timeout)
size_t Write(const void *Buffer, size_t Count)
Implements the virtual method responsible for writing to the stream.
void setBaudRate(int baud)
Changes the serial port baud rate (call prior to 'doProcess'); valid values are 9600,38400 and 500000.
void Tic()
Starts the stopwatch.
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...
uint8_t m_priority
The priority.
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
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
bool CANBusCloseChannel()
Closes the CAN Channel.
bool waitForVersion(uint16_t timeout, bool printOutVersion=false)
uint8_t m_pdu_spec
PDU Specific.
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
virtual ~CCANBusReader()
Destructor.
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.
This class implements a high-performance stopwatch.
This "software driver" implements the communication protocol for interfacing a SICK LMS 2XX laser sca...
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.
uint8_t m_received_frame_buffer[2000]
GLsizei const GLchar ** string
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
void initialize()
Set-up communication with the laser.
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).
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...
bool sendCommandToCANReader(const uint8_t *cmd, const uint16_t cmd_len, bool wait=true)
unsigned int m_nTries_current
void purgeBuffers()
Purge tx and rx buffers.
bool m_CANBusChannel_isOpen
uint8_t m_pdu_format
PDU Format.
void open()
Open the port.
std::vector< char > m_raw_frame
The ASCII frame.
uint16_t m_pgn
The Parameter Group Number within this frame.
double Tac()
Stops the stopwatch.
void appendObservation(const mrpt::utils::CSerializablePtr &obj)
Like appendObservations() but for just one observation.
std::string m_com_port
If set to non-empty, the serial port will be attempted to be opened automatically when this class is ...
static CObservationCANBusJ1939Ptr Create()
int m_com_baudRate
Baudrate: 9600, 38400, 500000.
uint8_t m_src_address
The address of the source node within this frame.
#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.
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.
bool queryVersion(bool printOutVersion=false)
unsigned int m_nTries_connect
Default = 1.