Files
FlyShotHost/docs/controller-client-api-reverse-engineering.md
yunxiao.zhu 8a20d9f507 feat: 实现 ControllerClient HTTP 兼容层及 FANUC 运行时
- 新增 Flyshot.ControllerClientCompat 兼容层模块
  - 新增 Flyshot.Runtime.Fanuc 运行时模块
  - 新增 LegacyHttpApiController 暴露 HTTP 兼容 API
  - 补充 RuntimeOrchestrationTests 等测试覆盖
  - 补充 docs/ 兼容性需求与逆向工程文档
  - 更新 Host 注册、配置及解决方案引用

  变更概览:
  - Flyshot.ControllerClientCompat — 旧 ControllerClient 语义的 HTTP 适配
  - Flyshot.Runtime.Fanuc — IControllerRuntime 的 FANUC 真机实现
  - LegacyHttpApiController — HTTP API 兼容旧 SDK
  - docs/ — 兼容性需求与逆向工程分析文档
  - 测试:RuntimeOrchestrationTests、LegacyHttpApiCompatibilityTests
2026-04-24 16:55:25 +08:00

31 KiB
Raw Blame History

ControllerClient API 全量逆向归档

记录时间2026-04-24 适用仓库:flyshot-replacement 目标:为后续 50001/TCP+JSON 兼容网关实现提供只读合同

1. 总览

本次归档覆盖 ../FlyingShot/FlyingShot/Include/ControllerClient/ControllerClient.h 中全部 32 个公开方法。

当前分类结果:

  • 29 个 API 可与 ControllerServer 公开 _Xxx 方法一一映射
  • 1 个 API 属于协议分发层行为:GetServerVersion
  • 2 个 API 属于客户端侧行为:ConnectServerGetClientVersion

本文档中的“协议 / 命令线索”有两个层次:

  • 命令名:已从头文件、字符串或逆向文档坐实,例如 SetUpRobotGetIO
  • JSON envelope请求 JSON 的精确键名、必填规则、整体结构;当前大多仍未完全恢复

因此,除 GetSpeedRatio / SetSpeedRatio / GetIO / SetIO 等已在命令通道层坐实字段顺序的接口外,其余接口默认只写“命令名已知,精确 JSON 包结构待确认”。

置信度定义:

  • 高:头文件 + 示例/手册 + 字符串/逆向文档三方交叉确认
  • 中:头文件 + 示例,或头文件 + 字符串,缺少第三方交叉
  • 低:仅有间接线索,未达到本轮归档主结论标准

2. 传输与版本

ConnectServer

  • C++ 公开签名:bool ConnectServer(const std::string &server_ip = "127.0.0.1", unsigned port = 50001);
  • Python 包装形态:c.ConnectServer(server_ip="127.0.0.1", port=50001) -> bool
  • 服务端归属:客户端传输层行为,不进入 ControllerServer._Xxx 命令表
  • 协议 / 命令线索:建立到 127.0.0.1:50001 的 TCP 连接JSON 负载只发生在连接建立之后
  • 返回值与默认值:默认 server_ip="127.0.0.1"port=50001;成功返回 true
  • 典型工作流位置:所有远程 API 的前置步骤
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyUseRealRobot.py
  • 置信度:高
  • 待确认点:重连、超时、握手细节未恢复

GetServerVersion

  • C++ 公开签名:bool GetServerVersion(std::string &version);
  • Python 包装形态:样例中表现为 controller.GetServerVersion() -> str
  • 服务端归属:协议分发层行为;当前未恢复到显式 _GetServerVersion
  • 协议 / 命令线索:命令名字符串 GetServerVersion 已坐实;服务端存在 GetServerVersion success: {}. 日志;精确 JSON envelope 未恢复
  • 返回值与默认值C++ 为 bool + out stringPython 样例把结果当作直接字符串使用
  • 典型工作流位置:ConnectServer 之后、机器人初始化前后均可读取的元信息接口
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdlibControllerClient.soControllerServer.cpython-37m-x86_64-linux-gnu.so
  • 置信度:高
  • 待确认点Python 失败路径的返回形态未看到样例;请求 JSON 的精确字段未恢复

