How DART Integrates with Gazebo for Physics Simulation: A Complete Technical Guide

DART integrates with Gazebo through a runtime-loadable dartsim plugin consumed by gz-physics, maintained via an automated workflow that downloads, patches, builds, and tests the integration against DART's latest APIs.

The Dynamic Animation and Robotics Toolkit (DART) provides optional but fully supported integration with Gazebo, the popular robotics simulator. This integration allows Gazebo to use DART as its physics backend through the gz-physics abstraction layer, enabling accurate rigid-body dynamics and collision detection within Gazebo simulations.

The Architecture of DART-Gazebo Integration

Runtime Plugin Loading via gz-physics

Gazebo (version ≥ gz-sim 9) uses gz-physics as its physics engine abstraction layer. DART integrates by exposing a dartsim plugin that gz-physics loads at runtime. When Gazebo requests physics simulation, gz-physics dynamically loads libgz-physics-dartsim-plugin and binds DART's API to Gazebo's simulation loop.

Backward Compatibility Shims

To maintain binary compatibility with gz-physics, DART retains specific API signatures that would otherwise be deprecated. In dart/simulation/world.cpp at line 189, DART maintains the CollisionDetector::getType() method returning const std::string& specifically for gz-physics compatibility.

Similarly, DART preserves deprecated solver types like BoxedLcpConstraintSolver because gz-physics performs dynamic_cast operations on the solver returned by World::getConstraintSolver(). These shims are documented in docs/onboarding/build-system.md (lines 733-785) under the "Gazebo Integration Feature" section.

The Integration Workflow: From Source to Runtime

The DART repository automates the entire Gazebo integration pipeline through a series of pixi tasks defined in pixi.toml. This workflow ensures DART 7.0 remains compatible with gz-physics 9.0.0.

Step 1: Download gz-physics Source

The workflow begins by cloning the upstream gz-physics repository at the specific branch gz-physics9_9.0.0. This is handled by the download-gz task in pixi.toml (line 1779).

Step 2: Patch CMake Version Requirements

Before building, DART patches gz-physics to accept DART 7.0. The script scripts/patch_gz_physics.py (lines 3-24) modifies the CMake configuration to bump the required DART package version, ensuring the downstream build recognizes the installed DART libraries.

Step 3: Configure with Vendored Dependencies

The config-gz task (line 1815) configures the gz-physics build with a special CMake include file gz_physics_force_vendor_gtest.cmake. This forces gz-physics to use its vendored GoogleTest headers rather than system versions, preventing link-time mismatches between DART's testing infrastructure and gz-physics.

Step 4: Build the DART Plugin

The build-gz task (line 1838) compiles libgz-physics-dartsim-plugin, linking against the DART libraries produced by the main DART build. This produces the shared library that Gazebo loads at runtime.

Step 5: Run Integration Tests

The test-gz task (line 1851) executes gz-physics' own test suite against the DART plugin. This validates that physics simulation, collision detection, and constraint solving behave correctly through the gz-physics abstraction.

Step 6: Runtime Loading

At runtime, Gazebo's gz-physics layer searches for the dartsim plugin by name. When found, it loads libgz-physics-dartsim-plugin and binds DART's World, Skeleton, and collision detection systems to the Gazebo simulation loop.

Building the DART Plugin for Gazebo

To reproduce the integration locally, use the automated pixi workflow:


# Enable the Gazebo integration environment

pixi run -e gazebo download-gz      # Clones gz-physics9_9.0.0

pixi run -e gazebo patch-gz         # Patches CMake for DART 7.0 compatibility

pixi run -e gazebo config-gz        # Configures with vendored gtest

pixi run -e gazebo build-gz         # Builds libgz-physics-dartsim-plugin

pixi run -e gazebo test-gz          # Runs gz-physics test suite

For custom plugins that depend on DART within Gazebo, use this CMake pattern:

cmake_minimum_required(VERSION 3.16)
project(my_gazebo_dart_plugin)

find_package(DART 7.0 REQUIRED COMPONENTS dynamics io)
find_package(gz-physics REQUIRED)

add_library(my_dart_plugin SHARED src/my_plugin.cpp)
target_link_libraries(my_dart_plugin PRIVATE DART::dart)
gz_add_plugin(my_dart_plugin)

Continuous Integration and Testing

The DART repository validates Gazebo integration through .github/workflows/ci_gz_physics.yml. This workflow executes the full pixi task sequence on every pull request, ensuring that changes to DART's API do not break the gz-physics plugin. The CI job specifically tests the plugin at line 72 of the workflow file, running the same test-gz command used in local development.

Summary

  • DART integrates with Gazebo through a runtime plugin (libgz-physics-dartsim-plugin) consumed by gz-physics.
  • Automated workflow in pixi.toml handles downloading, patching, building, and testing gz-physics against DART 7.0.
  • Backward compatibility is maintained through specific API shims in dart/simulation/world.cpp and preserved deprecated classes like BoxedLcpConstraintSolver.
  • CI validation occurs via .github/workflows/ci_gz_physics.yml on every pull request.
  • Runtime loading happens when Gazebo's gz-physics layer dynamically loads the DART plugin and binds it to the simulation loop.

Frequently Asked Questions

How does Gazebo load DART as a physics engine?

Gazebo uses gz-physics as an abstraction layer that dynamically loads physics engine plugins at runtime. When configured to use DART, gz-physics searches for and loads libgz-physics-dartsim-plugin, which links against DART's libraries and exposes DART's World, collision detection, and constraint solving capabilities through the gz-physics API.

Why does DART maintain deprecated API signatures for Gazebo integration?

DART preserves specific deprecated signatures—such as CollisionDetector::getType() returning const std::string& and the BoxedLcpConstraintSolver class—because gz-physics performs dynamic_cast operations and expects specific binary interfaces. These backward-compatibility shims, documented in docs/onboarding/build-system.md, ensure that DART 7.0 remains compatible with existing gz-physics releases without requiring downstream changes.

What is the purpose of the patch script in the DART-Gazebo integration workflow?

The scripts/patch_gz_physics.py script modifies gz-physics' CMake configuration to accept DART 7.0 by bumping the required DART package version. This patching is necessary because upstream gz-physics may specify an older DART version requirement; the script ensures the downstream build recognizes and links against the DART libraries built from the current repository source.

How can I verify that DART's Gazebo integration works correctly on my system?

You can run the automated integration tests using the pixi workflow defined in pixi.toml. Execute pixi run -e gazebo test-gz to run gz-physics' full test suite against the DART plugin. This command validates physics simulation, collision detection, and constraint solving through the gz-physics abstraction, ensuring the integration functions correctly with your DART build.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →