用Socket套接字通过TCP/IP以太网实现虚拟机Ubuntu中ROS与Windows10中ABB Robot Studio的协同工作

上一篇:建立虚拟机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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值