ROS2与Matlab入门教程-调用并提供ROS2服务
说明:
- 介绍如何设置服务服务器以向 ROS2 网络发布服务
介绍:
ROS 支持两种主要的通信机制:主题和服务。主题有发布者和订阅者,用于发送和接收消息
服务通过允许请求-响应通信来实现更紧密的耦合。服务客户端向服务服务器发送请求消息并等待响应。服务器将使用请求中的数据构造响应消息并将其发送回客户端。每个服务都有一个类型,它决定了请求和响应消息的结构
这种服务通信具有以下特点:
服务请求(或服务调用)用于一对一通信。单个节点将发起请求,只有一个节点将接收请求并发送回响应。
执行服务调用时,服务客户端和服务服务器紧密耦合。服务器需要在服务调用时存在,一旦请求发送,客户端将阻塞,直到收到响应。
服务的概念如下图所示:
步骤:
- 创建服务Server,在检查服务概念之前,创建具有三个节点的示例 ROS 2 网络以模拟真实网络
node_1 = ros2node( "node_1" );
node_2 = ros2node( "node_2" );
node_3 = ros2node( "node_3" );
假设您要创建一个简单的服务服务器,当您调用服务时显示“服务客户端正在调用” 。
ros2svcserver使用命令创建服务。指定服务名称、服务消息类型和连接服务器的节点。还将回调函数定义为exampleHelperROSEmptyCallback. 服务服务器的回调函数有一个非常具体的签名
testserver = ros2svcserver(node_1, "/service_example" , "std_srvs/Empty" ,@exampleHelperROS2EmptyCallback)
testserver =
ros2svcserver with properties:
ServiceType: 'std_srvs/Empty'
ServiceName: '/service_example'
NewRequestFcn: @exampleHelperROS2EmptyCallback
History: 'keeplast'
Depth: 10
Reliability: 'reliable'
Durability: 'volatile'
- /test当您列出 ROS 网络中的所有服务时,您可以看到您的新服务
ros2("service","list");
/_matlab_introspec__0/describe_parameters
/_matlab_introspec__0/get_parameter_types
/_matlab_introspec__0/get_parameters
/_matlab_introspec__0/list_parameters
/_matlab_introspec__0/set_parameters
/_matlab_introspec__0/set_parameters_atomically
/node_1/describe_parameters
/node_1/get_parameter_types
/node_1/get_parameters
/node_1/list_parameters
/node_1/set_parameters
/node_1/set_parameters_atomically
/node_2/describe_parameters
/node_2/get_parameter_types
/node_2/get_parameters
/node_2/list_parameters
/node_2/set_parameters
/node_2/set_parameters_atomically
/node_3/describe_parameters
/node_3/get_parameter_types
/node_3/get_parameters
/node_3/list_parameters
/node_3/set_parameters
/node_3/set_parameters_atomically
/service_example
创建服务客户端。使用服务客户端从 ROS 2 服务服务器请求信息。要创建客户端,请使用ros2svcclient服务名称作为参数。
为我们刚刚创建的服务创建一个服务客户端/test并将其附加到不同的节点。
testclient = ros2svcclient(node_2,"/service_example","std_srvs/Empty")
testclient =
ros2svcclient with properties:
ServiceType: 'std_srvs/Empty'
ServiceName: '/service_example'
History: 'keeplast'
Depth: 10
Reliability: 'reliable'
Durability: 'volatile'
- 为服务创建一个空的请求消息。使用该ros2message函数并将客户端作为第一个参数传递。这将创建一个服务请求函数,该函数具有服务指定的消息类型
testreq = ros2message (testclient)
testreq = struct with fields:
MessageType: 'std_srvs/EmptyRequest'
- 确保服务已连接到客户端,如有必要,等待它们连接
waitForServer(testclient,"Timeout",3)
当您想从服务器获取响应时,请使用该call函数,该函数调用服务服务器并返回响应。您之前创建的服务服务器将返回一个空响应
此外,它将调用该exampleHelperROSEmptyCallback函数并显示字符串"A service client is calling"
定义一个Timeout参数,该参数指示客户端应等待响应的时间。status和statustext输出提供有关响应状态的附加信息
testresp = call(testclient,testreq,"Timeout",3)
testresp = struct with fields:
MessageType: 'std_srvs/EmptyResponse'
如果上面的调用函数失败,就会报错。
如果您希望使用条件对调用失败做出反应,而不是错误,请从调用函数返回状态和状态文本输出。状态输出指示调用是否成功,而状态文本提供附加信息。类似的输出可以从 waitForServer 返回
numCallFailures = 0;
[testresp,status,statustext] = call(testclient,testreq,"Timeout",3);
if ~status
numCallFailures = numCallFailues + 1;
fprintf("Call failure number %d. Error cause: %s\n",numCallFailures,statustext)
else
disp(testresp)
end
MessageType: 'std_srvs/EmptyResponse'
创建用于添加两个数字的服务
到目前为止,服务服务器还没有做任何有意义的工作,但您可以使用服务进行计算和数据操作。创建一个将两个整数相加的服务。
有一个现有的服务类型,example_interfaces/AddTwoInts我们可以用于此任务。您可以通过调用来检查请求和响应消息的结构ros2 msg show。请求包含两个整数a和b,响应包含它们在 中的加法sum。
ros2 msg show example_interfaces/AddTwoIntsRequest
int64 a
int64 b
ros2 msg show example_interfaces/AddTwoIntsResponse
int64 sum
- 使用此消息类型和计算加法的回调函数创建服务服务器。为了您的方便,该exampleHelperROS2SumCallback函数已经实现了这个计算。将函数指定为回调
sumserver = ros2svcserver(node_1, "/sum" , "example_interfaces/AddTwoInts" ,@exampleHelperROS2SumCallback)
sumserver =
ros2svcserver with properties:
ServiceType: 'example_interfaces/AddTwoInts'
ServiceName: '/sum'
NewRequestFcn: @exampleHelperROS2SumCallback
History: 'keeplast'
Depth: 10
Reliability: 'reliable'
Durability: 'volatile'
要调用服务服务器,您必须创建服务客户端。请注意,可以在 ROS 2 网络中的任何位置创建此客户端。
出于本示例的目的,我们将/sum在 MATLAB 中为该服务创建一个客户端。然后我们将等待以确保客户端已连接到服务器。
sumclient = ros2svcclient(node_3, "/sum" , "example_interfaces/AddTwoInts" )
sumclient =
ros2svcclient with properties:
ServiceType: 'example_interfaces/AddTwoInts'
ServiceName: '/sum'
History: 'keeplast'
Depth: 10
Reliability: 'reliable'
Durability: 'volatile'
waitForServer(sumclient,"Timeout",3);
- 创建请求消息。您可以定义使用命令时相加的两个整数
sumreq = ros2message(sumclient);
sumreq.a = int64(2);
sumreq.b = int64(1);
- 期望这两个数字之和为 3。要调用该服务,请使用以下命令。服务响应消息将包含一个sum属性,该属性存储a和的添加b
sumresp = call(sumclient,sumreq,"Timeout",3)
sumresp = struct with fields:
MessageType: 'example_interfaces/AddTwoIntsResponse'
sum: 3
- 关闭 ROS 2 网络,从 ROS 2 网络中删除示例节点和服务服务器
clear("node_1");
clear("node_2");
clear("node_3");
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号