00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00043 
00044 #include <ros/ros.h>
00045 
00046 #include <sensor_msgs/PointCloud.h>
00047 
00048 #include  <tools/file_io.h>
00049 
00050 #include <point_cloud_mapping/cloud_io.h>
00051 
00052 #include  <tools/transform.h>
00053 #include <geometry_msgs/Point32.h>
00054 #include <angles/angles.h>
00055 
00056 #include <string>
00057 using namespace std;
00058 using namespace ros;
00059 using namespace sensor_msgs;
00060 using namespace geometry_msgs;
00061 using namespace cloud_io;
00062 using namespace player_log_actarray;
00063 
00064 
00065 #define ANGLE_SHIFT 180.0
00066 
00067 class PointcloudMerger
00068 {
00069 protected:
00070   NodeHandle nh_;
00071   
00072 public:
00073   
00074   PointCloud cloud_in_, cloud_out_, cloud_interim_;
00075   string dir_;
00076   vector<string> file_list_;
00077   Point32 axis_, trans_;
00078   
00079   double x_, y_, z_;
00080   
00081   double tx_, ty_, tz_;
00082   
00084   
00086   PointcloudMerger()
00087   {
00088     nh_.param ("~dir", dir_, string(""));     
00089     if(dir_ == "")
00090       ROS_ERROR("You must specify path to .pcd files");
00091     
00092     file_io::get_log_files(dir_, file_list_, ".pcd");
00093   
00094     nh_.param ("~axis_x", x_, 0.0);     
00095     nh_.param ("~axis_y", y_, 0.0);     
00096     nh_.param ("~axis_z", z_, 0.0);     
00097     axis_.x = float(x_), axis_.y = float(y_), axis_.z = float(z_); 
00098 
00099     nh_.param ("~tx", tx_, 0.0);     
00100     nh_.param ("~ty", ty_, 0.0);     
00101     nh_.param ("~tz", tz_, 0.0);     
00102     trans_.x = float(tx_), trans_.y = float(ty_), trans_.z = float(tz_); 
00103   }
00104   
00105 
00107   
00109   int get_angle (string file_name)
00110   {
00111     string angle;
00112     int angle_int;
00113     int found = file_name.find("_");
00114     if (found!=-1)
00115       {
00116         for (int i = found+1; i < found+5; i++)
00117           {
00118             angle += file_name[i];
00119             angle_int = atoi(angle.c_str()); 
00120           }
00121       }
00122     else
00123       ROS_ERROR("Delimiter _ not found!");
00124     return angle_int;
00125   }
00126     
00128   
00130   virtual ~PointcloudMerger () { }
00131 
00132   bool
00133   spin ()
00134   {
00135     int angle = 0;
00136     ROS_INFO("Rot. axis: [%f %f %f]", axis_.x, axis_.y, axis_.z);
00137     while (nh_.ok ())
00138       {  
00139         for (unsigned int i = 0; i < file_list_.size(); i++)
00140           {
00141             ROS_INFO("Loading file %s", file_list_[i].c_str());
00142             loadPCDFile(file_list_[i].c_str(), cloud_in_);
00143             angle = get_angle(file_list_[i]) + ANGLE_SHIFT;
00144             ROS_INFO("Rotating for %d deg.", angle);
00145             transform::translatePointCloud (cloud_in_, cloud_interim_, trans_);
00146             if(transform::rotatePointCloud (cloud_interim_, cloud_out_, angles::from_degrees(-angle), axis_))
00147               {
00148                 if(cloud_out_.points.size() != 0)    
00149                   {
00150                     int str_len = file_list_[i].length();
00151                     string pcd_del = file_list_[i].erase((str_len - 4), 4);
00152                     pcd_del += ".rotated.pcd";
00153                     ROS_INFO("Saving file %s with nr. of points %d", pcd_del.c_str(), cloud_out_.points.size());
00154                     savePCDFile (pcd_del.c_str(), cloud_out_, false);
00155                     pcd_del.clear();
00156                   }
00157               }
00158             else
00159               continue;
00160           }
00161         ros::spinOnce ();
00162         break;
00163       }
00164     return (true);
00165   }
00166   
00167 };
00168 
00169 
00170 int
00171 main (int argc, char** argv)
00172 {
00173   init (argc, argv, "pointcloud_merger");
00174 
00175   PointcloudMerger p;
00176   p.spin ();
00177 
00178   return (0);
00179 }
00180