# 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 属于客户端侧行为:`ConnectServer`、`GetClientVersion` 本文档中的“协议 / 命令线索”有两个层次: - 命令名:已从头文件、字符串或逆向文档坐实,例如 `SetUpRobot`、`GetIO` - 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.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`UseRealRobot.py` - 置信度:高 - 待确认点:重连、超时、握手细节未恢复 ### `GetServerVersion` - C++ 公开签名:`bool GetServerVersion(std::string &version);` - Python 包装形态:样例中表现为 `controller.GetServerVersion() -> str` - 服务端归属:协议分发层行为;当前未恢复到显式 `_GetServerVersion` - 协议 / 命令线索:命令名字符串 `GetServerVersion` 已坐实;服务端存在 `GetServerVersion success: {}.` 日志;精确 JSON envelope 未恢复 - 返回值与默认值:C++ 为 `bool + out string`;Python 样例把结果当作直接字符串使用 - 典型工作流位置:`ConnectServer` 之后、机器人初始化前后均可读取的元信息接口 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`libControllerClient.so`、`ControllerServer.cpython-37m-x86_64-linux-gnu.so` - 置信度:高 - 待确认点:Python 失败路径的返回形态未看到样例;请求 JSON 的精确字段未恢复 ### `GetClientVersion` - C++ 公开签名:`bool GetClientVersion(std::string &version);` - Python 包装形态:未见公开样例;从包装库字符串看接口存在 - 服务端归属:客户端本地行为,不进入服务端命令表 - 协议 / 命令线索:`libControllerClient.so` 与 `PyControllerClient` 都有 `GetClientVersion` 符号;未见 `ControllerServer` 对应 `_Xxx` - 返回值与默认值:C++ 为 `bool + out string`;Python 侧返回形态待确认 - 典型工作流位置:客户端自检或 SDK 版本上报,不依赖服务端状态 - 证据来源:`ControllerClient.h`、`libControllerClient.so`、`PyControllerClient.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.h`、`UseControllerClient.cpp`、`UseControllerClient.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.h`、`ControllerServer_analysis.md`、`ControllerServer` 字符串、`libControllerClient.so` - 置信度:高 - 待确认点:环境文件路径是否必须为绝对路径由注释可见,但服务端是否做额外归一化未恢复 ### `IsSetUp` - C++ 公开签名:`bool IsSetUp();` - Python 包装形态:`c.IsSetUp() -> bool` - 服务端归属:`ControllerServer._IsSetUp` - 协议 / 命令线索:命令名 `IsSetUp` 已坐实;精确 JSON envelope 未恢复 - 返回值与默认值:直接返回布尔值 - 典型工作流位置:`SetUpRobot` 或 `SetUpRobotFromEnv` 之后的状态确认 - 证据来源:`ControllerClient.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`ControllerServer_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=true`、`axis_length=0.1`、`axis_size=2` - 典型工作流位置:初始化完成后、切换控制器前的仿真显示配置 - 证据来源:`ControllerClient.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`ControllerServer_analysis.md`、`ControllerServer` 字符串 - 置信度:高 - 待确认点:仅仿真控制器生效还是真实控制器也接受该命令,当前未见明确负例 ### `GetName` - C++ 公开签名:`std::string GetName();` - Python 包装形态:`c.GetName() -> str` - 服务端归属:`ControllerServer._GetName` - 协议 / 命令线索:命令名 `GetName` 已坐实;精确 JSON envelope 未恢复 - 返回值与默认值:直接返回机器人名称字符串 - 典型工作流位置:完成机器人初始化后读取名称确认 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:失败时是返回空串还是异常/默认值,Python 样例未覆盖 ### `GetDoF` - C++ 公开签名:`int GetDoF();` - Python 包装形态:`c.GetDoF() -> int` - 服务端归属:`ControllerServer._GetDoF` - 协议 / 命令线索:命令名 `GetDoF` 已坐实;精确 JSON envelope 未恢复 - 返回值与默认值:直接返回自由度整数 - 典型工作流位置:完成机器人初始化后读取自由度 - 证据来源:`ControllerClient.h`、`UseControllerClient.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.h`、`UseControllerClient.py`、`UseRealRobot.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.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`UseRealRobot.py`、SDK 手册、`ControllerServer_analysis.md`、`FANUC_realtime_comm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:JSON 键名是否为 `ip` 或 `robot_ip` 未恢复;仿真模式下是否接受同一命令仍需实现侧验证 ### `Disconnect` - C++ 公开签名:`bool Disconnect();` - Python 包装形态:`c.Disconnect() -> bool` - 服务端归属:`ControllerServer._Disconnect` - 协议 / 命令线索:命令名 `Disconnect` 已坐实;字符串中可见 `Disconnect success/failed` - 返回值与默认值:直接返回布尔值 - 典型工作流位置:真实控制器断开或工作流结束时调用 - 证据来源:`ControllerClient.h`、`ControllerServer_analysis.md`、`ControllerServer` 字符串、`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.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`UseRealRobot.py`、`ControllerServer_analysis.md`、`FANUC_realtime_comm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:`buffer_size` 在旧服务端具体如何映射到伺服缓冲区参数,当前未完全恢复 ### `DisableRobot` - C++ 公开签名:`bool DisableRobot();` - Python 包装形态:`c.DisableRobot() -> bool` - 服务端归属:`ControllerServer._DisableRobot` - 协议 / 命令线索:命令名 `DisableRobot` 已坐实;字符串中可见 `DisableRobot success/failed` - 返回值与默认值:直接返回布尔值 - 典型工作流位置:停机或退出前关闭机器人使能 - 证据来源:`ControllerClient.h`、`ControllerServer_analysis.md`、`FANUC_realtime_comm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:与 `StopMove` 的先后顺序约束未恢复 ### `StopMove` - C++ 公开签名:`bool StopMove();` - Python 包装形态:`c.StopMove() -> bool` - 服务端归属:`ControllerServer._StopMove` - 协议 / 命令线索:命令名 `StopMove` 已坐实;字符串中可见 `StopMove success/failed` - 返回值与默认值:直接返回布尔值 - 典型工作流位置:当前运动中止;Python 示例中调用后会再次 `EnableRobot()` - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、`ControllerServer_analysis.md`、`FANUC_realtime_comm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:是否会清空控制器执行队列、是否必须重新使能,当前只从示例看到倾向性而非硬约束 ## 5. 参数与 IO ### `GetSpeedRatio` - C++ 公开签名:`double GetSpeedRatio();` - Python 包装形态:`c.GetSpeedRatio() -> float` - 服务端归属:`ControllerServer._GetSpeedRatio` - 协议 / 命令线索:命令通道 `MsgID = 0x2206`;响应字段为 `ratio_int` 与 `result_code`;成功后客户端将 `ratio_int / 100.0` - 返回值与默认值:直接返回 `0~1` 之间的倍率 - 典型工作流位置:连机并使能后读取当前速度倍率 - 证据来源:`ControllerClient.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`CommonMsg_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.h`、`UseControllerClient.py`、`UseRealRobot.py`、SDK 手册、`ControllerServer_analysis.md`、`CommonMsg_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 Pose`;Python 为 `(bool, Pose)` - 典型工作流位置:连机后读取当前控制器 TCP - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、`ControllerServer_analysis.md`、`CommonMsg_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.h`、`UseControllerClient.py`、`ControllerServer_analysis.md`、`CommonMsg_protocol_analysis.md`、`FANUC_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_type`、`io_index`;响应字段是 `result_code`、`io_value` - 返回值与默认值:默认 `type = kIOTypeDI`;C++ 为 `bool + out bool`;Python 为 `(bool, bool)` - 典型工作流位置:连机后读取 DI/DO/RI/RO 等 IO 值 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`CommonMsg_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_type`、`io_index`、`io_value` - 返回值与默认值:默认 `type = kIOTypeDO` - 典型工作流位置:连机后设置数字输出;飞拍链路之外的普通 IO 调试也会用到 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`CommonMsg_protocol_analysis.md`、`FANUC_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 JointPositions`;Python 为 `(bool, JointPositions)` - 典型工作流位置:读取当前关节角,常作为 `GetNearestIK` 的 seed 或 `MoveJoint` 的基准 - 证据来源:`ControllerClient.h`、`UseControllerClient.cpp`、`UseControllerClient.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 Pose`;Python 为 `(bool, Pose)` - 典型工作流位置:读取当前 TCP 位姿,常与 `GetNearestIK` 配套使用 - 证据来源:`ControllerClient.h`、`UseControllerClient.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 JointPositions`;Python 为 `(bool, JointPositions)` - 典型工作流位置:先 `GetPose` 得到当前位姿,再构造目标位姿,并使用当前关节或邻近关节作为 seed 求最近 IK - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、`ControllerServer_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.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`ControllerServer_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:移动速度/平滑参数是否固定在服务端内部,公开 API 未暴露 ### `ExecuteTrajectory` - C++ 公开签名:`bool ExecuteTrajectory(const std::vector &waypoints, const std::string &method = "icsp", bool save_traj = false);` - Python 包装形态:`c.ExecuteTrajectory(waypoints=[...], method="icsp", save_traj=True) -> bool` - 服务端归属:`ControllerServer._ExecuteTrajectory` - 协议 / 命令线索:命令名 `ExecuteTrajectory` 已坐实;`method` 至少支持 `icsp` 与 `doubles` - 返回值与默认值:默认 `method="icsp"`、`save_traj=false` - 典型工作流位置:普通多点轨迹执行,不带飞拍 IO;输入是关节空间稀疏 waypoint,而不是笛卡尔点 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`Trajectory_generation_algorithm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:JSON 中 waypoint 列表的键名和序列化结构未恢复;`doubles` 的失败语义未在公开样例中体现 ## 7. 飞拍轨迹 ### `UploadFlyShotTraj` - C++ 公开签名:`bool UploadFlyShotTraj(const std::string &name, const std::vector &waypoints, const std::vector &shot_flags, const std::vector &offset_values, const std::vector> &addrs);` - Python 包装形态:`c.UploadFlyShotTraj(name="test_traj", waypoints=..., shot_flags=..., offset_values=..., addrs=...) -> bool` - 服务端归属:`ControllerServer._UploadFlyShotTraj` - 协议 / 命令线索:命令名 `UploadFlyShotTraj` 已坐实;客户端字符串中可见 `StartUploadFlyShotTraj` 与 `EndUploadFlyShotTraj`,说明上传阶段很可能分为开始 / 传输 / 结束三个子步骤 - 返回值与默认值:成功返回 `true`;无默认参数 - 典型工作流位置:运行时动态构造飞拍轨迹时,先把轨迹定义登记到服务端 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`Trajectory_generation_algorithm_analysis.md`、`libControllerClient.so`、`ControllerServer` 字符串 - 置信度:高 - 待确认点: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.h`、`UseControllerClient.py`、SDK 手册、`ControllerServer_analysis.md`、`PyControllerClient` 字符串、`ControllerServer` 字符串 - 置信度:高 - 待确认点:删除配置内固有轨迹名与删除运行时上传轨迹时是否走同一条路径,当前未恢复 ### `ListFlyShotTraj` - C++ 公开签名:`std::vector ListFlyShotTraj();` - Python 包装形态:`c.ListFlyShotTraj() -> list[str]` - 服务端归属:`ControllerServer._ListFlyShotTraj` - 协议 / 命令线索:命令名 `ListFlyShotTraj` 已坐实;客户端与服务端字符串都出现 `GetNextListFlyShotTraj`,说明底层列举很可能是迭代式获取,而不是一次性返回整个数组 - 返回值与默认值:直接返回轨迹名称列表 - 典型工作流位置:查看当前服务端已登记的飞拍轨迹 - 证据来源:`ControllerClient.h`、`UseControllerClient.py`、`ControllerServer_analysis.md`、`libControllerClient.so`、`ControllerServer` 字符串 - 置信度:高 - 待确认点:高层 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_start`、`use_cache`;伪代码级逆向已恢复其主流程 - 返回值与默认值:默认 `move_to_start=false`、`method="icsp"`、`save_traj=false`、`use_cache=false` - 典型工作流位置:对已存在的飞拍轨迹定义执行“生成 + 挂接 DO 时间轴 + 执行” - 证据来源:`ControllerClient.h`、`UseControllerClient.cpp`、`UseControllerClient.py`、`UseRealRobot.py`、SDK 手册、`ControllerServer_analysis.md`、`Trajectory_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.txt`、`CartDetialTraj.txt` - 证据来源:`ControllerClient.h`、`ControllerServer_analysis.md`、`Trajectory_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=false`;C++ 为 `bool + out double`;Python 为 `(bool, float)` - 典型工作流位置:在执行飞拍轨迹前预校验;也可与 `save_traj=True` 结合导出分析文件 - 证据来源:`ControllerClient.h`、`UseControllerClient.py` 中的注释样例、`ControllerServer_analysis.md`、`Trajectory_generation_algorithm_analysis.md`、二进制字符串 - 置信度:高 - 待确认点:`method="self-adapt-icsp"` 是否被该接口完整支持,分析文档显示公开手册更强调 `icsp` / `doubles`,而示例注释里又出现 `self-adapt-icsp`,这里仍需后续抓包或真环境验证 ## 8. 四条旧 SDK 工作流 ### 8.1 初始化工作流 ```text ControllerClient() -> ConnectServer("127.0.0.1", 50001) -> SetUpRobot("FANUC_LR_Mate_200iD") 或 SetUpRobotFromEnv(...) -> IsSetUp() -> GetName() -> GetDoF() -> SetShowTCP(...) ``` 说明: - 这是最常见的仿真或真机前置流程。 - `SetUpRobot` 是旧说明里明确要求首先执行的服务端初始化动作。 ### 8.2 控制器状态工作流 ```text 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 普通轨迹工作流 ```text GetJointPosition() -> GetPose() -> GetNearestIK(pose, seed) -> MoveJoint(home_joint) -> ExecuteTrajectory(waypoints, method="icsp", save_traj=True) ``` 说明: - 输入是关节空间稀疏 waypoint。 - `ExecuteTrajectory` 至少支持 `icsp` 与 `doubles`。 ### 8.4 飞拍轨迹工作流 #### 方案 A:轨迹名已在配置中存在 ```text 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:客户端动态上传飞拍轨迹 ```text 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`。 - 命令通道字段已确认: - `GetSpeedRatio`:`MsgID = 0x2206` - `SetSpeedRatio`:`MsgID = 0x2207` - `GetIO`:`MsgID = 0x2208` - `SetIO`:`MsgID = 0x2209` - 2026-04-28 `UTTC_MS11` 抓包中,`speed_ratio=0.7` 的效果能从 UDP 60015 主运行段时间尺度反推出来,但机器人侧 `TCP 10012` 未出现 `0x2207 SetSpeedRatio`;兼容实现不能只依赖一次 10012 命令来表达执行倍率,还要在 J519 发送时间轴上应用当前倍率。实发规则为 `t_traj = k * 0.008 * speed_ratio`,包数为 `floor(duration / (0.008 * speed_ratio)) + 1`。 - 飞拍轨迹相关额外字符串线索: - `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. `IsFlyShotTrajValid` 对 `self-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. 最后实现飞拍轨迹相关接口,并把本文档中的“待确认问题”逐项收敛成兼容测试。