lms400_node.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id: lms400_node.cpp 657 2010-09-25 23:31:31Z moesenle $
00028  *
00029  */
00030 
00042 #include <ros/ros.h>
00043 #include <geometry_msgs/Point.h>
00044 #include <sensor_msgs/LaserScan.h>
00045 
00046 #include <sick_lms400/sick_lms400.h>
00047 
00048 using namespace std;
00049 using namespace ros;
00050 using namespace sick_lms400;
00051 using namespace geometry_msgs;
00052 using namespace sensor_msgs;
00053 
00054 class LMS400Node
00055 {
00056   protected:
00057     ros::NodeHandle nh_;
00058   public:
00059 
00060     SickLMS400 lms_;
00061     LaserScan scan_;
00062 
00063     Publisher scan_pub_;
00064 
00065     // TCP/IP connection parameters
00066     string hostname_, password_;
00067     int    port_;
00068 
00069     // Filter settings
00070     int filter_;
00071     int mean_filter_params_;
00072     double range_filter_params_min_, range_filter_params_max_;
00073 
00074     // Turn intensity data on/off
00075     bool intensity_;
00076 
00077     // Turn laser on/off
00078     bool laser_enabled_;
00079 
00080     // Basic measurement parameters
00081     double angular_resolution_, scanning_frequency_;
00082     double min_angle_, max_angle_;
00083     int eRIS_;
00084 
00085     // Password for changing to userlevel 3 (service)
00086     bool loggedin_;
00087     int debug_;
00088 
00090     LMS400Node (ros::NodeHandle &n) : nh_(n), debug_ (0)
00091     {
00092       nh_.param ("hostname", hostname_, string ("192.168.0.1"));
00093       // Userlevel 3 password (hashed). Default: servicelevel/81BE23AA (Service (userlevel 3) password. Used for enabling/disabling and/or setting the filter parameters.
00094 
00095       nh_.param ("password", password_, string ("81BE23AA"));
00096       nh_.param ("port", port_, 2111);
00097 
00098       // Filter settings. Valid values are:
00099       // 0 (disabled)
00100       // 1 (enable median filter)
00101       // 2 (enable edge filter)
00102       // 4 (enable range filter)
00103       // 8 (enable mean filter)
00104       // 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
00105       //            previous filter. The processing in this case follows the following sequence: edge filter, median filter, range filter, mean filter.
00106       //         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
00107       //            filters are stored in a float array in the sequence mentioned above. Since the current LMS400 firmware version (1.20) supports setting the
00108       //            parameters for the range and mean filters, the order of the parameters in the (player_laser_set_filter_config_t - float parameters[]) array,
00109       //            provided that both range and mean are enabled is: [BottomLimit TopLimit Mean]
00110       nh_.param ("filter", filter_, 11);     // Enable median, edge and mean filter
00111 
00112       // Enable extended RIS detectivity. If you want to measure objects with remission values < 10%,
00113       // you can extend the so-called Remission Information System (RIS) on the LMS4000.
00114       nh_.param ("enable_eRIS", eRIS_, 1);
00115 
00116       // Define the number of means for the mean filter. Possible values: 2..200.
00117       nh_.param ("mean_filter_parameter", mean_filter_params_, 3);
00118 
00119       // Define a specific range within which measured values are valid and are output. Possible values: [+700.0...+3000.0 <bottom limit>...+3000.0]
00120       nh_.param ("range_filter_parameter_min", range_filter_params_min_, 700.0);
00121       nh_.param ("range_filter_parameter_max", range_filter_params_max_, 3000.0);
00122 
00123       {
00124         // Angular resolution. Valid values are: 0.1 ..1 (with 0.1 degree increments)
00125         nh_.param ("angular_resolution", angular_resolution_, 0.1);
00126 
00127         // Scanning frequency. Valid values are: - 200..500Hz (on the LMS400-0000) / 360..500Hz (on the LMS400-1000)
00128         nh_.param ("scanning_frequency", scanning_frequency_, 360.0);
00129 
00130         nh_.param ("enable_laser", laser_enabled_, true);
00131         nh_.param ("enable_intensity", intensity_, true);
00132 
00133         // Defines the minimum / maximum angle of the laser unit (where the scan should start / end). Valid values: 55-125 degrees.
00134         nh_.param ("min_angle", min_angle_, 55.0);
00135         nh_.param ("max_angle", max_angle_, 125.0);
00136       }
00137 
00138       scan_pub_ = nh_.advertise<LaserScan>("laser_scan", 1);
00139 
00140       loggedin_  = false;
00141     }
00142 
00144     ~LMS400Node ()
00145     {
00146       stop ();
00147     }
00148 
00150     // Start
00151     int
00152       start ()
00153     {
00154       // Open the LMS400 device
00155       lms_ = SickLMS400 (hostname_.c_str (), port_, debug_);
00156 
00157       // Attempt to connect to the laser unit
00158       if (lms_.Connect () != 0)
00159       {
00160         ROS_ERROR ("> [SickLMS400] Connecting to SICK LMS400 on [%s:%d]...[failed!]", hostname_.c_str (), port_);
00161         return (-1);
00162       }
00163       ROS_INFO ("> [SickLMS400] Connecting to SICK LMS400 on [%s:%d]... [done]", hostname_.c_str (), port_);
00164 
00165       // Stop the measurement process (in case it's running from another instance)
00166       lms_.StopMeasurement ();
00167 
00168       if (strncmp (password_.c_str (), "NULL", 4) != 0)
00169       {
00170         // Login to userlevel 3
00171         if (lms_.SetUserLevel (4, password_.c_str ()) != 0)
00172           ROS_WARN ("> [SickLMS400] Unable to change userlevel to 'Service' using %s", password_.c_str ());
00173         else
00174         {
00175           loggedin_ = true;
00176           // Enable or disable filters
00177           if ((mean_filter_params_ >= 2) && (mean_filter_params_ <= 200))
00178             lms_.SetMeanFilterParameters (mean_filter_params_);
00179 
00180           if ((range_filter_params_min_ >= 700.0) && (range_filter_params_max_> range_filter_params_min_) && (range_filter_params_max_ <= 3600.0))
00181             lms_.SetRangeFilterParameters ((float)range_filter_params_min_, (float)range_filter_params_max_);
00182 
00183           lms_.EnableFilters (filter_);
00184 
00185           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_);
00186         }
00187       }
00188       else
00189         ROS_WARN ("> [SickLMS400] Userlevel 3 password not given. Filter(s) disabled!");
00190 
00191       // Enable extended RIS detectivity
00192       if (eRIS_)
00193       {
00194         lms_.EnableRIS (1);
00195         ROS_INFO ("> [SickLMS400] Enabling extended RIS detectivity... [done]");
00196       }
00197       // Set scanning parameters
00198       if (lms_.SetResolutionAndFrequency (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_) != 0)
00199         ROS_ERROR ("> [SickLMS400] Couldn't set values for resolution, frequency, and min/max angle. Using previously set values.");
00200       else
00201         ROS_INFO ("> [SickLMS400] Enabling user values for resolution (%f), frequency (%f) and min/max angle (%f/%f)... [done]",
00202                   angular_resolution_, scanning_frequency_, min_angle_, max_angle_);
00203 
00204       return (0);
00205     }
00206 
00208     // Stop
00209     int
00210       stop ()
00211     {
00212       // Stop the measurement process
00213       lms_.StopMeasurement ();
00214       // Set back to userlevel 0
00215       lms_.TerminateConfiguration ();
00216       // Disconnect from the laser unit
00217       lms_.Disconnect ();
00218 
00219       ROS_INFO ("> [SickLMS400] SICK LMS400 driver shutting down... [done]");
00220       return (0);
00221     }
00222 
00224     // Set new measurement values and restart scanning
00225     void
00226       restartMeasurementWithNewValues (float scanning_frequency, float angular_resolution,
00227                                        float min_angle, float diff_angle, int intensity,
00228                                        bool laser_enabled)
00229     {
00230       // Stop the measurement process
00231       lms_.StopMeasurement ();
00232 
00233       // Change userlevel to 3
00234       if (lms_.SetUserLevel (4, password_.c_str ()) != 0)
00235       {
00236         ROS_WARN ("> Unable to change userlevel to 'Service' using %s", password_.c_str ());
00237         if (laser_enabled)
00238           lms_.StartMeasurement (intensity);
00239       }
00240       else
00241       {
00242         // Set the angular resolution and frequency
00243         if (lms_.SetResolutionAndFrequency (scanning_frequency, angular_resolution, min_angle, diff_angle) == 0)
00244           // Re-start the measurement process
00245           if (laser_enabled)
00246             lms_.StartMeasurement (intensity);
00247       }
00248     }
00249 
00251     // Obtain a set of interesting parameters from the parameter server
00252     void
00253       getParametersFromServer ()
00254     {
00255       // LMS400 related parameters
00256       bool laser_enabled;
00257       nh_.getParam ("enable_laser", laser_enabled);
00258       // New value specified
00259       if (laser_enabled != laser_enabled_)
00260       {
00261         ROS_INFO ("New enable_laser parameter received (%d)", laser_enabled);
00262         laser_enabled_ = laser_enabled;
00263 
00264         if (!laser_enabled_)
00265           lms_.StopMeasurement ();
00266         else
00267           lms_.StartMeasurement (intensity_);
00268       }
00269 
00270       bool intensity;
00271       nh_.getParam ("enable_intensity", intensity);
00272       // New value specified
00273       if (intensity != intensity_)
00274       {
00275         ROS_INFO ("New enable_intensity parameter received (%d)", intensity);
00276         intensity_ = intensity;
00277       }
00278 
00279       double angular_resolution;
00280       nh_.getParam ("angular_resolution", angular_resolution);
00281       // New value specified
00282       if (angular_resolution != angular_resolution_)
00283       {
00284         ROS_INFO ("New angular_resolution parameter received (%f)", angular_resolution);
00285         angular_resolution_ = angular_resolution;
00286         restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
00287       }
00288 
00289       double min_angle;
00290       nh_.getParam ("min_angle", min_angle);
00291       // New value specified
00292       if (min_angle != min_angle_)
00293       {
00294         ROS_INFO ("New min_angle parameter received (%f)", min_angle);
00295         min_angle_ = min_angle;
00296         restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
00297       }
00298 
00299       double max_angle;
00300       nh_.getParam ("max_angle", max_angle);
00301       // New value specified
00302       if (max_angle != max_angle_)
00303       {
00304         ROS_INFO ("New max_angle parameter received (%f)", max_angle);
00305         max_angle_ = max_angle;
00306         restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
00307       }
00308 
00309       double scanning_frequency;
00310       nh_.getParam ("scanning_frequency", scanning_frequency);
00311       // New value specified
00312       if (scanning_frequency != scanning_frequency_)
00313       {
00314         ROS_INFO ("New scanning_frequency parameter received (%f)", scanning_frequency);
00315         scanning_frequency_ = scanning_frequency;
00316         restartMeasurementWithNewValues (scanning_frequency_, angular_resolution_, min_angle_, max_angle_ - min_angle_, intensity_, laser_enabled_);
00317       }
00318     }
00319 
00321     // Spin (!)
00322     bool
00323       spin ()
00324     {
00325       // Start Continous measurements
00326       lms_.StartMeasurement (intensity_);
00327 
00328       while (nh_.ok ())
00329       {
00330         // Change certain parameters in the cameras, based on values from the parameter server
00331         //getParametersFromServer ();
00332 
00333         // Refresh data only if laser power is on
00334         if (laser_enabled_)
00335         {
00336           scan_ = lms_.ReadMeasurement ();
00337 
00338           if (scan_.ranges.size () != 0)
00339             scan_pub_.publish (scan_);
00340           //ROS_INFO ("Publishing %d measurements.", (int)scan_.ranges.size ());
00341         }
00342         ros::spinOnce ();
00343       }
00344 
00345       return (true);
00346     }
00347 };
00348 
00349 /* ---[ */
00350 int
00351   main (int argc, char** argv)
00352 {
00353   ros::init (argc, argv, "lms400_node");
00354   ros::NodeHandle n("~");
00355   LMS400Node c(n);
00356 
00357   if (c.start () == 0)
00358     c.spin ();
00359 
00360   return (0);
00361 }
00362 /* ]--- */
00363 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


sick_lms400
Author(s): Radu Bogdan Rusu (rusu@cs.tum.edu), Dejan Pangercic (dejan.pangercic@cs.tum.edu)
autogenerated on Thu May 23 2013 18:45:17