Go to the documentation of this file.00001 #include <numeric>
00002 #include <math.h>
00003 #include <boost/lambda/lambda.hpp>
00004
00005 #include <ros/ros.h>
00006 #include <std_msgs/Bool.h>
00007 #include <std_msgs/Float32.h>
00008 #include "geometry_msgs/Vector3Stamped.h"
00009 #include <pr2_collision_monitor/fir_diff_filter.h>
00010
00011 #define bl boost::lambda
00012
00013 using namespace std;
00014 using namespace boost;
00015
00016 namespace pr2_collision_monitor {
00017
00018 class ForceTorqueMonitor {
00019 public:
00020 ros::NodeHandle nh;
00021 std::string arm;
00022 ros::Subscriber force_sub;
00023 ros::Publisher coll_state_pub, signal_pub;
00024
00025 shared_ptr<FIRDiffFilter> force_x_filter, force_y_filter, force_z_filter;
00026 double threshold, time_constant;
00027 int history;
00028
00029 ForceTorqueMonitor();
00030 void onInit();
00031 void forceCallback(const geometry_msgs::Vector3Stamped& msg);
00032 };
00033
00034 ForceTorqueMonitor::ForceTorqueMonitor() : nh("~") {
00035 }
00036
00037 void ForceTorqueMonitor::onInit() {
00038 nh.param<std::string>("arm", arm, std::string("r"));
00039 nh.param<double>("force_threshold", threshold, 4.0);
00040 nh.param<double>("time_constant", time_constant, 0.01);
00041 nh.param<int>("history", history, 30);
00042
00043 force_x_filter = shared_ptr<FIRDiffFilter>(new FIRDiffFilter(history, time_constant));
00044 force_y_filter = shared_ptr<FIRDiffFilter>(new FIRDiffFilter(history, time_constant));
00045 force_z_filter = shared_ptr<FIRDiffFilter>(new FIRDiffFilter(history, time_constant));
00046
00047 coll_state_pub = nh.advertise<std_msgs::Bool>("collision_detected", 2);
00048 force_sub = nh.subscribe("/force_topic", 1,
00049 &ForceTorqueMonitor::forceCallback, this);
00050 signal_pub = nh.advertise<std_msgs::Float32>("force_signal", 2);
00051 }
00052
00053 void ForceTorqueMonitor::forceCallback(const geometry_msgs::Vector3Stamped& msg) {
00054 double signal_x = force_x_filter->updateState(msg.vector.x);
00055 double signal_y = force_y_filter->updateState(msg.vector.y);
00056 double signal_z = force_z_filter->updateState(msg.vector.z);
00057 double sig_mag = sqrt(signal_x * signal_x +
00058 signal_y * signal_y +
00059 signal_z * signal_z);
00060
00061 bool in_collision = sig_mag > threshold;
00062 std_msgs::Bool state_msg;
00063 state_msg.data = in_collision;
00064 coll_state_pub.publish(state_msg);
00065 std_msgs::Float32 signal_msg;
00066 signal_msg.data = sig_mag;
00067 signal_pub.publish(signal_msg);
00068 }
00069
00070 };
00071
00072 using namespace pr2_collision_monitor;
00073
00074 int main(int argc, char **argv)
00075 {
00076 ros::init(argc, argv, "force_torque_monitor", ros::init_options::AnonymousName);
00077 ForceTorqueMonitor fm;
00078 fm.onInit();
00079 ros::spin();
00080 return 0;
00081 }
00082
00083