A Gazebo Harmonic (gz-sim8) C++ plugin that applies controlled forces to any model link, no flight stack needed. Currently does Z-axis altitude hold with automatic mass calculation. Runs a cascaded PD controller at 1000Hz — unlike Gazebo's built-in ApplyLinkWrench which is open-loop, this actively corrects every tick to hold altitude.
- Gazebo Harmonic (gz-sim8)
- ROS2 Humble
cd ~/ros_ws
colcon build --packages-select gz_wrench_plugin --cmake-args -DCMAKE_BUILD_TYPE=Release
source install/setup.bashexport GZ_SIM_SYSTEM_PLUGIN_PATH=~/ros_ws/install/gz_wrench_plugin/libTo persist across sessions:
echo 'export GZ_SIM_SYSTEM_PLUGIN_PATH=~/ros_ws/install/gz_wrench_plugin/lib' >> ~/.bashrc
source ~/.bashrcAdd inside your <model> tag in your SDF:
<plugin filename="WrenchController"
name="gz::sim::systems::WrenchController">
<target_z>2.0</target_z>
<link_name>base_link</link_name>
<hover_force>18.4</hover_force>
<kp>3.0</kp>
<kd>8.0</kd>
<enable_log>true</enable_log>
</plugin>Hit play — the model lifts off and holds at target_z. Hover force is auto-calculated from model mass if omitted.
| Parameter | Required | Default | Description |
|---|---|---|---|
target_z |
yes | — | Target altitude in metres |
link_name |
yes | — | Link to apply force to |
hover_force |
no | auto | Gravity feedforward in Newtons. Omit to auto-calculate |
kp |
no | 3.0 |
Position gain |
kd |
no | 8.0 |
Velocity gain |
enable_log |
no | true |
Print status to terminal |
A ready-to-run Parrot Bebop 2 example is included in examples/parrot_bebop_2/.
gz sim examples/parrot_bebop_2/model.sdfHit play — the Bebop lifts off and holds at target_z: 2.0.
Parrot Bebop 2 model by Olivier Crave — used as an example only.
Planning to add X/Y axis control, torque control, runtime target updates via ROS2 topic, and multi-link support.
MIT