RokubiminiEthercat.cpp
Go to the documentation of this file.
2 #include <rokubimini_msgs/Reading.h>
3 #include <csignal>
4 #include <thread>
5 
6 namespace rokubimini
7 {
8 namespace ethercat
9 {
11 {
12 }
13 
15 {
16  {
17  std::lock_guard<std::recursive_mutex> lock(readingMutex_);
18  slavePtr_->getReading(reading_);
19 
20  // Update statusword.
21  auto statusword(reading_.getStatusword());
22  setStatusword(statusword);
23  statuswordRequested_ = false;
24 
25  // Handle some errors here
26 
27  // Log if activated.
28  // if (logger_.logIsActive()) {
29  // logger_.addDataToLog(reading_);
30  // }
31 
32  // External reading callbacks.
33  for (const auto& reading_cb : readingCbs_)
34  {
35  reading_cb.second(getName(), reading_);
36  }
37  }
38 
39  if (deviceIsMissing())
40  {
41  Statusword statusword;
42  // statusword.setStateEnum(fsm::StateEnum::DeviceMissing);
43  setStatusword(statusword);
44  }
45  else
46  {
47  // if (statusword_.isEmpty()) {
48  // requestAndSetStatusword();
49  // }
50  // if (statusword_.isEmpty()) {
51  // return;
52  // }
53  }
54 
55  // const fsm::StateEnum activeState = statusword_.getStateEnum();
56  // if (activeState == fsm::StateEnum::NA) {
57  // ROS_WARN_STREAM("The FSM state is not available.");
58  // return;
59  // }
60  // stateMachine_.updateActiveState(activeState);
61 }
62 
64 {
65  slavePtr_->shutdown();
66 }
67 
69 {
70  return false;
71 }
72 
73 bool RokubiminiEthercat::getSerialNumber(unsigned int& serialNumber)
74 {
75  return slavePtr_->getSerialNumber(serialNumber);
76 }
77 
79 {
80  return slavePtr_->getForceTorqueSamplingRate(samplingRate);
81 }
82 
84 {
85  return slavePtr_->setForceTorqueFilter(filter);
86 }
87 
88 bool RokubiminiEthercat::setAccelerationFilter(const unsigned int filter)
89 {
90  return slavePtr_->setAccelerationFilter(filter);
91 }
92 
93 bool RokubiminiEthercat::setAngularRateFilter(const unsigned int filter)
94 {
95  return slavePtr_->setAngularRateFilter(filter);
96 }
97 
98 bool RokubiminiEthercat::setAccelerationRange(const unsigned int range)
99 {
100  return slavePtr_->setAccelerationRange(range);
101 }
102 
103 bool RokubiminiEthercat::setAngularRateRange(const unsigned int range)
104 {
105  return slavePtr_->setAngularRateRange(range);
106 }
107 
108 bool RokubiminiEthercat::setForceTorqueOffset(const Eigen::Matrix<double, 6, 1>& forceTorqueOffset)
109 {
110  return slavePtr_->setForceTorqueOffset(forceTorqueOffset);
111 }
112 
114 {
115  if (!slavePtr_->setSensorConfiguration(sensorConfiguration))
116  {
117  return false;
118  }
119  getConfiguration().setSensorConfiguration(sensorConfiguration);
120  return true;
121 }
122 
124 {
125  if (!slavePtr_->setSensorCalibration(sensorCalibration))
126  {
127  return false;
128  }
129  getConfiguration().setSensorCalibration(sensorCalibration);
130  return true;
131 }
132 
134 {
135  return slavePtr_->setConfigMode();
136 }
137 
139 {
140  return slavePtr_->setRunMode();
141 }
142 
144 {
145  return slavePtr_->saveConfigParameter();
146 }
147 
148 using RokubiminiReadingRos = rokubimini_msgs::Reading;
149 using RokubiminiWrenchRos = geometry_msgs::WrenchStamped;
150 using RokubiminiImuRos = sensor_msgs::Imu;
151 using RokubiminiTemperatureRos = sensor_msgs::Temperature;
153 {
154  readingPublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiReadingRos>(
155  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/reading", 10, false));
156 
157  wrenchPublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiWrenchRos>(
158  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/wrench", 10, false));
159 
160  imuPublisher_ = std::make_shared<ros::Publisher>(
161  nh_->advertise<RokubiminiImuRos>(nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/imu", 10, false));
162 
163  temperaturePublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiTemperatureRos>(
164  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/temperature", 10, false));
165 }
166 
168 {
169  auto reading = getReading();
170  rokubimini_msgs::Reading reading_msg;
171  reading_msg.header.stamp = reading.getWrench().header.stamp;
172  // reading_msg.header.frame_id = reading.getWrench().header.frame_id;
173  reading_msg.statusword = reading.getStatusword().getData();
174  reading_msg.imu = reading.getImu();
175  reading_msg.wrench = reading.getWrench();
176  reading_msg.externalImu = reading.getExternalImu();
177  reading_msg.isForceTorqueSaturated = reading.isForceTorqueSaturated();
178  reading_msg.temperature = reading.getTemperature();
179 
180  // if reset wrench is triggered take the mean of the measurements
182  {
183  std::lock_guard<std::recursive_mutex> lock(meanWrenchOffsetMutex_);
185  meanWrenchOffset_.force.x +=
186  ((reading.getWrench().wrench.force.x - meanWrenchOffset_.force.x) / wrenchMessageCount_);
187  meanWrenchOffset_.force.y +=
188  ((reading.getWrench().wrench.force.y - meanWrenchOffset_.force.y) / wrenchMessageCount_);
189  meanWrenchOffset_.force.z +=
190  ((reading.getWrench().wrench.force.z - meanWrenchOffset_.force.z) / wrenchMessageCount_);
191  meanWrenchOffset_.torque.x +=
192  ((reading.getWrench().wrench.torque.x - meanWrenchOffset_.torque.x) / wrenchMessageCount_);
193  meanWrenchOffset_.torque.y +=
194  ((reading.getWrench().wrench.torque.y - meanWrenchOffset_.torque.y) / wrenchMessageCount_);
195  meanWrenchOffset_.torque.z +=
196  ((reading.getWrench().wrench.torque.z - meanWrenchOffset_.torque.z) / wrenchMessageCount_);
197  }
198  readingPublisher_->publish(reading_msg);
199  wrenchPublisher_->publish(reading.getWrench());
200  imuPublisher_->publish(reading.getImu());
201  temperaturePublisher_->publish(reading.getTemperature());
202 }
203 
205 {
206  // wait a small amount of time so that the callback can return the result to the user.
207  std::this_thread::sleep_for(std::chrono::microseconds(500));
208  kill(getpid(), SIGINT);
209 }
210 
211 bool RokubiminiEthercat::firmwareUpdateCallback(rokubimini_msgs::FirmwareUpdateEthercat::Request& request,
212  rokubimini_msgs::FirmwareUpdateEthercat::Response& response)
213 {
214  response.result = slavePtr_->firmwareUpdate(request.file_path, request.file_name, request.password);
215  if (!slavePtr_->isRunning())
216  {
217  // time to shut down the ROS node.
218  std::thread shutdown_thread(&RokubiminiEthercat::signalShutdown, this);
219  shutdown_thread.detach();
220  }
221  return true;
222 }
223 
224 bool RokubiminiEthercat::resetWrenchCallback(rokubimini_msgs::ResetWrench::Request& request,
225  rokubimini_msgs::ResetWrench::Response& response)
226 {
227  ROS_INFO("[%s] Reseting sensor measurements...", name_.c_str());
228 
229  // initialize all variables to zero
230  meanWrenchOffset_.force.x = 0;
231  meanWrenchOffset_.force.y = 0;
232  meanWrenchOffset_.force.z = 0;
233  meanWrenchOffset_.torque.x = 0;
234  meanWrenchOffset_.torque.y = 0;
235  meanWrenchOffset_.torque.z = 0;
237  // enable the computation of the mean wrench
238  computeMeanWrenchFlag_ = true;
239  // wait for computing the mean of wrench measurements
241  ;
242  // disable the computation of the mean wrench
243  computeMeanWrenchFlag_ = false;
244  if (!setConfigMode())
245  {
246  ROS_ERROR("[%s] Device could not switch to config mode", name_.c_str());
247  response.success = false;
248  return true;
249  }
250  geometry_msgs::Wrench wrench;
251  // lock to get the meanWrenchOffset value
252  {
253  std::lock_guard<std::recursive_mutex> lock(meanWrenchOffsetMutex_);
254  wrench = meanWrenchOffset_;
255  }
256  geometry_msgs::Wrench desired_wrench = request.desired_wrench;
257  auto current_offset = configuration_.getForceTorqueOffset();
258  Eigen::Matrix<double, 6, 1> new_offset;
259  // new offset = current wrench measurements + current offset - desired offset
260  new_offset(0, 0) = desired_wrench.force.x - wrench.force.x + current_offset(0, 0);
261  new_offset(1, 0) = desired_wrench.force.y - wrench.force.y + current_offset(1, 0);
262  new_offset(2, 0) = desired_wrench.force.z - wrench.force.z + current_offset(2, 0);
263  new_offset(3, 0) = desired_wrench.torque.x - wrench.torque.x + current_offset(3, 0);
264  new_offset(4, 0) = desired_wrench.torque.y - wrench.torque.y + current_offset(4, 0);
265  new_offset(5, 0) = desired_wrench.torque.z - wrench.torque.z + current_offset(5, 0);
266  ROS_DEBUG_STREAM("[" << getName() << "] "
267  << "New offset is: " << new_offset);
268  if (!setForceTorqueOffset(new_offset))
269  {
270  ROS_ERROR("[%s] Could not write new offset to device", name_.c_str());
271  response.success = false;
272  return true;
273  }
274  if (!setRunMode())
275  {
276  ROS_ERROR("[%s] Device could not switch to run mode", name_.c_str());
277  response.success = false;
278  return true;
279  }
280  response.success = true;
282  ROS_INFO("[%s] Sensor measurements are reset successfully", name_.c_str());
283  return true;
284 }
286 {
287  firmwareUpdateService_ = nh_->advertiseService(nh_->getNamespace() + "/" + getName() + "/firmware_update",
289  resetWrenchService_ = nh_->advertiseService(nh_->getNamespace() + "/" + getName() + "/reset_wrench",
291 }
292 bool RokubiminiEthercat::sendSdoReadGeneric(const std::string& indexString, const std::string& subindexString,
293  const std::string& valueTypeString, std::string& valueString)
294 {
295  return slavePtr_->sendSdoReadGeneric(indexString, subindexString, valueTypeString, valueString);
296 }
297 
298 bool RokubiminiEthercat::sendSdoWriteGeneric(const std::string& indexString, const std::string& subindexString,
299  const std::string& valueTypeString, const std::string& valueString)
300 {
301  return slavePtr_->sendSdoWriteGeneric(indexString, subindexString, valueTypeString, valueString);
302 }
303 
304 template <>
305 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
306  int8_t& value)
307 {
308  return slavePtr_->sendSdoReadInt8(index, subindex, completeAccess, value);
309 }
310 
311 template <>
312 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
313  int16_t& value)
314 {
315  return slavePtr_->sendSdoReadInt16(index, subindex, completeAccess, value);
316 }
317 
318 template <>
319 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
320  int32_t& value)
321 {
322  return slavePtr_->sendSdoReadInt32(index, subindex, completeAccess, value);
323 }
324 
325 template <>
326 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
327  int64_t& value)
328 {
329  return slavePtr_->sendSdoReadInt64(index, subindex, completeAccess, value);
330 }
331 
332 template <>
333 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
334  uint8_t& value)
335 {
336  return slavePtr_->sendSdoReadUInt8(index, subindex, completeAccess, value);
337 }
338 
339 template <>
340 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
341  uint16_t& value)
342 {
343  return slavePtr_->sendSdoReadUInt16(index, subindex, completeAccess, value);
344 }
345 
346 template <>
347 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
348  uint32_t& value)
349 {
350  return slavePtr_->sendSdoReadUInt32(index, subindex, completeAccess, value);
351 }
352 
353 template <>
354 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
355  uint64_t& value)
356 {
357  return slavePtr_->sendSdoReadUInt64(index, subindex, completeAccess, value);
358 }
359 
360 template <>
361 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
362  float& value)
363 {
364  return slavePtr_->sendSdoReadFloat(index, subindex, completeAccess, value);
365 }
366 
367 template <>
368 bool RokubiminiEthercat::sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess,
369  double& value)
370 {
371  return slavePtr_->sendSdoReadDouble(index, subindex, completeAccess, value);
372 }
373 
374 template <>
375 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
376  const int8_t value)
377 {
378  return slavePtr_->sendSdoWriteInt8(index, subindex, completeAccess, value);
379 }
380 
381 template <>
382 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
383  const int16_t value)
384 {
385  return slavePtr_->sendSdoWriteInt16(index, subindex, completeAccess, value);
386 }
387 
388 template <>
389 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
390  const int32_t value)
391 {
392  return slavePtr_->sendSdoWriteInt32(index, subindex, completeAccess, value);
393 }
394 
395 template <>
396 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
397  const int64_t value)
398 {
399  return slavePtr_->sendSdoWriteInt64(index, subindex, completeAccess, value);
400 }
401 
402 template <>
403 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
404  const uint8_t value)
405 {
406  return slavePtr_->sendSdoWriteUInt8(index, subindex, completeAccess, value);
407 }
408 
409 template <>
410 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
411  const uint16_t value)
412 {
413  return slavePtr_->sendSdoWriteUInt16(index, subindex, completeAccess, value);
414 }
415 
416 template <>
417 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
418  const uint32_t value)
419 {
420  return slavePtr_->sendSdoWriteUInt32(index, subindex, completeAccess, value);
421 }
422 
423 template <>
424 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
425  const uint64_t value)
426 {
427  return slavePtr_->sendSdoWriteUInt64(index, subindex, completeAccess, value);
428 }
429 
430 template <>
431 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
432  const float value)
433 {
434  return slavePtr_->sendSdoWriteFloat(index, subindex, completeAccess, value);
435 }
436 
437 template <>
438 bool RokubiminiEthercat::sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess,
439  const double value)
440 {
441  return slavePtr_->sendSdoWriteDouble(index, subindex, completeAccess, value);
442 }
443 
444 } // namespace ethercat
445 } // namespace rokubimini
void shutdownWithCommunication() override
Shuts down a Rokubimini Ethercat device before communication has been closed.
std::atomic< uint32_t > wrenchMessageCount_
The counter that is used for the computation of the mean of the wrench measurements. Used for the "reset service" callback.
void createRosPublishers() override
Adds ROS publishers related to the device.
RokubiminiEthercatSlavePtr slavePtr_
The pointer to implementation.
bool saveConfigParameter() override
Saves the current configuration to the device.
bool sendSdoReadGeneric(const std::string &indexString, const std::string &subindexString, const std::string &valueTypeString, std::string &valueString)
Sends a generic reading SDO to the Ethercat device.
geometry_msgs::WrenchStamped RokubiminiWrenchRos
void setStatusword(Statusword &statusword)
void signalShutdown()
Signals shutdown for the ROS node. It&#39;s used if a firmware update was successful. ...
unsigned short uint16_t
bool setAccelerationRange(const unsigned int range) override
Sets an acceleration range to the device.
bool resetWrenchCallback(rokubimini_msgs::ResetWrench::Request &request, rokubimini_msgs::ResetWrench::Response &response)
The callback for the reset wrench ROS service.
void setSensorConfiguration(const SensorConfiguration &sensorConfiguration)
unsigned char uint8_t
bool setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset) override
Sets a force torque offset to the device.
const Eigen::Matrix< double, 6, 1 > & getForceTorqueOffset() const
bool setForceTorqueFilter(const configuration::ForceTorqueFilter &filter) override
Sets a force torque filter to the device.
sensor_msgs::Temperature RokubiminiTemperatureRos
bool sendSdoWrite(const uint16_t index, const uint8_t subindex, const bool completeAccess, const Value value)
RosPublisherPtr readingPublisher_
The rokubimini_msgs::Reading publisher.
bool setSensorCalibration(const calibration::SensorCalibration &sensorCalibration) override
Sets a sensor calibration to the device.
bool setSensorConfiguration(const configuration::SensorConfiguration &sensorConfiguration) override
Sets a sensor configuration to the device.
bool firmwareUpdateCallback(rokubimini_msgs::FirmwareUpdateEthercat::Request &request, rokubimini_msgs::FirmwareUpdateEthercat::Response &response)
The callback for the firmware update ROS service.
void updateProcessReading() override
Updates the RokubiminiEthercat object with new measurements.
bool setAngularRateFilter(const unsigned int filter) override
Sets an angular rate filter to the device.
bool setAccelerationFilter(const unsigned int filter) override
Sets an acceleration filter to the device.
RosPublisherPtr imuPublisher_
The sensor_msgs::Imu publisher.
std::string getName() const
bool getForceTorqueSamplingRate(int &samplingRate) override
Gets the force torque sampling rate of the device.
unsigned int uint32_t
rokubimini_msgs::Reading RokubiminiReadingRos
signed short int16_t
sensor_msgs::Imu RokubiminiImuRos
ros::ServiceServer resetWrenchService_
The service for resetting the sensor wrench measurements.
#define ROS_INFO(...)
configuration::Configuration configuration_
unsigned __int64 uint64_t
bool sendSdoWriteGeneric(const std::string &indexString, const std::string &subindexString, const std::string &valueTypeString, const std::string &valueString)
Sends a generic write SDO to the Ethercat device.
signed char int8_t
void createRosServices() override
Adds ROS services related to the device.
bool setConfigMode()
Sets the device in config mode.
std::atomic< bool > statuswordRequested_
bool setRunMode()
Sets the device in run mode.
void setSensorCalibration(const calibration::SensorCalibration &sensorCalibration)
std::atomic< bool > computeMeanWrenchFlag_
The flag for enabling the computation of the mean of the wrench measurements. Used withing the "reset...
#define ROS_DEBUG_STREAM(args)
std::recursive_mutex meanWrenchOffsetMutex_
The mutex for accessing the mean of the wrench measurements. Used for the "reset service" callback...
RosPublisherPtr wrenchPublisher_
The sensor_msgs::Wrench publisher.
Reading getReading() const
ros::ServiceServer firmwareUpdateService_
The service for firmware updates.
bool deviceIsMissing() const override
Checks if the device is missing.
const Statusword & getStatusword() const
void setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset)
signed __int64 int64_t
std::multimap< int, ReadingCb, std::greater< int > > readingCbs_
bool getSerialNumber(unsigned int &samplingRate) override
Gets the serial number of the device.
RosPublisherPtr temperaturePublisher_
The sensor_msgs::Temperature publisher.
bool sendSdoRead(const uint16_t index, const uint8_t subindex, const bool completeAccess, Value &value)
signed int int32_t
configuration::Configuration & getConfiguration()
#define ROS_ERROR(...)
std::recursive_mutex readingMutex_
geometry_msgs::Wrench meanWrenchOffset_
The computed mean wrench offset. Used for the "reset service" callback.
void publishRosMessages() override
Publishes ROS messages with data from the rokubimini device.
bool setAngularRateRange(const unsigned int range) override
Sets an angular rate range to the device.


rokubimini_ethercat
Author(s):
autogenerated on Wed Mar 3 2021 03:09:16