00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include <string>
00016 #include <boost/thread.hpp>
00017
00018 #include <pluginlib/class_list_macros.h>
00019 #include <nodelet/nodelet.h>
00020 #include <ros/ros.h>
00021 #include <tf/transform_listener.h>
00022
00023 #include <velodyne/input.h>
00024 #include <velodyne_msgs/VelodyneScan.h>
00025
00026 class DriverNodelet: public nodelet::Nodelet
00027 {
00028 public:
00029 DriverNodelet()
00030 {
00031 input_ = NULL;
00032 running_ = false;
00033 }
00034
00035 ~DriverNodelet()
00036 {
00037 if (running_)
00038 {
00039 NODELET_INFO("shutting down driver thread");
00040 running_ = false;
00041 deviceThread_->join();
00042 NODELET_INFO("driver thread stopped");
00043 }
00044 if (input_)
00045 {
00046 input_->vclose();
00047 delete input_;
00048 }
00049 }
00050
00051 private:
00052 virtual void onInit();
00053 virtual void devicePoll();
00054
00055
00056 int npackets_;
00057
00058 bool running_;
00059 std::string frame_id_;
00060 velodyne::Input *input_;
00061 ros::Publisher output_;
00062 boost::shared_ptr<boost::thread> deviceThread_;
00063 };
00064
00065 void DriverNodelet::onInit()
00066 {
00067
00068 ros::NodeHandle private_nh = getPrivateNodeHandle();
00069
00070 private_nh.param("frame_id", frame_id_, std::string("velodyne"));
00071 std::string tf_prefix = tf::getPrefixParam(private_nh);
00072 ROS_DEBUG_STREAM("tf_prefix: " << tf_prefix);
00073 frame_id_ = tf::resolve(tf_prefix, frame_id_);
00074
00075 private_nh.param("npackets", npackets_, (int)
00076 velodyne_msgs::VelodyneScan::PACKETS_PER_REVOLUTION);
00077
00078 std::string dump_file;
00079 private_nh.param("pcap", dump_file, std::string(""));
00080
00081 if (dump_file != "")
00082 {
00083 NODELET_INFO("reading data from file: %s", dump_file.c_str());
00084 input_ = new velodyne::InputPCAP(dump_file);
00085 }
00086 else
00087 {
00088 NODELET_INFO("reading data from socket");
00089 input_ = new velodyne::InputSocket();
00090 }
00091
00092 ros::NodeHandle node = getNodeHandle();
00093
00094
00095 if(input_->vopen() != 0)
00096 {
00097 NODELET_FATAL("Cannot open Velodyne input.");
00098
00099 return;
00100 }
00101
00102 output_ = node.advertise<velodyne_msgs::VelodyneScan>("velodyne/packets", 10);
00103
00104
00105 running_ = true;
00106 deviceThread_ = boost::shared_ptr< boost::thread >
00107 (new boost::thread(boost::bind(&DriverNodelet::devicePoll, this)));
00108 }
00109
00110 void DriverNodelet::devicePoll()
00111 {
00112
00113 while(running_)
00114 {
00115
00116 velodyne_msgs::VelodyneScanPtr scan(new velodyne_msgs::VelodyneScan);
00117 scan->packets.resize(npackets_);
00118
00119
00120
00121 for (int i = 0; i < npackets_; ++i)
00122 {
00123 while (true)
00124 {
00125
00126 int rc = input_->getPacket(&scan->packets[i]);
00127 if (rc == 0) break;
00128 if (rc < 0) return;
00129 }
00130 }
00131
00132
00133 NODELET_DEBUG("Publishing a full Velodyne scan.");
00134 scan->header.stamp = ros::Time(scan->packets[npackets_ - 1].stamp);
00135 scan->header.frame_id = frame_id_;
00136 output_.publish(scan);
00137 }
00138 }
00139
00140
00141
00142
00143 PLUGINLIB_DECLARE_CLASS(velodyne_common, DriverNodelet,
00144 DriverNodelet, nodelet::Nodelet);