一、FSM 的基本概念

FSM 是 Finite State Machine,有限状态机

在机器人任务中,FSM 用来描述机器人处于哪个任务阶段,以及收到事件后应该切换到哪个状态。

核心公式可以理解为:

当前状态 + 输入事件 = 下一个状态

例如机器人执行“寻找目标并靠近”的任务时,不应该一直发布同一个速度,而是要经历:

空闲 → 准备 → 搜索 → 靠近 → 停止

FSM 的价值是把复杂任务拆成清晰状态,避免控制逻辑写成一堆混乱的 if-else


二、状态和事件的区别

FSM 中最重要的是区分 状态 state事件 event

概念

含义

项目例子

状态

机器人当前处于什么阶段

IDLESEARCHAPPROACHERROR

事件

触发状态变化的输入

starttarget_foundtarget_reachederror

状态表示“现在是什么”。 事件表示“发生了什么”。

在我的项目里:

topic

含义

/task/event

输入给 FSM 的事件

/task/state

FSM 输出的当前状态

所以 /task/event/task/state 不能混用。前者是触发条件,后者是任务结果。


三、FSM 状态设计

我项目中设计了 7 个状态。

状态

中文含义

任务含义

IDLE

空闲

等待任务开始

STAND

站立准备

模拟机器人进入准备姿态

SEARCH

搜索

原地旋转寻找目标

APPROACH

靠近

发现目标后向目标靠近

STOP

停止

到达目标后停止

REPORT

汇报

可扩展为任务完成上报

ERROR

异常

安全保护触发后的异常状态

主状态转移关系:

当前状态

事件

下一个状态

IDLE

start

STAND

STAND

stand_done

SEARCH

SEARCH

target_found

APPROACH

APPROACH

target_reached

STOP

异常转移关系:

当前状态

事件

下一个状态

任意运行状态

error

ERROR

ERROR

reset

IDLE

注意:stand_done 只在 STAND 状态下有效。如果机器人还在 IDLE,直接发送 stand_done 被忽略是正常现象。


四、task_fsm_node 的职责

task_fsm_node 是状态机节点。

它只负责一件事:

接收任务事件,更新任务状态,发布当前状态。

项目

内容

订阅

/task/event

发布

/task/state

输入

startstand_donetarget_foundtarget_reachedtarget_losterrorreset

输出

IDLESTANDSEARCHAPPROACHSTOPREPORTERROR

它不直接发布 /cmd_vel

这样设计的核心思想是:

FSM 负责“任务决策”,不负责“底层运动”。

也就是说:

节点

负责问题

task_fsm_node

机器人现在应该处于哪个任务阶段

task_motion_node

这个状态下应该怎么动

robot_control_node

如何把速度交给底层 driver

MockDogDriver

如何模拟机器人执行

这种分层让后续升级更容易。比如以后把 APPROACH 从固定前进改成视觉跟随,不需要重写 FSM。


五、视觉桥接节点的作用

视觉节点输出的是感知结果,例如是否检测到目标、置信度、目标框大小、目标位置等。

但 FSM 不应该直接处理复杂视觉字段。

所以需要 vision_fsm_bridge_node,它的作用是:

把视觉检测结果转换成 FSM 能理解的任务事件。

输入

作用

/perception/target

接收目标检测结果

/task/state

判断当前 FSM 状态

/task/event

发布任务事件

核心逻辑:

当前状态

视觉条件

发布事件

SEARCH

检测到有效目标

target_found

APPROACH

目标面积足够大

target_reached

APPROACH

长时间没看到目标

target_lost

这样视觉层不会直接控制机器人,而是通过事件影响 FSM,再由 FSM 影响运动。


六、目标检测字段与任务事件

/perception/target 中常见字段如下。

字段

含义

用途

detected

是否检测到目标

判断有没有目标

confidence

检测置信度

过滤不可靠检测

area_ratio

目标框面积占图像比例

判断目标是否足够近

center_x

目标中心横坐标

可用于左右方向判断

offset_x

目标相对中心的偏移

可用于转向控制

class_name

目标类别

YOLO 中区分物体类别

frame_id

坐标系名称

后续结合 TF 使用

三个核心事件:

事件

含义

常见状态变化

target_found

搜索时发现目标

SEARCH -> APPROACH

target_reached

目标已经足够近

APPROACH -> STOP

target_lost

靠近过程中目标丢失

APPROACH -> SEARCH

其中 area_ratio 是一个简化距离判断方法。

目标越靠近相机,通常检测框越大;因此 area_ratio 越大,可以认为目标越近。


七、task_motion_node 的职责

task_motion_node 负责把任务状态转换成速度命令。

输入

输出

/task/state

/cmd_vel

它不关心视觉细节,也不关心事件来源,只关心当前状态。

当前运动规则:

FSM 状态

运动行为

IDLE

停止

STAND

停止

SEARCH

原地旋转

APPROACH

低速前进

STOP

停止

REPORT

停止

ERROR

停止

这体现了一个重要工程原则:决策和控制分离。

FSM 只决定“现在是什么状态”,motion 节点负责“这个状态下发什么速度”。

尤其要注意:ERROR 状态下必须输出零速度,因为异常时默认行为应该是停止,而不是继续运动。


八、robot_control_node、driver 与 heartbeat

robot_control_node 是 ROS2 速度命令和底层机器人 driver 之间的桥。

上层输入

中间节点

底层执行

/cmd_vel

robot_control_node

MockDogDriver

这样上层控制逻辑不需要知道具体机器人 SDK 的细节。

上层只发布标准 ROS2 速度命令,底层 driver 负责适配具体机器人。

heartbeat 是控制安全机制。

heartbeat 状态

控制行为

正常

执行 /cmd_vel

超时

忽略 /cmd_vel,调用 stop()

未启动

认为不安全,不执行速度

heartbeat 的意义是:

防止上层节点异常退出后,机器人继续执行旧速度命令。


九、安全保护节点

task_safety_node 是独立安全监控节点。

它不直接发布 /cmd_vel,而是把异常转换成 FSM 事件。

订阅

作用

/robot/state

判断机器人本体是否安全

/task/state

判断任务是否卡住或超时

发布

内容

/task/event

error

安全处理链路:

异常

安全节点输出

FSM 状态

运动结果

低电量

error

ERROR

停止

急停

error

ERROR

停止

任务超时

error

ERROR

停止

这个设计的好处是:

安全节点不抢控制权,而是让 FSM 进入 ERROR,再由 motion 节点统一输出零速度。

这样系统不会出现多个节点同时发布 /cmd_vel 的控制冲突。


十、完整任务系统的数据流

主任务链路:

/perception/targetvision_fsm_bridge_node/task/eventtask_fsm_node/task/statetask_motion_node/cmd_velrobot_control_nodeMockDogDriver

安全保护链路:

/robot/state + /task/statetask_safety_node/task/event:errortask_fsm_nodeERRORtask_motion_node/cmd_vel=0

对应工程分层:

层级

项目模块

感知层

AprilTag / YOLO / /perception/target

事件桥接层

vision_fsm_bridge_node

决策层

task_fsm_node

控制层

task_motion_node

执行层

robot_control_node + MockDogDriver

安全层

heartbeat + task_safety_node

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