Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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
00038 output_ =
00039 node.advertise<sensor_msgs::PointCloud2>("velodyne_points", 10);
00040
00041
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)
00059 return;
00060
00061
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
00068 for (size_t next = 0; next < scanMsg->packets.size(); ++next)
00069 {
00070
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
00080 data_->unpack(scanMsg->packets[next], inPc_);
00081
00082
00083 tfPc_.points.clear();
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
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
00107 ROS_WARN_THROTTLE(100, "%s", ex.what());
00108 continue;
00109 }
00110
00111
00112 outMsg->points.insert(outMsg->points.end(),
00113 tfPc_.points.begin(),
00114 tfPc_.points.end());
00115 outMsg->width += tfPc_.points.size();
00116 }
00117
00118
00119 ROS_DEBUG_STREAM("Publishing " << outMsg->height * outMsg->width
00120 << " Velodyne points, time: " << outMsg->header.stamp);
00121 output_.publish(outMsg);
00122 }
00123
00124 }