Skip to main content

S1 末端工具原始透传

S1 末端工具原始透传 API 用于在 SDK 应用与左臂或右臂 TIB 之间传输不透明的 64 字节帧。

SDK 核心层只负责以下工作:

  • 选择左侧或右侧 TIB;
  • 通过 DDS 发布 64 字节原始命令;
  • 订阅左右两侧的 1 kHz、250 Hz 原始接收流;
  • 将原始数据分发给已注册的用户回调;
  • 管理回调注册和注销。

SDK 核心层不解析具体设备协议。CAN ID、RS485 报文、寄存器、夹爪位置和力传感器数值等逻辑位于示例或用户自己的设备适配层。

部署前提

启动应用前需要完成以下操作:

  1. 部署支持 S1 末端原始透传的 WBCS 版本。

  2. 在当前 S1 使用的 robot_config.toml 中设置以下配置并重启 WBCS:

    [robot_info.custom_params]
    endtool_raw_enabled = true
  3. 将 CAN 或 RS485 设备连接并配置到预期的 TIB。

  4. 停止或通过业务逻辑排除所有会写入同一末端的生产控制器。

警告

SDK 返回发送成功只表示 DDS 消息已在本地成功发布,不代表 WBCS 已完成转发,也不代表 TIB 或末端设备已经接收并执行命令。

数据链路

发送链路:

应用层设备编码器
-> 64 字节 frame
-> send_endtool_raw_frame(side, frame)
-> EndToolRawCommand
-> WBCS Raw relay
-> EtherCAT -> TIB -> CAN/RS485 -> 末端设备

接收链路:

末端设备应答/主动上报
-> CAN/RS485 -> TIB -> EtherCAT
-> WBCS 1 kHz 或 250 Hz 接收缓冲区
-> singorix_proto::EndToolRawData
-> SDK 内部传输回调
-> EndToolRawData
-> 应用回调及设备协议解析器

GBS 1.18.1 使用两个公共 DDS topic:

singorix/wbcs/endtool/raw_command
singorix/wbcs/endtool/raw_data

SDK 发送时将左右侧映射为逻辑 endpoint_id,并固定使用 channel_id=command;接收时再将 endpoint_id/channel_id 映射回公开 API 的 side/kind

传输契约

字段含义
frameS1 WBCS/TIB 布局下严格为 64 字节的不透明数据
sideSDK 将 LEFT/RIGHT 映射为 left_endtool/right_endtool
kindSDK 将 BUFFER_1KHZ/BUFFER_250HZ 映射为 feedback_1khz/feedback_250hz
generation底层 sequence,在一个 endpoint/channel 流和一次发布进程生命周期内单调递增;WBCS 重启后可以复位

SDK 会订阅 side 和 kind 的四种组合。每个已注册回调都会收到全部四路数据,因此应用必须先过滤 sidekind,再解析设备 payload。

具体使用哪一路接收流由设备决定。例如,自研 CAN 夹爪使用 250 Hz buffer,坤维 RS485 传感器使用 1 kHz buffer。

API 使用流程

C++ 和 Python API 的生命周期一致:

robot.init() 会自动初始化 S1 原始透传节点、一个公共接收 reader 和一个公共发送 writer;任一资源创建失败时,S1 机器人初始化会返回 false。SDK 在公共 topic 内根据 endpoint/channel 分流,公开的 side/kind API 不变。

  1. 获取 S1 机器人实例并调用 init()
  2. 注册原始接收回调。
  3. 将设备命令编码为严格的 64 字节帧。
  4. 将帧发送到选定的机械臂/TIB。
  5. 在回调中先过滤 side/kind,再完整校验设备帧;只有有效帧才能更新业务状态。
  6. 销毁 SDK 实例前注销回调。

C++ 最小结构:

auto& robot = GalbotRobot::get_instance(MachineType::S1);
if (!robot.init()) {
return 1;
}

const auto handle = robot.register_endtool_raw_callback(
[](const EndToolRawData& data) {
if (data.side != EndToolSide::LEFT ||
data.kind != EndToolRxKind::BUFFER_250HZ) {
return;
}
// 根据已安装设备的协议校验并解析 data.frame。
});

std::array<uint8_t, END_TOOL_RAW_FRAME_SIZE> frame{};
// 将设备特定的 CAN/RS485 命令编码到 frame。
const auto status = robot.send_endtool_raw_frame(EndToolSide::LEFT, frame);

robot.unregister_endtool_raw_callback(handle);
robot.destroy();

回调与资源安全

  • 接收回调运行在中间件线程;应用仍应按并发回调场景保护共享状态。
  • 回调应尽量简短,并使用 mutex 或 atomic 保护共享状态。
  • 需要在回调结束后继续使用的数据必须复制,不要保留 EndToolRawData 的引用。
  • unregister_endtool_raw_callback() 返回时,已经开始执行的某次回调仍可能继续完成,因此回调捕获的共享状态必须具备安全生命周期。
  • 同一个 SDK 实例内的 Raw 发送已经串行化,但不存在跨进程或跨客户端的资源租约。
  • Raw writer 仍可能与标准夹爪控制器或另一个进程对同一 TIB 的写入发生竞争。

设备适配器职责

生产级适配器不能只检查帧头。应根据设备协议检查:

  • 帧类型、CAN/设备 ID 和 payload 长度;
  • 命令码、功能码和 response 标志;
  • 校验和或帧尾;
  • 数值有限性和物理量程;
  • generation 单调性和响应超时;
  • generation 持续增长时 payload 是否长期冻结;
  • 发送前的命令参数范围。

坏帧必须直接拒绝,不能覆盖业务层保存的最后一份有效状态。

SDK 示例

SDK 为三种设备提供了完整的 C++ 和 Python 示例:

设备总线接收流行为
自研二指夹爪CAN250 Hz初始化/运动命令及被动状态上报
大寰二指夹爪CAN/Modbus 变体依设备响应参数配置、运动和主动状态轮询
坤维六维力传感器RS4851 kHz每 10 ms 主动查询并解析力/力矩

完整可运行源码请参阅 C++ 示例Python 示例

故障排查

现象检查项
Publish 成功但末端无动作确认 [robot_info.custom_params].endtool_raw_enabled=true 并重启 WBCS,然后检查末端选择、设备供电和接线
没有接收回调确认预期的 side/kind、WBCS Raw RX 日志、设备波特率和应答模式
大量帧被拒绝检查 CAN/设备 ID、response 标志、帧尾/校验和及字节偏移
generation 出现跳变接收端或中间件可能过载,应减少回调中的工作量和日志量
generation 增长但 payload 长期不变检查传感器或设备接收链路是否冻结
命令行为偶发异常确认标准控制器或第二个客户端没有同时写入同一 TIB