gazebo_ros_sonar.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Modified BSD License)
00003  *
00004  *  Copyright (c) 2012, PAL Robotics, S.L.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of PAL Robotics, S.L. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 #include <range_gazebo_plugin/gazebo_ros_sonar.h>
00036 #include <gazebo/common/Event.hh>
00037 #include <gazebo/physics/physics.h>
00038 
00039 using namespace gazebo;
00040 
00041 GazeboRosSonar::GazeboRosSonar()
00042 {
00043 }
00044 
00045 GazeboRosSonar::~GazeboRosSonar()
00046 {
00047     sensor_->SetActive(false);
00048     event::Events::DisconnectWorldUpdateStart(updateConnection);
00049     node_handle_->shutdown();
00050     delete node_handle_;
00051 }
00052 
00053 void GazeboRosSonar::Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
00054 {
00055     ROS_DEBUG("Starting range gazebo plugin");
00056 
00057     // Get then name of the parent sensor
00058     sensor_ = boost::shared_dynamic_cast<sensors::RaySensor>(_parent);
00059     if (!sensor_)
00060     {
00061         gzthrow("GazeboRosSonar requires a Ray Sensor as its parent");
00062         return;
00063     }
00064 
00065     // Get the world name.
00066     std::string worldName = sensor_->GetWorldName();
00067     parent_ = gazebo::physics::get_world(worldName);
00068 
00069     this->namespace_ = "";
00070     if (_sdf->HasElement("robotNamespace"))
00071         this->namespace_ = _sdf->GetElement("robotNamespace")->GetValueString();
00072 
00073     if (!_sdf->HasElement("topicName"))
00074     {
00075         ROS_WARN("Range plugin missing <topicName>, defaults to sonar");
00076         this->topic_name_ = "sonar";
00077     }
00078     else
00079         this->topic_name_ = _sdf->GetElement("topicName")->GetValueString();
00080 
00081     if (!_sdf->HasElement("frameId"))
00082     {
00083         ROS_WARN("Range plugin missing <frameId>, defaults to sonar_base_link");
00084         this->frame_id_ = "sonar_base_link";
00085     }
00086     else
00087         this->frame_id_ = _sdf->GetElement("frameId")->GetValueString();
00088 
00089     if (!_sdf->HasElement("radiation"))
00090     {
00091         ROS_WARN("Range plugin missing <radiation>, defaults to ultrasound");
00092         this->radiation_ = "ultrasound";
00093 
00094     }
00095     else
00096         this->radiation_ = _sdf->GetElement("radiation")->GetValueString();
00097 
00098     if (!_sdf->HasElement("fov"))
00099     {
00100         ROS_WARN("Range plugin missing <fov>, defaults to 0.05");
00101         this->fov_ = 0.05;
00102     }
00103     else
00104         this->fov_ = _sdf->GetElement("fov")->GetValueDouble();
00105 
00106     if (!_sdf->HasElement("gaussianNoise"))
00107     {
00108         ROS_WARN("Range plugin missing <gaussianNoise>, defaults to 0.0");
00109         this->gaussian_noise_ = 0.0;
00110     }
00111     else
00112         this->gaussian_noise_ = _sdf->GetElement("gaussianNoise")->GetValueDouble();
00113 
00114     ROS_DEBUG("Loaded with values:   robotNamespace = %s, topicName = %s, frameId = %s, radiation = %s, fov = %f, noise = %f",
00115              this->namespace_.c_str(), this->topic_name_.c_str(),this->frame_id_.c_str(),this->radiation_.c_str(),
00116              this->fov_, this->gaussian_noise_);
00117 
00118     node_handle_ = new ros::NodeHandle(this->namespace_);
00119 
00120     range_.header.frame_id = frame_id_;
00121     if (radiation_==std::string("ultrasound"))
00122         range_.radiation_type = sensor_msgs::Range::ULTRASOUND;
00123     else
00124         range_.radiation_type = sensor_msgs::Range::INFRARED;
00125 
00126     range_.field_of_view = fov_;
00127     range_.max_range = sensor_->GetRangeMax();
00128     range_.min_range = sensor_->GetRangeMin();
00129 
00130 
00131     node_handle_ = new ros::NodeHandle(namespace_);
00132     publisher_ = node_handle_->advertise<sensor_msgs::Range>(topic_name_, 1);
00133 
00134     updateConnection = sensor_->GetLaserShape()->ConnectNewLaserScans(boost::bind(&GazeboRosSonar::Update, this));
00135 
00136     // activate RaySensor
00137     sensor_->SetActive(true);
00138 
00139     ROS_DEBUG("%s is active!",frame_id_.c_str());
00140 }
00141 
00142 
00144 // Utility for adding noise
00145 double GazeboRosSonar::GaussianKernel(double mu,double sigma)
00146 {
00147     // using Box-Muller transform to generate two independent standard normally disbributed normal variables
00148     double U = (double)rand()/(double)RAND_MAX;             // normalized uniform random variable
00149     double V = (double)rand()/(double)RAND_MAX;             // normalized uniform random variable
00150     double X = sqrt(-2.0 * ::log(U)) * cos( 2.0*M_PI * V);
00151 
00152     // we'll just use X scale to our mu and sigma
00153     X = sigma * X + mu;
00154     return X;
00155 }
00156 
00157 void GazeboRosSonar::Update()
00158 {
00159     //Activate sensor
00160     if (!sensor_->IsActive())
00161         sensor_->SetActive(true);
00162 
00163     range_.header.stamp.sec  = (parent_->GetSimTime()).sec;
00164     range_.header.stamp.nsec = (parent_->GetSimTime()).nsec;
00165 
00166     // find ray with minimal range
00167     range_.range = std::numeric_limits<sensor_msgs::Range::_range_type>::max();
00168 
00169     int num_ranges = sensor_->GetLaserShape()->GetSampleCount() * sensor_->GetLaserShape()->GetVerticalSampleCount();
00170 
00171     for(int i = 0; i < num_ranges; ++i) {
00172         double ray = sensor_->GetLaserShape()->GetRange(i);
00173         if (ray < range_.range) range_.range = ray;
00174     }
00175 
00176     // add Gaussian noise and limit to min/max range
00177     if (range_.range < range_.max_range)
00178         range_.range = std::min(range_.range + this->GaussianKernel(0,gaussian_noise_), sensor_->GetRangeMax());
00179 
00180     publisher_.publish(range_);
00181 
00182 }
00183 
00184 GZ_REGISTER_SENSOR_PLUGIN(GazeboRosSonar)
00185 


range_gazebo_plugin
Author(s): Jose Capriles
autogenerated on Thu Jan 2 2014 11:37:22