RokubiminiSerial.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 serial
9 {
11 {
12  /*
13  ** Print configurations of the sensor
14  */
15  // configuration_.printConfiguration();
16  ROS_DEBUG_STREAM("[" << name_.c_str() << "] Calibration Matrix of the sensor: "
18 
19  implPtr_->startup();
20 }
21 
23 {
24  double time_step;
25  if (!nh_->getParam("time_step", time_step))
26  {
27  ROS_ERROR("[%s] Failed to retrieve 'time_step' parameter", name_.c_str());
28  return false;
29  }
30  implPtr_->setPollingTimeStep(time_step);
31  return implPtr_->init();
32 }
33 
35 {
36  /* ATTENTION
37  **
38  ** All of this is legacy code
39  **
40  */
41  {
42  std::lock_guard<std::recursive_mutex> lock(readingMutex_);
43  implPtr_->getReading(reading_);
44 
45  // Update statusword.
46  auto statusword(reading_.getStatusword());
47  setStatusword(statusword);
48  statuswordRequested_ = false;
49 
50  // Handle some errors here
51 
52  // Log if activated.
53  // if (logger_.logIsActive()) {
54  // logger_.addDataToLog(reading_);
55  // }
56 
57  // External reading callbacks.
58  for (const auto& reading_cb : readingCbs_)
59  {
60  reading_cb.second(getName(), reading_);
61  }
62  }
63 
64  if (deviceIsMissing())
65  {
66  Statusword statusword;
67  // statusword.setStateEnum(fsm::StateEnum::DeviceMissing);
68  setStatusword(statusword);
69  }
70  else
71  {
72  // if (statusword_.isEmpty()) {
73  // requestAndSetStatusword();
74  // }
75  // if (statusword_.isEmpty()) {
76  // return;
77  // }
78  }
79 
80  // const fsm::StateEnum activeState = statusword_.getStateEnum();
81  // if (activeState == fsm::StateEnum::NA) {
82  // ROS_WARN_STREAM("The FSM state is not available.");
83  // return;
84  // }
85  // stateMachine_.updateActiveState(activeState);
86 }
87 
89 {
90  implPtr_->shutdown();
91 }
92 
94 {
95  return false;
96 }
97 
98 bool RokubiminiSerial::getSerialNumber(unsigned int& serialNumber)
99 {
100  return implPtr_->getSerialNumber(serialNumber);
101 }
102 
104 {
105  return implPtr_->getForceTorqueSamplingRate(samplingRate);
106 }
107 
109 {
110  return implPtr_->setForceTorqueFilter(filter);
111 }
112 
113 bool RokubiminiSerial::setAccelerationFilter(const unsigned int filter)
114 {
115  return implPtr_->setAccelerationFilter(filter);
116 }
117 
118 bool RokubiminiSerial::setAngularRateFilter(const unsigned int filter)
119 {
120  return implPtr_->setAngularRateFilter(filter);
121 }
122 
123 bool RokubiminiSerial::setAccelerationRange(const unsigned int range)
124 {
125  return implPtr_->setAccelerationRange(range);
126 }
127 
128 bool RokubiminiSerial::setAngularRateRange(const unsigned int range)
129 {
130  return implPtr_->setAngularRateRange(range);
131 }
132 
133 bool RokubiminiSerial::setForceTorqueOffset(const Eigen::Matrix<double, 6, 1>& forceTorqueOffset)
134 {
135  return implPtr_->setForceTorqueOffset(forceTorqueOffset);
136 }
137 
139 {
140  if (!implPtr_->setSensorConfiguration(sensorConfiguration))
141  {
142  return false;
143  }
144  getConfiguration().setSensorConfiguration(sensorConfiguration);
145  return true;
146 }
147 
149 {
150  if (!implPtr_->setSensorCalibration(sensorCalibration))
151  {
152  return false;
153  }
154  getConfiguration().setSensorCalibration(sensorCalibration);
155  return true;
156 }
157 
159 {
160  return implPtr_->setConfigMode();
161 }
162 
164 {
165  return implPtr_->setRunMode();
166 }
167 
169 {
170  return implPtr_->saveConfigParameter();
171 }
172 
174 {
175  return implPtr_->loadConfig();
176 }
177 
179 {
180  return implPtr_->printUserConfig();
181 }
182 
184 {
185  return implPtr_->setHardwareReset();
186 }
187 
189 {
190  return implPtr_->setInitMode();
191 }
192 
193 using RokubiminiReadingRos = rokubimini_msgs::Reading;
194 using RokubiminiWrenchRos = geometry_msgs::WrenchStamped;
195 using RokubiminiTemperatureRos = sensor_msgs::Temperature;
197 {
198  readingPublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiReadingRos>(
199  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/reading", 10, false));
200 
201  wrenchPublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiWrenchRos>(
202  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/wrench", 10, false));
203 
204  temperaturePublisher_ = std::make_shared<ros::Publisher>(nh_->advertise<RokubiminiTemperatureRos>(
205  nh_->getNamespace() + "/" + getName() + "/ft_sensor_readings/temperature", 10, false));
206 }
207 
209 {
210  if (implPtr_->hasFrameSync() && implPtr_->isRunning())
211  {
212  auto reading = getReading();
213  rokubimini_msgs::Reading reading_msg;
214  reading_msg.header.stamp = reading.getWrench().header.stamp;
215  reading_msg.header.frame_id = reading.getWrench().header.frame_id;
216  reading_msg.statusword = reading.getStatusword().getData();
217  reading_msg.wrench = reading.getWrench();
218  reading_msg.isForceTorqueSaturated = reading.isForceTorqueSaturated();
219  reading_msg.temperature = reading.getTemperature();
220 
221  // if reset wrench is triggered take the mean of the measurements
223  {
224  std::lock_guard<std::recursive_mutex> lock(meanWrenchOffsetMutex_);
226  meanWrenchOffset_.force.x +=
227  ((reading.getWrench().wrench.force.x - meanWrenchOffset_.force.x) / wrenchMessageCount_);
228  meanWrenchOffset_.force.y +=
229  ((reading.getWrench().wrench.force.y - meanWrenchOffset_.force.y) / wrenchMessageCount_);
230  meanWrenchOffset_.force.z +=
231  ((reading.getWrench().wrench.force.z - meanWrenchOffset_.force.z) / wrenchMessageCount_);
232  meanWrenchOffset_.torque.x +=
233  ((reading.getWrench().wrench.torque.x - meanWrenchOffset_.torque.x) / wrenchMessageCount_);
234  meanWrenchOffset_.torque.y +=
235  ((reading.getWrench().wrench.torque.y - meanWrenchOffset_.torque.y) / wrenchMessageCount_);
236  meanWrenchOffset_.torque.z +=
237  ((reading.getWrench().wrench.torque.z - meanWrenchOffset_.torque.z) / wrenchMessageCount_);
238  }
239  readingPublisher_->publish(reading_msg);
240  wrenchPublisher_->publish(reading.getWrench());
241  temperaturePublisher_->publish(reading.getTemperature());
243  }
244  else
245  {
247  }
248  // check if there is no synced frame over 100 times
249  if (noFrameSyncCounter_ > 100)
250  {
251  ROS_ERROR_THROTTLE(3, "[%s] Driver failed to synchronize with the device", name_.c_str());
252  }
253 }
254 
256 {
257  // wait a small amount of time so that the callback can return the result to the user.
258  std::this_thread::sleep_for(std::chrono::microseconds(500));
259  kill(getpid(), SIGINT);
260 }
261 
262 bool RokubiminiSerial::firmwareUpdateCallback(rokubimini_msgs::FirmwareUpdateSerial::Request& request,
263  rokubimini_msgs::FirmwareUpdateSerial::Response& response)
264 {
265  response.result = implPtr_->firmwareUpdate(request.file_path);
266  if (!implPtr_->isRunning())
267  {
268  // time to shut down the ROS node.
269  std::thread shutdown_thread(&RokubiminiSerial::signalShutdown, this);
270  shutdown_thread.detach();
271  }
272  return true;
273 }
274 
275 bool RokubiminiSerial::resetWrenchCallback(rokubimini_msgs::ResetWrench::Request& request,
276  rokubimini_msgs::ResetWrench::Response& response)
277 {
278  ROS_INFO("[%s] Reseting sensor measurements...", name_.c_str());
279 
280  // initialize all variables to zero
281  meanWrenchOffset_.force.x = 0;
282  meanWrenchOffset_.force.y = 0;
283  meanWrenchOffset_.force.z = 0;
284  meanWrenchOffset_.torque.x = 0;
285  meanWrenchOffset_.torque.y = 0;
286  meanWrenchOffset_.torque.z = 0;
288  // enable the computation of the mean wrench
289  computeMeanWrenchFlag_ = true;
290  // wait for computing the mean of wrench measurements
292  ;
293  // disable the computation of the mean wrench
294  computeMeanWrenchFlag_ = false;
295 
296  if (!setConfigMode())
297  {
298  ROS_ERROR("[%s] Device could not switch to config mode", name_.c_str());
299  response.success = false;
300  return true;
301  }
302  geometry_msgs::Wrench wrench;
303  // lock to get the meanWrenchOffset value
304  {
305  std::lock_guard<std::recursive_mutex> lock(meanWrenchOffsetMutex_);
306  wrench = meanWrenchOffset_;
307  }
308 
309  geometry_msgs::Wrench desired_wrench = request.desired_wrench;
310  auto current_offset = configuration_.getForceTorqueOffset();
311  Eigen::Matrix<double, 6, 1> new_offset;
312  // new offset = current offset + desired offset - current wrench measurements
313  new_offset(0, 0) = desired_wrench.force.x - wrench.force.x + current_offset(0, 0);
314  new_offset(1, 0) = desired_wrench.force.y - wrench.force.y + current_offset(1, 0);
315  new_offset(2, 0) = desired_wrench.force.z - wrench.force.z + current_offset(2, 0);
316  new_offset(3, 0) = desired_wrench.torque.x - wrench.torque.x + current_offset(3, 0);
317  new_offset(4, 0) = desired_wrench.torque.y - wrench.torque.y + current_offset(4, 0);
318  new_offset(5, 0) = desired_wrench.torque.z - wrench.torque.z + current_offset(5, 0);
319  ROS_DEBUG_STREAM("[" << getName() << "] "
320  << "New offset is: " << new_offset);
321  if (!setForceTorqueOffset(new_offset))
322  {
323  ROS_ERROR("[%s] Could not write new offset to device", name_.c_str());
324  response.success = false;
325  return true;
326  }
327  if (!setRunMode())
328  {
329  ROS_ERROR("[%s] Device could not switch to run mode", name_.c_str());
330  response.success = false;
331  return true;
332  }
333  response.success = true;
335  ROS_INFO("[%s] Sensor measurements are reset successfully", name_.c_str());
336  return true;
337 }
339 {
340  firmwareUpdateService_ = nh_->advertiseService(nh_->getNamespace() + "/" + getName() + "/firmware_update",
342  resetWrenchService_ = nh_->advertiseService(nh_->getNamespace() + "/" + getName() + "/reset_wrench",
344 }
345 
346 } // namespace serial
347 } // namespace rokubimini
bool getSerialNumber(unsigned int &serialNumber) override
Gets the serial number of the device.
void publishRosMessages() override
Publishes ROS messages with data from the rokubimini device.
uint64_t noFrameSyncCounter_
The counter for measuring failed frame synchronizations.
std::atomic< bool > computeMeanWrenchFlag_
The flag for enabling the computation of the mean of the wrench measurements. Used withing the "reset...
RosPublisherPtr temperaturePublisher_
The sensor_msgs::Temperature publisher.
bool setAngularRateRange(const unsigned int range) override
Sets an angular rate range to the device.
bool saveConfigParameter() override
Saves the current configuration to the device.
bool firmwareUpdateCallback(rokubimini_msgs::FirmwareUpdateSerial::Request &request, rokubimini_msgs::FirmwareUpdateSerial::Response &response)
The callback for the firmware update ROS service.
void setStatusword(Statusword &statusword)
bool setInitMode()
Triggers a software reset of the sensor bringing it to a known state.
void setSensorConfiguration(const SensorConfiguration &sensorConfiguration)
void doStartupWithCommunication() override
Starts up a Rokubimini Serial device after communication has been established.
bool setAccelerationFilter(const unsigned int filter) override
Sets an acceleration filter to the device.
const Eigen::Matrix< double, 6, 1 > & getForceTorqueOffset() const
bool setHardwareReset()
Triggers a hardware reset of the sensor.
sensor_msgs::Temperature RokubiminiTemperatureRos
bool loadConfig()
Loads the configuration of the device.
ros::ServiceServer firmwareUpdateService_
The service for firmware updates.
bool printUserConfig()
Prints all the user configurable parameters.
void createRosServices() override
Adds ROS services related to the device.
static const uint32_t TOTAL_NUMBER_OF_WRENCH_MESSAGES
rokubimini_msgs::Reading RokubiminiReadingRos
#define ROS_ERROR_THROTTLE(rate,...)
RosPublisherPtr readingPublisher_
The rokubimini_msgs::Reading publisher.
std::string getName() const
void updateProcessReading() override
Updates the RokubiminiSerial object with new measurements.
bool getForceTorqueSamplingRate(int &samplingRate) override
Gets the force torque sampling rate of the device.
void createRosPublishers() override
Adds ROS publishers related to the device.
#define ROS_INFO(...)
bool setForceTorqueFilter(const configuration::ForceTorqueFilter &filter) override
Sets a force torque filter to the device.
configuration::Configuration configuration_
bool setSensorConfiguration(const configuration::SensorConfiguration &sensorConfiguration) override
Sets a sensor configuration to the device.
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.
const calibration::SensorCalibration & getSensorCalibration() const
bool init()
Initializes communication with a Rokubimini Serial device.
std::atomic< bool > statuswordRequested_
bool setAngularRateFilter(const unsigned int filter) override
Sets an angular rate filter to the device.
void setSensorCalibration(const calibration::SensorCalibration &sensorCalibration)
geometry_msgs::WrenchStamped RokubiminiWrenchRos
#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...
bool setSensorCalibration(const calibration::SensorCalibration &sensorCalibration) override
Sets a sensor calibration to the device.
Reading getReading() const
RosPublisherPtr wrenchPublisher_
The sensor_msgs::Wrench publisher.
const Statusword & getStatusword() const
void setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset)
ros::ServiceServer resetWrenchService_
The service for resetting the sensor wrench measurements.
bool setAccelerationRange(const unsigned int range) override
Sets an acceleration range to the device.
std::multimap< int, ReadingCb, std::greater< int > > readingCbs_
geometry_msgs::Wrench meanWrenchOffset_
The computed mean wrench offset. Used for the "reset service" callback.
bool resetWrenchCallback(rokubimini_msgs::ResetWrench::Request &request, rokubimini_msgs::ResetWrench::Response &response)
The callback for the reset wrench ROS service.
RokubiminiSerialImplPtr implPtr_
The pointer to implementation.
bool deviceIsMissing() const override
Checks if the device is missing.
configuration::Configuration & getConfiguration()
bool setConfigMode()
Sets the device in config mode.
#define ROS_ERROR(...)
const Eigen::Matrix< double, 6, 6 > & getCalibrationMatrix() const
std::recursive_mutex readingMutex_
void shutdownWithCommunication() override
Shuts down a Rokubimini Serial device before communication has been closed.
void signalShutdown()
Signals shutdown for the ROS node. It&#39;s used if a firmware update was successful. ...
System dependencies.
bool setForceTorqueOffset(const Eigen::Matrix< double, 6, 1 > &forceTorqueOffset) override
Sets a force torque offset to the device.
bool setRunMode()
Sets the device in run mode.


rokubimini_serial
Author(s):
autogenerated on Wed Mar 3 2021 03:09:18