ROS2 多机器人通用 Driver 层复盘:BaseRobotDriver 到多平台 Mock 切换实现
2026/6/13 2:07:57 网站建设 项目流程

1. Driver 层的作用

在机器人二次开发中,不能把所有逻辑都写在 ROS2 节点里。

ROS2 节点更适合负责:

Topic 通信 Service 调用 参数读取 launch 启动 日志输出 任务逻辑组织

而机器人底层相关能力应该交给 Driver 层,例如:

连接机器人 读取状态 发送速度 普通停止 急停 模式切换

这样设计的核心思想是:

ROS2 节点负责“通信和调度”,Driver 层负责“真正控制机器人”。

后续如果从 Mock 机器人换成真实四足机器人、人形机器人或者机械臂,只需要替换 Driver,不需要大改上层 ROS2 节点。


2. BaseRobotDriver 统一接口

BaseRobotDriver是所有机器人 Driver 的统一标准。

它不直接控制机器人,而是规定每一种机器人都应该具备哪些基础能力。

推荐接口:

connect() get_state() send_velocity(linear_x, angular_z) stop() emergency_stop() set_mode(mode)

每个接口的含义:

接口

作用

connect()

连接机器人,或初始化模拟机器人

get_state()

获取机器人状态,例如电量、速度、模式、急停状态

send_velocity()

发送速度命令

stop()

普通停止

emergency_stop()

急停,进入安全停止状态

set_mode()

切换机器人模式,例如stand/walk/stop/estop


3. MockRobotDriver 的意义

MockRobotDriver是一个模拟机器人驱动。

它不需要真实硬件,而是在代码里模拟机器人状态和控制行为。

它可以模拟:是否连接 connected 当前模式 mode 当前电量 battery 当前线速度 linear_x

当前角速度 angular_z 是否急停 emergency_stop

示例状态:{

"connected": true,

"mode": "stand",

"battery": 87.5,

"linear_x": 0.0,

"angular_z": 0.0,

"emergency_stop": false

}

没有真实机器人时,也能先把 ROS2 通信、状态发布、速度控制、安全保护这些上层逻辑跑通。


4./robot/state状态发布

机器人状态是持续变化的数据,所以应该用 ROS2 Topic 发布。

推荐话题名:/robot/state

前期为了简单,可以用:std_msgs/msg/String 里面放 JSON 字符串。

数据流如下:

MockRobotDriver | | get_state() v state_publisher_node | | publish v /robot/state

也就是说:

  1. state_publisher_node定时调用driver.get_state()
  2. Driver 返回当前机器人状态
  3. 节点把状态发布到/robot/state
  4. 其他模块,比如 FSM、安全模块、可视化模块,都可以订阅这个状态

验证命令:ros2 topic echo /robot/state

也可以查看发布频率:ros2 topic hz /robot/state


5./cmd_vel速度控制

移动机器人常用/cmd_vel表示速度控制命令。

话题名:/cmd_vel

消息类型:geometry_msgs/msg/Twist

常用字段:linear.x # 前进 / 后退速度 angular.z # 左转 / 右转角速度

控制节点的数据流:

/cmd_vel | | Twist 消息 v control_node | | 提取 linear.x 和 angular.z v driver.send_velocity()

也就是说,control_node不直接控制硬件,而是把 ROS2 收到的速度命令转交给 Driver 层。

/cmd_vel负责 ROS2 通信,send_velocity()负责底层控制。


6. 速度限幅

速度控制不能完全相信上游输入。

因为/cmd_vel可能来自:键盘控制节点 视觉闭环节点 FSM 状态机 导航模块 测试脚本

如果某个节点发出了过大的速度,机器人可能发生危险。所以控制节点里要加入速度限幅。

例如参数:max_linear_speed: 0.5 max_angular_speed: 1.0

如果收到:linear.x = 9.9 angular.z = 9.9

实际下发给 Driver 的速度应该被限制成:linear.x = 0.5 angular.z = 1.0

超过最大速度,就裁剪到安全范围内。


7. 普通停止和急停

机器人停止至少要区分两种:普通停止 stop() 急停 emergency_stop()

功能

含义

后续能否继续运动

stop()

普通停止,把速度清零

可以

emergency_stop()

急停,进入安全锁定状态

不应该直接继续

stop()是“停一下”,emergency_stop()是“危险情况下立刻停,并且锁住运动”。

急停后,普通速度命令不应该继续生效。

例如:

触发 emergency_stop | v 速度清零 | v emergency_stop = True | v 后续 send_velocity() 被拒绝

急停可以设计成 Service:/robot/emergency_stop

调用命令:ros2 service call /robot/emergency_stop std_srvs/srv/Trigger "{}"


8. Heartbeat 心跳机制

Heartbeat 中文叫心跳机制。它用来判断控制端是否还在线。

例如控制端持续发送:/robot/heartbeat

如果机器人控制节点长时间没有收到心跳,就认为控制端可能崩溃或断开连接。

这时应该自动调用:driver.stop()

它主要解决这个危险场景:

程序崩溃后,机器人继续执行最后一次速度命令。

例如机器人正在前进,控制程序突然退出,如果没有心跳超时保护,机器人可能还会保持前进状态。

心跳逻辑可以理解为:

如果当前时间 - 上一次心跳时间 > heartbeat_timeout 自动停止机器人

9. 多平台 Driver 切换

为了体现“多机器人平台二次开发”,不能只写一个 Mock 机器人。

可以设计多个 Driver:

BaseRobotDriver | ├── MockRobotDriver ├── MockDogDriver └── MockHumanoidDriver

它们都实现同一套接口:connect() get_state() send_velocity() stop() emergency_stop() set_mode()

区别只是底层实现不同。

例如: MockDogDriver 模拟四足机器人

MockHumanoidDriver 模拟人形机器人

MockRobotDriver 通用模拟机器人

上层 ROS2 节点不需要知道当前是哪种机器人,只需要调用统一接口。

这就是接口抽象的价值:

上层代码不变,底层 Driver 可替换。


10. 配置文件切换机器人类型

为了避免在代码里写死机器人类型,可以使用配置文件。

例如:robot_type: mock_dog max_linear_speed: 0.5 max_angular_speed: 1.0 heartbeat_timeout: 2.0

也可以切换成:robot_type: mock_humanoid

切换机器人平台时,只改配置,不改代码。


11. 推荐项目结构

可以采用下面这种结构:

robot_base/ ├── robot_base/ │ ├── drivers/ │ │ ├── base_driver.py │ │ ├── mock_robot_driver.py │ │ ├── mock_dog_driver.py │ │ └── mock_humanoid_driver.py │ │ │ ├── nodes/ │ │ ├── state_publisher_node.py │ │ └── control_node.py │ │ │ ├── config/ │ │ └── robot_config.yaml │ │ │ └── utils/ │ └── driver_factory.py │ ├── launch/ │ └── robot_base.launch.py ├── package.xml └── setup.py

重点是分清职责:

模块

职责

drivers/

封装机器人底层能力

nodes/

ROS2 通信节点

config/

参数和机器人类型配置

launch/

一键启动

driver_factory.py

根据配置创建不同 Driver

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询