ROS-Industrial 之 ABB_Driver ——ROS Server(2/3)

本文深入剖析ROS-Industrial ABB_Driver中的ROS Server,重点讲解ROS_socket.sys和ROS_stateServer.sys的功能。ROS_socket.sys涵盖了初始化、等待连接、接收和发送信息的流程,而ROS_stateServer.sys则负责周期性获取机器人状态并发送给ROS。通过理解这些核心组件,有助于掌握ROS与机器人控制器的交互控制机制。
摘要由CSDN通过智能技术生成

前面的ROS-Industrial 之 ABB_Driver——ROS Server (1/3)对ABB_Driver中的ROS Server部分中的ROS_common和ROS_messages两个功能文件进行了分析与学习,现在继续分析接下来的内容,最终的目的就是彻底搞清楚ROS Server里到底是如何实现ROS与机器人控制器的交互控制的,借鉴ABB的经验实现最终目的。

ROS_socket.sys

先把整个代码文件贴上来欣赏一下,不想看太长的话直接到后面按功能分段分析:

MODULE ROS_socket(SYSMODULE)

PROC ROS_init_socket(VAR socketdev server_socket, num port)
    IF (SocketGetStatus(server_socket) = SOCKET_CLOSED) SocketCreate server_socket;
    IF (SocketGetStatus(server_socket) = SOCKET_CREATED) SocketBind server_socket, GetSysInfo(\LanIp), port;
    IF (SocketGetStatus(server_socket) = SOCKET_BOUND) SocketListen server_socket;
ERROR
    RAISE;  ! raise errors to calling code
ENDPROC

PROC ROS_wait_for_client(VAR socketdev server_socket, VAR socketdev client_socket, \num wait_time)
    VAR string client_ip;
    VAR num time_val := WAIT_MAX;  ! default to wait-forever
    IF Present(wait_time) time_val := wait_time;
    IF (SocketGetStatus(client_socket) <> SOCKET_CLOSED) SocketClose client_socket;
    WaitUntil (SocketGetStatus(client_socket) = SOCKET_CLOSED);
    SocketAccept server_socket, client_socket, \ClientAddress:=client_ip, \Time:=time_val;
    TPWrite "Client at "+client_ip+" connected.";
ERROR
    RAISE;  ! raise errors to calling code
ENDPROC

PROC ROS_receive_msg(VAR socketdev client_socket, VAR ROS_msg message, \num wait_time)
    VAR rawbytes buffer;
    VAR num time_val := WAIT_MAX;  ! default to wait-forever
    VAR num bytes_rcvd;
    VAR num msg_length;
    ClearRawBytes buffer;
    IF Present(wait_time) time_val := wait_time;
    SocketReceive client_socket, \RawData:=buffer, \ReadNoOfBytes:=4, \Time:=time_val;
    UnpackRawBytes buffer, 1, msg_length, \IntX:=UDINT;
    SocketReceive client_socket, \RawData:=buffer, \ReadNoOfBytes:=msg_length, \NoRecBytes:=bytes_rcvd, \Time:=time_val;
    IF (bytes_rcvd <> msg_length) THEN
        ErrWrite \W, "ROS Socket Recv Failed", "Did not receive expected # of bytes.",
                 \RL2:="Expected: " + ValToStr(msg_length),
                 \RL3:="Received: " + ValToStr(bytes_rcvd);
        RETURN;
    ENDIF
    UnpackRawBytes buffer, 1, message.header.msg_type, \IntX:=DINT;
    UnpackRawBytes buffer, 5, message.header.comm_type, \IntX:=DINT;
    UnpackRawBytes buffer, 9, message.header.reply_code, \IntX:=DINT;
    CopyRawBytes   buffer, 13, message.data, 1;
ERROR
    RAISE;  ! raise errors to calling code
ENDPROC

PROC ROS_send_msg(VAR socketdev client_socket, VAR ROS_msg message)
    VAR rawbytes buffer;
    PackRawBytes 12 + RawBytesLen(message.data), buffer,  1, \IntX := UDINT; ! Packet length (excluding this prefix)
    PackRawBytes message.header.msg_type,        buffer,  5, \IntX := DINT;  ! Message type
    PackRawBytes message.header.comm_type,       buffer,  9, \IntX := DINT;  ! Comm type
    PackRawBytes message.header.reply_code,      buffer, 13, \IntX := DINT;  ! Reply code
    CopyRawBytes message.data, 1,                buffer, 17;                 ! Message data
    SocketSend client_socket \RawData:=buffer;
ERROR
    RAISE;  ! raise errors to calling code
ENDPROC

ENDMODULE

以上Socket通信的代码主要分为四大功能,初始化、等待连接、接收信息与发送信息,接下来我们按功能分段按行来分析其内容。
先来研究Socket的初始化代码:

PROC ROS_init_socket(VAR socketdev server_socket, num port)
    IF (SocketGetStatus(server_socket) = SOCKET_CLOSED) SocketCreate server_socket;
    IF (SocketGetStatus(server_socket) = SOCKET_CREATED) SocketBind server_socket, GetSysInfo(\LanIp), port;
    IF (SocketGetStatus(server_socket) = SOCKET_BOUND) SocketListen server_socket;
ERROR
    RAISE;  ! raise errors to calling code
ENDPROC

初始化代码完成对ROS Server服务器的初始化工作,在RAPID中直接定义了一个程序调用过程PROC进行初始化工作。

PROC ROS_init_socket(VAR socketdev server_socket, num port)
······
ENDPROC

其参数一个为服务器的套接字,一个为对应的通信端口。socketdev是在RAPID语言中对套接字数据类型的定义,端口对应数值数据类型num。从上一段代码中可以分析出,其Socket初始化的过程由三步完成,首先:

 IF (SocketGetStatus(server_socket) = SOCKET_CLOSED) SocketCreate server_socket;

直观上理解,如果server_socket还处于连接可用的状态过就执行下一步,如果已经关闭不可用了就重新创建有效的套接字后执行下一步。对给定的服务器套接字server_socket使用SocketGetStatus()函数读取状态,判断套接字是否已经关闭,如果已经关闭,则上面IF语句的主体内容就会执行,通过Soc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值