GetClientVersion

  • C++ 公开签名:bool GetClientVersion(std::string &version);
  • Python 包装形态:未见公开样例;从包装库字符串看接口存在
  • 服务端归属:客户端本地行为,不进入服务端命令表
  • 协议 / 命令线索:libControllerClient.soPyControllerClient 都有 GetClientVersion 符号;未见 ControllerServer 对应 _Xxx
  • 返回值与默认值C++ 为 bool + out stringPython 侧返回形态待确认
  • 典型工作流位置:客户端自检或 SDK 版本上报,不依赖服务端状态
  • 证据来源:ControllerClient.hlibControllerClient.soPyControllerClient.cpython-37m-x86_64-linux-gnu.so
  • 置信度:高
  • 待确认点:实际版本字符串来源与 Python 包装失败行为未恢复

3. 机器人初始化

SetUpRobot

  • C++ 公开签名:bool SetUpRobot(const std::string &robot_name);
  • Python 包装形态:c.SetUpRobot("FANUC_LR_Mate_200iD") -> bool
  • 服务端归属:ControllerServer._SetUpRobot
  • 协议 / 命令线索:命令名 SetUpRobot 已坐实;参数高概率是 robot_name;精确 JSON envelope 未恢复
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:创建客户端并连上 50001 后首先调用;旧说明明确它是最先执行的服务端初始化动作
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:请求字段键名是否为 robot_name 仍需抓包或 hook 坐实

SetUpRobotFromEnv

  • C++ 公开签名:bool SetUpRobotFromEnv(const std::string &env_file);
  • Python 包装形态:未见公开样例;服务端与客户端字符串均存在
  • 服务端归属:ControllerServer._SetUpRobotFromEnv
  • 协议 / 命令线索:命令名 SetUpRobotFromEnv 已坐实;参数高概率是环境文件绝对路径;精确 JSON envelope 未恢复
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:与 SetUpRobot 二选一;当现场通过环境文件而不是型号名初始化时使用
  • 证据来源:ControllerClient.hControllerServer_analysis.mdControllerServer 字符串、libControllerClient.so
  • 置信度:高
  • 待确认点:环境文件路径是否必须为绝对路径由注释可见,但服务端是否做额外归一化未恢复

IsSetUp

  • C++ 公开签名:bool IsSetUp();
  • Python 包装形态:c.IsSetUp() -> bool
  • 服务端归属:ControllerServer._IsSetUp
  • 协议 / 命令线索:命令名 IsSetUp 已坐实;精确 JSON envelope 未恢复
  • 返回值与默认值:直接返回布尔值
  • 典型工作流位置:SetUpRobotSetUpRobotFromEnv 之后的状态确认
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:服务端返回是否仅受机器人对象存在性控制,还是还依赖模型/控制器更深层状态,当前未完全恢复

SetShowTCP

  • C++ 公开签名:bool SetShowTCP(bool is_show = true, double axis_length = 0.1, size_t axis_size = 2);
  • Python 包装形态:c.SetShowTCP(is_show=True, axis_length=0.1, axis_size=2) -> bool
  • 服务端归属:ControllerServer._SetShowTCP
  • 协议 / 命令线索:命令名 SetShowTCP 已坐实;字符串中可见 SetShowTCP is_show success/failed;精确 JSON envelope 未恢复
  • 返回值与默认值:默认 is_show=trueaxis_length=0.1axis_size=2
  • 典型工作流位置:初始化完成后、切换控制器前的仿真显示配置
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyControllerServer_analysis.mdControllerServer 字符串
  • 置信度:高
  • 待确认点:仅仿真控制器生效还是真实控制器也接受该命令,当前未见明确负例

