46 #include <usv_msgs/RangeBearing.h> 48 #include <ignition/math/Pose3.hh> 70 this->
model = _parent;
73 GZ_ASSERT(_parent !=
nullptr,
"Received NULL model pointer");
79 " Gazebo hasn't been initialised, unable to load plugin. Load the Gazebo " 80 "system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
86 std::string modelName = _parent->GetName();
87 auto delim = modelName.find(
":");
88 if (delim != std::string::npos)
89 modelName = modelName.substr(0, delim);
92 std::string ns = modelName;
93 if (_sdf->HasElement(
"robotNamespace"))
94 ns = _sdf->GetElement(
"robotNamespace")->Get<std::string>();
98 "missing <robotNamespace>, defaulting to %s", ns.c_str());
103 if (_sdf->HasElement(
"frameId"))
104 this->frameId = _sdf->GetElement(
"frameId")->Get<std::string>();
107 std::string topicName =
"/pinger/range_bearing";
108 if (_sdf->HasElement(
"topicName"))
109 topicName = _sdf->GetElement(
"topicName")->Get<std::string>();
113 "missing <topicName>, defaulting to %s", topicName.c_str());
117 std::string setPositionTopicName =
"/pinger/set_pinger_position";
118 if (_sdf->HasElement(
"setPositionTopicName"))
120 setPositionTopicName =
121 _sdf->GetElement(
"setPositionTopicName")->Get<std::string>();
126 "missing <setPositionTopicName>, defaulting to %s", topicName.c_str());
130 this->
position = ignition::math::Vector3d::Zero;
131 if (_sdf->HasElement(
"position"))
132 this->position = _sdf->Get<ignition::math::Vector3d>(
"position");
136 if (_sdf->HasElement(
"updateRate"))
137 this->
updateRate = _sdf->Get<
float>(
"updateRate");
141 if (_sdf->HasElement(
"rangeNoise"))
143 sdf::ElementPtr rangeNoiseElem = _sdf->GetElement(
"rangeNoise");
146 if (rangeNoiseElem->HasElement(
"noise"))
148 this->
rangeNoise = sensors::NoiseFactory::NewNoiseModel(
149 rangeNoiseElem->GetElement(
"noise"));
153 ROS_WARN(
"usv_gazebo_acoustic_pinger_plugin: " 154 "The rangeNoise SDF element must contain noise tag");
159 ROS_INFO(
"usv_gazebo_acoustic_pinger_plugin: " 160 "No rangeNoise tag found, no noise added to measurements");
164 if (_sdf->HasElement(
"bearingNoise"))
166 sdf::ElementPtr bearingNoiseElem = _sdf->GetElement(
"bearingNoise");
169 if (bearingNoiseElem->HasElement(
"noise"))
171 this->
bearingNoise = sensors::NoiseFactory::NewNoiseModel(
172 bearingNoiseElem->GetElement(
"noise"));
176 ROS_WARN(
"usv_gazebo_acoustic_pinger_plugin: " 177 "The bearingNoise SDF element must contain noise tag");
182 ROS_INFO(
"usv_gazebo_acoustic_pinger_plugin: " 183 "No bearingNoise tag found, no noise added to measurements");
186 if (_sdf->HasElement(
"elevationNoise"))
188 sdf::ElementPtr elevationNoiseElem = _sdf->GetElement(
"elevationNoise");
191 if (elevationNoiseElem->HasElement(
"noise"))
194 elevationNoiseElem->GetElement(
"noise"));
198 ROS_WARN(
"usv_gazebo_acoustic_pinger_plugin: " 199 "The elevationNoise SDF element must contain noise tag");
204 ROS_INFO(
"usv_gazebo_acoustic_pinger_plugin: " 205 "No elevationNoise tag found, no noise added to measurements");
214 std::string(topicName), 1);
220 #if GAZEBO_MAJOR_VERSION >= 8 235 #if GAZEBO_MAJOR_VERSION >= 8 244 std::lock_guard<std::mutex> lock(this->
mutex);
246 #if GAZEBO_MAJOR_VERSION >= 8 249 ignition::math::Pose3d modelPose = this->
model->WorldPose();
253 ignition::math::Pose3d modelPose = this->
model->GetWorldPose().Ign();
257 ignition::math::Vector3d direction = this->
position - modelPose.Pos();
261 ignition::math::Vector3d directionSensorFrame =
262 modelPose.Rot().RotateVectorReverse(direction);
265 ignition::math::Vector3d directionSensorFrame2d =
266 ignition::math::Vector3d(
267 directionSensorFrame.X(), directionSensorFrame.Y(), 0);
274 double bearing = atan2(directionSensorFrame.Y(), directionSensorFrame.X());
275 double range = directionSensorFrame.Length();
277 atan2(directionSensorFrame.Z(), directionSensorFrame2d.Length());
289 usv_msgs::RangeBearing msg;
292 this->lastUpdateTime.nsec);
295 msg.header.frame_id = this->
frameId;
298 msg.bearing = bearing;
299 msg.elevation = elevation;
308 const geometry_msgs::Vector3ConstPtr &_pos)
311 std::lock_guard<std::mutex> lock(this->
mutex);
312 this->
position = ignition::math::Vector3d(_pos->x, _pos->y, _pos->z);
physics::ModelPtr model
Pointer to model object.
ros::Subscriber setPositionSub
Subscribes to the topic that set the pinger position.
float updateRate
Sensor update rate.
#define ROS_INFO_NAMED(name,...)
event::ConnectionPtr updateConnection
Pointer used to connect gazebo callback to plugins update function.
virtual void Update()
Callback used by gazebo to update the plugin.
GZ_REGISTER_MODEL_PLUGIN(AcousticPinger)
AcousticPinger()
Constructor.
ROSCPP_DECL bool isInitialized()
gazebo::sensors::NoisePtr rangeNoise
rangeNoise - Gazebo noise object for range.
gazebo::sensors::NoisePtr elevationNoise
Gazebo noise object for elevation angle.
std::mutex mutex
Mutex to protect the position vector.
#define ROS_DEBUG_NAMED(name,...)
common::Time lastUpdateTime
Variable used to track time of last update. This is used to produce data at the correct rate...
virtual ~AcousticPinger()
Destructor.
void publish(const boost::shared_ptr< M > &message) const
#define ROS_FATAL_STREAM_NAMED(name, args)
Implements a simulated range and bearing pinger localisation system.
ros::Publisher rangeBearingPub
Publisher used to send sensor messages generated by the plugin.
void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
std::string frameId
String holding the frame id of the sensor.
ignition::math::Vector3d position
Vector storing the position of the pinger.
std::unique_ptr< ros::NodeHandle > rosNodeHandle
Nodehandle used to integrate with the ROS system.
gazebo::sensors::NoisePtr bearingNoise
Gazebo noise object for bearing angle.
void PingerPositionCallback(const geometry_msgs::Vector3ConstPtr &_pos)
Callback function called when receiving a new pinger position via the pinger subscription callback...