# SBUS信号不稳定导致状态机反复重置 - 最终修复 ## 问题持续存在 即使过滤了1024 failsafe值,问题依然存在。从最新log分析: ``` [MC_CTRL] CH8 entered MANUAL zone: 1800 -> 120 (<1400) [MC_CTRL] *** Auto mode triggered! Resetting to GOTO_START *** [MC_CTRL] CH8 entered AUTO zone: 120 -> 1800 (>1600) [MC_CTRL] *** Stage transition: goto_start -> idle *** [MC_CTRL] CH8 recovered from failsafe (1024), count=6, new value=1953 [MC_CTRL] SBUS valid changed: 1 -> 0 [MC_CTRL] SBUS valid changed: 0 -> 1 ``` ## 根本原因分析 **SBUS信号质量极差,频繁丢失和恢复,导致:** 1. **CH8值在多个异常值之间跳动**:120、1024、1953、1800 2. **SBUS valid状态频繁切换**:信号有效→丢失→恢复 3. **每次恢复都触发"Auto mode triggered"**:导致状态机重置到GOTO_START ### 为什么1024不是唯一的failsafe值? - **1024**:SBUS_CENTER_VALUE,信号丢失时的标准返回值 - **120、1953等**:信号恢复瞬间或干扰时的异常读数 - **有效范围**:SBUS协议定义为172-1811(对应PWM 1000-2000) ## 最终修复方案 ### 修复1:扩展CH8异常值过滤 **不仅过滤1024,过滤所有不在有效范围内的值:** ```c /* 判断是否为有效SBUS值:172-1811范围内,且不是精确的1024 */ HIDO_BOOL is_valid = (ch8_raw >= 172 && ch8_raw <= 1811 && ch8_raw != 1024); if (is_valid) { ch8 = ch8_raw; /* 只更新有效值 */ } else { /* 异常值,保持之前的值 */ DBG_Printf("[MC_CTRL] CH8 failsafe detected (%u), keeping previous value=%u\r\n", ch8_raw, ch8); } ``` **过滤范围:** - `<172`:低于SBUS最小值(如120) - `=1024`:SBUS中心值(failsafe默认) - `>1811`:高于SBUS最大值(如1953) ### 修复2:只在IDLE/FINISHED状态允许重新初始化 **核心理念:正在执行任务时,忽略模式切换抖动** ```c if (s_last_auto_condition == HIDO_FALSE && current_auto_condition == HIDO_TRUE) { E_MCStage current_stage = g_motion_state.stage; if (current_stage == MC_STAGE_IDLE || current_stage == MC_STAGE_FINISHED) { /* 只有空闲或完成时才允许重新初始化 */ MC_Init(&g_motion_state, &g_motion_config, g_motion_path_xy, g_motion_path_point_count); } else { /* 正在执行任务,忽略此次模式切换(可能是信号抖动) */ DBG_Printf("[MC_CTRL] WARNING: Auto mode re-triggered during %d, ignoring (SBUS interference)\r\n", current_stage); } } ``` **逻辑:** - **IDLE/FINISHED状态**:允许重新初始化(用户真正想重新开始) - **GOTO_START/FOLLOW_PATH状态**:忽略模式切换(认为是信号干扰) ## 为什么之前的修复不够? ### 迟滞方案(保留) - **目的**:防止阈值附近的模拟量抖动 - **局限**:无法防止120→1800这种大幅跳变 ### 1024过滤方案(已扩展) - **目的**:过滤SBUS failsafe返回值 - **局限**:只过滤了1024,没有覆盖其他异常值(120、1953) ### 本次最终方案 - **范围过滤**:覆盖所有SBUS有效范围之外的值 - **状态保护**:只有在安全状态下才允许重新初始化 ## 三层防护体系 ### 第一层:CH8异常值过滤 ``` if (ch8_raw < 172 || ch8_raw > 1811 || ch8_raw == 1024) → 忽略,保持last-known-good值 ``` ### 第二层:CH8迟滞 ``` 进入自动:CH8 > 1600 退出自动:CH8 < 1400 死区:1400-1600 ``` ### 第三层:状态保护 ``` if (正在执行任务 && 检测到模式切换) → 忽略,认为是干扰 ``` ## 日志输出示例 ### 检测到异常值 ``` [MC_CTRL] CH8 failsafe detected (120), keeping previous value=1800 [MC_CTRL] CH8 failsafe detected (1953), keeping previous value=1800 ``` ### 信号恢复 ``` [MC_CTRL] CH8 recovered from failsafe, count=56, new value=1800 ``` ### 忽略干扰 ``` [MC_CTRL] WARNING: Auto mode re-triggered during 2, ignoring (SBUS interference) ``` ## 根本解决方案(硬件) **软件修复只是workaround,真正需要:** ### 立即检查: 1. **SBUS接收机天线**:检查方向、连接、损坏 2. **遥控器距离**:测试时保持在可靠距离内 3. **电磁干扰源**: - 电机/电调的EMI - GPS模块的干扰 - 其他无线设备 ### 长期优化: 1. **使用高质量SBUS接收机**:带failsafe hold功能 2. **双接收机冗余**:A/B接收机切换 3. **信号强度监控**:低于阈值时报警 4. **备用控制模式**:SBUS失效时切换到其他输入源 ## 测试验证 ### 场景1:正常启动 1. 手动模式(CH8=1000) 2. 推高遥控器拨杆到1800 3. **预期**:触发一次"Auto mode triggered",车辆开始运行 ### 场景2:运行中信号抖动 1. 自动模式运行中 2. SBUS信号短暂丢失和恢复 3. **预期**: - 看到"CH8 failsafe detected" - 看到"CH8 recovered from failsafe" - **不应该**看到"Auto mode triggered" - 车辆继续当前任务,不重新初始化 ### 场景3:运行中手动干预 1. 自动模式运行中 2. 遥控器拨杆拉低到手动模式 3. 车辆停止自动控制 4. 拨杆推回自动模式 5. **预期**:如果还在FOLLOW_PATH,忽略切换;如果已经FINISHED,允许重新初始化 ## 修改文件 - `STM32H743/APL/motion_control_task.c` - 扩展异常值过滤,添加状态保护 ## 相关文档 - `BUGFIX_HEADING_CONTROL.md` - 航向控制方向修复 - `BUGFIX_CH8_HYSTERESIS.md` - CH8迟滞方案 - `BUGFIX_CH8_FAILSAFE_1024.md` - 1024 failsafe过滤 - `DEBUG_GOTO_START_LOOP.md` - 问题诊断过程 ## 总结 这是一个**层层深入、逐步完善**的bug修复过程: 1. **表象**:车辆在原点和路径点之间来回 2. **第一次分析**:以为是模拟量抖动 → 添加迟滞 3. **第二次分析**:发现是1024 failsafe → 过滤1024 4. **第三次分析**:发现还有其他异常值(120、1953)→ 扩展过滤范围 5. **最终方案**:添加状态保护,防止任务执行中被重新初始化 **关键教训:** - 复杂的问题往往需要多层防护 - 不要假设只有一个根本原因 - SBUS信号质量问题必须从硬件层面根本解决 - 软件要robust,能应对各种异常情况 **本次修复应该能彻底解决状态机重复重置的问题!**