concat_fields.cpp
Go to the documentation of this file.
00001 
00060 #include <ros/ros.h>
00061 #include <sensor_msgs/PointCloud2.h>
00062 #include "pcl_ros/point_cloud.h"
00063 #include <pcl/point_types.h>
00064 #include <pcl/io/io.h>
00065 #include <pcl/io/pcd_io.h>
00066 
00067 #include <message_filters/subscriber.h>
00068 #include <message_filters/sync_policies/approximate_time.h>
00069 #include <message_filters/synchronizer.h>
00070 
00071 
00072 class ConcatFields
00073 {
00074 public:
00075         typedef sensor_msgs::PointCloud2 PointCloud2;
00076         typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
00077 
00078         ConcatFields()
00079         {
00080                 sub_input_filter_.subscribe(nh_, "input", 3);
00081                 sub_cloud2_filter_.subscribe(nh_, "input2", 3);
00082 
00083                 sync_input_ = boost::make_shared <message_filters::Synchronizer<message_filters::sync_policies::ApproximateTime<PointCloud2, PointCloud2> > >(3);
00084                 sync_input_->connectInput(sub_input_filter_, sub_cloud2_filter_);
00085                 sync_input_->registerCallback (boost::bind (&ConcatFields::input_callback, this, _1, _2));
00086 
00087                 pub_output_ = nh_.advertise<sensor_msgs::PointCloud2> ("output", 3);
00088         }
00089 
00090         void input_callback(const PointCloud2::ConstPtr &cloud, const PointCloud2::ConstPtr &cloud2)
00091         {
00092                 ROS_INFO("[ConcatNormals] SyncCallback");
00093                 ROS_INFO("width: %d, %d", cloud->width,cloud2->width);
00094                 ROS_INFO("stamp: %f, %f", cloud->header.stamp.toSec(),cloud2->header.stamp.toSec());
00095                 PointCloud2 cloud_out;
00096                 if(cloud->height*cloud->width != cloud2->height*cloud2->width)
00097                 {
00098                         ROS_ERROR("[input_callback] Error: Point cloud and cloud2 cloud do not have the same size.");
00099                         return;
00100                 }
00101                 cloud_out = *cloud;
00102                 // Resize the output dataset
00103                 int data_size = cloud_out.data.size ();
00104                 int nr_fields = cloud_out.fields.size ();
00105                 int nr_points = cloud_out.width * cloud_out.height;
00106 
00107                 // Point step must increase with the length of each new field
00108                 cloud_out.point_step += cloud2->point_step;
00109                 // Resize data to hold all clouds
00110                 data_size += cloud2->data.size ();
00111 
00112                 // Concatenate fields
00113                 cloud_out.fields.resize (nr_fields + cloud2->fields.size ());
00114                 int delta_offset = cloud->point_step;//cloud_out.fields[nr_fields - 1].offset + pcl::getFieldSize (cloud_out.fields[nr_fields - 1].datatype);
00115                 for (size_t d = 0; d < cloud2->fields.size (); ++d)
00116                 {
00117                   cloud_out.fields[nr_fields + d] = cloud2->fields[d];
00118                   cloud_out.fields[nr_fields + d].offset += delta_offset;
00119                 }
00120                 /*for (size_t d = 0; d < cloud->fields.size (); d++)
00121                 {
00122                         ROS_INFO("Field name: %s, offset: %d", cloud->fields[d].name.c_str(),cloud->fields[d].offset);
00123                 }
00124                 ROS_INFO("Point step: %d\n", cloud->point_step);
00125                 for (size_t d = 0; d < cloud2->fields.size (); d++)
00126                 {
00127                         ROS_INFO("Field name: %s, offset: %d", cloud2->fields[d].name.c_str(),cloud2->fields[d].offset);
00128                 }
00129                 ROS_INFO("Point step: %d\n", cloud2->point_step);
00130                 for (size_t d = 0; d < cloud_out.fields.size (); d++)
00131                 {
00132                         ROS_INFO("Field name: %s, offset: %d", cloud_out.fields[d].name.c_str(),cloud_out.fields[d].offset);
00133                 }
00134                 ROS_INFO("Point step: %d", cloud_out.point_step);*/
00135                 //nr_fields += cloud2->fields.size ();
00136 
00137           // Recalculate row_step
00138           cloud_out.row_step = cloud_out.point_step * cloud_out.width;
00139           cloud_out.data.resize (data_size);
00140 
00141           // Iterate over each point and perform the appropriate memcpys
00142           int point_offset = delta_offset;//0;
00143           int point_offset2 = 0;
00144           for (int cp = 0; cp < nr_points; ++cp)
00145           {
00146                   // Copy each individual point
00147                   memcpy (&cloud_out.data[point_offset], &cloud2->data[cp * cloud2->point_step], cloud2->point_step);
00148                   point_offset += cloud_out.point_step;
00149                   memcpy (&cloud_out.data[point_offset2], &cloud->data[cp * cloud->point_step], cloud->point_step);
00150                   point_offset2 += cloud_out.point_step;
00151           }
00152           pub_output_.publish (boost::make_shared<const PointCloud2> (cloud_out));
00153 
00154         }
00155 
00156         ros::NodeHandle nh_;
00157         message_filters::Subscriber<PointCloud2> sub_input_filter_;
00158         message_filters::Subscriber<PointCloud2> sub_cloud2_filter_;
00159         ros::Publisher pub_output_;
00160         boost::shared_ptr <message_filters::Synchronizer<message_filters::sync_policies::ApproximateTime<PointCloud2, PointCloud2> > > sync_input_;
00161 
00162 };
00163 
00164 int main(int argc, char** argv)
00165 {
00166         ros::init(argc, argv, "concat_cloud2_node");
00167         ConcatFields cf;
00168 
00169         ros::spin();
00170 
00171         return 0;
00172 }


cob_3d_mapping_tools
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:04:26