Skip to content

Automating the ROS 1-ROS 2 Bridge for RoboClaw

Introduction

Setting up the ROS 1-ROS 2 bridge manually every time can be frustrating. This guide provides a Python script that automates the process, making it easier to run your RoboClaw motor controller in ROS 1 while sending commands from ROS 2.


Why Use a Bridge?

Since ROS 1 Noetic and ROS 2 Foxy use different middleware, we need the ros1_bridge to communicate between them. With this setup, you can control RoboClaw from ROS 2 while it runs on ROS 1.


Steps Automated by the Script

  1. Detect ROS 1 and ROS 2 installations
  2. Start roscore (if not running)
  3. Launch the RoboClaw node in ROS 1
  4. Start the ROS 1-ROS 2 bridge
  5. Verify if /cmd_vel is bridged between ROS versions
  6. Send a velocity command from ROS 2

The Python Script

Here is the script that automates the process:

import os
import subprocess
import time

def run_command(command):
    """ Runs a shell command and returns the output """
    try:
        output = subprocess.run(command, shell=True, check=True, text=True, capture_output=True)
        return output.stdout.strip()
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")
        return None

def source_ros(version):
    """ Sources the correct ROS environment """
    if version == "ros1":
        os.system("source /opt/ros/noetic/setup.bash")
    elif version == "ros2":
        os.system("source /opt/ros/foxy/setup.bash")
    else:
        print("Invalid ROS version specified")

def check_ros_version():
    """ Checks if ROS 1 and ROS 2 are installed """
    ros1_check = run_command("rosversion -d")
    ros2_check = run_command("ros2 --version")

    if "noetic" in str(ros1_check):
        print("[✔] ROS 1 Noetic detected")
    else:
        print("[X] ROS 1 Noetic not found!")

    if ros2_check:
        print(f"[✔] ROS 2 detected (Version: {ros2_check})")
    else:
        print("[X] ROS 2 not found!")

def start_roscore():
    """ Starts roscore if not already running """
    output = run_command("pgrep -x roscore")
    if output:
        print("[✔] roscore is already running")
    else:
        print("[✔] Starting roscore...")
        os.system("roscore &")
        time.sleep(3)

def start_roboclaw_node():
    """ Launches the RoboClaw node """
    print("[✔] Launching RoboClaw node...")
    os.system("roslaunch roboclaw_node roboclaw.launch &")
    time.sleep(3)

def start_ros1_bridge():
    """ Starts the ROS 1-ROS 2 bridge """
    print("[✔] Launching ROS 1-ROS 2 bridge...")
    os.system("ros2 run ros1_bridge dynamic_bridge &")
    time.sleep(3)

def check_cmd_vel_topic():
    """ Checks if /cmd_vel is available in both ROS 1 and ROS 2 """
    ros1_topics = run_command("rostopic list")
    ros2_topics = run_command("ros2 topic list")

    if "/cmd_vel" in str(ros1_topics):
        print("[✔] /cmd_vel is available in ROS 1")
    else:
        print("[X] /cmd_vel not found in ROS 1")

    if "/cmd_vel" in str(ros2_topics):
        print("[✔] /cmd_vel is available in ROS 2")
    else:
        print("[X] /cmd_vel not found in ROS 2")

if __name__ == "__main__":
    print("\n[✔] Setting up ROS 1-ROS 2 Bridge for RoboClaw...")
    check_ros_version()

    source_ros("ros1")
    start_roscore()
    start_roboclaw_node()

    source_ros("ros2")
    start_ros1_bridge()

    check_cmd_vel_topic()

    print("\n[✔] Setup complete! You can now control RoboClaw from ROS 2.")

Conclusion

This script automates the ROS bridge setup so you can focus on developing your robot. Just run:

python3 setup_ros_bridge.py

🚀 Now you can control your RoboClaw motor from ROS 2 effortlessly!


Created 2025-01-30, Updated 2025-01-30
Authors: Harminder Singh Nijjar (2)

Comments