RTDE协议说明

简介

RTDE(Real-Time Data Exchange)协议是机器人控制器与外部设备进行实时数据交换的协议。通过 RTDE 协议,外部设备可以获取机器人的状态信息,例如关节角大小、末端工具的位置姿态、运动的速度和加速度等。此外,外部设备还可以通过 RTDE 协议向机器人发送控制命令,例如通过写入寄存器来使机器人运动到指定的位置。

RTDE 协议具有以下特性:

  • 实时性:机器人控制器与外部设备通过RTDE协议进行数据交换的时候,数据传输快,不会破坏机器人控制器的实时性。
  • 双向通信:RTDE 协议支持机器人控制器与外部设备进行双向数据交换,即外部设备既可以接收机器人数据,也可以发送指令。
  • 跨语言和跨平台:RTDE 协议支持多种编程语言(如 C++、Python 等)和不同平台之间的通信。
  • 支持多种传输协议:RTDE 协议可以使用多种传输协议进行数据传输,如 TCP Socket、WebSocket等,适用于多种网络环境。

支持的传输协议与端口号

AUBO SDK 中的 RTDE功能模块支持 TCP Socket 和 WebSocket 传输协议,其对应的端口号如下:

协议 端口号
TCP Socket 30010
WebSocket 9013

RTDE 协议规范

RTDE 菜单

RTDE菜单是一个定义了 RTDE 数据同步包的内容和格式的菜单,它是一个规范。它描述了可同步的输入和输出字段以及它们的数据类型。RTDE 菜单包括了输入菜单和输出菜单,输入菜单为客户端向服务端推送数据的菜单,输出菜单为服务端向客户端推送数据的菜单。如想知道 RTDE 菜单中的话题和数据类型列表,可查看 RTDE 菜单

请求-响应

客户端可以向服务器订阅话题、发布话题和取消话题。

订阅话题

当客户端订阅话题的时候,客户端会向服务器发送的一个数据包。数据包的第1个元素为索引值,固定为100,第二个元素为对象,包含了以下成员:chanel、frequency、segments、to_server和trigger。其中,to_server的值固定为false,segments为RTDE 菜单中的输出菜单的成员。这些成员的定义可参考 RtdeRecipe 结构体,RtdeRecipe的结构体如下:

struct RtdeRecipe
{
    bool to_server;                    ///< 输入/输出,to_server=false表示订阅来自服务器的数据,to_server=true表示向服务器推送数据
    int chanel;                        ///< 通道  通道数仅支持 0-99
    double frequency;                  ///< 更新频率
    int trigger;                       ///< 触发方式(该功能暂未实现): 0 - 周期; 1 - 变化
    std::vector<std::string> segments; ///< 字段列表,表示订阅/发布的话题
};

之后,客户端会接收到服务器响应的数据包。数据包的第一个元素是通道,值和订阅的通道相同。第二个以及往后的元素是订阅话题的数据。

例如,想在0号通道订阅话题 "R1_actual_q",那么客户端向服务器发送的数据包为:

[100,{"chanel":0,"frequency":50.0,"segments":["R1_actual_q"],"to_server":false,"trigger":0}]

客户端接收到的服务器响应如下:

[0,[-0.027531569059195515,-0.28143723119618147,1.6961810563264004,0.4177235477634482,1.5627876064666573,-0.03521353669519756]]

上面示例中,数据包中的第一个元素表示0号通道,第二个元素是订阅话题 "R1_actual_q"的值,即实际六个关节角大小。

取消话题

订阅话题之后,客户端会不断地接收到从服务器发送的数据。如果想取消掉推送,则可以取消话题。取消话题与订阅话题发送的数据包格式相同,但要frequency设置为0,chanel设置为要取消的话题通道,segments设置为空。

例如,想取消0号通道的话题

[100,{"chanel":0,"frequency":0.0,"segments":[],"to_server":false,"trigger":0}]

发布话题

当客户端发布话题的时候,客户端会向服务器发送的一个数据包。数据包的第1个元素为索引值,固定为100,第二个元素为对象,包含了以下成员:chanel、frequency、segments、to_server和trigger。其中,to_server的值固定为true,segments为RTDE 菜单中的输入菜单的成员。这些成员的定义可参考 RtdeRecipe 结构体,RtdeRecipe的结构体如下:

struct RtdeRecipe
{
    bool to_server;                    ///< 输入/输出,to_server=false表示订阅来自服务器的数据,to_server=true表示向服务器推送数据
    int chanel;                        ///< 通道  通道数仅支持 0-99
    double frequency;                  ///< 更新频率
    int trigger;                       ///< 触发方式(该功能暂未实现): 0 - 周期; 1 - 变化
    std::vector<std::string> segments; ///< 字段列表,表示订阅/发布的话题
};

然后,客户端再向服务器推送数据,数据包的第一个元素是通道,值和发布话题的通道相同。第二个以及往后的元素是发布话题的数据。

例如,想在1号通道发布话题 "input_float_registers_0"和"input_double_registers_1",那么客户端向服务器发送的数据包为:

[100,{"chanel":1,"frequency":1.0,"segments":["input_float_registers_0","input_double_registers_1"],"to_server":true,"trigger":0}]

然后,再从客户端向服务器推送数据:

[1,3.1,4.1]

上面示例中,数据包中的第一个元素表示1号通道,第二个和第三个元素分别表示 "input_float_registers_0" 和 " input_double_registers_1"的值。

如想判断数据是否被成功推送,可订阅话题"input_float_registers_r0" 和 " input_double_registers_r1":

[100,{"chanel":1,"frequency":1.0,"segments":["input_float_registers_r0","input_double_registers_r1"],"to_server":false,"trigger":0}]

如果数据被成功推送,那么客户端接收到的服务器响应为:

[1,3.0999999046325684,4.1]

示例

用python编写的websocket协议传输示例如下:

localhost 是 机器人IP地址

import asyncio
import websockets


async def rtde_communication():
    uri = "ws://localhost:9013"
    async with websockets.connect(uri) as websocket:
        # 发布话题
        publish_topic = '[100,{"chanel":1,"frequency":1.0,"segments":["input_float_registers_0",' \
                        '"input_double_registers_1"],"to_server":true,"trigger":0}] '
        await websocket.send(publish_topic)

        # 向服务器推送数据
        publish_data = '[1,3.3,4.4]'
        await websocket.send(publish_data)

        # 订阅话题
        subscribe_topic = '[100,{"chanel":1,"frequency":50.0,"segments":["input_float_registers_r0",' \
                          '"input_double_registers_r1"],"to_server":false,"trigger":0}] '
        await websocket.send(subscribe_topic)

        # 接收 RTDE 数据包
        while True:
            data_packet = await websocket.recv()
            print("Received data packet:", data_packet)


asyncio.get_event_loop().run_until_complete(rtde_communication())

程序运行结果:

Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]
Received data packet: [1,3.299999952316284,4.4]

results matching ""

    No results matching ""