Files
FlyShotHost/docs/planning-duration-mismatch-investigation.md
yunxiao.zhu af65ca03a0 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 串行化行为
2026-05-03 19:29:31 +08:00

25 KiB
Raw Permalink Blame History

轨迹规划时长差异调查记录

背景

当前新 C# 规划链路在不额外缩放规划约束时,部分真实现场轨迹会比旧 RVBUST/FlyingShot 导出的 JointTraj.txt 更短。

最典型现象:

  • 真实 Rvbust/uttc-20260428/Data/JointTraj.txtUTTC_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 上都一致:

    C#默认规划时间 / 真实规划时间 = 5.495112 / 7.403046 = 0.742277
    

    这说明路点顺序、相对分段时间和 ICSP 主要逻辑基本一致,差异更像是规划时传入的有效 vel/acc/jerk joint limits 存在整体倍率差异。

  4. 现场配置中没有找到显式倍率字段。

    已检查现场现有配置,未发现类似 planning_speed_scale 或等价字段保存了 0.7422770.70.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 0EOL9 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 追加现场新样本:

../Rvbust/20260428 多点/RobotConfig.json
../Rvbust/20260428 多点/JointTraj.txt
../Rvbust/20260428 多点/JointDetialTraj.txt

该样本中的飞拍程序名为:

UTTC_MS11_TEST01

配置摘要:

waypoints=21
shot_flags=21
acc_limit=1
jerk_limit=1

实机导出的 JointTraj.txt

rows=21
duration=7.805885s

用当前 C# ICspPlanner、同一个 LR_Mate_200iD_7L.robot、同一份 RobotConfig.json 规划:

rows=21
duration=5.814370s
C# / 实机 = 0.744870

逐点/逐段统计:

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_MS110.742277 非常接近,进一步支持“同一类 UTTC 现场导出使用了一组更保守的 effective JointLimits”这一判断。

和原 UTTC_MS11 对比:

原 UTTC_MS11 实机 rows=20 duration=7.403046s
新 UTTC_MS11_TEST01 实机 rows=21 duration=7.805885s
新增路径点后实机时长增加 0.402839s

当前观察不到新增点导致规划形状或局部段比例失真;它更像是在同一套旧系统规划约束下正常增加了一段路径时间。

20260430.pcap 初始化抓包复核

2026-04-30 继续复核现场提供的完整初始化抓包:

../Rvbust/20260428 多点/20260430.pcap

抓包总览:

packet_count=4821
tcp_payload_bytes=35302
udp_payload_bytes=451946

主要有效负载会话为:

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

全包搜索以下明文关键字没有命中:

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 状态通道只有机器人侧到上位机的状态帧:

390 个 90B 状态帧
1 个 2B 连接前导

这些帧与已逆向的 pose[6] + joint[6] + external_axes[3] + raw_tail_words[4] 状态布局一致,不携带规划约束。

UDP 60015 J519 通道只出现既有三类长度:

C->R 8B   初始化包 1 个
C->R 64B  目标关节命令包 970 个
R->C 132B 反馈包 2938 个

没有出现其他长度的 UDP 参数帧。64B 命令包是 J519 逐周期目标关节/IO 命令132B 是机器人反馈;这条链路承载的是执行期 streaming motion而不是旧 RVBUST 规划器的 joint limit 配置。

阶段结论:

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 追加复核本机所有网卡抓包:

../Rvbust/20260428 多点/all-50001.pcap
SHA256=C3543F314AE446CABA8E2097EFAFB36F39DD73FFE166F051A1F9387CFD15990F

该文件由 tcpdump -i any 生成pcap linktype 为 113,即 Linux cooked capture。按 SLL 头解析后,确认抓到了本机到本机的 50001 TCP JSON 通信:

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 命令序列为:

{"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"}

服务端返回为:

