用Socket套接字通过TCP/IP以太网实现虚拟机Ubuntu中ROS与Windows10中ABB Robot Studio的协同工作
序言
继前文中分享的ABB Robot Studio与ROS建立以太网连接之后,现在可以通过Socket套接字的方式来传递信息了。
本文着重分享ABB Rapid语言和Python语言如何打包、解包及收发Socket套接字。
关于Socket套接字
- Socket套接字简单来说就是把包括浮点数、整数、字符串等在内的不同长度数据类型的变量或常数首尾相连完成合并,变成一串二进制数。
- Python中通过一句“import socket”,即可导入socket指令包。
- ABB Robot Studio采用ABB公司自己的Rapid语言编程,而Rapid语言刚好就带有Socket套接字的操作函数,直接使用即可。
- 前文中,在配置了ROS-Industrial ABB Driver驱动包的ABB Robot Studio工程里,ROS_socket、ROS_motionServer、ROS_messages等等多个文件中都有Socket套接字操作相关的代码(我也是从这里边看边百度自学的)。
- ROS在C++,Python等多个语言平台都有相应的程序接口,这里我只分享如何用Python编写一段Socket套接字的操作代码,如果需要使用ROS的功能,在今后只需要在此基础上增加ROS功能代码即可。
Rapid语言的Socket套接字操作
先上程序(ABB 官方例程 ROS_messages.sys,上一篇文章中配置支持ROS的ABB RoboStudio工程时提到过)
MODULE ROS_messages(SYSMODULE)
RECORD ROS_msg_header
num msg_type;
num comm_type;
num reply_code;
ENDRECORD
RECORD ROS_msg
ROS_msg_header header;
rawbytes data;
ENDRECORD
RECORD ROS_msg_joint_traj_pt
ROS_msg_header header;
num sequence_id;
robjoint joints; ! in DEGREES
num velocity;
num duration;
ENDRECORD
RECORD ROS_msg_joint_data
ROS_msg_header header;
num sequence_id;
robjoint joints; ! in DEGREES
ENDRECORD
! Message Type Codes (from simple_message/simple_message.h)
CONST num ROS_MSG_TYPE_INVALID := 0;
CONST num ROS_MSG_TYPE_JOINT := 10; ! joint-position feedback
CONST num ROS_MSG_TYPE_JOINT_TRAJ_PT := 11; ! joint-trajectory-point (for path downloading)
CONST num ROS_COM_TYPE_TOPIC := 1;
CONST num ROS_COM_TYPE_SRV_REQ := 2;
CONST num ROS_COM_TYPE_SRV_REPLY := 3;
CONST num ROS_REPLY_TYPE_INVALID := 0;
CONST num ROS_REPLY_TYPE_SUCCESS := 1;
CONST num ROS_REPLY_TYPE_FAILURE := 2;
! "Special" Sequence Codes (from simple_message/joint_traj_pt.h)
CONST num ROS_TRAJECTORY_START_DOWNLOAD := -1;
CONST num ROS_TRAJECTORY_END := -3;
CONST num ROS_TRAJECTORY_STOP := -4;
! Other message constants
CONST num ROS_MSG_MAX_JOINTS := 10; ! from joint_data.h
PROC ROS_send_msg_joint_data(VAR socketdev client_socket, ROS_msg_joint_data message)
VAR ROS_msg raw_message;
VAR robjoint ROS_joints;
VAR num i;
! Force message header to the correct values
raw_message.header.msg_type := ROS_MSG_TYPE_JOINT;
raw_message.header.comm_type := ROS_COM_TYPE_TOPIC;
raw_message.header.reply_code := ROS_REPLY_TYPE_INVALID;
! Convert data from ABB units to ROS units
ROS_joints := deg2rad_robjoint(message.joints);
! Pack data into message
PackRawBytes message.sequence_id, raw_message.data, 1, \IntX:=DINT;
PackRawBytes ROS_joints.rax_1, raw_message.data, 5, \Float4;
PackRawBytes ROS_joints.rax_2, raw_message.data, 9, \Float4;
PackRawBytes ROS_joints.rax_3, raw_message.data, 13, \Float4;
PackRawBytes ROS_joints.rax_4, raw_message.data, 17, \Float4;
PackRawBytes ROS_joints.rax_5, raw_message.data, 21, \Float4;
PackRawBytes ROS_joints.rax_6, raw_message.data, 25, \Float4;
FOR i FROM 1 TO ROS_MSG_MAX_JOINTS-6 DO ! Insert placeholders for joints 7-10 (message expects 10 joints)
PackRawBytes 0, raw_message.data, 25+i*4, \Float4;
ENDFOR
ROS_send_msg client_socket, raw_message;
ERROR
RAISE; ! raise errors to calling code
ENDPROC
ENDMODULE
Rapid中Socket 套接字的打包
! Pack data into message
PackRawBytes message.sequence_id, raw_message.data, 1, \IntX:=DINT;
PackRawBytes ROS_joints.rax_1, raw_message.data, 5, \Float4;
PackRawBytes ROS_joints.rax_2, raw_message.data, 9, \Float4;
PackRawBytes ROS_joints.rax_3, raw_message.data, 13, \Float4;
PackRawBytes ROS_joints.rax_4, raw_message.data, 17, \Float4;
PackRawBytes ROS_joints.rax_5, raw_message.data, 21, \Float4;
PackRawBytes ROS_joints.rax_6, raw_message.data, 25, \Float4;
FOR i FROM 1 TO ROS_MSG_MAX_JOINTS-6 DO ! Insert placeholders for joints 7-10 (message expects 10 joints)
PackRawBytes 0, raw_message.data, 25+i*4, \Float4;
ENDFOR
PackRawBytes是Socket套接字打包的一个关键,它的作用简单来讲就是把我们需要打包的数据转为2进制数,直接拼接起来。
message.sequence_id、ROS_joints.rax_1、ROS_joints.rax_2……这些就是我们需要打包的变量名。
\IntX:=DINT、\Float4定义的是变量的数据类型,它定义了变量转为二进制数后的的长度,常用的还有\String等数据类型,需要注意的是\IntX:=DINT、\Float4长度都是4,而\String长度则由变量包含的字符个数决定,一个字符占用的长度是1。(数据长度单位都是byte,即8位二进制数)
1、5、9、13、17……这些数字指定了我们的参数转为二进制后,在Socket套接字中的起始位置,它是解码时的重要参考,需要注意起始位置必须考虑到为前一个参数留足够的数据长度,否则前一个参数的部分数据将被覆盖导致接收方解码失败。这里由于 \IntX:=DINT


9253

被折叠的 条评论
为什么被折叠?



