< >
Home » ROS2与Matlab入门教程 » ROS2与Matlab入门教程-调用并提供ROS2服务

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");

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros2与matlab入门教程