yunxiao.zhu bcbf8017ad 📝 docs(planning): 统一 Rust 规划库命名
将 Rust 原生规划库设计口径统一为 flyshot_planning。

同步更新 Windows 和 Linux 产物名以及复制命令示例。
2026-06-27 15:10:06 +08:00

Flyshot Replacement

基于 .NET 8 的跨平台飞拍服务端重写项目。

当前目标:

  • 以新的 ASP.NET Core HTTP API 作为唯一上层接口
  • 重写轨迹生成、触发时序和 FANUC 实时控制链路
  • 提供 Web 状态监控页面
  • 在 Windows 和 Linux 上运行完整后台服务

说明:

  • 这是长期运行的无头后台服务,不是 GUI 桌面程序。
  • 第一版仅面向当前现场组合,后续再扩展机型与控制柜适配。
  • 当前仓库不再恢复旧 50001/TCP+JSON 监听入口;旧 ControllerClient 逆向资料只作为接口语义参考,不作为运行时目标。
  • 宿主只保留 ASP.NET Core HTTP 控制器层,以及其后端 Flyshot.ControllerClientCompat 兼容服务。
  • ExecuteTrajectory 与 ExecuteFlyShotTraj 已经接入 Planning + Triggering + Runtime 链路;Web 状态页已通过 /status 和 /api/status/snapshot 暴露当前兼容层与运行时状态。
  • Flyshot.Core.Planning 保留规划公共模型、样条、采样、导出和运动学能力;C# ICSP / self-adapt-icsp 已拆分到可选项目 Flyshot.CSharp.Planning。
  • Flyshot.Native.Planning 已提供默认 Rust ICSP 规划入口,通过 C ABI 调用 flyshot_planning;普通轨迹和飞拍轨迹的默认 method="icsp" 使用 Rust 后端,method="icsp-csharp" 和 method="self-adapt-icsp" 只有显式注册 C# 后端时可用。
  • Flyshot.Runtime.Fanuc 已固化 10010 / 10012 / 60015 基础协议帧编解码。10010 状态通道以 j519 协议.pcap 和 Rvbust/uttc-20260428/20260428.pcap 真机抓包确认为 90B 固定帧。
  • 2026-04-28 UTTC 抓包确认:UDP 60015 命令 target[0..5] 为关节角度制 deg,JointDetialTraj.txt 为弧度制 rad,speed_ratio=0.7 体现为 UDP 下发时间轴约 1.427730x 拉伸;2026-04-30 实体机确认 speed_ratio 不影响生成的 JointTraj.txt 规划时长,当前实际生成约 7.4s 轨迹。
  • 2026-04-30 本机 50001/TCP+JSON 抓包确认:ExecuteFlyShotTraj(save_traj=true,use_cache=false) 请求只显式携带规划方法、保存、缓存和等待参数,不携带 JointLimits / acc_limit / jerk_limit / velocity / acceleration / jerk。因此旧系统不可见的有效规划限制不再继续假设来自公开链路,新系统按 replacement-only 内部参数限制规划加速度。
  • 真机 Socket 客户端已具备基础连接、程序启停、速度倍率/TCP/IO 参数命令和 J519 状态包驱动发送能力;稠密轨迹下发已按 speed_ratio 做执行时间缩放,并已用 0.5/0.7/1.0 三份 UTTC 抓包固化 J519 golden tests。真实 R30iB 全流程现场联调仍需执行。
  • 2026-05-11 对 UTTC_MS11 的独立 ConfigRoot 重新生成确认:flyshot 链路若继续用离散 jerk 作为阻断条件,会把新结果拉长到约 16.576s / 33.152s;只保留速度、加速度校验并跳过 flyshot jerk 阻断后,新 1.0x / 0.5x 时长回落到约 7.552s / 15.104s,与旧抓包主段 7.408s / 14.808s 的差异已很小,当前按可忽略处理。详见 docs/uttc-ms11-jerk-validation-decision-20260511.md。
  • MoveJoint 已按 2026042802-mvpoint*.pcap 复刻为点到点临时轨迹:当前关节到目标关节的关节空间直线,五次 smoothstep 起停,按 status=15 运动窗口复现 40/55/77 点,并由 J519 层完成 rad -> deg 下发。
  • 单程序只对应一台机器人,上传/删除/恢复飞拍轨迹统一读写运行目录 Config/RobotConfig.json,不再创建独立轨迹存储文件。
  • 服务启动时支持真机优先初始化:在 ControllerClientCompat.AutoInit 配置 RobotName 和 RobotIp,启动后执行 SetUpRobot → Connect → EnableRobot(8);连接失败后进入 OfflineReady,模型仍可用于离线飞拍规划。
  • 飞拍资产与机器人型号解耦:未加载模型时也可上传、列出和删除;模型自由度与关节限制延迟到规划阶段校验。
  • /save_traj_info/ 已成为离线规划入口,返回最终 8ms 发送点列、ShotEvents、触发绑定和全部导出文件绝对路径;/execute_flyshot/ 仍只允许 RealReady。

