ranges_to_cloud.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (C) 2014, Jack O'Quin
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 the author nor other contributors may be
00018 *     used to endorse or promote products derived from this software
00019 *     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 
00035 
00051 #include <string>
00052 #include <limits>
00053 #include <sensor_msgs/PointCloud2.h>
00054 #include <sensor_msgs/Range.h>
00055 #include <pcl_ros/point_cloud.h>
00056 #include "ranges_to_cloud.h"
00057 
00058 namespace segbot_sensors
00059 {
00061   RangesToCloud::RangesToCloud(ros::NodeHandle node,
00062                                ros::NodeHandle private_nh)
00063   {
00064     // advertise output point cloud (before subscribing to input data)
00065     points_ =
00066       node.advertise<sensor_msgs::PointCloud2>("range_points", 1);
00067 
00068     // subscribe to input ranges
00069     ranges_ =
00070       node.subscribe("sensor_ranges", 10,
00071                      &RangesToCloud::processRanges, (RangesToCloud *) this,
00072                      ros::TransportHints().tcpNoDelay(true));
00073   }
00074 
00075   void RangesToCloud::processRanges(const segbot_sensors::RangeArray::ConstPtr
00076                                     &ranges_msg)
00077   {
00078     unsigned int nsensors = ranges_msg->ranges.size(); // number of sensors
00079     ROS_DEBUG_STREAM("Received " << nsensors << " ranges");
00080     if (nsensors == 0)                  // empty message?
00081       return;
00082 
00083     // allocate a point cloud message
00084     pcl::PointCloud<pcl::PointXYZ>::Ptr
00085         cloud(new pcl::PointCloud<pcl::PointXYZ>());
00086     // cloud's header is a pcl::PCLHeader, convert it before stamp assignment
00087     cloud->header.stamp =
00088       pcl_conversions::toPCL(ranges_msg->ranges[0].header).stamp;
00089     cloud->header.frame_id = "sensor_base"; // TODO: make this a parameter
00090     cloud->height = 1;
00091 
00092     // Provide points for sensor ranges provided.
00093     for (int sensor = 0; sensor < nsensors; ++sensor)
00094       {
00095         // Skip readings with no object within range (see: REP-0117).
00096         const sensor_msgs::Range *r = &ranges_msg->ranges[sensor];
00097         if (r->range < std::numeric_limits<float>::infinity())
00098           {
00099             // Transform this range point into the "sensor_base" frame.
00100             tf::StampedTransform transform;
00101             try
00102               {
00103                 listener_.lookupTransform(cloud->header.frame_id,
00104                                           r->header.frame_id,
00105                                           ros::Time(0), transform);
00106               }
00107             catch (tf::TransformException ex)
00108               {
00109                 ROS_WARN_STREAM(ex.what());
00110                 continue;               // skip this sensor
00111               }
00112 
00113             tf::Point pt(r->range, 0.0, 0.0);
00114             pt = transform * pt;
00115 
00116             pcl::PointXYZ pcl_point;
00117             pcl_point.x = pt.m_floats[0];
00118             pcl_point.y = pt.m_floats[1];
00119             pcl_point.z = pt.m_floats[2];
00120             cloud->points.push_back(pcl_point);
00121             ++cloud->width;
00122           }
00123       }
00124 
00125     // publish the accumulated cloud message
00126     points_.publish(cloud);
00127   }
00128 
00129 
00130 }; // end namespace segbot_sensors


segbot_sensors
Author(s): Piyush Khandelwal
autogenerated on Mon Oct 6 2014 07:30:56