RokubiminiEthercatSlave.cpp
Go to the documentation of this file.
1 
9 
10 #include <fstream>
11 #include <thread>
12 namespace rokubimini
13 {
14 namespace ethercat
15 {
18  const uint32_t address, const PdoTypeEnum pdoTypeEnum)
19  : rokubimini::soem_interface::EthercatSlaveBase(bus, address)
20  , name_(name)
21  , pdoTypeEnum_(pdoTypeEnum)
22  , currentPdoTypeEnum_(PdoTypeEnum::NA)
23  , isRunning_{ true }
24  , runsAsync_{ false }
25 {
26  PdoInfo pdo_info;
27 
28  pdo_info.rxPdoId_ = OD_RX_PDO_ID_VAL_A;
29  pdo_info.txPdoId_ = OD_TX_PDO_ID_VAL_A;
30  pdo_info.rxPdoSize_ = sizeof(RxPdo);
31  pdo_info.txPdoSize_ = sizeof(TxPdoA);
32  pdo_info.moduleId_ = 0x00119800;
33  pdoInfos_.insert({ PdoTypeEnum::A, pdo_info });
34 }
35 
37 {
38  // Configure PDO setup
39  return configurePdo(pdoTypeEnum_);
40 }
41 
43 {
44 }
46 {
47  std::lock_guard<std::recursive_mutex> lock(mutex_);
48  const auto& update_stamp = bus_->getUpdateReadStamp();
49 
50  switch (getCurrentPdoTypeEnum())
51  {
52  case PdoTypeEnum::A:
53  TxPdoA tx_pdo_a;
54  bus_->readTxPdo(address_, tx_pdo_a);
55  {
56  reading_.getWrench().header.stamp = update_stamp;
57  reading_.getWrench().header.frame_id = name_ + "_wrench";
58  reading_.getWrench().wrench.force.x = tx_pdo_a.forceX_;
59  reading_.getWrench().wrench.force.y = tx_pdo_a.forceY_;
60  reading_.getWrench().wrench.force.z = tx_pdo_a.forceZ_;
61  reading_.getWrench().wrench.torque.x = tx_pdo_a.torqueX_;
62  reading_.getWrench().wrench.torque.y = tx_pdo_a.torqueY_;
63  reading_.getWrench().wrench.torque.z = tx_pdo_a.torqueZ_;
64 
65  reading_.getImu().header.stamp = update_stamp;
66  reading_.getImu().header.frame_id = name_ + "_imu";
67  reading_.getImu().angular_velocity.x = tx_pdo_a.angularRateX_ * DEG_TO_RAD;
68  reading_.getImu().angular_velocity.y = tx_pdo_a.angularRateY_ * DEG_TO_RAD;
69  reading_.getImu().angular_velocity.z = tx_pdo_a.angularRateZ_ * DEG_TO_RAD;
70  reading_.getImu().linear_acceleration.x = tx_pdo_a.accelerationX_ * G_TO_METERS_PER_SECOND_SQUARED;
71  reading_.getImu().linear_acceleration.y = tx_pdo_a.accelerationY_ * G_TO_METERS_PER_SECOND_SQUARED;
72  reading_.getImu().linear_acceleration.z = tx_pdo_a.accelerationZ_ * G_TO_METERS_PER_SECOND_SQUARED;
73  reading_.getImu().orientation.x = tx_pdo_a.estimatedOrientationX_;
74  reading_.getImu().orientation.y = tx_pdo_a.estimatedOrientationY_;
75  reading_.getImu().orientation.z = tx_pdo_a.estimatedOrientationZ_;
76  reading_.getImu().orientation.w = tx_pdo_a.estimatedOrientationW_;
77 
80 
81  reading_.getTemperature().header.stamp = update_stamp;
82  reading_.getTemperature().header.frame_id = name_ + "_temp";
83  reading_.getTemperature().temperature = tx_pdo_a.temperature_;
84  reading_.getTemperature().variance = 0; // unknown variance
85  }
86  break;
87  default:
88  break;
89  }
90 }
91 
92 bool RokubiminiEthercatSlave::getSerialNumber(unsigned int& serialNumber)
93 {
94  std::lock_guard<std::recursive_mutex> lock(mutex_);
95  bool success = true;
96  uint32_t serial_number;
97  success &= sendSdoRead(OD_IDENTITY_ID, OD_IDENTITY_SID_SERIAL_NUMBER, false, serial_number);
98  serialNumber = static_cast<unsigned int>(serial_number);
99  ROS_DEBUG("[%s] Reading serial number: %u", name_.c_str(), serialNumber);
100  return success;
101 }
102 
104 {
105  std::lock_guard<std::recursive_mutex> lock(mutex_);
106  bool success = true;
107  int16_t sampling_rate;
108  success &= sendSdoRead(OD_SAMPLING_RATE_ID, 0x00, false, sampling_rate);
109  samplingRate = static_cast<int>(sampling_rate);
110  ROS_DEBUG("[%s] Force/Torque sampling rate: %d Hz", name_.c_str(), samplingRate);
111  return success;
112 }
113 
115 {
116  std::lock_guard<std::recursive_mutex> lock(mutex_);
117  ROS_DEBUG("[%s] Setting force/torque filter", name_.c_str());
118  ROS_DEBUG("[%s] \tchop: %u", name_.c_str(), filter.getChopEnable());
119  ROS_DEBUG("[%s] \tfast: %u", name_.c_str(), filter.getFastEnable());
120  ROS_DEBUG("[%s] \tskip: %u", name_.c_str(), filter.getSkipEnable());
121  ROS_DEBUG("[%s] \tsize: %u", name_.c_str(), filter.getSincFilterSize());
122  bool success = true;
123  /* the following order is mandatory as the sinc filter size range is depending on the other values.
124  * Thats why has to be the last one to be changed */
125  success &=
127  success &=
129  success &=
131  success &=
133  return success;
134 }
135 
136 bool RokubiminiEthercatSlave::setAccelerationFilter(const unsigned int filter)
137 {
138  std::lock_guard<std::recursive_mutex> lock(mutex_);
139  ROS_DEBUG("[%s] Setting acceleration filter: %u", name_.c_str(), filter);
140  bool success = true;
141  success &= sendSdoWrite(OD_ACCELERATION_FILTER_ID, 0x00, false, static_cast<uint8_t>(filter));
142  return success;
143 }
144 
145 bool RokubiminiEthercatSlave::setAngularRateFilter(const unsigned int filter)
146 {
147  std::lock_guard<std::recursive_mutex> lock(mutex_);
148  ROS_DEBUG("[%s] Setting angular rate filter: %u", name_.c_str(), filter);
149  bool success = true;
150  success &= sendSdoWrite(OD_ANGULAR_RATE_FILTER_ID, 0x00, false, static_cast<uint8_t>(filter));
151  return success;
152 }
153 
154 bool RokubiminiEthercatSlave::setAccelerationRange(const unsigned int range)
155 {
156  std::lock_guard<std::recursive_mutex> lock(mutex_);
157  ROS_DEBUG("[%s] Setting acceleration range: %u", name_.c_str(), range);
158  bool success = true;
159  success &= sendSdoWrite(OD_ACCELERATION_RANGE_ID, 0x00, false, static_cast<uint8_t>(range));
160  return success;
161 }
162 
163 bool RokubiminiEthercatSlave::setAngularRateRange(const unsigned int range)
164 {
165  std::lock_guard<std::recursive_mutex> lock(mutex_);
166  ROS_DEBUG("[%s] Setting angular rate range: %u", name_.c_str(), range);
167  bool success = true;
168  success &= sendSdoWrite(OD_ANGULAR_RATE_RANGE_ID, 0x00, false, static_cast<uint8_t>(range));
169  return success;
170 }
171 
172 bool RokubiminiEthercatSlave::setForceTorqueOffset(const Eigen::Matrix<double, 6, 1>& forceTorqueOffset)
173 {
174  std::lock_guard<std::recursive_mutex> lock(mutex_);
175  ROS_DEBUG_STREAM("[" << name_.c_str() << "] Setting Force/Torque offset: " << forceTorqueOffset << std::endl);
176  bool success = true;
178  static_cast<float>(forceTorqueOffset(0, 0)));
180  static_cast<float>(forceTorqueOffset(1, 0)));
182  static_cast<float>(forceTorqueOffset(2, 0)));
184  static_cast<float>(forceTorqueOffset(3, 0)));
186  static_cast<float>(forceTorqueOffset(4, 0)));
188  static_cast<float>(forceTorqueOffset(5, 0)));
189  return success;
190 }
191 
193 {
194  std::lock_guard<std::recursive_mutex> lock(mutex_);
195  ROS_DEBUG("[%s] Setting sensor configuration", name_.c_str());
196  bool success = true;
197 
199  sensorConfiguration.getCalibrationMatrixActive());
201  sensorConfiguration.getTemperatureCompensationActive());
203  sensorConfiguration.getImuActive());
205  sensorConfiguration.getCoordinateSystemConfigurationActive());
207  sensorConfiguration.getInertiaCompensationActive());
209  sensorConfiguration.getOrientationEstimationActive());
210 
211  return success;
212 }
213 
215 {
216  return sendSdoWrite(OD_SENSOR_CALIBRATION_ID, subId, false, static_cast<float>(entry));
217 }
218 
220 {
221  std::lock_guard<std::recursive_mutex> lock(mutex_);
222  bool success = true;
223 
224  success &= sendCalibrationMatrixEntry(0x02, sensorCalibration.getCalibrationMatrix()(0, 0));
225  success &= sendCalibrationMatrixEntry(0x03, sensorCalibration.getCalibrationMatrix()(0, 1));
226  success &= sendCalibrationMatrixEntry(0x04, sensorCalibration.getCalibrationMatrix()(0, 2));
227  success &= sendCalibrationMatrixEntry(0x05, sensorCalibration.getCalibrationMatrix()(0, 3));
228  success &= sendCalibrationMatrixEntry(0x06, sensorCalibration.getCalibrationMatrix()(0, 4));
229  success &= sendCalibrationMatrixEntry(0x07, sensorCalibration.getCalibrationMatrix()(0, 5));
230  success &= sendCalibrationMatrixEntry(0x08, sensorCalibration.getCalibrationMatrix()(1, 0));
231  success &= sendCalibrationMatrixEntry(0x09, sensorCalibration.getCalibrationMatrix()(1, 1));
232  success &= sendCalibrationMatrixEntry(0x0A, sensorCalibration.getCalibrationMatrix()(1, 2));
233  success &= sendCalibrationMatrixEntry(0x0B, sensorCalibration.getCalibrationMatrix()(1, 3));
234  success &= sendCalibrationMatrixEntry(0x0C, sensorCalibration.getCalibrationMatrix()(1, 4));
235  success &= sendCalibrationMatrixEntry(0x0D, sensorCalibration.getCalibrationMatrix()(1, 5));
236  success &= sendCalibrationMatrixEntry(0x0E, sensorCalibration.getCalibrationMatrix()(2, 0));
237  success &= sendCalibrationMatrixEntry(0x0F, sensorCalibration.getCalibrationMatrix()(2, 1));
238  success &= sendCalibrationMatrixEntry(0x10, sensorCalibration.getCalibrationMatrix()(2, 2));
239  success &= sendCalibrationMatrixEntry(0x11, sensorCalibration.getCalibrationMatrix()(2, 3));
240  success &= sendCalibrationMatrixEntry(0x12, sensorCalibration.getCalibrationMatrix()(2, 4));
241  success &= sendCalibrationMatrixEntry(0x13, sensorCalibration.getCalibrationMatrix()(2, 5));
242  success &= sendCalibrationMatrixEntry(0x14, sensorCalibration.getCalibrationMatrix()(3, 0));
243  success &= sendCalibrationMatrixEntry(0x15, sensorCalibration.getCalibrationMatrix()(3, 1));
244  success &= sendCalibrationMatrixEntry(0x16, sensorCalibration.getCalibrationMatrix()(3, 2));
245  success &= sendCalibrationMatrixEntry(0x17, sensorCalibration.getCalibrationMatrix()(3, 3));
246  success &= sendCalibrationMatrixEntry(0x18, sensorCalibration.getCalibrationMatrix()(3, 4));
247  success &= sendCalibrationMatrixEntry(0x19, sensorCalibration.getCalibrationMatrix()(3, 5));
248  success &= sendCalibrationMatrixEntry(0x1A, sensorCalibration.getCalibrationMatrix()(4, 0));
249  success &= sendCalibrationMatrixEntry(0x1B, sensorCalibration.getCalibrationMatrix()(4, 1));
250  success &= sendCalibrationMatrixEntry(0x1C, sensorCalibration.getCalibrationMatrix()(4, 2));
251  success &= sendCalibrationMatrixEntry(0x1D, sensorCalibration.getCalibrationMatrix()(4, 3));
252  success &= sendCalibrationMatrixEntry(0x1E, sensorCalibration.getCalibrationMatrix()(4, 4));
253  success &= sendCalibrationMatrixEntry(0x1F, sensorCalibration.getCalibrationMatrix()(4, 5));
254  success &= sendCalibrationMatrixEntry(0x20, sensorCalibration.getCalibrationMatrix()(5, 0));
255  success &= sendCalibrationMatrixEntry(0x21, sensorCalibration.getCalibrationMatrix()(5, 1));
256  success &= sendCalibrationMatrixEntry(0x22, sensorCalibration.getCalibrationMatrix()(5, 2));
257  success &= sendCalibrationMatrixEntry(0x23, sensorCalibration.getCalibrationMatrix()(5, 3));
258  success &= sendCalibrationMatrixEntry(0x24, sensorCalibration.getCalibrationMatrix()(5, 4));
259  success &= sendCalibrationMatrixEntry(0x25, sensorCalibration.getCalibrationMatrix()(5, 5));
260  success &= sendSdoWrite(OD_SENSOR_CALIBRATION_ID, 0x01, false, sensorCalibration.getPassPhrase());
261 
262  return success;
263 }
265 {
267  // Sleep for some time to give the slave time to execute the pre-op cb
268  std::this_thread::sleep_for(std::chrono::milliseconds(500));
270  {
271  ROS_ERROR("[%s] Slave failed to switch to PREOP state", name_.c_str());
272  return false;
273  }
274  return true;
275 }
276 
278 {
279  return bus_->getSlaveState(address_);
280 }
281 
283 {
285 }
286 
288 {
289  return STATE_TO_STRING.find(state)->second;
290 }
291 
293 {
294  // although SOEM names it state, it's actually status since it has also the error.
295  uint8_t status = getState();
296  std::bitset<8> status_bits(status);
297  // get the error from the 4th bit.
298  bool has_error = status_bits[4];
299  // get the state of the slave, without the errors
300  uint8_t state = status & 0x0F;
301  // get the AL Status Code (indicating if there are any errors)
302  uint16_t al_status_code = getALStatusCode();
303  if (state == EC_STATE_INIT || has_error)
304  {
305  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Slave is in " + getSlaveStateString(state));
306  }
307  else if (state == EC_STATE_PRE_OP || !bus_->workingCounterIsOk())
308  {
309  if (state == EC_STATE_PRE_OP)
310  {
311  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Slave is in " + getSlaveStateString(state));
312  }
313  else if (!bus_->workingCounterIsOk())
314  {
315  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Working counter is too low, expected working counter is " +
316  std::to_string(bus_->getExpectedWorkingCounter()));
317  }
318  }
319  else if (state == EC_STATE_SAFE_OP || state == EC_STATE_OPERATIONAL)
320  {
321  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Slave is in " + getSlaveStateString(state));
322  }
323  stat.add("EtherCAT Slave State", getSlaveStateString(state));
324  stat.add("Product Name", getProductName());
325  stat.add("Serial Number (S/N)", std::to_string(fetchSerialNumber()));
326  stat.add("EtherCAT Interface", bus_->getName());
327  stat.add("EtherCAT Address", std::to_string(address_));
328  stat.add("Runs Async", runsAsync() ? "Yes" : "No");
329  stat.add("Has Error", has_error ? "Yes" : "No");
330  std::stringstream al_status_code_stream;
331  al_status_code_stream << "0x" << std::setfill('0') << std::setw(8) << std::hex << al_status_code;
332  stat.add("Error Code", al_status_code_stream.str());
333 }
334 
336 {
337  Reading reading;
338  getReading(reading);
339  Statusword status_word = reading.getStatusword();
340  std::lock_guard<std::recursive_mutex> lock(dataFlagsMutex_);
341  status_word.setData(status_word.getData() | currentDataFlagsDiagnostics_.getData());
342  currentDataFlagsDiagnostics_ = status_word;
343 }
344 
346 {
347  std::lock_guard<std::recursive_mutex> lock(dataFlagsMutex_);
349 }
350 
352 {
353  std::lock_guard<std::recursive_mutex> lock(dataFlagsMutex_);
355  std::bitset<32> bits(status_word.getData());
356  if (status_word.hasErrorAdcSaturated() || status_word.hasErrorAccSaturated() || status_word.hasErrorGyroSaturated() ||
357  status_word.hasErrorAdcOutOfSync() || status_word.hasErrorSensingRangeExceeded() ||
358  status_word.hasFatalSupplyVoltage())
359  {
360  stat.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Errors in Data Flags");
361  }
362  else if (status_word.hasWarningOvertemperature())
363  {
364  stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "Errors in Data Flags");
365  }
366  else
367  {
368  stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "No errors in Data Flags");
369  }
370  stat.add("ADC Saturated", bits[0] ? "Yes" : "No");
371  stat.add("ACC Saturated", bits[1] ? "Yes" : "No");
372  stat.add("Gyroscope Saturated", bits[2] ? "Yes" : "No");
373  stat.add("ADC is out of sync", bits[3] ? "Yes" : "No");
374  stat.add("Sensing Range Exceeded", bits[4] ? "Yes" : "No");
375  stat.add("High temperature in Rokubimini Sensor", bits[5] ? "Yes" : "No");
376  stat.add("Supply voltage exceeds limits", bits[6] ? "Yes" : "No");
377  stat.add("Reserved 1", bits[7] ? "Yes" : "No");
378  stat.add("Reserved 2", bits[8] ? "Yes" : "No");
379  stat.add("Reserved 3", bits[9] ? "Yes" : "No");
380  stat.add("Reserved 4", bits[10] ? "Yes" : "No");
381  stat.add("Reserved 5", bits[11] ? "Yes" : "No");
382  stat.add("Reserved 6", bits[12] ? "Yes" : "No");
383  stat.add("Reserved 7", bits[13] ? "Yes" : "No");
384  stat.add("Reserved 8", bits[14] ? "Yes" : "No");
385  stat.add("Reserved 9", bits[15] ? "Yes" : "No");
386  stat.add("Reserved 10", bits[16] ? "Yes" : "No");
387  stat.add("Reserved 11", bits[17] ? "Yes" : "No");
388  stat.add("Reserved 12", bits[18] ? "Yes" : "No");
389  stat.add("Reserved 13", bits[19] ? "Yes" : "No");
390  stat.add("Reserved 14", bits[20] ? "Yes" : "No");
391  stat.add("Reserved 15", bits[21] ? "Yes" : "No");
392  stat.add("Reserved 16", bits[22] ? "Yes" : "No");
393  stat.add("Reserved 17", bits[23] ? "Yes" : "No");
394  stat.add("Reserved 18", bits[24] ? "Yes" : "No");
395  stat.add("Reserved 19", bits[25] ? "Yes" : "No");
396  stat.add("Reserved 20", bits[26] ? "Yes" : "No");
397  stat.add("Reserved 21", bits[27] ? "Yes" : "No");
398  stat.add("Reserved 22", bits[28] ? "Yes" : "No");
399  stat.add("Reserved 23", bits[29] ? "Yes" : "No");
400  stat.add("Reserved 24", bits[30] ? "Yes" : "No");
401  stat.add("Reserved 25", bits[31] ? "Yes" : "No");
402 }
404 {
407  return true;
408 }
409 
411 {
412  std::lock_guard<std::recursive_mutex> lock(mutex_);
413  ROS_DEBUG("[%s] Saving configuration parameters", name_.c_str());
414  bool success = true;
415  uint8_t retain_configuration = 0x01;
416  success &= sendSdoWrite(OD_CONTROL_ID, OD_CONTROL_SID_COMMAND, false, retain_configuration);
417  uint8_t status;
418  success &= sendSdoRead(OD_CONTROL_ID, OD_CONTROL_SID_STATUS, false, status);
419  if (status != 0)
420  {
421  ROS_ERROR("[%s] Could not save configuration parameters on device. Status value is: %u", name_.c_str(), status);
422  return false;
423  }
424  return success;
425 }
426 
428 {
429  std::lock_guard<std::recursive_mutex> lock(mutex_);
430  reading = reading_;
431 }
432 
434 {
435  std::lock_guard<std::recursive_mutex> lock(mutex_);
436 
437  RxPdo rx_pdo;
438  rx_pdo.digitalOutput_ = static_cast<uint8_t>(0);
439  bus_->writeRxPdo(address_, rx_pdo);
440 }
441 
443 {
446 }
447 
449 {
450  std::lock_guard<std::recursive_mutex> lock(mutex_);
451  bus_->setState(state, address_);
452 }
453 
455 {
456  std::lock_guard<std::recursive_mutex> lock(mutex_);
457  return bus_->waitForState(state, address_);
458 }
459 
461 {
462  // const auto a = pdoInfos_[PdoTypeEnum::A];
463  std::lock_guard<std::recursive_mutex> lock(mutex_);
464  return pdoInfos_.at(currentPdoTypeEnum_);
465 }
466 
468 {
469  std::lock_guard<std::recursive_mutex> lock(mutex_);
470  if (pdoTypeEnum == PdoTypeEnum::NA)
471  {
472  ROS_ERROR("[%s] Invalid EtherCAT PDO Type.", name_.c_str());
473  return false;
474  }
475 
476  // If PDO setup is already active, return.
477  if (pdoTypeEnum == getCurrentPdoTypeEnum())
478  {
479  return true;
480  }
481 
482  // {
483  // std::lock_guard<std::recursive_mutex> lock(busMutex_);
484  // if (!sendSdoWrite(OD_SWITCH_PDO_ID, OD_SWITCH_PDO_SID, false, pdoInfos_.at(pdoTypeEnum).moduleId_)) {
485  // return false;
486  // }
487  // }
488 
489  currentPdoTypeEnum_ = pdoTypeEnum;
490  return true;
491 }
492 
493 bool RokubiminiEthercatSlave::readFileToBuffer(const std::string& filePath)
494 {
495  // Read the file into the file buffer
496  std::ifstream file(filePath, std::ios::binary);
497  std::string file_buffer;
498  if (file.is_open())
499  {
500  int ch;
501  while ((ch = file.get()) != std::istream::traits_type::eof())
502  {
503  file_buffer.push_back(static_cast<char>(ch));
504  }
505  fileBuffer_ = const_cast<char*>(file_buffer.c_str());
506  fileSize_ = static_cast<int>(file_buffer.size());
507  file.close();
509  {
510  ROS_ERROR("[%s] File is too big.", name_.c_str());
511  return false;
512  }
513  }
514  else
515  {
516  ROS_ERROR_STREAM("[" << getName() << "] "
517  << "Failed to open file " << filePath);
518  return false;
519  }
520  ROS_DEBUG_STREAM("[" << getName() << "] "
521  << "The firmware was read successfully. Size of file buffer: " << fileSize_);
522  return true;
523 }
524 
525 bool RokubiminiEthercatSlave::firmwareUpdate(const std::string& filePath, const std::string& fileName,
526  const uint32_t& password)
527 {
528  bool success;
529  std::lock_guard<std::recursive_mutex> lock(mutex_);
530  if (!readFileToBuffer(filePath))
531  {
532  ROS_ERROR_STREAM("[" << getName() << "] "
533  << "Could not read file in path " << filePath << ".");
534  return false;
535  }
536  success = bus_->writeFirmware(address_, fileName, password, fileSize_, fileBuffer_);
537  if (!bus_->isRunning())
538  {
539  isRunning_ = false;
540  }
541  if (!success)
542  {
543  ROS_ERROR("[%s] Flashing was not successful.", name_.c_str());
544  }
545  return success;
546 }
547 } // namespace ethercat
548 } // namespace rokubimini
void readTxPdo(const uint16_t slave, TxPdo &txPdo) const
bool setAccelerationRange(const unsigned int range)
Sets an acceleration range to the device.
bool hasErrorSensingRangeExceeded() const
bool setAngularRateRange(const unsigned int range)
Sets an angular rate range to the device.
bool firmwareUpdate(const std::string &filePath, const std::string &fileName, const uint32_t &password)
Updates the firmware of the device.
#define OD_SENSOR_CONFIGURATION_SID_CALIBRATION_MATRIX_ACTIVE
Statusword currentDataFlagsDiagnostics_
The current Data Flags Diagnostics (Data Status) which is updated when a new frame is published and i...
const WrenchType & getWrench() const
bool getSerialNumber(unsigned int &serialNumber) override
Accessor for device serial number.
void updateRead() override
This method is called by the EthercatBusManager. Each device attached to this bus reads its data from...
bool getForceTorqueSamplingRate(int &samplingRate)
Gets the force torque sampling rate of the device.
#define OD_IDENTITY_SID_SERIAL_NUMBER
#define OD_TX_PDO_ID_VAL_A
RokubiminiEthercatSlave()=delete
Default constructor is deleted.
PdoTypeEnum getCurrentPdoTypeEnum() const
Accessor for the current PDO type.
bool hasErrorGyroSaturated() const
std::atomic< PdoTypeEnum > currentPdoTypeEnum_
Current PDO type.
bool hasErrorAccSaturated() const
void summary(unsigned char lvl, const std::string s)
uint8_t getState()
Returns the EtherCAT State of the device.
Base class for generic ethercat slaves using soem.
unsigned int fetchSerialNumber() const
Accessor for device serial number.
uint32_t getData() const
#define OD_ANGULAR_RATE_RANGE_ID
bool isRunning()
Returns if the instance is running.
bool writeFirmware(const uint16_t slave, const std::string &fileName, const uint32_t &password, const int fileSize, char *fileBuffer)
#define OD_SENSOR_CONFIGURATION_ID
void updateDataFlags()
Updates the Data Flags variable currentDataFlagsDiagnostics_.
unsigned short uint16_t
const TempType & getTemperature() const
bool sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess, Value &value)
void updateWrite() override
This method is called by the EthercatBusManager. Each device attached to the bus writes its data to t...
int getExpectedWorkingCounter(const uint16_t slave=0) const
#define OD_FORCE_TORQUE_FILTER_SID_SINC_SIZE
#define OD_SAMPLING_RATE_ID
unsigned char uint8_t
void shutdown() override
Shuts down the device.
void setData(const uint32_t data)
bool setSensorConfiguration(const configuration::SensorConfiguration &sensorConfiguration)
Sets a sensor configuration to the device.
#define OD_SENSOR_CONFIGURATION_SID_ORIENTATION_ESTIMATION
const Statusword & getStatusword() const
const Eigen::Matrix< double, 6, 6 > & getCalibrationMatrix() const
bool configurePdo(const PdoTypeEnum pdoTypeEnum)
Configures a PDO in the Ethercat device.
bool setAccelerationFilter(const unsigned int filter)
Sets an acceleration filter to the device.
#define OD_SENSOR_CONFIGURATION_SID_IMU_ACTIVE
void resetDataFlags()
Resets the Data Flags variable currentDataFlagsDiagnostics_.
uint16_t getSlaveALStatusCode(uint16_t slave)
Returns the AL Status Code of a slave.
std::recursive_mutex dataFlagsMutex_
Mutex prohibiting simultaneous access to the Data Flags structure.
#define MAX_FILE_SIZE_FIRMWARE
bool readFileToBuffer(const std::string &filePath)
Reads the contents of a file to an internal buffer.
#define OD_CONTROL_SID_STATUS
void getReading(rokubimini::Reading &reading) const
Gets the internal reading variable.
bool setAngularRateFilter(const unsigned int filter)
Sets an angular rate filter to the device.
EC_STATE_OPERATIONAL
PdoInfos pdoInfos_
Map between PDO types and their infos.
const ImuType & getImu() const
#define OD_CONTROL_SID_COMMAND
unsigned int uint32_t
#define OD_FORCE_TORQUE_FILTER_SID_FIR_DISABLE
std::string getProductName() const
Gets the product name of the device.
void setState(const uint16_t state, const uint16_t slave=0)
#define OD_FORCE_TORQUE_FILTER_ID
signed short int16_t
bool saveConfigParameter()
Saves the current configuration to the device.
#define OD_ACCELERATION_RANGE_ID
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_1
char * fileBuffer_
The buffer to save the contents of the file.
void setStatusword(const Statusword &statusword)
EC_STATE_SAFE_OP
EC_STATE_PRE_OP
void setState(const uint16_t state)
Sets the desired EtherCAT state machine state of the device in the bus.
#define OD_FORCE_TORQUE_FILTER_SID_CHOP_ENABLE
void setForceTorqueSaturated(const bool isForceTorqueSaturated)
#define OD_RX_PDO_ID_VAL_A
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_3
bool waitForState(const uint16_t state)
Wait for an EtherCAT state machine state to be reached.
std::string getSlaveStateString(uint8_t state)
Returns the EtherCAT State of the device in a string.
#define ROS_DEBUG_STREAM(args)
bool setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset)
Sets a force torque offset to the device.
bool sendCalibrationMatrixEntry(const uint8_t subId, const double entry)
Sends a calibration matrix entry to device.
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_6
bool hasFatalSupplyVoltage() const
bool waitForState(const uint16_t state, const uint16_t slave=0, const unsigned int maxRetries=40, const double retrySleep=0.001)
#define OD_CONTROL_ID
bool hasErrorAdcSaturated() const
void updateConnectionStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
Fills the Device Connection Status (ROS diagnostics).
bool runsAsync() const
Returns if the driver runs asynchronously.
PdoInfo getCurrentPdoInfo() const override
Accessor for the current PDO info.
static constexpr double G_TO_METERS_PER_SECOND_SQUARED
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_2
#define OD_SENSOR_CONFIGURATION_SID_TEMPERATURE_COMPENSATION
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_4
#define OD_SENSOR_CALIBRATION_ID
#define OD_SENSOR_FORCE_TORQUE_OFFSET_SID_5
bool hasErrorAdcOutOfSync() const
void createDataFlagsDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Creates the Data Flags Diagnostics status.
static const std::map< uint8_t, std::string > STATE_TO_STRING
bool setConfigMode()
Sets the device in config mode.
Struct defining the Pdo characteristic.
Class for managing an ethercat bus containing one or multiple slaves.
std::string getName() const override
Accessor for device name.
void preSetupConfiguration()
Pre-setup configuration hook.
#define OD_SENSOR_CONFIGURATION_SID_COORD_SYSTEM_CONFIGURATION
#define OD_FORCE_TORQUE_FILTER_SID_FAST_ENABLE
bool sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess, const Value value)
#define OD_ACCELERATION_FILTER_ID
void add(const std::string &key, const T &val)
#define ROS_ERROR_STREAM(args)
#define OD_ANGULAR_RATE_FILTER_ID
#define OD_IDENTITY_ID
#define OD_SENSOR_FORCE_TORQUE_OFFSET_ID
#define OD_SENSOR_CONFIGURATION_SID_INERTIA_COMPENSATION
#define ROS_ERROR(...)
bool setForceTorqueFilter(const configuration::ForceTorqueFilter &filter)
Sets a force torque filter to the device.
void writeRxPdo(const uint16_t slave, const RxPdo &rxPdo)
uint16_t getALStatusCode()
Returns the AL Status Code of the slave.
bool startup() override
This method starts up and initializes the device.
bool hasWarningOvertemperature() const
bool setSensorCalibration(const calibration::SensorCalibration &sensorCalibration)
Sets a sensor calibration to the device.
Reading reading_
The internal reading variable. It&#39;s used for providing to client code the sensor readings, through the getReading () function.
std::atomic< bool > isRunning_
Internal flag to indicate if the instance is running.
static constexpr double DEG_TO_RAD
#define ROS_DEBUG(...)
EC_STATE_INIT


rokubimini_ethercat
Author(s):
autogenerated on Sat Apr 15 2023 02:51:33