Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <csignal>
00020 #include <cstdio>
00021
00022
00023 #include "ros/ros.h"
00024
00025
00026 #include <sensor_msgs/LaserScan.h>
00027 #include <diagnostic_msgs/DiagnosticArray.h>
00028
00029
00030 #include <lms1xx.h>
00031
00032 #define DEG2RAD M_PI/180.0
00033
00034
00035 class SickLMS1xxNode
00036 {
00037 public:
00038
00039 SickLMS1xxNode();
00040
00041 bool initalize();
00042
00043 void startScanner();
00044 void publish();
00045 void stopScanner();
00046
00047 ros::NodeHandle nh;
00048
00049 private:
00050
00051 bool initalizeLaser();
00052 bool initalizeMessage();
00053 void setScanDataConfig();
00054 void publishError(std::string error_str);
00055
00056 ros::Publisher scan_pub;
00057 ros::Publisher diagnostic_pub;
00058
00059
00060 LMS1xx laser;
00061 scanCfg cfg;
00062 scanDataCfg dataCfg;
00063 scanData data;
00064
00065 sensor_msgs::LaserScan scan_msg;
00066
00067 std::string host;
00068 std::string frame_id;
00069 bool inverted;
00070 double resolution;
00071 double frequency;
00072 bool set_config;
00073 double min_range;
00074 double max_range;
00075 };
00076
00077 SickLMS1xxNode::SickLMS1xxNode()
00078 {
00079 ros::NodeHandle nh;
00080
00081 scan_pub = nh.advertise<sensor_msgs::LaserScan>("scan", 1);
00082 diagnostic_pub = nh.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00083
00084 if(!nh.hasParam("host")) ROS_WARN("Used default parameter for host");
00085 nh.param<std::string>("host", host, "192.168.1.2");
00086 if(!nh.hasParam("frame_id")) ROS_WARN("Used default parameter for frame_id");
00087 nh.param<std::string>("frame_id", frame_id, "base_laser_link");
00088 if(!nh.hasParam("inverted")) ROS_WARN("Used default parameter for inverted");
00089 nh.param<bool>("inverted", inverted, false);
00090 if(!nh.hasParam("angle_resolution")) ROS_WARN("Used default parameter for resolution");
00091 nh.param<double>("angle_resolution", resolution, 0.5);
00092 if(!nh.hasParam("scan_frequency")) ROS_WARN("Used default parameter for frequency");
00093 nh.param<double>("scan_frequency", frequency, 25);
00094 if(!nh.hasParam("set_config")) ROS_WARN("Used default parameter for set_config");
00095 nh.param<bool>("set_config", set_config, false);
00096 if(!nh.hasParam("min_range")) ROS_WARN("Used default parameter for min_range");
00097 nh.param<double>("min_range", min_range, 0.01);
00098 if(!nh.hasParam("max_range")) ROS_WARN("Used default parameter for max_range");
00099 nh.param<double>("max_range", max_range, 20.0);
00100
00101 ROS_INFO("connecting to laser at : %s", host.c_str());
00102 ROS_INFO("using frame_id : %s", frame_id.c_str());
00103 ROS_INFO("inverted : %s", (inverted)?"true":"false");
00104 ROS_INFO("using res : %f", resolution);
00105 ROS_INFO("using freq : %f", frequency);
00106 }
00107
00108 bool SickLMS1xxNode::initalize()
00109 {
00110 bool ret = false;
00111
00112 if (initalizeLaser() && initalizeMessage()) {
00113
00114 setScanDataConfig();
00115 ret = true;
00116 }
00117
00118 return ret;
00119 }
00120
00121 bool SickLMS1xxNode::initalizeLaser()
00122 {
00123 bool ret = false;
00124
00125 laser.connect(host);
00126
00127 if (laser.isConnected()) {
00128
00129 ROS_INFO("Connected to laser.");
00130 ret = true;
00131
00132
00133 laser.login();
00134 cfg = laser.getScanCfg();
00135
00136 if(set_config)
00137 {
00138 ROS_DEBUG("Set angle resolution to %f deg",resolution);
00139 cfg.angleResolution = (int)(resolution * 10000);
00140 ROS_DEBUG("Set scan frequency to %f hz",frequency);
00141 cfg.scaningFrequency = (int)(frequency * 100);
00142
00143 laser.setScanCfg(cfg);
00144 laser.saveConfig();
00145 }
00146
00147 cfg = laser.getScanCfg();
00148
00149 if(cfg.angleResolution != (int)(resolution * 10000))
00150 ROS_ERROR("Setting angle resolution failed: Current angle resolution is %f.", cfg.angleResolution/10000.0);
00151 if(cfg.scaningFrequency != (int)(frequency * 100))
00152 ROS_ERROR("Setting scan frequency failed: Current scan frequency is %f.", cfg.scaningFrequency/100.0);
00153
00154 } else {
00155 ROS_ERROR("Connection to device failed");
00156 publishError("Connection to device failed");
00157 }
00158 return ret;
00159 }
00160
00161 bool SickLMS1xxNode::initalizeMessage()
00162 {
00163 bool ret = true;
00164
00165
00166 scan_msg.header.frame_id = frame_id;
00167
00168 scan_msg.range_min = min_range;
00169 scan_msg.range_max = max_range;
00170
00171 scan_msg.scan_time = 100.0/cfg.scaningFrequency;
00172
00173 scan_msg.angle_increment = (double)cfg.angleResolution/10000.0 * DEG2RAD;
00174 scan_msg.angle_min = (double)cfg.startAngle/10000.0 * DEG2RAD - M_PI/2;
00175 scan_msg.angle_max = (double)cfg.stopAngle/10000.0 * DEG2RAD - M_PI/2;
00176
00177 int num_values;
00178 if (cfg.angleResolution == 2500)
00179 {
00180 num_values = 1081;
00181 }
00182 else if (cfg.angleResolution == 5000)
00183 {
00184 num_values = 541;
00185 }
00186 else
00187 {
00188 ROS_ERROR("Unsupported resolution");
00189 publishError("Unsupported resolution");
00190 ret = false;
00191 }
00192
00193 scan_msg.time_increment = scan_msg.scan_time/num_values;
00194
00195 scan_msg.ranges.resize(num_values);
00196 scan_msg.intensities.resize(num_values);
00197
00198 if(not inverted)
00199 scan_msg.time_increment *= -1.;
00200
00201 return ret;
00202 }
00203
00204 void SickLMS1xxNode::setScanDataConfig()
00205 {
00206
00207 dataCfg.outputChannel = 1;
00208 dataCfg.remission = true;
00209 dataCfg.resolution = 1;
00210 dataCfg.encoder = 0;
00211 dataCfg.position = false;
00212 dataCfg.deviceName = false;
00213 dataCfg.outputInterval = 1;
00214
00215 laser.setScanDataCfg(dataCfg);
00216 ROS_DEBUG("setScanDataCfg");
00217
00218 laser.startMeas();
00219 ROS_DEBUG("startMeas");
00220 }
00221
00222 void SickLMS1xxNode::startScanner()
00223 {
00224 status_t stat;
00225 do
00226 {
00227 stat = laser.queryStatus();
00228 ros::Duration(1.0).sleep();
00229 }
00230 while (stat != ready_for_measurement);
00231
00232 laser.startDevice();
00233 ROS_DEBUG("startDevice");
00234
00235 laser.scanContinous(1);
00236 ROS_DEBUG("scanContinous true");
00237 }
00238
00239 void SickLMS1xxNode::publish()
00240 {
00241 scan_msg.header.stamp = ros::Time::now();
00242 ++scan_msg.header.seq;
00243
00244 if(laser.getData(data))
00245 {
00246 for (int i = 0; i < data.dist_len1; i++)
00247 {
00248 if(not inverted) {
00249 scan_msg.ranges[i] = data.dist1[data.dist_len1-1-i] * 0.001;
00250 scan_msg.intensities[i] = data.rssi1[data.rssi_len1-1-i];
00251 } else {
00252 scan_msg.ranges[i] = data.dist1[i] * 0.001;
00253 scan_msg.intensities[i] = data.rssi1[i];
00254 }
00255 }
00256 scan_pub.publish(scan_msg);
00257
00258
00259 diagnostic_msgs::DiagnosticArray diagnostics;
00260 diagnostics.status.resize(1);
00261 diagnostics.status[0].level = 0;
00262 diagnostics.status[0].name = nh.getNamespace();
00263 diagnostics.status[0].message = "sick scanner running";
00264 diagnostic_pub.publish(diagnostics);
00265 }
00266 }
00267
00268 void SickLMS1xxNode::stopScanner()
00269 {
00270 laser.scanContinous(0);
00271 ROS_DEBUG("scanContinous false");
00272 laser.stopMeas();
00273 ROS_DEBUG("stopMeas");
00274 laser.disconnect();
00275 ROS_DEBUG("disconnect");
00276 }
00277
00278 void SickLMS1xxNode::publishError(std::string error_str)
00279 {
00280 diagnostic_msgs::DiagnosticArray diagnostics;
00281 diagnostics.status.resize(1);
00282 diagnostics.status[0].level = 2;
00283 diagnostics.status[0].name = nh.getNamespace();
00284 diagnostics.status[0].message = error_str;
00285 diagnostic_pub.publish(diagnostics);
00286 }
00287
00288
00289
00290
00291 int main(int argc, char** argv)
00292 {
00293 ros::init(argc, argv, "sick_lms1xx_node");
00294
00295 SickLMS1xxNode node;
00296
00297 if (!node.initalize()) {
00298 return 1;
00299 }
00300
00301 node.startScanner();
00302
00303 while(ros::ok())
00304 {
00305 node.publish();
00306
00307 ros::spinOnce();
00308 }
00309
00310 node.stopScanner();
00311
00312 return 0;
00313 }