LMS1xx_node.cpp
Go to the documentation of this file.
1 /*
2  * LMS1xx.cpp
3  *
4  * Created on: 09-08-2010
5  * Author: Konrad Banachowicz
6  ***************************************************************************
7  * This library is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU Lesser General Public *
9  * License as published by the Free Software Foundation; either *
10  * version 2.1 of the License, or (at your option) any later version. *
11  * *
12  * This library is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * Lesser General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public *
18  * License along with this library; if not, write to the Free Software *
19  * Foundation, Inc., 59 Temple Place, *
20  * Suite 330, Boston, MA 02111-1307 USA *
21  * *
22  ***************************************************************************/
23 
24 #include <csignal>
25 #include <cstdio>
26 #include <LMS1xx/LMS1xx.h>
27 #include "ros/ros.h"
28 #include "sensor_msgs/LaserScan.h"
29 #include <limits>
30 #include <string>
31 
32 #define DEG2RAD M_PI/180.0
33 
34 int main(int argc, char **argv)
35 {
36  // laser data
37  LMS1xx laser;
38  scanCfg cfg;
40  scanDataCfg dataCfg;
41  sensor_msgs::LaserScan scan_msg;
42 
43  // parameters
44  std::string host;
45  std::string frame_id;
46  bool inf_range;
47  int port;
48 
49  ros::init(argc, argv, "lms1xx");
50  ros::NodeHandle nh;
51  ros::NodeHandle n("~");
52  ros::Publisher scan_pub = nh.advertise<sensor_msgs::LaserScan>("scan", 1);
53 
54  n.param<std::string>("host", host, "192.168.1.2");
55  n.param<std::string>("frame_id", frame_id, "laser");
56  n.param<bool>("publish_min_range_as_inf", inf_range, false);
57  n.param<int>("port", port, 2111);
58 
59  while (ros::ok())
60  {
61  ROS_INFO_STREAM("Connecting to laser at " << host);
62  laser.connect(host, port);
63  if (!laser.isConnected())
64  {
65  ROS_WARN("Unable to connect, retrying.");
66  ros::Duration(1).sleep();
67  continue;
68  }
69 
70  ROS_DEBUG("Logging in to laser.");
71  laser.login();
72  cfg = laser.getScanCfg();
73  outputRange = laser.getScanOutputRange();
74 
75  if (cfg.scaningFrequency != 5000)
76  {
77  laser.disconnect();
78  ROS_WARN("Unable to get laser output range. Retrying.");
79  ros::Duration(1).sleep();
80  continue;
81  }
82 
83  ROS_INFO("Connected to laser.");
84 
85  ROS_DEBUG("Laser configuration: scaningFrequency %d, angleResolution %d, startAngle %d, stopAngle %d",
87  ROS_DEBUG("Laser output range:angleResolution %d, startAngle %d, stopAngle %d",
88  outputRange.angleResolution, outputRange.startAngle, outputRange.stopAngle);
89 
90  scan_msg.header.frame_id = frame_id;
91  scan_msg.range_min = 0.01;
92  scan_msg.range_max = 20.0;
93  scan_msg.scan_time = 100.0 / cfg.scaningFrequency;
94  scan_msg.angle_increment = static_cast<double>(outputRange.angleResolution / 10000.0 * DEG2RAD);
95  scan_msg.angle_min = static_cast<double>(outputRange.startAngle / 10000.0 * DEG2RAD - M_PI / 2);
96  scan_msg.angle_max = static_cast<double>(outputRange.stopAngle / 10000.0 * DEG2RAD - M_PI / 2);
97 
98  ROS_DEBUG_STREAM("Device resolution is " << (double)outputRange.angleResolution / 10000.0 << " degrees.");
99  ROS_DEBUG_STREAM("Device frequency is " << (double)cfg.scaningFrequency / 100.0 << " Hz");
100 
101  int angle_range = outputRange.stopAngle - outputRange.startAngle;
102  int num_values = angle_range / outputRange.angleResolution;
103  if (angle_range % outputRange.angleResolution == 0)
104  {
105  // Include endpoint
106  ++num_values;
107  }
108  scan_msg.ranges.resize(num_values);
109  scan_msg.intensities.resize(num_values);
110 
111  scan_msg.time_increment =
112  (outputRange.angleResolution / 10000.0)
113  / 360.0
114  / (cfg.scaningFrequency / 100.0);
115 
116  ROS_DEBUG_STREAM("Time increment is " << static_cast<int>(scan_msg.time_increment * 1000000) << " microseconds");
117 
118  dataCfg.outputChannel = 1;
119  dataCfg.remission = true;
120  dataCfg.resolution = 1;
121  dataCfg.encoder = 0;
122  dataCfg.position = false;
123  dataCfg.deviceName = false;
124  dataCfg.outputInterval = 1;
125 
126  ROS_DEBUG("Setting scan data configuration.");
127  laser.setScanDataCfg(dataCfg);
128 
129  ROS_DEBUG("Starting measurements.");
130  laser.startMeas();
131 
132  ROS_DEBUG("Waiting for ready status.");
133  ros::Time ready_status_timeout = ros::Time::now() + ros::Duration(5);
134 
135  // while(1)
136  // {
137  status_t stat = laser.queryStatus();
138  ros::Duration(1.0).sleep();
139  if (stat != ready_for_measurement)
140  {
141  ROS_WARN("Laser not ready. Retrying initialization.");
142  laser.disconnect();
143  ros::Duration(1).sleep();
144  continue;
145  }
146  /*if (stat == ready_for_measurement)
147  {
148  ROS_DEBUG("Ready status achieved.");
149  break;
150  }
151 
152  if (ros::Time::now() > ready_status_timeout)
153  {
154  ROS_WARN("Timed out waiting for ready status. Trying again.");
155  laser.disconnect();
156  continue;
157  }
158 
159  if (!ros::ok())
160  {
161  laser.disconnect();
162  return 1;
163  }
164  }*/
165 
166  ROS_DEBUG("Starting device.");
167  laser.startDevice(); // Log out to properly re-enable system after config
168 
169  ROS_DEBUG("Commanding continuous measurements.");
170  laser.scanContinous(1);
171 
172  while (ros::ok())
173  {
175 
176  scan_msg.header.stamp = start;
177  ++scan_msg.header.seq;
178 
179  scanData data;
180  ROS_DEBUG("Reading scan data.");
181  if (laser.getScanData(&data))
182  {
183  for (int i = 0; i < data.dist_len1; i++)
184  {
185  float range_data = data.dist1[i] * 0.001;
186 
187  if (inf_range && range_data < scan_msg.range_min)
188  {
189  scan_msg.ranges[i] = std::numeric_limits<float>::infinity();
190  }
191  else
192  {
193  scan_msg.ranges[i] = range_data;
194  }
195  }
196 
197  for (int i = 0; i < data.rssi_len1; i++)
198  {
199  scan_msg.intensities[i] = data.rssi1[i];
200  }
201 
202  ROS_DEBUG("Publishing scan data.");
203  scan_pub.publish(scan_msg);
204  }
205  else
206  {
207  ROS_ERROR("Laser timed out on delivering scan, attempting to reinitialize.");
208  break;
209  }
210 
211  ros::spinOnce();
212  }
213 
214  laser.scanContinous(0);
215  laser.stopMeas();
216  laser.disconnect();
217  }
218 
219  return 0;
220 }
int startAngle
Start angle. 1/10000 degree.
Definition: lms_structs.h:139
Structure containing single scan message.
Definition: lms_structs.h:154
ROSCPP_DECL void start()
void setScanDataCfg(const scanDataCfg &cfg)
Set scan data configuration. Set format of scan message returned by device.
Definition: LMS1xx.cpp:197
void publish(const boost::shared_ptr< M > &message) const
scanCfg getScanCfg() const
Get current scan configuration. Get scan configuration :
Definition: LMS1xx.cpp:164
status_t queryStatus()
Get current status of LMS1xx device.
Definition: LMS1xx.cpp:114
scanOutputRange getScanOutputRange() const
Get current output range configuration. Get output range configuration :
Definition: LMS1xx.cpp:211
bool sleep() const
uint16_t dist1[1082]
Radial distance for the first reflected pulse.
Definition: lms_structs.h:167
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void login()
Log into LMS1xx unit. Increase privilege level, giving ability to change device configuration.
Definition: LMS1xx.cpp:133
int resolution
Remission resolution. Defines whether the remission values are output with 8-bit or 16bit resolution...
Definition: lms_structs.h:87
bool remission
Remission. Defines whether remission values are output.
Definition: lms_structs.h:81
int outputInterval
Output interval. Defines which scan is output.
Definition: lms_structs.h:118
Structure containing scan data configuration.
Definition: lms_structs.h:68
int angleResolution
Scanning resolution. 1/10000 degree.
Definition: lms_structs.h:133
int stopAngle
Stop angle. 1/10000 degree.
Definition: lms_structs.h:145
#define ROS_WARN(...)
int encoder
Encoders channels. Defines which output channel is activated.
Definition: lms_structs.h:93
void stopMeas()
Stop measurements. After receiving this command LMS1xx unit stop spinning laser and measuring...
Definition: LMS1xx.cpp:100
int scaningFrequency
Scanning frequency. 1/100 Hz.
Definition: lms_structs.h:41
Structure containing scan configuration.
Definition: lms_structs.h:35
bool getScanData(scanData *scan_data)
Receive single scan message.
Definition: LMS1xx.cpp:242
void startDevice()
The device is returned to the measurement mode after configuration.
Definition: LMS1xx.cpp:485
#define ROS_INFO(...)
void scanContinous(int start)
Start or stop continuous data acquisition. After reception of this command device start or stop conti...
Definition: LMS1xx.cpp:226
int outputChannel
Output channels. Defines which output channel is activated.
Definition: lms_structs.h:75
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int angleResolution
Scanning resolution. 1/10000 degree.
Definition: lms_structs.h:47
int dist_len1
Number of samples in dist1.
Definition: lms_structs.h:161
ROSCPP_DECL bool ok()
void startMeas()
Start measurements. After receiving this command LMS1xx unit starts spinning laser and measuring...
Definition: LMS1xx.cpp:86
bool isConnected()
Get status of connection.
Definition: LMS1xx.cpp:81
void disconnect()
Disconnect from LMS1xx device.
Definition: LMS1xx.cpp:72
void connect(std::string host, int port=2111)
Connect to LMS1xx.
Definition: LMS1xx.cpp:47
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_DEBUG_STREAM(args)
int stopAngle
Stop angle. 1/10000 degree.
Definition: lms_structs.h:59
int startAngle
Start angle. 1/10000 degree.
Definition: lms_structs.h:53
Structure containing scan output range configuration.
int main(int argc, char **argv)
Definition: LMS1xx_node.cpp:34
#define ROS_INFO_STREAM(args)
#define DEG2RAD
Definition: LMS1xx_node.cpp:32
Class responsible for communicating with LMS1xx device.
Definition: LMS1xx.h:51
static Time now()
bool position
Position. Defines whether position values are output.
Definition: lms_structs.h:99
status_t
Definition: LMS1xx.h:32
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
uint16_t rssi1[1082]
Remission values for the first reflected pulse.
Definition: lms_structs.h:191
int rssi_len1
Number of samples in rssi1.
Definition: lms_structs.h:185
#define ROS_DEBUG(...)
bool deviceName
Device name. Determines whether the device name is to be output.
Definition: lms_structs.h:105


lms1xx
Author(s): Konrad Banachowicz
autogenerated on Wed Jan 22 2020 03:36:59