point_cloud_converter.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: converter.cpp 33249 2010-03-11 02:09:24Z rusu $
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     // ROS
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       // Subscribe to the cloud topic using both the old message format and the new
00074       sub_points_ = nh_.subscribe (points_in_, queue_size_, &PointCloudConverter::cloud_cb_points, this);
00075       //sub_points2_ = nh_.subscribe (points2_in_, queue_size_, &PointCloudConverter::cloud_cb_points2, this);
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         //ROS_DEBUG ("[point_cloud_converter] Got a PointCloud2 with %d points on %s, but no subscribers.", msg->width * msg->height, nh_.resolveName (points2_in_).c_str ());
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       // Convert to the new PointCloud format
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         //ROS_DEBUG ("[point_cloud_converter] Got a PointCloud with %d points on %s, but no subscribers.", (int)msg->points.size (), nh_.resolveName (points_in_).c_str ());
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       // Convert to the old point cloud format
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   // ROS init
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


cob_gazebo
Author(s): Florian Weisshardt
autogenerated on Fri Mar 1 2013 18:02:27