3. 状态机基础:状态机定义、状态、事件、转移、动作,有限状态机(FSM)与分层状态机(HSM)的区别
在运动控制系统中,无论是伺服驱动器的使能与急停逻辑、CNC 的自动换刀流程,还是机器人关节的轨迹切换与抱闸时序,其控制逻辑本质上都遵循“当前处于什么状态 → 收到什么事件 → 执行什么动作 → 转移到哪个新状态”的循环。状态机(State Machine)正是对这种离散事件驱动逻辑的数学抽象与工程实现。本章将系统讲解状态机的核心要素——状态、事件、转移、动作,并深入对比有限状态机(FSM)与分层状态机(HSM)在运动控制场景中的适用边界与设计取舍。
3.1 状态机核心要素:状态、事件、转移、动作
3.1.1 核心原理:四个要素的严谨定义
状态机是一种以“状态”为中心的数学模型,用于描述系统在离散时间点上的行为。其四个核心要素缺一不可:
- 状态(State):系统在某一时刻的稳定情形,由内部变量和外部输出共同刻画。在运动控制中,典型状态包括
IDLE(待机)、HOMING(回零)、RUN(运行)、ALARM(报警)、STOP(停止)等。状态必须满足“互斥性”(同一时刻只能处于一个状态)和“完整性”(任何时刻必处于某个状态)。 - 事件(Event):触发状态转移的外部或内部信号。事件可以是布尔量变化(如限位开关触发)、定时器超时、通信指令(如上位机发送
START命令)、或内部故障标志(如驱动器过流)。事件是瞬时的,不占用时间。 - 转移(Transition):从当前状态到下一个状态的路径,由“事件 + 条件(Guard)”共同决定。条件是可选的,例如“收到
START事件且伺服使能已就绪”才允许从IDLE转移到RUN。转移具有原子性——要么不发生,要么完整执行。 - 动作(Action):在转移过程中或进入/退出状态时执行的操作。动作分为三类:进入动作(Entry Action,进入状态时执行)、退出动作(Exit Action,离开状态时执行)、转移动作(Transition Action,转移过程中执行)。例如,进入
RUN状态时执行“解除抱闸”,退出时执行“使能抱闸”。
3.1.2 判断方法与操作流程:如何设计一个状态机
在运动控制项目中,设计状态机应遵循以下流程:
- 列出所有稳定状态:从系统需求中提取。例如,一个伺服轴至少需要
POWER_OFF、POWER_ON、HOMING、READY、RUN、ALARM六个状态。 - 定义事件集:包括外部指令(
START、STOP、RESET)、内部信号(HOME_SENSOR、LIMIT_POS、FAULT)、定时事件(TIMEOUT)。 - 绘制状态转移表:以状态为行、事件为列,填写目标状态和动作。该表是后续编码和测试的依据。
- 定义动作清单:明确每个动作对应的物理操作,如
Servo_Enable()、Brake_Release()、Alarm_Lamp_On()。 - 验证完备性与安全性:检查每个状态对每个事件是否有明确响应;对未定义的事件应有默认处理(如忽略或进入
ALARM)。
3.1.3 案例拆解:伺服驱动器使能与急停逻辑
以某型伺服驱动器的使能控制为例,其状态机定义如下:
| 当前状态 | 事件 | 条件 | 动作 | 下一状态 |
|---|---|---|---|---|
| POWER_OFF | POWER_ON_CMD | 主回路正常 | 闭合主接触器 | POWER_ON |
| POWER_ON | ENABLE_CMD | 无报警 | 使能脉冲输出 | READY |
| READY | START_CMD | 抱闸已释放 | 解除抱闸,开始运动 | RUN |
| RUN | ESTOP | — | 立即封锁输出,抱闸闭合 | ALARM |
| ALARM | RESET_CMD | 故障已清除 | 清除故障寄存器 | POWER_ON |
该案例中,ESTOP 事件在 RUN 状态被处理,但如果在 READY 状态收到 ESTOP,同样需要响应——这暴露了 FSM 的一个典型问题:公共事件需要在每个状态重复处理,导致代码冗余。
3.1.4 常见误区与总结复盘
RUN 状态,用速度规划参数区分。误区二:忽略转移条件。仅凭事件触发转移,未检查安全条件(如急停未复位时不允许启动),会导致设备误动作。
误区三:动作写在错误的位置。将进入动作写在转移动作中,导致状态重入时动作不执行。
3.2 有限状态机(FSM)与分层状态机(HSM)的区别
3.2.1 核心原理:从扁平到分层的演进
有限状态机(FSM)是最经典的状态机模型,所有状态处于同一层级,每个状态独立处理所有事件。其优点是结构简单、易于理解和调试,适合状态数量较少(通常不超过 10 个)的场景。然而,当运动控制系统复杂度上升——例如多轴协调、工艺切换、异常恢复——FSM 的状态数量会急剧膨胀,状态之间的转移关系变得混乱,代码维护成本显著增加。
分层状态机(HSM)通过引入“父状态-子状态”的嵌套结构解决了这一问题。其核心思想是:子状态继承父状态的行为。如果子状态未处理某个事件,该事件自动向上传递给父状态处理。例如,在 POWER_ON 父状态下有 HOMING、READY、RUN 三个子状态,当任何子状态收到 SHUTDOWN 事件时,如果子状态未定义该事件的处理,则父状态统一执行“断电时序”,无需在每个子状态中重复编写。
3.2.2 判断方法与选择标准
在实际项目中,选择 FSM 还是 HSM 可参考以下标准:
| 判断维度 | 选择 FSM | 选择 HSM |
|---|---|---|
| 状态数量 | ≤ 10 个 | > 10 个,且有公共行为 |
| 事件处理 | 每个状态对事件响应差异大 | 多个状态对同一事件响应相同 |
| 扩展需求 | 需求稳定,很少增加状态 | 预计会持续增加子状态或工艺分支 |
| 团队经验 | 团队对 FSM 熟悉,项目周期紧 | 团队有面向对象设计经验,愿意投入前期设计 |
| 实时性要求 | 硬实时,要求事件响应延迟极低 | 软实时,允许少量事件向上传递的开销 |
3.2.3 案例拆解:CNC 自动换刀流程的 HSM 设计
以 CNC 加工中心的自动换刀(ATC)为例,其流程包含:主轴定向、刀套下翻、抓刀、拔刀、刀库旋转、插刀、刀套复位等多个步骤。若使用 FSM,每个步骤都是一个状态,且每个状态都需要处理急停、暂停、报警等公共事件,状态数可能超过 20 个,转移关系复杂。
采用 HSM 设计后,结构如下:
- 父状态
ATC_ACTIVE:处理公共事件——ESTOP(立即停止刀库电机并抱闸)、PAUSE(暂停当前动作)、TIMEOUT(进入ATC_ALARM)。 - 子状态:
SPINDLE_ORIENT(主轴定向)、TOOL_GRASP(抓刀)、TOOL_PULL(拔刀)、MAGAZINE_ROTATE(刀库旋转)、TOOL_INSERT(插刀)。 - 子状态间转移:如
SPINDLE_ORIENT完成(事件ORIENT_DONE)→TOOL_GRASP;TOOL_GRASP完成(GRASP_DONE)→TOOL_PULL。
当在 MAGAZINE_ROTATE 子状态中收到 ESTOP 事件时,子状态本身不处理该事件,事件自动上抛至 ATC_ACTIVE 父状态,父状态统一执行“刀库电机急停 + 抱闸 + 进入 ATC_ALARM”。这样避免了在 5 个子状态中重复编写急停逻辑。
该设计的实际效果:状态转移表从 FSM 的 20×8 矩阵缩减为 HSM 的 5×3(子状态内部转移)+ 1×4(父状态公共事件),代码量减少约 40%,且新增一个子状态(如“刀具吹屑”)时,只需定义其特有事件,公共事件自动继承。
3.2.4 常见误区与总结复盘
误区二:父状态与子状态事件冲突。当子状态定义了与父状态相同的事件时,子状态优先处理,父状态逻辑被屏蔽。设计时需明确优先级规则。
误区三:忽略状态转移的“历史记录”。HSM 支持“历史状态”记忆(如从
RUN 退出后重新进入 POWER_ON 时恢复到 RUN),但若未正确实现,可能导致恢复后状态不一致。
POWER_ON、HOMING、RUN、ESTOP 等公共状态,而每个关节内部使用 FSM 处理 POSITION、VELOCITY、TORQUE 等控制模式切换。这样既保证了公共逻辑的复用,又保持了底层控制的简洁性。
状态机是运动控制软件的核心骨架。理解状态、事件、转移、动作四要素的严谨含义,掌握 FSM 与 HSM 的适用边界,是设计可靠、可维护运动控制程序的基础。在实际工程中,建议先用状态转移表梳理逻辑,再根据状态数量和公共行为选择 FSM 或 HSM,最后通过代码评审和仿真测试验证状态机的完备性与安全性。