data_extractor.cpp
Go to the documentation of this file.
00001 #include <rosbag/bag.h>
00002 #include <rosbag/view.h>
00003 #include <rosbag/message_instance.h>
00004 
00005 #include <tf/transform_listener.h>
00006 #include <geometry_msgs/WrenchStamped.h>
00007 #include <geometry_msgs/Wrench.h>
00008 #include <hrl_phri_2011/hsl_rgb_conversions.h>
00009 #include <hrl_phri_2011/ForceProcessed.h>
00010 #include <hrl_phri_2011/pcl_features.h>
00011 #include <hrl_phri_2011/utils.h>
00012 #include <hrl_phri_2011/ellipsoid_space.h>
00013 
00014 typedef Eigen::Matrix<double, 6, 1> CartVec;
00015 
00016 void wrenchMsgToEigen(const geometry_msgs::Wrench& wrench_msg, CartVec& wrench_eig) 
00017 {
00018     wrench_eig(0, 0) = wrench_msg.force.x;
00019     wrench_eig(1, 0) = wrench_msg.force.y;
00020     wrench_eig(2, 0) = wrench_msg.force.z;
00021     wrench_eig(3, 0) = wrench_msg.torque.x;
00022     wrench_eig(4, 0) = wrench_msg.torque.y;
00023     wrench_eig(5, 0) = wrench_msg.torque.z;
00024 }
00025 
00026 #define NORM(x, y, z) ( std::sqrt( (x) * (x) + (y) * (y) + (z) * (z) ) )
00027 #ifndef SQ
00028 #define SQ(x) ( (x) * (x) )
00029 #endif
00030 #define NORMAL(x, sig) ( std::exp( - (x) * (x) / (2.0 * (sig) * (sig))) / std::sqrt(2.0 * 3.14159 * (sig) * (sig)))
00031 
00032 class DataExtractor 
00033 {
00034 private:
00035     ros::Subscriber wrench_sub;
00036     tf::TransformListener tf_list;
00037     ros::NodeHandle nh;
00038     PCRGB::Ptr pc_head;
00039     KDTree::Ptr kd_tree;
00040     PCNormals::Ptr normals;
00041     int pub_ind;
00042     double start_time;
00043     vector<hrl_phri_2011::ForceProcessed> fp_list;
00044     bool compute_norms;
00045     tf::Transform registration_tf, ell_reg_tf;
00046     Ellipsoid ell;
00047 
00048     void wrenchCallback(geometry_msgs::WrenchStamped::ConstPtr wrench_stamped) 
00049     {
00050         double cur_time = wrench_stamped->header.stamp.toSec();
00051         if(start_time == -1)
00052             start_time = cur_time;
00053         CartVec w;
00054         wrenchMsgToEigen(wrench_stamped->wrench, w);
00055         double force_mag = NORM(w(0, 0), w(1, 0), w(2, 0));
00056         tf::StampedTransform tool_loc_tf;
00057         try {
00058             tf_list.waitForTransform("/head_center", "/wipe_finger", wrench_stamped->header.stamp, ros::Duration(0.1));
00059             tf_list.lookupTransform("/head_center", "/wipe_finger", wrench_stamped->header.stamp, tool_loc_tf);
00060         }
00061         catch (tf::TransformException ex) {
00062             ROS_ERROR("%s", ex.what());
00063             return;
00064         }
00065         tool_loc_tf.mult(registration_tf, tool_loc_tf);
00066         btVector3 tool_loc = tool_loc_tf.getOrigin();
00067         PRGB query_pt;
00068         query_pt.x = tool_loc.x(); query_pt.y = tool_loc.y(); query_pt.z = tool_loc.z(); 
00069         vector<int> nk_inds(1);
00070         vector<float> nk_dists(1);
00071         kd_tree->nearestKSearch(query_pt, 1, nk_inds, nk_dists);
00072         int closest_ind = nk_inds[0];
00073         float closest_dist = nk_dists[0];
00074 
00075         hrl_phri_2011::ForceProcessed fp;
00076         fp.time_offset = cur_time - start_time;
00077         tf::transformStampedTFToMsg(tool_loc_tf, fp.tool_frame);
00078         fp.header = wrench_stamped->header;
00079         fp.header.frame_id = "/head_center";
00080         fp.wrench = wrench_stamped->wrench;
00081         fp.pc_ind = closest_ind;
00082         fp.pc_dist = closest_dist;
00083         fp.pc_pt.x = pc_head->points[closest_ind].x;
00084         fp.pc_pt.y = pc_head->points[closest_ind].y;
00085         fp.pc_pt.z = pc_head->points[closest_ind].z;
00086         fp.force_magnitude = force_mag;
00087         if(compute_norms) {
00088             fp.pc_normal.x = normals->points[closest_ind].normal[0];
00089             fp.pc_normal.y = normals->points[closest_ind].normal[1];
00090             fp.pc_normal.z = normals->points[closest_ind].normal[2];
00091         }
00092 
00093         // do ellipsoidal processing
00094         tf::Transform tool_loc_ell = ell_reg_tf * tool_loc_tf;
00095         tf::transformTFToMsg(tool_loc_ell, fp.tool_ell_frame);
00096         btVector3 tloce_pos = tool_loc_ell.getOrigin();
00097         ell.cartToEllipsoidal(tloce_pos.x(), tloce_pos.y(), tloce_pos.z(), 
00098                               fp.ell_coords.x, fp.ell_coords.y, fp.ell_coords.z);
00099 
00100         fp_list.push_back(fp);
00101         pub_ind++;
00102         if(pub_ind % 100 == 0)
00103             ROS_INFO("Recorded %d samples", pub_ind);
00104     }
00105 
00106 public:
00107     void startVisualization(bool use_raw = false) 
00108     {
00109         string topic;
00110         if(!use_raw)
00111             topic = "/tool_netft_zeroer/wrench_zeroed";
00112         else
00113             topic = "/tool_netft/wrench_raw";
00114         wrench_sub = nh.subscribe(topic, 100, &DataExtractor::wrenchCallback, this);
00115     }
00116 
00117     DataExtractor(PCRGB::Ptr& pch, bool compute_normals, const geometry_msgs::Transform& registration,
00118                   const hrl_phri_2011::EllipsoidParams& ep) : 
00119         pc_head(pch),
00120         kd_tree(new pcl::KdTreeFLANN<PRGB> ()),
00121         normals(new PCNormals()),
00122         pub_ind(0),
00123         start_time(-1),
00124         compute_norms(compute_normals),
00125         ell(ep)
00126     {
00127         kd_tree->setInputCloud(pc_head);
00128         if(compute_norms)
00129             computeNormals(pc_head, kd_tree, normals);
00130         pc_head->header.frame_id = "/head_center";
00131         tf::transformMsgToTF(registration, registration_tf);
00132         if(ep.e_frame.transform.rotation.w != 0) {
00133             tf::transformMsgToTF(ep.e_frame.transform, ell_reg_tf);
00134             ell_reg_tf = ell_reg_tf.inverse();
00135         }
00136     }
00137 
00138     void writeBag(const string& pbag_name) 
00139     {
00140         rosbag::Bag processed_bag;
00141         processed_bag.open(pbag_name, rosbag::bagmode::Write);
00142         BOOST_FOREACH(const hrl_phri_2011::ForceProcessed& fp, fp_list) {
00143             processed_bag.write("/force_processed", fp.header.stamp, fp);
00144         }
00145         processed_bag.close();
00146     }
00147 };
00148 
00149 int main(int argc, char **argv)
00150 {
00151     ros::init(argc, argv, "data_extractor");
00152 
00153     if(argc < 3 || argc > 7) {
00154         printf("Usage: data_extractor head_pc forces_bag_output [compute_normals=1] [registration_bag] [use_raw=0] [ellipse_registration]\n");
00155         return 1;
00156     }
00157 
00158     rosbag::Bag pc_bag, force_bag;
00159     PCRGB::Ptr pc_head(new PCRGB);
00160     // Load PC bag
00161     pc_bag.open(std::string(argv[1]), rosbag::bagmode::Read);
00162     rosbag::View pc_view(pc_bag, rosbag::TopicQuery("/stitched_head"));
00163     BOOST_FOREACH(rosbag::MessageInstance const m, pc_view) {
00164         sensor_msgs::PointCloud2::Ptr pc2 = m.instantiate<sensor_msgs::PointCloud2>();
00165         pcl::fromROSMsg(*pc2, *pc_head);
00166     }
00167 
00168     bool compute_normals = true;
00169     if(argc >= 4)
00170         compute_normals = atoi(argv[3]);
00171     bool use_raw = false;
00172     if(argc >= 6)
00173         use_raw = atoi(argv[5]);
00174     geometry_msgs::Transform tf_msg;
00175     tf_msg.rotation.w = 1.0;
00176     if(argc >= 5) {
00177         vector<geometry_msgs::TransformStamped::Ptr> tf_msgs;
00178         readBagTopic<geometry_msgs::TransformStamped>(argv[4], tf_msgs, "/itf_transform");
00179         tf_msg = tf_msgs[0]->transform;
00180     }
00181     vector<hrl_phri_2011::EllipsoidParams::Ptr> e_params_msgs;
00182     e_params_msgs.push_back(boost::shared_ptr<hrl_phri_2011::EllipsoidParams>(new hrl_phri_2011::EllipsoidParams()));
00183     e_params_msgs[0]->e_frame.transform.rotation.w = 1.0;
00184     if(argc >= 7) {
00185         e_params_msgs.clear();
00186         readBagTopic<hrl_phri_2011::EllipsoidParams>(argv[6], e_params_msgs, "/ellipsoid_params");
00187     }
00188     
00189 
00190     DataExtractor de(pc_head, compute_normals, tf_msg, *e_params_msgs[0]);
00191     de.startVisualization(use_raw);
00192     ROS_INFO("Ready for collection");
00193     ros::spin();
00194     de.writeBag(argv[2]);
00195     ROS_INFO("Bag written to %s", argv[2]);
00196 }


hrl_phri_2011
Author(s): Kelsey Hawkins
autogenerated on Wed Nov 27 2013 12:22:39