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 #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
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
00059 void GazeboRosSonar::Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)
00060 {
00061
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
00070 std::string worldName = sensor_->GetWorldName();
00071 world = physics::get_world(worldName);
00072
00073
00074 namespace_.clear();
00075 topic_ = "sonar";
00076 frame_id_ = "/sonar_link";
00077
00078
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
00098 range_.max_range = sensor_->GetRangeMax();
00099 range_.min_range = sensor_->GetRangeMin();
00100
00101
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
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
00119 updateTimer.setUpdateRate(10.0);
00120 updateTimer.Load(world, _sdf);
00121 updateConnection = updateTimer.Connect(boost::bind(&GazeboRosSonar::Update, this));
00122
00123
00124 sensor_->SetActive(true);
00125 }
00126
00127 void GazeboRosSonar::Reset()
00128 {
00129 updateTimer.Reset();
00130 sensor_model_.reset();
00131 }
00132
00134
00135 void GazeboRosSonar::Update()
00136 {
00137 common::Time sim_time = world->GetSimTime();
00138 double dt = updateTimer.getTimeSinceLastUpdate().Double();
00139
00140
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
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
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
00167 GZ_REGISTER_SENSOR_PLUGIN(GazeboRosSonar)
00168
00169 }