# PLSR Bug 报告(2026-08-13,逻辑分析仪实测) > 发送对象:Codex 开发 > 全部现象来自实板逻辑分析仪波形(6.25MS/s),运动计数均正确(1000/1000 脉冲),问题集中在**短轮廓(脉冲数不足以完成完整加减速)路径**和**段间延迟**。 --- ## Bug 1:短轮廓减速提前切换,尾部以停止速度慢爬(bug1.bin) **配置**:段数 1|基准 100000Hz|启动 100Hz|停止 100Hz|加速 100ms|减速 100ms|段频率 100000Hz|脉冲数 **1000** **现象**:总时长 **461ms**(理论 ~64ms),尾部 ~38 个脉冲以 **100Hz** 输出(每个 10ms,共 400ms)。 波形结构: ``` 100Hz →(450脉冲)→ 33kHz 峰值 →(485脉冲 减速到~8kHz)→ 跳变 100Hz×38个 → 停 ``` **实测 vs 理论**: | 项 | 理论 | 实测 | |---|---|---| | 峰值 | ~31,623Hz((f²−10⁴)/1e6=1000 → f=√1e9) | 33,069Hz(+4.5%) | | 加速段 | ~500 脉冲 | ~450 脉冲 | | 减速段 | 平滑减到 100Hz,正好用完 | **减到 ~8kHz 直接跳 100Hz** | | 总时长 | ~64ms | **461ms** | **根因**:剩余脉冲不足以完成完整减速 ramp 时,固件直接 `ApplyFrequency(停止速度)` 把剩余脉冲发完,而不是按剩余脉冲**裁剪/重算减速斜坡**(截断三角)。 **修复方向**:减速进入判定 `剩余脉冲 ≤ 减速所需` 时,按剩余脉冲重算减速斜率(保持三角形面积守恒),不要跳变到停止速度。 --- ## Bug 2:加速 ramp 消失 + 减速提前切换(bug2.bin) **配置**:段数 1|基准 100000Hz|启动 100Hz|停止 100Hz|加速 **10ms**|减速 **10ms**|段频率 100000Hz|脉冲数 **1000** **现象**:总时长 **524ms**(理论 ~20ms)。加速段整个丢失(**3 个脉冲**就从 100Hz 冲到 100kHz),然后 100kHz 恒速 945 个,尾部 **51 个 100Hz**(510ms)。 波形结构: ``` 100Hz →(1脉冲 10ms)→ 200Hz →(66kHz)→ 100kHz × 945个 → 100Hz × 51个 → 停 ``` **根因 A(加速消失)——时序错位**: ``` 启动速度 100Hz → 第 1 个脉冲要等 1/100Hz = 10ms 才发出 加速 ramp → (100000−100)×10ms/100000 = 9.99ms 就走完了 → ramp 在第一个脉冲之前完成,加速段物理不可见 → 首脉冲出来时频率已是 100kHz ``` **根因 B(减速提前切换)**:同 Bug 1。 **修复方向**:ramp 计时起点改为**第一个脉冲发出时刻**(或段启动先应用启动速度、等首脉冲后再启动 ramp),而不是从段启动瞬间计时。 --- ## Bug 3:整段以启动/停止速度输出(启动速度极低场景,无波形,配置可复现) **配置**:段数 1|基准 100000Hz|启动 **10Hz**|停止 **10Hz**|加速 **10ms**|减速 **100ms**|段频率 100000Hz|脉冲数 **1000** **现象**:**输出 10Hz 脉冲 1000 个**(约 100 秒)。 **数学推演**: ``` 启动速度 10Hz → 第 1 个脉冲要等 1/10Hz = 100ms 完整梯形需要 → 加速500 + 减速5000 = 5500 脉冲(1000 不够 → 短轮廓) 短轮廓总时长 → 10Hz↗42,640Hz↘10Hz ≈ 47ms 47ms 曲线 < 100ms 首脉冲等待 → ramp 全程跑在第一个脉冲之前,消耗脉冲 = 0 固件曲线走完后的处理:频率回到停止速度 10Hz,剩余 1000 脉冲全部 10Hz 输出 ``` **根因**:Bug 2 根因 A 的极端版(ramp 时长 < 首脉冲等待时间),叠加"曲线走完但 0 脉冲消耗"的判定缺陷。 **修复方向**:同 Bug 2 根因 A;并检查短轮廓"脉冲消耗=0"时的处理(应按首脉冲后的剩余脉冲重新规划)。 **验证方法**:把启动速度改成 1000Hz(首脉冲 1ms < ramp 47ms),同一配置应恢复短轮廓三角——可快速验证根因。 --- ## Bug 4:段间 2.5ms 低电平间隙(TC-PD-011,有限路径 10 段连续执行) **配置**:段数 10|完成模式|相对位置|恒速 1000Hz(启动=停止=段频率)|段脉冲 100~109|跳转 0 **现象**:每个段之间固定 ~2.5ms 低电平(段 100ms 内占 2.5%)。 **根因**:恒速小段走**有限脉冲路径**,段完成与下一段启动被拆成**两个主循环周期**(每周期 ~1ms): ``` 段 N 最后脉冲 → CC1 中断置 FiniteCompletionPending(IRQ 内,零延迟) 周期 N:PlsrPoll1ms → PlsrServiceFiniteCompletion() 消费完成事件 (诊断结算 + PlsrBoundaryPending=1)→ return ← plsr.c:4502 提前返回 周期 N+1:PlsrPoll1ms → PlsrHandleBoundary() → 启动段 N+1 延迟 = 段结束→周期N随机等待(0~1ms) + 2 周期 ≈ 2~3ms,平均 2.5ms ``` **对比**:非有限路径(有加减速)段完成在 IRQ 内直接置 `PlsrBoundaryPending`,段间仅 0~1ms——无此问题。 **修复方向**:`PlsrServiceFiniteCompletion` 消费完成后**不 return**,同周期继续处理 `PlsrBoundaryPending`(去掉 plsr.c:4502 的提前返回),段间延迟降到 ~1ms。 --- ## 汇总与优先级 | # | 问题 | 严重度 | 涉及路径 | 实测文件 | |---|---|---|---|---| | 1 | 减速预算不足时跳停止速度发完剩余 | 高 | 短轮廓/减速切换(`PlsrMaybePlanBoundaryRamp`、短轮廓边界规划) | bug1.bin、bug2.bin | | 2 | ramp 计时从段启动起算,ramp 时长 < 首脉冲等待时加速丢失 | 高 | 段启动/ramp(`PlsrBeginSegmentOutput`→`PlsrRampStart`) | bug2.bin、Bug 3 | | 3 | 短轮廓"0 脉冲消耗"判定 + 峰值规划偏差(31623 vs 实测 33069,加速 500 vs 450) | 中 | 短轮廓峰值/预算计算(`PlsrShortProfilePeak` 等) | bug1.bin | | 4 | 有限路径段间 2 周期延迟(~2.5ms) | 低 | `PlsrServiceFiniteCompletion` → `PlsrPoll1ms` | TC-PD-011 | **建议修复顺序**:Bug 1/2 根因(同一短轮廓路径)→ Bug 3(同根因极端版,改完 1/2 后复测确认)→ Bug 4(一行 return 改动)→ 峰值规划偏差(精度优化)。 **回归验证**: - bug1 配置预期:三角平滑到 100Hz 恰好 1000 脉冲,总时长 ~64ms,无 100Hz 尾巴 - bug2 配置预期:10Hz→100kHz→10Hz(或短轮廓峰值),总时长 ~20ms - Bug 3 配置预期:首脉冲等待 100ms 后短轮廓三角 ~47ms,总时长 ~147ms - TC-PD-011 预期:段间间隙 <1ms