im_gazebo_ros_sonar.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include <plugins/im_gazebo_ros_sonar.h>
00030 #include <gazebo/common/Events.hh>
00031 #include <gazebo/physics/physics.hh>
00032 #include <gazebo/sensors/RaySensor.hh>
00033 
00034 #include <tf/tf.h>
00035 
00036 #include <limits>
00037 
00038 namespace gazebo {
00039 
00040 GazeboRosSonar::GazeboRosSonar()
00041 {
00042 }
00043 
00045 // Destructor
00046 GazeboRosSonar::~GazeboRosSonar()
00047 {
00048   updateTimer.Disconnect(updateConnection);
00049   sensor_->SetActive(false);
00050 
00051   dynamic_reconfigure_server_.reset();
00052 
00053   node_handle_->shutdown();
00054   delete node_handle_;
00055 }
00056 
00058 // Load the controller
00059 void GazeboRosSonar::Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)
00060 {
00061   // Get then name of the parent sensor
00062   sensor_ = boost::dynamic_pointer_cast<sensors::RaySensor>(_sensor);
00063   if (!sensor_)
00064   {
00065     gzthrow("GazeboRosSonar requires a Ray Sensor as its parent");
00066     return;
00067   }
00068 
00069   // Get the world name.
00070   std::string worldName = sensor_->GetWorldName();
00071   world = physics::get_world(worldName);
00072 
00073   // default parameters
00074   namespace_.clear();
00075   topic_ = "sonar";
00076   frame_id_ = "/sonar_link";
00077 
00078   // load parameters
00079   if (_sdf->HasElement("robotNamespace"))
00080     namespace_ = _sdf->GetElement("robotNamespace")->GetValue()->GetAsString();
00081 
00082   if (_sdf->HasElement("frameId"))
00083     frame_id_ = _sdf->GetElement("frameId")->GetValue()->GetAsString();
00084 
00085   if (_sdf->HasElement("topicName"))
00086     topic_ = _sdf->GetElement("topicName")->GetValue()->GetAsString();
00087 
00088   if (_sdf->HasElement("fov"))
00089      d_field_of_view = _sdf->GetElement("fov")->Get<double>();
00090   sensor_model_.Load(_sdf);
00091 
00092         this->frame_id_ = tf::resolve(this->namespace_, this->frame_id_);
00093         
00094   range_.header.frame_id = this->frame_id_;
00095   range_.radiation_type = sensor_msgs::Range::ULTRASOUND;
00096   range_.field_of_view = d_field_of_view;
00097 //std::min(fabs((sensor_->GetAngleMax() - sensor_->GetAngleMin()).Radian()), fabs((sensor_->GetVerticalAngleMax() - sensor_->GetVerticalAngleMin()).Radian()));
00098   range_.max_range = sensor_->GetRangeMax();
00099   range_.min_range = sensor_->GetRangeMin();
00100 
00101   // Make sure the ROS node for Gazebo has already been initialized
00102   if (!ros::isInitialized())
00103   {
00104     ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. "
00105       << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
00106     return;
00107   }
00108 
00109   node_handle_ = new ros::NodeHandle(namespace_);
00110   publisher_ = node_handle_->advertise<sensor_msgs::Range>(topic_, 1);
00111 
00112   // setup dynamic_reconfigure server
00113   dynamic_reconfigure_server_.reset(new dynamic_reconfigure::Server<SensorModelConfig>(ros::NodeHandle(*node_handle_, topic_)));
00114   dynamic_reconfigure_server_->setCallback(boost::bind(&SensorModel::dynamicReconfigureCallback, &sensor_model_, _1, _2));
00115 
00116   Reset();
00117 
00118   // connect Update function
00119   updateTimer.setUpdateRate(10.0);
00120   updateTimer.Load(world, _sdf);
00121   updateConnection = updateTimer.Connect(boost::bind(&GazeboRosSonar::Update, this));
00122 
00123   // activate RaySensor
00124   sensor_->SetActive(true);
00125 }
00126 
00127 void GazeboRosSonar::Reset()
00128 {
00129   updateTimer.Reset();
00130   sensor_model_.reset();
00131 }
00132 
00134 // Update the controller
00135 void GazeboRosSonar::Update()
00136 {
00137   common::Time sim_time = world->GetSimTime();
00138   double dt = updateTimer.getTimeSinceLastUpdate().Double();
00139 
00140   // activate RaySensor if it is not yet active
00141   if (!sensor_->IsActive()) sensor_->SetActive(true);
00142 
00143   range_.header.stamp.sec  = (world->GetSimTime()).sec;
00144   range_.header.stamp.nsec = (world->GetSimTime()).nsec;
00145 
00146   // find ray with minimal range
00147   range_.range = std::numeric_limits<sensor_msgs::Range::_range_type>::max();
00148   int num_ranges = sensor_->GetLaserShape()->GetSampleCount() * sensor_->GetLaserShape()->GetVerticalSampleCount();
00149   for(int i = 0; i < num_ranges; ++i) 
00150   {
00151     double ray = sensor_->GetLaserShape()->GetRange(i);
00152     if (ray < range_.range) range_.range = ray;
00153   }
00154 
00155   // add Gaussian noise (and limit to min/max range)
00156   if (range_.range < range_.max_range) 
00157   {
00158     range_.range = sensor_model_(range_.range, dt);
00159     if (range_.range < range_.min_range) range_.range = range_.min_range;
00160     if (range_.range > range_.max_range) range_.range = range_.max_range;
00161   }
00162 
00163   publisher_.publish(range_);
00164 }
00165 
00166 // Register this plugin with the simulator
00167 GZ_REGISTER_SENSOR_PLUGIN(GazeboRosSonar)
00168 
00169 } // namespace gazebo


evarobot_gazebo
Author(s): Mehmet Akcakoca
autogenerated on Thu Jun 6 2019 18:18:10