GetName

  • C++ 公开签名:std::string GetName();
  • Python 包装形态:c.GetName() -> str
  • 服务端归属:ControllerServer._GetName
  • 协议 / 命令线索:命令名 GetName 已坐实;精确 JSON envelope 未恢复
  • 返回值与默认值:直接返回机器人名称字符串
  • 典型工作流位置:完成机器人初始化后读取名称确认
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:失败时是返回空串还是异常/默认值Python 样例未覆盖

GetDoF

  • C++ 公开签名:int GetDoF();
  • Python 包装形态:c.GetDoF() -> int
  • 服务端归属:ControllerServer._GetDoF
  • 协议 / 命令线索:命令名 GetDoF 已坐实;精确 JSON envelope 未恢复
  • 返回值与默认值:直接返回自由度整数
  • 典型工作流位置:完成机器人初始化后读取自由度
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:失败时的客户端行为未恢复

4. 控制器状态

SetActiveController

  • C++ 公开签名:bool SetActiveController(bool sim = true);
  • Python 包装形态:c.SetActiveController(sim=True) -> bool;真机样例使用 sim=False
  • 服务端归属:ControllerServer._SetActiveController
  • 协议 / 命令线索:命令名 SetActiveController 已坐实;字符串中可见 SetActiveController sim success/failed
  • 返回值与默认值:默认 sim=true
  • 典型工作流位置:机器人初始化后、Connect 前,用于在仿真控制器和真实控制器之间切换
  • 证据来源:ControllerClient.hUseControllerClient.pyUseRealRobot.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:切换控制器时是否会隐式断开旧控制器,当前只有 _DisconnectAll 的间接线索

Connect

  • C++ 公开签名:bool Connect(const std::string &robot_ip);
  • Python 包装形态:c.Connect("192.168.10.101") -> bool
  • 服务端归属:ControllerServer._Connect
  • 协议 / 命令线索:命令名 Connect 已坐实;字符串中可见 Connect ip success/failed
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:选定活动控制器后,通知服务端连接真实机器人 IP
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyUseRealRobot.py、SDK 手册、ControllerServer_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 键名是否为 iprobot_ip 未恢复;仿真模式下是否接受同一命令仍需实现侧验证

Disconnect

  • C++ 公开签名:bool Disconnect();
  • Python 包装形态:c.Disconnect() -> bool
  • 服务端归属:ControllerServer._Disconnect
  • 协议 / 命令线索:命令名 Disconnect 已坐实;字符串中可见 Disconnect success/failed
  • 返回值与默认值:直接返回布尔值
  • 典型工作流位置:真实控制器断开或工作流结束时调用
  • 证据来源:ControllerClient.hControllerServer_analysis.mdControllerServer 字符串、libControllerClient.so
  • 置信度:高
  • 待确认点:是否同步清理状态通道 / 命令通道 / 伺服通道,当前只在 FANUC 分析文档看到对象链,并未完全坐实释放顺序

EnableRobot

  • C++ 公开签名:bool EnableRobot(unsigned buffer_size = 2);
  • Python 包装形态:c.EnableRobot() -> bool
  • 服务端归属:ControllerServer._EnableRobot
  • 协议 / 命令线索:命令名 EnableRobot 已坐实;字符串中可见 EnableRobot success/failed
  • 返回值与默认值:默认 buffer_size=2
  • 典型工作流位置:Connect 后使能机器人;多数运动 API 前置条件
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyUseRealRobot.pyControllerServer_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:buffer_size 在旧服务端具体如何映射到伺服缓冲区参数,当前未完全恢复

DisableRobot

  • C++ 公开签名:bool DisableRobot();
  • Python 包装形态:c.DisableRobot() -> bool
  • 服务端归属:ControllerServer._DisableRobot
  • 协议 / 命令线索:命令名 DisableRobot 已坐实;字符串中可见 DisableRobot success/failed
  • 返回值与默认值:直接返回布尔值
  • 典型工作流位置:停机或退出前关闭机器人使能
  • 证据来源:ControllerClient.hControllerServer_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:与 StopMove 的先后顺序约束未恢复

