$search
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 <gazebo/Sensor.hh> 00036 #include <gazebo/Global.hh> 00037 #include <gazebo/XMLConfig.hh> 00038 #include <gazebo/Simulator.hh> 00039 #include <gazebo/gazebo.h> 00040 #include <gazebo/GazeboError.hh> 00041 #include <gazebo/ControllerFactory.hh> 00042 #include <limits> 00043 #include <range_gazebo_plugin/gazebo_ros_sonar.h> 00044 00045 using namespace gazebo; 00046 00047 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_sonar", GazeboRosSonar) 00048 00049 GazeboRosSonar::GazeboRosSonar(Entity *parent) : Controller(parent) 00050 { 00051 sensor_ = dynamic_cast<RaySensor*>(parent); 00052 if (!sensor_) gzthrow("GazeboRosSonar controller requires a RaySensor as its parent"); 00053 00054 Param::Begin(¶meters); 00055 topic_param_ = new ParamT<std::string>("topicName", "sonar", false); 00056 frame_id_param_ = new ParamT<std::string>("frameId", "", false); 00057 radiation_param_ = new ParamT<std::string>("radiation","ultrasound",false); 00058 fov_param_ = new ParamT<double>("fov", 0.05, false); 00059 gaussian_noise_ = new ParamT<double>("gaussianNoise", 0.0, 0); 00060 Param::End(); 00061 } 00062 00064 // Destructor 00065 GazeboRosSonar::~GazeboRosSonar() 00066 { 00067 delete topic_param_; 00068 delete frame_id_param_; 00069 delete radiation_param_; 00070 delete fov_param_; 00071 } 00072 00074 // Load the controller 00075 void GazeboRosSonar::LoadChild(XMLConfigNode *node) 00076 { 00077 ROS_INFO("INFO: gazebo_ros_ir plugin loading" ); 00078 topic_param_->Load(node); 00079 frame_id_param_->Load(node); 00080 radiation_param_->Load(node); 00081 fov_param_->Load(node); 00082 gaussian_noise_->Load(node); 00083 } 00084 00086 // Initialize the controller 00087 void GazeboRosSonar::InitChild() 00088 { 00089 Range.header.frame_id = **frame_id_param_; 00090 00091 if (**radiation_param_==std::string("ultrasound")) 00092 Range.radiation_type = sensor_msgs::Range::ULTRASOUND; 00093 else 00094 Range.radiation_type = sensor_msgs::Range::INFRARED; 00095 00096 Range.field_of_view = **fov_param_; 00097 Range.max_range = sensor_->GetMaxRange(); 00098 Range.min_range = sensor_->GetMinRange(); 00099 00100 sensor_->SetActive(false); 00101 node_handle_ = new ros::NodeHandle(""); 00102 publisher_ = node_handle_->advertise<sensor_msgs::Range>(**topic_param_, 10); 00103 } 00104 00106 // Utility for adding noise 00107 double GazeboRosSonar::GaussianKernel(double mu,double sigma) 00108 { 00109 // using Box-Muller transform to generate two independent standard normally disbributed normal variables 00110 // see wikipedia 00111 double U = (double)rand()/(double)RAND_MAX; // normalized uniform random variable 00112 double V = (double)rand()/(double)RAND_MAX; // normalized uniform random variable 00113 double X = sqrt(-2.0 * ::log(U)) * cos( 2.0*M_PI * V); 00114 //double Y = sqrt(-2.0 * ::log(U)) * sin( 2.0*M_PI * V); // the other indep. normal variable 00115 // we'll just use X 00116 // scale to our mu and sigma 00117 X = sigma * X + mu; 00118 return X; 00119 } 00120 00122 // Update the controller 00123 void GazeboRosSonar::UpdateChild() 00124 { 00125 if (!sensor_->IsActive()) sensor_->SetActive(true); 00126 00127 Range.header.stamp.sec = (Simulator::Instance()->GetSimTime()).sec; 00128 Range.header.stamp.nsec = (Simulator::Instance()->GetSimTime()).nsec; 00129 Range.range = std::numeric_limits<sensor_msgs::Range::_range_type>::max(); 00130 00131 for(int i = 0; i < sensor_->GetRangeCount(); ++i) { 00132 double ray = sensor_->GetRange(i); 00133 if (ray < Range.range) Range.range = ray; 00134 } 00135 00136 Range.range = std::min(Range.range + this->GaussianKernel(0,**gaussian_noise_), sensor_->GetMaxRange()); 00137 publisher_.publish(Range); 00138 } 00139 00141 // Finalize the controller 00142 void GazeboRosSonar::FiniChild() 00143 { 00144 sensor_->SetActive(false); 00145 node_handle_->shutdown(); 00146 delete node_handle_; 00147 } 00148