2. 多机器人命名空间配置

任务目标

在ROS2中,当多个机器人共享同一网络时,若不隔离话题和服务,会导致节点互相订阅错误数据。本案例通过为每个机器人设置独立命名空间,使各机器人拥有专属的话题和服务,实现多节点并行运行且互不干扰。

实现方案

采用ROS2的namespace机制:启动节点时在node name前添加命名空间前缀(如/robot1/cmd_vel),即可自动隔离所有话题、服务、参数和节点名。本案例使用launch文件同时启动两个模拟机器人节点,每个节点发布各自命名空间下的速度指令话题。

环境依赖

  • Ubuntu 22.04 + ROS2 Humble(或更高版本)
  • 已安装rclpy和launch包

完整代码

文件1:robot_node.py(机器人模拟节点,发布速度指令)

```python #!/usr/bin/env python3 import rclpy from rclpy.node import Node from std_msgs.msg import String class RobotNode(Node): def __init__(self, robot_id): # 节点名带命名空间前缀,例如 /robot1/robot_node super().__init__(f'robot_{robot_id}_node') self.pub = self.create_publisher(String, f'cmd_vel', 10) self.timer = self.create_timer(1.0, self.publish_cmd) self.robot_id = robot_id self.get_logger().info(f'Robot {robot_id} started, publishing on topic: {self.pub.topic_name}') def publish_cmd(self): msg = String() msg.data = f'Robot {self.robot_id}: move forward' self.pub.publish(msg) def main(args=None): rclpy.init(args=args) import sys robot_id = sys.argv[1] if len(sys.argv) > 1 else '1' node = RobotNode(robot_id) try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ```

文件2:multi_robot_launch.py(启动两个命名空间隔离的机器人)

```python from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ # 机器人1:命名空间 /robot1 Node( package='your_pkg', executable='robot_node', name='robot_node', namespace='robot1', parameters=[{'robot_id': '1'}], output='screen' ), # 机器人2:命名空间 /robot2 Node( package='your_pkg', executable='robot_node', name='robot_node', namespace='robot2', parameters=[{'robot_id': '2'}], output='screen' ), ]) ```

文件3:package.xml(补充依赖声明)

```xml your_pkg 0.0.1 Multi-robot namespace demo Your Name Apache-2.0 rclpy std_msgs launch_ros ament_python ```

运行与验证

编译与运行:

```bash # 在ROS2工作空间下 colcon build --packages-select your_pkg source install/setup.bash ros2 launch your_pkg multi_robot_launch.py ```

验证步骤:

  1. 新终端执行ros2 node list,应看到/robot1/robot_node和/robot2/robot_node两个独立节点名。
  2. 执行ros2 topic list,应看到/robot1/cmd_vel和/robot2/cmd_vel两个独立话题。
  3. 分别订阅两个话题验证数据隔离:
```bash ros2 topic echo /robot1/cmd_vel # 预期输出:Robot 1: move forward(每1秒重复) ros2 topic echo /robot2/cmd_vel # 预期输出:Robot 2: move forward(每1秒重复) ```

通过判定标准:两个话题同时输出各自机器人的数据,且互不混叠;节点列表和话题列表均带独立命名空间前缀。

关键说明

  • launch文件中namespace参数是隔离的核心,节点内创建话题时无需手动加前缀,ROS2会自动拼接。
  • 若需在节点内获取完整话题名,可通过self.pub.topic_name查看(如代码中日志所示)。
  • 参数robot_id通过launch传入,用于区分不同机器人的行为逻辑。
ROS2 多机器人命名空间隔离架构 /robot1 命名空间 robot_node cmd_vel 发布 /robot1/cmd_vel /robot2 命名空间 robot_node cmd_vel 发布 /robot2/cmd_vel 隔离 同名话题 cmd_vel 因命名空间不同而完全隔离,互不干扰