00001 #include <hrl_phri_2011/pc_utils.h>
00002 #include <tf/transform_listener.h>
00003 #include <geometry_msgs/WrenchStamped.h>
00004 #include <geometry_msgs/Wrench.h>
00005 #include <hrl_phri_2011/hsl_rgb_conversions.h>
00006
00007 typedef Eigen::Matrix<double, 6, 1> CartVec;
00008
00009 void wrenchMsgToEigen(const geometry_msgs::Wrench& wrench_msg, CartVec& wrench_eig)
00010 {
00011 wrench_eig(0, 0) = wrench_msg.force.x;
00012 wrench_eig(1, 0) = wrench_msg.force.y;
00013 wrench_eig(2, 0) = wrench_msg.force.z;
00014 wrench_eig(3, 0) = wrench_msg.torque.x;
00015 wrench_eig(4, 0) = wrench_msg.torque.y;
00016 wrench_eig(5, 0) = wrench_msg.torque.z;
00017 }
00018
00019 #define NORM(x, y, z) ( std::sqrt( (x) * (x) + (y) * (y) + (z) * (z) ) )
00020
00021 #define NORMAL(x, sig) ( std::exp( - (x) * (x) / (2.0 * (sig) * (sig))) / std::sqrt(2.0 * 3.14159 * (sig) * (sig)))
00022
00023 class ForceVisualizer
00024 {
00025 private:
00026 ros::Subscriber wrench_sub;
00027 ros::Publisher pc_pub;
00028 tf::TransformListener tf_list;
00029 ros::NodeHandle nh;
00030 PCRGB::Ptr pc_head;
00031 KDTree::Ptr kd_tree;
00032 int pub_ind;
00033 vector<double> force_densities;
00034 vector<double> force_high;
00035 double force_density_sum;
00036 double force_high_sum;
00037
00038 void wrenchCallback(geometry_msgs::WrenchStamped::ConstPtr wrench_stamped)
00039 {
00040 double sigma = 0.002, force_zero_thresh = 1.0, force_high_thresh = 3.0;
00041 CartVec w;
00042 wrenchMsgToEigen(wrench_stamped->wrench, w);
00043 double force_mag = NORM(w(0, 0), w(1, 0), w(2, 0));
00044 if(force_mag < force_zero_thresh)
00045 return;
00046 tf::StampedTransform tool_loc_tf;
00047 try {
00048 tf_list.lookupTransform("/head_center", "/wipe_finger", ros::Time(0), tool_loc_tf);
00049 }
00050 catch (tf::TransformException ex) {
00051 ROS_ERROR("%s", ex.what());
00052 return;
00053 }
00054 btVector3 tool_loc = tool_loc_tf.getOrigin();
00055 PRGB query_pt;
00056 query_pt.x = tool_loc.x(); query_pt.y = tool_loc.y(); query_pt.z = tool_loc.z();
00057 vector<int> nk_inds(1), rs_inds;
00058 vector<float> nk_dists(1), rs_dists;
00059 kd_tree->nearestKSearch(query_pt, 1, nk_inds, nk_dists);
00060 int closest_ind = nk_inds[0];
00061 kd_tree->radiusSearch(closest_ind, sigma * 3, rs_inds, rs_dists);
00062 for(uint32_t i=0;i<rs_inds.size();i++) {
00063 double prob_dens = NORMAL(rs_dists[i], sigma);
00064 force_densities[rs_inds[i]] += prob_dens;
00065 force_density_sum += prob_dens;
00066 if(force_mag > force_high_thresh) {
00067 force_high[rs_inds[i]] += prob_dens;
00068 force_high_sum += prob_dens;
00069 }
00070
00071 }
00072 if(++pub_ind % 10 == 0)
00073 colorHead(wrench_stamped->header.stamp);
00074 }
00075
00076 void colorHead(const ros::Time& stamp)
00077 {
00078 PCRGB::Ptr cur_head(new PCRGB(*pc_head));
00079 for(uint32_t i=0;i<pc_head->points.size();i++) {
00080
00081 uint8_t r = ((uint8_t*) &cur_head->points[i].rgb)[2];
00082 uint8_t g = ((uint8_t*) &cur_head->points[i].rgb)[1];
00083 uint8_t b = ((uint8_t*) &cur_head->points[i].rgb)[0];
00084 double h, s, l;
00085 RGBToHSL(r, g, b, h, s, l);
00086 h = 0.0; s = 0.0;
00087
00089 if(force_densities[i] > 0.001) {
00090
00091 double post_prob = force_high[i] / force_densities[i];
00092
00093
00094 s = post_prob * 100.0;
00095 }
00097
00098 HSLToRGB(h, s, l, r, g, b);
00099 ((uint8_t*) &cur_head->points[i].rgb)[2] = r;
00100 ((uint8_t*) &cur_head->points[i].rgb)[1] = g;
00101 ((uint8_t*) &cur_head->points[i].rgb)[0] = b;
00102 }
00103 cur_head->header.stamp = stamp;
00104 pc_pub.publish(*cur_head);
00105 }
00106
00107 public:
00108 void startVisualization()
00109 {
00110 wrench_sub = nh.subscribe("/tool_netft_zeroer/wrench_zeroed", 1, &ForceVisualizer::wrenchCallback, this);
00111 pc_pub = nh.advertise<PCRGB >("/colored_pc", 1);
00112 }
00113
00114 ForceVisualizer(PCRGB::Ptr& pch) :
00115 pc_head(pch),
00116 kd_tree(new pcl::KdTreeFLANN<PRGB> ()),
00117 pub_ind(0),
00118 force_densities(pch->points.size()),
00119 force_high(pch->points.size()),
00120 force_density_sum(0.0),
00121 force_high_sum(0.0) {
00122 kd_tree->setInputCloud(pc_head);
00123 pc_head->header.frame_id = "/head_center";
00124 ros::Duration(1.0).sleep();
00125 }
00126 };
00127
00128 int main(int argc, char **argv)
00129 {
00130 ros::init(argc, argv, "force_labeler");
00131
00132 rosbag::Bag pc_bag, force_bag;
00133 PCRGB::Ptr pc_head(new PCRGB);
00134
00135 pc_bag.open(std::string(argv[1]), rosbag::bagmode::Read);
00136
00137 rosbag::View pc_view(pc_bag, rosbag::TopicQuery("/pub_pc"));
00138 BOOST_FOREACH(rosbag::MessageInstance const m, pc_view) {
00139 sensor_msgs::PointCloud2::Ptr pc2 = m.instantiate<sensor_msgs::PointCloud2>();
00140 pcl::fromROSMsg(*pc2, *pc_head);
00141 }
00142
00143 ForceVisualizer fv(pc_head);
00144 fv.startVisualization();
00145 ros::spin();
00146 }