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"}
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"}
79 ROS_ERROR_STREAM (
"Failed to getParam 'sensor_hw' (namespace: " << nh.getNamespace() <<
").");
80 ROS_ERROR (
"Sensor hardware failed to load");
139 ROS_DEBUG_STREAM(
"Filters are using namespace '" << filters_nh.getNamespace() <<
"'.");
142 if(filters_nh.hasParam(
"MovingMeanFilter")) {
151 ROS_WARN(
"MovingMeanFilter configuration not found. It will not be used!");
155 if(filters_nh.hasParam(
"LowPassFilter")) {
164 ROS_WARN(
"LowPassFilter configuration not found. It will not be used!");
168 if(filters_nh.hasParam(
"GravityCompensation")) {
179 ROS_WARN(
"GravityCompensation configuration not found. It will not be used!");
183 if(filters_nh.hasParam(
"ThresholdFilter")) {
192 ROS_WARN(
"ThresholdFilter configuration not found. It will not be used!");
203 ROS_INFO(
"Autoinit: %s", msg.c_str());
220 msg =
"FTS initialized!";
225 std::map<std::string,double> forceVal,torqueVal;
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"]
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"];
246 ROS_INFO(
"Calibrating sensor. Plase wait...");
247 geometry_msgs::Wrench temp_offset;
251 msg =
"Calibration failed! :/";
259 msg =
"FTS could not be initialized! :/";
260 ROS_FATAL(
"FTS Hardware could not be initialized");
273 res.success = success;
283 res.message =
"Measurement successfull! :)";
289 res.message =
"FTS not initialised! :/";
302 res.message =
"Calibration successfull! :)";
307 res.message =
"Calibration failed! :/";
313 res.message =
"FTS not initialised! :/";
323 ROS_WARN(
"FTS-Node is not initialized, please initialize first!");
325 res.message =
"Failed to recalibrate because Node is not initiliazed.";
330 ROS_ERROR(
"Cannot use dynamic recalibration without all values for Gravity Compensation, set parameters or use " 331 "'Calibrate' service instead.");
333 res.message =
"Failed to recalibrate because of missing Parameters for Gravity Compensation.";
336 geometry_msgs::Vector3Stamped gravity, gravity_transformed;
337 geometry_msgs::Vector3 cog;
343 gravity.vector.z = -force_value;
345 geometry_msgs::Wrench 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);
354 res.message =
"Successfully recalibrated FTS!";
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;
368 res.message =
"Offset is successfully set!";
381 if (apply_after_calculation) {
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);
389 *new_offset = temp_offset;
396 geometry_msgs::Wrench measurement;
397 int num_of_errors = 0;
399 for (
int i = 0; i < number_of_measurements; i++) {
400 geometry_msgs::Wrench output;
401 if (not frame_id.empty()) {
404 if (num_of_errors > 200) {
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;
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;
436 std_srvs::Trigger::Response& res)
442 ROS_INFO(
"Please push FTS with force larger than 10 N in desired direction of new axis %d",
445 for (
int i = 0; i <
CS_params_.n_measurements; i++)
448 double Fx, Fy, Fz, Tx, Ty, Tz = 0;
451 angle +=
atan2(Fy, Fx);
463 ROS_INFO(
"Please rotate your coordinate system for %f rad (%f deg) around z-axis", angle, angle / M_PI * 180.0);
466 res.message =
"CoordianteSystem successfull! :)";
471 res.message =
"FTS not initialised or not calibrated! :/";
478 force_torque_sensor::DiagnosticVoltages::Response& res)
518 if (
ft_data_lock_.try_lock_for(std::chrono::milliseconds(1))) {
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!");
551 if (
ft_data_lock_.try_lock_for(std::chrono::milliseconds(1))) {
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!");
609 ROS_INFO(
"Got FTS Transform for static application!");
bool configure(const std::string ¶m_name, ros::NodeHandle node_handle=ros::NodeHandle())
double interface_torque_[3]
bool srvCallback_CalculateOffsetWithoutGravity(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
force_torque_sensor::FTSConfigurationParameters FTS_params_
ForceTorqueSensorHandle()
force_torque_sensor::CalibrationParameters calibration_params_
tf2_ros::TransformListener * p_tfListener
virtual bool initCommunication(int type, std::string path, int baudrate, int base_identifier)
bool ongoing_offset_calculation
void prepareNode(std::string output_frame)
force_torque_sensor::CoordinateSystemCalibrationParameters CS_params_
TF2SIMD_FORCE_INLINE tf2Scalar angle(const Quaternion &q1, const Quaternion &q2)
geometry_msgs::TransformStamped output_transform_
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_
geometry_msgs::WrenchStamped filtered_data_input_
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
realtime_tools::RealtimePublisher< geometry_msgs::WrenchStamped > * moving_mean_pub_
filters::FilterBase< geometry_msgs::WrenchStamped > * threshold_filter_
geometry_msgs::WrenchStamped low_pass_filtered_data
bool srvCallback_CalculateAverageMasurement(force_torque_sensor::CalculateAverageMasurement::Request &req, force_torque_sensor::CalculateAverageMasurement::Response &res)
ros::ServiceServer srvServer_CalculateAverageMasurement_
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)
geometry_msgs::WrenchStamped prefiltered_data_
bool calculate_offset(bool apply_after_calculation, geometry_msgs::Wrench *new_offset)
void updateFTData(const ros::TimerEvent &event)
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
geometry_msgs::WrenchStamped sensor_data
tf2_ros::Buffer * p_tfBuffer
#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)
ros::ServiceServer srvServer_DetermineCoordianteSystem_
geometry_msgs::WrenchStamped moving_mean_filtered_data
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_
geometry_msgs::WrenchStamped transformed_data
ros::ServiceServer srvServer_SetSensorOffset
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)
std::string transform_frame_
bool useGravityCompensator
#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)
std::timed_mutex ft_data_lock_
geometry_msgs::WrenchStamped gravity_compensated_force
geometry_msgs::WrenchStamped threshold_filtered_force
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)
#define ROS_INFO_THROTTLE(rate,...)
boost::shared_ptr< pluginlib::ClassLoader< hardware_interface::ForceTorqueSensorHW > > sensor_loader_
ros::Timer ftUpdateTimer_
ros::ServiceServer srvServer_ReCalibrate
filters::FilterBase< geometry_msgs::WrenchStamped > * low_pass_filter_
virtual bool readDiagnosticADCVoltages(int index, short int &value)
bool hasParam(const std::string &key) const
geometry_msgs::Wrench offset_
#define ROS_ERROR_STREAM(args)
geometry_msgs::WrenchStamped output_data
force_torque_sensor::NodeConfigurationParameters node_params_
ros::ServiceServer srvServer_Temp_
ros::ServiceServer srvServer_CalculateOffset_
bool srvCallback_DetermineCoordinateSystem(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
void pullFTData(const ros::TimerEvent &event)
hardware_interface::ForceTorqueSensorHW * p_Ftc
ros::ServiceServer srvServer_Init_
double interface_force_[3]