33 std::string inputTopic;
34 GetSDFParam<std::string>(_sdf,
"plume_topic", inputTopic,
"");
35 GZ_ASSERT(!inputTopic.empty(),
"Plume topic for the point cloud is empty!");
37 GetSDFParam<double>(_sdf,
"gamma", this->
gamma, 0.001);
38 GZ_ASSERT(this->gamma > 0,
"Gamma value must be greater than zero");
40 GetSDFParam<double>(_sdf,
"gain", this->
gain, 1.0);
41 GZ_ASSERT(this->gamma > 0,
"Gain value must be greater than zero");
44 GZ_ASSERT(this->smoothingLength > 0,
45 "Radius of the sensor must be greater than zero");
48 std::string salinityTopic;
49 GetSDFParam<std::string>(_sdf,
"salinity_output_topic", salinityTopic,
"salinity");
50 GZ_ASSERT(!salinityTopic.empty(),
"Salinity topic name is empty!");
56 std::string salinityUnit;
57 GetSDFParam<std::string>(_sdf,
"salinity_unit", salinityUnit,
"ppt");
59 GZ_ASSERT(salinityUnit.compare(
"ppt") == 0 ||
60 salinityUnit.compare(
"ppm") == 0 ||
61 salinityUnit.compare(
"psu") == 0,
62 "Invalid salinity unit, it can be ppt, ppm or psu");
66 if (_sdf->HasElement(
"water_salinity_value"))
69 GZ_ASSERT(this->waterSalinityValue > 0,
"Water salinity reference must be a positive value");
73 if (salinityUnit.compare(uuv_sensor_ros_plugins_msgs::Salinity::PPT) == 0)
75 else if (salinityUnit.compare(uuv_sensor_ros_plugins_msgs::Salinity::PPM) == 0)
82 GZ_ASSERT(this->plumeSalinityValue >= 0.0,
83 "Plume salinity value must be greater or equal to zero");
85 "Plume salinity value must be lower than the water salinity value");
101 uuv_sensor_ros_plugins_msgs::ChemicalParticleConcentration>(
105 uuv_sensor_ros_plugins_msgs::Salinity>(salinityTopic, 1);
109 gzmsg <<
"CPCROSPlugin[" << this->
link->GetName()
110 <<
"] initialized!" << std::endl
111 <<
"\t- Input topic= " << inputTopic << std::endl
112 <<
"\t- Output topic= " << this->sensorOutputTopic << std::endl
113 <<
"\t- Salinity output topic= " << salinityTopic << std::endl;
136 this->
outputMsg.header.stamp.sec = _info.simTime.sec;
137 this->
outputMsg.header.stamp.nsec = _info.simTime.nsec;
141 this->
salinityMsg.header.stamp.sec = _info.simTime.sec;
142 this->
salinityMsg.header.stamp.nsec = _info.simTime.nsec;
151 #if GAZEBO_MAJOR_VERSION >= 8 161 const sensor_msgs::PointCloud::ConstPtr &_msg)
167 double totalParticleConc = 0.0;
168 double smoothingParam;
170 double distToParticle;
172 ignition::math::Vector3d linkPos, linkPosRef;
173 #if GAZEBO_MAJOR_VERSION >= 8 174 linkPos = this->
link->WorldPose().Pos();
176 linkPos = this->
link->GetWorldPose().Ign().Pos();
181 linkPosRef = this->
referenceFrame.Rot().RotateVectorReverse(linkPosRef);
186 this->
outputMsg.position.x = linkPosRef.X();
187 this->
outputMsg.position.y = linkPosRef.Y();
188 this->
outputMsg.position.z = linkPosRef.Z();
191 ignition::math::Vector3d cartVec = linkPos;
192 #if GAZEBO_MAJOR_VERSION >= 8 193 ignition::math::Vector3d scVec =
194 this->
link->GetWorld()->SphericalCoords()->SphericalFromLocal(
197 ignition::math::Vector3d scVec =
198 this->
link->GetWorld()->GetSphericalCoordinates()->SphericalFromLocal(
208 double currentTime = _msg->header.stamp.
toSec();
211 ignition::math::Vector3d particle;
212 for (
int i = 0; i < _msg->points.size(); i++)
214 particle = ignition::math::Vector3d(_msg->points[i].x, _msg->points[i].y,
217 smoothingParam = std::pow(initSmoothingLength +
218 this->
gamma * (currentTime - _msg->channels[0].values[i]), 1.5);
219 distToParticle = linkPos.Distance(particle);
222 if (distToParticle >= 0 && distToParticle < smoothingParam)
224 6.0 * std::pow(distToParticle / smoothingParam, 2) +
225 3.0 * std::pow(distToParticle / smoothingParam, 3);
226 else if (distToParticle >= smoothingParam && distToParticle < 2 * smoothingParam)
227 particleConc = std::pow(2 - distToParticle / smoothingParam, 3);
231 particleConc *= 1 / (4 * M_PI * std::pow(smoothingParam, 3));
232 totalParticleConc += particleConc;
235 this->
outputMsg.concentration = this->
gain * totalParticleConc;
bool updatingCloud
Flag to ensure the cloud and measurement update don't coincide.
virtual ~CPCROSPlugin()
Class destructor.
uuv_sensor_ros_plugins_msgs::ChemicalParticleConcentration outputMsg
Output measurement topic.
double GetGaussianNoise(double _amp)
Returns noise value for a function with zero mean from the default Gaussian noise model...
void publish(const boost::shared_ptr< M > &message) const
bool EnableMeasurement(const common::UpdateInfo &_info) const
Enables generation of simulated measurement if the timeout since the last update has been reached...
ignition::math::Pose3d referenceFrame
Pose of the reference frame wrt world frame.
CPCROSPlugin()
Class constructor.
physics::WorldPtr world
Pointer to the world.
ros::Subscriber particlesSub
Input topic for the plume particle point cloud.
common::Time lastMeasurementTime
(Simulation) time when the last sensor measurement was generated.
ros::Time lastUpdateTimestamp
Last update from the point cloud callback.
double waterSalinityValue
double plumeSalinityValue
double noiseAmp
Noise amplitude.
virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
Load the plugin.
virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
Load plugin and its configuration from sdf,.
virtual void OnPlumeParticlesUpdate(const sensor_msgs::PointCloud::ConstPtr &_msg)
Update callback from simulator.
double noiseSigma
Noise standard deviation.
std::string referenceFrameID
Frame ID of the reference frame.
uuv_sensor_ros_plugins_msgs::Salinity salinityMsg
Output salinity measurement message.
physics::LinkPtr link
Pointer to the link.
std::string sensorOutputTopic
Name of the sensor's output topic.
uint32_t getNumSubscribers() const
ros::Publisher rosSensorOutputPub
Gazebo's publisher for transporting measurement messages.
virtual bool OnUpdate(const common::UpdateInfo &_info)
Update sensor measurement.
boost::shared_ptr< ros::NodeHandle > rosNode
ROS node handle for communication with ROS.
ros::Publisher salinityPub
Output topic for salinity measurements based on the particle concentration.
GZ_REGISTER_MODEL_PLUGIN(GazeboRosP3D)
void PublishState()
Publish the current state of the plugin.
double gamma
Gamma velocity parameter for the smoothing function.