底层模块提供能力,应用状态机决定何时组合这些能力。当前工程用模式状态表示“正在执行哪类任务”,再用循迹阶段表示“任务进行到哪一步”,最后通过统一停机收拢所有退出路径。
| 文档属性 | 内容 |
|---|---|
| 文档编号 | 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_SENSOR | 30 秒配置继续等待单路命中 | 终点图案已确认 |
| LEFT_STOP_DELAY | 按当前配置执行最终短阶段 | 结束条件满足 |
阶段名称和转移由当前代码确认。具体距离、速度和时间是调试参数,不能脱离赛道、车轮与供电条件复制到另一辆车。
4. 启动一个循迹任务发生什么
TrackMode_StartProfile() 不是只设置一个标志,而是执行完整启动事务:
- 选择 20 秒或 30 秒配置。
- 设置运行模式与目标速度。
- 清除上一轮距离、PWM、转向与阶段状态。
- 在短临界区内清左右编码器增量和累计值。
- 设置起始 tick。
- 允许电机工作。
- 清目标斜坡和速度 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. 新增任务模式的接入模板
- 定义模式及其唯一状态所有者。
- 定义启动前置条件和输入参数校验。
- 启动时统一清理冲突模式与控制历史。
- 用周期状态机推进长流程。
- 输出左右目标 RPM,不直接写 TB6612。
- 定义正常完成、人工中止和错误退出。
- 为 OLED、串口和外部同步提供可观测状态。
- 复用统一停机路径。
本篇总结
- 模式回答“执行什么任务”,阶段回答“任务进行到哪一步”,两者不应混在底层驱动中。
- Tracker 任务推进感知与阶段,PID 任务生成目标并闭环执行。
- 延时、等待终点等长流程采用基于 tick 的状态机,不阻塞调度器。
- 启动和停止都是系统级事务,需要同步复位模式、阶段、控制历史、输出和协同信号。
上一篇:08|人机交互与可观测性
下一篇:10|整车协作