Files
FlyShotHost/docs/move-joint-jerk-comparison-20260505.md
yunxiao.zhu b1710e5d01 ♻️ refactor(compat): 替换 MoveJoint 时间律为解析式 7 阶平滑函数并添加离散限位校验
* 将预捕获 alpha 数据表替换为解析式 7 阶平滑点到点时间律
  s(u)=35u⁴-84u⁵+70u⁶-20u⁷,形状系数按 1~3 阶导数最大值重算
* 新增离散限位校验:按真实 8ms 采样点反算速度/加速度/jerk,
  不满足时自动拉长总时长后重采样,最多迭代 10000 次
* 实发轨迹落盘:ActualSendJointTraj.txt(角度制)、
  ActualSendJerkStats.txt(点间跃度统计),按时间目录归档
* J519 AcceptsCommand 门控:只有机器人就绪时才发送下一帧,
  减少无效下发;状态日志附带最近发送目标关节轴
* FanucControllerRuntime 构造函数改为必选 ILogger 注入,
  确保 DI 解析时稳定拿到日志实例
* LegacyHttpApiController 移除已废弃的 ConnectServer 调用,
  EnableRobot 参数从 2 改为 4
* 新增跃度报警分析文档和六轴限值表,补充反馈远离拒绝测试

Co-authored-by: Copilot <copilot@github.com>
2026-05-06 09:06:28 +08:00