单位约定总览:

  • 规划层、JointDetialTraj.txt 和运行时内部关节轨迹,默认按弧度制 rad 理解。
  • UDP 60015 J519 命令 target[0..5] 和响应关节反馈按角度制 deg 理解;运行时下发前必须显式执行 rad -> deg 转换。
  • TCP 10010 状态通道是混合单位:pose[0..2] 更像 mm,pose[3..5] 更像 deg,joint_or_ext[0..5] 当前现场抓包更支持按 rad 理解。
  • 不要把“关节角”默认当成统一单位;在规划、状态监控和 J519 执行三条链路之间必须明确标注 rad/deg。

当前现场主链路的单位流转可简化为:

位置 内容 当前更可信单位
规划输入 / 轨迹算法 关节角 rad
JointDetialTraj.txt / JointTraj.txt 关节角 rad
运行时下发前内部轨迹 关节角 rad
UDP 60015 命令 target[0..5] 关节目标 deg
UDP 60015 响应 Joint 关节反馈 deg
TCP 10010 pose[0..2] X/Y/Z mm
TCP 10010 pose[3..5] 姿态角 deg
TCP 10010 joint_or_ext[0..5] 关节状态 更像 rad
TCP 10010 joint_or_ext[6..8] 扩展轴槽位 当前样本为 0

TCP 10010 的正式字段表、样例帧和已确认/待确认说明见 docs/fanuc-10010-state-frame.md。

开发约定:

  • 建议从 flyshot-replacement/ 根目录启动 IDE、终端和 Codex 会话。
  • 当前仓库内的 @ 引用主要覆盖本仓库文件;引用父目录资料时,请直接写相对路径,如 ../analysis/ICSP_algorithm_reverse_analysis.md。
  • 父目录中的 analysis/、FlyingShot/、RobotController/、RPS/ 主要作为逆向参考资料和样本来源,新实现默认只落地在当前仓库。

当前已完成:

  • 初始化独立仓库
  • 创建 dotnet 8 解决方案骨架
  • 打通最小宿主与 /healthz
  • 建立领域模型与模块边界
  • 落地配置兼容与机器人模型解析
  • 落地 Rust ICSP、可选 C# ICSP / self-adapt-icsp 轨迹规划与飞拍触发时间轴
  • 完成 ICSP 轨迹导出结果与旧系统对齐
  • 增加 Rust cdylib ICSP 核心、C# P/Invoke 适配和 C#/Rust 自动对拍
  • 将 ExecuteTrajectory / ExecuteFlyShotTraj 接入 FANUC 运行时链路
  • 落地 Web 状态页
  • 落地浏览器内 OpenAPI 自动驱动的接口调试页(/debug),与 Swagger:Enabled 同步可见
  • 调试页的人类可读说明文本已静态内嵌到 debug.html,即使发布产物删除 XML 文档也能继续展示接口提示
  • 固化 10010 / 10012 / 60015 FANUC 基础协议帧编解码,确认 10010 状态帧为 90B
  • 使用本地 TCP/UDP 模拟器覆盖命令通道、状态通道和 J519 基础收发
  • 补齐 Get/SetSpeedRatio、Get/SetTCP、Get/SetIO 真机命令体与响应解析
  • 保留新 HTTP 接口路线,明确不再实现旧 50001/TCP+JSON 网关
  • 将飞拍轨迹持久化收敛到运行目录 Config/RobotConfig.json
  • 服务启动自动初始化机器人:通过 ControllerClientCompat.AutoInit 配置节指定 RobotName 和 RobotIp,启动时自动执行初始化链路
  • 完成真机优先与离线飞拍规划改造:RealReady / OfflineReady / ModelLoadFailed 状态、固定轨迹资产、完整离线规划响应和 Debug 页面
  • 删除生产仿真切换 HTTP 入口及旧 /init_mpc_robt,统一使用 /init_mpc_robot

