lms400_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  *
27  * $Id$
28  *
29  */
30 
42 #include <ros/ros.h>
43 #include <geometry_msgs/Point.h>
44 #include <sensor_msgs/LaserScan.h>
45 
46 #include <asr_sick_lms_400/sick_lms400.h>
47 
48 using namespace std;
49 using namespace ros;
50 using namespace asr_sick_lms_400;
51 using namespace geometry_msgs;
52 using namespace sensor_msgs;
53 
55 {
56  protected:
58  public:
59 
61  LaserScan scan_;
62 
64 
65  // TCP/IP connection parameters
66  string hostname_, password_;
67  int port_;
68 
69  // Filter settings
70  int filter_;
72  double range_filter_params_min_, range_filter_params_max_;
73 
74  // Turn intensity data on/off
75  bool intensity_;
76 
77  // Turn laser on/off
79 
80  // Basic measurement parameters
81  double angular_resolution_, scanning_frequency_;
82  double min_angle_, max_angle_;
83  int eRIS_;
84 
85  // Password for changing to userlevel 3 (service)
86  bool loggedin_;
87  int debug_;
88 
90  LMS400Node (ros::NodeHandle &n) : nh_(n), debug_ (0)
91  {
92  nh_.param ("hostname", hostname_, string ("192.168.0.1"));
93  // Userlevel 3 password (hashed). Default: servicelevel/81BE23AA (Service (userlevel 3) password. Used for enabling/disabling and/or setting the filter parameters.
94 
95  nh_.param ("password", password_, string ("81BE23AA"));
96  nh_.param ("port", port_, 2111);
97 
98  // Filter settings. Valid values are:
99  // 0 (disabled)
100  // 1 (enable median filter)
101  // 2 (enable edge filter)
102  // 4 (enable range filter)
103  // 8 (enable mean filter)
104  // Notes : 1) You can combine the filters as required. If several filters are active, then the filters act one after the other on the result of the
105  // previous filter. The processing in this case follows the following sequence: edge filter, median filter, range filter, mean filter.
106  // 2) You can use PLAYER_LASER_REQ_SET_FILTER to enable/disable the filters as well as set their parameters from the client. The parameters of the
107  // filters are stored in a float array in the sequence mentioned above. Since the current LMS400 firmware version (1.20) supports setting the
108  // parameters for the range and mean filters, the order of the parameters in the (player_laser_set_filter_config_t - float parameters[]) array,
109  // provided that both range and mean are enabled is: [BottomLimit TopLimit Mean]
110  nh_.param ("filter", filter_, 11); // Enable median, edge and mean filter
111 
112  // Enable extended RIS detectivity. If you want to measure objects with remission values < 10%,
113  // you can extend the so-called Remission Information System (RIS) on the LMS4000.
114  nh_.param ("enable_eRIS", eRIS_, 1);
115 
116  // Define the number of means for the mean filter. Possible values: 2..200.
117  nh_.param ("mean_filter_parameter", mean_filter_params_, 3);
118 
119  // Define a specific range within which measured values are valid and are output. Possible values: [+700.0...+3000.0 <bottom limit>...+3000.0]
120  nh_.param ("range_filter_parameter_min", range_filter_params_min_, 700.0);
121  nh_.param ("range_filter_parameter_max", range_filter_params_max_, 3000.0);
122 
123  {
124  // Angular resolution. Valid values are: 0.1 ..1 (with 0.1 degree increments)
125  nh_.param ("angular_resolution", angular_resolution_, 0.1);
126 
127  // Scanning frequency. Valid values are: - 200..500Hz (on the LMS400-0000) / 360..500Hz (on the LMS400-1000)
128  nh_.param ("scanning_frequency", scanning_frequency_, 360.0);
129 
130  nh_.param ("enable_laser", laser_enabled_, true);
131  nh_.param ("enable_intensity", intensity_, true);
132 
133  // Defines the minimum / maximum angle of the laser unit (where the scan should start / end). Valid values: 55-125 degrees.
134  nh_.param ("min_angle", min_angle_, 55.0);
135  nh_.param ("max_angle", max_angle_, 125.0);
136  }
137 
138  scan_pub_ = nh_.advertise<LaserScan>("laser_scan", 1);
139 
140  loggedin_ = false;
141  }
142 
145  {
146  stop ();
147  }
148 
150  // Start
151  int
152  start ()
153  {
154  // Open the LMS400 device
155  lms_ = asr_sick_lms_400 (hostname_.c_str (), port_, debug_);
156 
157  // Attempt to connect to the laser unit
158  if (lms_.Connect () != 0)
159  {
160  ROS_ERROR ("> [SickLMS400] Connecting to SICK LMS400 on [%s:%d]...[failed!]", hostname_.c_str (), port_);
161  return (-1);
162  }
163  ROS_INFO ("> [SickLMS400] Connecting to SICK LMS400 on [%s:%d]... [done]", hostname_.c_str (), port_);
164 
165  // Stop the measurement process (in case it's running from another instance)
166  lms_.StopMeasurement ();
167 
168  if (strncmp (password_.c_str (), "NULL", 4) != 0)
169  {
170  // Login to userlevel 3
171  if (lms_.SetUserLevel (4, password_.c_str ()) != 0)
172  ROS_WARN ("> [SickLMS400] Unable to change userlevel to 'Service' using %s", password_.c_str ());
173  else
174  {
175  loggedin_ = true;
176  // Enable or disable filters
177  if ((mean_filter_params_ >= 2) && (mean_filter_params_ <= 200))
178  lms_.SetMeanFilterParameters (mean_filter_params_);
179 
180  if ((range_filter_params_min_ >= 700.0) && (range_filter_params_max_> range_filter_params_min_) && (range_filter_params_max_ <= 3600.0))
181  lms_.SetRangeFilterParameters ((float)range_filter_params_min_, (float)range_filter_params_max_);
182 
183  lms_.EnableFilters (filter_);
184 
185  ROS_INFO ("> [SickLMS400] Enabling selected filters (%d, %f, %f, %d)... [done]", mean_filter_params_, (float)range_filter_params_min_, (float)range_filter_params_max_, filter_);
186  }
187  }
188  else
189  ROS_WARN ("> [SickLMS400] Userlevel 3 password not given. Filter(s) disabled!");
190 
191  // Enable extended RIS detectivity
192  if (eRIS_)
193  {
194  lms_.EnableRIS (1);
195  ROS_INFO ("> [SickLMS400] Enabling extended RIS detectivity... [done]");
196  }
197  // Set scanning parameters
198  if (lms_.SetResolutionAndFrequency (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_) != 0)
199  ROS_ERROR ("> [SickLMS400] Couldn't set values for resolution, frequency, and min/max angle. Using previously set values.");
200  else
201  ROS_INFO ("> [SickLMS400] Enabling user values for resolution (%f), frequency (%f) and min/max angle (%f/%f)... [done]",
202  angular_resolution_, scanning_frequency_, min_angle_, max_angle_);
203 
204  return (0);
205  }
206 
208  // Stop
209  int
210  stop ()
211  {
212  // Stop the measurement process
213  lms_.StopMeasurement ();
214  // Set back to userlevel 0
215  lms_.TerminateConfiguration ();
216  // Disconnect from the laser unit
217  lms_.Disconnect ();
218 
219  ROS_INFO ("> [SickLMS400] SICK LMS400 driver shutting down... [done]");
220  return (0);
221  }
222 
224  // Set new measurement values and restart scanning
225  void
226  restartMeasurementWithNewValues (float scanning_frequency, float angular_resolution,
227  float min_angle, float diff_angle, int intensity,
228  bool laser_enabled)
229  {
230  // Stop the measurement process
231  lms_.StopMeasurement ();
232 
233  // Change userlevel to 3
234  if (lms_.SetUserLevel (4, password_.c_str ()) != 0)
235  {
236  ROS_WARN ("> Unable to change userlevel to 'Service' using %s", password_.c_str ());
237  if (laser_enabled)
238  lms_.StartMeasurement (intensity);
239  }
240  else
241  {
242  // Set the angular resolution and frequency
243  if (lms_.SetResolutionAndFrequency (scanning_frequency, angular_resolution, min_angle, diff_angle) == 0)
244  // Re-start the measurement process
245  if (laser_enabled)
246  lms_.StartMeasurement (intensity);
247  }
248  }
249 
251  // Obtain a set of interesting parameters from the parameter server
252  void
254  {
255  // LMS400 related parameters
256  bool laser_enabled;
257  nh_.getParam ("enable_laser", laser_enabled);
258  // New value specified
259  if (laser_enabled != laser_enabled_)
260  {
261  ROS_INFO ("New enable_laser parameter received (%d)", laser_enabled);
262  laser_enabled_ = laser_enabled;
263 
264  if (!laser_enabled_)
265  lms_.StopMeasurement ();
266  else
267  lms_.StartMeasurement (intensity_);
268  }
269 
270  bool intensity;
271  nh_.getParam ("enable_intensity", intensity);
272  // New value specified
273  if (intensity != intensity_)
274  {
275  ROS_INFO ("New enable_intensity parameter received (%d)", intensity);
276  intensity_ = intensity;
277  }
278 
279  double angular_resolution;
280  nh_.getParam ("angular_resolution", angular_resolution);
281  // New value specified
282  if (angular_resolution != angular_resolution_)
283  {
284  ROS_INFO ("New angular_resolution parameter received (%f)", angular_resolution);
285  angular_resolution_ = angular_resolution;
286  restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
287  }
288 
289  double min_angle;
290  nh_.getParam ("min_angle", min_angle);
291  // New value specified
292  if (min_angle != min_angle_)
293  {
294  ROS_INFO ("New min_angle parameter received (%f)", min_angle);
295  min_angle_ = min_angle;
296  restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
297  }
298 
299  double max_angle;
300  nh_.getParam ("max_angle", max_angle);
301  // New value specified
302  if (max_angle != max_angle_)
303  {
304  ROS_INFO ("New max_angle parameter received (%f)", max_angle);
305  max_angle_ = max_angle;
306  restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
307  }
308 
309  double scanning_frequency;
310  nh_.getParam ("scanning_frequency", scanning_frequency);
311  // New value specified
312  if (scanning_frequency != scanning_frequency_)
313  {
314  ROS_INFO ("New scanning_frequency parameter received (%f)", scanning_frequency);
315  scanning_frequency_ = scanning_frequency;
316  restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
317  }
318  }
319 
321  // Spin (!)
322  bool
323  spin ()
324  {
325  // Start Continous measurements
326  lms_.StartMeasurement (intensity_);
327 
328  while (nh_.ok ())
329  {
330  // Change certain parameters in the cameras, based on values from the parameter server
331  //getParametersFromServer ();
332 
333  // Refresh data only if laser power is on
334  if (laser_enabled_)
335  {
336  scan_ = lms_.ReadMeasurement ();
337 
338  if (scan_.ranges.size () != 0)
339  scan_pub_.publish (scan_);
340  //ROS_INFO ("Publishing %d measurements.", (int)scan_.ranges.size ());
341  }
342  ros::spinOnce ();
343  }
344 
345  return (true);
346  }
347 };
348 
349 /* ---[ */
350 int
351  main (int argc, char** argv)
352 {
353  ros::init (argc, argv, "lms400_node");
354  ros::NodeHandle n("~");
355  LMS400Node c(n);
356 
357  if (c.start () == 0)
358  c.spin ();
359 
360  return (0);
361 }
362 /* ]--- */
363 
int mean_filter_params_
Definition: lms400_node.cpp:71
void publish(const boost::shared_ptr< M > &message) const
bool intensity_
Definition: lms400_node.cpp:75
double min_angle_
Definition: lms400_node.cpp:82
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
int SetResolutionAndFrequency(float freq, float ang_res, float angle_start, float angle_range)
int SetMeanFilterParameters(int num_scans)
void getParametersFromServer()
#define ROS_WARN(...)
bool loggedin_
Definition: lms400_node.cpp:86
sensor_msgs::LaserScan ReadMeasurement()
Publisher scan_pub_
Definition: lms400_node.cpp:63
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
bool laser_enabled_
Definition: lms400_node.cpp:78
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
asr_sick_lms_400 lms_
Definition: lms400_node.cpp:60
double range_filter_params_min_
Definition: lms400_node.cpp:72
ros::NodeHandle nh_
Definition: lms400_node.cpp:57
bool getParam(const std::string &key, std::string &s) const
void restartMeasurementWithNewValues(float scanning_frequency, float angular_resolution, float min_angle, float diff_angle, int intensity, bool laser_enabled)
string password_
Definition: lms400_node.cpp:66
int StartMeasurement(bool intensity=true)
LMS400Node(ros::NodeHandle &n)
Definition: lms400_node.cpp:90
bool ok() const
LaserScan scan_
Definition: lms400_node.cpp:61
int EnableFilters(int filter_mask)
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
int main(int argc, char **argv)
int SetRangeFilterParameters(float range_min, float range_max)
int SetUserLevel(int8_t userlevel, const char *password)
double scanning_frequency_
Definition: lms400_node.cpp:81


asr_sick_lms_400
Author(s): Aumann Florian, Krehl Yann, Meißner Pascal
autogenerated on Mon Jun 10 2019 12:41:54