StopMove

  • C++ 公开签名:bool StopMove();
  • Python 包装形态:c.StopMove() -> bool
  • 服务端归属:ControllerServer._StopMove
  • 协议 / 命令线索:命令名 StopMove 已坐实;字符串中可见 StopMove success/failed
  • 返回值与默认值:直接返回布尔值
  • 典型工作流位置当前运动中止Python 示例中调用后会再次 EnableRobot()
  • 证据来源:ControllerClient.hUseControllerClient.pyControllerServer_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:是否会清空控制器执行队列、是否必须重新使能,当前只从示例看到倾向性而非硬约束

5. 参数与 IO

GetSpeedRatio

  • C++ 公开签名:double GetSpeedRatio();
  • Python 包装形态:c.GetSpeedRatio() -> float
  • 服务端归属:ControllerServer._GetSpeedRatio
  • 协议 / 命令线索:命令通道 MsgID = 0x2206;响应字段为 ratio_intresult_code;成功后客户端将 ratio_int / 100.0
  • 返回值与默认值:直接返回 0~1 之间的倍率
  • 典型工作流位置:连机并使能后读取当前速度倍率
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdCommonMsg_protocol_analysis.md
  • 置信度:高
  • 待确认点:服务端 JSON 层到命令通道层的参数桥接结构未恢复

SetSpeedRatio

  • C++ 公开签名:bool SetSpeedRatio(double ratio);
  • Python 包装形态:c.SetSpeedRatio(0.8) -> bool
  • 服务端归属:ControllerServer._SetSpeedRatio
  • 协议 / 命令线索:命令通道 MsgID = 0x2207;请求字段为 ratio_int_0_100;输入 double 先乘 100 并夹到 [0,100]
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:连机并使能后修改控制器速度倍率
  • 证据来源:ControllerClient.hUseControllerClient.pyUseRealRobot.py、SDK 手册、ControllerServer_analysis.mdCommonMsg_protocol_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点ratio 越界时客户端是裁剪还是直接失败,当前更偏向裁剪,但缺少公开负例

GetTCP

  • C++ 公开签名:bool GetTCP(Pose &tcp);
  • Python 包装形态:res, tcp = c.GetTCP()
  • 服务端归属:ControllerServer._GetTCP
  • 协议 / 命令线索:控制器命令通道底层接口 GetTCP 已有 MsgID = 0x2200 证据,但 ControllerClient JSON 层请求结构未完全恢复
  • 返回值与默认值C++ 为 bool + out PosePython 为 (bool, Pose)
  • 典型工作流位置:连机后读取当前控制器 TCP
  • 证据来源:ControllerClient.hUseControllerClient.pyControllerServer_analysis.mdCommonMsg_protocol_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 层是否支持多个 TCP ID目前只看到底层命令通道有 tcp_id

SetTCP

  • C++ 公开签名:bool SetTCP(const Pose &tcp);
  • Python 包装形态:c.SetTCP(tcp) -> bool
  • 服务端归属:ControllerServer._SetTCP
  • 协议 / 命令线索:控制器命令通道底层接口 SetTCP 已有 MsgID = 0x2201 证据JSON 层精确字段未恢复
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:连机后修改控制器 TCP
  • 证据来源:ControllerClient.hUseControllerClient.pyControllerServer_analysis.mdCommonMsg_protocol_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 层是否也暴露 tcp_id 概念尚未恢复

GetIO

  • C++ 公开签名:bool GetIO(unsigned port, bool &value, IOType type = kIOTypeDI);
  • Python 包装形态:res, value = c.GetIO(port=1, io_type=IOType.kIOTypeDI)
  • 服务端归属:ControllerServer._GetIO
  • 协议 / 命令线索:命令通道 MsgID = 0x2208;请求字段顺序是 io_typeio_index;响应字段是 result_codeio_value
  • 返回值与默认值:默认 type = kIOTypeDIC++ 为 bool + out boolPython 为 (bool, bool)
  • 典型工作流位置:连机后读取 DI/DO/RI/RO 等 IO 值
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdCommonMsg_protocol_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:高层 JSON 是否把字段命名为 port / value / type,还是 io_index / io_type,当前未抓到完整包

