00001
00002
00003
00004
00005
00006
00007
00008
00016 #include <ros/ros.h>
00017 #include <sensor_msgs/PointCloud.h>
00018
00019 #include <velodyne/data.h>
00020
00021 #define NODE "velodyne_cloud"
00022
00023 using namespace velodyne_common;
00024
00025
00026 static int qDepth = 1;
00027
00028
00029 static velodyne::DataXYZ *data = NULL;
00030 static ros::Publisher output;
00031
00032 sensor_msgs::PointCloud pc;
00033
00034
00039 void processXYZ(const std::vector<velodyne::laserscan_xyz_t> &scan)
00040 {
00041
00042 data->getMsgHeaderFields(pc.header.stamp, pc.header.frame_id);
00043
00044
00045
00046 size_t npoints = scan.size();
00047 pc.points.resize(npoints);
00048 pc.channels[0].values.resize(npoints);
00049
00050 for (unsigned i = 0; i < npoints; ++i)
00051 {
00052 pc.points[i].x = scan[i].x;
00053 pc.points[i].y = scan[i].y;
00054 pc.points[i].z = scan[i].z;
00055 pc.channels[0].values[i] = (float) scan[i].intensity;
00056 }
00057
00058 ROS_DEBUG_STREAM("Publishing " << npoints << " Velodyne points.");
00059 output.publish(pc);
00060 }
00061
00062 void displayHelp()
00063 {
00064 std::cerr << "format raw Velodyne data and republish as a PointCloud\n"
00065 << std::endl
00066 << "Usage: rosrun velodyne_file cloud <options>\n"
00067 << std::endl
00068 << "Options:\n"
00069 << "\t -h, -? print usage message\n"
00070 << "\t -q <integer> set ROS topic queue depth (default: 1)\n"
00071 << std::endl
00072 << "Example:\n"
00073 << " rosrun velodyne_file cloud -q2\n"
00074 << std::endl;
00075 }
00076
00077
00082 int getParameters(int argc, char *argv[])
00083 {
00084
00085 char ch;
00086 const char* optflags = "hq:?";
00087 while(-1 != (ch = getopt(argc, argv, optflags)))
00088 {
00089 switch(ch)
00090 {
00091 case 'q':
00092 qDepth = atoi(optarg);
00093 if (qDepth < 1)
00094 qDepth = 1;
00095 break;
00096 default:
00097 ROS_WARN("unknown parameter: %c", ch);
00098
00099 case 'h':
00100 case '?':
00101 displayHelp();
00102 return 1;
00103 }
00104 }
00105
00106 ROS_INFO("topic queue depth = %d", qDepth);
00107
00108 data = new velodyne::DataXYZ();
00109 data->getParams();
00110
00111 return 0;
00112 }
00113
00114 int main(int argc, char *argv[])
00115 {
00116 ros::init(argc, argv, NODE);
00117 ros::NodeHandle node;
00118
00119 if (0 != getParameters(argc, argv))
00120 return 9;
00121
00122 if (0 != data->setup())
00123 return 2;
00124
00125
00126
00127
00128 ros::Subscriber velodyne_scan =
00129 data->subscribe(node, "velodyne/rawscan", qDepth,
00130 boost::bind(&processXYZ, _1),
00131 ros::TransportHints().tcpNoDelay(true));
00132
00133 output = node.advertise<sensor_msgs::PointCloud>("velodyne/pointcloud",
00134 qDepth);
00135
00136
00137 pc.points.resize(velodyne::SCANS_PER_REV);
00138 pc.channels.resize(1);
00139 pc.channels[0].name = "intensity";
00140 pc.channels[0].values.resize(velodyne::SCANS_PER_REV);
00141
00142 ROS_DEBUG(NODE ": starting main loop");
00143
00144 ros::spin();
00145
00146 ROS_DEBUG(NODE ": exiting main loop");
00147
00148 data->shutdown();
00149 delete data;
00150
00151 return 0;
00152 }