# CH8通道抖动导致状态机重复重置问题修复 ## 问题描述 实车测试时,车辆在原点和第二个路径点之间反复切换,无法正常完成路径跟踪。Log显示状态机反复从`follow_path`回到`goto_start`。 ## 根本原因 **CH8通道(自动模式开关)剧烈抖动,在1024和1800之间反复跳变。** 从log分析(`python/hitl/runlog.txt`): ``` [HOST=1764923751.607s] CH8 crossed threshold: 1800 -> 1024 [HOST=1764923751.686s] *** Auto mode triggered! Resetting to GOTO_START *** [HOST=1764923751.688s] CH8 crossed threshold: 1024 -> 1800 [HOST=1764923752.166s] CH8 crossed threshold: 1800 -> 1024 [HOST=1764923752.387s] *** Auto mode triggered! Resetting to GOTO_START *** [HOST=1764923752.389s] CH8 crossed threshold: 1024 -> 1800 ``` **每次CH8跨越阈值1500时,都会触发自动模式的开关,导致状态机被`MC_Init`重新初始化到`GOTO_START`。** ### 触发频率 在短短10秒内,CH8跨越阈值触发了**50+次**"Auto mode triggered",导致: - 车辆无法完成路径跟踪 - 目标点在原点和第二个路径点之间反复切换 - 状态机不断被重置 ## 解决方案:CH8迟滞(Hysteresis) ### 原理 使用**施密特触发器**原理,为CH8设置两个阈值: ``` 手动模式状态: - 保持手动,直到 CH8 > 1600 (高阈值) - 当 CH8 > 1600 时 → 切换到自动模式 自动模式状态: - 保持自动,直到 CH8 < 1400 (低阈值) - 当 CH8 < 1400 时 → 切换到手动模式 死区(1400-1600): - 在此区间内,保持之前的状态不变 - 避免在阈值附近抖动时反复切换 ``` ### 实现代码 **文件:`STM32H743/APL/motion_control_task.c`** ```c static HIDO_BOOL s_ch8_auto_state = HIDO_FALSE; /* CH8迟滞状态 */ /* CH8迟滞阈值定义 */ #define CH8_THRESHOLD_ENTER 1600 // 进入自动模式的阈值 #define CH8_THRESHOLD_EXIT 1400 // 退出自动模式的阈值 if (s_ch8_auto_state == HIDO_FALSE) { /* 当前在手动模式,检查是否应该进入自动模式 */ if (ch8 > CH8_THRESHOLD_ENTER) { s_ch8_auto_state = HIDO_TRUE; } } else { /* 当前在自动模式,检查是否应该退出自动模式 */ if (ch8 < CH8_THRESHOLD_EXIT) { s_ch8_auto_state = HIDO_FALSE; } } /* 使用迟滞状态而不是直接使用CH8值 */ HIDO_BOOL current_auto_condition = (sbus_valid == HIDO_TRUE && s_ch8_auto_state == HIDO_TRUE && gps_ready == HIDO_TRUE); ``` ### 优化后的日志输出 **修改前:** ``` [MC_CTRL] CH8 crossed threshold: 1800 -> 1024 (threshold=1500) [MC_CTRL] CH8 crossed threshold: 1024 -> 1800 (threshold=1500) ... (每次跨越1500都记录,输出大量重复信息) ``` **修改后:** ``` [MC_CTRL] CH8 entered MANUAL zone: 1800 -> 1024 (<1400) [MC_CTRL] CH8 entered AUTO zone: 1024 -> 1800 (>1600) ... (只记录真正的状态切换,简洁清晰) ``` ## 修改内容 ### 1. 添加CH8迟滞逻辑(第219-243行) - 定义了`s_ch8_auto_state`静态变量来保存CH8的迟滞状态 - 定义了`CH8_THRESHOLD_ENTER`(1600)和`CH8_THRESHOLD_EXIT`(1400) - 实现了施密特触发器逻辑 ### 2. 修改自动模式条件判断(第245行) - 从:`ch8 > MOTION_SBUS_AUTO_THRESHOLD_US` (1500) - 改为:`s_ch8_auto_state == HIDO_TRUE`(使用迟滞状态) ### 3. 优化日志输出(第272-287行) - 只记录CH8状态真正改变的情况(跨越迟滞边界) - 减少了日志噪音,便于调试 ### 4. 增强触发日志(第251-254行) - 在"Auto mode triggered"时,额外输出CH8迟滞状态的变化 - 便于确认迟滞逻辑是否正常工作 ## 预期效果 ### 修复前 - CH8在1024和1800之间跳动 - 每次跨越1500都触发重新初始化 - 短时间内触发50+次 - 车辆无法完成路径跟踪 ### 修复后 - CH8必须超过1600才能进入自动模式 - CH8必须低于1400才能退出自动模式 - 在1400-1600区间内,状态保持稳定 - 即使CH8在此区间抖动,也不会触发重新初始化 - 车辆能正常完成路径跟踪 ## 测试验证 1. **编译并烧录**最新代码 2. **测试场景1:正常切换** - 手动模式(CH8=1000) - 推高遥控器拨杆,CH8上升到1700 → 应该只触发一次"Auto mode triggered" - 车辆开始自动运行 3. **测试场景2:抖动测试** - 将遥控器拨杆置于1500附近(死区内) - 轻微抖动,CH8在1400-1600之间波动 - 应该**不会**触发"Auto mode triggered" - 状态保持稳定 4. **测试场景3:退出自动模式** - 自动模式运行中(CH8=1800) - 拉低遥控器拨杆,CH8下降到1300 → 应该切换到手动模式 - 状态机保持当前状态(不重新初始化) ## 技术细节 ### 为什么选择1600/1400? - **原阈值1500**:CH8在此附近抖动最剧烈 - **死区200**:根据log观察,CH8抖动幅度约±100-300 - **1600/1400**:提供足够的死区,避免误触发 ### 迟滞的优势 1. **抗干扰**:对EMI、ADC噪声、机械抖动不敏感 2. **稳定性**:一旦进入某个状态,需要明确的操作才能退出 3. **用户体验**:避免在临界点附近的不确定行为 ### 适用场景 迟滞逻辑特别适用于: - 模拟开关输入(如PWM通道) - 温度控制(恒温器) - 电池电量检测 - 任何需要避免在阈值附近反复切换的场景 ## 相关文件 - `STM32H743/APL/motion_control_task.c` - 主要修改 - `BUGFIX_HEADING_CONTROL.md` - 之前修复的航向控制问题 - `DEBUG_GOTO_START_LOOP.md` - 问题诊断文档 ## 总结 通过为CH8通道添加迟滞逻辑,彻底解决了因通道抖动导致的状态机反复重置问题。这是一个经典的**去抖动(Debouncing)**应用案例,使用施密特触发器原理提高了系统的稳定性和鲁棒性。 **关键教训**:对于任何模拟开关输入,特别是可能在阈值附近抖动的信号,都应该考虑添加迟滞或时间延迟来提高稳定性。