capture.cpp
Go to the documentation of this file.
00001 
00064 #include <math.h>
00065 #include <stdio.h>
00066 #include <stdlib.h>
00067 
00068 #include <ros/ros.h>
00069 #include <pcl/point_types.h>
00070 #include <geometry_msgs/Twist.h>
00071 #include <sensor_msgs/Image.h>
00072 #include <tf/transform_listener.h>
00073 #include <Eigen/Core>
00074 #include <Eigen/Geometry>
00075 #include <nav_msgs/Odometry.h>
00076 #include <trajectory_msgs/JointTrajectory.h>
00077 #include <pcl_ros/point_cloud.h>
00078 #include <pcl/io/pcd_io.h>
00079 #include <gazebo/GetModelState.h>
00080 #include <iostream>
00081 
00082 class Capture
00083 {
00084 private:
00085   double walk_vel, yaw_rate, nick_rate;
00086   geometry_msgs::Twist cmd;
00087   trajectory_msgs::JointTrajectory cmd_nick_;
00088 
00089   ros::NodeHandle n_;
00090   ros::Publisher vel_pub_, nick_pub_;
00091   ros::Subscriber odo_sub_, point_cloud_sub_, image_sub_, image_depth_sub_;
00092   tf::TransformListener listener;
00093 
00094   bool moving_, freeze_, first_;
00095   int not_moving_;
00096   int phase1_len_, phase2_len_, phase3_len_;
00097 
00098   Eigen::Vector3f absolute_pos_, start_pos_;
00099   Eigen::Quaternionf absolute_rot_, start_rot_;
00100 
00101   sensor_msgs::PointCloud2ConstPtr last_pc_;
00102   sensor_msgs::ImageConstPtr last_img_, last_depth_img_;
00103 
00104   std::string prefix_;
00105   int frame_number_;
00106   FILE *fp_xml_;
00107   int mode_; //1 for gazebo, 2 for manual
00108 
00109   bool states_[4];
00110 
00111 public:
00112   void init()
00113   {
00114     moving_ = true; //be superspecious
00115     freeze_ = false;
00116     first_  = true;
00117 
00118     frame_number_=0;
00119 
00120     cmd.linear.x = cmd.linear.y = cmd.angular.z = 0;
00121     cmd_nick_.joint_names.push_back("torso_lower_neck_tilt_joint");
00122     cmd_nick_.joint_names.push_back("torso_pan_joint");
00123     cmd_nick_.joint_names.push_back("torso_upper_neck_tilt_joint");
00124 
00125     trajectory_msgs::JointTrajectoryPoint point;
00126     point.positions.push_back(0.);
00127     point.positions.push_back(0.);
00128     point.positions.push_back(0.);
00129     point.time_from_start = ros::Duration(0.01);
00130 
00131     cmd_nick_.points.push_back(point);
00132 
00133     vel_pub_ = n_.advertise<geometry_msgs::Twist>("/base_controller/command", 1);
00134     nick_pub_= n_.advertise<trajectory_msgs::JointTrajectory>("/torso_controller/command", 1);
00135     odo_sub_ = n_.subscribe("/base_controller/odometry",10,&Capture::odometrySubCallback, this);
00136     point_cloud_sub_ = n_.subscribe("/cam3d/rgb/points", 1, &Capture::pointCloudSubCallback, this);
00137     image_sub_ = n_.subscribe("/cam3d/rgb/image_raw", 1, &Capture::imageSubCallback, this);
00138     image_depth_sub_ = n_.subscribe("/cam3d/depth/image_raw", 1, &Capture::imageSubCallback_depth, this);
00139 
00140     ros::NodeHandle n_private("~");
00141 
00142     n_private.param("mode", mode_, 1);
00143 
00144     n_private.param("walk_vel", walk_vel, 0.01);
00145     n_private.param("yaw_rate", yaw_rate, 0.01);
00146     n_private.param("nick_rate", nick_rate, 0.01);
00147     n_private.param("prefix", prefix_, std::string(""));
00148     n_private.param("phase1_len", phase1_len_, 3);
00149     n_private.param("phase2_len", phase2_len_, 10);
00150     n_private.param("phase3_len", phase3_len_, 3);
00151 
00152     n_private.param("state_trans_x", states_[0], false);
00153     n_private.param("state_trans_y", states_[1], false);
00154     n_private.param("state_rot_z", states_[2], false);
00155     n_private.param("state_rot_x", states_[3], false);
00156 
00157   }
00158 
00159   ~Capture()   { }
00160 
00161   void reset_world() {system("rosservice call /gazebo/reset_world");}
00162 
00163   void run();
00164 
00165   void record_start() {
00166     char fn[256];
00167     sprintf(fn, "%sreplay.xml",prefix_.c_str());
00168 
00169     ROS_INFO("creating %s...",fn);
00170     fp_xml_ = fopen(fn,"w");
00171 
00172     ROS_ASSERT(fp_xml_);
00173 
00174     fputs("<?xml version=\"1.0\" ?>\n", fp_xml_);
00175     fputs("<replay>\n", fp_xml_);
00176   }
00177 
00178   void record_end() {
00179     fputs("</replay>\n", fp_xml_);
00180     fclose(fp_xml_);
00181   }
00182 
00183   void record_entry() {
00184     if(!last_pc_ || !last_img_)
00185       return;
00186 
00187     freeze_=true;
00188 
00189     if(first_) {
00190       first_=false;
00191       start_pos_= absolute_pos_;
00192       start_rot_= absolute_rot_;
00193     }
00194 
00195     char fn_pcd[256], fn_img[256], fn_img_depth[256];
00196     sprintf(fn_pcd, "%spcd_%d.pcd",prefix_.c_str(),frame_number_);
00197     sprintf(fn_img, "%simg_%d.img",prefix_.c_str(),frame_number_);
00198     sprintf(fn_img_depth, "%simg_depth_%d.img",prefix_.c_str(),frame_number_);
00199 
00200     frame_number_++;
00201 
00202     pcl::PointCloud<pcl::PointXYZRGB> pc;
00203     pcl::fromROSMsg(*last_pc_,pc);
00204     pcl::io::savePCDFileASCII (fn_pcd, pc);
00205 
00206     #ifdef PCL_VERSION_COMPARE
00207       std::ofstream stream(fn_img);
00208           stream << *last_img_;
00209           stream.close();
00210         #else
00211       //serialize image
00212       FILE *fp = fopen(fn_img,"wb");
00213       if(fp)
00214       {
00215         uint32_t len = last_img_->serializationLength();
00216 
00217         uint8_t *wptr = new uint8_t[len];
00218         last_img_->serialize(wptr,0);
00219         fwrite(wptr, 1, len, fp);
00220         delete [] wptr;
00221 
00222         fclose(fp);
00223       }
00224         #endif
00225 
00226     /*fp = fopen(fn_img_depth,"wb");
00227     if(fp)
00228     {
00229       uint32_t len = last_depth_img_->serializationLength();
00230 
00231       uint8_t *wptr = new uint8_t[len];
00232       last_depth_img_->serialize(wptr,0);
00233       fwrite(wptr, 1, len, fp);
00234       delete [] wptr;
00235 
00236       fclose(fp);
00237     }*/
00238 
00239     Eigen::Vector3f pos= absolute_pos_ - start_pos_;
00240     Eigen::Quaternionf rot = absolute_rot_*start_rot_.inverse();
00241 
00242     /*std::cout<<"saving pos:\n"<<pos<<"\n";
00243     std::cout<<"saving rot:\n"<<rot.toRotationMatrix()<<"\n";
00244     Eigen::Vector3f v;
00245     v(0)=0;
00246     v(1)=0;
00247     v(2)=1;
00248     std::cout<<"rotating:\n"<<rot.toRotationMatrix()*v<<"\n";*/
00249 
00250     fputs("\t<frame>\n", fp_xml_);
00251 
00252     fputs("\t\t<pose>\n", fp_xml_);
00253 
00254     fputs("\t\t\t<position>", fp_xml_);
00255     fprintf(fp_xml_,"%f,%f,%f",pos(0),pos(1),pos(2));
00256     fputs("</position>\n", fp_xml_);
00257 
00258     fputs("\t\t\t<orientation>", fp_xml_);
00259     fprintf(fp_xml_,"%f,%f,%f,%f",rot.x(), rot.y(), rot.z(), rot.w());
00260     fputs("</orientation>\n", fp_xml_);
00261 
00262     fputs("\t\t</pose>\n", fp_xml_);
00263 
00264     fputs("\t\t<pcd>", fp_xml_);
00265     fputs(fn_pcd, fp_xml_);
00266     fputs("</pcd>\n", fp_xml_);
00267 
00268     fputs("\t\t<img>", fp_xml_);
00269     fputs(fn_img, fp_xml_);
00270     fputs("</img>\n", fp_xml_);
00271 
00272     /*fputs("\t\t<img_depth>", fp_xml_);
00273     fputs(fn_img_depth, fp_xml_);
00274     fputs("</img_depth>\n", fp_xml_);*/
00275 
00276     fputs("\t</frame>\n", fp_xml_);
00277 
00278     last_pc_.reset();
00279     last_img_.reset();
00280 
00281     freeze_=false;
00282   }
00283 
00284   void
00285   pointCloudSubCallback(const sensor_msgs::PointCloud2ConstPtr& pc_in)
00286   {
00287     if(freeze_)
00288       return;
00289 
00290     last_pc_ = pc_in;
00291   }
00292 
00293   void
00294   imageSubCallback(const sensor_msgs::ImageConstPtr& img_in)
00295   {
00296     if(freeze_)
00297       return;
00298 
00299     last_img_ = img_in;
00300   }
00301 
00302   void
00303   imageSubCallback_depth(const sensor_msgs::ImageConstPtr& img_in)
00304   {
00305     if(freeze_)
00306       return;
00307 
00308     last_depth_img_ = img_in;
00309   }
00310 
00311   void
00312   odometrySubCallback(const nav_msgs::Odometry &odometry)
00313   {
00314     if(freeze_ || mode_==2)
00315       return;
00316 
00317     tf::StampedTransform transform;
00318     try{
00319       listener.lookupTransform("/base_footprint", "/head_cam3d_link",
00320                                ros::Time(0), transform);
00321     }
00322     catch (tf::TransformException ex){
00323       ROS_ERROR("%s",ex.what());
00324       moving_ = true;
00325       return;
00326     }
00327 
00328     ros::ServiceClient client = n_.serviceClient<gazebo::GetModelState>("/gazebo/get_model_state");
00329     gazebo::GetModelState srv;
00330 
00331     srv.request.model_name = "robot";
00332 
00333     if(!client.call(srv)) {
00334       ROS_ERROR("service call for gazebo model state failed");
00335       moving_ = true;
00336       return;
00337     }
00338 
00339     Eigen::Vector3f pos_base, pos_rel;
00340     Eigen::Quaternionf rot_base, rot_rel;
00341 
00342     /*pos_base(0) = odometry.pose.pose.position.x;
00343     pos_base(1) = odometry.pose.pose.position.y;
00344     pos_base(2) = odometry.pose.pose.position.z;*/
00345     pos_base(0) = srv.response.pose.position.x;
00346     pos_base(1) = srv.response.pose.position.y;
00347     pos_base(2) = srv.response.pose.position.z;
00348 
00349     pos_rel(0) = transform.getOrigin().m_floats[0];
00350     pos_rel(1) = transform.getOrigin().m_floats[1];
00351     pos_rel(2) = transform.getOrigin().m_floats[2];
00352 
00353     /*rot_base.x() = odometry.pose.pose.orientation.x;
00354     rot_base.y() = odometry.pose.pose.orientation.y;
00355     rot_base.z() = odometry.pose.pose.orientation.z;
00356     rot_base.w() = odometry.pose.pose.orientation.w;*/
00357     rot_base.x() = srv.response.pose.orientation.x;
00358     rot_base.y() = srv.response.pose.orientation.y;
00359     rot_base.z() = srv.response.pose.orientation.z;
00360     rot_base.w() = srv.response.pose.orientation.w;
00361 
00362     rot_rel.x() = transform.getRotation().getX();
00363     rot_rel.y() = transform.getRotation().getY();
00364     rot_rel.z() = transform.getRotation().getZ();
00365     rot_rel.w() = transform.getRotation().getW();
00366 
00367     //rematch
00368     {
00369       Eigen::Vector3f Y;
00370       Y(0)=Y(2)=0;Y(1)=1;
00371       Eigen::Vector3f X;
00372       X(1)=X(2)=0;X(0)=1;
00373       Eigen::AngleAxisf r1(-M_PI/2,Y), r2(-M_PI/2,X);
00374 
00375       Eigen::Matrix3f R=r1.toRotationMatrix()*r2.toRotationMatrix();
00376 
00377       /*Eigen::Vector3f Z;
00378       Z(1)=Z(0)=0;Z(2)=1;
00379 
00380       std::cout<<"X\n"<<(R*X)<<"\n";
00381       std::cout<<"Y\n"<<(R*Y)<<"\n";
00382       std::cout<<"Z\n"<<(R*Z)<<"\n";*/
00383 
00384       rot_base = R*rot_base;
00385       pos_base = R*pos_base;
00386     }
00387 
00388     //std::cout<<"rel: \n"<<pos_rel<<"\n";
00389     //std::cout<<"base: \n"<<pos_base<<"\n";
00390 
00391     Eigen::Vector3f pos= pos_base+pos_rel;
00392     Eigen::Quaternionf rot = rot_base*rot_rel;
00393 
00394     //ROS_INFO("rotated %f°",180/M_PI*rot.angularDistance(Eigen::Quaternionf(Eigen::AngleAxisf(0,Eigen::Vector3f(0,1,0)))));
00395 
00396     moving_ =
00397         (pos-absolute_pos_).norm()>0.00001 ||
00398         rot.angularDistance(absolute_rot_)>0.00001;
00399 
00400     absolute_pos_= pos;
00401     absolute_rot_= rot;
00402 
00403     if(!moving_) {
00404       not_moving_++;
00405     }
00406     else
00407       not_moving_=0;
00408 
00409   }
00410 
00411   void buildState() {
00412     if(mode_==2) {
00413       ROS_INFO("please move camera to desired position");
00414       ROS_INFO("now enter:");
00415 
00416       float x=0,y=0,a=0;
00417 
00418       std::cout<<"translation x (in cm): ";
00419       std::cin>>x;
00420       std::cout<<"translation y (in cm): ";
00421       std::cin>>y;
00422       std::cout<<"rotation (degree): ";
00423       std::cin>>a;
00424 
00425       x/=100.f;
00426       y/=100.f;
00427       a*=M_PI/180.f;
00428 
00429       absolute_pos_(0)=x;
00430       absolute_pos_(1)=0;
00431       absolute_pos_(2)=y;
00432 
00433       Eigen::Vector3f Y;
00434       Y(0)=Y(2)=0.f;Y(1)=1.f;
00435       Eigen::AngleAxisf aa(a,Y);
00436       absolute_rot_=Eigen::Quaternionf(aa);
00437     }
00438     else
00439     {
00440       cmd.linear.x = cmd.linear.y = cmd.angular.z = 0;
00441 
00442       if(frame_number_ >= phase1_len_&& frame_number_<phase1_len_+phase2_len_) {
00443         if(states_[0]) state2_x();
00444         if(states_[1]) state2_y();
00445         if(states_[2]) state3();
00446         if(states_[3]) state4();
00447       }
00448     }
00449 
00450   }
00451 
00452   void state2_x() {
00453     static bool forw=true;
00454     if(absolute_pos_(0)<-2.5)
00455       forw=false;
00456     if(absolute_pos_(0)>-0.5)
00457       forw=true;
00458 
00459     if(forw)
00460       cmd.linear.x = - walk_vel;
00461     else
00462       cmd.linear.x = walk_vel;
00463   }
00464 
00465   void state2_y() {
00466     static bool forw=true;
00467     if(absolute_pos_(1)<-1)
00468       forw=false;
00469     if(absolute_pos_(1)>1)
00470       forw=true;
00471 
00472     if(forw)
00473       cmd.linear.y = - walk_vel;
00474     else
00475       cmd.linear.y = walk_vel;
00476   }
00477 
00478   void state3() {
00479     static bool forw=true;
00480 
00481     static float yaw = 0.;
00482 
00483     if(yaw<-0.4)
00484       forw=false;
00485     if(yaw>0.4)
00486       forw=true;
00487 
00488     if(forw)
00489       yaw += -nick_rate;
00490     else
00491       yaw +=  nick_rate;
00492 
00493     cmd_nick_.points[0].positions[1] = yaw;
00494   }
00495 
00496   void state4() {
00497     static bool forw=true;
00498 
00499     static float yaw = 0.;
00500 
00501     if(yaw<-0.4)
00502       forw=false;
00503     if(yaw>0.4)
00504       forw=true;
00505 
00506     if(forw)
00507       yaw += -nick_rate;
00508     else
00509       yaw +=  nick_rate;
00510 
00511     cmd_nick_.points[0].positions[0] = yaw;
00512     cmd_nick_.points[0].positions[2] = 1.5*yaw;
00513   }
00514 };
00515 
00516 
00517 int main(int argc, char** argv)
00518 {
00519   ros::init(argc, argv, "capture");
00520 
00521   Capture tpk;
00522   tpk.init();
00523 
00524   tpk.reset_world();
00525   boost::thread workerThread(&Capture::run, &tpk);
00526 
00527   ros::spin();
00528 
00529   return(0);
00530 }
00531 
00532 void Capture::run()
00533 {
00534   record_start();
00535 
00536   for(;ros::ok();)
00537   {
00538 
00539     ROS_INFO("move");
00540 
00541     buildState();
00542 
00543     vel_pub_.publish(cmd);
00544     nick_pub_.publish(cmd_nick_);
00545 
00546     usleep(1000*200);
00547     while(moving_&&not_moving_<20) usleep(10000);
00548 
00549     //getchar(); //testing...
00550 
00551     Eigen::Matrix3f t =absolute_rot_.toRotationMatrix();
00552 
00553     /*std::cout<<"origin: \n"<<absolute_pos_<<"\n";
00554     std::cout<<"rot: "
00555         <<rx<<" "
00556         <<ry<<" "
00557         <<rz<<" "
00558         <<"\n";*/
00559 
00560     record_entry();
00561 
00562     if(frame_number_ >= phase1_len_+phase2_len_+phase3_len_)
00563       break;
00564   }
00565   ROS_INFO("finished");
00566   record_end();
00567   ros::shutdown();
00568 }


cob_3d_registration
Author(s): Joshua Hampp
autogenerated on Wed Aug 26 2015 11:02:35