18 #include <gazebo/gazebo.hh> 26 GZ_ASSERT(_link != NULL,
"Invalid link pointer");
51 #if GAZEBO_MAJOR_VERSION >= 8 54 math::Box bBox =
link->GetBoundingBox();
55 this->
boundingBox = ignition::math::Box(bBox.min.x, bBox.min.y, bBox.min.z,
56 bBox.max.x, bBox.max.y, bBox.max.z);
72 #if GAZEBO_MAJOR_VERSION >= 8 73 mass = this->
link->GetInertial()->Mass();
75 mass = this->
link->GetInertial()->GetMass();
78 gzmsg << this->
link->GetName() <<
" is neutrally buoyant" << std::endl;
83 ignition::math::Vector3d &buoyancyForce,
84 ignition::math::Vector3d &buoyancyTorque)
87 double z = _pose.Pos().Z();
90 buoyancyForce = ignition::math::Vector3d(0, 0, 0);
91 buoyancyTorque = ignition::math::Vector3d(0, 0, 0);
94 #if GAZEBO_MAJOR_VERSION >= 8 95 mass = this->
link->GetInertial()->Mass();
97 mass = this->
link->GetInertial()->GetMass();
102 if (z + height / 2 > 0 && z < 0)
105 volume = this->
GetVolume() * (std::fabs(z) + height / 2) / height;
107 else if (z + height / 2 < 0)
114 buoyancyForce = ignition::math::Vector3d(0, 0,
117 buoyancyForce = ignition::math::Vector3d(
118 0, 0, mass * this->g);
130 gzmsg << this->
link->GetName() <<
"::" <<
"waterLevelPlaneArea = " <<
135 double curSubmergedHeight;
137 "Water level plane area must be greater than zero");
139 if (z > height / 2.0) {
141 buoyancyForce = ignition::math::Vector3d(0, 0, 0);
142 buoyancyTorque = ignition::math::Vector3d(0, 0, 0);
144 }
else if (z < -height / 2.0) {
147 curSubmergedHeight = height / 2.0 - z;
151 buoyancyForce = ignition::math::Vector3d(0, 0, volume * this->
fluidDensity * this->
g);
152 buoyancyTorque = ignition::math::Vector3d(
169 ignition::math::Pose3d pose;
170 #if GAZEBO_MAJOR_VERSION >= 8 171 pose = this->
link->WorldPose();
173 pose = this->
link->GetWorldPose().Ign();
176 ignition::math::Vector3d buoyancyForce, buoyancyTorque;
180 GZ_ASSERT(!std::isnan(buoyancyForce.Length()),
181 "Buoyancy force is invalid");
182 GZ_ASSERT(!std::isnan(buoyancyTorque.Length()),
183 "Buoyancy torque is invalid");
185 #if GAZEBO_MAJOR_VERSION >= 8 186 this->
link->AddForceAtRelativePosition(buoyancyForce, this->
GetCoB());
188 this->
link->AddForceAtRelativePosition(
189 math::Vector3(buoyancyForce.X(), buoyancyForce.Y(), buoyancyForce.Z()),
194 #if GAZEBO_MAJOR_VERSION >= 8 195 this->
link->AddForce(buoyancyForce);
196 this->
link->AddRelativeTorque(buoyancyTorque);
198 this->
link->AddForce(
199 math::Vector3(buoyancyForce.X(), buoyancyForce.Y(), buoyancyForce.Z()));
200 this->
link->AddRelativeTorque(
201 math::Vector3(buoyancyTorque.X(), buoyancyTorque.Y(), buoyancyTorque.Z()));
212 gzmsg <<
"New bounding box for " << this->
link->GetName() <<
"::" 219 GZ_ASSERT(_volume > 0,
"Invalid input volume");
232 GZ_ASSERT(_fluidDensity > 0,
"Fluid density must be a positive value");
243 _centerOfBuoyancy.X(), _centerOfBuoyancy.Y(), _centerOfBuoyancy.Z());
252 GZ_ASSERT(_g > 0,
"Acceleration of gravity must be positive");
272 this->
hydroWrench[_tag] = ignition::math::Vector3d(0, 0, 0);
279 return ignition::math::Vector3d(0, 0, 0);
283 return ignition::math::Vector3d(0, 0, 0);
288 ignition::math::Vector3d _vec)
double volume
Volume of fluid displaced by the submerged object.
double submergedHeight
Height of the robot that is submerged (only for surface vessels)
void StoreVector(std::string _tag, ignition::math::Vector3d _vec)
Store vector in the hydroWrench map if the field has been created.
bool IsNeutrallyBuoyant()
Returns true if the link was set to be neutrally buoyant.
Description of a buoyant object.
void SetDebugFlag(bool _debugOn=true)
Set debug flag to store intermediate forces and torques.
bool debugFlag
Debug flag, storing all intermediate forces and torques.
ignition::math::Box boundingBox
TEMP for calculation of the buoyancy force close to the surface.
void SetNeutrallyBuoyant()
Sets this link as neutrally buoyant.
std::map< std::string, ignition::math::Vector3d > hydroWrench
Storage for hydrodynamic and hydrostatic forces and torques for debugging purposes.
ignition::math::Vector3d GetStoredVector(std::string _tag)
Get vector from the hydroWrench map.
void SetCoB(const ignition::math::Vector3d &_centerOfBuoyancy)
Sets the position of the center of buoyancy on the body frame.
double GetGravity()
Get stored acceleration of gravity.
bool neutrallyBuoyant
If true, the restoring force will be equal to the gravitational.
double offsetVolume
Offset for the volume.
double g
Acceleration of gravity.
double waterLevelPlaneArea
If the cross section area around water level of the surface vessel is not given, it will be computed ...
bool GetDebugFlag()
Returns the debug flag.
void SetBoundingBox(const ignition::math::Box &_bBox)
Sets bounding box.
bool isSubmerged
Is submerged flag.
void SetFluidDensity(double _fluidDensity)
Sets the fluid density in kg/m^3.
void ApplyBuoyancyForce()
Applies buoyancy force on link.
double GetVolume()
Returns the stored link submerged volume.
~BuoyantObject()
Destructor.
bool isSurfaceVessel
Flag set to true if the information about the metacentric width and height is available.
void SetVolume(double _volume=-1)
Sets the link's submerged volume.
void SetStoreVector(std::string _tag)
Adds a field in the hydroWrench map.
BuoyantObject(physics::LinkPtr _link)
Constructor.
void SetGravity(double _g)
Set acceleration of gravity.
double fluidDensity
Fluid density.
ignition::math::Vector3d centerOfBuoyancy
Center of buoyancy in the body frame.
ignition::math::Vector3d GetCoB()
Returns the stored center of buoyancy.
void GetBuoyancyForce(const ignition::math::Pose3d &_pose, ignition::math::Vector3d &buoyancyForce, ignition::math::Vector3d &buoyancyTorque)
Returns the buoyancy force vector in the world frame.
double metacentricLength
Metacentric length of the robot, used only for surface vessels and floating objects.
double GetFluidDensity()
Returns the stored fluid density.
physics::LinkPtr link
Pointer to the correspondent robot link.
double scalingVolume
Scaling factor for the volume.
bool isSurfaceVesselFloating
Flag set to true if the vessel has reached its submerged height.
bool IsSubmerged()
Returns true if the robot is completely submerged.