16th 服务通信_自定义srv调用实现(C++)

15th 服务通信自定义srv | 生成头文件

一、目标及分析

目标:

编写服务通信,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

  1. 服务端
  2. 客户端
  3. 数据

二、实现方法(C++)

2.0 配置VSCode

不配置也是可以的,但是不能再vscode中代码自动补齐,且导报时VSCode会报错,但是不影响最终程序的运行,建议配置。

 

 使用pwd获得到路径。

添加路径:

2.1  服务器端

2.1.1新建文件

#include<ros/ros.h>
#include<plumbing_server_client/Addints.h>
/*
        服务端实现:解析客户端提交的数据,并运算再返回相应
        1.包含头文件
        2.初始化ros节点
        3.创建节点句柄
        4.创建一个服务对象
        5.处理并产生相应
        6.spin()
*/
bool doNum(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);
    //2.组织响应
    int sum = num2+num1;
    response.sum = sum;
    ROS_INFO("求得的结果为:sum = %d",sum);

    return true;
}

int main(int argc, char  *argv[])
{
        setlocale(LC_ALL,"");
        // 2.初始化ros节点
        ros::init(argc,argv,"gongsi");   //设置节点名,为gongsi
        // 3.创建节点句柄
        ros::NodeHandle nh;
        // 4.创建一个服务对象
        ros::ServiceServer  server = nh.advertiseService("AddInts",doNum);
        ROS_INFO("服务器端已启动");
        // 5.处理并产生相应
        // 6.spin()
        ros::spin();

        return 0;
}

2.1.2服务器端的配置

在CMakelist.txt文件中:

2.1.3编译及测试

编译:Ctrl + Shift + B

rosservice  call  AddInts   Tab键补齐

 2.2 客户端

2.2.1 新建文件

#include<ros/ros.h>
#include<plumbing_server_client/Addints.h>
/*
    客户端:提交两个整数,并处理响应的结果(打印出来即可)
        1.包含头文件
        2.初始化ros节点
        3.创建节点句柄
        4.创建一个客户端对象
        5.提交请求并处理相应

        没有回调函数,spin()就可有可无了

*/
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
        // 2.初始化ros节点
    ros::init(argc,argv,"DaBao");
        // 3.创建节点句柄
    ros::NodeHandle nh;
        // 4.创建一个客户端对象
    ros::ServiceClient client = nh.serviceClient<plumbing_server_client::Addints>("AddInts");
        // 5.提交请求并处理相应
            //5.1组织请求
    plumbing_server_client::Addints ai;
     ai.request.num1 = 100;
     ai.request.num2 = 200;
            //5.2处理响应
    client.call(ai);
    bool flag = client.call(ai);
    if (flag = true)
      {
          ROS_INFO("响应成功!");
          ROS_INFO("响应结果=%d",ai.response.sum);
      }
    else
      {
          ROS_INFO("处理失败!");
      }   
    return 0;

    
}

2.2.2 配置

CMakelists.txt文件中:

2.2.3 编译并测试

 编译:Ctrl + Shift + B

 测试:

2.2.4 客户端的优化——参数的动态提交

这上面的例程中,num1和num2都是固定死的,如何实现那种任意输入的参数呢,实现参数的动态提交。格式: rosrun  包名  节点名  num1  num2

#include<ros/ros.h>
#include<plumbing_server_client/Addints.h>
/*
    客户端:提交两个整数,并处理响应的结果(打印出来即可)
        1.包含头文件
        2.初始化ros节点
        3.创建节点句柄
        4.创建一个客户端对象
        5.提交请求并处理相应

        没有回调函数,spin()就可有可无了

    
    实现参数的动态提交:
            1.格式: rosrun  包名  节点名  num1  num2
            2.节点执行时,需要获取命令中的参数,并赋值入request
*/
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");

    //优化实现,获取命令中的参数
    if (argc != 3)
    {
        ROS_INFO("提交的参数个数不对");
        return 1;
    }

        // 2.初始化ros节点
    ros::init(argc,argv,"DaBao");
        // 3.创建节点句柄
    ros::NodeHandle nh;
        // 4.创建一个客户端对象
    ros::ServiceClient client = nh.serviceClient<plumbing_server_client::Addints>("AddInts");
        // 5.提交请求并处理相应
            //5.1组织请求
    plumbing_server_client::Addints ai;
     ai.request.num1 = atoi(argv[1]);
     ai.request.num2 = atoi(argv[2]);   //atoi,将字符串类型转换为整数类型
            //5.2处理响应
    client.call(ai);
    bool flag = client.call(ai);
    if (flag = true)
      {
          ROS_INFO("响应成功!");
          ROS_INFO("响应结果=%d",ai.response.sum);
      }
    else
      {
          ROS_INFO("处理失败!");
      }   
    return 0;

    
}

 运行测试:

 3.思考题

如果先启动客户端,那么会导致运行失败,但是现在就需要先启动客户端,并且要求正常挂起,如何实现?

优化:

在客户端发送请求前添加:client.waitForExistence();

或:ros::service::waitForService("AddInts");   需要传一个参数,为服务的话题名。

这是一个阻塞式函数,只有服务启动成功后才会继续执行

此处可以使用 launch 文件优化,但是需要注意 args 传参特点

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是刃小木啦~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值