保姆级教程:用Docker Compose同时运行两个URSim,搞定ROS2双臂仿真环境搭建

在工业自动化和机器人研究领域,双臂协作系统正成为越来越重要的研究方向。相比单臂系统,双臂协同工作能完成更复杂的任务,如装配、搬运和精密操作。然而,搭建一个可靠的双臂仿真环境对初学者来说往往充满挑战——从硬件资源分配到网络配置,每一步都可能遇到意想不到的问题。

本教程将手把手教你使用Docker Compose技术,在一台普通开发机上轻松部署两个独立的URSim仿真器,并通过ROS2实现双臂协同控制。这种方法不仅避免了传统虚拟机方案对系统资源的过度占用,还能完美解决多实例URSim的端口冲突问题。无论你是机器人专业的学生,还是刚接触UR机械臂的工程师,都能在30分钟内完成从零到可运行的双臂仿真环境搭建。

1. 环境准备与基础概念

在开始之前,我们需要明确几个关键组件的作用和相互关系。URSim是Universal Robots官方提供的机械臂仿真软件,能够模拟真实UR机械臂的所有功能;ROS2则是目前最流行的机器人操作系统,提供了丰富的工具和库;Docker Compose则帮助我们定义和运行多容器应用,解决环境隔离和资源配置问题。

1.1 硬件与软件要求

  • 硬件配置

    • CPU:至少4核(推荐8核以上)
    • 内存:8GB(推荐16GB)
    • 显卡:支持OpenGL 3.3及以上
    • 存储:20GB可用空间
  • 软件依赖

    # 检查Docker和Docker Compose是否安装
    docker --version
    docker-compose --version
    
    # 若未安装,使用以下命令安装(Ubuntu示例)
    sudo apt-get update
    sudo apt-get install docker.io docker-compose
    

提示:建议使用Ubuntu 20.04或22.04系统,这些版本对ROS2和Docker的支持最为完善。

1.2 网络架构设计

双臂仿真环境的核心挑战在于网络配置。我们需要确保:

  1. 两个URSim实例能够独立运行,互不干扰
  2. ROS2节点能够同时发现并控制两个机械臂
  3. 宿主机与容器间的通信畅通无阻

解决方案是使用Docker的桥接网络模式,为每个URSim容器分配独立的IP地址,同时通过ROS2的多机通信机制实现节点发现。

2. Docker Compose配置详解

下面是我们精心设计的docker-compose.yml文件,它定义了两个URSim实例和相关的网络配置。

2.1 基础服务定义

version: '3.8'

services:
  ursim_left:
    image: universalrobots/ursim_e-series
    container_name: ursim_left
    environment:
      - ROS_MASTER_URI=http://localhost:11311
      - ROS_IP=172.20.0.2
    ports:
      - "6080:6080"  # NoVNC端口
      - "29999:29999" # Dashboard服务器
      - "30001-30004:30001-30004" # 实时数据接口
    networks:
      ros_network:
        ipv4_address: 172.20.0.2

  ursim_right:
    image: universalrobots/ursim_e-series
    container_name: ursim_right 
    environment:
      - ROS_MASTER_URI=http://localhost:11311
      - ROS_IP=172.20.0.3
    ports:
      - "6081:6080"
      - "30000:30000"
      - "31001-31004:30001-30004"
    networks:
      ros_network:
        ipv4_address: 172.20.0.3

networks:
  ros_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24

2.2 关键配置解析

  1. 端口映射策略

    • 左臂使用标准端口(30001-30004)
    • 右臂使用偏移后的端口(31001-31004)
    • NoVNC端口分别映射到6080和6081
  2. 网络隔离设计

    • 自定义ros_network桥接网络
    • 为每个容器分配固定IP(172.20.0.2和172.20.0.3)
    • 确保容器间可直接通信
  3. ROS2环境变量

    • ROS_MASTER_URI指向同一主机
    • ROS_IP设置为各自容器IP

3. 启动与验证双臂仿真

配置完成后,通过以下命令启动整个系统:

docker-compose up -d

等待约1-2分钟,两个URSim实例应该都能正常运行。可以通过浏览器访问:

  • 左臂控制界面:http://localhost:6080
  • 右臂控制界面:http://localhost:6081

3.1 常见问题排查

如果遇到启动失败,可以检查以下几个方面:

  1. 端口冲突

    sudo netstat -tulnp | grep -E '6080|6081|29999|30000'
    

    确保这些端口没有被其他进程占用

  2. 显卡驱动问题

    glxinfo | grep "OpenGL version"
    

    确认OpenGL版本符合要求

  3. 容器日志查看

    docker logs ursim_left
    docker logs ursim_right
    

4. ROS2与双臂通信配置

现在我们已经有两个独立的URSim实例运行,下一步是配置ROS2节点与它们的通信。

4.1 Universal_Robots_ROS2_Driver安装

sudo apt-get install ros-humble-universal-robots

4.2 左右臂启动文件配置

创建dual_arm_control.launch.py文件:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        # 左臂驱动节点
        Node(
            package='ur_robot_driver',
            executable='ur_robot_driver_node',
            name='ur_driver_left',
            namespace='left',
            parameters=[
                {'robot_ip': '172.20.0.2'},
                {'use_fake_hardware': True}
            ]
        ),
        
        # 右臂驱动节点
        Node(
            package='ur_robot_driver',
            executable='ur_robot_driver_node',
            name='ur_driver_right',
            namespace='right',
            parameters=[
                {'robot_ip': '172.20.0.3'},
                {'use_fake_hardware': True}
            ]
        ),
        
        # 双臂协同控制节点
        Node(
            package='dual_arm_control',
            executable='coordinator',
            name='dual_arm_coordinator'
        )
    ])

4.3 通信测试

启动ROS2节点后,可以通过以下命令测试通信是否正常:

# 查看左臂关节状态
ros2 topic echo /left/joint_states

# 查看右臂关节状态
ros2 topic echo /right/joint_states

# 发送测试命令到左臂
ros2 service call /left/io_and_status_controller/set_io ur_msgs/srv/SetIO "{fun: 1, pin: 0, state: 1.0}"

5. 高级配置与性能优化

当基础环境搭建完成后,我们可以进一步优化系统性能并添加高级功能。

5.1 实时性调优

对于需要更高实时性的应用,可以调整Docker容器的CPU和内存限制:

# 在docker-compose.yml中添加
deploy:
  resources:
    limits:
      cpus: '2'
      memory: 4G

5.2 数据同步策略

双臂协同控制的关键是数据同步。以下是几种常见策略对比:

策略优点缺点适用场景
主从控制实现简单从臂有延迟简单搬运
对称控制响应一致需要精确同步精密装配
混合控制灵活性强算法复杂复杂任务

5.3 可视化监控

使用rqt和PlotJuggler监控双臂状态:

# 安装可视化工具
sudo apt-get install ros-humble-rqt ros-humble-plotjuggler-ros

# 启动rqt
rqt

在实际项目中,我发现最常遇到的问题是两个URSim实例的时间不同步,这会导致ROS2消息时间戳混乱。解决方法是在容器启动时同步时间:

# 在docker-compose.yml的每个服务中添加
volumes:
  - /etc/localtime:/etc/localtime:ro

更多推荐