137 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MoveJoint 失败样本六轴限值与 ActualSendJerkStats 对比
记录时间2026-05-05
## 1. 目的
本文档固定记录以下三类证据,避免后续继续混用测试基线、旧文档结论和当前运行目录中的真实模型数据:
- 当前运行目录 `.robot` 模型中的六轴基础 `velocity / acceleration / jerk`
- 当前运行目录 `RobotConfig.json` 中的 `acc_limit / jerk_limit`
- 当前失败样本 `ActualSendJerkStats.txt` 中的逐轴实发跃度峰值
本次样本对应目录:
- `.robot``src/Flyshot.Server.Host/bin/Debug/net8.0/Config/Models/LR_Mate_200iD_7L.robot`
- 配置:`src/Flyshot.Server.Host/bin/Debug/net8.0/Config/RobotConfig.json`
- 实发跃度:`src/Flyshot.Server.Host/bin/Debug/net8.0/Config/Data/move-joint/DenseSend/20260505_203416_563/ActualSendJerkStats.txt`
- 抓包:`src/Flyshot.Server.Host/bin/Debug/net8.0/Config/Data/move-joint/DenseSend/20260505_203416_563/移动点 跃度过大.pcap`
## 2. 当前运行模型的真实六轴限值
当前仓库运行时通过 `RobotModelLoader.LoadProfile(...)``.robot` 中读取每轴 `limit.velocity / limit.acceleration / limit.jerk`,然后只对加速度和 jerk 叠加 `RobotConfig.json` 的全局倍率:
- `velocity_eff = velocity_base`
- `acceleration_eff = acceleration_base * acc_limit`
- `jerk_eff = jerk_base * jerk_limit`
当前运行目录 `RobotConfig.json` 中:
- `acc_limit = 0.74`
- `jerk_limit = 0.74`
按当前运行目录真实模型解出的六轴基础值与生效值如下:
| Joint | vel_base | acc_base | jerk_base | vel_eff | acc_eff | jerk_eff(rad/s^3) | jerk_eff(deg/s^3) |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| Joint1 | 6.45 | 26.90 | 224.22 | 6.45 | 19.9060 | 165.9228 | 9506.6762 |
| Joint2 | 5.41 | 22.54 | 187.86 | 5.41 | 16.6796 | 139.0164 | 7965.0530 |
| Joint3 | 7.15 | 29.81 | 248.46 | 7.15 | 22.0594 | 183.8604 | 10534.4249 |
| Joint4 | 9.59 | 39.99 | 333.30 | 9.59 | 29.5926 | 246.6420 | 14131.5457 |
| Joint5 | 9.51 | 39.63 | 330.27 | 9.51 | 29.3262 | 244.3998 | 14003.0771 |
| Joint6 | 17.45 | 72.72 | 606.01 | 17.45 | 53.8128 | 448.4474 | 25694.1434 |
重要结论:
- 当前运行目录中,`Joint1.jerk_base` 不是测试基线里常见的 `272.7`,而是 `224.22`
- 因此当前样本的 `Joint1` 生效 jerk 上限应按 `224.22 * 0.74 = 165.9228 rad/s^3` 计算。
## 3. ActualSendJerkStats 的单位边界
`ActualSendJerkStats.txt` 的代码注释写的是 `rad/s^3`,但当前实现里真实输入不是弧度,而是角度:
1. `SampleDenseJointTrajectoryDegrees(...)` 先把轨迹点从 `rad` 转成 `deg`
2. `BuildDenseSendJointRow(...)` 把这组角度制关节写入 `ActualSendJointTraj.txt`
3. `BuildDenseSendJerkRow(...)` 再直接基于这组角度制关节做三阶差分
因此当前这份 `ActualSendJerkStats.txt` 的逐轴跃度应按以下方式理解:
- 文本中的数值口径:`deg/s^3`
- 若要与 `.robot` / `RobotProfile` 中的 jerk limit 比较,需要先换算为 `rad/s^3`
- 换算公式:`jerk_rad = jerk_deg * π / 180`
## 4. 全文件逐轴最大跃度对比
扫描整份 `ActualSendJerkStats.txt` 后,各轴绝对值最大跃度如下:
| Joint | peak window(s) | peak line | peak actual(deg/s^3) | peak actual(rad/s^3) | jerk_eff(rad/s^3) | peak/limit |
| --- | --- | ---: | ---: | ---: | ---: | ---: |
| Joint1 | `1.056 -> 1.064` | 133 | 21868.115990 | 381.670625 | 165.922800 | 2.3003 |
| Joint2 | `1.056 -> 1.064` | 133 | 40.271793 | 0.702875 | 139.016400 | 0.0051 |
| Joint3 | `1.056 -> 1.064` | 133 | 98.314401 | 1.715910 | 183.860400 | 0.0093 |
| Joint4 | `1.056 -> 1.064` | 133 | 0.207266 | 0.003617 | 246.642000 | 0.0000 |
| Joint5 | `1.056 -> 1.064` | 133 | 26.759688 | 0.467045 | 244.399800 | 0.0019 |
| Joint6 | `1.056 -> 1.064` | 133 | 2.328736 | 0.040644 | 448.447400 | 0.0001 |
结论非常明确:
- 全文件范围内,只有 `Joint1` 的实发跃度显著超过当前生效 jerk 上限。
- 其余 5 个轴即使取全文件峰值,也远低于各自当前生效 jerk limit。
- 当前样本本质上是一个“J1 主导”的跃度问题,而不是六轴普遍同时逼近上限。
## 5. 报警窗口逐轴对比
结合抓包与 J519 序号,报警前最后一个关键窗口是:
- `seq=41552`
- 轨迹时间窗口:`0.296 -> 0.304s`
- `ActualSendJerkStats.txt` 行号38
该窗口逐轴跃度如下:
| Joint | alarm window jerk(deg/s^3) | alarm window jerk(rad/s^3) | jerk_eff(rad/s^3) | alarm/limit |
| --- | ---: | ---: | ---: | ---: |
| Joint1 | -20395.713579 | 355.972355 | 165.922800 | 2.1454 |
| Joint2 | -37.560252 | 0.655550 | 139.016400 | 0.0047 |
| Joint3 | 91.694793 | 1.600376 | 183.860400 | 0.0087 |
| Joint4 | -0.193310 | 0.003374 | 246.642000 | 0.0000 |
| Joint5 | 24.957931 | 0.435598 | 244.399800 | 0.0018 |
| Joint6 | 2.171939 | 0.037907 | 448.447400 | 0.0001 |
该窗口的直接结论与全局扫描一致:
- 机器人开始报警的 `0.296 -> 0.304s` 窗口里,真正越限的仍然只有 `Joint1`
- `Joint1` 在报警窗口内已经达到当前生效 jerk limit 的 `2.1454x`
- 其余 5 轴在同一窗口仍远低于生效 jerk 上限
## 6. 报警窗口与全局峰值窗口的关系
本次样本不能简单理解为“最大峰值出现的位置就是首次报警位置”。
当前证据表明:
- 首次报警相关窗口在 `0.296 -> 0.304s`
- 全文件最大的 J1 跃度峰值出现在更后面的 `1.056 -> 1.064s`
这说明至少有两件事需要分开:
1. 机器人第一次进入异常态时,`Joint1` 已经在 `0.296 -> 0.304s` 超限约 `2.15x`
2. 即便忽略第一次报警,后续轨迹中仍存在更高的 J1 跃度峰值,说明当前 `MoveJoint` 临时轨迹整体都偏激,不只是单个孤立点异常
## 7. 当前可落地的结论
基于当前运行目录的真实模型、配置和实发跃度文件,本次失败样本可以先固定为下面这组结论:
- 当前运行模型 `Joint1.jerk_base = 224.22`,不是 `272.7`
- 当前样本 `jerk_limit = 0.74`,所以 `Joint1.jerk_eff = 165.9228 rad/s^3`
- `ActualSendJerkStats.txt` 需要按 `deg/s^3` 理解,再换算成 `rad/s^3` 后与模型 jerk limit 对比
- 无论看报警窗口还是看全文件峰值,越限主体都只有 `Joint1`
- 报警窗口 `0.296 -> 0.304s` 中,`Joint1` 已经约为当前生效 jerk 上限的 `2.1454x`
- 全文件最大峰值窗口 `1.056 -> 1.064s` 中,`Joint1` 约为当前生效 jerk 上限的 `2.3003x`
因此当前最合理的根因指向仍然是:
- `MoveJoint` 临时轨迹生成得过于激进
- 当前问题首先应按 `Joint1` 的 jerk 约束失配来处理
- 暂时没有证据支持“六轴普遍一起逼近限制”或“网络链路导致跃度统计失真”这类解释