16 #include <gazebo/gazebo.hh> 25 GZ_ASSERT(_link != NULL,
"Invalid link pointer");
32 if (_sdf->HasElement(
"volume"))
33 this->
volume = _sdf->Get<
double>(
"volume");
38 if (_sdf->HasElement(
"metacentric_width") &&
39 _sdf->HasElement(
"metacentric_length") &&
40 _sdf->HasElement(
"submerged_height"))
47 gzmsg <<
"Surface vessel parameters" << std::endl;
49 gzmsg <<
"\tMetacentric length [m]=" << this->metacentricLength << std::endl;
50 gzmsg <<
"\tSubmerged height [m]=" << this->submergedHeight << std::endl;
61 std::vector<double> cob = {0, 0, 0};
62 if (_sdf->HasElement(
"center_of_buoyancy"))
64 cob =
Str2Vector(_sdf->Get<std::string>(
"center_of_buoyancy"));
65 this->
SetCoB(ignition::math::Vector3d(cob[0], cob[1], cob[2]));
69 if (_sdf->HasElement(
"box"))
71 sdf::ElementPtr sdfModel = _sdf->GetElement(
"box");
72 if (sdfModel->HasElement(
"width") && sdfModel->HasElement(
"length") &&
73 sdfModel->HasElement(
"height"))
75 double width = sdfModel->Get<
double>(
"width");
76 double length = sdfModel->Get<
double>(
"length");
77 double height = sdfModel->Get<
double>(
"height");
78 ignition::math::Box
boundingBox = ignition::math::Box(
79 ignition::math::Vector3d(-width / 2, -length / 2, -height / 2),
80 ignition::math::Vector3d(width / 2, length / 2, height / 2));
88 if (_sdf->HasElement(
"neutrally_buoyant"))
90 if (_sdf->Get<
bool>(
"neutrally_buoyant"))
130 ignition::math::Vector3d output = _vec;
131 output.Y() = -1 * output.Y();
132 output.Z() = -1 * output.Z();
139 return this->
ToNED(_vec);
145 if (this->
params.empty())
return true;
147 for (
auto tag : this->
params)
149 if (!_sdf->HasElement(tag))
151 gzerr <<
"Hydrodynamic model: Expected element " <<
162 sdf::ElementPtr _sdf, physics::LinkPtr _link)
164 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
165 "Hydrodynamic model is missing");
166 sdf::ElementPtr sdfModel = _sdf->GetElement(
"hydrodynamic_model");
167 if (!sdfModel->HasElement(
"type"))
169 std::cerr <<
"Model has no type" << std::endl;
173 std::string identifier = sdfModel->Get<std::string>(
"type");
175 if (creators_.find(identifier) == creators_.end())
177 std::cerr <<
"Cannot create HydrodynamicModel with unknown identifier: " 178 << identifier << std::endl;
182 return creators_[identifier](_sdf, _link);
196 if (creators_.find(_identifier) != creators_.end())
198 std::cerr <<
"Warning: Registering HydrodynamicModel with identifier: " 199 << _identifier <<
" twice" << std::endl;
201 creators_[_identifier] = _creator;
203 std::cout <<
"Registered HydrodynamicModel type " << _identifier << std::endl;
217 physics::LinkPtr _link)
224 physics::LinkPtr _link)
227 std::vector<double> addedMass(36, 0.0);
228 std::vector<double> linDampCoef(6, 0.0);
229 std::vector<double> linDampForward(6, 0.0);
232 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
233 "Hydrodynamic model is missing");
235 sdf::ElementPtr modelParams = _sdf->GetElement(
"hydrodynamic_model");
238 if (modelParams->HasElement(
"added_mass"))
239 addedMass =
Str2Vector(modelParams->Get<std::string>(
"added_mass"));
241 gzmsg <<
"HMFossen: Using added mass NULL" << std::endl;
243 this->
params.push_back(
"added_mass");
247 if (modelParams->HasElement(
"linear_damping"))
248 linDampCoef =
Str2Vector(modelParams->Get<std::string>(
"linear_damping"));
250 gzmsg <<
"HMFossen: Using linear damping NULL" << std::endl;
253 this->
params.push_back(
"scaling_added_mass");
257 this->
params.push_back(
"offset_added_mass");
262 this->
params.push_back(
"linear_damping");
267 if (modelParams->HasElement(
"linear_damping_forward_speed"))
269 modelParams->Get<std::string>(
"linear_damping_forward_speed"));
271 gzmsg <<
"HMFossen: Using linear damping for forward speed NULL" 275 this->
params.push_back(
"linear_damping_forward_speed");
279 if (modelParams->HasElement(
"quadratic_damping"))
281 modelParams->Get<std::string>(
"quadratic_damping"));
283 gzmsg <<
"HMFossen: Using quad damping NULL" << std::endl;
286 this->
params.push_back(
"quadratic_damping");
288 this->
params.push_back(
"scaling_damping");
293 this->
params.push_back(
"offset_linear_damping");
298 this->
params.push_back(
"offset_lin_forward_speed_damping");
303 this->
params.push_back(
"offset_nonlin_damping");
308 this->
params.push_back(
"volume");
310 this->
params.push_back(
"scaling_volume");
312 GZ_ASSERT(addedMass.size() == 36,
313 "Added-mass coefficients vector must have 36 elements");
314 GZ_ASSERT(linDampCoef.size() == 6 || linDampCoef.size() == 36,
315 "Linear damping coefficients vector must have 6 elements for a " 316 "diagonal matrix or 36 elements for a full matrix");
317 GZ_ASSERT(linDampForward.size() == 6 || linDampForward.size() == 36,
318 "Linear damping coefficients proportional to the forward speed " 319 "vector must have 6 elements for a diagonal matrix or 36 elements" 320 " for a full matrix");
321 GZ_ASSERT(quadDampCoef.size() == 6 || quadDampCoef.size() == 36,
322 "Quadratic damping coefficients vector must have 6 elements for a " 323 "diagonal matrix or 36 elements for a full matrix");
325 this->
DLin.setZero();
329 for (
int row = 0; row < 6; row++)
330 for (
int col = 0; col < 6; col++)
333 this->
Ma(row, col) = addedMass[6*row+col];
335 if (linDampCoef.size() == 36)
336 this->
DLin(row, col) = linDampCoef[6*row+col];
337 if (quadDampCoef.size() == 36)
338 this->
DNonLin(row, col) = quadDampCoef[6*row+col];
339 if (linDampForward.size() == 36)
344 for (
int i = 0; i < 6; i++)
346 if (linDampCoef.size() == 6)
347 this->
DLin(i, i) = linDampCoef[i];
348 if (quadDampCoef.size() == 6)
349 this->
DNonLin(i, i) = quadDampCoef[i];
350 if (linDampForward.size() == 6)
361 double _time,
const ignition::math::Vector3d &_flowVelWorld)
364 ignition::math::Pose3d pose;
365 ignition::math::Vector3d linVel, angVel;
367 #if GAZEBO_MAJOR_VERSION >= 8 368 pose = this->
link->WorldPose();
369 linVel = this->
link->RelativeLinearVel();
370 angVel = this->
link->RelativeAngularVel();
372 pose = this->
link->GetWorldPose().Ign();
374 gazebo::math::Vector3 linVelG, angVelG;
375 linVelG = this->
link->GetRelativeLinearVel();
376 angVelG = this->
link->GetRelativeAngularVel();
377 linVel = ignition::math::Vector3d(
378 linVelG.x, linVelG.y, linVelG.z);
379 angVel = ignition::math::Vector3d(
380 angVelG.x, angVelG.y, angVelG.z);
384 ignition::math::Vector3d flowVel = pose.Rot().RotateVectorReverse(
390 this->
ToNED(linVel - flowVel),
391 this->
ToNED(angVel));
417 GZ_ASSERT(!std::isnan(tau.norm()),
"Hydrodynamic forces vector is nan");
419 if (!std::isnan(tau.norm()))
422 ignition::math::Vector3d hydForce =
424 ignition::math::Vector3d hydTorque =
428 this->
link->AddRelativeForce(hydForce);
429 this->
link->AddRelativeTorque(hydTorque);
458 _Ca << Eigen::Matrix3d::Zero(), Sa,
480 for (
int i = 0; i < 6; i++)
499 _output = std::vector<double>();
500 if (!_tag.compare(
"added_mass"))
502 for (
int i = 0; i < 6; i++)
503 for (
int j = 0; j < 6; j++)
504 _output.push_back(this->Ma(i, j));
506 else if (!_tag.compare(
"linear_damping"))
508 for (
int i = 0; i < 6; i++)
509 for (
int j = 0; j < 6; j++)
510 _output.push_back(this->DLin(i, j));
512 else if (!_tag.compare(
"linear_damping_forward_speed"))
514 for (
int i = 0; i < 6; i++)
515 for (
int j = 0; j < 6; j++)
516 _output.push_back(this->DLinForwardSpeed(i, j));
518 else if (!_tag.compare(
"quadratic_damping"))
520 for (
int i = 0; i < 6; i++)
521 for (
int j = 0; j < 6; j++)
522 _output.push_back(this->DNonLin(i, j));
524 else if (!_tag.compare(
"center_of_buoyancy"))
532 gzmsg <<
"HydrodynamicModel::GetParam <" << _tag <<
">=" << std::endl;
533 for (
auto elem : _output)
534 std::cout << elem <<
" ";
535 std::cout << std::endl;
543 if (!_tag.compare(
"volume"))
545 else if (!_tag.compare(
"scaling_volume"))
547 else if (!_tag.compare(
"scaling_added_mass"))
549 else if (!_tag.compare(
"scaling_damping"))
551 else if (!_tag.compare(
"fluid_density"))
553 else if (!_tag.compare(
"bbox_height"))
555 else if (!_tag.compare(
"bbox_width"))
557 else if (!_tag.compare(
"bbox_length"))
559 else if (!_tag.compare(
"offset_volume"))
561 else if (!_tag.compare(
"offset_added_mass"))
563 else if (!_tag.compare(
"offset_linear_damping"))
565 else if (!_tag.compare(
"offset_lin_forward_speed_damping"))
567 else if (!_tag.compare(
"offset_nonlin_damping"))
575 gzmsg <<
"HydrodynamicModel::GetParam <" << _tag <<
">=" << _output <<
583 if (!_tag.compare(
"scaling_volume"))
589 else if (!_tag.compare(
"scaling_added_mass"))
595 else if (!_tag.compare(
"scaling_damping"))
601 else if (!_tag.compare(
"fluid_density"))
607 else if (!_tag.compare(
"offset_volume"))
609 else if (!_tag.compare(
"offset_added_mass"))
611 else if (!_tag.compare(
"offset_linear_damping"))
613 else if (!_tag.compare(
"offset_lin_forward_speed_damping"))
615 else if (!_tag.compare(
"offset_nonlin_damping"))
619 gzmsg <<
"HydrodynamicModel::SetParam <" << _tag <<
">=" << _input <<
627 if (!_paramName.compare(
"all"))
629 for (
auto tag : this->
params)
633 if (!_message.empty())
634 std::cout << _message << std::endl;
636 std::cout << this->
link->GetModel()->GetName() <<
"::" 637 << this->
link->GetName() <<
"::" << _paramName
639 if (!_paramName.compare(
"added_mass"))
641 for (
int i = 0; i < 6; i++)
643 for (
int j = 0; j < 6; j++)
644 std::cout << std::setw(12) << this->
Ma(i, j);
645 std::cout << std::endl;
648 else if (!_paramName.compare(
"linear_damping"))
650 for (
int i = 0; i < 6; i++)
652 for (
int j = 0; j < 6; j++)
653 std::cout << std::setw(12) << this->
DLin(i, j);
654 std::cout << std::endl;
657 else if (!_paramName.compare(
"linear_damping_forward_speed"))
659 for (
int i = 0; i < 6; i++)
661 for (
int j = 0; j < 6; j++)
663 std::cout << std::endl;
666 else if (!_paramName.compare(
"quadratic_damping"))
668 for (
int i = 0; i < 6; i++)
670 for (
int j = 0; j < 6; j++)
671 std::cout << std::setw(12) << this->
DNonLin(i, j);
672 std::cout << std::endl;
675 else if (!_paramName.compare(
"volume"))
677 std::cout << std::setw(12) << this->
volume <<
" m^3" << std::endl;
691 physics::LinkPtr _link)
698 physics::LinkPtr _link)
701 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
702 "Hydrodynamic model is missing");
704 sdf::ElementPtr modelParams = _sdf->GetElement(
"hydrodynamic_model");
706 if (modelParams->HasElement(
"radius"))
707 this->
radius = modelParams->Get<
double>(
"radius");
710 gzmsg <<
"HMSphere: Using the smallest length of bounding box as radius" 716 gzmsg <<
"HMSphere::radius=" << this->
radius << std::endl;
717 gzmsg <<
"HMSphere: Computing added mass" << std::endl;
719 this->
params.push_back(
"radius");
739 std::pow(this->
radius, 3.0);
743 for (
int i = 0; i < 3; i++)
746 this->
Ma(i, i) = -sphereMa;
755 if (!_paramName.compare(
"all"))
757 for (
auto tag : this->
params)
761 if (!_message.empty())
762 std::cout << _message << std::endl;
764 std::cout << this->
link->GetModel()->GetName() <<
"::" 765 << this->
link->GetName() <<
"::" << _paramName
767 if (!_paramName.compare(
"radius"))
768 std::cout << std::setw(12) << this->
radius << std::endl;
783 physics::LinkPtr _link)
790 physics::LinkPtr _link)
793 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
794 "Hydrodynamic model is missing");
796 sdf::ElementPtr modelParams = _sdf->GetElement(
"hydrodynamic_model");
798 if (modelParams->HasElement(
"radius"))
799 this->
radius = modelParams->Get<
double>(
"radius");
802 gzmsg <<
"HMCylinder: Using the smallest length of bounding box as radius" 808 gzmsg <<
"HMCylinder::radius=" << this->
radius << std::endl;
810 if (modelParams->HasElement(
"length"))
811 this->
length = modelParams->Get<
double>(
"length");
814 gzmsg <<
"HMCylinder: Using the biggest length of bounding box as length" 820 gzmsg <<
"HMCylinder::length=" << this->
length << std::endl;
824 gzmsg <<
"HMCylinder::dimension_ratio=" << this->
dimRatio << std::endl;
842 if (modelParams->HasElement(
"axis"))
844 this->
axis = modelParams->Get<std::string>(
"axis");
845 GZ_ASSERT(this->
axis.compare(
"i") == 0 ||
846 this->
axis.compare(
"j") == 0 ||
847 this->
axis.compare(
"k") == 0,
"Invalid axis of rotation");
851 gzmsg <<
"HMCylinder: Using the direction of biggest length as axis" 853 double maxLength = std::max(this->
boundingBox.XLength(),
863 gzmsg <<
"HMCylinder::rotation_axis=" << this->
axis << std::endl;
877 * std::pow(this->
radius, 2.0) * std::pow(this->length, 3.0);
881 double DCirc = -0.5 * this->
cdCirc *
PI * std::pow(this->
radius, 2.0) \
883 double DLength = -0.5 * this->
cdLength * this->
radius * this->length \
886 if (this->
axis.compare(
"i") == 0)
888 this->
Ma(0, 0) = -MaCirc;
889 this->
Ma(1, 1) = -MaLength;
890 this->
Ma(2, 2) = -MaLength;
892 this->
Ma(4, 4) = -MaLengthTorque;
893 this->
Ma(5, 5) = -MaLengthTorque;
899 else if (this->
axis.compare(
"j") == 0)
901 this->
Ma(0, 0) = -MaLength;
902 this->
Ma(1, 1) = -MaCirc;
903 this->
Ma(2, 2) = -MaLength;
905 this->
Ma(3, 3) = -MaLengthTorque;
906 this->
Ma(5, 5) = -MaLengthTorque;
914 this->
Ma(0, 0) = -MaLength;
915 this->
Ma(1, 1) = -MaLength;
916 this->
Ma(2, 2) = -MaCirc;
918 this->
Ma(3, 3) = -MaLengthTorque;
919 this->
Ma(4, 4) = -MaLengthTorque;
930 if (!_paramName.compare(
"radius"))
932 if (!_message.empty())
933 gzmsg << this->
link->GetName() << std::endl;
934 std::cout << std::setw(12) << this->
radius << std::endl;
936 else if (!_paramName.compare(
"length"))
938 if (!_message.empty())
939 gzmsg << _message << std::endl;
940 std::cout << std::setw(12) << this->
length << std::endl;
955 physics::LinkPtr _link)
962 physics::LinkPtr _link)
965 gzerr <<
"Hydrodynamic model for a spheroid is still in development!" 967 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
968 "Hydrodynamic model is missing");
970 sdf::ElementPtr modelParams = _sdf->GetElement(
"hydrodynamic_model");
972 if (modelParams->HasElement(
"radius"))
973 this->
radius = modelParams->Get<
double>(
"radius");
976 gzmsg <<
"HMSpheroid: Using the smallest length of bounding box as radius" 982 GZ_ASSERT(this->
radius > 0,
"Radius cannot be negative");
983 gzmsg <<
"HMSpheroid::radius=" << this->
radius << std::endl;
985 if (modelParams->HasElement(
"length"))
986 this->
length = modelParams->Get<
double>(
"length");
989 gzmsg <<
"HMSpheroid: Using the biggest length of bounding box as length" 995 GZ_ASSERT(this->
length > 0,
"Length cannot be negative");
996 gzmsg <<
"HMSpheroid::length=" << this->
length << std::endl;
999 double ecc = std::sqrt(1 -
1002 gzmsg <<
"ecc=" << ecc << std::endl;
1004 double ln = std::log((1 + ecc) / (1 - ecc));
1005 double alpha = 2 * (1 - std::pow(ecc, 2.0)) / std::pow(ecc, 3.0);
1007 alpha *= (0.5 * ln - ecc);
1009 double beta = 1 / std::pow(ecc, 2.0) - \
1010 (1 - std::pow(ecc, 2.0) / (2 * std::pow(ecc, 3.0))) * ln;
1012 gzmsg <<
"alpha=" << alpha << std::endl;
1013 gzmsg <<
"beta=" << beta << std::endl;
1016 #if GAZEBO_MAJOR_VERSION >= 8 1017 mass = this->
link->GetInertial()->Mass();
1019 mass = this->
link->GetInertial()->GetMass();
1022 this->
Ma(0, 0) = mass * alpha / (2 - alpha);
1023 this->
Ma(1, 1) = mass * beta / (2 - beta);
1024 this->
Ma(2, 2) = this->
Ma(1, 1);
1027 double ba_minus = std::pow(this->
radius, 2.0) - std::pow(this->
length, 2.0);
1028 double ba_plus = std::pow(this->
radius, 2.0) + std::pow(this->
length, 2.0);
1029 this->
Ma(4, 4) = -0.2 * mass * std::pow(ba_minus, 2.0) * (alpha - beta);
1030 this->
Ma(4, 4) /= (2 * ba_minus - ba_plus * (alpha - beta));
1032 this->
Ma(5, 5) = this->
Ma(4, 4);
1038 if (!_paramName.compare(
"radius"))
1040 if (!_message.empty())
1041 gzmsg << this->
link->GetName() << std::endl;
1042 std::cout << std::setw(12) << this->
radius << std::endl;
1044 else if (!_paramName.compare(
"length"))
1046 if (!_message.empty())
1047 gzmsg << _message << std::endl;
1048 std::cout << std::setw(12) << this->
length << std::endl;
1064 physics::LinkPtr _link)
1066 return new HMBox(_sdf, _link);
1071 physics::LinkPtr _link)
1074 gzerr <<
"Hydrodynamic model for box is still in development!" << std::endl;
1076 GZ_ASSERT(_sdf->HasElement(
"hydrodynamic_model"),
1077 "Hydrodynamic model is missing");
1079 sdf::ElementPtr modelParams = _sdf->GetElement(
"hydrodynamic_model");
1081 if (modelParams->HasElement(
"cd"))
1082 this->
Cd = modelParams->Get<
double>(
"cd");
1085 gzmsg <<
"HMBox: Using 1 as drag coefficient" 1090 GZ_ASSERT(modelParams->HasElement(
"length"),
"Length of the box is missing");
1091 GZ_ASSERT(modelParams->HasElement(
"width"),
"Width of the box is missing");
1092 GZ_ASSERT(modelParams->HasElement(
"height"),
"Height of the box is missing");
1094 this->
length = modelParams->Get<
double>(
"length");
1095 this->
width = modelParams->Get<
double>(
"width");
1096 this->
height = modelParams->Get<
double>(
"height");
1099 this->
quadDampCoef[0] = -0.5 * this->
Cd * this->width * this->height \
1101 this->quadDampCoef[1] = -0.5 * this->
Cd * this->length * this->height \
1103 this->quadDampCoef[2] = -0.5 * this->
Cd * this->width * this->length \
1110 if (!_paramName.compare(
"length"))
1112 if (!_message.empty())
1113 gzmsg << _message << std::endl;
1114 std::cout << std::setw(12) << this->
length << std::endl;
1116 else if (!_paramName.compare(
"width"))
1118 if (!_message.empty())
1119 gzmsg << _message << std::endl;
1120 std::cout << std::setw(12) << this->
width << std::endl;
1122 else if (!_paramName.compare(
"height"))
1124 if (!_message.empty())
1125 gzmsg << _message << std::endl;
1126 std::cout << std::setw(12) << this->
height << std::endl;
double volume
Volume of fluid displaced by the submerged object.
double height
Height of the box.
double Cd
Drag coefficient.
virtual void Print(std::string _paramName, std::string _message=std::string())
Prints parameters.
double submergedHeight
Height of the robot that is submerged (only for surface vessels)
Eigen::Matrix6d DLin
Linear damping matrix.
void ComputeAddedCoriolisMatrix(const Eigen::Vector6d &_vel, const Eigen::Matrix6d &_Ma, Eigen::Matrix6d &_Ca) const
Computes the added-mass Coriolis matrix Ca.
void StoreVector(std::string _tag, ignition::math::Vector3d _vec)
Store vector in the hydroWrench map if the field has been created.
Eigen::Matrix6d DLinForwardSpeed
Linear damping matrix proportional only to the forward speed (useful for modeling AUVs)...
double radius
Prolate spheroid's smaller radius.
double cdCirc
Approximated drag coefficient for the circular area.
void ComputeAcc(Eigen::Vector6d _velRel, double _time, double _alpha=0.3)
Filter acceleration (fix due to the update structure of Gazebo)
#define UUV_ADDED_CORIOLIS_FORCE
ignition::math::Vector3d FromNED(ignition::math::Vector3d _vec)
Convert vector to comply with the NED reference frame.
double width
Width of the box.
static const std::string IDENTIFIER
Unique identifier for this geometry.
virtual void Print(std::string _paramName, std::string _message=std::string())
Prints parameters.
Class containing the methods and attributes for a hydrodynamic model for a spheroid in the fluid Refe...
virtual void Print(std::string _paramName, std::string _message=std::string())
Prints parameters.
static HydrodynamicModel * create(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create model of this type with parameter values from sdf.
HMBox(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Constructor.
double radius
Sphere radius.
double areaSection
Area of the cross section.
double offsetLinearDamping
Offset for the linear damping matrix.
double length
Length of the cylinder.
double offsetAddedMass
Offset for the added-mass matrix.
static const std::string IDENTIFIER
Unique identifier for this geometry.
bool debugFlag
Debug flag, storing all intermediate forces and torques.
ignition::math::Vector3d Vec3dToGazebo(const Eigen::Vector3d &_x)
double length
Length of the sphroid.
static HydrodynamicModel * create(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create model of this type with parameter values from sdf.
double offsetNonLinDamping
Offset for the linear damping matrix.
double Re
Reynolds number (not used by all models)
Class containing the methods and attributes for a hydrodynamic model for a box in the fluid...
ignition::math::Box boundingBox
TEMP for calculation of the buoyancy force close to the surface.
double lastTime
Last timestamp (in seconds) at which ApplyHydrodynamicForces was called.
Eigen::Matrix< double, 6, 1 > Vector6d
Definition of a 6 element Eigen vector.
virtual bool SetParam(std::string _tag, double _input)
Set scalar parameter.
Factory singleton class that creates a HydrodynamicModel from sdf.
virtual void Print(std::string _paramName, std::string _message=std::string())
Prints parameters.
HMFossen(sdf::ElementPtr _sdf, physics::LinkPtr _link)
void SetNeutrallyBuoyant()
Sets this link as neutrally buoyant.
HydrodynamicModel(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Protected constructor: Use the factory for object creation.
#define UUV_DAMPING_TORQUE
Eigen::Matrix6d GetAddedMass() const
Returns the added-mass matrix with the scaling and offset.
static HydrodynamicModelFactory & GetInstance()
Returns the singleton instance of this factory.
Class containing the methods and attributes for a hydrodynamic model for a sphere in the fluid...
bool RegisterCreator(const std::string &_identifier, HydrodynamicModelCreator _creator)
Register a class with its creator.
Eigen::Vector6d filteredAcc
Filtered linear & angular acceleration vector in link frame. This is used to prevent the model to bec...
void SetCoB(const ignition::math::Vector3d &_centerOfBuoyancy)
Sets the position of the center of buoyancy on the body frame.
static const std::string IDENTIFIER
Unique identifier for this geometry.
ignition::math::Vector3d ToNED(ignition::math::Vector3d _vec)
Convert vector to comply with the NED reference frame.
Eigen::Vector6d lastVelRel
Last body-fixed relative velocity (nu_R in Fossen's equations)
double offsetVolume
Offset for the volume.
HMCylinder(sdf::ElementPtr _sdf, physics::LinkPtr _link)
double waterLevelPlaneArea
If the cross section area around water level of the surface vessel is not given, it will be computed ...
static const std::string IDENTIFIER
Unique identifier for this geometry.
void SetBoundingBox(const ignition::math::Box &_bBox)
Sets bounding box.
double temperature
Temperature (not used by all models)
Eigen::Matrix6d Ca
Added-mass associated Coriolis matrix.
#define UUV_ADDED_CORIOLIS_TORQUE
Class containting the methods and attributes for a Fossen robot-like hydrodynamic model...
Eigen::Matrix6d Ma
Added-mass matrix.
HydrodynamicModel *(* HydrodynamicModelCreator)(sdf::ElementPtr, physics::LinkPtr)
Function pointer to create a certain a model.
HydrodynamicModel * CreateHydrodynamicModel(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create HydrodynamicModel object according to its sdf Description.
Eigen::Vector6d EigenStack(const ignition::math::Vector3d &_x, const ignition::math::Vector3d &_y)
void ApplyBuoyancyForce()
Applies buoyancy force on link.
#define UUV_ADDED_MASS_FORCE
std::vector< double > quadDampCoef
Quadratic damping coefficients.
static HydrodynamicModel * create(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create model of this type with parameter values from sdf.
HMSpheroid(sdf::ElementPtr _sdf, physics::LinkPtr _link)
bool isSurfaceVessel
Flag set to true if the information about the metacentric width and height is available.
static HydrodynamicModel * create(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create model of this type with parameter values from sdf.
Eigen::Matrix6d D
Damping matrix.
Eigen::Matrix< double, 6, 6 > Matrix6d
Definition of a 6x6 Eigen matrix.
Eigen::Matrix3d CrossProductOperator(Eigen::Vector3d _x)
Returns the cross product operator matrix for Eigen vectors.
virtual bool GetParam(std::string _tag, std::vector< double > &_output)
Return paramater in vector form for the given tag.
std::vector< double > Str2Vector(std::string _input)
Conversion of a string to a double vector.
virtual void Print(std::string _paramName, std::string _message=std::string())
Prints parameters.
double fluidDensity
Fluid density.
std::string axis
Name of the unit rotation axis (just a tag for x, y or z)
This file contains the definition for different classes of hydrodynamic models for submerged objects...
bool CheckParams(sdf::ElementPtr _sdf)
Returns true if all parameters are available from the SDF element.
ignition::math::Vector3d centerOfBuoyancy
Center of buoyancy in the body frame.
REGISTER_HYDRODYNAMICMODEL_CREATOR(HMFossen,&HMFossen::create)
double scalingDamping
Scaling of the damping matrix.
double metacentricLength
Metacentric length of the robot, used only for surface vessels and floating objects.
Class describing the dynamics of a buoyant object, useful for simple representations of underwater st...
double Cd
Drag coefficient.
#define UUV_ADDED_MASS_TORQUE
double cdLength
Approximated drag coefficient for the rectangular section.
physics::LinkPtr link
Pointer to the correspondent robot link.
void ComputeDampingMatrix(const Eigen::Vector6d &_vel, Eigen::Matrix6d &_D) const
Updates the damping matrix for the current velocity.
virtual void ApplyHydrodynamicForces(double time, const ignition::math::Vector3d &_flowVelWorld)
Computation of the hydrodynamic forces.
Class containing the methods and attributes for a hydrodynamic model for a cylinder in the fluid...
Eigen::Matrix6d DNonLin
Nonlinear damping coefficients.
#define UUV_DAMPING_FORCE
double scalingVolume
Scaling factor for the volume.
double dimRatio
Ratio between length and diameter.
double offsetLinForwardSpeedDamping
Offset for the linear damping matrix.
static const std::string IDENTIFIER
Unique identifier for this geometry.
static HydrodynamicModel * create(sdf::ElementPtr _sdf, physics::LinkPtr _link)
Create model of this type with parameter values from sdf.
std::vector< std::string > params
List of parameters needed from the SDF element.
std::vector< double > linearDampCoef
Linear damping coefficients.
double radius
Sphere radius.
HMSphere(sdf::ElementPtr _sdf, physics::LinkPtr _link)
double scalingAddedMass
Scaling of the added-mass matrix.
double length
Length of the box.