{"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

阶段结论:

all-50001.pcap 已经证明抓包接口选对了;
但这次只抓到了初始化链路,没有抓到规划/保存轨迹那一刻的 50001 请求。

该待确认点已由下一节 all-50001-plan.pcap 覆盖:后续抓包确实抓到了 ExecuteFlyShotTraj(save_traj=true,use_cache=false),仍未出现规划限制字段。

all-50001-plan.pcap 规划执行抓包复核

2026-04-30 追加复核规划/执行动作期间的本机 50001 抓包:

../Rvbust/20260428 多点/all-50001-plan.pcap
SHA256=311DC45B4789ED11EBEAB7A396E2EE7A16EC8534E20F10127FB43BBAD823C21D

该抓包同样是 tcpdump -i any 生成的 Linux cooked capture已按 SLL 头解析。有效 TCP JSON 流为:

192.168.1.100:35814 -> 192.168.1.100:50001  2612B payload
192.168.1.100:50001 -> 192.168.1.100:35814  516B payload

客户端到服务端的关键命令序列为:

{"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}

两次执行请求均为:

{
  "cmd": "ExecuteFlyShotTraj",
  "method": "icsp",
  "move_to_start": true,
  "name": "UTTC_MS11_TEST01",
  "save_traj": true,
  "use_cache": false,
  "wait": true
}

它们前面的速度倍率分别为:

第一次SetSpeedRatio ratio=0.5
第二次SetSpeedRatio ratio=1.0

服务端对所有命令均返回:

{"res": true}

这份抓包确认了两点:

  1. 公开 50001 JSON 链路确实会把 SetSpeedRatioExecuteFlyShotTraj(save_traj=true,use_cache=false) 发给旧服务端。
  2. 即便覆盖到了实际执行/保存轨迹动作,请求中仍没有出现 GetJointLimits / SetJointLimitsSetVelocityLimit / SetAccelerationLimit / SetJerkLimit,也没有 acc_limit / jerk_limit / velocity / acceleration / jerk / JointLimits 等规划限制字段。

因此,当前能从 50001 抓包确认的是:

规划方法、是否保存轨迹、是否使用缓存、是否等待执行,都会显式发到旧服务端;
速度倍率通过 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 追加测试:为了验证 .robotJoint3Joint2 的 couple 是否是规划时长差异主因,使用 Python ICSP demo 做了多组只读 A/B。

测试模型来自:

flyshot-replacement/Config/Models/LR_Mate_200iD_7L.robot

其中 Joint3 的 couple 信息为:

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_MS11raw 规划时间和真实时间保持严格等比例,point_ratio_std=0segment_ratio_std≈0;加入 couple 后反而出现分段比例波动。
  2. EOL10_EAU_0EOL9_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_200iDFANUC_LR_Mate_200iD_7L 都映射到 LR_Mate_200iD_7L.robot
  3. LR_Mate_200iD.robot 短臂模型的前三轴 vel/acc/jerk7L 更高。用短臂模型试算会让轨迹更短,不会解释“旧系统真实导出更慢”。

模型 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.hExecuteFlyShotTraj(..., use_cache=false) 明确说明旧服务端可以把计算好的轨迹保存在内存中并复用。
  • SaveTrajInfo(name, method) 没有 use_cache 参数,不能仅凭公开头文件判断它一定每次从当前配置重新规划。

当前更合理的解释是:

同一个 .robot
  -> SetUpRobot 初始化基础 JointLimits
  -> 旧服务端运行期间可能被 _SetJointLimits / 速度倍率联动 / 缓存轨迹 覆盖
  -> SaveTrajInfo 或 IsFlyShotTrajValid(save_traj=true) 导出的是真正规划时那份状态
  -> 当前 C# 每次用静态 .robot + RobotConfig 重新规划,所以时长更短

尤其需要注意:EOL10_EAU_0新规划/真实 比例为 0.706394,接近 0.7EOL9_EAU_90 的比例为 0.882873,接近 0.9。这不像模型误差,更像历史导出时混入了某个运行态速度/限制倍率。UTTC_MS110.742277 不等于抓包确认的执行层 0.7,所以不能简单把所有样本都归因到 SetSpeedRatio,但“运行态规划约束不是静态模型值”仍是目前最强方向。

旧服务端与 GUI 二进制复核

2026-04-30 继续从旧系统二进制字符串中复核,重点看公开 Python/HTTP 层没有暴露出来的运行态对象。

服务端确实持有 runtime JointLimits

../FlyingShot/FlyingShot/Python/ControllerServer/ControllerServer.cpython-37m-x86_64-linux-gnu.so 中能稳定看到以下方法和关键字:

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/ 的执行路径是:

c.ExecuteFlyShotTraj(name=name, move_to_start=True, method="icsp", save_traj=True)

/set_speedRatio/ 是单独接口:

c.SetSpeedRatio(speed)

同时,../flyshot-uaes-interface/lib/PyControllerClient.cpython-37m-x86_64-linux-gnu.so../flyshot-uaes-interface/lib/libControllerClient.so 中只看到公开客户端侧的:

GetSpeedRatio
SetSpeedRatio
ExecuteFlyShotTraj
SaveTrajInfo
IsFlyShotTrajValid
JointLimits

没有看到客户端侧 GetJointLimits / SetJointLimits 符号。也就是说UAES Python 服务本身大概率没有主动把旧服务端的 runtime JointLimits 设置成某个值;如果现场旧导出时的 limits 被改过,更可能来自:

  • 旧 GUI 初始化/保存路径;
  • 旧服务端内部默认初始化;
  • 服务端隐藏 TCP JSON 方法;
  • 历史上某次执行/保存后留下的缓存结果。

样本文件与配置文件可能不是同一次运行态

新增一个需要警惕的现象:

  • ../Rvbust/EOL9 EAU 0/eol9_eau_0.jsonacc_limit=1jerk_limit=1
  • ../Rvbust/EOL9 EAU 90/eol9_eau_90.jsonacc_limit=0.8jerk_limit=0.8
  • 但两个目录下保存的真实 JointTraj.txt 内容和时长一致。

哈希复核:

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

本轮新增证据把方向进一步收敛为:

同一个 .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=1jerk_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 形式为:

{
  "robot": {
    "planning_speed_scale": 0.742277
  }
}

该字段只用于规划阶段:

  • vel *= planning_speed_scale
  • acc *= planning_speed_scale^2
  • jerk *= planning_speed_scale^3

它不等同于运行时 /set_speedRatio/,也不改变 J519 的 8ms 发送周期。运行阶段仍按:

t_traj = k * 0.008 * speed_ratio

从已生成轨迹中重采样。

由于现场真实配置和本轮抓包中都没有找到这类倍率,所有 planning_* 字段都必须标注为 replacement-only 兼容校准参数,不能声称它们来自旧配置文件或公开 TCP JSON。

后续设计方向

  1. 默认不再把运行时 speed_ratio 混入 IsFlyshotTrajectoryValid / SaveTrajectoryInfo 的规划时间计算。
  2. 后续实现优先新增 planning_acceleration_scale,只限制规划加速度,并将其写入 RobotConfig.jsonrobot 节点或当前现场默认配置。
  3. 若只需快速对齐整条时间轴,可临时使用现有 planning_speed_scale;但文档、日志和配置说明必须标注它是新系统校准值。
  4. 如果未来能直接调用旧服务端 _GetJointLimits,再用返回值替换当前反推参数;在此之前,显式内部参数是当前可控且可审计的兼容策略。