规划后端与 Rust ICSP 原生库构建

普通轨迹或飞拍轨迹的默认参数 method="icsp" 会调用 Rust ICSP 后端。旧 method="icsp_rust" 已不再作为正式入口,调用时会提示改用 method="icsp";Rust 原生库缺失时会明确报错,不会静默回退 C#。

C# ICspPlanner 与 SelfAdaptIcspPlanner 已拆分到 Flyshot.CSharp.Planning.dll。默认服务项目不引用该 DLL;只有在部署方显式引用并调用 AddCSharpPlanningBackends() 后,method="icsp-csharp" 与 method="self-adapt-icsp" 才可用。

Windows x64 需要安装:

  • rustup 的 stable-x86_64-pc-windows-msvc 工具链。
  • Visual Studio 或 Visual Studio Build Tools 的 C++ x64 编译工具和 Windows SDK。

在仓库根目录执行:

.\build\Copy-NativePlanningArtifacts.ps1 -Configuration Release

脚本会执行 cargo build --release,构建 native/flyshot-native-planning/target/release/flyshot_planning.dll, 并默认复制到 src/Libs/flyshot_planning.dll 与 tests/Flyshot.Core.Tests/bin/Release/net8.0/。发布服务时可通过 -DestinationDirectories 把原生库复制到实际发布目录。

Linux x64 在已安装 stable-x86_64-unknown-linux-gnu 工具链的 Linux 环境执行同一脚本, 产物为 libflyshot_planning.so,默认写入 src/Libs/libflyshot_planning.so。 Windows 第一阶段不要求交叉编译 Linux 原生库。

