Go to the documentation of this file.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
00031
00032
00033
00034
00035
00036
00037
00046 #include <ros/ros.h>
00047 #include <boost/thread.hpp>
00048 #include <sensor_msgs/PointCloud.h>
00049 #include <sensor_msgs/PointCloud2.h>
00050 #include <sensor_msgs/point_cloud_conversion.h>
00051
00052 using namespace std;
00053
00054 class PointCloudConverter
00055 {
00056 private:
00057 boost::mutex m_mutex_;
00058
00059 ros::NodeHandle nh_;
00060 ros::Subscriber sub_points_, sub_points2_;
00061 ros::Publisher pub_points_, pub_points2_;
00062
00063 int queue_size_;
00064 string points_in_, points2_in_, points_out_, points2_out_;
00065 int num_subs;
00066
00067 public:
00069 PointCloudConverter () : nh_ ("~"), queue_size_ (100),
00070 points_in_ ("/points_in"), points2_in_ ("/points2_in"),
00071 points_out_ ("/points_out"), points2_out_ ("/points2_out"), num_subs(0)
00072 {
00073
00074 sub_points_ = nh_.subscribe (points_in_, queue_size_, &PointCloudConverter::cloud_cb_points, this);
00075
00076 pub_points_ = nh_.advertise<sensor_msgs::PointCloud> (points_out_, queue_size_, boost::bind(&PointCloudConverter::connectCb, this), boost::bind(&PointCloudConverter::disconnectCb, this));
00077 pub_points2_ = nh_.advertise<sensor_msgs::PointCloud2> (points2_out_, queue_size_);
00078 ROS_INFO ("PointCloudConverter initialized to transform from PointCloud (%s) to PointCloud2 (%s).", nh_.resolveName (points_in_).c_str (), nh_.resolveName (points2_out_).c_str ());
00079 ROS_INFO ("PointCloudConverter initialized to transform from PointCloud2 (%s) to PointCloud (%s).", nh_.resolveName (points2_in_).c_str (), nh_.resolveName (points_out_).c_str ());
00080 }
00081
00083
00086 inline std::string
00087 getFieldsList (const sensor_msgs::PointCloud2 &cloud)
00088 {
00089 std::string result;
00090 for (size_t i = 0; i < cloud.fields.size () - 1; ++i)
00091 result += cloud.fields[i].name + " ";
00092 result += cloud.fields[cloud.fields.size () - 1].name;
00093 return (result);
00094 }
00095
00097
00100 inline std::string
00101 getFieldsList (const sensor_msgs::PointCloud &points)
00102 {
00103 std::string result = "x y z";
00104 for (size_t i = 0; i < points.channels.size (); i++)
00105 result = result + " " + points.channels[i].name;
00106 return (result);
00107 }
00108
00109 void connectCb()
00110 {
00111 num_subs++;
00112 if(num_subs > 0)
00113 {
00114 sub_points2_ = nh_.subscribe (points2_in_, queue_size_, &PointCloudConverter::cloud_cb_points2, this);
00115 }
00116 }
00117
00118 void disconnectCb()
00119 {
00120 num_subs--;
00121 if(num_subs <= 0)
00122 {
00123 sub_points2_.shutdown();
00124 }
00125 }
00126
00127
00129
00130 void
00131 cloud_cb_points2 (const sensor_msgs::PointCloud2ConstPtr &msg)
00132 {
00133 if (pub_points_.getNumSubscribers () <= 0)
00134 {
00135
00136 return;
00137 }
00138
00139 ROS_DEBUG ("[point_cloud_converter] Got a PointCloud2 with %d points (%s) on %s.", msg->width * msg->height, getFieldsList (*msg).c_str (), nh_.resolveName (points2_in_).c_str ());
00140
00141 sensor_msgs::PointCloud output;
00142
00143 if (!sensor_msgs::convertPointCloud2ToPointCloud (*msg, output))
00144 {
00145 ROS_ERROR ("[point_cloud_converter] Conversion from sensor_msgs::PointCloud2 to sensor_msgs::PointCloud failed!");
00146 return;
00147 }
00148 ROS_DEBUG ("[point_cloud_converter] Publishing a PointCloud with %d points on %s.", (int)output.points.size (), nh_.resolveName (points_out_).c_str ());
00149 pub_points_.publish (output);
00150 }
00151
00153
00154 void
00155 cloud_cb_points (const sensor_msgs::PointCloudConstPtr &msg)
00156 {
00157 if (pub_points2_.getNumSubscribers () <= 0)
00158 {
00159
00160 return;
00161 }
00162
00163 ROS_DEBUG ("[point_cloud_converter] Got a PointCloud with %d points (%s) on %s.", (int)msg->points.size (), getFieldsList (*msg).c_str (), nh_.resolveName (points_in_).c_str ());
00164
00165 sensor_msgs::PointCloud2 output;
00166
00167 if (!sensor_msgs::convertPointCloudToPointCloud2 (*msg, output))
00168 {
00169 ROS_ERROR ("[point_cloud_converter] Conversion from sensor_msgs::PointCloud to sensor_msgs::PointCloud2 failed!");
00170 return;
00171 }
00172 ROS_DEBUG ("[point_cloud_converter] Publishing a PointCloud2 with %d points on %s.", output.height * output.width, nh_.resolveName (points2_out_).c_str ());
00173 pub_points2_.publish (output);
00174 }
00175
00176 };
00177
00178
00179 int
00180 main (int argc, char** argv)
00181 {
00182
00183 ros::init (argc, argv, "point_cloud_converter", ros::init_options::AnonymousName);
00184
00185 PointCloudConverter p;
00186 ros::spin ();
00187
00188 return (0);
00189 }
00190