SetIO

  • C++ 公开签名:bool SetIO(unsigned port, bool value, IOType type = kIOTypeDO);
  • Python 包装形态:c.SetIO(port=1, value=True, io_type=IOType.kIOTypeDO) -> bool
  • 服务端归属:ControllerServer._SetIO
  • 协议 / 命令线索:命令通道 MsgID = 0x2209;请求字段顺序是 io_typeio_indexio_value
  • 返回值与默认值:默认 type = kIOTypeDO
  • 典型工作流位置:连机后设置数字输出;飞拍链路之外的普通 IO 调试也会用到
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdCommonMsg_protocol_analysis.mdFANUC_realtime_comm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:布尔值在高层 JSON 中是否以 true/false 传输、在命令通道中以 float 传输,当前只坐实了命令通道层

6. 运动与求解

GetJointPosition

  • C++ 公开签名:bool GetJointPosition(JointPositions &joint_position);
  • Python 包装形态:res, joints = c.GetJointPosition()
  • 服务端归属:ControllerServer._GetJointPositions
  • 协议 / 命令线索:命令名 GetJointPositions 已坐实;客户端公开 API 名与服务端方法名存在单复数差异
  • 返回值与默认值C++ 为 bool + out JointPositionsPython 为 (bool, JointPositions)
  • 典型工作流位置:读取当前关节角,常作为 GetNearestIK 的 seed 或 MoveJoint 的基准
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 层返回数组字段键名未恢复

GetPose

  • C++ 公开签名:bool GetPose(Pose &pose);
  • Python 包装形态:res, pose = c.GetPose()
  • 服务端归属:ControllerServer._GetPose
  • 协议 / 命令线索:命令名 GetPose 已坐实;字符串中可见 GetPose success/failed
  • 返回值与默认值C++ 为 bool + out PosePython 为 (bool, Pose)
  • 典型工作流位置:读取当前 TCP 位姿,常与 GetNearestIK 配套使用
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:位姿坐标系定义虽然在 Types.h 中体现为 7 元数组,但 JSON 层字段结构未恢复

GetNearestIK

  • C++ 公开签名:bool GetNearestIK(const Pose &pose, const JointPositions &seed, JointPositions &ik);
  • Python 包装形态:res, ik = c.GetNearestIK(pose, joint_seed=joints)
  • 服务端归属:ControllerServer._GetNearestIK
  • 协议 / 命令线索:命令名 GetNearestIK 已坐实;字符串中可见 GetNearestIK success/failed
  • 返回值与默认值C++ 为 bool + out JointPositionsPython 为 (bool, JointPositions)
  • 典型工作流位置:先 GetPose 得到当前位姿,再构造目标位姿,并使用当前关节或邻近关节作为 seed 求最近 IK
  • 证据来源:ControllerClient.hUseControllerClient.pyControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 层中 seed 参数键名在 Python 里表现为 joint_seed,但 C++ 注释写的是 seed;高层字段命名仍待确认

MoveJoint

  • C++ 公开签名:bool MoveJoint(const JointPositions &joint_position);
  • Python 包装形态:c.MoveJoint(home_joint) -> bool
  • 服务端归属:ControllerServer._MoveJoint
  • 协议 / 命令线索:命令名 MoveJoint 已坐实;字符串中可见 MoveJoint waypoint success/failed
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:点到点回零或移动到飞拍轨迹起点
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyControllerServer_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:移动速度/平滑参数是否固定在服务端内部,公开 API 未暴露

