force_torque_sensor_handle.cpp
Go to the documentation of this file.
1 /****************************************************************
2  *
3  * Copyright 2020 Intelligent Industrial Robotics (IIROB) Group,
4  * Institute for Anthropomatics and Robotics (IAR) -
5  * Intelligent Process Control and Robotics (IPR),
6  * Karlsruhe Institute of Technology
7  *
8  * Maintainer: Denis Štogl, email: denis.stogl@kit.edu
9  *
10  * Date of update: 2014-2020
11  *
12  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are met:
16  *
17  * * Redistributions of source code must retain the above copyright
18  * notice, this list of conditions and the following disclaimer.
19  * * Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution.
22  * * Neither the name of the copyright holder nor the names of its
23  * contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  *
26  * This program is free software: you can redistribute it and/or modify
27  * it under the terms of the GNU Lesser General Public License LGPL as
28  * published by the Free Software Foundation, either version 3 of the
29  * License, or (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34  * GNU Lesser General Public License LGPL for more details.
35  *
36  * You should have received a copy of the GNU Lesser General Public
37  * License LGPL along with this program.
38  * If not, see <http://www.gnu.org/licenses/>.
39  *
40  ****************************************************************/
41 
43 
44 #include <pluginlib/class_loader.h>
45 
46 using namespace force_torque_sensor;
47 
48 ForceTorqueSensorHandle::ForceTorqueSensorHandle(ros::NodeHandle& nh, hardware_interface::ForceTorqueSensorHW *sensor, std::string sensor_name, std::string output_frame) :
49  hardware_interface::ForceTorqueSensorHandle(sensor_name, output_frame, interface_force_, interface_torque_), nh_(nh), calibration_params_{nh.getNamespace()+"/Calibration/Offset"}, CS_params_{nh.getNamespace()}, HWComm_params_{nh.getNamespace()+"/HWComm"}, FTS_params_{nh.getNamespace()+"/FTS"}, pub_params_{nh.getNamespace()+"/Publish"}, node_params_{nh.getNamespace()+"/Node"}, gravity_params_{nh.getNamespace()+"/GravityCompensation/params"}
50 {
51  p_Ftc = sensor;
52  prepareNode(output_frame);
53 }
54 
55 ForceTorqueSensorHandle::ForceTorqueSensorHandle(ros::NodeHandle& nh, std::string sensor_name, std::string output_frame) :
56  hardware_interface::ForceTorqueSensorHandle(sensor_name, output_frame, interface_force_, interface_torque_), nh_(nh), calibration_params_{nh.getNamespace()+"/Calibration/Offset"}, CS_params_{nh.getNamespace()}, HWComm_params_{nh.getNamespace()+"/HWComm"}, FTS_params_{nh.getNamespace()+"/FTS"}, pub_params_{nh.getNamespace()+"/Publish"}, node_params_{nh.getNamespace()+"/Node"}, gravity_params_{nh.getNamespace()+"/GravityCompensation/params"}
57 {
58  node_params_.fromParamServer();
59 
60  //load specified sensor HW
61  sensor_loader_.reset (new pluginlib::ClassLoader<hardware_interface::ForceTorqueSensorHW>("force_torque_sensor", "hardware_interface::ForceTorqueSensorHW"));
62  if (!node_params_.sensor_hw.empty())
63  {
64  try
65  {
66  sensor_.reset (sensor_loader_->createUnmanagedInstance (node_params_.sensor_hw));
67  ROS_INFO_STREAM ("Sensor type " << node_params_.sensor_hw << " was successfully loaded.");
68 
69  p_Ftc = sensor_.get();
70  prepareNode(output_frame);
71  }
73  {
74  ROS_ERROR_STREAM ("Plugin failed to load:" << e.what());
75  }
76  }
77  else
78  {
79  ROS_ERROR_STREAM ("Failed to getParam 'sensor_hw' (namespace: " << nh.getNamespace() << ").");
80  ROS_ERROR ("Sensor hardware failed to load");
81  }
82 }
83 
84 
85 void ForceTorqueSensorHandle::prepareNode(std::string output_frame)
86 {
87  ROS_DEBUG_STREAM ("Sensor is using namespace '" << nh_.getNamespace() << "'.");
88 
89  transform_frame_ = output_frame;
90 
92 
93  calibration_params_.fromParamServer();
94  CS_params_.fromParamServer();
95  HWComm_params_.fromParamServer();
96  FTS_params_.fromParamServer();
97  pub_params_.fromParamServer();
98  node_params_.fromParamServer();
99 
100  if (calibration_params_.n_measurements <= 0)
101  {
102  ROS_WARN("Parameter 'Calibration/n_measurements' is %d (<=0) using default: 20", calibration_params_.n_measurements);
103  calibration_params_.n_measurements = 20;
104  }
105  else {
106  calibration_params_.n_measurements = std::abs(calibration_params_.n_measurements);
107  }
108 
109  m_isInitialized = false;
110  m_isCalibrated = false;
118 
119  p_tfBuffer = new tf2_ros::Buffer();
121 
124 
125  //Wrench Publisher
126  if(pub_params_.sensor_data){
128  }
129 
130  if(pub_params_.transformed_data){
132  }
133 
134  if(pub_params_.output_data){
136  }
137 
138  ros::NodeHandle filters_nh("~");
139  ROS_DEBUG_STREAM("Filters are using namespace '" << filters_nh.getNamespace() << "'.");
140 
141  //Median Filter
142  if(filters_nh.hasParam("MovingMeanFilter")) {
143  ROS_DEBUG("Using MovingMeanFilter");
144  useMovingMean = true;
145  moving_mean_filter_->configure(filters_nh.getNamespace()+"/MovingMeanFilter");
146 
147  if(pub_params_.moving_mean){
149  }
150  } else {
151  ROS_WARN("MovingMeanFilter configuration not found. It will not be used!");
152  }
153 
154  //Low Pass Filter
155  if(filters_nh.hasParam("LowPassFilter")) {
156  ROS_DEBUG("Using LowPassFilter");
157  useLowPassFilter = true;
158  low_pass_filter_->configure(filters_nh.getNamespace()+"/LowPassFilter");
159 
160  if(pub_params_.low_pass){
162  }
163  } else {
164  ROS_WARN("LowPassFilter configuration not found. It will not be used!");
165  }
166 
167  //Gravity Compenstation
168  if(filters_nh.hasParam("GravityCompensation")) {
169  ROS_DEBUG("Using GravityCompensation");
170  useGravityCompensator = true;
171  gravity_compensator_->configure(filters_nh.getNamespace()+"/GravityCompensation");
172 
173  // Read GravityParams also here to use for recalibration (see: srvCallback_CalculateOffsetWithoutGravity Function)
174  gravity_params_.fromParamServer();
175  if(pub_params_.gravity_compensated){
177  }
178  } else {
179  ROS_WARN("GravityCompensation configuration not found. It will not be used!");
180  }
181 
182  //Threshold Filter
183  if(filters_nh.hasParam("ThresholdFilter")) {
184  ROS_DEBUG("Using ThresholdFilter");
185  useThresholdFilter = true;
186  threshold_filter_->configure(filters_nh.getNamespace()+"/ThresholdFilter");
187 
188  if(pub_params_.threshold_filtered){
190  }
191  } else {
192  ROS_WARN("ThresholdFilter configuration not found. It will not be used!");
193  }
194 
195  p_Ftc->initCommunication(HWComm_params_.type, HWComm_params_.path, HWComm_params_.baudrate, FTS_params_.base_identifier);
196 
197  if (FTS_params_.auto_init)
198  {
199  std::string msg;
200  bool success;
201  ROS_DEBUG("Starting Autoinit...");
202  init_sensor(msg, success);
203  ROS_INFO("Autoinit: %s", msg.c_str());
204  }
205 }
206 
207 void ForceTorqueSensorHandle::init_sensor(std::string& msg, bool& success)
208 {
209  if (!m_isInitialized)
210  {
211  // read return init status and check it!
212  if (p_Ftc->init())
213  {
214  // start timer for reading FT-data
216  ros::Duration(0.1).sleep(); //wait for measurements to come
217 
218  m_isInitialized = true;
219  success = true;
220  msg = "FTS initialized!";
221 
222  // Calibrate sensor
223  if (calibration_params_.isStatic)
224  {
225  std::map<std::string,double> forceVal,torqueVal;
226  forceVal = calibration_params_.force;
227  torqueVal = calibration_params_.torque;
228 
229  ROS_INFO("Using static Calibration Offset from paramter server with parametes Force: x:%f, y:%f, z:%f; Torque: x: %f, y:%f, z:%f;",
230  forceVal["x"], forceVal["y"], forceVal["z"],
231  torqueVal["x"], torqueVal["y"], torqueVal["z"]
232  );
233 
234  offset_.force.x = forceVal["x"];
235  offset_.force.y = forceVal["y"];
236  offset_.force.z = forceVal["z"];
237  offset_.torque.x = torqueVal["x"];
238  offset_.torque.y = torqueVal["y"];
239  offset_.torque.z = torqueVal["z"];
240 
241  apply_offset = true;
242  m_isCalibrated = true;
243  }
244  else
245  {
246  ROS_INFO("Calibrating sensor. Plase wait...");
247  geometry_msgs::Wrench temp_offset;
248  if (not calculate_offset(true, &temp_offset))
249  {
250  success = false;
251  msg = "Calibration failed! :/";
252  }
253  }
254  }
255  else
256  {
257  m_isInitialized = false;
258  success = false;
259  msg = "FTS could not be initialized! :/";
260  ROS_FATAL("FTS Hardware could not be initialized");
261  }
263  }
264 }
265 
266 bool ForceTorqueSensorHandle::srvCallback_Init(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
267 {
268  std::string msg;
269  bool success;
270 
271  init_sensor(msg, success);
272  res.message = msg;
273  res.success = success;
274 
275  return true;
276 }
277 
278 bool ForceTorqueSensorHandle::srvCallback_CalculateAverageMasurement(force_torque_sensor::CalculateAverageMasurement::Request& req, force_torque_sensor::CalculateAverageMasurement::Response& res)
279 {
280  if (m_isInitialized)
281  {
282  res.success = true;
283  res.message = "Measurement successfull! :)";
284  res.measurement = makeAverageMeasurement(req.N_measurements, req.T_between_meas, req.frame_id);
285  }
286  else
287  {
288  res.success = false;
289  res.message = "FTS not initialised! :/";
290  }
291 
292  return true;
293 }
294 
295 bool ForceTorqueSensorHandle::srvCallback_CalculateOffset(force_torque_sensor::CalculateSensorOffset::Request& req, force_torque_sensor::CalculateSensorOffset::Response& res)
296 {
297  if (m_isInitialized)
298  {
299  if (calculate_offset(req.apply_after_calculation, &res.offset))
300  {
301  res.success = true;
302  res.message = "Calibration successfull! :)";
303  }
304  else
305  {
306  res.success = false;
307  res.message = "Calibration failed! :/";
308  }
309  }
310  else
311  {
312  res.success = false;
313  res.message = "FTS not initialised! :/";
314  }
315 
316  return true;
317 }
318 
319 bool ForceTorqueSensorHandle::srvCallback_CalculateOffsetWithoutGravity(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
320 {
321  if (!m_isInitialized)
322  {
323  ROS_WARN("FTS-Node is not initialized, please initialize first!");
324  res.success = false;
325  res.message = "Failed to recalibrate because Node is not initiliazed.";
326  return true;
327  }
328  if (!(nh_.hasParam("force") && nh_.hasParam("CoG_x") && nh_.hasParam("CoG_y") && nh_.hasParam("CoG_z")))
329  {
330  ROS_ERROR("Cannot use dynamic recalibration without all values for Gravity Compensation, set parameters or use "
331  "'Calibrate' service instead.");
332  res.success = false;
333  res.message = "Failed to recalibrate because of missing Parameters for Gravity Compensation.";
334  return true;
335  }
336  geometry_msgs::Vector3Stamped gravity, gravity_transformed;
337  geometry_msgs::Vector3 cog;
338  double force_value;
339  cog.x = gravity_params_.CoG_x;
340  cog.y = gravity_params_.CoG_y;
341  cog.z = gravity_params_.CoG_z;
342  force_value = gravity_params_.force;
343  gravity.vector.z = -force_value;
344  tf2::doTransform(gravity, gravity_transformed, p_tfBuffer->lookupTransform(node_params_.sensor_frame, transform_frame_, ros::Time(0)));
345  geometry_msgs::Wrench offset;
346  calculate_offset(false, &offset);
347  offset_.force.x -= gravity_transformed.vector.x;
348  offset_.force.y -= gravity_transformed.vector.y;
349  offset_.force.z -= gravity_transformed.vector.z;
350  offset_.torque.x -= (gravity_transformed.vector.y * cog.z - gravity_transformed.vector.z * cog.y);
351  offset_.torque.y -= (gravity_transformed.vector.z * cog.x - gravity_transformed.vector.x * cog.z);
352  offset_.torque.z -= (gravity_transformed.vector.x * cog.y - gravity_transformed.vector.y * cog.x);
353  res.success = true;
354  res.message = "Successfully recalibrated FTS!";
355  return true;
356 }
357 
358 bool ForceTorqueSensorHandle::srvCallback_setSensorOffset(force_torque_sensor::SetSensorOffset::Request &req, force_torque_sensor::SetSensorOffset::Response &res)
359 {
360  offset_.force.x = req.offset.force.x;
361  offset_.force.y = req.offset.force.y;
362  offset_.force.z = req.offset.force.z;
363  offset_.torque.x = req.offset.torque.x;
364  offset_.torque.y = req.offset.torque.y;
365  offset_.torque.z = req.offset.torque.z;
366 
367  res.success = true;
368  res.message = "Offset is successfully set!";
369  return true;
370 }
371 
372 
373 bool ForceTorqueSensorHandle::calculate_offset(bool apply_after_calculation, geometry_msgs::Wrench *new_offset)
374 {
375  apply_offset = false;
377  ROS_DEBUG("Calibrating using %d measurements and %f s pause between measurements.", calibration_params_.n_measurements, calibration_params_.T_between_meas);
378  geometry_msgs::Wrench temp_offset = makeAverageMeasurement(calibration_params_.n_measurements, calibration_params_.T_between_meas);
379 
381  if (apply_after_calculation) {
382  offset_ = temp_offset;
383  }
384  apply_offset = true;
385 
386  ROS_DEBUG("Calculated Calibration Offset: Fx: %f; Fy: %f; Fz: %f; Mx: %f; My: %f; Mz: %f", temp_offset.force.x, temp_offset.force.y, temp_offset.force.z, temp_offset.torque.x, temp_offset.torque.y, temp_offset.torque.z);
387 
388  m_isCalibrated = true;
389  *new_offset = temp_offset;
390 
391  return m_isCalibrated;
392 }
393 
394 geometry_msgs::Wrench ForceTorqueSensorHandle::makeAverageMeasurement(uint number_of_measurements, double time_between_meas, std::string frame_id)
395 {
396  geometry_msgs::Wrench measurement;
397  int num_of_errors = 0;
398  ros::Duration duration(time_between_meas);
399  for (int i = 0; i < number_of_measurements; i++) {
400  geometry_msgs::Wrench output;
401  if (not frame_id.empty()) {
402  if (not transform_wrench(frame_id, node_params_.sensor_frame, moving_mean_filtered_data.wrench, output)) {
403  num_of_errors++;
404  if (num_of_errors > 200) {
405  return measurement;
406  }
407  i--;
408  continue;
409  }
410  }
411  else {
412  output = moving_mean_filtered_data.wrench;
413  }
414 
415  measurement.force.x += output.force.x;
416  measurement.force.y += output.force.y;
417  measurement.force.z += output.force.z;
418  measurement.torque.x += output.torque.x;
419  measurement.torque.y += output.torque.y;
420  measurement.torque.z+= output.torque.z;
421 
422  duration.sleep();
423  }
424  measurement.force.x /= number_of_measurements;
425  measurement.force.y /= number_of_measurements;
426  measurement.force.z /= number_of_measurements;
427  measurement.torque.x /= number_of_measurements;
428  measurement.torque.y /= number_of_measurements;
429  measurement.torque.z /= number_of_measurements;
430  return measurement;
431 }
432 
433 
434 // TODO: make this to use filtered data (see calibrate)
436  std_srvs::Trigger::Response& res)
437 {
439  {
440  double angle;
441 
442  ROS_INFO("Please push FTS with force larger than 10 N in desired direction of new axis %d",
443  CS_params_.push_direction);
444 
445  for (int i = 0; i < CS_params_.n_measurements; i++)
446  {
447  int status = 0;
448  double Fx, Fy, Fz, Tx, Ty, Tz = 0;
449  p_Ftc->readFTData(status, Fx, Fy, Fz, Tx, Ty, Tz);
450 
451  angle += atan2(Fy, Fx);
452 
453  usleep(CS_params_.T_between_meas);
454  }
455 
456  angle /= CS_params_.n_measurements;
457 
458  if (CS_params_.push_direction)
459  {
460  angle -= M_PI / 2;
461  }
462 
463  ROS_INFO("Please rotate your coordinate system for %f rad (%f deg) around z-axis", angle, angle / M_PI * 180.0);
464 
465  res.success = true;
466  res.message = "CoordianteSystem successfull! :)";
467  }
468  else
469  {
470  res.success = false;
471  res.message = "FTS not initialised or not calibrated! :/";
472  }
473 
474  return true;
475 }
476 
477 bool ForceTorqueSensorHandle::srvReadDiagnosticVoltages(force_torque_sensor::DiagnosticVoltages::Request& req,
478  force_torque_sensor::DiagnosticVoltages::Response& res)
479 {
480  p_Ftc->readDiagnosticADCVoltages(req.index, res.adc_value);
481 
482  return true;
483 }
484 
486 {
487 // ros::Time timestamp = ros::Time::now();
488  if (p_Ftc->readFTData(0, sensor_data.wrench.force.x, sensor_data.wrench.force.y, sensor_data.wrench.force.z,
489  sensor_data.wrench.torque.x, sensor_data.wrench.torque.y, sensor_data.wrench.torque.z)
490  != false)
491  {
492  sensor_data.header.stamp = ros::Time::now();
493  sensor_data.header.frame_id = node_params_.sensor_frame;
494  if (apply_offset) {
495  sensor_data.wrench.force.x -= offset_.force.x;
496  sensor_data.wrench.force.y -= offset_.force.y;
497  sensor_data.wrench.force.z -= offset_.force.z;
498  sensor_data.wrench.torque.x -= offset_.torque.x;
499  sensor_data.wrench.torque.y -= offset_.torque.y;
500  sensor_data.wrench.torque.z -= offset_.torque.z;
501  }
502 
503  //lowpass
504  low_pass_filtered_data.header = sensor_data.header;
507  }
509 
510  //moving_mean
512  if(useMovingMean){
514  }
516 
517 
518  if (ft_data_lock_.try_lock_for(std::chrono::milliseconds(1))) {
520  ft_data_lock_.unlock();
521  }
522  else {
523  ROS_WARN("pullFTData: Waiting for Lock for 1ms not successful! If this happens more often You might have a problem with timing of measurements!");
524  }
525 
526 
527  if(pub_params_.sensor_data)
528  if (sensor_data_pub_->trylock()){
531  }
532 
533  if(pub_params_.low_pass)
534  if (low_pass_pub_->trylock()){
537  }
538 
539  if(pub_params_.moving_mean)
540  if (moving_mean_pub_->trylock()){
543  }
544  }
545 
546 // std::cout << (ros::Time::now() - timestamp).toNSec()/1000.0 << " ms" << std::endl;
547 }
548 
550 {
551  if (ft_data_lock_.try_lock_for(std::chrono::milliseconds(1))) {
553  ft_data_lock_.unlock();
554  }
555  else {
556  ROS_WARN("filterFTData: Waiting for Lock for 1ms not successful! Using old data! If this happens more often You might have a problem with timing of measurements!");
557  }
558 
559  transformed_data.header.stamp = filtered_data_input_.header.stamp;
560  transformed_data.header.frame_id = transform_frame_;
562  {
563  //gravity compensation
565  {
567  }
569 
570  //treshhold filtering
572  {
574  }
576 
577  if(pub_params_.transformed_data)
581  }
582  if(pub_params_.gravity_compensated && useGravityCompensator)
586  }
587 
588  if(pub_params_.threshold_filtered && useThresholdFilter)
592  }
594  }
595  else {
597  }
598 }
599 
600 bool ForceTorqueSensorHandle::transform_wrench(std::string goal_frame, std::string source_frame, geometry_msgs::Wrench wrench, geometry_msgs::Wrench& transformed)
601 {
602  if (output_transform_.transform.rotation.x == 0 and output_transform_.transform.rotation.y == 0 and output_transform_.transform.rotation.z == 0 and output_transform_.transform.rotation.w == 0) {
603  ROS_INFO_THROTTLE(1, "FTS Transform not yet initalized, Trying to get one...");
604  if (!updateTransform(transform_frame_, node_params_.sensor_frame)) {
605  ROS_WARN_STREAM_THROTTLE(1, "Transform between '" << node_params_.sensor_frame << "' and '" << transform_frame_ << "' not available! Probably not ready yet. If get this mesage more often, please check URDF descritption of Your robot!");
606  return false;
607  }
608  else if (node_params_.static_application) {
609  ROS_INFO("Got FTS Transform for static application!");
610  }
611  }
612  if (!node_params_.static_application) {
613  if (!updateTransform(goal_frame, source_frame)) {
614  return false;
615  }
616  }
617 
618  tf2::doTransform(wrench, transformed, output_transform_);
619  return true;
620 }
621 
622 bool ForceTorqueSensorHandle::updateTransform(std::string goal_frame, std::string source_frame)
623 {
624  try
625  {
626  output_transform_ = p_tfBuffer->lookupTransform(goal_frame, source_frame, ros::Time(0));
627  }
628  catch (tf2::TransformException ex)
629  {
630  ROS_ERROR_THROTTLE(2, "%s", ex.what());
631  return false;
632  }
633  return true;
634 }
635 
636 void ForceTorqueSensorHandle::reconfigureCalibrationRequest(force_torque_sensor::CalibrationConfig& config, uint32_t level)
637 {
638  calibration_params_.fromConfig(config);
639 }
640 
642 {
643  filterFTData();
644 
645  if(pub_params_.output_data) {
646  if (output_data_pub_->trylock()){
649  }
650  }
651 
652  interface_force_[0] = output_data.wrench.force.x;
653  interface_force_[1] = output_data.wrench.force.y;
654  interface_force_[2] = output_data.wrench.force.z;
655 
656  interface_torque_[0] = output_data.wrench.torque.x;
657  interface_torque_[1] = output_data.wrench.torque.y;
658  interface_torque_[2] = output_data.wrench.torque.z;
659 }
bool configure(const std::string &param_name, ros::NodeHandle node_handle=ros::NodeHandle())
bool srvCallback_CalculateOffsetWithoutGravity(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
force_torque_sensor::FTSConfigurationParameters FTS_params_
#define ROS_FATAL(...)
force_torque_sensor::CalibrationParameters calibration_params_
virtual bool initCommunication(int type, std::string path, int baudrate, int base_identifier)
force_torque_sensor::CoordinateSystemCalibrationParameters CS_params_
TF2SIMD_FORCE_INLINE tf2Scalar angle(const Quaternion &q1, const Quaternion &q2)
bool updateTransform(std::string goal_frame, std::string source_frame)
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * threshold_filtered_pub_
geometry_msgs::Wrench makeAverageMeasurement(uint number_of_measurements, double time_between_meas, std::string frame_id="")
filters::FilterBase< geometry_msgs::WrenchStamped > * gravity_compensator_
bool sleep() const
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
void start()
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * moving_mean_pub_
filters::FilterBase< geometry_msgs::WrenchStamped > * threshold_filter_
bool srvCallback_CalculateAverageMasurement(force_torque_sensor::CalculateAverageMasurement::Request &req, force_torque_sensor::CalculateAverageMasurement::Response &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
#define ROS_WARN(...)
bool calculate_offset(bool apply_after_calculation, geometry_msgs::Wrench *new_offset)
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * output_data_pub_
filters::FilterBase< geometry_msgs::WrenchStamped > * moving_mean_filter_
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * transformed_data_pub_
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * low_pass_pub_
force_torque_sensor::PublishConfigurationParameters pub_params_
virtual bool update(const T &data_in, T &data_out)=0
#define ROS_ERROR_THROTTLE(rate,...)
iirob_filters::GravityCompensationParameters gravity_params_
virtual bool readFTData(int statusCode, double &Fx, double &Fy, double &Fz, double &Tx, double &Ty, double &Tz)
bool srvCallback_setSensorOffset(force_torque_sensor::SetSensorOffset::Request &req, force_torque_sensor::SetSensorOffset::Response &res)
bool srvCallback_Init(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
#define ROS_INFO(...)
bool transform_wrench(std::string goal_frame, std::string source_frame, geometry_msgs::Wrench wrench, geometry_msgs::Wrench &transformed)
bool srvCallback_CalculateOffset(force_torque_sensor::CalculateSensorOffset::Request &req, force_torque_sensor::CalculateSensorOffset::Response &res)
dynamic_reconfigure::Server< force_torque_sensor::CalibrationConfig > reconfigCalibrationSrv_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
const std::string & getNamespace() const
force_torque_sensor::HWCommunicationConfigurationParameters HWComm_params_
void reconfigureCalibrationRequest(force_torque_sensor::CalibrationConfig &config, uint32_t level)
#define ROS_DEBUG_STREAM(args)
void init_sensor(std::string &msg, bool &success)
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * gravity_compensated_pub_
#define ROS_WARN_STREAM_THROTTLE(rate, args)
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * sensor_data_pub_
#define ROS_INFO_STREAM(args)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
boost::shared_ptr< hardware_interface::ForceTorqueSensorHW > sensor_
bool srvReadDiagnosticVoltages(force_torque_sensor::DiagnosticVoltages::Request &req, force_torque_sensor::DiagnosticVoltages::Response &res)
static Time now()
#define ROS_INFO_THROTTLE(rate,...)
boost::shared_ptr< pluginlib::ClassLoader< hardware_interface::ForceTorqueSensorHW > > sensor_loader_
filters::FilterBase< geometry_msgs::WrenchStamped > * low_pass_filter_
virtual bool readDiagnosticADCVoltages(int index, short int &value)
bool hasParam(const std::string &key) const
#define ROS_ERROR_STREAM(args)
force_torque_sensor::NodeConfigurationParameters node_params_
#define ROS_ERROR(...)
bool srvCallback_DetermineCoordinateSystem(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
hardware_interface::ForceTorqueSensorHW * p_Ftc
#define ROS_DEBUG(...)


force_torque_sensor
Author(s):
autogenerated on Fri Sep 18 2020 03:06:30