管理入口

请输入管理密码。此密码门槛仅用于前端原型,不提供真正的仓库权限保护。

0%
TI小车实战

09|应用层状态机:模式、阶段与统一停机

拆解 MSPM0G35XX TI 小车如何用模式状态、循迹阶段和统一停机路径,把多个底层模块组织成可预测任务。

底层模块提供能力,应用状态机决定何时组合这些能力。当前工程用模式状态表示“正在执行哪类任务”,再用循迹阶段表示“任务进行到哪一步”,最后通过统一停机收拢所有退出路径。

文档属性内容
文档编号TI-CAR-09
模式状态ModeState_App.c
循迹阶段TrackMode_App.c
调度编排Task_App.c
核心原则单一输出链、显式阶段、统一退出

1. 模式与阶段为什么分开

“循迹模式正在运行”是模式,“正在加速”是阶段。模式决定系统采用哪套业务逻辑,阶段决定同一模式内部的速度、转向限幅和结束条件。

模式:位置任务 / 循迹任务 / 自定义循迹
阶段:加速 → 巡航 → 减速 → 等待终点 → 停止延时

如果把所有条件都堆在一个函数里,新增任务会造成大量交叉分支。分开后,模式负责选择流程,阶段负责推进流程。

2. ModeState 保存什么

当前模式状态集中保存:

  • 自定义循迹是否启用;
  • 自定义转向因子;
  • 循迹调试模式是否启用;
  • 当前目标速度。

ModeState_ClearRunModes() 可以一次清除运行模式和目标速度。它是统一停机的重要组成,而不是让每个任务分别猜哪些标志需要复位。

3. 循迹阶段有哪些

阶段主要行为进入依据
ACCELERATING按启动斜坡放大基础速度和转向任务刚启动
CRUISING按配置速度持续循迹启动斜坡结束
DECELERATING按剩余距离限制基础速度接近左右目标距离
WAITING_FOR_FINISH_SENSOR低速等待连续终点图案左右目标距离达到
WAITING_FOR_SINGLE_SENSOR30 秒配置继续等待单路命中终点图案已确认
LEFT_STOP_DELAY按当前配置执行最终短阶段结束条件满足

阶段名称和转移由当前代码确认。具体距离、速度和时间是调试参数,不能脱离赛道、车轮与供电条件复制到另一辆车。

4. 启动一个循迹任务发生什么

TrackMode_StartProfile() 不是只设置一个标志,而是执行完整启动事务:

  1. 选择 20 秒或 30 秒配置。
  2. 设置运行模式与目标速度。
  3. 清除上一轮距离、PWM、转向与阶段状态。
  4. 在短临界区内清左右编码器增量和累计值。
  5. 设置起始 tick。
  6. 允许电机工作。
  7. 清目标斜坡和速度 PID 历史。

这保证新任务从已知初始状态开始。若中途跳过任一步,上一轮状态可能污染新任务。

5. 感知与控制任务各自推进什么

Tracker 任务每 5 ms 采样五路输入,并调用 TrackMode_OnTrackerSample() 推进终点和距离阶段。PID 任务每 10 ms 调用 TrackMode_RunDebug() 生成左右目标,再完成速度闭环和电机输出。

Tracker 任务:更新“看到了什么、阶段是否变化”
PID 任务:根据当前阶段计算“左右轮应该多快”

两者通过明确状态协作。Tracker 不直接写 PWM,PID 也不重复读取所有 GPIO。

6. 为什么阶段逻辑不应阻塞等待

例如停止延时不是:

Delay(300);
stop();

而是记录阶段起始 tick,之后每次 Tracker 任务运行时检查经过时间。等待期间编码器、PID、OLED 和按键任务仍可运行。

这正是非抢占式系统的基本写法:长过程必须拆成“保存状态—下次继续”,不能把时间消耗在一个函数内部。

7. 统一停机做了什么

Task_StopAll() 收口正常完成、按键中止和部分异常路径:

  • 撤销外部运行信号;
  • 停止位置控制;
  • 清运行模式;
  • 复位循迹阶段;
  • 完成并复位正常停车流程;
  • 左右 PWM 写零;
  • 关闭蜂鸣器并清脉冲状态。

此外,set_motor_disable() 可进一步拉低 TB6612 STBY。不同停机路径应明确是否需要保留驱动使能以完成缓停,何时再进入硬停机。

8. 正常完成与异常停止要区分

当前工程有任务完成蜂鸣和完成状态,但企业化设计还应把退出原因结构化:

退出类型例子应保留的信息
正常完成距离和终点条件成立完成时刻、距离、最终误差
人工中止按键停止中止来源、当时阶段
传感器异常连续丢线、IMU 错误错误码、连续次数
执行异常单轮堵转、速度不跟随目标、实际、PWM
调度异常任务超时或周期严重抖动任务名、最大耗时

目前并非所有异常都已有检测,因此这些是后续接口方向,不应写成现成功能。

9. 状态所有权

模式、阶段、控制器与驱动各自拥有不同状态:

  • ModeState 拥有当前运行模式。
  • TrackMode 拥有循迹阶段、滤波和任务配置。
  • PositionControl 拥有位置目标与完成状态。
  • SpeedTarget 拥有目标斜坡和正常停车状态。
  • SpeedPID 拥有左右控制器历史。
  • Motor BSP 拥有输出极性、编码器与当前 PWM。

跨模块修改他人内部状态会破坏复位语义。应用应通过 Start、Stop、Reset、Update、Get 等接口协作。

10. 新增任务模式的接入模板

  1. 定义模式及其唯一状态所有者。
  2. 定义启动前置条件和输入参数校验。
  3. 启动时统一清理冲突模式与控制历史。
  4. 用周期状态机推进长流程。
  5. 输出左右目标 RPM,不直接写 TB6612。
  6. 定义正常完成、人工中止和错误退出。
  7. 为 OLED、串口和外部同步提供可观测状态。
  8. 复用统一停机路径。

本篇总结

  • 模式回答“执行什么任务”,阶段回答“任务进行到哪一步”,两者不应混在底层驱动中。
  • Tracker 任务推进感知与阶段,PID 任务生成目标并闭环执行。
  • 延时、等待终点等长流程采用基于 tick 的状态机,不阻塞调度器。
  • 启动和停止都是系统级事务,需要同步复位模式、阶段、控制历史、输出和协同信号。

上一篇:08|人机交互与可观测性

下一篇:10|整车协作

输入标题、正文关键词或标签,查找文章。