ExecuteTrajectory

  • C++ 公开签名:bool ExecuteTrajectory(const std::vector<JointPositions> &waypoints, const std::string &method = "icsp", bool save_traj = false);
  • Python 包装形态:c.ExecuteTrajectory(waypoints=[...], method="icsp", save_traj=True) -> bool
  • 服务端归属:ControllerServer._ExecuteTrajectory
  • 协议 / 命令线索:命令名 ExecuteTrajectory 已坐实;method 至少支持 icspdoubles
  • 返回值与默认值:默认 method="icsp"save_traj=false
  • 典型工作流位置:普通多点轨迹执行,不带飞拍 IO输入是关节空间稀疏 waypoint而不是笛卡尔点
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdTrajectory_generation_algorithm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 中 waypoint 列表的键名和序列化结构未恢复;doubles 的失败语义未在公开样例中体现

7. 飞拍轨迹

UploadFlyShotTraj

  • C++ 公开签名:bool UploadFlyShotTraj(const std::string &name, const std::vector<JointPositions> &waypoints, const std::vector<bool> &shot_flags, const std::vector<int> &offset_values, const std::vector<std::vector<int>> &addrs);
  • Python 包装形态:c.UploadFlyShotTraj(name="test_traj", waypoints=..., shot_flags=..., offset_values=..., addrs=...) -> bool
  • 服务端归属:ControllerServer._UploadFlyShotTraj
  • 协议 / 命令线索:命令名 UploadFlyShotTraj 已坐实;客户端字符串中可见 StartUploadFlyShotTrajEndUploadFlyShotTraj,说明上传阶段很可能分为开始 / 传输 / 结束三个子步骤
  • 返回值与默认值:成功返回 true;无默认参数
  • 典型工作流位置:运行时动态构造飞拍轨迹时,先把轨迹定义登记到服务端
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdTrajectory_generation_algorithm_analysis.mdlibControllerClient.soControllerServer 字符串
  • 置信度:高
  • 待确认点JSON 上传是否一次性发送完整 payload还是像字符串暗示的那样分片上传当前未完全恢复

DeleteFlyShotTraj

  • C++ 公开签名:bool DeleteFlyShotTraj(const std::string &name);
  • Python 包装形态:c.DeleteFlyShotTraj(name="test_traj") -> bool
  • 服务端归属:ControllerServer._DeleteFlyShotTraj
  • 协议 / 命令线索:命令名 DeleteFlyShotTraj 已坐实;字符串中可见 DeleteFlyShotTraj {} success/failed
  • 返回值与默认值:成功返回 true
  • 典型工作流位置:删除已上传的临时飞拍轨迹定义
  • 证据来源:ControllerClient.hUseControllerClient.py、SDK 手册、ControllerServer_analysis.mdPyControllerClient 字符串、ControllerServer 字符串
  • 置信度:高
  • 待确认点:删除配置内固有轨迹名与删除运行时上传轨迹时是否走同一条路径,当前未恢复

ListFlyShotTraj

  • C++ 公开签名:std::vector<std::string> ListFlyShotTraj();
  • Python 包装形态:c.ListFlyShotTraj() -> list[str]
  • 服务端归属:ControllerServer._ListFlyShotTraj
  • 协议 / 命令线索:命令名 ListFlyShotTraj 已坐实;客户端与服务端字符串都出现 GetNextListFlyShotTraj,说明底层列举很可能是迭代式获取,而不是一次性返回整个数组
  • 返回值与默认值:直接返回轨迹名称列表
  • 典型工作流位置:查看当前服务端已登记的飞拍轨迹
  • 证据来源:ControllerClient.hUseControllerClient.pyControllerServer_analysis.mdlibControllerClient.soControllerServer 字符串
  • 置信度:高
  • 待确认点:高层 JSON 是否真的直接返回数组,还是客户端内部循环拉取后再拼成数组,当前未完全恢复

