Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
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
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
00137 sensor_->SetActive(true);
00138
00139 ROS_DEBUG("%s is active!",frame_id_.c_str());
00140 }
00141
00142
00144
00145 double GazeboRosSonar::GaussianKernel(double mu,double sigma)
00146 {
00147
00148 double U = (double)rand()/(double)RAND_MAX;
00149 double V = (double)rand()/(double)RAND_MAX;
00150 double X = sqrt(-2.0 * ::log(U)) * cos( 2.0*M_PI * V);
00151
00152
00153 X = sigma * X + mu;
00154 return X;
00155 }
00156
00157 void GazeboRosSonar::Update()
00158 {
00159
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
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
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