transform.cc
Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2009, 2010 Austin Robot Technology, Jack O'Quin
00003  *  Copyright (C) 2011 Jesse Vera
00004  *  Copyright (C) 2012 Austin Robot Technology, Jack O'Quin
00005  *  License: Modified BSD Software License Agreement
00006  *
00007  *  $Id$
00008  */
00009 
00020 #include "transform.h"
00021 
00022 #include <pcl_conversions/pcl_conversions.h>
00023 
00024 namespace velodyne_pointcloud
00025 {
00027   Transform::Transform(ros::NodeHandle node, ros::NodeHandle private_nh):
00028     data_(new velodyne_rawdata::RawData())
00029   {
00030     private_nh.param("frame_id", config_.frame_id, std::string("odom"));
00031     std::string tf_prefix = tf::getPrefixParam(private_nh);
00032     config_.frame_id = tf::resolve(tf_prefix, config_.frame_id);
00033     ROS_INFO_STREAM("target frame ID: " << config_.frame_id);
00034 
00035     data_->setup(private_nh);
00036 
00037     // advertise output point cloud (before subscribing to input data)
00038     output_ =
00039       node.advertise<sensor_msgs::PointCloud2>("velodyne_points", 10);
00040 
00041     // subscribe to VelodyneScan packets using transform filter
00042     velodyne_scan_.subscribe(node, "velodyne_packets", 10);
00043     tf_filter_ =
00044       new tf::MessageFilter<velodyne_msgs::VelodyneScan>(velodyne_scan_,
00045                                                          listener_,
00046                                                          config_.frame_id, 10);
00047     tf_filter_->registerCallback(boost::bind(&Transform::processScan, this, _1));
00048   }
00049 
00055   void
00056     Transform::processScan(const velodyne_msgs::VelodyneScan::ConstPtr &scanMsg)
00057   {
00058     if (output_.getNumSubscribers() == 0)         // no one listening?
00059       return;                                     // avoid much work
00060 
00061     // allocate an output point cloud with same time as raw data
00062     VPointCloud::Ptr outMsg(new VPointCloud());
00063     outMsg->header.stamp = pcl_conversions::toPCL(scanMsg->header).stamp;
00064     outMsg->header.frame_id = config_.frame_id;
00065     outMsg->height = 1;
00066 
00067     // process each packet provided by the driver
00068     for (size_t next = 0; next < scanMsg->packets.size(); ++next)
00069       {
00070         // clear input point cloud to handle this packet
00071         inPc_.points.clear();
00072         inPc_.width = 0;
00073         inPc_.height = 1;
00074         std_msgs::Header header;
00075         header.stamp = scanMsg->packets[next].stamp;
00076         header.frame_id = scanMsg->header.frame_id;
00077         pcl_conversions::toPCL(header, inPc_.header);
00078 
00079         // unpack the raw data
00080         data_->unpack(scanMsg->packets[next], inPc_);
00081 
00082         // clear transform point cloud for this packet
00083         tfPc_.points.clear();           // is this needed?
00084         tfPc_.width = 0;
00085         tfPc_.height = 1;
00086         header.stamp = scanMsg->packets[next].stamp;
00087         pcl_conversions::toPCL(header, tfPc_.header);
00088         tfPc_.header.frame_id = config_.frame_id;
00089 
00090         // transform the packet point cloud into the target frame
00091         try
00092           {
00093             ROS_DEBUG_STREAM("transforming from" << inPc_.header.frame_id
00094                              << " to " << config_.frame_id);
00095             pcl_ros::transformPointCloud(config_.frame_id, inPc_, tfPc_,
00096                                          listener_);
00097 #if 0       // use the latest transform available, should usually work fine
00098             pcl_ros::transformPointCloud(inPc_.header.frame_id,
00099                                          ros::Time(0), inPc_,
00100                                          config_.frame_id,
00101                                          tfPc_, listener_);
00102 #endif
00103           }
00104         catch (tf::TransformException &ex)
00105           {
00106             // only log tf error once every 100 times
00107             ROS_WARN_THROTTLE(100, "%s", ex.what());
00108             continue;                   // skip this packet
00109           }
00110 
00111         // append transformed packet data to end of output message
00112         outMsg->points.insert(outMsg->points.end(),
00113                              tfPc_.points.begin(),
00114                              tfPc_.points.end());
00115         outMsg->width += tfPc_.points.size();
00116       }
00117 
00118     // publish the accumulated cloud message
00119     ROS_DEBUG_STREAM("Publishing " << outMsg->height * outMsg->width
00120                      << " Velodyne points, time: " << outMsg->header.stamp);
00121     output_.publish(outMsg);
00122   }
00123 
00124 } // namespace velodyne_pointcloud


velodyne_pointcloud
Author(s): Jack O'Quin, Piyush Khandelwal, Jesse Vera
autogenerated on Thu Aug 27 2015 15:37:05