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]