Bridging to ROS1 - osrf/mbzirc GitHub Wiki

The MBZIRC Simulation Environment is primarily built to be used with Ignition Fortress and ROS 2 Galactic. Some developers may already have a set of nodes or libraries that are built to work with ROS 1, rather than ROS 2. This guide outlines how to integrate existing ROS 1 code into an MBZIRC simulation solution.

When the simulation environment is running, the only API that is exposed to developers is via ROS 2 topics and is outlined in the API documentation.

To interact with the API from ROS 1, developers will need to utilize the ros1_bridge package in their ROS 2 workspace. The ros1_bridge provides a network bridge that allows ROS 1 Noetic and ROS 2 Galactic messages to be exchanged.

The following demonstrates how to build and configure a workspace to use the simulation API from ROS 1 Noetic.

Installation

In order to use the ros1_bridge, there must be a workspace set up to interact with both ROS 1 and ROS 2 packages.

# Set up ROS key
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Set up ROS 2 repositories
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null'

# Set up ROS 1 repositories
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros.list > /dev/null'


# Install ROS 1 and ROS 2 base dependencies
sudo apt install ros-noetic-ros-base ros-galactic-ros-base

# Install ros1-bridge binaries
sudo apt install ros-galactic-ros1-bridge

Note that due to the way the ros1_bridge works, it can only bridge pairs that were available at the time that it was built. The MBZIRC API makes use of messages that would be available in a base ROS 2 install, so they will be available via the precompiled-binaries. If you wish to make use of bridging custom message types, ros1_bridge must be built from source.

Usage

Once all of the required packages are installed, the bridge is available to be used.

The bridge can be used for single topics in a single direction (2->1 or 1->2), or can be configured to bridge all topics. For simplicity, we will begin with bridging all topics in both directions.

Note While for ease of use here, we are bridging all topics in both directions, in practice this is likely not the desired behavior. Bridging all topics will mean that all ROS1 topics will additionally be bridged into the ROS2 side leading to potential conflicts or additional processing overhead. It is recommended to scope the bridge to relevant topics whenever possible.

Starting the Simulator

Launch the simple demo and spawn a UAV as described in API documentation.

In the first terminal:

ros2 launch ros_ign_gazebo ign_gazebo.launch.py ign_args:="-v 4 -r simple_demo.sdf"

In a second terminal:

ros2 launch mbzirc_ign spawn.launch.py name:=quadrotor_1 world:=simple_demo model:=mbzirc_quadrotor type:=uav x:=1 y:=2 z:=0.05 R:=0 P:=0 Y:=0 slot0:=mbzirc_hd_camera slot1:=mbzirc_rgbd_camera

Verify that ROS 2 topics are visible

First, make sure that all expected ROS 2 topics are enumerated in the location where the bridge will run. If you are running on the same system/container as the simulator, this shouldn't be an issue. It is a good check for networking configuration when the simulator and solution are in different containers.

source /opt/ros/galactic/setup.bash

ros2 topic list

For a quadrotor spawned as above, we would expect to see:

/parameter_events
/quadrotor_1/air_pressure
/quadrotor_1/cmd_vel
/quadrotor_1/front/camera_info
/quadrotor_1/front/image_raw
/quadrotor_1/front/optical/camera_info
/quadrotor_1/front/optical/image_raw
/quadrotor_1/imu/data
/quadrotor_1/magnetic_field
/quadrotor_1/points
/quadrotor_1/pose
/quadrotor_1/pose_static
/rosout
/tf
/tf_static

Setting up the bridge

Now that we have verfied that the ROS 2 topics exist, we can start the bridge. Before the bridge is started, a ROS 1 roscore must be started.

In a new terminal:

source /opt/ros/noetic/setup.bash
roscore

In another new terminal start the bridge

ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

There should be console messages indicating which topics are being bridged.

Finally, in another new terminal, interact with the ROS 1 topics

List the topics:

$ source /opt/ros/noetic/setup.bash
$ rostopic list
/quadrotor_1/air_pressure
/quadrotor_1/cmd_vel
/quadrotor_1/front/camera_info
/quadrotor_1/front/image_raw
/quadrotor_1/front/optical/camera_info
/quadrotor_1/front/optical/image_raw
/quadrotor_1/imu/data
/quadrotor_1/magnetic_field
/quadrotor_1/points
/quadrotor_1/pose
/quadrotor_1/pose_static
/rosout
/rosout_agg
/tf
/tf_static

Echo a topic:

$ rostopic echo -n 1 /quadrotor_1/air_pressure
header:
  seq: 2859
  stamp:
    secs: 334
    nsecs: 850000000
  frame_id: "quadrotor_1/base_link/air_pressure"
fluid_pressure: 101324.33927954608
variance: 0.0
---

Make the quadrotor take off:

$ rostopic pub /quadrotor_1/cmd_vel geometry_msgs/Twist "linear:
  x: 0.0
  y: 0.0
  z: 0.5
angular:
  x: 0.0
  y: 0.0
  z: 0.0"

Using the Docker container

There is a docker configuration available that contains all necessary dependencies for running a bridge for the competition.

To build the docker container:

cd mbzirc/docker
./build.bash mbzirc_ros1_bridge

To run the docker container:

cd mbzirc/docker
./run.bash mbzirc_ros1_bridge

Note By default, the mbzirc_ros1_bridge will only bridge topics from ROS 2 to ROS 1. In order to bridge ROS 1 topics back into ROS 2, users will have to start individual bridges.