ExecuteFlyShotTraj

  • C++ 公开签名:bool ExecuteFlyShotTraj(const std::string &name, const bool move_to_start = false, const std::string &method = "icsp", bool save_traj = false, bool use_cache = false);
  • Python 包装形态:c.ExecuteFlyShotTraj(name="002", move_to_start=True, method="icsp", save_traj=True, use_cache=False) -> bool
  • 服务端归属:ControllerServer._ExecuteFlyShotTraj
  • 协议 / 命令线索:命令名 ExecuteFlyShotTraj 已坐实;字符串中出现 move_to_startuse_cache;伪代码级逆向已恢复其主流程
  • 返回值与默认值:默认 move_to_start=falsemethod="icsp"save_traj=falseuse_cache=false
  • 典型工作流位置:对已存在的飞拍轨迹定义执行“生成 + 挂接 DO 时间轴 + 执行”
  • 证据来源:ControllerClient.hUseControllerClient.cppUseControllerClient.pyUseRealRobot.py、SDK 手册、ControllerServer_analysis.mdTrajectory_generation_algorithm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点JSON 包结构未恢复;use_cache 的缓存键是否只按 name,当前从伪代码判断是,但未见更底层证据

SaveTrajInfo

  • C++ 公开签名:bool SaveTrajInfo(const std::string &name, const std::string &method = "icsp");
  • Python 包装形态:未见运行样例,但包装库和服务端都有明确字符串;语义可由手册和分析文档确认
  • 服务端归属:ControllerServer._SaveTrajInfo
  • 协议 / 命令线索:命令名 SaveTrajInfo 已坐实;字符串中可见 SaveTrajInfo {} success/failed
  • 返回值与默认值:默认 method="icsp"self-adapt-icsp 在执行时保存分析文件会回落成 icsp 导出语义
  • 典型工作流位置:按给定 name + method 生成并导出轨迹分析文件,例如 JointTraj.txtCartDetialTraj.txt
  • 证据来源:ControllerClient.hControllerServer_analysis.mdTrajectory_generation_algorithm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点Python 包装是否直接暴露该方法并返回 bool,虽然字符串存在,但公开示例未调用

IsFlyShotTrajValid

  • C++ 公开签名:bool IsFlyShotTrajValid(double &time, const std::string &name, const std::string &method = "icsp", bool save_traj = false);
  • Python 包装形态:valid, time_sec = c.IsFlyShotTrajValid("EOL9_EAU_90", "icsp", save_traj=True)
  • 服务端归属:ControllerServer._IsFlyShotTrajValid
  • 协议 / 命令线索:命令名 IsFlyShotTrajValid 已坐实;作用是“生成 + 合法性检查 + 返回轨迹总时长”
  • 返回值与默认值:默认 method="icsp"save_traj=falseC++ 为 bool + out doublePython 为 (bool, float)
  • 典型工作流位置:在执行飞拍轨迹前预校验;也可与 save_traj=True 结合导出分析文件
  • 证据来源:ControllerClient.hUseControllerClient.py 中的注释样例、ControllerServer_analysis.mdTrajectory_generation_algorithm_analysis.md、二进制字符串
  • 置信度:高
  • 待确认点:method="self-adapt-icsp" 是否被该接口完整支持,分析文档显示公开手册更强调 icsp / doubles,而示例注释里又出现 self-adapt-icsp,这里仍需后续抓包或真环境验证

8. 四条旧 SDK 工作流

8.1 初始化工作流

ControllerClient()
  -> ConnectServer("127.0.0.1", 50001)
  -> SetUpRobot("FANUC_LR_Mate_200iD") 或 SetUpRobotFromEnv(...)
  -> IsSetUp()
  -> GetName()
  -> GetDoF()
  -> SetShowTCP(...)

说明:

  • 这是最常见的仿真或真机前置流程。
  • SetUpRobot 是旧说明里明确要求首先执行的服务端初始化动作。

8.2 控制器状态工作流

SetActiveController(sim=True/False)
  -> Connect(robot_ip)
  -> EnableRobot(buffer_size=2)
  -> GetSpeedRatio() / SetSpeedRatio(...)
  -> GetTCP() / SetTCP(...)
  -> GetIO() / SetIO(...)
  -> StopMove()
  -> DisableRobot()
  -> Disconnect()

