ROS通信机制~服务通信(server&client)·笔记3

 系列文章目录:

ROS开发(ubuntu)笔记·1_嘻·嘻的博客-CSDN博客

ROS通信机制~话题通信(Publisher&Subscriber)·笔记2_嘻·嘻的博客-CSDN博客

服务通信 

概念:以请求响应的方式实现不同节点之间数据交互的通信模式。

结合话题通信来理解,两者差别不大,差别在于,话题通信多对多传递信息的,而服务通信一对一传递信息

服务通信需要保证顺序,即先启动服务端server,再启动客户端client,否则会报错

不过ROS中有些内置函数(阻塞式)可以解决这个问题,

    函数1  client.waitForExistence();
    函数2  ros::service::waitForService("服务话题");   下面代码中有体现。

服务通信自定义srv:(实现传递两个正整数相加的和)

【1】功能包下新建 srv 目录,添加 xxx.srv 文件

 【2】编辑配置文件

1.package.xml中添加编译依赖与执行依赖

2.CMakeLists.txt编辑 srv 相关配置

1.

 2.

3. 

4. 

 修改,编译后,可C++ 需要调用的中间文件,在devel的include下:

 【3】vscode配置(可以代码补齐,防止导包时误抛异常)

 

文件路径如之前话题通信中的操作相同,都是右击功能包,再点生成集成终端 ,输入pwd即可

【4】

服务端server

#include"ros/ros.h"
#include"plumbing_server_client/Addints.h"
/*
    服务端实现:解析客户端提交的数据,并运算再产生响应
         1.包含头文件
         2.初始化ROS节点
         3.创建节点句柄;
         4.创建一个服务对象;
         5.处理请求并响应;
         6.spin()
*/
bool doNums(plumbing_server_client::Addints::Request &request,
             plumbing_server_client::Addints::Response &response )
{
    //1.处理请求
    int num1 = request.num1;//为什么这里是.不是-> 因为函数的形参不是指针
    int num2 = request.num2;
    ROS_INFO("收到的请求数据: num1 = %d, num2 = %d",num1,num2);
     //逻辑处理
    if (num1 < 0 || num2 < 0)
    {
        ROS_ERROR("提交的数据异常:数据不可以为负数");
        return false;
    }
    //2.组织响应
    int sum0 = num1 + num2 ;
    response.sum = sum0;
    ROS_INFO("求和结果: sum = %d",sum0);
    return true;
}
int main(int argc ,char *argv[])
{ 
    setlocale(LC_ALL,"");
   //2.初始化ROS节点
   ros::init(argc,argv,"company");
   ros::NodeHandle nh;
   //创建一个服务对象
   ros::ServiceServer sever = nh.advertiseService("addints",doNums);
   ros::spin();
   return 0;
}

注意:

     当访问地址(指针或迭代器)的成员或数据时,用“->”
     当访问直接对象的成员或数据时,用“.”

客户端client

#include"ros/ros.h"
#include"plumbing_server_client/Addints.h"
/*
    客户端:提交两个整数,并处理响应的结果
    1.包含头文件
         2.初始化ROS节点
         3.创建节点句柄;
         4.创建一个客户端对象;
         5.提交请求并响应;
    实现参数的动态提交:
        1.格式: rosrun xxxxx(功能包名) xxxxx(第一个参数:文件名) 12(第二个参数) 34(第三个参数)
        2.节点执行时,需要获取命令中的参数,并组织进 request    

    问题:
        如果先启动客户端,那么会请求异常
    需求:
        如果先启动客户端,不要直接抛出异常,而是挂起,等服务器启动后,再正常请求
    解决:
        在ROS中内置了相关函数,这些函数可以让客户端启动后挂起,等待服务器启动
        client.waitForExistence();
        ros::service::waitForService("服务话题");             
*/

int main(int argc , char *argv[])
{      //argc代表传入的参数的总数量
   setlocale(LC_ALL,"");
   //优化实现,获取命令中参数
   if(argc != 3)
   {
       ROS_INFO("提交的参数个数不对。");
       return 1;
   }

   
   
   ros::init(argc,argv,"client");

   ros::NodeHandle nh;
   //4.创建一个客户端对象
   ros::ServiceClient client = nh.serviceClient<plumbing_server_client::Addints>("addints");
   //5.提交请求并响应
   plumbing_server_client::Addints ai;//创建一个Addints对象
   //5-1.组织请求
   ai.request.num1= atoi(argv[1]);//argv[1]是char类型的,要转化成int类型,使用了atoi
   ai.request.num2= atoi(argv[2]);

   //5-2.处理响应
   //调用函数判断服务器状态
   //函数1
 //client.waitForExistence();
   //函数2
   ros::service::waitForService("addints");  
   
   // 6.发送请求,返回 bool 值,标记是否成功
   bool flag = client.call(ai);
   if(flag)
   {
       ROS_INFO("响应成功!");
       //获取结果
       ROS_INFO("响应结果 = %d",ai.response.sum);
   }
   else
   {
       ROS_INFO("处理失败。。。");
   }
   return 0;

}

client的代码中实现了动态输入两个整数,用到了argc和argv[],具体解释上面有。

对于atoi函数,实现了数据类型转换的功能,可看源码:

函数1  client.waitForExistence();
函数2  ros::service::waitForService("服务话题");   的运行效果

【5】 配置 CMakeLists.txt

运行结果:  

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ROS通信机制包括话题(Topic)、服务Service)和动作(Action)三种方式。 1. 话题:话题是一种发布/订阅(Publish/Subscribe)机制,发布者(Publisher)将消息发布到话题中,订阅者(Subscriber)从话题中接收消息。话题的实现流程如下: - 发布者指定话题名、消息类型和队列长度。 - 发布者将消息发布到话题中。 - 订阅者从话题中接收消息。 2. 服务服务是一种请求/响应(Request/Response)机制,客户端(Client)向服务器(Server)发送请求,服务器对请求进行处理并返回响应。服务的实现流程如下: - 定义服务类型和服务名。 - 服务器等待客户端请求。 - 客户端向服务器发送请求。 - 服务器对请求进行处理并返回响应。 3. 动作:动作是一种异步请求/响应机制,客户端向服务器发送请求,服务器对请求进行处理并返回响应,但在响应返回之前,客户端可以取消请求或者向服务器发送取消请求。动作的实现流程如下: - 定义动作类型和动作名。 - 服务器等待客户端请求。 - 客户端向服务器发送请求。 - 服务器对请求进行处理并返回响应。 - 在响应返回之前,客户端可以取消请求或者向服务器发送取消请求。 相同点:话题、服务和动作都是ROS通信机制的一部分,它们都实现了不同的通信机制,使得ROS系统中的组件能够进行数据交换和协作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值