00001
00002
00003
00004
00005
00006
00007
00015 #include <pluginlib/class_list_macros.h>
00016 #include <nodelet/nodelet.h>
00017 #include <ros/ros.h>
00018 #include <sensor_msgs/PointCloud.h>
00019
00020 #include <velodyne/data_xyz.h>
00021 using namespace Velodyne;
00022
00023 class PointCloudNodelet: public nodelet::Nodelet
00024 {
00025 public:
00026 PointCloudNodelet()
00027 {
00028 data_ = new DataXYZ();
00029 }
00030 ~PointCloudNodelet()
00031 {
00032 delete data_;
00033 }
00034
00035 private:
00036 virtual void onInit();
00037 void processXYZ(const std::vector<laserscan_xyz_t> &scan,
00038 ros::Time stamp,
00039 const std::string &frame_id);
00040 void allocSharedMsg();
00041
00042 DataXYZ *data_;
00043 ros::Subscriber velodyne_scan_;
00044 ros::Publisher output_;
00045
00046
00047 sensor_msgs::PointCloudPtr pc_;
00048 unsigned pc_next_;
00049 };
00050
00051 void PointCloudNodelet::onInit()
00052 {
00053 ros::NodeHandle node = getNodeHandle();
00054
00055
00056 allocSharedMsg();
00057
00058 data_->getParams();
00059
00060 if (0 != data_->setup())
00061 return;
00062
00063
00064 velodyne_scan_ =
00065 data_->subscribe(node, "velodyne/packets", 10,
00066 boost::bind(&PointCloudNodelet::processXYZ,
00067 this, _1, _2, _3),
00068 ros::TransportHints().tcpNoDelay(true));
00069
00070 output_ = node.advertise<sensor_msgs::PointCloud>("velodyne/pointcloud", 1);
00071 }
00072
00079 void PointCloudNodelet::allocSharedMsg()
00080 {
00081
00082 pc_ = sensor_msgs::PointCloudPtr(new sensor_msgs::PointCloud);
00083
00084
00085 pc_->points.resize(SCANS_PER_REV);
00086 pc_->channels.resize(1);
00087 pc_->channels[0].name = "intensity";
00088 pc_->channels[0].values.resize(SCANS_PER_REV);
00089
00090
00091 pc_->points.resize(SCANS_PER_REV);
00092 pc_->channels[0].values.resize(SCANS_PER_REV);
00093 pc_next_= 0;
00094 }
00095
00100 void PointCloudNodelet::processXYZ(const std::vector<laserscan_xyz_t> &scan,
00101 ros::Time stamp,
00102 const std::string &frame_id)
00103 {
00104
00105
00106
00107
00108 ROS_ASSERT(pc_next_ + scan.size() <= pc_->points.size());
00109
00110 for (unsigned i = 0; i < scan.size(); ++i)
00111 {
00112 pc_->points[pc_next_].x = scan[i].x;
00113 pc_->points[pc_next_].y = scan[i].y;
00114 pc_->points[pc_next_].z = scan[i].z;
00115 pc_->channels[0].values[pc_next_] = (float) scan[i].intensity;
00116 ++pc_next_;
00117 }
00118
00119 if (pc_next_ == pc_->points.size())
00120 {
00121
00122 NODELET_DEBUG_STREAM("Publishing " << pc_->points.size()
00123 << " Velodyne points.");
00124
00125
00126 pc_->header.stamp = stamp;
00127 pc_->header.frame_id = frame_id;
00128
00129 output_.publish(pc_);
00130
00131
00132
00133 allocSharedMsg();
00134 }
00135 }
00136
00137
00138
00139
00140 PLUGINLIB_DECLARE_CLASS(velodyne_common, PointCloudNodelet,
00141 PointCloudNodelet, nodelet::Nodelet);