剩余 Todo:

  1. 配置与测试基线

    • 修正 ConfigCompatibilityTests 当前样本路径漂移:Rvbust/EOL10_EAU_0/RobotConfig.json 不再包含 001,应改用稳定样本或更新断言。
    • 将 RobotConfig.json 中的 use_do、io_keep_cycles、acc_limit、jerk_limit、adapt_icsp_try_num 全部贯通到规划和执行链路。
    • 将上传飞拍轨迹统一保存到运行目录 Config/RobotConfig.json 的 flying_shots 节点。
    • 为新 HTTP API 补一份当前现场调用顺序文档,替代旧 ControllerClient 工作流:见 docs/fanuc-field-runtime-workflow.md。
  2. 轨迹规划

    • 补齐 ICSP 最终 global_scale > 1.0 失败判定,避免未收敛轨迹被当作有效结果执行。
    • 将 self-adapt-icsp 的补点次数改为使用配置中的 adapt_icsp_try_num。
    • 新增 replacement-only 的 planning_acceleration_scale 规划加速度校准参数,用于复现旧服务端公开链路中抓不到的保守 effective limits;该参数只影响规划结果,不影响运行时 speed_ratio。
    • 如果现场仍需要 method="doubles",实现 TrajectoryDoubleS 等价规划;否则在 HTTP 文档中明确标为不支持。
    • 把已完成对齐的旧系统轨迹样本固化为 golden tests,防止后续重构破坏轨迹一致性。
    • 将 Rvbust/uttc-20260428/Data/JointDetialTraj.txt 固化为 J519 golden 样本:输入为 rad,下发为 deg,并按 speed_ratio 拉伸时间轴;覆盖 2026042802-0.5/0.7/1.pcap。
    • 补齐飞拍 save_traj / SaveTrajInfo 的规划结果导出,将关节关键点、稠密关节轨迹、笛卡尔关键点、稠密笛卡尔轨迹和 ShotEvents 写入 Config/Data/<name>。
  3. FANUC TCP 10012 命令通道

    • 补齐 GetSpeedRatio / SetSpeedRatio 真机命令体与响应解析。
    • 补齐 GetTCP / SetTCP 真机命令体与响应解析。
    • 补齐 GetIO / SetIO 真机命令体与响应解析。
    • 所有命令响应必须检查 result_code,失败时返回可诊断错误,而不是只更新本地缓存。
  4. FANUC TCP 10010 状态通道

    • 用 j519 协议.pcap 和 Rvbust/uttc-20260428/20260428.pcap 中的 90B 真机状态帧扩充状态解析测试样本。
    • 明确 pose[6]、joint_or_ext[9]、尾部状态字的字段语义,并映射到 ControllerStateSnapshot。
    • 补充 TCP 10010 正式字段表与已确认/待确认说明:见 docs/fanuc-10010-state-frame.md。
    • 补充断线清理和异常帧拒绝测试。
    • 补充状态通道超时和重连策略,超时后标记陈旧状态并按退避策略自动重连。
  5. FANUC UDP 60015 J519 运动链路

    • 重新确认 J519 发送节拍与 FanucControllerRuntime 稠密轨迹循环的职责边界:FanucJ519Client 收到机器人 UDP status 后按该 status sequence 回发命令,FanucControllerRuntime 只按轨迹时间更新下一帧命令内容。
    • 执行时将规划输出 rad 转为 J519 deg 目标,并按当前 speed_ratio 调整原轨迹采样时间尺度:第 k 个 J519 目标的实发时间为 t_send = k * 0.008,采样时间为 t_traj = t_send * speed_ratio,包数为 floor(duration / (0.008 * speed_ratio)) + 1。
    • 补齐 accept_cmd、received_cmd、sysrdy、rbt_inmotion 状态位解析与启动前闭环检查;若已有 J519 响应且 accept_cmd/sysrdy 未就绪,则拒绝稠密轨迹执行。
    • 校验序号递增、状态包 sequence 校准、响应滞后、丢包、停止包和最后一帧语义:UTTC golden tests 覆盖连续 seq、无重复 seq、响应滞后 2 到 8 帧、lastData=0;J519 客户端测试覆盖收到 status 后按 status sequence 回发命令和 type 2 状态输出停止包。
    • 将飞拍 IO 触发的 write_io_type/index/mask/value 与现场控制柜实际 IO 地址逐项对齐;UTTC golden tests 确认 17 个触发点对应 17 个 UDP IO set 脉冲、17 个 clear 帧,mask 集合为 10/12/14。
    • 将 MoveJoint 从单点最终目标改为临时 PTP 稠密轨迹:按 status=15 运动窗口统计,speed=1 抓包 40 点,speed=0.7 抓包 55 点,speed=0.5 抓包 77 点,路径为关节空间直线 + smoothstep 进度。
    • ExecuteFlyShotTraj(move_to_start=true) 复用临时 PTP 稠密轨迹移动到规划起点,并等待运行时完成后再启动飞拍轨迹,避免第一帧 J519 目标突变导致控制柜报警。
    • ExecuteFlyShotTraj(wait=true) 等待正式飞拍轨迹执行完成后再返回;HTTP /execute_flyshot/ 已接入旧抓包中的 wait 字段,默认值为 true。
  6. 真机联调与运行安全

    • 在真实 R30iB + RVBUSTSM 程序上验证 Connect -> EnableRobot -> ExecuteFlyShotTraj -> StopMove -> DisableRobot -> Disconnect 全流程。
    • 实体机复核运行速度对轨迹生成时间的影响:speed_ratio 不影响 IsFlyshotTrajectoryValid / SaveTrajectoryInfo 生成的 JointTraj.txt 规划时长,当前实际生成约 7.4s 轨迹;运行阶段仅 J519 下发时长和包数按 speed_ratio 拉伸,UTTC_MS11 参考值为约 7.4s 与 10.56s。
    • 增加急停、伺服未就绪、程序未启动、网络断开、控制柜拒收命令等故障路径处理。
    • 给 HTTP 执行接口增加运行互斥、执行中拒绝重复轨迹、取消和超时控制。
    • 增加运行日志、协议摘要日志和状态快照导出,便于现场排查。
  7. 发布与部署

    • 增加 Obfuscar 跨平台混淆发布脚本,全部 Flyshot.* 自研程序集会生成一份不区分运行平台的 .NET 8 框架依赖部署包。
    • 固化 Windows / Linux 启动脚本和 systemd 服务配置。
    • 补充生产配置模板、端口说明和现场部署检查表。
    • 给 Web 状态页增加程序状态和最近报警显示;J519 状态位已通过快照和状态页显示。

