RokubiminiSerialImpl.cpp
Go to the documentation of this file.
1 /*
2  * RokubiminiSerialImpl.hpp
3  * Created on: April, 2020
4  * Author(s): Mike Karamousadakis, Ilias Patsiaouras
5  */
6 
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <termios.h>
11 #include <time.h>
12 #include <unistd.h>
13 #include <cerrno>
14 #include <functional>
15 #include <thread>
16 #include <sys/wait.h>
17 #include <asm/ioctls.h>
18 #include <linux/serial.h>
19 #include <sys/ioctl.h>
20 #include <iostream>
21 #include <fstream>
22 #include <string>
23 #include <bitset>
24 #include "ros/ros.h"
28 
29 namespace rokubimini
30 {
31 namespace serial
32 {
33 RokubiminiSerialImpl::RokubiminiSerialImpl(const std::string& name, const std::string& port)
34  : name_(name)
35  , port_(port)
36  , productName_("")
37  , serialNumber_(-1)
38  , usbFileDescriptor_{ -1 }
39  , frameSync_{ false }
40  , usbStreamIn_{ nullptr }
41  , usbStreamOut_{ nullptr }
42  , runInThreadedMode_(true)
43  , connectionThread_()
44  , pollingThread_()
45  , connectionState_(ConnectionState::DISCONNECTED)
46  , errorFlags_{ 0 }
47  , modeState_{ ModeState::RUN_MODE }
48  , isRunning_{ true }
49  , pollingSyncErrorCounter_(0)
50  , frameReceivedCounter_(0)
51  , frameSuccessCounter_(0)
52  , frameCrcErrorCounter_(0)
53  , frameSyncErrorCounter_(0)
54  , maxFrameSyncErrorCounts_(10000)
55  , maxCountOpenSerialPort_(10)
56  , frameOffset_(0)
57  , readTimeout_(MAXIMUM_ACCEPTABLE_TIMEOUT)
58  , timeoutCounter_(0)
59  , dataReady_{ false }
60  , runsAsync_{ false }
61  , frameDataStatus_()
62 {
63 }
64 
66 {
67  ROS_DEBUG("[%s] Attempting to init device.", name_.c_str());
68 
69  // Connect to serial port
70  if (connect())
71  {
72  // If running in threaded mode, wait for the connection thread to finish. This either means that connection has been
73  // established or failed.
74  if (runInThreadedMode_ && connectionThread_.joinable())
75  {
76  connectionThread_.join();
77  if (!isConnected())
78  {
79  ROS_ERROR("[%s] Could not establish connection with device. Init failed.", name_.c_str());
80  return false;
81  }
82  }
83  }
84  else
85  {
86  ROS_ERROR("[%s] Could not establish connection with device. Init failed.", name_.c_str());
87  return false;
88  }
89  if (!setInitMode())
90  {
91  ROS_ERROR("[%s] Could not bring device to INIT mode. Init failed.", name_.c_str());
92  return false;
93  }
94  return true;
95 }
96 
98 {
99  // Start the polling thread if driver is to run in threaded mode and
100  // if the polling thread is not already running
101  if (runInThreadedMode_ && !pollingThread_.joinable())
102  {
103  ROS_INFO("[%s] Launching polling thread.", name_.c_str());
104  pollingThread_ = boost::thread{ &RokubiminiSerialImpl::pollingWorker, this };
105  }
106  return true;
107 }
108 
110 {
111  ROS_INFO_STREAM("[" << getName() << "] "
112  << "The following serial device has been found and initialized:");
113  ROS_INFO_STREAM("[" << getName() << "] "
114  << "Port: " << port_);
115  ROS_INFO_STREAM("[" << getName() << "] "
116  << "Name: '" << productName_ << "'");
117  ROS_INFO_STREAM("[" << getName() << "] "
118  << "S/N: " << serialNumber_);
119  return true;
120 }
121 
123 {
124  // Close the serial-port file descriptior
125  if (usbFileDescriptor_ != -1)
126  {
127  ROS_DEBUG("[%s] Closing Serial Communication", name_.c_str());
128  close(usbFileDescriptor_);
129  }
130  usbStreamIn_.close();
131  usbStreamOut_.close();
132  if (((usbStreamIn_.fail() | usbStreamOut_.fail()) != 0))
133  {
134  ROS_ERROR("[%s] Failed to close file streams.", name_.c_str());
135  }
136 }
137 
139 {
140  ROS_INFO("[%s] Driver will attempt to shut-down", name_.c_str());
141 
142  // Signal for termination (all background thread)
143  isRunning_ = false;
144 
145  // change the connection state for ros diagnostics
147 
148  if (runsAsync())
149  {
150  // notify the publishing thread to stop
151  dataReady_ = true;
152  newFrameIsAvailable_.notify_all();
153  }
154 
155  // Shutdown the connection thread if running
156  if (runInThreadedMode_ && connectionThread_.joinable())
157  {
158  connectionThread_.join();
159  }
160 
161  // Shutdown the polling thread if running
162  if (runInThreadedMode_ && pollingThread_.joinable())
163  {
164  pollingThread_.join();
165  }
166  closeSerialPort();
167 
168  ROS_INFO("[%s] Shut-down successful", name_.c_str());
169 }
170 
172 {
173  // Abort attempt if the driver is already in the process of connecting
175  {
176  return false;
177  }
178  else
179  {
181  }
182 
183  // Close the file descriptor if it was already open
184  if (usbFileDescriptor_ != -1)
185  {
186  close(usbFileDescriptor_);
187  usbFileDescriptor_ = -1;
188  }
189 
190  // Reset error counters and error state
195  timeoutCounter_ = 0;
196  errorFlags_ = { 0 };
197 
198  // Check if the driver is set to run in threaded mode
199  if (!runInThreadedMode_)
200  {
201  return initSensorCommunication(false);
202  }
203  else
204  {
205  // Start the connection thread
207  }
208 
209  return true;
210 }
211 
212 bool RokubiminiSerialImpl::connect(const std::string& port)
213 {
214  port_ = port;
215  return connect();
216 }
217 
219 {
220  ++timeoutCounter_;
221  ROS_WARN_THROTTLE(1.0, "[%s] Timeout reached and didn't get any valid data from the device.", name_.c_str());
222 }
223 
225 {
226  uint32_t stored_chars;
227  bool read_finished = false;
228  timespec t_current, t_previous;
229  double time_delta;
230  char dummy;
232  {
233  /* peek the next available byte and check if is the header.
234  * make sure to consume it after, if it isn't. Using static
235  * variable for the sync flag will preserve status of sync
236  * between calls */
237  time_delta = 0.0;
238  clock_gettime(CLOCK_MONOTONIC, &t_current);
239  while (!frameSync_ && time_delta < readTimeout_)
240  {
241  uint8_t possible_header;
242  /* read bytes 1 by 1 to find the header */
243  possible_header = usbStreamIn_.peek();
244  if (possible_header == frameHeader)
245  {
246  /* read the remaining frame to make check also CRC */
247  usbStreamIn_.read((char*)&frame.bytes, sizeof(frame));
248  if (frame.crc16_ccitt == calcCrc16X25(frame.data.bytes, sizeof(frame.data)))
249  {
250  ROS_INFO("[%s] Frame synced with 0x%X header", name_.c_str(), frameHeader);
251  frameSync_ = true;
252  frameOffset_ = 0;
253  return true;
254  }
255  else
256  {
257  ROS_WARN("[%s] Skipping incomplete frame", name_.c_str());
258  }
259  }
260  else
261  {
262  // consume the wrong header
263  usbStreamIn_.get(dummy);
264  }
265  t_previous = t_current;
266  clock_gettime(CLOCK_MONOTONIC, &t_current);
267  time_delta += diffSec(t_previous, t_current);
268  }
269  if (time_delta > readTimeout_)
270  {
272  return false;
273  }
274  /* Read the sensor measurements frame assuming that is aligned with the RX buffer */
275  try
276  {
277  time_delta = 0.0;
278  clock_gettime(CLOCK_MONOTONIC, &t_current);
279  ROS_DEBUG("[%s] Frame offset before reading is: %u", name_.c_str(), frameOffset_);
280  while (!read_finished && time_delta < readTimeout_)
281  {
282  stored_chars = usbStreamIn_.readsome((char*)&placeholder_.bytes + frameOffset_, sizeof(RxFrame) - frameOffset_);
283  frameOffset_ += stored_chars;
284  if (stored_chars != 0)
285  {
286  if (frameOffset_ < sizeof(RxFrame))
287  {
288  ROS_DEBUG("[%s] Stored chars from the device: %d", name_.c_str(), frameOffset_);
289  }
290  else
291  {
292  uint32_t remainder_bytes = frameOffset_ % sizeof(RxFrame);
293  ROS_DEBUG("[%s] Whole frame received, remaining bytes: %u", name_.c_str(), remainder_bytes);
294  frame = placeholder_;
295  if (remainder_bytes != 0)
296  {
297  memmove((char*)&placeholder_.bytes, (char*)&placeholder_.bytes + sizeof(RxFrame) - remainder_bytes,
298  remainder_bytes);
299  memset((char*)&placeholder_.bytes + remainder_bytes, 0, sizeof(RxFrame) - remainder_bytes);
300  }
301  frameOffset_ = remainder_bytes;
302  read_finished = true;
304  }
305  }
306  t_previous = t_current;
307  clock_gettime(CLOCK_MONOTONIC, &t_current);
308  time_delta += diffSec(t_previous, t_current);
309  }
311  if (time_delta > readTimeout_)
312  {
314  return false;
315  }
316  }
317  catch (std::exception& e)
318  {
319  ROS_ERROR("[%s] Error while reading a packet, %s", name_.c_str(), e.what());
320  // errorState_ = ErrorState::SYNC_ERROR;
322  return false;
323  }
324  /* Check if the frame is still aligned, otherwise exit */
325  if (frame.header != frameHeader)
326  {
327  frameSync_ = false;
328  /* keep some statistics */
330  {
331  ROS_WARN("[%s] Reached max syncing errors. Disconnecting sensor.", name_.c_str());
332  // errorState_ = ErrorState::SYNC_ERROR;
335  }
336  return false;
337  }
338  // Read and check CRC 16-bit
339  try
340  {
341  uint16_t crc_received = frame.crc16_ccitt;
342  uint16_t crc_computed = calcCrc16X25(frame.data.bytes, sizeof(frame.data));
343  if (crc_received != crc_computed)
344  {
346  ROS_WARN("[%s] CRC missmatch received: 0x%04x calculated: 0x%04x", name_.c_str(), crc_received, crc_computed);
347  return false;
348  }
349  }
350  catch (std::exception& e)
351  {
352  ROS_ERROR("[%s] Error while reading a packet, %s", name_.c_str(), e.what());
353  // errorState_ = ErrorState::CRC_ERROR;
354  errorFlags_.crc = 1;
355  return false;
356  }
357 
358  if (frame.data.status.app_took_too_long)
359  {
360  ROS_WARN("[%s] Warning force sensor is skipping measurements, Increase sinc length", name_.c_str());
361  }
362  if (frame.data.status.overrange)
363  {
364  ROS_WARN("[%s] Warning measuring range exceeded", name_.c_str());
365  }
366  if (frame.data.status.invalid_measurements)
367  {
368  ROS_ERROR("[%s] Warning force torque measurements are invalid, Permanent damage may occur", name_.c_str());
369  }
370  if (frame.data.status.raw_measurements)
371  {
372  ROS_WARN_THROTTLE(1.0, "[%s] Warning raw force torque measurements from gages", name_.c_str());
373  }
375  return true;
376  }
377  // This point should not be reached
378  return false;
379 }
380 
382 {
384 }
385 
387 {
389 }
390 
392 {
393  bool ret;
394  ret = (errorFlags_.crc == 1);
395  ret &= (errorFlags_.frame_sync == 1);
396  ret &= (errorFlags_.timeout == 1);
397  ret &= (errorFlags_.polling_sync == 1);
398  return ret;
399 }
400 
402 {
404 }
405 
407 {
408  return connectionState_;
409 }
410 
412 {
413  return errorFlags_;
414 }
415 
416 std::vector<std::string> RokubiminiSerialImpl::getErrorStrings() const
417 {
418  std::vector<std::string> errors;
419  if (hasError())
420  {
421  if (errorFlags_.crc == 1)
422  {
423  errors.emplace_back("CRC Errors have occurred in the Serial Communication.");
424  }
425  if (errorFlags_.frame_sync == 1)
426  {
427  errors.emplace_back("Frame Sync Errors have occurred in the Serial Communication.");
428  }
429  if (errorFlags_.timeout == 1)
430  {
431  errors.emplace_back("Timeout Errors have occurred in the Serial Communication.");
432  }
433  if (errorFlags_.polling_sync == 1)
434  {
435  errors.emplace_back("Polling Sync Errors have occurred in the Serial Communication.");
436  }
437  }
438  else
439  {
440  errors.emplace_back("No error flags set.");
441  }
442  return errors;
443 }
444 
446 {
447  // Block, continuously trying to open and initialize the serial-port, until signaled to stop or the serial port has
448  // been opened
449  bool open_port = false;
450  unsigned int counter_open_serial_port = 0;
451  do
452  {
453  open_port = initSerialPort(port_);
454  } while (isRunning_ && keepOpening && !open_port && counter_open_serial_port++ <= maxCountOpenSerialPort_);
455  if (!isRunning_)
456  {
457  // opening process was cancelled from somewhere else
458  ROS_ERROR("[%s] Sensor is disconnected.", name_.c_str());
460  return false;
461  }
462  return true;
463 }
464 
466 {
467  ROS_DEBUG("[%s] Initializing serial-port at: %s", name_.c_str(), port_.c_str());
468  bool success;
469 
474  for (const auto& baud_rate_option : CODE_TO_BAUD_RATE_MAP)
475  {
476  baudRate_ = baud_rate_option.second;
477  success = openSerialPort(keepOpening);
478  if (!success)
479  {
480  ROS_ERROR("[%s] Could not open serial port %s with baud rate %u", name_.c_str(), port_.c_str(), baudRate_.value);
481  return false;
482  }
483  ROS_DEBUG("[%s] Successful initialization of first communication with baud rate %u", name_.c_str(),
484  baudRate_.value);
486  closeSerialPort();
487  }
488 
495  success = openSerialPort(keepOpening);
496  if (!success)
497  {
498  ROS_ERROR("[%s] Could not open serial port %s with baud rate %u", name_.c_str(), port_.c_str(), baudRate_.value);
499  return false;
500  }
501 
502  ROS_DEBUG("[%s] Successful initialization of first communication with default baud rate.", name_.c_str());
504  success = parseRegexWaitTimeout(comm_setup, 2);
505  if (!success)
506  {
507  ROS_ERROR("[%s] Failed to parse successfully the communication setup", name_.c_str());
508  return false;
509  }
519  if (comm_setup.getBaudRate() != MAX_BAUD_RATE_OPTION)
520  {
522  if (comm_setup.getBaudRate() != DEFAULT_BAUD_RATE_OPTION)
523  {
524  closeSerialPort();
525  baudRate_ = CODE_TO_BAUD_RATE_MAP.find((comm_setup.getBaudRate()))->second;
526  success = openSerialPort(keepOpening);
527  if (!success)
528  {
529  ROS_ERROR("[%s] Could not open serial port %s with baud rate %u", name_.c_str(), port_.c_str(),
530  baudRate_.value);
531  return false;
532  }
533  ROS_DEBUG("[%s] Successful initialization of second communication with baud rate %u", name_.c_str(),
534  baudRate_.value);
535  }
536  // Wait for sensor boot.
537  if (!parseRegexWaitTimeout(regexBoot, 2))
538  {
539  ROS_ERROR("[%s] Failed to parse successfully the boot response", name_.c_str());
540  return false;
541  }
542  // Set the sensor in init mode.
543  if (!setInitMode())
544  {
545  ROS_ERROR("[%s] Device could not switch to init mode", name_.c_str());
546  return false;
547  }
548  // Set the sensor in configuration mode.
549  if (!setConfigMode())
550  {
551  ROS_ERROR("[%s] Device could not switch to config mode", name_.c_str());
552  return false;
553  }
554  if (!parseRegexWaitTimeout(regexBoot, 2))
555  {
556  ROS_ERROR("[%s] Failed to parse successfully the boot response", name_.c_str());
557  return false;
558  }
559  ROS_DEBUG("[%s] Setting max baud rate to device", name_.c_str());
560  // set the maximum baud rate
561  uint8_t max_baud_rate = MAX_BAUD_RATE_OPTION;
562  comm_setup.setBaudRate(max_baud_rate);
563  // leave the rest of the fields (temp. comp., calibration active, data format) as we found them
565  sensor_config.setTemperatureCompensationActive(comm_setup.getTempComp());
566  sensor_config.setCalibrationMatrixActive(comm_setup.getCalibration());
567  uint8_t data_format = 0; // this is required for the driver to operate in binary mode
568  // set the communication setup with the new max baud rate
569  if (!setCommunicationSetup(sensor_config, data_format, comm_setup.getBaudRate()))
570  {
571  ROS_ERROR("[%s] Could not set the communication setup", name_.c_str());
572  return false;
573  }
574  // save the configuration
575  if (!saveConfigParameter())
576  {
577  ROS_ERROR("[%s] Could not save the configuration to the device", name_.c_str());
578  return false;
579  }
580  // set hardware reset to device
581  if (!setHardwareReset())
582  {
583  ROS_ERROR("[%s] Device could not switch to run mode", name_.c_str());
584  return false;
585  }
586  }
587  closeSerialPort();
588  ROS_DEBUG("[%s] Re-initializing serial-port at: %s with maximum baud rate", name_.c_str(), port_.c_str());
589 
591  success = openSerialPort(keepOpening);
592  if (!success)
593  {
594  ROS_ERROR("[%s] Could not open serial port %s with baud rate %u", name_.c_str(), port_.c_str(), baudRate_.value);
595  return false;
596  }
599  if (!parseRegexWaitTimeout(reg, 2))
600  {
601  ROS_ERROR("[%s] Failed to parse successfully the boot response.", name_.c_str());
602  return false;
603  }
604  if (!parseCommunicationMsgs())
605  {
606  ROS_ERROR("[%s] Failed to parse successfully the communication msgs.", name_.c_str());
607  return false;
608  }
609  // Finally if the whole process succeeded, change the connection state to CONNECTED.
611  return true;
612 }
613 
615 {
616  std::string str, tmp_str;
617  timespec t_start, t_current;
618  clock_gettime(CLOCK_MONOTONIC, &t_start);
619  t_current = t_start;
620  while (diffSec(t_start, t_current) < timeout) // run the loop for timeout seconds.
621  {
622  readSerialNoWait(1, tmp_str);
623  if (tmp_str.size() > 0)
624  {
625  str.append(tmp_str);
626  if (reg.matchInString(str))
627  {
628  ROS_DEBUG("[%s] Found exact match: %s, time: %f", name_.c_str(), str.c_str(), diffSec(t_start, t_current));
629  return true;
630  }
631  }
632  clock_gettime(CLOCK_MONOTONIC, &t_current);
633  }
634  return false;
635 }
636 
637 bool RokubiminiSerialImpl::readSerialNoWait(const uint32_t& numChars, std::string& str)
638 {
639  char buffer[numChars];
640  uint32_t stored_chars;
641  stored_chars = usbStreamIn_.readsome(buffer, sizeof(buffer));
642  str.assign(buffer, stored_chars);
643  // return whether there were any chars to read
644  return (stored_chars != 0);
645 }
646 
647 bool RokubiminiSerialImpl::readSerialWaitTimeout(const uint32_t& numChars, std::string& str, const double& timeout)
648 {
649  char buffer[numChars];
650  uint32_t read_offset = 0, stored_chars;
651  timespec t_start, t_current;
652  clock_gettime(CLOCK_MONOTONIC, &t_start);
653  t_current = t_start;
654  while (diffSec(t_start, t_current) < timeout) // run the loop for timeout seconds.
655  {
656  /* run the next readsome() only if there are available bytes in the input buffer.*/
657  if (usbStreamIn_.rdbuf()->in_avail() > 0)
658  {
659  stored_chars = usbStreamIn_.readsome((char*)&buffer[read_offset], sizeof(buffer) - read_offset);
660  read_offset += stored_chars;
661  }
662  clock_gettime(CLOCK_MONOTONIC, &t_current);
663  }
664  str.assign(buffer, read_offset);
665  // return whether there were any chars to read
666  return (read_offset != 0);
667 }
668 
670 {
671  RokubiminiSerialResponseRegexProductName product_name_regex;
672  bool success = parseRegexWaitTimeout(product_name_regex);
673  if (!success)
674  {
675  ROS_ERROR("[%s] Failed to parse Product Name of the serial device", name_.c_str());
676  return false;
677  }
678  productName_ = product_name_regex.getProductName();
679  RokubiminiSerialResponseRegexSerialNumber serial_number_regex;
680  success &= parseRegexWaitTimeout(serial_number_regex);
681  if (!success)
682  {
683  ROS_ERROR("[%s] Failed to parse Serial Number of the serial device", name_.c_str());
684  return false;
685  }
686 
687  RokubiminiSerialResponseRegexFirmwareVersion firmware_version_regex;
688  success &= parseRegexWaitTimeout(firmware_version_regex);
689  if (!success)
690  {
691  ROS_ERROR("[%s] Failed to parse Firmware Version of the serial device", name_.c_str());
692  return false;
693  }
694 
695  serialNumber_ = serial_number_regex.getSerialNumber();
696  return true;
697 }
698 
699 bool RokubiminiSerialImpl::initSerialPort(const std::string& port)
700 {
701  // int flags;
702  termios newtio;
703  struct serial_struct ser_info;
704 
705  // make the fstreams unbuffered
706  usbStreamIn_.rdbuf()->pubsetbuf(nullptr, 0);
707  usbStreamOut_.rdbuf()->pubsetbuf(nullptr, 0);
708 
709  // Open the Serial Port
710  usbFileDescriptor_ = open(port.c_str(), O_RDWR | O_NOCTTY);
711  if (usbFileDescriptor_ < 0)
712  {
713  ROS_ERROR_THROTTLE(1.0, "[%s] Failed to open serial-port: '%s'", name_.c_str(), port.c_str());
714  return false;
715  }
716 
717  // Get the Serial Descriptor Flags
718  if (tcgetattr(usbFileDescriptor_, &newtio) < 0)
719  {
720  ROS_ERROR("[%s] Failed to get connection attributes.", name_.c_str());
721  return false;
722  }
723 
724  // Set the Serial Speed
725  cfsetispeed(&newtio, baudRate_.mask);
726  cfsetospeed(&newtio, baudRate_.mask);
727 
728  cfmakeraw(&newtio);
729 
730  // Set the Serial Connection Attributes (SCA)
731  if (tcsetattr(usbFileDescriptor_, TCSAFLUSH, &newtio) < 0)
732  {
733  ROS_ERROR("[%s] Failed to set connection attributes.", name_.c_str());
734  return false;
735  }
736 
737  // Flush the input and output streams
738  if (tcflush(usbFileDescriptor_, TCIOFLUSH) < 0)
739  {
740  ROS_ERROR("[%s] Failed to flush the input and output streams.", name_.c_str());
741  return false;
742  }
743 
744  // Enable linux FTDI low latency mode
745  ioctl(usbFileDescriptor_, TIOCGSERIAL, &ser_info);
746  ser_info.flags |= ASYNC_LOW_LATENCY;
747  ioctl(usbFileDescriptor_, TIOCSSERIAL, &ser_info);
748 
749  // Get the Serial Descriptor Flags
750  if (fcntl(usbFileDescriptor_, F_GETFL) < 0)
751  {
752  ROS_ERROR("[%s] Failed to set the descriptor flags.", name_.c_str());
753  return false;
754  }
755 
756  // create a std stream to read and write from/to device
757  usbStreamIn_.open(port.c_str(), std::ifstream::in);
758  usbStreamOut_.open(port.c_str(), std::ofstream::out);
759  if (((usbStreamIn_.fail() | usbStreamOut_.fail()) != 0))
760  {
761  ROS_ERROR("[%s] Failed to open file streams.", name_.c_str());
762  return false;
763  }
764  return true;
765 }
766 
767 inline uint16_t RokubiminiSerialImpl::calcCrc16X25(uint8_t* data, int len)
768 {
769  uint16_t crc = 0xFFFF;
770  while (len--)
771  crc = crcCcittUpdate(crc, *data++);
772  return ~crc;
773 }
774 
775 uint16_t RokubiminiSerialImpl::crcCcittUpdate(uint16_t crc, uint8_t data)
776 {
777 #define lo8(x) ((x)&0xFF)
778 #define hi8(x) (((x) >> 8) & 0xFF)
779  data ^= lo8(crc);
780  data ^= data << 4;
781 
782  return ((((uint16_t)data << 8) | hi8(crc)) ^ (uint8_t)(data >> 4) ^ ((uint16_t)data << 3));
783 }
784 
786 {
788 }
789 
791 {
792  // Configure the scheduling policy for the polling thread
793  int priority = 99;
794  sched_param params;
795  params.sched_priority = priority;
796  if (sched_setscheduler(getpid(), SCHED_FIFO, &params) != 0)
797  {
798  ROS_WARN("[%s] Failed to set thread priority to %d: %s.", name_.c_str(), priority, std::strerror(errno));
799  }
800 
801  // Wait for connection to be established before starting to poll
802  usleep(10000);
803  if (!isConnected())
804  {
805  while (!isConnected() && isRunning_)
806  {
807  usleep(1000);
808  ROS_WARN_THROTTLE(4.0, "[%s] Polling thread waiting for connection. ", name_.c_str());
809  }
810  }
811  uint32_t time_stamp_previous, time_stamp = 0;
812  double time_stamp_diff;
813 
814  // Variables for timing
815  timespec t_current, t_cycle = { 0 /* initialize t_cycle to avoid may-be-uninitialized errors */ }, t_loop;
816  bool run_processing = true;
817  unsigned long loop_counter = 0;
819  double int_part;
820 
821  // Start sensor polling
823  {
824  clock_gettime(CLOCK_MONOTONIC, &t_current);
825  // Poll the serial device, skipping processing in current iteration if no valid data has been received
826  RxFrame frame;
827 
828  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
829  (this->readDevice(frame)) ? (run_processing = true) : (run_processing = false);
830  lock.unlock();
831  // TODO: check if PID of sent data and PID configured match
832  // We have to check the connection again because readDevice() may have signalled to disconnect
833  // if too many communication errors occurred
834  if (connectionState_ == ConnectionState::CONNECTED && run_processing)
835  {
836  /* Set the time-stamp */
837  time_stamp_previous = time_stamp;
838  time_stamp = frame.data.timestamp;
839  time_stamp_diff = static_cast<double>(time_stamp - time_stamp_previous) * 1e-6;
840  if (time_stamp_previous > time_stamp)
841  {
842  ROS_WARN("[%s] Time stamp difference is negative: Time counter has wrapped: current time stamp=%u, previous "
843  "time stamp=%u and time "
844  "stamp diff=%f",
845  name_.c_str(), time_stamp, time_stamp_previous, time_stamp_diff);
846  }
847 
848  // change the t_cycle so that the loop time can adapt to the Hz of the sensor
849  readTimeout_ = (time_stamp_diff < MAXIMUM_ACCEPTABLE_TIMEOUT) ?
850  FTDI_DRIVER_LATENCY + (1 + TIMEOUT_MARGIN) * time_stamp_diff :
852  if (frameSuccessCounter_ <= 1 || usbStreamIn_.rdbuf()->in_avail() >= static_cast<long int>(sizeof(RxFrame)))
853  {
854  time_stamp_diff = 0;
855  }
856  // Use a scaling factor (0.9) to avoid sleeping to long.
857  t_cycle.tv_nsec = NSEC_PER_SEC * modf(time_stamp_diff * 0.9, &int_part);
858  t_cycle.tv_sec = static_cast<uint64_t>(int_part);
859 
860  // Store the final measurement into the primary buffer
861  {
862  std::lock_guard<std::mutex> lock(readingMutex_);
863  frame_ = frame;
864  frameDataStatus_ = frame.data.status;
865  dataReady_ = true;
866  }
867  if (runsAsync())
868  {
869  newFrameIsAvailable_.notify_one();
870  }
871  }
872  clock_gettime(CLOCK_MONOTONIC, &t_current);
873  t_loop = timespecAdd(t_current, t_cycle);
874  // Sleep to avoid too fast polling
875  clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_loop, nullptr);
876  loop_counter++;
877  }
878 
879  // Show error statistics if errors have been detected
881  (timeoutCounter_ > 0))
882  {
883  ROS_WARN("[%s] Sensor polling thread error report:", name_.c_str());
884  ROS_WARN("[%s] Total iterations: %lu", name_.c_str(), loop_counter);
885  ROS_WARN("[%s] Frames received: %lu, (%f%%)", name_.c_str(), frameReceivedCounter_,
886  100.0 * ((double)frameReceivedCounter_ / (double)loop_counter));
887  ROS_WARN("[%s] Correct frames: %lu, (%f%%)", name_.c_str(), frameSuccessCounter_,
888  100.0 * ((double)frameSuccessCounter_ / (double)frameReceivedCounter_));
889  ROS_WARN("[%s] Polling sync errors: %lu, (%f%%)", name_.c_str(), pollingSyncErrorCounter_,
890  100.0 * ((double)pollingSyncErrorCounter_ / (double)loop_counter));
891  ROS_WARN("[%s] Frame CRC errors: %lu, (%f%%)", name_.c_str(), frameCrcErrorCounter_,
892  100.0 * ((double)frameCrcErrorCounter_ / (double)frameReceivedCounter_));
893  ROS_WARN("[%s] Frame sync errors: %d", name_.c_str(), frameSyncErrorCounter_);
894  ROS_WARN("[%s] Timeout errors: %d", name_.c_str(), timeoutCounter_);
895  }
896 }
897 
899 {
900  if (isConnected())
901  {
902  {
903  std::unique_lock<std::mutex> lock(readingMutex_);
904  if (runsAsync())
905  {
906  newFrameIsAvailable_.wait(lock, [&] { return dataReady_; });
907  }
908  if (isRunning_)
909  {
910  dataReady_ = false;
912  serialImplReading_.getWrench().header.frame_id = name_ + "_wrench";
913  serialImplReading_.getWrench().wrench.force.x = frame_.data.forces[0];
914  serialImplReading_.getWrench().wrench.force.y = frame_.data.forces[1];
915  serialImplReading_.getWrench().wrench.force.z = frame_.data.forces[2];
916  serialImplReading_.getWrench().wrench.torque.x = frame_.data.forces[3];
917  serialImplReading_.getWrench().wrench.torque.y = frame_.data.forces[4];
918  serialImplReading_.getWrench().wrench.torque.z = frame_.data.forces[5];
919 
921  serialImplReading_.getTemperature().header.frame_id = name_ + "_temp";
922  serialImplReading_.getTemperature().temperature = frame_.data.temperature;
923  serialImplReading_.getTemperature().variance = 0; // unknown variance
924  reading = serialImplReading_;
925  }
926  }
927  }
928 }
929 
931 {
932  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
933  auto config_command = RokubiminiSerialCommandConfig();
934  std::string str;
935  bool success = true;
936  if (!config_command.formatCommand(str))
937  {
938  ROS_ERROR("[%s] Could not format the config command", name_.c_str());
939  return false;
940  }
941 
942  success &= sendCommand(str);
943  if (!success)
944  {
945  lock.unlock();
946  return false;
947  }
948  else
949  {
951  lock.unlock();
952  if (runInThreadedMode_ && pollingThread_.joinable())
953  {
954  pollingThread_.join();
955  }
956  // Reset error counters and error state
961  timeoutCounter_ = 0;
962  errorFlags_ = { 0 };
963  return true;
964  }
965 }
966 
968 {
969  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
970  auto run_command = RokubiminiSerialCommandRun();
971  std::string str;
972  if (!run_command.formatCommand(str))
973  {
974  ROS_ERROR("[%s] Could not format the run command", name_.c_str());
975  return false;
976  }
977  bool success = sendCommand(str);
978  lock.unlock();
979  if (!success)
980  {
981  return false;
982  }
983 
985  // Start a new polling thread.
986  return startPollingThread();
987 }
988 
990 {
991  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
992  auto hard_reset_command = RokubiminiSerialCommandHardReset();
993  std::string str;
994  if (!hard_reset_command.formatCommand(str))
995  {
996  ROS_ERROR("[%s] Could not format the hardware reset command", name_.c_str());
997  return false;
998  }
999  bool success = writeSerial(str);
1000  lock.unlock();
1001  return success;
1002 }
1003 
1005 {
1006  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1007  auto soft_reset_command = RokubiminiSerialCommandSoftReset();
1008  std::string str;
1009  if (!soft_reset_command.formatCommand(str))
1010  {
1011  ROS_ERROR("[%s] Could not format the software reset command", name_.c_str());
1012  return false;
1013  }
1014  bool success = sendCommand(str);
1015  if (!success)
1016  {
1017  lock.unlock();
1018  return false;
1019  }
1020  else
1021  {
1023  lock.unlock();
1024 
1025  if (runInThreadedMode_ && pollingThread_.joinable())
1026  {
1027  pollingThread_.join();
1028  }
1029  // Reset error counters and error state
1034  errorFlags_ = { 0 };
1035  return true;
1036  }
1037 }
1038 
1040 {
1041  if (!isInConfigMode())
1042  {
1043  return false;
1044  }
1045 
1046  ROS_DEBUG("[%s] Setting force/torque filter", name_.c_str());
1047  ROS_DEBUG("[%s] \tsize: %u", name_.c_str(), filter.getSincFilterSize());
1048  ROS_DEBUG("[%s] \tchop: %u", name_.c_str(), filter.getChopEnable());
1049  ROS_DEBUG("[%s] \tfast: %u", name_.c_str(), filter.getFastEnable());
1050  ROS_DEBUG("[%s] \tskip: %u", name_.c_str(), filter.getSkipEnable());
1051 
1052  auto filter_command = RokubiminiSerialCommandFilter(filter);
1053  std::string str;
1054  if (!filter_command.formatCommand(str))
1055  {
1056  ROS_ERROR("[%s] Could not format the filter command", name_.c_str());
1057  return false;
1058  }
1059  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1060  bool success = sendCommand(str);
1061  lock.unlock();
1062  return success;
1063 }
1064 
1065 bool RokubiminiSerialImpl::setForceTorqueOffset(const Eigen::Matrix<double, 6, 1>& forceTorqueOffset)
1066 {
1067  if (!isInConfigMode())
1068  {
1069  return false;
1070  }
1071 
1072  ROS_DEBUG_STREAM("[" << name_.c_str() << "] Setting Force/Torque offset: " << forceTorqueOffset << std::endl);
1073  auto offset_command = RokubiminiSerialCommandOffset(forceTorqueOffset);
1074  std::string str;
1075  if (!offset_command.formatCommand(str))
1076  {
1077  ROS_ERROR("[%s] Could not format the force torque offset command", name_.c_str());
1078  return false;
1079  }
1080  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1081  bool success = sendCommand(str);
1082  lock.unlock();
1083  return success;
1084 }
1085 
1087 {
1088  if (!isInConfigMode())
1089  {
1090  return false;
1091  }
1092  char buffer[100];
1093  bool success = true;
1094  for (uint32_t row = 0; row < 6; row++)
1095  {
1096  auto sensor_calibration_row_command = RokubiminiSerialCommandSensorCalibrationRow(
1097  sensorCalibration.getCalibrationMatrix()(row, 0), sensorCalibration.getCalibrationMatrix()(row, 1),
1098  sensorCalibration.getCalibrationMatrix()(row, 2), sensorCalibration.getCalibrationMatrix()(row, 3),
1099  sensorCalibration.getCalibrationMatrix()(row, 4), sensorCalibration.getCalibrationMatrix()(row, 5), row);
1100  std::string str;
1101  if (!sensor_calibration_row_command.formatCommand(str))
1102  {
1103  ROS_ERROR("[%s] Could not format the calibration matrix command", name_.c_str());
1104  return false;
1105  }
1106  ROS_DEBUG_STREAM("[" << name_.c_str() << "] Calibration matrix line is: " << str << ". Size is " << str.size());
1107  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1108  success &= sendCommand(str);
1109  lock.unlock();
1110  memset(buffer, 0, sizeof(buffer));
1111  // Sleep for 10.0 milliseconds before sending the next chunk of data.
1112  std::this_thread::sleep_for(std::chrono::microseconds(10000));
1113  }
1114  return success;
1115 }
1116 
1118 {
1119  if (!isInConfigMode())
1120  {
1121  return false;
1122  }
1123  ROS_DEBUG("[%s] Setting sensor configuration", name_.c_str());
1124  uint8_t baud_rate = MAX_BAUD_RATE_OPTION;
1125  uint8_t data_format = 0;
1126  return setCommunicationSetup(sensorConfiguration, data_format, baud_rate);
1127 }
1128 
1130  const uint8_t& dataFormat, const uint8_t& baudRate)
1131 {
1132  ROS_DEBUG("[%s] Setting communication setup with baud rate: %u, data format: %u, temp comp: %u and calibration: %u",
1133  name_.c_str(), baudRate, dataFormat, sensorConfiguration.getTemperatureCompensationActive(),
1134  sensorConfiguration.getCalibrationMatrixActive());
1135  auto comm_setup = RokubiminiSerialCommandCommSetup(sensorConfiguration, dataFormat, baudRate);
1136  std::string str;
1137  if (!comm_setup.formatCommand(str))
1138  {
1139  ROS_ERROR("[%s] Could not format the communication setup command", name_.c_str());
1140  return false;
1141  }
1142  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1143  bool success = sendCommand(str);
1144  lock.unlock();
1145  return success;
1146 }
1147 
1149 {
1150  if (!isInConfigMode())
1151  {
1152  return false;
1153  }
1154  auto save_config = RokubiminiSerialCommandSave();
1155  std::string str;
1156  if (!save_config.formatCommand(str))
1157  {
1158  ROS_ERROR("[%s] Could not format the save config command", name_.c_str());
1159  return false;
1160  }
1161  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1162  bool success = sendCommand(str);
1163  lock.unlock();
1164  return success;
1165 }
1166 
1168 {
1169  if (!isInConfigMode())
1170  {
1171  return false;
1172  }
1173  auto load_config = RokubiminiSerialCommandLoad();
1174  std::string str;
1175  if (!load_config.formatCommand(str))
1176  {
1177  ROS_ERROR("[%s] Could not format the load config command", name_.c_str());
1178  return false;
1179  }
1180  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1181  bool success = sendCommand(str);
1182  lock.unlock();
1183  return success;
1184 }
1185 
1187 {
1188  if (!isInConfigMode())
1189  {
1190  return false;
1191  }
1192  auto print_config = RokubiminiSerialCommandPrint();
1193  std::string str;
1194  if (!print_config.formatCommand(str))
1195  {
1196  ROS_ERROR("[%s] Could not format the print config command", name_.c_str());
1197  return false;
1198  }
1199  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1200  bool success = sendCommand(str);
1201  lock.unlock();
1202  if (!success)
1203  {
1204  return false;
1205  }
1206  uint8_t c;
1207  uint64_t timespec_diff_ns;
1208  timespec tnow, t_loop;
1209  clock_gettime(CLOCK_MONOTONIC, &tnow);
1210  t_loop = tnow;
1211  lock.lock();
1212  ROS_INFO("[%s] Printing user configuration:", name_.c_str());
1213  do
1214  {
1215  /* run the next readsome() only if there are available bytes in the input buffer.*/
1216  if (usbStreamIn_.rdbuf()->in_avail() > 0)
1217  {
1218  /* read bytes 1 by 1 and print them.*/
1219  usbStreamIn_.readsome((char*)&c, 1);
1220  printf("%c", c);
1221  }
1222  clock_gettime(CLOCK_MONOTONIC, &t_loop);
1223  timespec_diff_ns = (t_loop.tv_sec - tnow.tv_sec) * 1e9 + (t_loop.tv_nsec - tnow.tv_nsec);
1224  } while (timespec_diff_ns < 1e9); // run the loop for 1sec.
1225  lock.unlock();
1226  return true;
1227 }
1228 
1229 bool RokubiminiSerialImpl::sendCommand(const std::string& command)
1230 {
1231  bool success = true;
1232  success &= clearReadBuffer();
1233  success &= writeSerial(command);
1234  success &= parseAcknowledgement(command.front()); // the first character represents the type of command
1235  return success;
1236 }
1237 
1239 {
1240  ROS_DEBUG("[%s] Clearing read buffer", name_.c_str());
1241  // Flush the input streams
1242  if (tcflush(usbFileDescriptor_, TCIFLUSH) < 0)
1243  {
1244  ROS_ERROR("[%s] Failed to flush the input read buffer.", name_.c_str());
1245  return false;
1246  }
1247  return true;
1248 }
1250 {
1251  if (!isConnected() && !isConnecting())
1252  {
1253  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, getConnectionStateString());
1254  }
1255  else if (isConnecting())
1256  {
1257  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, getConnectionStateString());
1258  }
1259  else if (isConnected())
1260  {
1261  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, getConnectionStateString());
1262  }
1263  stat.add("Device Mode State", getModeStateString());
1264  stat.add("Runs Async", runsAsync() ? "Yes" : "No");
1265  stat.add("Product Name", productName_);
1266  unsigned int serial_number;
1267  getSerialNumber(serial_number);
1268  stat.add("Serial Number (S/N)", std::to_string(serial_number));
1269  stat.add("Baud Rate", std::to_string(baudRate_.value));
1270  stat.add("Port", port_);
1271  stat.add("Received Frames", std::to_string(frameReceivedCounter_));
1272  stat.add("Successful Frames", std::to_string(frameSuccessCounter_));
1273  stat.add("CRC Errors", std::to_string(frameCrcErrorCounter_));
1274  stat.add("Polling sync Errors", std::to_string(pollingSyncErrorCounter_));
1275  stat.add("Frame Sync Errors", std::to_string(frameSyncErrorCounter_));
1276  stat.add("Timeout Errors", std::to_string(timeoutCounter_));
1277 }
1278 
1280 {
1281  DataStatus data_status;
1282  getFrameDataStatus(data_status);
1283  data_status.byte |= currentDataFlagsDiagnostics_.load().byte;
1284  currentDataFlagsDiagnostics_ = data_status;
1285 }
1286 
1288 {
1290 }
1291 
1293 {
1295  std::bitset<16> bits(data_status.byte);
1296  if (data_status.invalid_measurements)
1297  {
1298  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Errors in Data Flags");
1299  }
1300  else if (data_status.app_took_too_long || data_status.overrange || data_status.raw_measurements)
1301  {
1302  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Warnings in Data Flags");
1303  }
1304  else
1305  {
1306  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "No errors in Data Flags");
1307  }
1308  stat.add("Sensor is skipping measurements", data_status.app_took_too_long ? "Yes" : "No");
1309  stat.add("Measuring range exceeded", data_status.overrange ? "Yes" : "No");
1310  stat.add("Measurements are invalid", data_status.invalid_measurements ? "Yes" : "No");
1311  stat.add("Raw Measurements from gages", data_status.raw_measurements ? "Yes" : "No");
1312  stat.add("Reserved 1", bits[4] ? "Yes" : "No");
1313  stat.add("Reserved 2", bits[5] ? "Yes" : "No");
1314  stat.add("Reserved 3", bits[6] ? "Yes" : "No");
1315  stat.add("Reserved 4", bits[7] ? "Yes" : "No");
1316  stat.add("Reserved 5", bits[8] ? "Yes" : "No");
1317  stat.add("Reserved 6", bits[9] ? "Yes" : "No");
1318  stat.add("Reserved 7", bits[10] ? "Yes" : "No");
1319  stat.add("Reserved 8", bits[11] ? "Yes" : "No");
1320  stat.add("Reserved 9", bits[12] ? "Yes" : "No");
1321  stat.add("Reserved 10", bits[13] ? "Yes" : "No");
1322  stat.add("Reserved 11", bits[14] ? "Yes" : "No");
1323  stat.add("Reserved 12", bits[15] ? "Yes" : "No");
1324 }
1326 {
1327  std::unique_lock<std::mutex> lock(readingMutex_);
1328  status = frameDataStatus_;
1329 }
1330 
1331 bool RokubiminiSerialImpl::parseAcknowledgement(const char& command_code, const double& timeout)
1332 {
1334  bool success = parseRegexWaitTimeout(ack, timeout);
1335  if (!success)
1336  {
1337  ROS_ERROR("[%s] Command not found in ACK", name_.c_str());
1338  return false;
1339  }
1340  if (command_code != ack.getCommand())
1341  {
1342  ROS_ERROR("[%s] Didn't find the correct command in ACK", name_.c_str());
1343  return false;
1344  }
1345  if (ack.getReturnCode() != 0)
1346  {
1347  ROS_ERROR("[%s] Device responded with error code: %u", name_.c_str(), ack.getReturnCode());
1348  return false;
1349  }
1350  return true;
1351 }
1352 
1353 bool RokubiminiSerialImpl::writeSerial(const std::string& str)
1354 {
1355  try
1356  {
1357  // check that the string size doesn't exceed the serial input buffer's size (64) of the device.
1358  if (str.size() > 64)
1359  {
1360  ROS_WARN("[%s] String's length exceeds permittable limit (64)", name_.c_str());
1361  return false;
1362  }
1363  ROS_DEBUG("[%s] Number of chars: %zu", name_.c_str(), str.size());
1364  ROS_DEBUG("[%s] String chars: %s", name_.c_str(), str.c_str());
1365  if (usbStreamIn_.is_open() && usbStreamOut_.is_open())
1366  {
1367  usbStreamIn_.sync();
1368  char cstr[str.size() + 1];
1369  strcpy(cstr, str.c_str());
1370  for (uint8_t i = 0; i < str.size(); i++)
1371  {
1372  usbStreamOut_.put(cstr[i]);
1373  std::this_thread::sleep_for(std::chrono::microseconds(5000));
1374  usbStreamOut_.flush();
1375  }
1376  if ((usbStreamOut_.fail() | usbStreamIn_.fail()) != 0)
1377  {
1378  ROS_WARN("[%s] Serial Write or Read failed", name_.c_str());
1379  return false;
1380  }
1381  }
1382  else
1383  {
1384  ROS_WARN("[%s] Streams are not yet open.", name_.c_str());
1385  return false;
1386  }
1387  }
1388  catch (const std::exception& e)
1389  {
1390  ROS_ERROR("[%s] %s", name_.c_str(), e.what());
1391  return false;
1392  }
1393  return true;
1394 }
1395 
1396 bool RokubiminiSerialImpl::firmwareUpdate(const std::string& filePath)
1397 {
1398  pid_t pid;
1399  int status;
1400  ROS_INFO("Flashing firmware...");
1401  std::unique_lock<std::recursive_mutex> lock(serialMutex_);
1402  setHardwareReset();
1403  pid = fork();
1404 
1405  if (pid == -1)
1406  {
1407  // pid == -1 means error occured
1408  ROS_ERROR("Could not fork, error occured");
1409  lock.unlock();
1410  return false;
1411  }
1412  else if (pid == 0)
1413  {
1414  ROS_DEBUG("Child process, pid = %u\n", getpid());
1415  // pid == 0 means child process created
1416  char path_argument[filePath.size() + 15];
1417  int ret = sprintf(path_argument, "-Uflash:w:%s:i", filePath.c_str());
1418  if (ret < 0)
1419  {
1420  ROS_ERROR("[%s] sprintf failed to write data", name_.c_str());
1421  lock.unlock();
1422  return false;
1423  }
1424  char port_argument[port_.size() + 2];
1425  ret = sprintf(port_argument, "-P%s", port_.c_str());
1426  if (ret < 0)
1427  {
1428  ROS_ERROR("[%s] sprintf failed to write data", name_.c_str());
1429  lock.unlock();
1430  return false;
1431  }
1432  // the argv list first argument should point to
1433  // filename associated with file being executed
1434  // the array pointer must be terminated by a NULL
1435  // pointer
1436  const char* argv_list[9] = { "avrdude", "-v", "-patmega328p", "-carduino", port_argument,
1437  "-b230400", "-D", path_argument, nullptr };
1438  ROS_DEBUG("Complete command for avrdude:");
1439  for (std::size_t i = 0; i < sizeof(argv_list); i++)
1440  {
1441  ROS_DEBUG("%s", argv_list[i]);
1442  }
1443  ROS_DEBUG("\n");
1444  // the execv() only returns if error occurred (then the return value is -1)
1445  ret = execvp(argv_list[0], const_cast<char* const*>(argv_list));
1446  if (ret < 0)
1447  {
1448  ROS_ERROR("[%s] Execution of avrdude failed: %s", name_.c_str(), strerror(errno));
1449  kill(getpid(), SIGKILL);
1450  }
1451  exit(0);
1452  }
1453  else
1454  {
1455  // a positive number is returned which is the pid of child process
1456  // the parent process calls waitpid() on the child.
1457  // waitpid() system call suspends execution of
1458  // calling process until a child specified by pid
1459  // argument has changed state
1460  // see wait() man page for all the flags or options
1461  // used here
1462  if (waitpid(pid, &status, WUNTRACED) > 0)
1463  {
1464  if (WIFEXITED(status) && !WEXITSTATUS(status))
1465  {
1466  ROS_INFO("[%s] avrdude returned successfully", name_.c_str());
1467  // stop polling and prepare to shutdown
1468  isRunning_ = false;
1469  }
1470  else if (WIFEXITED(status) && WEXITSTATUS(status))
1471  {
1472  if (WEXITSTATUS(status) == 127)
1473  {
1474  // execvp failed
1475  ROS_ERROR("[%s] execvp failed", name_.c_str());
1476  lock.unlock();
1477  return false;
1478  }
1479  else
1480  {
1481  ROS_ERROR("[%s] program terminated normally,"
1482  " but returned a non-zero status",
1483  name_.c_str());
1484  // stop polling and prepare to shutdown
1485  isRunning_ = false;
1486  lock.unlock();
1487  return false;
1488  }
1489  }
1490  else
1491  {
1492  ROS_ERROR("[%s] program didn't terminate normally", name_.c_str());
1493  lock.unlock();
1494  return false;
1495  }
1496  }
1497  else
1498  {
1499  // waitpid() failed
1500  ROS_ERROR("[%s] waitpid() failed", name_.c_str());
1501  lock.unlock();
1502  return false;
1503  }
1504  }
1505  lock.unlock();
1506  return true;
1507 }
1508 
1509 } // namespace serial
1510 } // namespace rokubimini
ROS_ERROR_THROTTLE
#define ROS_ERROR_THROTTLE(period,...)
rokubimini::serial::RokubiminiSerialImpl::NSEC_PER_SEC
const static uint64_t NSEC_PER_SEC
Definition: RokubiminiSerialImpl.hpp:1251
rokubimini::serial::RokubiminiSerialResponseRegexCommSetup::getCalibration
const uint8_t & getCalibration()
Definition: RokubiminiSerialCommunication.hpp:195
rokubimini::serial::RokubiminiSerialImpl::printUserConfig
bool printUserConfig()
Prints all the user configurable parameters.
Definition: RokubiminiSerialImpl.cpp:1186
rokubimini::serial::RokubiminiSerialResponseRegexProductName::getProductName
const std::string & getProductName()
Definition: RokubiminiSerialCommunication.hpp:217
rokubimini::serial::ConnectionState::CONNECTED
@ CONNECTED
rokubimini::serial::DataStatus
The status of the sensor data.
Definition: RokubiminiSerialImpl.hpp:53
hi8
#define hi8(x)
rokubimini::serial::RokubiminiSerialImpl::timeoutCounter_
unsigned int timeoutCounter_
Timeout counter.
Definition: RokubiminiSerialImpl.hpp:1326
rokubimini::serial::RokubiminiSerialCommandConfig
Definition: RokubiminiSerialCommunication.hpp:118
rokubimini::serial::RokubiminiSerialImpl::baudRate_
BaudRateStruct baudRate_
The baud rate of the serial communication, as a termios bit mask.
Definition: RokubiminiSerialImpl.hpp:1031
rokubimini::serial::RokubiminiSerialImpl::readDevice
bool readDevice(RxFrame &frame)
Reads a raw measurement frame from the serial-port.
Definition: RokubiminiSerialImpl.cpp:224
rokubimini::serial::RokubiminiSerialImpl::connectionState_
boost::atomic< ConnectionState > connectionState_
Internal connection state.
Definition: RokubiminiSerialImpl.hpp:1162
rokubimini::serial::RokubiminiSerialImpl::currentDataFlagsDiagnostics_
std::atomic< DataStatus > currentDataFlagsDiagnostics_
The current Data Flags Diagnostics (Data Status) which is updated when a new frame is published and i...
Definition: RokubiminiSerialImpl.hpp:1369
rokubimini::serial::RokubiminiSerialCommandFilter
Definition: RokubiminiSerialCommunication.hpp:47
rokubimini::serial::RokubiminiSerialImpl::usbStreamOut_
std::ofstream usbStreamOut_
Output stream for the USB file descriptor.
Definition: RokubiminiSerialImpl.hpp:1103
rokubimini::serial::RokubiminiSerialImpl::shutdown
void shutdown()
Shuts down the device. It automatically shuts-down threads and disconnects from serial-port.
Definition: RokubiminiSerialImpl.cpp:138
diagnostic_updater::DiagnosticStatusWrapper::add
void add(const std::string &key, const bool &b)
rokubimini::serial::RokubiminiSerialResponseRegexFirmwareVersion
Definition: RokubiminiSerialCommunication.hpp:269
rokubimini::serial::RokubiminiSerialImpl::frameSyncErrorCounter_
unsigned int frameSyncErrorCounter_
Frame sync errors.
Definition: RokubiminiSerialImpl.hpp:1229
rokubimini::serial::RokubiminiSerialResponseRegexCommSetup::getBaudRate
const uint8_t & getBaudRate()
Definition: RokubiminiSerialCommunication.hpp:191
rokubimini::serial::RokubiminiSerialImpl::getErrorStrings
std::vector< std::string > getErrorStrings() const
Retrieves detailed error indication.
Definition: RokubiminiSerialImpl.cpp:416
rokubimini::serial::RokubiminiSerialImpl::parseRegexWaitTimeout
bool parseRegexWaitTimeout(RokubiminiSerialResponseRegex &reg, const double &timeout=1.0)
Parses a regex from the serial sensor input stream.
Definition: RokubiminiSerialImpl.cpp:614
ROS_WARN_THROTTLE
#define ROS_WARN_THROTTLE(period,...)
ros.h
rokubimini::serial::RokubiminiSerialResponseRegexSerialNumber::getSerialNumber
const uint32_t & getSerialNumber()
Definition: RokubiminiSerialCommunication.hpp:258
rokubimini::configuration::SensorConfiguration::setTemperatureCompensationActive
void setTemperatureCompensationActive(const uint8_t temperatureCompensationActive)
rokubimini::serial::RokubiminiSerialCommandSave
Definition: RokubiminiSerialCommunication.hpp:142
rokubimini::serial::RokubiminiSerialImpl::setForceTorqueOffset
bool setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset)
Sets a force torque offset to the device.
Definition: RokubiminiSerialImpl.cpp:1065
command
ROSLIB_DECL std::string command(const std::string &cmd)
rokubimini::serial::RokubiminiSerialImpl::getConnectionStateString
std::string getConnectionStateString() const
Definition: RokubiminiSerialImpl.hpp:254
rokubimini::serial::RokubiminiSerialImpl::getName
std::string getName() const
Accessor for device name.
Definition: RokubiminiSerialImpl.hpp:234
rokubimini::serial::RokubiminiSerialImpl::MAX_BAUD_RATE_OPTION
const static uint8_t MAX_BAUD_RATE_OPTION
Definition: RokubiminiSerialImpl.hpp:1265
time.h
rokubimini::serial::RokubiminiSerialImpl::serialMutex_
std::recursive_mutex serialMutex_
Mutex prohibiting simultaneous access to Serial device.
Definition: RokubiminiSerialImpl.hpp:1067
rokubimini::serial::RokubiminiSerialImpl::sendCommand
bool sendCommand(const std::string &command)
Sends a command to the serial device.
Definition: RokubiminiSerialImpl.cpp:1229
rokubimini::serial::RokubiminiSerialImpl::connectionThread_
boost::thread connectionThread_
Connection thread handle.
Definition: RokubiminiSerialImpl.hpp:1144
rokubimini::serial::RokubiminiSerialImpl::startup
bool startup()
This method starts up communication with the device.
Definition: RokubiminiSerialImpl.cpp:109
rokubimini::serial::RxFrame::bytes
uint8_t bytes[1]
Definition: RokubiminiSerialImpl.hpp:102
rokubimini::calibration::SensorCalibration::getCalibrationMatrix
Eigen::Matrix< double, 6, 6 > & getCalibrationMatrix()
rokubimini::serial::ConnectionState::ISCONNECTING
@ ISCONNECTING
rokubimini::serial::RokubiminiSerialResponseRegexProductName
Definition: RokubiminiSerialCommunication.hpp:213
rokubimini::serial::RokubiminiSerialImpl::setCommunicationSetup
bool setCommunicationSetup(const configuration::SensorConfiguration &sensorConfiguration, const uint8_t &dataFormat, const uint8_t &baudRate)
Sets communication setup for the device. This includes setting the temperature compensation,...
Definition: RokubiminiSerialImpl.cpp:1129
rokubimini::serial::RokubiminiSerialImpl::hasError
bool hasError() const
Checks the connection has errors.
Definition: RokubiminiSerialImpl.cpp:391
rokubimini::serial::RokubiminiSerialImpl::frameCrcErrorCounter_
unsigned long frameCrcErrorCounter_
Counter for frames with CRC errors.
Definition: RokubiminiSerialImpl.hpp:1221
rokubimini::serial::RokubiminiSerialResponseRegexAck::getReturnCode
const uint8_t & getReturnCode()
Definition: RokubiminiSerialCommunication.hpp:241
RokubiminiSerialCommunication.hpp
rokubimini::serial::RokubiminiSerialImpl::DEFAULT_BAUD_RATE_OPTION
const static uint8_t DEFAULT_BAUD_RATE_OPTION
Definition: RokubiminiSerialImpl.hpp:1258
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
rokubimini::serial::RokubiminiSerialImpl::TIMEOUT_MARGIN
constexpr static double TIMEOUT_MARGIN
Definition: RokubiminiSerialImpl.hpp:1301
rokubimini::serial::RokubiminiSerialImpl::diffSec
double diffSec(timespec a, timespec b)
Calculates the difference (b-a) of two timespecs in seconds.
Definition: RokubiminiSerialImpl.hpp:769
rokubimini::serial::RokubiminiSerialImpl::frameHeader
uint8_t frameHeader
The frame header value.
Definition: RokubiminiSerialImpl.hpp:1112
rokubimini::serial::RokubiminiSerialImpl::pollingWorker
void pollingWorker()
Worker threads for polling the sensors.
Definition: RokubiminiSerialImpl.cpp:790
rokubimini::serial::RokubiminiSerialImpl::getReading
void getReading(rokubimini::Reading &reading)
Gets the internal reading variable.
Definition: RokubiminiSerialImpl.cpp:898
rokubimini::serial::ErrorFlags::crc
uint8_t crc
Definition: states.hpp:32
rokubimini::serial::RokubiminiSerialImpl::serialImplReading_
Reading serialImplReading_
The internal reading variable. It's used for providing to client code the sensor readings,...
Definition: RokubiminiSerialImpl.hpp:1013
rokubimini::serial::ConnectionState::DISCONNECTED
@ DISCONNECTED
rokubimini::serial::RokubiminiSerialImpl::timespec
struct timespec timespec
Definition: RokubiminiSerialImpl.hpp:757
rokubimini::serial::RokubiminiSerialCommandSoftReset
Definition: RokubiminiSerialCommunication.hpp:106
data
data
rokubimini::Reading::getTemperature
TempType & getTemperature()
rokubimini::Reading
rokubimini::serial::RxFrame
The frame transmitted and received via the serial bus.
Definition: RokubiminiSerialImpl.hpp:95
rokubimini::serial::RokubiminiSerialImpl::connect
bool connect()
Connects to the Serial-over-USB port.
Definition: RokubiminiSerialImpl.cpp:171
rokubimini::serial::RokubiminiSerialImpl::frame_
RxFrame frame_
The internal variable for the receiving frame. This variable represents the raw data received from th...
Definition: RokubiminiSerialImpl.hpp:1122
rokubimini::serial::RokubiminiSerialImpl::calcCrc16X25
uint16_t calcCrc16X25(uint8_t *data, int len)
Definition: RokubiminiSerialImpl.cpp:767
rokubimini::serial::RokubiminiSerialImpl::connectionWorker
void connectionWorker()
Worker threads for managing sensor connections.
Definition: RokubiminiSerialImpl.cpp:785
rokubimini::serial::RokubiminiSerialCommandHardReset
Definition: RokubiminiSerialCommunication.hpp:95
lo8
#define lo8(x)
diagnostic_updater::DiagnosticStatusWrapper::summary
void summary(const diagnostic_msgs::DiagnosticStatus &src)
rokubimini::serial::RokubiminiSerialImpl::pollingSyncErrorCounter_
unsigned long pollingSyncErrorCounter_
Internal statistics and error counters.
Definition: RokubiminiSerialImpl.hpp:1195
rokubimini::serial::RokubiminiSerialImpl::isRunning_
boost::atomic< bool > isRunning_
Internal flags/indicators.
Definition: RokubiminiSerialImpl.hpp:1186
rokubimini::serial::RokubiminiSerialImpl::updateConnectionStatus
void updateConnectionStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
Fills the Device Connection Status (ROS diagnostics).
Definition: RokubiminiSerialImpl.cpp:1249
rokubimini::serial::RokubiminiSerialImpl::frameSuccessCounter_
unsigned long frameSuccessCounter_
Correct frames counter.
Definition: RokubiminiSerialImpl.hpp:1212
rokubimini::serial::RokubiminiSerialImpl::name_
std::string name_
Name of the sensor.
Definition: RokubiminiSerialImpl.hpp:1002
rokubimini::configuration::ForceTorqueFilter
rokubimini::serial::RokubiminiSerialCommandRun
Definition: RokubiminiSerialCommunication.hpp:130
rokubimini::serial::RokubiminiSerialImpl::RokubiminiSerialImpl
RokubiminiSerialImpl()=delete
Default constructor is deleted.
rokubimini::serial::RokubiminiSerialImpl::maxCountOpenSerialPort_
unsigned int maxCountOpenSerialPort_
Maximum attempts to open serial port.
Definition: RokubiminiSerialImpl.hpp:1244
ROS_DEBUG
#define ROS_DEBUG(...)
rokubimini::serial::ConnectionState
ConnectionState
Definition: states.hpp:15
rokubimini::serial::RokubiminiSerialImpl::setHardwareReset
bool setHardwareReset()
Triggers a hardware reset of the sensor.
Definition: RokubiminiSerialImpl.cpp:989
rokubimini::serial::RokubiminiSerialResponseRegexCommSetup::setBaudRate
void setBaudRate(uint8_t &baudRate)
Definition: RokubiminiSerialCommunication.hpp:199
rokubimini::serial::RokubiminiSerialImpl::runsAsync
bool runsAsync()
Returns if the driver runs asynchronously.
Definition: RokubiminiSerialImpl.hpp:569
rokubimini::serial::RokubiminiSerialImpl::firmwareUpdate
bool firmwareUpdate(const std::string &filePath)
Updates the firmware of the device.
Definition: RokubiminiSerialImpl.cpp:1396
rokubimini::Reading::getWrench
WrenchType & getWrench()
rokubimini::serial::RokubiminiSerialResponseRegexAck::getCommand
const char & getCommand()
Definition: RokubiminiSerialCommunication.hpp:237
rokubimini::serial::RokubiminiSerialImpl::increaseAndCheckTimeoutCounter
void increaseAndCheckTimeoutCounter()
Increases the timeout counter and checks if it has passed the maximum available timeouts.
Definition: RokubiminiSerialImpl.cpp:218
rokubimini::serial::RokubiminiSerialImpl::createDataFlagsDiagnostics
void createDataFlagsDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Creates the Data Flags Diagnostics status.
Definition: RokubiminiSerialImpl.cpp:1292
rokubimini::serial::DataStatus::byte
uint16_t byte
Definition: RokubiminiSerialImpl.hpp:62
rokubimini::serial::RokubiminiSerialImpl::getFrameDataStatus
void getFrameDataStatus(DataStatus &status)
Gets the latest frame's Data Status.
Definition: RokubiminiSerialImpl.cpp:1325
rokubimini::configuration::SensorConfiguration::setCalibrationMatrixActive
void setCalibrationMatrixActive(const uint8_t calibrationMatrixActive)
rokubimini::serial::RokubiminiSerialResponseRegexCommSetup
Definition: RokubiminiSerialCommunication.hpp:178
rokubimini::serial::RokubiminiSerialImpl::frameReceivedCounter_
unsigned long frameReceivedCounter_
Received frame counter.
Definition: RokubiminiSerialImpl.hpp:1203
rokubimini::serial::RokubiminiSerialImpl::timespecAdd
timespec timespecAdd(timespec a, timespec b)
Calculates the sum of two timespecs.
Definition: RokubiminiSerialImpl.hpp:798
rokubimini
System dependencies.
rokubimini::serial::RokubiminiSerialImpl::writeSerial
bool writeSerial(const std::string &str)
Writes an Ascii string to the serial device.
Definition: RokubiminiSerialImpl.cpp:1353
rokubimini::serial::RokubiminiSerialImpl::isConnecting
bool isConnecting() const
Checks if device is already in the process of connecting.
Definition: RokubiminiSerialImpl.cpp:386
rokubimini::serial::RokubiminiSerialCommandOffset
Definition: RokubiminiSerialCommunication.hpp:60
rokubimini::serial::RokubiminiSerialImpl::setForceTorqueFilter
bool setForceTorqueFilter(const configuration::ForceTorqueFilter &filter)
Sets a force torque filter to the device.
Definition: RokubiminiSerialImpl.cpp:1039
ROS_WARN
#define ROS_WARN(...)
rokubimini::serial::RokubiminiSerialImpl::readSerialWaitTimeout
bool readSerialWaitTimeout(const uint32_t &numChars, std::string &str, const double &timeout=1.0)
Reads a string from the serial device waiting a timeout duration. The number of characters of the str...
Definition: RokubiminiSerialImpl.cpp:647
rokubimini::serial::RokubiminiSerialImpl::startPollingThread
bool startPollingThread()
This method starts up the polling thread.
Definition: RokubiminiSerialImpl.cpp:97
rokubimini::configuration::SensorConfiguration::getCalibrationMatrixActive
uint8_t getCalibrationMatrixActive() const
rokubimini::serial::RokubiminiSerialResponseRegex::matchInString
virtual bool matchInString(const std::string &str)=0
rokubimini::serial::RokubiminiSerialImpl::frameTimestamp_
ros::Time frameTimestamp_
Definition: RokubiminiSerialImpl.hpp:1370
rokubimini::serial::RokubiminiSerialImpl::getConnectionState
ConnectionState getConnectionState() const
Gets the current connection status.
Definition: RokubiminiSerialImpl.cpp:406
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
rokubimini::serial::RokubiminiSerialImpl::getErrorFlags
ErrorFlags getErrorFlags() const
Gets the current error status.
Definition: RokubiminiSerialImpl.cpp:411
rokubimini::serial::CODE_TO_BAUD_RATE_MAP
const static std::map< uint32_t, BaudRateStruct > CODE_TO_BAUD_RATE_MAP
Definition: RokubiminiSerialImpl.hpp:110
rokubimini::serial::RokubiminiSerialCommandCommSetup
Definition: RokubiminiSerialCommunication.hpp:31
rokubimini::serial::RokubiminiSerialImpl::openSerialPort
bool openSerialPort(bool keepOpening)
Opens the serial port.
Definition: RokubiminiSerialImpl.cpp:445
rokubimini::serial::RokubiminiSerialCommandPrint
Definition: RokubiminiSerialCommunication.hpp:166
rokubimini::serial::RokubiminiSerialImpl::readTimeout_
double readTimeout_
The timeout to read from device (in seconds).
Definition: RokubiminiSerialImpl.hpp:1318
rokubimini::serial::RokubiminiSerialImpl::maxFrameSyncErrorCounts_
unsigned int maxFrameSyncErrorCounts_
Maximum acceptable frame sync errors.
Definition: RokubiminiSerialImpl.hpp:1237
rokubimini::configuration::ForceTorqueFilter::getSincFilterSize
uint16_t getSincFilterSize() const
rokubimini::serial::RokubiminiSerialImpl::initSerialPort
bool initSerialPort(const std::string &port)
Sets up and initializes the serial port for communication.
Definition: RokubiminiSerialImpl.cpp:699
rokubimini::serial::RokubiminiSerialImpl::updateDataFlags
void updateDataFlags()
Updates the Data Flags variable currentDataFlagsDiagnostics_.
Definition: RokubiminiSerialImpl.cpp:1279
rokubimini::serial::RokubiminiSerialImpl::frameDataStatus_
DataStatus frameDataStatus_
The current frame's Data Status.
Definition: RokubiminiSerialImpl.hpp:1359
rokubimini::serial::RokubiminiSerialCommandSensorCalibrationRow
Definition: RokubiminiSerialCommunication.hpp:73
rokubimini::serial::RokubiminiSerialImpl::port_
std::string port_
The serial port to connect to.
Definition: RokubiminiSerialImpl.hpp:1022
rokubimini::serial::ErrorFlags
Definition: states.hpp:29
rokubimini::serial::RokubiminiSerialImpl::setSensorCalibration
bool setSensorCalibration(const calibration::SensorCalibration &sensorCalibration)
Sets a sensor calibration to the device.
Definition: RokubiminiSerialImpl.cpp:1086
rokubimini::serial::BaudRateStruct::value
uint32_t value
Definition: RokubiminiSerialImpl.hpp:107
rokubimini::serial::ModeState::CONFIG_MODE
@ CONFIG_MODE
rokubimini::serial::RokubiminiSerialImpl::errorFlags_
ErrorFlags errorFlags_
Flags to indicate errors in serial communication.
Definition: RokubiminiSerialImpl.hpp:1170
rokubimini::serial::RokubiminiSerialImpl::usbStreamIn_
std::ifstream usbStreamIn_
Input stream for the USB file descriptor.
Definition: RokubiminiSerialImpl.hpp:1094
rokubimini::serial::RokubiminiSerialImpl::parseAcknowledgement
bool parseAcknowledgement(const char &command_code, const double &timeout=2.0)
Parses the acknowledgement from the serial device.
Definition: RokubiminiSerialImpl.cpp:1331
rokubimini::serial::ErrorFlags::polling_sync
uint8_t polling_sync
Definition: states.hpp:34
rokubimini::serial::RokubiminiSerialImpl::readSerialNoWait
bool readSerialNoWait(const uint32_t &numChars, std::string &str)
Reads a string from the serial device without waiting. The number of characters of the string is not ...
Definition: RokubiminiSerialImpl.cpp:637
rokubimini::serial::ErrorFlags::frame_sync
uint8_t frame_sync
Definition: states.hpp:31
rokubimini::serial::RokubiminiSerialImpl::saveConfigParameter
bool saveConfigParameter()
Saves the current configuration to the device.
Definition: RokubiminiSerialImpl.cpp:1148
rokubimini::configuration::ForceTorqueFilter::getChopEnable
uint8_t getChopEnable() const
rokubimini::serial::RokubiminiSerialImpl::newFrameIsAvailable_
std::condition_variable newFrameIsAvailable_
The condition variable that is used between the publishing and the polling thread to synchronize on n...
Definition: RokubiminiSerialImpl.hpp:1335
RokubiminiSerialImpl.hpp
rokubimini::serial::RokubiminiSerialImpl::isInConfigMode
bool isInConfigMode() const
Checks if the ModeState is Config Mode.
Definition: RokubiminiSerialImpl.cpp:401
rokubimini::serial::RokubiminiSerialImpl::readingMutex_
std::mutex readingMutex_
Mutex prohibiting simultaneous access the internal Reading variable.
Definition: RokubiminiSerialImpl.hpp:1058
rokubimini::serial::RokubiminiSerialImpl::frameOffset_
uint32_t frameOffset_
The frame offset to start reading (in bytes).
Definition: RokubiminiSerialImpl.hpp:1273
rokubimini::serial::RokubiminiSerialImpl::crcCcittUpdate
uint16_t crcCcittUpdate(uint16_t crc, uint8_t data)
Implementation function of the CRC16 X25 checksum for the input data.
Definition: RokubiminiSerialImpl.cpp:775
ROS_ERROR
#define ROS_ERROR(...)
rokubimini::serial::RokubiminiSerialImpl::setConfigMode
bool setConfigMode()
Sets the device in config mode.
Definition: RokubiminiSerialImpl.cpp:930
rokubimini::configuration::ForceTorqueFilter::getSkipEnable
uint8_t getSkipEnable() const
rokubimini::serial::RokubiminiSerialImpl::frameSync_
boost::atomic< bool > frameSync_
Flag that indicates if the frame is synced.
Definition: RokubiminiSerialImpl.hpp:1085
rokubimini::serial::RokubiminiSerialImpl::parseCommunicationMsgs
bool parseCommunicationMsgs(const double &timeout=1.0)
Parses the Communication Messages of the serial sensor.
Definition: RokubiminiSerialImpl.cpp:669
rokubimini::serial::RokubiminiSerialImpl::isConnected
bool isConnected() const
Checks if the device is connected.
Definition: RokubiminiSerialImpl.cpp:381
rokubimini::serial::RokubiminiSerialImpl::dataReady_
bool dataReady_
This flag is on when new data are ready to be published.
Definition: RokubiminiSerialImpl.hpp:1343
rokubimini::serial::RokubiminiSerialImpl::MAXIMUM_ACCEPTABLE_TIMEOUT
constexpr static double MAXIMUM_ACCEPTABLE_TIMEOUT
Definition: RokubiminiSerialImpl.hpp:1310
rokubimini::serial::RokubiminiSerialImpl::initSensorCommunication
bool initSensorCommunication(bool keepOpening)
Initializes communication with the sensor.
Definition: RokubiminiSerialImpl.cpp:465
diagnostic_updater::DiagnosticStatusWrapper
rokubimini::serial::RokubiminiSerialImpl::resetDataFlags
void resetDataFlags()
Resets the Data Flags variable currentDataFlagsDiagnostics_.
Definition: RokubiminiSerialImpl.cpp:1287
rokubimini::serial::RokubiminiSerialImpl::usbFileDescriptor_
boost::atomic< int > usbFileDescriptor_
The USB file descriptor.
Definition: RokubiminiSerialImpl.hpp:1076
rokubimini::configuration::SensorConfiguration
rokubimini::serial::RokubiminiSerialImpl::runInThreadedMode_
bool runInThreadedMode_
Flag to indicate whether the driver should setup worker threads at startup.
Definition: RokubiminiSerialImpl.hpp:1135
rokubimini::serial::RokubiminiSerialImpl::getSerialNumber
bool getSerialNumber(unsigned int &serialNumber)
Accessor for device serial number.
Definition: RokubiminiSerialImpl.hpp:280
rokubimini::serial::RokubiminiSerialImpl::pollingThread_
boost::thread pollingThread_
Polling thread handle.
Definition: RokubiminiSerialImpl.hpp:1153
rokubimini::serial::RokubiminiSerialImpl::setInitMode
bool setInitMode()
Triggers a software reset of the sensor bringing it to a known state.
Definition: RokubiminiSerialImpl.cpp:1004
rokubimini::serial::RokubiminiSerialImpl::getModeStateString
std::string getModeStateString() const
Definition: RokubiminiSerialImpl.hpp:239
rokubimini::serial::RokubiminiSerialImpl::productName_
std::string productName_
The product name of the device.
Definition: RokubiminiSerialImpl.hpp:1040
rokubimini::configuration::ForceTorqueFilter::getFastEnable
uint8_t getFastEnable() const
rokubimini::serial::RokubiminiSerialImpl::setRunMode
bool setRunMode()
Sets the device in run mode.
Definition: RokubiminiSerialImpl.cpp:967
rokubimini::calibration::SensorCalibration
rokubimini::serial::RokubiminiSerialImpl::placeholder_
RxFrame placeholder_
A placeholder to save unfinished frames.
Definition: RokubiminiSerialImpl.hpp:1281
ROS_INFO
#define ROS_INFO(...)
rokubimini::serial::RokubiminiSerialImpl::setSensorConfiguration
bool setSensorConfiguration(const configuration::SensorConfiguration &sensorConfiguration)
Sets a sensor configuration to the device.
Definition: RokubiminiSerialImpl.cpp:1117
rokubimini::serial::RokubiminiSerialImpl::modeState_
boost::atomic< ModeState > modeState_
Mode state of the sensor.
Definition: RokubiminiSerialImpl.hpp:1178
rokubimini::serial::RokubiminiSerialCommandLoad
Definition: RokubiminiSerialCommunication.hpp:154
rokubimini::serial::RokubiminiSerialImpl::clearReadBuffer
bool clearReadBuffer()
Clears the Read Serial buffer by extracting every character available.
Definition: RokubiminiSerialImpl.cpp:1238
rokubimini::serial::RokubiminiSerialResponseRegexAck
Definition: RokubiminiSerialCommunication.hpp:228
rokubimini::serial::ErrorFlags::timeout
uint8_t timeout
Definition: states.hpp:33
rokubimini::serial::RokubiminiSerialResponseRegexBoot
Definition: RokubiminiSerialCommunication.hpp:284
rokubimini::serial::RokubiminiSerialResponseRegexCommSetup::getTempComp
const uint8_t & getTempComp()
Definition: RokubiminiSerialCommunication.hpp:183
rokubimini::serial::ModeState::RUN_MODE
@ RUN_MODE
rokubimini::configuration::SensorConfiguration::getTemperatureCompensationActive
uint8_t getTemperatureCompensationActive() const
rokubimini::serial::RokubiminiSerialResponseRegexSerialNumber
Definition: RokubiminiSerialCommunication.hpp:254
rokubimini::serial::RokubiminiSerialResponseRegex
Definition: RokubiminiSerialCommunication.hpp:13
rokubimini::serial::RokubiminiSerialImpl::init
bool init()
This method initializes internal variables and the device for communication. It connects to the seria...
Definition: RokubiminiSerialImpl.cpp:65
rokubimini::serial::RokubiminiSerialImpl::serialNumber_
uint32_t serialNumber_
The serial number of the device.
Definition: RokubiminiSerialImpl.hpp:1049
rokubimini::serial::BaudRateStruct::mask
uint32_t mask
Definition: RokubiminiSerialImpl.hpp:108
rokubimini::serial::RokubiminiSerialImpl::FTDI_DRIVER_LATENCY
constexpr static double FTDI_DRIVER_LATENCY
Definition: RokubiminiSerialImpl.hpp:1293
ros::Time::now
static Time now()
rokubimini::serial::RokubiminiSerialImpl::loadConfig
bool loadConfig()
Loads the configuration of the device.
Definition: RokubiminiSerialImpl.cpp:1167
rokubimini::serial::RokubiminiSerialImpl::closeSerialPort
void closeSerialPort()
Closes the serial port.
Definition: RokubiminiSerialImpl.hpp:202


rokubimini_serial
Author(s):
autogenerated on Sat Apr 15 2023 02:53:58