\page underwater_vehicles Underwater vehicles
Gazebo now supports basic simulation of underwater vehicles.
This capability is based on the equations described in Fossen's "Guidance and
Control of Ocean Vehicles".
This tutorial will guide you through the steps you
need to setup simulation of an underwater vehicle. In this tutorial, we will
guide you through the setup of the MBARI Tethys.
One can find the final sdf file for this tutorial in the
examples/worlds/auv_controls.sdf
file.
The behaviour of a moving body through water is different from the behaviour of
a ground based vehicle. In particular bodies moving underwater experience much
more forces derived from drag, buoyancy and lift. The way these forces act on
a body can be seen in the following diagram:
The buoyancy plugin in Gazebo uses the collision mesh to calculate the volume of the vehicle. The calculated volume is used to determine the buoyancy force, which is then applied at the pose of the collision mesh in the link frame. Note that this may be a different location from the center of volume.
Additionally, it needs to know the density of the fluid in which
it is moving. By default this is set to 1000kgm^-3. However, in real life this
may vary depending on many factors like depth, salinity of water etc. To add
the buoyancy plugin all one needs to do is add the following under the <world>
tag:
<plugin
filename="gz-sim-buoyancy-system"
name="gz::sim::systems::Buoyancy">
<uniform_fluid_density>1000</uniform_fluid_density>
</plugin>
We need the vehicle to move, so we will be adding the Thruster
plugin. The
thruster plugin takes in a force and applies it along with calculating the desired
rpm. Under the <include>
or <model>
tag add the following:
<plugin
filename="gz-sim-thruster-system"
name="gz::sim::systems::Thruster">
<namespace>tethys</namespace>
<joint_name>propeller_joint</joint_name>
<thrust_coefficient>0.004422</thrust_coefficient>
<fluid_density>1000</fluid_density>
<propeller_diameter>0.2</propeller_diameter>
</plugin>
Now if we were to publish to /model/tethys/joint/propeller_joint/cmd_pos
gz topic -t /model/tethys/joint/propeller_joint/cmd_thrust \
-m gz.msgs.Double -p 'data: -31'
we should see the model move. The thrusters are governed by the equation on
page 246 of Fossen's book. In particular it relates force to rpm as follows:
Thrust = fluid_density * RPM^2 * thrust_constant * propeller blade size^4
.
The plugin takes in commands in newtons. So if you have a different thrust
curve you can still use the plugin with some type of adapter script. The thrust
constant is normally determined by individual manufacturers. In this case we are
using the Tethys's thrust coefficient. you may also build a test rig to measure
your thruster's thrust coefficient.
You may notice that the robot now keeps getting faster and faster. This is because there is no drag to oppose the thruster's force. We will be using Fossen's equations which describe the motion of a craft through the water for this. For better understanding of the parameters here, I would refer you to his book. Usually these parameters can be found via fluid simulation programs or experimental tests in a water tub.
<plugin
filename="gz-sim-hydrodynamics-system"
name="gz::sim::systems::Hydrodynamics">
<link_name>base_link</link_name>
<xDotU>-4.876161</xDotU>
<yDotV>-126.324739</yDotV>
<zDotW>-126.324739</zDotW>
<kDotP>0</kDotP>
<mDotQ>-33.46</mDotQ>
<nDotR>-33.46</nDotR>
<xUabsU>-6.2282</xUabsU>
<xU>0</xU>
<yVabsV>-601.27</yVabsV>
<yV>0</yV>
<zWabsW>-601.27</zWabsW>
<zW>0</zW>
<kPabsP>-0.1916</kPabsP>
<kP>0</kP>
<mQabsQ>-632.698957</mQabsQ>
<mQ>0</mQ>
<nRabsR>-632.698957</nRabsR>
<nR>0</nR>
</plugin>
Just like aeroplanes, an underwater vehicle may also use fins for stability and control. Fortunately, Gazebo already has a version of the LiftDrag plugin. In this tutorial, we will simply add two liftdrag plugins to the rudder and elevator of MBARI's Tethys. For more info about the liftdrag plugin including what the parameters mean, you may look at this gazebo classic tutorial. Essentially when we tilt the fins, we should experience a lift force which will cause the vehicle to experience a torque and the vehicle should start turning when we move.
<!-- Vertical fin -->
<plugin
filename="gz-sim-lift-drag-system"
name="gz::sim::systems::LiftDrag">
<air_density>1000</air_density>
<cla>4.13</cla>
<cla_stall>-1.1</cla_stall>
<cda>0.2</cda>
<cda_stall>0.03</cda_stall>
<alpha_stall>0.17</alpha_stall>
<a0>0</a0>
<area>0.0244</area>
<upward>0 1 0</upward>
<forward>1 0 0</forward>
<link_name>vertical_fins</link_name>
<cp>0 0 0</cp>
</plugin>
<!-- Horizontal fin -->
<plugin
filename="gz-sim-lift-drag-system"
name="gz::sim::systems::LiftDrag">
<air_density>1000</air_density>
<cla>4.13</cla>
<cla_stall>-1.1</cla_stall>
<cda>0.2</cda>
<cda_stall>0.03</cda_stall>
<alpha_stall>0.17</alpha_stall>
<a0>0</a0>
<area>0.0244</area>
<upward>0 0 1</upward>
<forward>1 0 0</forward>
<link_name>horizontal_fins</link_name>
<cp>0 0 0</cp>
</plugin>
The numbers in this case were kindly provided by MBARI for the Tethys. We also need to be able to control the position of the thruster fins so we will use the joint controller plugin.
<plugin
filename="gz-sim-joint-position-controller-system"
name="gz::sim::systems::JointPositionController">
<joint_name>horizontal_fins_joint</joint_name>
<p_gain>0.1</p_gain>
</plugin>
<plugin
filename="gz-sim-joint-position-controller-system"
name="gz::sim::systems::JointPositionController">
<joint_name>vertical_fins_joint</joint_name>
<p_gain>0.1</p_gain>
</plugin>
We should now be able to wiggle the fins using the following command:
gz topic -t /model/tethys/joint/vertical_fins_joint/0/cmd_pos \
-m gz.msgs.Double -p 'data: -0.17'
To control the rudder of the craft run the following
gz topic -t /model/tethys/joint/vertical_fins_joint/0/cmd_pos \
-m gz.msgs.Double -p 'data: -0.17'
To apply a thrust you may run the following command
gz topic -t /model/tethys/joint/propeller_joint/cmd_thrust \
-m gz.msgs.Double -p 'data: -31'
The vehicle should move in a circle.
When underwater, vehicles are often subject to ocean currents. The hydrodynamics plugin allows simulation of such currents. We can add a current simply by publishing the following:
gz topic -t /ocean_current -m gz.msgs.Vector3d -p 'x: 1, y:0, z:0'
You should observe your vehicle slowly drift to the side.