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 }
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
size_t Write(const void *Buffer, size_t Count)
Implements the virtual method responsible for writing to the stream.
bool sendCANBusReaderSpeed()
Sends the specified speed to the CAN Converter.
bool read_bool(const std::string &section, 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.
unsigned __int16 uint16_t
Definition: rptypes.h:44
A communications serial port built as an implementation of a utils::CStream.
Definition: CSerialPort.h:47
bool waitACK(uint16_t timeout_ms)
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.
GLenum GLsizei n
Definition: glext.h:5074
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 open()
Open the port.
Definition: CSerialPort.cpp:88
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:76
Contains classes for various device interfaces.
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
bool waitIncomingFrame(uint16_t timeout)
STL namespace.
void setBaudRate(int baud)
Changes the serial port baud rate (call prior to &#39;doProcess&#39;); valid values are 9600,38400 and 500000.
GLdouble s
Definition: glext.h:3676
void setConfig(int baudRate, int parity=0, int bits=8, int nStopBits=1, bool enableFlowControl=false)
Changes the configuration of the port.
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
std::shared_ptr< CObservationCANBusJ1939 > Ptr
This class allows loading and storing values and vectors of different types from a configuration text...
unsigned char uint8_t
Definition: rptypes.h:41
int read_int(const std::string &section, 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)
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
#define RET_ERROR(msg)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
virtual ~CCANBusReader()
Destructor.
This class implements a high-performance stopwatch.
Definition: CTicTac.h:23
This "software driver" implements the communication protocol for interfacing a SICK LMS 2XX laser sca...
Definition: CCANBusReader.h:60
bool isOpen() const
Returns if port has been correctly open.
This namespace contains representation of robot actions and observations.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
GLubyte GLubyte b
Definition: glext.h:6279
void purgeBuffers()
Purge tx and rx buffers.
uint8_t m_received_frame_buffer[2000]
Definition: CCANBusReader.h:91
bool tryToOpenComms(std::string *err_msg=nullptr)
Tries to open the com port and setup all the LMS protocol.
GLsizei const GLchar ** string
Definition: glext.h:4101
#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.
void appendObservation(const mrpt::utils::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
void initialize()
Set-up communication with the laser.
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:60
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Definition: CObservation.h:58
bool sendCommandToCANReader(const uint8_t *cmd, const uint16_t cmd_len, bool wait=true)
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.
Definition: CCANBusReader.h:99
uint16_t m_pgn
The Parameter Group Number within this frame.
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
#define ASSERT_(f)
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
int m_com_baudRate
Baudrate: 9600, 38400, 500000.
uint8_t m_src_address
The address of the source node within this frame.
GLuint res
Definition: glext.h:7268
#define MRPT_LOG_ERROR_STREAM(__CONTENTS)
std::vector< uint8_t > m_data
The data within this frame (0-8 bytes)
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 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".
Definition: os.cpp:355
bool queryVersion(bool printOutVersion=false)
unsigned int m_nTries_connect
Default = 1.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019