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
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
00108 cloud_out.point_step += cloud2->point_step;
00109
00110 data_size += cloud2->data.size ();
00111
00112
00113 cloud_out.fields.resize (nr_fields + cloud2->fields.size ());
00114 int delta_offset = cloud->point_step;
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
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 cloud_out.row_step = cloud_out.point_step * cloud_out.width;
00139 cloud_out.data.resize (data_size);
00140
00141
00142 int point_offset = delta_offset;
00143 int point_offset2 = 0;
00144 for (int cp = 0; cp < nr_points; ++cp)
00145 {
00146
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 }