✨ feat(compat): 补齐飞拍执行等待与 FANUC 状态驱动链路
- 为 ExecuteFlyShotTraj 补齐 wait 语义,并让 move_to_start 先完成临时 PTP 运动后再启动正式飞拍轨迹 - 将 J519 命令发送改为由机器人 UDP status sequence 驱动, 避免在未收到状态包时主动发周期命令 - 将 10010 状态通道关节字段统一按 JointRadians 命名, 同步更新运行时读取逻辑与协议测试 - 新增 FANUC 10010 状态帧、流运动手册和 Python client 逆向文档,并更新 README 与兼容需求说明 - 补充兼容层编排测试与 HTTP 集成测试,覆盖 wait 和 move_to_start 串行化行为
This commit is contained in:
591
docs/planning-duration-mismatch-investigation.md
Normal file
591
docs/planning-duration-mismatch-investigation.md
Normal file
@@ -0,0 +1,591 @@
|
||||
# 轨迹规划时长差异调查记录
|
||||
|
||||
## 背景
|
||||
|
||||
当前新 C# 规划链路在不额外缩放规划约束时,部分真实现场轨迹会比旧 RVBUST/FlyingShot 导出的 `JointTraj.txt` 更短。
|
||||
|
||||
最典型现象:
|
||||
|
||||
- 真实 `Rvbust/uttc-20260428/Data/JointTraj.txt`:`UTTC_MS11` 总时长约 `7.403046s`。
|
||||
- 新 C# 当前默认规划输出:`src/Flyshot.Server.Host/bin/Debug/net8.0/Config/Data/UTTC_MS11/JointTraj.txt` 总时长约 `5.495112s`。
|
||||
- 实体机复核确认:修改运行时 `speed_ratio` 不影响 `IsFlyshotTrajectoryValid` / `SaveTrajectoryInfo` 生成的 `JointTraj.txt` 规划时长。
|
||||
|
||||
因此,本问题不应继续归因到运行时 `speed_ratio`,而应归到规划阶段的有效关节约束来源。
|
||||
|
||||
## 已确认事实
|
||||
|
||||
1. `speed_ratio` 是运行执行倍率。
|
||||
|
||||
UTTC 抓包和实体机测试都显示,`speed_ratio=0.7` 会拉伸 J519 实际下发时间和包数,但不会改变已生成的 `JointTraj.txt` 规划时间轴。
|
||||
|
||||
2. `JointTraj.txt` 是规划结果点位。
|
||||
|
||||
`saveTrajectory` / `SaveTrajInfo` / `IsFlyshotTrajectoryValid(saveTrajectory=true)` 生成的 `JointTraj.txt` 表示规划后的 sparse waypoint 时间轴,不是上传的原始飞拍路径,也不是 J519 逐周期下发点。
|
||||
|
||||
3. UTTC_MS11 的差异是整条时间轴等比例缩放。
|
||||
|
||||
对 `UTTC_MS11`,真实时间和当前 C# 默认规划时间之间的比例在所有 waypoint 上都一致:
|
||||
|
||||
```text
|
||||
C#默认规划时间 / 真实规划时间 = 5.495112 / 7.403046 = 0.742277
|
||||
```
|
||||
|
||||
这说明路点顺序、相对分段时间和 ICSP 主要逻辑基本一致,差异更像是规划时传入的有效 `vel/acc/jerk` joint limits 存在整体倍率差异。
|
||||
|
||||
4. 现场配置中没有找到显式倍率字段。
|
||||
|
||||
已检查现场现有配置,未发现类似 `planning_speed_scale` 或等价字段保存了 `0.742277`、`0.7`、`0.9` 等规划倍率值。
|
||||
|
||||
## 样本对比
|
||||
|
||||
| 样本 | 真实 `JointTraj.txt` 时长 | 当前/已有新规划时长 | 等效倍率 `新规划/真实` | 说明 |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| `UTTC_MS11` | `7.403046s` | `5.495112s` | `0.742277` | 所有 waypoint 时间均为同一比例 |
|
||||
| `UTTC_MS11_TEST01` | `7.805885s` | `5.814370s` | `0.744870` | `20260428 多点` 新增 1 个路径点后仍几乎是整条时间轴等比例缩放 |
|
||||
| `EOL10_EAU_0` | `14.849788s` | `10.489800s` | `0.706394` | 同样表现为新规划偏快 |
|
||||
| `EOL9_EAU_0` / `EOL9_EAU_90` | `6.400851s` | `5.651140s` | `0.882873` | `EOL9 EAU 0` 与 `EOL9 EAU 90` 的真实 `JointTraj.txt` 文件一致 |
|
||||
| `EOL9_EAU_90` | `6.400851s` | `6.471610s` | `1.011055` | 使用 `speedRatio=0.9 + self-adapt-icsp` 的旧离线结果已接近真实 |
|
||||
|
||||
这些样本说明差异不是 `UTTC_MS11` 的个案,也不是一个可以全局写死的常数。不同真实样本对应的等效规划倍率不同。
|
||||
|
||||
## `20260428 多点` 新样本对比
|
||||
|
||||
2026-04-30 追加现场新样本:
|
||||
|
||||
```text
|
||||
../Rvbust/20260428 多点/RobotConfig.json
|
||||
../Rvbust/20260428 多点/JointTraj.txt
|
||||
../Rvbust/20260428 多点/JointDetialTraj.txt
|
||||
```
|
||||
|
||||
该样本中的飞拍程序名为:
|
||||
|
||||
```text
|
||||
UTTC_MS11_TEST01
|
||||
```
|
||||
|
||||
配置摘要:
|
||||
|
||||
```text
|
||||
waypoints=21
|
||||
shot_flags=21
|
||||
acc_limit=1
|
||||
jerk_limit=1
|
||||
```
|
||||
|
||||
实机导出的 `JointTraj.txt`:
|
||||
|
||||
```text
|
||||
rows=21
|
||||
duration=7.805885s
|
||||
```
|
||||
|
||||
用当前 C# `ICspPlanner`、同一个 `LR_Mate_200iD_7L.robot`、同一份 `RobotConfig.json` 规划:
|
||||
|
||||
```text
|
||||
rows=21
|
||||
duration=5.814370s
|
||||
C# / 实机 = 0.744870
|
||||
```
|
||||
|
||||
逐点/逐段统计:
|
||||
|
||||
```text
|
||||
point_ratio_std = 2.18e-7
|
||||
segment_ratio_std = 9.0e-7
|
||||
max_joint_diff = 5.0e-7 rad
|
||||
```
|
||||
|
||||
这说明:
|
||||
|
||||
1. 新样本的路点关节值与 C# 输入基本完全一致,不是解析错点或单位错位。
|
||||
2. 新增 1 个路径点后,C# 与旧系统仍然保持几乎严格的整条时间轴等比例差异。
|
||||
3. `UTTC_MS11_TEST01` 的倍率 `0.744870` 与原 `UTTC_MS11` 的 `0.742277` 非常接近,进一步支持“同一类 UTTC 现场导出使用了一组更保守的 effective JointLimits”这一判断。
|
||||
|
||||
和原 `UTTC_MS11` 对比:
|
||||
|
||||
```text
|
||||
原 UTTC_MS11 实机 rows=20 duration=7.403046s
|
||||
新 UTTC_MS11_TEST01 实机 rows=21 duration=7.805885s
|
||||
新增路径点后实机时长增加 0.402839s
|
||||
```
|
||||
|
||||
当前观察不到新增点导致规划形状或局部段比例失真;它更像是在同一套旧系统规划约束下正常增加了一段路径时间。
|
||||
|
||||
## `20260430.pcap` 初始化抓包复核
|
||||
|
||||
2026-04-30 继续复核现场提供的完整初始化抓包:
|
||||
|
||||
```text
|
||||
../Rvbust/20260428 多点/20260430.pcap
|
||||
```
|
||||
|
||||
抓包总览:
|
||||
|
||||
```text
|
||||
packet_count=4821
|
||||
tcp_payload_bytes=35302
|
||||
udp_payload_bytes=451946
|
||||
```
|
||||
|
||||
主要有效负载会话为:
|
||||
|
||||
```text
|
||||
UDP 192.168.10.11:60015 -> 192.168.10.10:56118 260700B
|
||||
UDP 192.168.10.11:60015 -> 192.168.10.10:48455 127116B
|
||||
UDP 192.168.10.10:48455 -> 192.168.10.11:60015 62088B
|
||||
TCP 192.168.10.11:10010 -> 192.168.10.10:42106 35102B
|
||||
TCP 192.168.10.11:10012 -> 192.168.10.10:33528 106B
|
||||
TCP 192.168.10.10:33528 -> 192.168.10.11:10012 94B
|
||||
```
|
||||
|
||||
全包搜索以下明文关键字没有命中:
|
||||
|
||||
```text
|
||||
Joint / joint / Limit / limit / vel / acc / jerk / Speed / speed /
|
||||
Robot / JSON / Traj / ratio / Ratio / GetJoint / SetJoint
|
||||
```
|
||||
|
||||
`TCP 10012` 命令通道按 `doz + length + message_id + body + zod` 解码后,只看到以下初始化/程序命令:
|
||||
|
||||
| 方向 | 消息号 | 含义 | 请求体/结果 |
|
||||
| --- | ---: | --- | --- |
|
||||
| C->R | `0x0001` | 未知握手 | 空请求 |
|
||||
| R->C | `0x0001` | 未知握手响应 | `result=0` |
|
||||
| C->R | `0x2000` | 未知版本/状态查询 | 空请求 |
|
||||
| R->C | `0x2000` | 未知版本/状态响应 | 包含 `0.6.0` 字符串 |
|
||||
| C->R | `0x2100` | `ResetRobot` | 空请求 |
|
||||
| R->C | `0x2100` | `ResetRobot` 响应 | `result=0` |
|
||||
| C->R | `0x2003` | `GetProgramStatus("RVBUSTSM")` | 程序名 `RVBUSTSM` |
|
||||
| R->C | `0x2003` | 程序状态响应 | `result=0, status=1` |
|
||||
| C->R | `0x2102` | `StartProgram("RVBUSTSM")` | 程序名 `RVBUSTSM` |
|
||||
| R->C | `0x2102` | 启动响应 | `result=0` |
|
||||
|
||||
没有看到:
|
||||
|
||||
- `0x2207 SetSpeedRatio`
|
||||
- `0x2206 GetSpeedRatio`
|
||||
- `0x2200/0x2201 GetTcp/SetTcp`
|
||||
- `0x2208/0x2209 GetIo/SetIo`
|
||||
- 任何疑似 `JointLimits / velocity / acceleration / jerk` 的参数帧
|
||||
|
||||
`TCP 10010` 状态通道只有机器人侧到上位机的状态帧:
|
||||
|
||||
```text
|
||||
390 个 90B 状态帧
|
||||
1 个 2B 连接前导
|
||||
```
|
||||
|
||||
这些帧与已逆向的 `pose[6] + joint[6] + external_axes[3] + raw_tail_words[4]` 状态布局一致,不携带规划约束。
|
||||
|
||||
`UDP 60015` J519 通道只出现既有三类长度:
|
||||
|
||||
```text
|
||||
C->R 8B 初始化包 1 个
|
||||
C->R 64B 目标关节命令包 970 个
|
||||
R->C 132B 反馈包 2938 个
|
||||
```
|
||||
|
||||
没有出现其他长度的 UDP 参数帧。64B 命令包是 J519 逐周期目标关节/IO 命令,132B 是机器人反馈;这条链路承载的是执行期 streaming motion,而不是旧 RVBUST 规划器的 joint limit 配置。
|
||||
|
||||
阶段结论:
|
||||
|
||||
```text
|
||||
20260430.pcap 只覆盖机器人侧 10010 / 10012 / 60015 通信。
|
||||
它没有 50001/TCP+JSON,也没有 ControllerServer/Python 客户端到旧服务端的配置调用。
|
||||
因此,这份抓包看不到旧规划阶段的 effective JointLimits。
|
||||
```
|
||||
|
||||
这并不否定“旧系统规划瞬间存在更保守的 effective JointLimits”这一方向;它只说明这份初始化抓包不是抓取该信息的位置。若要抓到这类限制,需要抓旧服务端内部 `_GetJointLimits/_SetJointLimits`,或者抓上层 Python/GUI 与 ControllerServer 之间的配置/规划调用,而不是只抓机器人控制柜侧的执行链路。
|
||||
|
||||
## `all-50001.pcap` 本机 50001 抓包复核
|
||||
|
||||
2026-04-30 追加复核本机所有网卡抓包:
|
||||
|
||||
```text
|
||||
../Rvbust/20260428 多点/all-50001.pcap
|
||||
SHA256=C3543F314AE446CABA8E2097EFAFB36F39DD73FFE166F051A1F9387CFD15990F
|
||||
```
|
||||
|
||||
该文件由 `tcpdump -i any` 生成,pcap linktype 为 `113`,即 Linux cooked capture。按 SLL 头解析后,确认抓到了本机到本机的 `50001` TCP JSON 通信:
|
||||
|
||||
```text
|
||||
192.168.1.100:35814 -> 192.168.1.100:50001 217B payload
|
||||
192.168.1.100:50001 -> 192.168.1.100:35814 91B payload
|
||||
```
|
||||
|
||||
客户端到服务端的完整 JSON 命令序列为:
|
||||
|
||||
```json
|
||||
{"reply_from_client":true}
|
||||
{"cmd":"SetUpRobot","robot_name":"FANUC_LR_Mate_200iD_7L"}
|
||||
{"cmd":"IsSetUp"}
|
||||
{"cmd":"SetActiveController","sim":false}
|
||||
{"cmd":"Connect","ip":"192.168.10.11"}
|
||||
{"buffer_size":8,"cmd":"EnableRobot"}
|
||||
```
|
||||
|
||||
服务端返回为:
|
||||
|
||||
```json
|
||||
{"test_from_server": true}
|
||||
{"res": true}
|
||||
{"res": true}
|
||||
{"res": true}
|
||||
{"res": true}
|
||||
{"res": true}
|
||||
```
|
||||
|
||||
这说明本次抓包确实覆盖到了旧 `50001` 控制链路,但当前只包含机器人初始化、连接和使能流程。里面没有看到:
|
||||
|
||||
- `ExecuteFlyShotTraj`
|
||||
- `SaveTrajInfo`
|
||||
- `IsFlyShotTrajValid`
|
||||
- `GetJointLimits / SetJointLimits`
|
||||
- `SetVelocityLimit / SetAccelerationLimit / SetJerkLimit`
|
||||
- 任何包含 `acc_limit / jerk_limit / JointLimits / velocity / acceleration / jerk` 的配置 JSON
|
||||
|
||||
阶段结论:
|
||||
|
||||
```text
|
||||
all-50001.pcap 已经证明抓包接口选对了;
|
||||
但这次只抓到了初始化链路,没有抓到规划/保存轨迹那一刻的 50001 请求。
|
||||
```
|
||||
|
||||
该待确认点已由下一节 `all-50001-plan.pcap` 覆盖:后续抓包确实抓到了 `ExecuteFlyShotTraj(save_traj=true,use_cache=false)`,仍未出现规划限制字段。
|
||||
|
||||
## `all-50001-plan.pcap` 规划执行抓包复核
|
||||
|
||||
2026-04-30 追加复核规划/执行动作期间的本机 50001 抓包:
|
||||
|
||||
```text
|
||||
../Rvbust/20260428 多点/all-50001-plan.pcap
|
||||
SHA256=311DC45B4789ED11EBEAB7A396E2EE7A16EC8534E20F10127FB43BBAD823C21D
|
||||
```
|
||||
|
||||
该抓包同样是 `tcpdump -i any` 生成的 Linux cooked capture,已按 SLL 头解析。有效 TCP JSON 流为:
|
||||
|
||||
```text
|
||||
192.168.1.100:35814 -> 192.168.1.100:50001 2612B payload
|
||||
192.168.1.100:50001 -> 192.168.1.100:35814 516B payload
|
||||
```
|
||||
|
||||
客户端到服务端的关键命令序列为:
|
||||
|
||||
```json
|
||||
{"cmd":"ListFlyShotTraj"}
|
||||
{"cmd":"GetNextListFlyShotTraj","count":0}
|
||||
{"cmd":"SetSpeedRatio","ratio":0.5}
|
||||
{"cmd":"ExecuteFlyShotTraj","method":"icsp","move_to_start":true,"name":"UTTC_MS11_TEST01","save_traj":true,"use_cache":false,"wait":true}
|
||||
{"cmd":"SetSpeedRatio","ratio":1.0}
|
||||
{"cmd":"ExecuteFlyShotTraj","method":"icsp","move_to_start":true,"name":"UTTC_MS11_TEST01","save_traj":true,"use_cache":false,"wait":true}
|
||||
{"cmd":"StartUploadFlyShotTraj","name":"UTTC_MS11"}
|
||||
{"cmd":"UploadFlyShotTraj", "...":"4 批共 20 个 waypoint,每批包含 waypoints / shot_flags / offset_values / addrs"}
|
||||
{"cmd":"EndUploadFlyShotTraj","name":"UTTC_MS11"}
|
||||
{"cmd":"ListFlyShotTraj"}
|
||||
{"cmd":"GetNextListFlyShotTraj","count":0}
|
||||
```
|
||||
|
||||
两次执行请求均为:
|
||||
|
||||
```json
|
||||
{
|
||||
"cmd": "ExecuteFlyShotTraj",
|
||||
"method": "icsp",
|
||||
"move_to_start": true,
|
||||
"name": "UTTC_MS11_TEST01",
|
||||
"save_traj": true,
|
||||
"use_cache": false,
|
||||
"wait": true
|
||||
}
|
||||
```
|
||||
|
||||
它们前面的速度倍率分别为:
|
||||
|
||||
```text
|
||||
第一次:SetSpeedRatio ratio=0.5
|
||||
第二次:SetSpeedRatio ratio=1.0
|
||||
```
|
||||
|
||||
服务端对所有命令均返回:
|
||||
|
||||
```json
|
||||
{"res": true}
|
||||
```
|
||||
|
||||
这份抓包确认了两点:
|
||||
|
||||
1. 公开 50001 JSON 链路确实会把 `SetSpeedRatio` 和 `ExecuteFlyShotTraj(save_traj=true,use_cache=false)` 发给旧服务端。
|
||||
2. 即便覆盖到了实际执行/保存轨迹动作,请求中仍没有出现 `GetJointLimits / SetJointLimits`、`SetVelocityLimit / SetAccelerationLimit / SetJerkLimit`,也没有 `acc_limit / jerk_limit / velocity / acceleration / jerk / JointLimits` 等规划限制字段。
|
||||
|
||||
因此,当前能从 50001 抓包确认的是:
|
||||
|
||||
```text
|
||||
规划方法、是否保存轨迹、是否使用缓存、是否等待执行,都会显式发到旧服务端;
|
||||
速度倍率通过 SetSpeedRatio 单独发到旧服务端;
|
||||
但 effective JointLimits 没有通过这次公开 50001 JSON 请求显式传入。
|
||||
```
|
||||
|
||||
这进一步收敛了差异来源:如果旧系统规划时确实使用了更保守的 joint limits,它更可能来自旧服务端在 `SetUpRobot("FANUC_LR_Mate_200iD_7L")` 后加载/初始化的内部状态,或来自 GUI/服务端内部私有路径,而不是这次 50001 公开 JSON 在 `ExecuteFlyShotTraj` 请求中传入的字段。
|
||||
|
||||
## Joint3/Joint2 couple A/B 测试
|
||||
|
||||
2026-04-30 追加测试:为了验证 `.robot` 中 `Joint3` 对 `Joint2` 的 couple 是否是规划时长差异主因,使用 Python ICSP demo 做了多组只读 A/B。
|
||||
|
||||
测试模型来自:
|
||||
|
||||
```text
|
||||
flyshot-replacement/Config/Models/LR_Mate_200iD_7L.robot
|
||||
```
|
||||
|
||||
其中 `Joint3` 的 couple 信息为:
|
||||
|
||||
```text
|
||||
q3_kin = q3_raw + q2_kin * 1.0 + 0.0
|
||||
```
|
||||
|
||||
测试变体:
|
||||
|
||||
- `raw`:原始 6 轴路点直接规划。
|
||||
- `replace_q3=q3+q2`:规划输入中把第 3 轴替换为耦合后的运动学角。
|
||||
- `replace_q3=q3-q2`:反向符号试探,排除符号理解错误。
|
||||
- `raw+constraint(q3+q2)`:保留原始 6 轴,同时追加虚拟约束轴 `q3+q2`,用 Joint3 的 `vel/acc/jerk` 限值检查。
|
||||
- `raw+constraint(q3-q2)`:反向符号的虚拟约束轴试探。
|
||||
|
||||
结果:
|
||||
|
||||
| 样本 | 真实时长 | 最接近变体 | 变体时长 | 变体/真实 | 与真实差值 | 结论 |
|
||||
| --- | ---: | --- | ---: | ---: | ---: | --- |
|
||||
| `UTTC_MS11` | `7.403046s` | `raw` | `5.495112s` | `0.742277` | `1.907934s` | couple 变体全部更短,且破坏原本严格等比例关系 |
|
||||
| `EOL10_EAU_0` | `14.849788s` | `replace_q3=q3+q2` | `10.600711s` | `0.713863` | `4.249077s` | couple 只改善约 `0.11s`,距离真实仍差 `4.25s` |
|
||||
| `EOL9_EAU_90` | `6.400851s` | `raw+constraint(q3+q2)` | `5.748560s` | `0.898093` | `0.652291s` | couple 约束有小幅影响,但仍不足以解释真实时长 |
|
||||
|
||||
关键观察:
|
||||
|
||||
1. `UTTC_MS11` 的 `raw` 规划时间和真实时间保持严格等比例,`point_ratio_std=0`、`segment_ratio_std≈0`;加入 couple 后反而出现分段比例波动。
|
||||
2. `EOL10_EAU_0` 与 `EOL9_EAU_90` 的 couple 变体只带来小幅时长变化,不能解释 10% 到 30% 级别的差异。
|
||||
3. 因此,当前证据不支持“只要把 Joint3/Joint2 couple 带入 ICSP,就能对齐旧 RVBUST 规划时长”。
|
||||
|
||||
阶段结论:
|
||||
|
||||
`Joint3` couple 确实是 C# 与 Python demo 当前都没有进入规划约束的缺口,但它不像本轮时长 mismatch 的主因。它更可能影响 FK/运动学边界或少数局部段约束;当前主要时长差异仍更像有效 joint limits、旧系统运行期规划倍率、或 RPS 内部 ICSP 参数来源不同。
|
||||
|
||||
## 同模型复核与更可能的差异层
|
||||
|
||||
2026-04-30 继续复核:
|
||||
|
||||
1. 当前仓库固化的模型与旧 `FlyingShot/FlyingShot/Models/LR_Mate_200iD_7L.robot` 字节哈希一致。
|
||||
2. `ControllerClientCompatRobotCatalog` 当前会把 `FANUC_LR_Mate_200iD` 和 `FANUC_LR_Mate_200iD_7L` 都映射到 `LR_Mate_200iD_7L.robot`。
|
||||
3. `LR_Mate_200iD.robot` 短臂模型的前三轴 `vel/acc/jerk` 比 `7L` 更高。用短臂模型试算会让轨迹更短,不会解释“旧系统真实导出更慢”。
|
||||
|
||||
模型 A/B:
|
||||
|
||||
| 样本 | 真实时长 | `LR_Mate_200iD_7L.robot` | `LR_Mate_200iD.robot` | 结论 |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| `UTTC_MS11` | `7.403046s` | `5.495112s` | `5.345600s` | 短臂模型方向更错 |
|
||||
| `EOL10_EAU_0` | `14.849788s` | `10.489800s` | `10.342456s` | 短臂模型方向更错 |
|
||||
|
||||
因此,如果现场确认机器人模型确实一致,差异层就不应继续放在 `.robot` 静态文件本身,而应放在旧服务端规划时的运行态:
|
||||
|
||||
- 服务端内部存在 `_GetJointLimits / _SetJointLimits`,说明规划消费的是一份可能被运行期覆写的 `current JointLimits`。
|
||||
- `ControllerClient.h` 的 `ExecuteFlyShotTraj(..., use_cache=false)` 明确说明旧服务端可以把计算好的轨迹保存在内存中并复用。
|
||||
- `SaveTrajInfo(name, method)` 没有 `use_cache` 参数,不能仅凭公开头文件判断它一定每次从当前配置重新规划。
|
||||
|
||||
当前更合理的解释是:
|
||||
|
||||
```text
|
||||
同一个 .robot
|
||||
-> SetUpRobot 初始化基础 JointLimits
|
||||
-> 旧服务端运行期间可能被 _SetJointLimits / 速度倍率联动 / 缓存轨迹 覆盖
|
||||
-> SaveTrajInfo 或 IsFlyShotTrajValid(save_traj=true) 导出的是真正规划时那份状态
|
||||
-> 当前 C# 每次用静态 .robot + RobotConfig 重新规划,所以时长更短
|
||||
```
|
||||
|
||||
尤其需要注意:`EOL10_EAU_0` 的 `新规划/真实` 比例为 `0.706394`,接近 `0.7`;`EOL9_EAU_90` 的比例为 `0.882873`,接近 `0.9`。这不像模型误差,更像历史导出时混入了某个运行态速度/限制倍率。`UTTC_MS11` 的 `0.742277` 不等于抓包确认的执行层 `0.7`,所以不能简单把所有样本都归因到 `SetSpeedRatio`,但“运行态规划约束不是静态模型值”仍是目前最强方向。
|
||||
|
||||
## 旧服务端与 GUI 二进制复核
|
||||
|
||||
2026-04-30 继续从旧系统二进制字符串中复核,重点看公开 Python/HTTP 层没有暴露出来的运行态对象。
|
||||
|
||||
### 服务端确实持有 runtime JointLimits
|
||||
|
||||
`../FlyingShot/FlyingShot/Python/ControllerServer/ControllerServer.cpython-37m-x86_64-linux-gnu.so` 中能稳定看到以下方法和关键字:
|
||||
|
||||
```text
|
||||
ControllerServer.ControllerServer._GetJointLimits
|
||||
ControllerServer.ControllerServer._SetJointLimits
|
||||
ControllerServer.ControllerServer._IsWaypointInJointLimits
|
||||
ControllerServer.ControllerServer._IsTrajInJointLimits
|
||||
ControllerServer.ControllerServer._IsTrajInJerkLimits
|
||||
ControllerServer.ControllerServer._ExecuteFlyShotTraj
|
||||
ControllerServer.ControllerServer._SaveTrajInfo
|
||||
ControllerServer.ControllerServer._IsFlyShotTrajValid
|
||||
SetVelocityLimit
|
||||
SetAccelerationLimit
|
||||
SetJerkLimit
|
||||
GetMaxVelocity
|
||||
GetMaxAcceleration
|
||||
GetMaxJerk
|
||||
m_acc_limit
|
||||
m_jerk_limit
|
||||
save_traj_only
|
||||
use_cache
|
||||
```
|
||||
|
||||
这比公开 `ControllerClient.h` 暴露的信息更多。它说明旧服务端内部不是只把 `.robot` 静态值直接传给 `TrajectoryRnICSP`,而是存在一份可以查询、设置、校验、再用于规划的运行期 `JointLimits`。
|
||||
|
||||
### GUI 也直接接触规划约束与保存逻辑
|
||||
|
||||
旧 GUI 二进制里也能看到同一条链:
|
||||
|
||||
- `../FlyingShot/FlyingShot/Python/GUI/Robot/RobotManager.cpython-37m-x86_64-linux-gnu.so`
|
||||
- `GetJointLimits`
|
||||
- `TrajectoryRnICSP`
|
||||
- `IsTrajInJointLimits`
|
||||
- `IsTrajInJerkLimits`
|
||||
- `acc_limit`
|
||||
- `jerk_limit`
|
||||
- `../FlyingShot/FlyingShot/Python/GUI/Robot/RobotConfig.cpython-37m-x86_64-linux-gnu.so`
|
||||
- `SaveTraj`
|
||||
- `m_acc_limit`
|
||||
- `m_jerk_limit`
|
||||
- `../FlyingShot/FlyingShot/Python/GUI/Panels/FlyshotDockPanel.cpython-37m-x86_64-linux-gnu.so`
|
||||
- `__SaveTraj`
|
||||
- `IsTrajInJointLimits`
|
||||
- `IsTrajInJerkLimits`
|
||||
- `m_acc_limit`
|
||||
- `m_jerk_limit`
|
||||
|
||||
这说明旧 GUI 的“保存轨迹/检查轨迹”路径很可能不是简单调用公开 `ControllerClient.SaveTrajInfo` 后结束,而是直接拿当前 `JointLimits + acc_limit + jerk_limit` 做规划、合法性检查或保存。
|
||||
|
||||
### UAES 接口没有显式对齐 JointLimits
|
||||
|
||||
`../flyshot-uaes-interface/main.py` 中 `/execute_flyshot/` 的执行路径是:
|
||||
|
||||
```text
|
||||
c.ExecuteFlyShotTraj(name=name, move_to_start=True, method="icsp", save_traj=True)
|
||||
```
|
||||
|
||||
`/set_speedRatio/` 是单独接口:
|
||||
|
||||
```text
|
||||
c.SetSpeedRatio(speed)
|
||||
```
|
||||
|
||||
同时,`../flyshot-uaes-interface/lib/PyControllerClient.cpython-37m-x86_64-linux-gnu.so` 和 `../flyshot-uaes-interface/lib/libControllerClient.so` 中只看到公开客户端侧的:
|
||||
|
||||
```text
|
||||
GetSpeedRatio
|
||||
SetSpeedRatio
|
||||
ExecuteFlyShotTraj
|
||||
SaveTrajInfo
|
||||
IsFlyShotTrajValid
|
||||
JointLimits
|
||||
```
|
||||
|
||||
没有看到客户端侧 `GetJointLimits / SetJointLimits` 符号。也就是说,UAES Python 服务本身大概率没有主动把旧服务端的 runtime JointLimits 设置成某个值;如果现场旧导出时的 limits 被改过,更可能来自:
|
||||
|
||||
- 旧 GUI 初始化/保存路径;
|
||||
- 旧服务端内部默认初始化;
|
||||
- 服务端隐藏 TCP JSON 方法;
|
||||
- 历史上某次执行/保存后留下的缓存结果。
|
||||
|
||||
### 样本文件与配置文件可能不是同一次运行态
|
||||
|
||||
新增一个需要警惕的现象:
|
||||
|
||||
- `../Rvbust/EOL9 EAU 0/eol9_eau_0.json` 中 `acc_limit=1`、`jerk_limit=1`。
|
||||
- `../Rvbust/EOL9 EAU 90/eol9_eau_90.json` 中 `acc_limit=0.8`、`jerk_limit=0.8`。
|
||||
- 但两个目录下保存的真实 `JointTraj.txt` 内容和时长一致。
|
||||
|
||||
哈希复核:
|
||||
|
||||
```text
|
||||
EOL9 EAU 0 JointTraj.txt SHA256=DFD8E1130742CFB4ED72F70D0E8CA4E3A16F421E0D0D9D921B9F5177717536EC
|
||||
EOL9 EAU 90 JointTraj.txt SHA256=DFD8E1130742CFB4ED72F70D0E8CA4E3A16F421E0D0D9D921B9F5177717536EC
|
||||
eol9_eau_0.json SHA256=354D0D3F71499951976504802C4B2860132D1E4FF753738715A500529CD0BB68
|
||||
eol9_eau_90.json SHA256=7F854AA227D842CAE734AFA378FEEFA742D797F99FBE536E1B98DF981CD32B27
|
||||
```
|
||||
|
||||
这说明不能默认认为“某个 JSON 文件当前内容”就一定是旁边 `Data/JointTraj.txt` 的生成状态。旧系统的保存文件可能来自缓存、拷贝、历史运行态,或 GUI/服务端中未落盘到该 JSON 的当前 `JointLimits`。
|
||||
|
||||
本轮新增证据把方向进一步收敛为:
|
||||
|
||||
```text
|
||||
同一个 .robot 文件本身不是问题核心;
|
||||
真正影响时长的是旧系统规划瞬间的 effective JointLimits;
|
||||
但这份状态没有出现在现有配置、机器人侧抓包或 50001 公开 JSON 中。
|
||||
```
|
||||
|
||||
如果未来能直接进入旧服务端进程,仍可在 `SaveTrajInfo` / `IsFlyShotTrajValid(save_traj=true)` 前后抓取 `_GetJointLimits` 返回值,并把它与 `.robot` 原始 `vel/acc/jerk` 和当前 JSON 的 `acc_limit/jerk_limit` 做数值对比。但这不再阻塞 replacement 的现场对齐:当前设计默认用显式内部规划加速度参数补齐这份不可见状态。
|
||||
|
||||
## 当前判断
|
||||
|
||||
当前最可信的解释是:
|
||||
|
||||
1. 旧 RVBUST/FlyingShot 生成真实 `JointTraj.txt` 时,规划阶段使用的有效 joint limits 并不总是 `.robot` 文件中的原始 `velocity / acceleration / jerk`。
|
||||
2. 这些有效 joint limits 可能来自服务运行期状态,例如旧服务端内部的 `_SetJointLimits`、上层 GUI/脚本初始化流程、机器人环境配置,或其他未落入当前 JSON 文件的运行时参数。
|
||||
3. 现有现场 JSON 中只明确保存了:
|
||||
- `acc_limit`
|
||||
- `jerk_limit`
|
||||
- `adapt_icsp_try_num`
|
||||
- IO 相关配置
|
||||
4. 已重新抓取机器人侧 `10010/10012/60015` 和本机 `50001/TCP+JSON`,仍没有看到 `JointLimits / velocity / acceleration / jerk / acc_limit / jerk_limit` 通过公开链路在规划时下发。
|
||||
5. 目前没有证据表明现场配置文件或公开 TCP JSON 显式保存了一个“规划速度倍率”或“规划加速度限制”。
|
||||
|
||||
因此,`0.742277` 不应被理解为固定业务常量。它只是 `UTTC_MS11` 在当前 C# 默认约束和真实导出结果之间反推出来的等效规划倍率。
|
||||
|
||||
## 兼容设计决策
|
||||
|
||||
由于重新抓包后仍抓不到旧系统的 effective limits,新系统后续不再继续假设公开链路会传入这份数据,而是采用 replacement-only 的显式规划约束参数补齐不可见状态。
|
||||
|
||||
参数分层如下:
|
||||
|
||||
1. `acc_limit / jerk_limit`
|
||||
- 来源:旧 `RobotConfig.json` 中已经存在的字段。
|
||||
- 语义:继续作为旧配置的基础倍率,参与 `.robot` 模型加载。
|
||||
- 限制:现场样本中 `acc_limit=1`、`jerk_limit=1` 时,不能解释旧导出轨迹更慢的问题。
|
||||
|
||||
2. `planning_acceleration_scale`
|
||||
- 来源:新系统内部兼容参数,不声称来自旧 RVBUST 配置或抓包。
|
||||
- 语义:只用于规划阶段,额外缩放 `JointLimit.AccelerationLimit`,用于复现旧服务端不可见的保守加速度约束。
|
||||
- 默认值:`1.0`,表示不额外限制。
|
||||
- 现场校准:若按纯加速度限制解释 `UTTC_MS11_TEST01`,可先用 `(5.814370 / 7.805885)^2 ≈ 0.5548` 作为候选起点,再用真实 `JointTraj.txt` 对拍确认。
|
||||
|
||||
3. `planning_speed_scale`
|
||||
- 来源:当前 C# 已支持的显式兼容字段。
|
||||
- 语义:把整条规划时间轴按速度倍率解释,联动缩放速度、加速度、jerk。
|
||||
- 定位:保留为临时整体验证开关;当后续落地 `planning_acceleration_scale` 后,现场默认优先使用加速度限制参数,而不是把 `planning_speed_scale` 当成旧系统事实。
|
||||
|
||||
当前 C# 已支持的 `planning_speed_scale` 形式为:
|
||||
|
||||
```json
|
||||
{
|
||||
"robot": {
|
||||
"planning_speed_scale": 0.742277
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
该字段只用于规划阶段:
|
||||
|
||||
- `vel *= planning_speed_scale`
|
||||
- `acc *= planning_speed_scale^2`
|
||||
- `jerk *= planning_speed_scale^3`
|
||||
|
||||
它不等同于运行时 `/set_speedRatio/`,也不改变 J519 的 8ms 发送周期。运行阶段仍按:
|
||||
|
||||
```text
|
||||
t_traj = k * 0.008 * speed_ratio
|
||||
```
|
||||
|
||||
从已生成轨迹中重采样。
|
||||
|
||||
由于现场真实配置和本轮抓包中都没有找到这类倍率,所有 `planning_*` 字段都必须标注为 replacement-only 兼容校准参数,不能声称它们来自旧配置文件或公开 TCP JSON。
|
||||
|
||||
## 后续设计方向
|
||||
|
||||
1. 默认不再把运行时 `speed_ratio` 混入 `IsFlyshotTrajectoryValid` / `SaveTrajectoryInfo` 的规划时间计算。
|
||||
2. 后续实现优先新增 `planning_acceleration_scale`,只限制规划加速度,并将其写入 `RobotConfig.json` 的 `robot` 节点或当前现场默认配置。
|
||||
3. 若只需快速对齐整条时间轴,可临时使用现有 `planning_speed_scale`;但文档、日志和配置说明必须标注它是新系统校准值。
|
||||
4. 如果未来能直接调用旧服务端 `_GetJointLimits`,再用返回值替换当前反推参数;在此之前,显式内部参数是当前可控且可审计的兼容策略。
|
||||
Reference in New Issue
Block a user