说明:

  • 真机样例会使用 sim=False
  • StopMove() 之后Python 示例里会再次 EnableRobot(),说明停止运动后常伴随重新使能。

8.3 普通轨迹工作流

GetJointPosition()
  -> GetPose()
  -> GetNearestIK(pose, seed)
  -> MoveJoint(home_joint)
  -> ExecuteTrajectory(waypoints, method="icsp", save_traj=True)

说明:

  • 输入是关节空间稀疏 waypoint。
  • ExecuteTrajectory 至少支持 icspdoubles

8.4 飞拍轨迹工作流

方案 A轨迹名已在配置中存在

name
  -> IsFlyShotTrajValid(name, "icsp", save_traj=True)
  -> ExecuteFlyShotTraj(name, move_to_start=True, method="icsp", save_traj=True, use_cache=False)
  -> SaveTrajInfo(name, "icsp")

方案 B客户端动态上传飞拍轨迹

UploadFlyShotTraj(name, waypoints, shot_flags, offset_values, addrs)
  -> ListFlyShotTraj()
  -> IsFlyShotTrajValid(name, "icsp", save_traj=True)
  -> ExecuteFlyShotTraj(name, move_to_start=True, method="self-adapt-icsp", save_traj=True, use_cache=True)
  -> DeleteFlyShotTraj(name)

说明:

  • UploadFlyShotTraj 只负责登记轨迹定义。
  • IsFlyShotTrajValid 负责“生成 + 合法性检查”。
  • ExecuteFlyShotTraj 负责“生成 + 挂接 TrajectoryDO + 执行”。
  • SaveTrajInfo 负责导出分析文件。

9. 已知高置信协议线索

当前能直接用于后续实现的高置信协议结论如下:

  • 传输层为 TCP + JSON 风格协议,不是 HTTP/gRPC。
  • JSON 层至少存在 method 字段,服务端存在 _ClientCB_IsJsonValid
  • 命令通道字段已确认:
    • GetSpeedRatioMsgID = 0x2206
    • SetSpeedRatioMsgID = 0x2207
    • GetIOMsgID = 0x2208
    • SetIOMsgID = 0x2209
  • 飞拍轨迹相关额外字符串线索:
    • StartUploadFlyShotTraj
    • EndUploadFlyShotTraj
    • GetNextListFlyShotTraj
    • move_to_start
    • use_cache
    • shot_flags
    • offset_values
    • addr / addrs

10. 待确认问题

以下问题本轮故意保留,不冒充已确认结论:

  1. 50001/TCP+JSON 请求 JSON 的精确 envelope 结构、字段必填规则、响应包统一格式。
  2. GetServerVersion 在高层 JSON 中的完整请求 / 响应字段。
  3. GetClientVersion 的实际版本字符串来源,以及 Python 包装失败路径。
  4. ListFlyShotTraj 是高层一次性返回数组,还是客户端内部循环 GetNextListFlyShotTraj 后再拼装列表。
  5. UploadFlyShotTraj 是否采用开始 / 数据 / 结束的多阶段上传协议。
  6. IsFlyShotTrajValidself-adapt-icsp 的真实支持边界。
  7. SetTCP / GetTCP 在高层 JSON 中是否暴露 tcp_id 概念。
  8. SetActiveController 切换控制器时是否会隐式触发 _DisconnectAll

11. 后续实现使用方式

等继续扩展 Flyshot.ControllerClientCompat 时,建议按以下顺序使用本文档:

  1. 先把 32 个 API 按本文档拆成命令表。
  2. 先实现高置信、状态简单的接口:
    • GetServerVersion
    • SetUpRobot
    • IsSetUp
    • GetName
    • GetDoF
    • GetSpeedRatio
    • SetSpeedRatio
    • GetIO
    • SetIO
  3. 再实现返回复杂结构的接口:
    • GetTCP
    • GetJointPosition
    • GetPose
    • GetNearestIK
  4. 最后实现飞拍轨迹相关接口,并把本文档中的“待确认问题”逐项收敛成兼容测试。