Main MRPT website > C++ reference for MRPT 1.9.9
CCANBusReader.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 // This file contains portions of code from sicklms200.cc from the Player/Stage
11 // project.
12 
13 #include "hwdrivers-precomp.h" // Precompiled headers
14 
15 #include <mrpt/utils/crc.h>
16 #include <mrpt/utils/CTicTac.h>
17 #include <mrpt/system/os.h>
18 #include <cstdio> // printf
20 
21 #include <thread>
22 
24 
25 #define RET_ERROR(msg) \
26  { \
27  cout << "[" << __CURRENT_FUNCTION_NAME__ << "] " << msg << endl; \
28  return false; \
29  }
30 
31 using namespace std;
32 using namespace mrpt;
33 using namespace mrpt::utils;
34 using namespace mrpt::obs;
35 using namespace mrpt::hwdrivers;
36 
37 char hexCharToInt(char n)
38 {
39  if (n >= '0' && n <= '9')
40  return (n - '0');
41  else
42 
43  if (n >= 'A' && n <= 'F')
44  return (n - 'A' + 10);
45  else
46  return 0;
47 }
48 
49 /*-------------------------------------------------------------
50  CCANBusReader
51 -------------------------------------------------------------*/
52 CCANBusReader::CCANBusReader()
53  : mrpt::utils::COutputLogger("CCANBusReader"),
54  m_com_port(),
55  m_mySerialPort(nullptr),
56  m_com_baudRate(57600),
57  m_nTries_connect(1),
58  m_nTries_current(0),
59  m_canbus_speed(250000),
60  m_canreader_timestamp(false),
61  m_CANBusChannel_isOpen(false)
62 {
63  m_sensorLabel = "CANBusReader";
65 }
66 
67 /*-------------------------------------------------------------
68  ~CCANBusReader
69 -------------------------------------------------------------*/
71 {
73  {
74  try
75  {
77  }
78  catch (...)
79  {
80  }
81  }
82 
83  if (m_mySerialPort)
84  {
85  delete m_mySerialPort;
86  m_mySerialPort = nullptr;
87  }
88 }
89 
91 {
93  mrpt::make_aligned_shared<mrpt::obs::CObservationCANBusJ1939>();
94  bool thereIsObservation;
95  bool hardwareError;
96 
97  doProcessSimple(thereIsObservation, *obs, hardwareError);
98  if (thereIsObservation)
99  appendObservation(obs);
100  else
101  cout << "No frame received" << endl;
102 }
103 
104 /*-------------------------------------------------------------
105  doProcess
106 -------------------------------------------------------------*/
108  bool& outThereIsObservation,
109  mrpt::obs::CObservationCANBusJ1939& outObservation, bool& hardwareError)
110 {
111  outThereIsObservation = false;
112  hardwareError = false;
113 
114  if (!tryToOpenComms())
115  {
116  hardwareError = true;
117  return;
118  }
119 
120  m_state = ssWorking;
121 
122  // Wait for a scan:
123  uint8_t out_prio, out_pdu_format, out_pdu_spec, out_src_address,
124  out_data_length;
125  uint16_t out_pgn;
126  vector<uint8_t> out_data;
127  vector<char> out_raw_frame;
129  out_prio, out_pdu_format, out_pdu_spec, out_src_address,
130  out_data_length, out_pgn, out_data, out_raw_frame))
131  return;
132 
133  // Yes, we have a new scan:
134  // cout << "we've got a frame" << endl;
135  // -----------------------------------------------
136  // Extract the observation:
137  // -----------------------------------------------
138  outObservation.timestamp = mrpt::system::now();
139  outObservation.sensorLabel = m_sensorLabel; // Set label
140 
141  // And the scan ranges:
142  outObservation.m_priority = out_prio;
143  outObservation.m_pdu_spec = out_pdu_spec;
144  outObservation.m_pdu_format = out_pdu_format;
145  outObservation.m_src_address = out_src_address;
146  outObservation.m_pgn = out_pgn;
147  outObservation.m_data_length = out_data_length;
148  outObservation.m_data.resize(out_data.size());
149  for (uint8_t k = 0; k < out_data.size(); ++k)
150  outObservation.m_data[k] = out_data[k];
151  outObservation.m_raw_frame.resize(out_raw_frame.size());
152  for (uint8_t k = 0; k < out_raw_frame.size(); ++k)
153  outObservation.m_raw_frame[k] = out_raw_frame[k];
154 
155  // we've got a new observation
156  outThereIsObservation = true;
157 }
158 
159 /*-------------------------------------------------------------
160  loadConfig_sensorSpecific
161 -------------------------------------------------------------*/
163  const mrpt::utils::CConfigFileBase& configSource,
164  const std::string& iniSection)
165 {
166  // m_sensorPose = CPose3D(
167  // configSource.read_float(iniSection,"pose_x",0),
168  // configSource.read_float(iniSection,"pose_y",0),
169  // configSource.read_float(iniSection,"pose_z",0),
170  // DEG2RAD( configSource.read_float(iniSection,"pose_yaw",0) ),
171  // DEG2RAD( configSource.read_float(iniSection,"pose_pitch",0) ),
172  // DEG2RAD( configSource.read_float(iniSection,"pose_roll",0) )
173  // ); // irrelevant
174 
176  configSource.read_int(iniSection, "CANBusSpeed", m_canbus_speed);
177  m_canreader_timestamp = configSource.read_bool(
178  iniSection, "useCANReaderTimestamp", m_canreader_timestamp);
179 
180 #ifdef MRPT_OS_WINDOWS
181  m_com_port =
182  configSource.read_string(iniSection, "COM_port_WIN", m_com_port, true);
183 #else
184  m_com_port =
185  configSource.read_string(iniSection, "COM_port_LIN", m_com_port, true);
186 #endif
187 
189  configSource.read_int(iniSection, "COM_baudRate", m_com_baudRate);
191  configSource.read_int(iniSection, "nTries_connect", m_nTries_connect);
192 }
193 
194 /*-------------------------------------------------------------
195  Tries to open the com port and setup
196  all the LMS protocol. Returns true if OK or already open.
197 -------------------------------------------------------------*/
199 {
200  if (err_msg) *err_msg = "";
201  try
202  {
203  if (!m_mySerialPort)
204  {
205  // There is no COMMS port open yet...
206  if (!m_com_port.empty())
207  {
208  // cout << "Creating port" << endl;
210  new mrpt::comms::CSerialPort(); // Create the port myself:
211  }
212  else
213  throw std::logic_error(
214  "ERROR: No serial port attached with bindIO, neither it "
215  "set with 'setSerialPort'");
216  }
217 
218  // We assure now we have a stream... try to open it, if it's not done
219  // yet.
220  bool just_open = false;
221  if (m_mySerialPort != nullptr)
222  {
223  if (!m_mySerialPort->isOpen())
224  {
225  // Try to open it now:
227  m_mySerialPort->open(); // will raise an exception on error.
228 
229  // Set basic params:
230  m_mySerialPort->setConfig(9600);
231  m_mySerialPort->setTimeouts(100, 0, 10, 0, 50);
232 
233  just_open = true;
234  }
235  }
236 
237  // It seems the port was open and working so we are done here.
238  if (!just_open) return true;
239 
240  // ==================================================================
241  // Otherwise, it was just opened now, we must send the
242  // ** initialization commands **
243  // and put the CAN Converter in recording mode:
244  // ==================================================================
245  cout << "Setting up serial comms in port " << m_com_port;
246  if (!setupSerialComms()) RET_ERROR("error");
247  cout << " ... done" << endl;
248 
249  // initialize
250  // set CAN Bus speed
251  /**/
252  bool res;
253  cout << "Setting up CAN BUS Speed at: " << m_canbus_speed << endl;
254  for (int nTry = 0; nTry < 250000 /*4*/; nTry++)
255  if (true == (res = sendCANBusReaderSpeed())) break;
256  if (!res) return false;
257  cout << " ... done" << endl;
258 
259  // open the CAN channel. If true, at this point, frames should be poping
260  // out the CAN Bus
261  cout << "Opening CAN BUS and starting to receive." << endl;
262  for (int nTry = 0; nTry < 250000 /*4*/; nTry++)
263  if (true == (res = CANBusOpenChannel())) break;
264  if (!res) return false;
265  cout << " ... done" << endl;
266 
267  // cout << "Autopoll" << endl;
268  // for (int nTry=0;nTry<250000/*4*/;nTry++)
269  // if (true==(res=CANBusAutoPoll()))
270  // break;
271  // if(!res) return false;
272  // cout << " ... done" << endl;
273 
274  return res;
275  /**/
276  }
277  catch (std::exception& e)
278  {
279  std::string s =
280  "[CCANBusReader] Error trying to open CANBusReader at port ";
281  s += e.what();
282  if (err_msg) *err_msg = s;
284  return false;
285  }
286 }
287 
288 /*-------------------------------------------------------------
289  Tries to send the command to set up the speed of the
290  CAN Bus reader -> tractor link
291 -------------------------------------------------------------*/
293 {
294  // command: S0 --> S8 according to the selected speed
295  unsigned char cmd[2];
296 
297  cmd[0] = 'S';
298  switch (m_canbus_speed)
299  {
300  case 10000:
301  cmd[1] = '0';
302  break;
303  case 20000:
304  cmd[1] = '1';
305  break;
306  case 50000:
307  cmd[1] = '2';
308  break;
309  case 100000:
310  cmd[1] = '3';
311  break;
312  case 125000:
313  cmd[1] = '4';
314  break;
315  case 250000:
316  cmd[1] = '5';
317  break;
318  case 500000:
319  cmd[1] = '6';
320  break;
321  case 800000:
322  cmd[1] = '7';
323  break;
324  case 1000000:
325  cmd[1] = '8';
326  break;
327  default:
328  RET_ERROR("Incorrect CAN Bus speed");
329  break;
330  }
331  sendCommandToCANReader(cmd, 2);
332  return waitACK(50);
333 }
334 
336 {
337  unsigned char cmd[1];
338  cmd[0] = 'O';
339  sendCommandToCANReader(cmd, 1);
341  return m_CANBusChannel_isOpen;
342 }
343 
345 {
346  unsigned char cmd[1];
347  cmd[0] = 'C';
348  sendCommandToCANReader(cmd, 1);
349  // m_CANBusChannel_isOpen = !waitACK(50);
350  m_CANBusChannel_isOpen = false;
351  // return !m_CANBusChannel_isOpen;
352  return true;
353 }
354 
356 {
357  unsigned char cmd[1];
358  cmd[0] = 'A';
359  sendCommandToCANReader(cmd, 1);
360  return waitACK(50);
361 }
362 
364 {
365  unsigned char cmd[2];
366  cmd[0] = 'X';
367  cmd[1] = '1';
368  sendCommandToCANReader(cmd, 2);
369  return waitACK(50);
370 }
371 
373 {
374  unsigned char cmd[1];
375  cmd[0] = 'P';
376  sendCommandToCANReader(cmd, 1);
377  return waitACK(50);
378 }
379 
380 /*-------------------------------------------------------------
381  waitContinuousSampleFrame
382 -------------------------------------------------------------*/
384  uint8_t& out_prio, uint8_t& out_pdu_format, uint8_t& out_pdu_spec,
385  uint8_t& out_src_address, uint8_t& out_data_length, uint16_t& out_pgn,
386  vector<uint8_t>& out_data, vector<char>& out_raw_frame)
387 {
388  size_t nRead, nBytesToRead;
389  size_t nFrameBytes = 0;
390  size_t lengthField;
391  unsigned char buf[40];
392 
393  // clear buffer
394  for (uint8_t k = 0; k < 40; ++k) buf[k] = 0;
395 
396  uint8_t dlc = 0;
397  while (nFrameBytes < (lengthField = (10U + dlc + 1U)))
398  {
399  // cout << "trying to receive" << endl;
400  if (lengthField > 30)
401  {
402  cout << "#" << int(dlc) << " ";
403  nFrameBytes = 0; // No es cabecera de trama correcta
404  for (uint8_t k = 0; k < 40; ++k) buf[k] = 0;
405  dlc = 0;
406  }
407 
408  if (nFrameBytes < 10)
409  nBytesToRead = 1;
410  else
411  {
412  dlc = 2 * uint8_t(hexCharToInt(buf[9]));
413  // cout << "dlc: " << int(dlc) << endl;
414  nBytesToRead = (lengthField)-nFrameBytes;
415  }
416 
417  try
418  {
419  nRead = m_mySerialPort->Read(buf + nFrameBytes, nBytesToRead);
420  // cout << "to read: " << nBytesToRead << " received: " <<
421  // nRead << " -> ";
422  // for( uint8_t k = 0; k < nRead; ++k )
423  // cout << int(buf[k+nFrameBytes]);
424  // cout << endl;
425  }
426  catch (std::exception& e)
427  {
428  // Disconnected?
430  "[waitContinuousSampleFrame] Disconnecting due to comms error: "
431  << e.what());
432  return false;
433  }
434 
435  if (!nRead) return false;
436 
437  if (nRead < nBytesToRead) std::this_thread::sleep_for(30ms);
438 
439  // Reading OK:
440  // Was it the first one?
441  if (nFrameBytes > 0 || (nFrameBytes == 0 && buf[0] == 0x54 /*T*/))
442  nFrameBytes += nRead;
443  else
444  {
445  nFrameBytes = 0; // No es cabecera de trama correcta
446  for (uint8_t k = 0; k < 40; ++k) buf[k] = 0;
447  }
448  } // end while
449 
450  // Process frame
451  // convert ASCII text into integer
452  vector<uint8_t> aux;
453  out_raw_frame.resize(nFrameBytes);
454  for (uint8_t k = 0; k < nFrameBytes; ++k)
455  {
456  aux.push_back(hexCharToInt(buf[k]));
457  out_raw_frame[k] = buf[k];
458  }
459 
460  out_prio = (aux[1] << 2) | (aux[2] >> 2);
461  out_pdu_format = (aux[3] << 4) | aux[4];
462  out_pdu_spec = (aux[5] << 4) | aux[6];
463  out_src_address = (aux[7] << 4) | aux[8];
464  out_data_length = aux[9];
465  out_pgn = uint16_t(out_pdu_format) << 8 | uint16_t(out_pdu_spec);
466  out_data.resize(out_data_length);
467  for (uint8_t k = 0, k2 = 0; k < 2 * out_data_length; k += 2, k2++)
468  out_data[k2] = (aux[10 + k] << 4) | aux[11 + k];
469 
470  if (buf[nFrameBytes - 1] != 0x0D)
471  {
472  cout << format(
473  "[CCANBusReader::waitContinuousSampleFrame] expected 0x0D "
474  "ending flag, 0x%X found instead",
475  buf[nFrameBytes])
476  << endl;
477  return false; // Bad ending flag
478  }
479 
480  // All OK
481  return true;
482 }
483 
484 /*-------------------------------------------------------------
485  initialize
486 -------------------------------------------------------------*/
488 {
489  string err_str;
491  if (!tryToOpenComms(&err_str))
492  {
493  cerr << err_str << endl;
494  throw std::logic_error(err_str);
495  }
496 }
497 
498 /*-----------------------------------------------------------------
499  Assures laser is connected and operating at 38400, in
500  its case returns true.
501  -----------------------------------------------------------------*/
503 {
504  ASSERT_(
505  m_com_baudRate == 9600 || m_com_baudRate == 38400 ||
506  m_com_baudRate == 57600 || m_com_baudRate == 500000);
507 
508  if (m_mySerialPort == nullptr) return true;
509 
510  int detected_rate = 0;
511  for (size_t reps = 0; !detected_rate && reps < m_nTries_connect; reps++)
512  {
513  m_nTries_current = reps;
514 
515  int rates[] = {0, 9600, 38400, 57600, 500000};
516 
517  // Try first the desired rate to speed up the process, just in case
518  // the converter is already setup from a previous run:
519  rates[0] = m_com_baudRate;
520 
521  detected_rate = 0;
522 
523  for (size_t i = 0;
524  !detected_rate && i < sizeof(rates) / sizeof(rates[0]); i++)
525  {
526  // Are we already receiving at 500k?
527  // ------------------------------------------------
528  m_mySerialPort->setConfig(rates[i]);
529  std::this_thread::sleep_for(100ms);
531 
532  // close the connection
533  /**/
534  cout << endl << "Closing CAN Channel " << endl;
535  for (int nTry = 0; nTry < 250000 /*4*/; nTry++)
536  if (true == CANBusCloseChannel()) break;
537  cout << " ... done" << endl;
538  /**/
539 
540  std::this_thread::sleep_for(100ms);
542 
543  for (int nTry = 0; nTry < 250000 /*4*/ && !detected_rate; nTry++)
544  {
546 
547  // Ask for the laser version at the current rate:
548  if (queryVersion(true))
549  {
550  detected_rate = rates[i];
551  break;
552  }
553  std::this_thread::sleep_for(20ms);
554  } // for tries
555  // There is no link, or the baudrate is wrong...
556  }
557 
558  // Try again in a while:
559  if (!detected_rate && reps != (m_nTries_connect - 1))
560  std::this_thread::sleep_for(5000ms);
561  }
562 
563  // Switch "this" serial port to the detected baudrate
564  setBaudRate(detected_rate);
565 
568 
569  // Wait...
570  std::this_thread::sleep_for(500ms);
571 
572  // And check comms at the new baud rate:
573  return true;
574 }
575 
576 /*-----------------------------------------------------------------
577  Query to LMS a status query.
578  Returns true if response is read ok.
579  -----------------------------------------------------------------*/
580 bool CCANBusReader::queryVersion(bool printOutVersion)
581 {
583 
584  uint8_t cmd[1];
585  cmd[0] = 'V';
586  uint16_t cmd_len = 1;
587 
588  if (!sendCommandToCANReader(cmd, cmd_len, false)) return false;
589  return waitForVersion(500, printOutVersion);
590 }
591 
592 // Returns false if timeout
594 {
595  uint8_t b = 0;
596  CTicTac tictac;
597  tictac.Tic();
598 
599  do
600  {
601  if (m_mySerialPort->Read(&b, 1))
602  {
603  // Byte rx:
604  if (b == 0x0D /*0x30*/)
605  {
606  cout << int(b) << endl;
607  return true; // [CR]
608  }
609  }
610  } while (tictac.Tac() < timeout_ms * 1e-3);
611 
612  if (b == 0x07) // [BELL]
613  RET_ERROR(format("ERROR received."))
614  else if (b != 0)
615  RET_ERROR(format("Unexpected code received: 0x%02X", b))
616  else
617  return false; // RET_ERROR("Timeout")
618 }
619 
620 bool CCANBusReader::waitForVersion(uint16_t timeout, bool printOutVersion)
621 {
622  uint8_t b;
623  unsigned int nBytes = 0;
624 
625  CTicTac tictac;
626  tictac.Tic();
627  const double maxTime = timeout * 1e-3;
628 
629  while (nBytes < 6)
630  {
631  if (m_mySerialPort->Read(&b, 1))
632  {
633  // cout << "received " << nBytes << " bytes: " << char(b)
634  //<<
635  // endl;
636  // First byte must be STX:
637  if (nBytes > 0 || (nBytes == 0 && b == 'V'))
638  {
639  // Store in frame:
640  m_received_frame_buffer[nBytes] = b;
641  nBytes++;
642  }
643  }
644  if (tictac.Tac() >= maxTime)
645  {
646  cout << "Version timeout" << endl;
647  return false; // Timeout
648  }
649  }
650 
651  // Check len:
652  if (m_received_frame_buffer[nBytes - 1] != 0x0D)
653  {
654  printf(
655  "[CCANBusReader::waitForVersion] Error: expected 0x0D final byte, "
656  "received %x\n",
657  m_received_frame_buffer[nBytes - 1]);
658  return false;
659  }
660 
661  if (printOutVersion)
662  {
663  cout << "Version: ";
664  for (uint8_t k = 0; k < nBytes; ++k)
665  cout << char(m_received_frame_buffer[k]);
666  cout << endl;
667  }
668  return true;
669 }
670 // Returns false if timeout
672 {
673  uint8_t b;
674  unsigned int nBytes = 0;
675 
676  CTicTac tictac;
677  tictac.Tic();
678  const double maxTime = timeout * 1e-3;
679  uint8_t dlc = 0;
680  while (nBytes < 10 || (nBytes < (10U + dlc + 1U /*CR*/)))
681  {
682  if (m_mySerialPort->Read(&b, 1))
683  {
684  // First byte must be STX:
685  if (nBytes > 1 || (!nBytes && b == 0x54 /*'T'*/))
686  {
687  // Store in frame:
688  m_received_frame_buffer[nBytes] = b;
689  nBytes++;
690  }
691  if (nBytes == 10)
692  dlc = 2 * uint8_t(
693  hexCharToInt(
694  m_received_frame_buffer[9])); // here is the
695  // number of
696  // BYTES of
697  // data -> 2
698  // hex values
699  // for byte
700  }
701  if (tictac.Tac() >= maxTime) return false; // Timeout
702  }
703  // Check final flag
704  if (m_received_frame_buffer[10U + dlc] != 0x0D)
705  {
706  printf(
707  "[CCANBusReader::waitIncomingFrame] Error: expected 0x0D as final "
708  "flag, received %x\n",
709  m_received_frame_buffer[10U + dlc]);
710  return false;
711  }
712 
713 #if 0
714  printf("RX: ");
715  for (unsigned int i=0;i<nBytes;i++)
716  printf("%02X ",m_received_frame_buffer[i]);
717  printf("\n");
718 #endif
719 
720  // OK
721  return true;
722 }
723 
725  const uint8_t* cmd, const uint16_t cmd_len, bool wait)
726 {
727  MRPT_UNUSED_PARAM(wait);
728  uint8_t cmd_full[1024];
729  ASSERT_(sizeof(cmd_full) > cmd_len);
730 
731  // command is just plain text so no frame header nor CRC is needed
732  memcpy(cmd_full, cmd, cmd_len);
733  cmd_full[cmd_len] = 0x0D; // [CR] at the end
734 
735  const size_t toWrite = cmd_len + 1;
736 
737 #if 1
738  printf("TX: ");
739  for (unsigned int i = 0; i < toWrite; i++) printf("%02X ", cmd_full[i]);
740  printf("\n");
741 #endif
742 
743  // const int NTRIES = 3;
744 
745  // for (int k=0;k<NTRIES;k++)
746  // {
747  if (toWrite != m_mySerialPort->Write(cmd_full, toWrite))
748  {
749  cout << "[CCANBusReader::SendCommandToCANReader] Error writing data to "
750  "serial port."
751  << endl;
752  return false;
753  }
754  return true;
755  // std::this_thread::sleep_for(15ms);
756  // if(wait)
757  // {
758  // if(waitACK(5000))
759  // return true;
760  // std::this_thread::sleep_for(10ms);
761  // }
762  // else
763  // return true; // perform special wait outside this method
764  // }
765 
766  return false;
767 }
#define RET_ERROR(msg)
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)
A communications serial port built as an implementation of a utils::CStream.
Definition: CSerialPort.h:48
bool isOpen() const
Returns if port has been correctly open.
void open()
Open the port.
Definition: CSerialPort.cpp:88
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.
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).
Definition: CSerialPort.h:74
This "software driver" implements the communication protocol for interfacing a SICK LMS 2XX laser sca...
Definition: CCANBusReader.h:61
bool waitIncomingFrame(uint16_t timeout)
bool CANBusCloseChannel()
Closes the CAN Channel.
mrpt::comms::CSerialPort * m_mySerialPort
Will be !=nullptr only if I created it, so I must destroy it at the end.
Definition: CCANBusReader.h:99
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]
Definition: CCANBusReader.h:91
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)
std::string m_com_port
If set to non-empty, the serial port will be attempted to be opened automatically when this class is ...
Definition: CCANBusReader.h:96
bool tryToOpenComms(std::string *err_msg=nullptr)
Tries to open the com port and setup all the LMS protocol.
unsigned int m_nTries_connect
Default = 1.
bool sendCommandToCANReader(const uint8_t *cmd, const uint16_t cmd_len, bool wait=true)
std::string m_sensorLabel
See CGenericSensor.
void appendObservation(const mrpt::utils::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
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)
std::vector< char > m_raw_frame
The ASCII frame.
std::shared_ptr< CObservationCANBusJ1939 > Ptr
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:60
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Definition: CObservation.h:58
This class allows loading and storing values and vectors of different types from a configuration text...
bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This class implements a high-performance stopwatch.
Definition: CTicTac.h:24
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
GLenum GLsizei n
Definition: glext.h:5074
GLuint res
Definition: glext.h:7268
GLubyte GLubyte b
Definition: glext.h:6279
GLdouble s
Definition: glext.h:3676
GLsizei const GLchar ** string
Definition: glext.h:4101
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:355
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:76
#define ASSERT_(f)
Definition: mrpt_macros.h:309
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
Definition: mrpt_macros.h:365
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 format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
unsigned __int16 uint16_t
Definition: rptypes.h:44
unsigned char uint8_t
Definition: rptypes.h:41



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 63ea9d1f1 Thu Nov 23 00:06:53 2017 +0100 at mar 26 may 2026 12:19:29 CEST