混淆发布

发布脚本直接依赖构建环境,不在仓库中引用或还原 Obfuscar 包。首次使用前安装全局工具:

dotnet tool install --global Obfuscar.GlobalTool --version 2.2.50

安装后确认 obfuscar.console 已加入当前终端的 PATH,然后在仓库根目录执行:

pwsh -NoProfile -File .\scripts\Publish-Obfuscated.ps1

也可以在 VS Code 中运行 publish 任务。脚本不再接受 RID 或运行平台参数,默认生成:

  • outputs/obfuscated/framework-dependent/:Windows 与 Linux 共用的 .NET 8 框架依赖混淆部署包。
  • outputs/obfuscation-maps/framework-dependent/Mapping.txt:仅供内部还原异常堆栈使用,不得交付给用户。

Visual Studio 的 FolderProfile 已接入同一套混淆流程。在“发布”页面选择 FolderProfile 并点击“发布”后,Visual Studio 会生成 .NET 8 框架依赖多文件包,再自动混淆发布目录中的全部 Flyshot.*.dll。如果环境缺少 obfuscar.console、缺少对应的 .NET 8 共享框架或混淆失败,Visual Studio 发布会直接失败,不会静默留下未保护产物。

混淆范围包含发布目录中的全部 Flyshot.*.dll 自研程序集,并校验当前八个核心程序集不可缺失;后续新增的 Flyshot.* 模块也会自动纳入。第三方程序集不会被处理;公共 API、属性和事件名称会保留,以维持 ASP.NET Core 控制器发现、依赖注入、配置绑定、JSON 序列化和 Swagger 行为,内部类型、私有方法及字段会执行重命名。

若环境缺少 obfuscar.console、发布目录缺少任一自研程序集、混淆器返回失败或未生成完整输出,脚本会返回非零退出码并停止,不会把未完整保护的产物作为成功结果交付。

混淆完成后会删除发布目录中的 Flyshot*.xml XML 文档和 Flyshot*.pdb 调试符号,避免反编译器自动显示源码文档注释。生产环境 Swagger 因此不再展示来自 XML 文档的接口说明,但接口路由和调用不受影响。

启动部署包时必须先进入对应 RID 的发布目录,确保宿主能从当前目录加载 appsettings.json、NLog.config 和 Config/:

Set-Location .\outputs\obfuscated\framework-dependent
dotnet .\Flyshot.Server.Host.dll
cd outputs/obfuscated/framework-dependent
dotnet Flyshot.Server.Host.dll

Windows 与 Linux 目标机器都必须预先安装 .NET 8 ASP.NET Core Runtime。

Description
No description provided
Readme 11 MiB
Languages
RobotFramework 93%
C# 6.2%
Python 0.4%
JavaScript 0.2%
CSS 0.1%