1.7 请求和提供服务
1.7.1 引言
ROS支持两种主要的通信机制:话题和服务。话题拥有发布器和订阅器,用于发送和接收消息(参阅使用发布器和订阅器交换数据)。另一方面,服务通过允许请求和应答通信实现紧耦合。服务终端发送请求到服务器,并等待响应。服务器根据请求里的数据构建响应消息并回传给终端。每个服务都有一个类型用于决定请求和响应消息的结构。服务还拥有ROS网络中独一无二的名称。 服务通信具有如下特征:
①服务请求用于一对一通信。单独的节点发起请求,也只有一个节点接收请求并发送回去相应。
②当服务请求执行的时候,服务终端和服务器紧密地联系在一起。当服务请求发送的时候必须要有服务器存在,一旦请求发送出去,服务终端将会阻塞直到接收到相应。 服务的概念阐述如下图:
1.7.2 创建服务器
在查看服务的概念之前,在MATLAB中启动ROS节点管理器和ROS网络实例。“exampleHelperROSCreateSampleNetwork”将创建一些服务器以仿真真实的ROS网络。
rosinit
exampleHelperROSCreateSampleNetwork
Initializing ROS master on http://bat5136glnxa64.mathworks.com:11311/. Initializing global node /matlab_global_node_8332 with NodeURI http://bat5136glnxa64:40154/
在创建服务器之前,查看可用的服务类型:
rostype.getServiceList ans =
'adhoc_communication/BroadcastCMgrRobotUpdate'
'adhoc_communication/BroadcastString'
'adhoc_communication/ChangeMCMembership'
'adhoc_communication/GetGroupState'
'adhoc_communication/GetNeighbors'
'adhoc_communication/SendCMgrRobotUpdate'
'adhoc_communication/SendExpAuction'
'adhoc_communication/SendExpCluster'
'adhoc_communication/SendExpFrontier'
'adhoc_communication/SendMmControl'
'adhoc_communication/SendMmMapUpdate'
'adhoc_communication/SendMmPoint'
'adhoc_communication/SendMmRobotPosition'
'adhoc_communication/SendOccupancyGrid'
'adhoc_communication/SendQuaternion'
'adhoc_communication/SendString'
'adhoc_communication/SendTwist'
'adhoc_communication/ShutDown'
'app_manager/GetAppDetails'
'app_manager/GetInstallationState'
'app_manager/InstallApp'
'app_manager/ListApps'
'app_manager/StartApp'
'app_manager/StopApp'
'app_manager/UninstallApp'
'arbotix_msgs/Enable'
'arbotix_msgs/Relax'
假设你想要在创建一个简单的服务器,当你请求服务的时候显示“A service client is calling”。使用“rossvcserver”指令创建服务,指定服务的名称和服务消息的类型。同时定义回调函数“exampleHelperROSEmptyCallback”。服务器的回调函数有非常明确的签名。
testserver = rossvcserver(‘/test’, rostype.std_srvs_Empty, @exampleHelperROSEmptyCallback)
testserver =
ServiceServer with properties:
ServiceName: '/test'
ServiceType: 'std_srvs/Empty'
NewRequestFcn: @exampleHelperROSEmptyCallback
此时,当用户在ROS网络中罗列所有的服务,可以看到新创建的服务“/test”。
rosservice list
/add
/reply
/test
用户可以使用“rosservice info”查看有关服务的更多信息,全局节点也被列出,这是因为在该节点下,服务才是可用的,同时,用户还能够看到服务类型“itsstd_srvs/Empty”。
rosservice info /test
Node: /matlab_global_node_8332
URI: rosrpc://bat5136glnxa64:46049/
Type: std_srvs/Empty
Args:
1.7.3 创建服务终端
使用服务终端从ROS服务器获得请求信息,使用“rossvcclient”指令创建服务器,该指令需要服务作为参数。 为上一节创建的服务创建服务终端:
testclient = rossvcclient(‘/test’)
testclient =
ServiceClient with properties:
ServiceName: '/test'
ServiceType: 'std_srvs/Empty'
为服务创建一个空的请求消息,使用“rosmessage”函数并传递服务终端作为第一个参数,这会创建服务请求函数,拥有由服务指定的消息类型。
testreq = rosmessage(testclient)
testreq =
ROS EmptyRequest message with properties:
MessageType: 'std_srvs/EmptyRequest'
当想要从服务器获得相应,使用“call”函数请求参数服务器并返回响应。用户之前创建的服务器将会返回一个空的效应。此外,还会调用“exampleHelperROSEmptyCallback”显示字符串“A service client is calling”。用户还可以定义“Timeout”参数,该参数指示服务器应该等待响应的时间。
testresp = call(testclient,testreq,’Timeout’,3);
A service client is calling
用户能够看到回调函数输出的字符串。
1.7.4 创建服务做加法运算
目前为止,服务器没有做任何有意义的工作,但是用户现在可以使用服务完成计算或者数据处理,创建服务完成两个整数的加法运算。
已经存在服务类型“roscpp_tutorials/TwoInts”能够完成该任务。用户可以使用“rosmsg show”查看请求和相应消息的结构,请求包含两个整型数A和B,相应包含他们的和Sum。
rosmsg show roscpp_tutorials/TwoIntsRequest
int64 A
int64 B
rosmsg show roscpp_tutorials/TwoIntsResponse
int64 Sum
创建一个带有这种消息类型的服务器,以及一个回调函数执行加法运算。为方便用户,“exampleHelperROSSumCallback”函数已经实现了加法计算,指定该函数作为回调函数。
sumserver = rossvcserver(‘/sum’, rostype.roscpp_tutorials_TwoInts, @exampleHelperROSSumCallback) sumserver =
ServiceServer with properties:
ServiceName: '/sum'
ServiceType: 'roscpp_tutorials/TwoInts'
NewRequestFcn: @exampleHelperROSSumCallback
为了调用服务器,用户需要创建一个服务终端,注意,服务终端可以在ROS网络中的任何地方创建。结合本例需要,我们将在MATLAB中为“/sum”服务创建终端。
sumclient = rossvcclient(‘/sum’) sumclient =
ServiceClient with properties:
ServiceName: '/sum'
ServiceType: 'roscpp_tutorials/TwoInts'
创建请求消息,用户可以定义两个整型变量A和B,这两个数在调用“call”指令是将用于做加法运算。 sumreq = rosmessage(sumclient); sumreq.A = 2; sumreq.B = 1 sumreq =
ROS TwoIntsRequest message with properties:
MessageType: 'roscpp_tutorials/TwoIntsRequest'
A: 2
B: 1
执行的结果是两个数的和为3,为了调用服务,使用如下的代码。服务响应消息包含了“Sum”属性,存储A和B的加法结果。
sumresp = call(sumclient,sumreq,’Timeout’,3)
sumresp =
ROS TwoIntsResponse message with properties:
MessageType: 'roscpp_tutorials/TwoIntsResponse'
Sum: 3
1.7.5 关闭ROS网络
从ROS网络中移除示例节点、发布器、订阅器: exampleHelperROSShutDownSampleNetwork
关闭ROS主控节点并删除全局节点:
rosshutdown
Shutting down global node /matlab_global_node_8332 with NodeURI http://bat5136glnxa64:40154/
Shutting down ROS master on http://bat5136glnxa64.mathworks.com:11311/.
1.7.6 下一步
1.8访问ROS参数服务器。(下回分解)
转自公众号:
Robot404