Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include <string>
00016 #include <cmath>
00017
00018 #include <ros/ros.h>
00019 #include <tf/transform_listener.h>
00020 #include <velodyne_msgs/VelodyneScan.h>
00021
00022 #include "driver.h"
00023
00024 namespace velodyne_driver
00025 {
00026
00027 VelodyneDriver::VelodyneDriver(ros::NodeHandle node,
00028 ros::NodeHandle private_nh)
00029 {
00030
00031 private_nh.param("frame_id", config_.frame_id, std::string("velodyne"));
00032 std::string tf_prefix = tf::getPrefixParam(private_nh);
00033 ROS_DEBUG_STREAM("tf_prefix: " << tf_prefix);
00034 config_.frame_id = tf::resolve(tf_prefix, config_.frame_id);
00035
00036
00037 private_nh.param("model", config_.model, std::string("64E"));
00038 double packet_rate;
00039 std::string model_full_name;
00040 if ((config_.model == "64E_S2") ||
00041 (config_.model == "64E_S2.1"))
00042 {
00043 packet_rate = 3472.17;
00044 model_full_name = std::string("HDL-") + config_.model;
00045 }
00046 else if (config_.model == "64E")
00047 {
00048 packet_rate = 2600.0;
00049 model_full_name = std::string("HDL-") + config_.model;
00050 }
00051 else if (config_.model == "32E")
00052 {
00053 packet_rate = 1808.0;
00054 model_full_name = std::string("HDL-") + config_.model;
00055 }
00056 else if (config_.model == "VLP16")
00057 {
00058 packet_rate = 781.25;
00059 model_full_name = "VLP-16";
00060 }
00061 else
00062 {
00063 ROS_ERROR_STREAM("unknown Velodyne LIDAR model: " << config_.model);
00064 packet_rate = 2600.0;
00065 }
00066 std::string deviceName(std::string("Velodyne ") + model_full_name);
00067
00068 private_nh.param("rpm", config_.rpm, 600.0);
00069 ROS_INFO_STREAM(deviceName << " rotating at " << config_.rpm << " RPM");
00070 double frequency = (config_.rpm / 60.0);
00071
00072
00073
00074 config_.npackets = (int) ceil(packet_rate / frequency);
00075 private_nh.getParam("npackets", config_.npackets);
00076 ROS_INFO_STREAM("publishing " << config_.npackets << " packets per scan");
00077
00078 std::string dump_file;
00079 private_nh.param("pcap", dump_file, std::string(""));
00080
00081
00082 diagnostics_.setHardwareID(deviceName);
00083 const double diag_freq = packet_rate/config_.npackets;
00084 diag_max_freq_ = diag_freq;
00085 diag_min_freq_ = diag_freq;
00086 ROS_INFO("expected frequency: %.3f (Hz)", diag_freq);
00087
00088 using namespace diagnostic_updater;
00089 diag_topic_.reset(new TopicDiagnostic("velodyne_packets", diagnostics_,
00090 FrequencyStatusParam(&diag_min_freq_,
00091 &diag_max_freq_,
00092 0.1, 10),
00093 TimeStampStatusParam()));
00094
00095
00096 if (dump_file != "")
00097 {
00098 input_.reset(new velodyne_driver::InputPCAP(private_nh,
00099 packet_rate,
00100 dump_file));
00101 }
00102 else
00103 {
00104 input_.reset(new velodyne_driver::InputSocket(private_nh));
00105 }
00106
00107
00108 output_ = node.advertise<velodyne_msgs::VelodyneScan>("velodyne_packets", 10);
00109 }
00110
00115 bool VelodyneDriver::poll(void)
00116 {
00117
00118 velodyne_msgs::VelodyneScanPtr scan(new velodyne_msgs::VelodyneScan);
00119 scan->packets.resize(config_.npackets);
00120
00121
00122
00123 for (int i = 0; i < config_.npackets; ++i)
00124 {
00125 while (true)
00126 {
00127
00128 int rc = input_->getPacket(&scan->packets[i]);
00129 if (rc == 0) break;
00130 if (rc < 0) return false;
00131 }
00132 }
00133
00134
00135 ROS_DEBUG("Publishing a full Velodyne scan.");
00136 scan->header.stamp = ros::Time(scan->packets[config_.npackets - 1].stamp);
00137 scan->header.frame_id = config_.frame_id;
00138 output_.publish(scan);
00139
00140
00141
00142 diag_topic_->tick(scan->header.stamp);
00143 diagnostics_.update();
00144
00145 return true;
00146 }
00147
00148 }