scan_to_point_cloud.cpp
Go to the documentation of this file.
00001 
00002 //#define USE_MT_NODE_HANDLE
00003 
00004 #include <laser_geometry/laser_geometry.h>
00005 #include <nifti_pcl_common/point_types.h>
00006 #include <nodelet/nodelet.h>
00007 #include <sensor_msgs/LaserScan.h>
00008 #include <pcl/common/io.h>
00009 #include <pcl/common/impl/io.hpp>
00010 #include <pcl/point_cloud.h>
00011 #include <pcl/point_types.h>
00012 #include <pcl_ros/point_cloud.h>
00013 #include <pluginlib/class_list_macros.h>
00014 #include <ros/ros.h>
00015 #include <tf/transform_listener.h>
00016 
00017 namespace point_cloud_color {
00018 
00019 typedef nifti_pcl_common::LaserPoint PointOut;
00020 
00021 class ScanToPointCloud: public nodelet::Nodelet {
00022 public:
00023   ScanToPointCloud();
00024   virtual ~ScanToPointCloud();
00025   void onInit();
00026   void scanCallback(const sensor_msgs::LaserScan::ConstPtr &scanMsg);
00027   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00028 private:
00029   std::string targetFrame;
00030   double waitForTransform;
00031   int scanQueue;
00032   int pointCloudQueue;
00033   tf::TransformListener transformListener;
00034   ros::Subscriber scanSubscriber;
00035   laser_geometry::LaserProjection projector;
00036   ros::Publisher pointCloudPublisher;
00037 };
00038 
00039 ScanToPointCloud::ScanToPointCloud() : targetFrame(""), waitForTransform(0.5), scanQueue(10), pointCloudQueue(10), transformListener() {
00040 }
00041 
00042 ScanToPointCloud::~ScanToPointCloud() {
00043 }
00044 
00045 void ScanToPointCloud::onInit() {
00046   NODELET_INFO("ScanToPointCloud::onInit: Initializing...");
00047 
00048 #ifdef USE_MT_NODE_HANDLE
00049   ros::NodeHandle &nh = getMTNodeHandle();
00050   ros::NodeHandle &pnh = getMTPrivateNodeHandle();
00051 #else
00052   ros::NodeHandle &nh = getNodeHandle();
00053   ros::NodeHandle &pnh = getPrivateNodeHandle();
00054 #endif
00055 
00056   // Process parameters.
00057   pnh.param("target_frame", targetFrame, targetFrame);
00058   NODELET_INFO("ScanToPointCloud::onInit: Using target frame %s.", targetFrame.data());
00059   pnh.param("wait_for_transform", waitForTransform, waitForTransform);
00060   NODELET_INFO("ScanToPointCloud::onInit: Maximum time to wait for transform %.2f s.", waitForTransform);
00061   pnh.param("scan_queue", scanQueue, scanQueue);
00062   NODELET_INFO("ScanToPointCloud::onInit: Scan queue size %i.", scanQueue);
00063   pnh.param("point_cloud_queue", pointCloudQueue, pointCloudQueue);
00064   NODELET_INFO("ScanToPointCloud::onInit: Point cloud queue size %i.", pointCloudQueue);
00065 
00066   // Subscribe scan topic.
00067   std::string scanTopic = nh.resolveName("scan", true);
00068   NODELET_INFO("ScanToPointCloud::onInit: Subscribing scan %s.", scanTopic.data());
00069   scanSubscriber = nh.subscribe<sensor_msgs::LaserScan>(scanTopic, scanQueue, &ScanToPointCloud::scanCallback, this);
00070 
00071   // Advertise scan point cloud.
00072   std::string pclTopic = nh.resolveName("scan_point_cloud", true);
00073   NODELET_INFO("ScanToPointCloud::onInit: Advertising point cloud %s.", pclTopic.data());
00074   pointCloudPublisher = nh.advertise<pcl::PointCloud<nifti_pcl_common::LaserPoint> >(pclTopic, pointCloudQueue, false);
00075 }
00076 
00077 void ScanToPointCloud::scanCallback(const sensor_msgs::LaserScan::ConstPtr &scanPtr) {
00078   ros::Time t1 = ros::Time::now();
00079   NODELET_DEBUG("ScanToPointCloud::scanCallback: Point cloud received (%lu points).", scanPtr->ranges.size());
00080   std::string frame = targetFrame.size() > 0 ? targetFrame : scanPtr->header.frame_id;
00081   if (!transformListener.waitForTransform(frame, scanPtr->header.frame_id, scanPtr->header.stamp + ros::Duration(scanPtr->scan_time), ros::Duration(waitForTransform))) {
00082     NODELET_WARN("ScanToPointCloud::scanCallback: Cannot transform from %s to %s at %.2f s.", scanPtr->header.frame_id.data(), frame.data(), scanPtr->header.stamp.toSec());
00083     return;
00084   }
00085   sensor_msgs::PointCloud2 pclMsg;
00086   try {
00087 //    projector.transformLaserScanToPointCloud(scanPtr->header.frame_id, *scanPtr, pclMsg, transformListener);
00088     int channelOptions = laser_geometry::channel_option::Intensity
00089         | laser_geometry::channel_option::Index
00090         | laser_geometry::channel_option::Timestamp
00091         | laser_geometry::channel_option::Viewpoint;
00092     projector.transformLaserScanToPointCloud(frame, *scanPtr, pclMsg, transformListener, -1.0, channelOptions);
00093     pcl::PointCloud<nifti_pcl_common::LaserProjectionPoint> pclProj;
00094     pcl::fromROSMsg(pclMsg, pclProj);
00095     // Convert relative time offsets to timestamps.
00096     pcl::PointCloud<nifti_pcl_common::LaserPoint> pclOut;
00097     pcl::copyPointCloud(pclProj, pclOut);
00098     for (size_t i = 0; i < pclProj.points.size(); ++i) {
00099       ros::Time pointStamp = pclProj.header.stamp + ros::Duration(pclProj.points[i].stamps);
00100       pclOut.points[i].sec = pointStamp.sec;
00101       pclOut.points[i].nsec = pointStamp.nsec;
00102     }
00103     pointCloudPublisher.publish(pclOut);
00104     NODELET_DEBUG("ScanToPointCloud::scanCallback: Converting scan to point cloud: %.3f s.", (ros::Time::now() - t1).toSec());
00105 
00106   } catch(tf::TransformException& ex) {
00107     ROS_ERROR("ScanToPointCloud::scanCallback: Transform exception: %s.", ex.what());
00108     return;
00109   }
00110 }
00111 
00112 } /* namespace point_cloud_color */
00113 
00114 PLUGINLIB_DECLARE_CLASS(point_cloud_color, scan_to_point_cloud, point_cloud_color::ScanToPointCloud, nodelet::Nodelet)
 All Classes Namespaces Files Functions Variables Typedefs


point_cloud_color
Author(s): Tomas Petricek / petrito1@cmp.felk.cvut.cz
autogenerated on Tue Dec 10 2013 14:28:16