Skip to content

Latest commit

 

History

History
187 lines (142 loc) · 3.66 KB

File metadata and controls

187 lines (142 loc) · 3.66 KB

ROS 2 + Gazebo Cross-Container Docker Bridge

A two-container Docker setup for running Gazebo and ROS 2 as separate services connected over a custom Docker network, with the ros_gz_bridge handling topic communication between them


Compatibility

ROS 2 Gazebo
Lyrical Jetty
Rolling Jetty
Kilted Ionic
Jazzy Harmonic
Iron Harmonic
Humble Fortress

Prerequisites

  • Docker installed and running
  • Both images built:
    • gazebo — from your Gazebo Dockerfile
    • ros2 — from your ROS 2 Dockerfile
  • ros-gz-bridge installed

Setup

1. Create the Docker Network

docker network create ros-link

2. Start Containers

docker run -it -d --name gazebo-container --network ros-link gazebo sleep infinity
docker run -it -d --name ros2-container --network ros-link ros2 sleep infinity

3. Check Container IPs

docker network inspect ros-link

Example output:

[
  {
    "Name": "ros-link",
    "Driver": "bridge",
    "IPAM": {
      "Config": [{ "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1" }]
    },
    "Containers": {
      "281b3cbfba6a...": {
        "Name": "ros2-container",
        "IPv4Address": "172.21.0.3/16" //<ros-ip>
      },
      "c2410d610249...": {
        "Name": "gazebo-container",
        "IPv4Address": "172.21.0.2/16" //<gz-ip>
      }
    }
  }
]

4. Configure Environment Variables

In gazebo-container:

export GZ_IP=<gz-ip>
export GZ_PARTITION=gazebo-container

In ros2-container:

export GZ_IP=<ros-ip>
export GZ_PARTITION=gazebo-container
source /opt/ros/<ros-distro>/setup.bash

:::{important} Add these to ~/.bashrc in each container to be available across sessions. :::

:::{note} When setting GZ_IP, use only the IP address without the subnet mask. For example:

export GZ_IP=172.21.0.3

Do not include /16. :::


5. Install the Bridge

apt-get update && apt-get install -y ros-<ros-distro>-ros-gz-bridge

Using a Config File (optional)

if you have a bridge.yaml config file, you can use it instead of passing topics as arguments:

ros2 run ros_gz_bridge parameter_bridge --ros-args -p config_file:=/path/to/bridge.yaml

See the ros_gz_bridge documentation for configuration options.


Running the Bridge

Terminal 1 — Start Gazebo sim

docker exec -it gazebo-container bash
gz sim shapes.sdf

Terminal 2 — Start the bridge

docker exec -it ros2-container bash
source /opt/ros/<ros-distro>/setup.bash

Option 1: Single topic (basic)

ros2 run ros_gz_bridge parameter_bridge \
  /clock@rosgraph_msgs/msg/Clock@gz.msgs.Clock

Option 2: Multiple topics

ros2 run ros_gz_bridge parameter_bridge \
  /clock@rosgraph_msgs/msg/Clock@gz.msgs.Clock \
  /world/default/model/vehicle/cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist \
  /world/default/model/vehicle/odometry@nav_msgs/msg/Odometry@gz.msgs.Odometry

Option 3: Using config file

ros2 run ros_gz_bridge parameter_bridge --ros-args -p config_file:=/path/to/bridge.yaml

See the ros_gz_bridge documentation for configuration options.

Terminal 3 — Verify

docker exec -it ros2-container bash
source /opt/ros/<ros-distro>/setup.bash
ros2 topic echo /clock

if you see something like this :-

clock:
  sec: 0
  nanosec: 0
---
clock:
  sec: 0
  nanosec: 0
---
clock:
  sec: 0
  nanosec: 0
---

then the connection between the two docker containers is succesfull