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



Page generated by Doxygen 1.8.14 for MRPT 2.0.2 Git: 9b4fd2465 Mon May 4 16:59:08 2020 +0200 at lun may 4 17:26:07 CEST 2020