目录

一、准备工作——配置vscode

二、服务端创建

1.创建文件demo01_server.cpp

2.服务端的CMakeList.txt配置

3.测试服务端

三、客户端实现

1.创建domo01_client.cpp

2.客户端的CMakeList.txt配置

3.测试客户端

4.优化客户端


学习参考:赵虚左的ROS课程与古月的ROS机器人开发实践书籍。

一、准备工作——配置vscode

为了vscode在调用自定义服务数据时不报假错同时能够补全代码,需要对vscode进行配置。

c_cpp_properties.json(注意逗号)

            "includePath": [--snip--"/home/rosmelodic/catkin_ws/devel/include/**"],

也就是刚刚创建自定义服务数据,catkin_make后中间文件的目录。

二、服务端创建

1.创建文件demo01_server.cpp

在src中创建demo01_server.cpp文件。

#include "ros/ros.h"
#include "server_client/AddInts.h"bool huidiao(server_client::AddInts::Request &request,server_client::AddInts::Response &response){int num11 = request.num1;int num22 = request.num2;ROS_INFO("收到的请求数据为:num11 =%d,num22=%d",num11,num22);int sum12 = num11 + num22;response.sum = sum12;ROS_INFO("求和结果:sum = %d",sum12);//ros::spin();//这是一次尝试return true;
}int main(int argc, char *argv[])
{setlocale(LC_ALL,"");ros::init(argc,argv,"jiafa_server");ros::NodeHandle n;ros::ServiceServer service = n.advertiseService("add_ints",huidiao);ROS_INFO("准备好加入两个整数");ros::spin();return 0;
}
#include "ros/ros.h"
#include "server_client/AddInts.h"

头文件:调用roscpp和刚刚创建的自定义服务数据类型。调用形式为功能包名/通过编译生成的自定义头文件名

bool huidiao(server_client::AddInts::Request &request,server_client::AddInts::Response &response){int num11 = request.num1;int num22 = request.num2;ROS_INFO("收到的请求数据为:num11 =%d,num22=%d",num11,num22);int sum12 = num11 + num22;response.sum = sum12;ROS_INFO("求和结果:sum = %d",sum12);ros::spin();return true;
}

首先先声明了函数输入参数的数据类型,其中数据类型为刚刚创建的自定义服务数据类型,需要注意的是,自定义服务数据类型创建时通过“---”的符号将上下两部分分为了请求和应答数据类型,如下图。其中调用方法为

server_client::AddInts::Request(Response)——功能包名::创建的自定义数据类型文件名::Request(Response)——请求(应答)

    int num11 = request.num1;int num22 = request.num2;

声明变量同时接收数据。

ROS_INFO("收到的请求数据为:num11 =%d,num22=%d",num11,num22);

在控制台输出字符串,同时注意中文乱码问题,为了解决此问题,主函数中加入:

setlocale(LC_ALL,"");

计算完,再赋值给response.sum应答。

    int sum12 = num11 + num22;response.sum = sum12;

控制台输出结果

ROS_INFO("求和结果:sum = %d",sum12);

因为服务的回调函数需要返回的时布尔类型,故运行成功应该返回true,不再是之前话题通信中返回的void(空)。这是一次尝试,在回调函数中加入回头函数,发现这是不行的,主函数运行一次,直接跳出去了,不再循环。

//ros::spin();//这是一次尝试
return true;

进入主函数部分:

int main(int argc, char *argv[])
{setlocale(LC_ALL,"");ros::init(argc,argv,"jiafa_server");ros::NodeHandle n;ros::ServiceServer service = n.advertiseService("add_ints",huidiao);ROS_INFO("准备好加入两个整数");ros::spin();return 0;
}

防止在控制台出现中文乱码。

setlocale(LC_ALL,"");

常规的初始化节点和创建节点句柄

    ros::init(argc,argv,"jiafa_server");ros::NodeHandle n;

服务端创建,其中发现区别:

泛型函数的没声明,不意味着不能声明,不加就跟随着回调函数数据类型了。(函数帮助通过ctrl+shift+空格,调出)

加上的效果。

ros::ServiceServer service = n.advertiseService<server_client::AddInts::Request,server_client::AddInts::Response>("add_ints",huidiao);

没有缓存区了,之前的话题通信都是有缓存区的。

    ros::ServiceServer service = n.advertiseService("add_ints",huidiao);

2.服务端的CMakeList.txt配置

add_executable(demo_server src/demo01_server.cpp)## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(demo_server ${PROJECT_NAME}_gencpp)target_link_libraries(demo_server${catkin_LIBRARIES}
)

加上注释掉的部分是因为CMakeList.txt中出现了两处 add_dependencies,配置不对会报错:

(2条消息) ROS报错:CMakeList.txt配置错误——add_dependencies位置错误(难发现)_机械专业的计算机小白的博客-CSDN博客https://blog.csdn.net/wzfafabga/article/details/127385406其中这是为了在编译cpp文件之前,先编译自定义服务数据类型,生成中间文件。

add_dependencies(demo_server ${PROJECT_NAME}_gencpp)

3.测试服务端

启动ROS Master

roscore

source一下,打开刚刚的cpp文件,其中指向的名字是CMakeList.txt文件中的add_executable设置的。

source ./devel/setup.bash
rosrun server_client demo_server 

此时服务端是挂起的。

rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ source ./devel/setup.bash
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun server_client demo_server
[ INFO] [1666080588.394932943]: 准备好加入两个整数

为了查看服务端是否功能正常:

source一下,

source ./devel/setup.bash 
rosservice call add_ints  "num1: 0
num2: 0"

其中 add_ints是cpp主函数中创建的服务名

ros::ServiceServer service = n.advertiseService("add_ints",huidiao);

后面的都是Tab代码补齐的。

rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosservice call add_ints  "num1: 1
num2: 5"
sum: 6

修改并运行,发现应答的sum得到了结果。这些参数都是对应着创建的自定义服务数据类型的srv文件:

int32 num1
int32 num2
---
int32 sum

同时观察启动服务端的控制台:

rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun server_client demo_server
[ INFO] [1666081116.775811954]: 准备好加入两个整数
[ INFO] [1666081146.878643685]: 收到的请求数据为:num11 =1,num22=5
[ INFO] [1666081146.878690322]: 求和结果:sum = 6

发现程序中的ROS_INFO输出的字符串全部输出了出来。到此服务端运行成功。

三、客户端实现

1.创建domo01_client.cpp

domo01_client.cpp

#include "ros/ros.h"
#include "server_client/AddInts.h"int main(int argc, char  *argv[])
{setlocale(LC_ALL,"");ros::init(argc,argv,"jiafa_client");ros::NodeHandle n;ros::ServiceClient client = n.serviceClient<server_client::AddInts>("add_ints");server_client::AddInts xiaoxi ;xiaoxi.request.num1 = 20;xiaoxi.request.num2 = 30;bool tiaojian = client.call(xiaoxi);if(tiaojian){ROS_INFO("应答结果接收成功");ROS_INFO("结果为:%d",xiaoxi.response.sum);}else{ROS_INFO("接收结果失败");}return 0;
}

只对与服务端不同地方进行讨论:

    ros::ServiceClient client = n.serviceClient<server_client::AddInts>("add_ints");

客户端的创建:

话题名必须和服务端话题名一致。

其中回调函数不在有,泛型数据类型为刚刚创建的自定义服务数据类型,注意这是不同于服务端的泛型数据类型的声明,其中服务端的泛型声明是请求和应答通过逗号隔开:

    ros::ServiceServer service = n.advertiseService<server_client::AddInts::Request,server_client::AddInts::Response>("add_ints",huidiao);

具体函数提示可以通过ctrl+shift+空格显示。

声明变量并赋值。

    server_client::AddInts xiaoxi ;xiaoxi.request.num1 = 20;xiaoxi.request.num2 = 30;

通过client.call函数发布请求,返回一个布尔值来确定应答是否成功。

    bool tiaojian = client.call(xiaoxi);if(tiaojian){ROS_INFO("应答结果接收成功");ROS_INFO("结果为:%d",xiaoxi.response.sum);}else{ROS_INFO("接收结果失败");}

2.客户端的CMakeList.txt配置

add_executable(demo_client src/demo01_client.cpp)
add_dependencies(demo_client ${PROJECT_NAME}_gencpp)
target_link_libraries(demo_client${catkin_LIBRARIES}
)

再次提醒add_dependencies出现了两次,注意是后面add_executable的add_dependencies!

3.测试客户端

服务通信与话题通信不同。话题通信中的发布者和订阅者可以以不同的先后顺序启动,当然,为了发布者发布的信息订阅者全能接收到,故先运行订阅者。服务通信必须先运行服务端再运行客户端。

启动ROS Master

roscore

启动服务端

source ./devel/setup.bash
rosrun server_client demo_server

启动客户端

source ./devel/setup.bash
rosrun server_client demo_client 

运行结果如图

4.优化客户端

主函数中加入,其中argc对应的是主函数的参数,argc代表着传入参数的个数。

    if (argc != 3)// if (argc != 5)//launch 传参(0-文件路径 1传入的参数 2传入的参数 3节点名称 4日志路径){ROS_ERROR("请提交两个整数");return 1;}

主函数中调整,其中atoi()函数作用是字符串转化为整形,可以按住ctrl点击函数名查看。其中古月的是atoll()是字符串转化为long long int型。其中argv[]对应主函数的参数。argv[]列表存放着传入参数的值,argv[1]和argv[2]是传入的第二个和第三个参数的值,由于传入的是字符串,故需要转化为int类型才能做数值计算。

/* Convert a string to an integer.  */
    // xiaoxi.request.num1 = 20;// xiaoxi.request.num2 = 30;xiaoxi.request.num1 = atoi(argv[1]);xiaoxi.request.num2 = atoi(argv[2]);

再次运行服务端和客户端

rosrun server_client demo_server
rosrun server_client demo_client 10 20

结果:

7.ROS编程学习:自定义服务数据c++调用相关推荐

  1. 12.ROS编程学习:ROS常用指令

    目录 rosnode 1.rosnode list--list active nodes 2.rosnode ping--test connectivity to node 3.rosnode inf ...

  2. ROS 学习笔记(三):自定义服务数据srv+server+client 示例运行

    ROS 学习笔记(三):自定义服务数据srv+Server+Client 示例运行 一.自定义服务数据: 1.向功能包添加自定义服务文件(AddTwoInts.srv) cd ~/catkin_ws/ ...

  3. ROS应用开发入门 服务数据的定义和使用

    ROS是机器人操作系统的简称,本文介绍ROS应用开发入门,服务数据的定义和使用.客户端和服务端 之间通讯都使用服务数据(service data).本文先定义一个服务数据,编译成功后,用一个服务端和一 ...

  4. 13.ROS编程学习:话题发布控制乌龟

    目录 准备工作 c++控制乌龟运动 python控制乌龟运动 参考学习资料:赵虚左的课程+古月的ROS机器人开发实践P56的例程. 准备工作 打开ROS乌龟仿真器 roscore rosrun tur ...

  5. C++网络编程学习:服务端多线程分离业务处理高负载

    网络编程学习记录 使用的语言为C/C++ 源码支持的平台为:Windows / Linux 笔记一:建立基础TCP服务端/客户端  点我跳转 笔记二:网络数据报文的收发  点我跳转 笔记三:升级为se ...

  6. C++网络编程学习:网络数据报文的收发

    网络编程学习记录 使用的语言为C/C++ 源码支持的平台为:Windows 笔记一:建立基础TCP服务端/客户端  点我跳转 笔记二:网络数据报文的收发  点我跳转 笔记三:升级为select网络模型 ...

  7. 1.ROS编程学习:helloworld的c++与python实现

    目录 一.c++实现 1.创建工作空间 3.CMakeLists.txt配置 4.catkin_make编译 5.source一下,配置环境变量 6.roscore+rosrun 二.python实现 ...

  8. 3.ROS编程学习:话题通信python

    目录 1.建立scripts文件夹与python文件 2.发布者实现 3.订阅者实现 4.CMakeList.txt配置 5.添加可执行权限 6.运行roscore+rosrun 7.计算图 8.注意 ...

  9. 【RK3399Pro学习笔记】十一、ROS服务数据的定义与使用

    目录 自定义服务数据 定义srv文件 在package.xml中添加功能包依赖 在CMakeLists.txt添加编译选项 编译生成语言相关文件 使用 C++ 编写程序 person_server.c ...

最新文章

  1. centos7 安装apache+php+memcache
  2. sqlite3admin触发器创建
  3. 相似度--欧氏距离(归一化)
  4. 实录分享 | 计算未来轻沙龙:大规模数据存储与挖掘(PPT下载)
  5. 教你一招如何使用几行代码实现zookeeper作为springcloud的服务注册中心
  6. 很棒的HTML5效果实例
  7. 我不看好data2vec这类多模态融合的研究
  8. 前端基础-html-文本格式化标签
  9. 55 MM配置-评估和科目设置-定义账户分类参考
  10. 2021深圳杯数学建模D题概览
  11. 计算机网络hdcp是什么意思,韩立平:笔记本电脑上hdcp是干什么的?
  12. No module named ‘_ssl‘
  13. python尼姆游戏_python实现聪明的尼姆游戏(人机对战)
  14. 「星火计划沙龙视频」云原生数据湖专场
  15. 新印的钞票如何流入市场?
  16. html像素测量尺,屏幕尺子:ruul.Screen ruler
  17. QML入门教程:一、QML和QtQuick简介以及QML实例
  18. 致微软利润下滑的七宗罪:Vista失败Xbox失守
  19. 百度网盘 技巧(资源搜索等)
  20. 智能照明c语言程序,C-BUS智能照明系统.ppt

热门文章

  1. 软件测试工程师如何保证软件的质量?
  2. Mac安装PL2303驱动
  3. Halcon图像拼接-算法速度优化
  4. 空间统计分析系列科普文章(By 虾神说D)
  5. learnopengl——HDR——完结
  6. python定义接口的关键字_使用*args和**kws指定关键字参数
  7. java poi生成word
  8. 手机尾号(与网上有点不一样的代码)
  9. Cobalt Strike (cs)联动 Goby 进行内网扫描
  10. 【GoCN酷Go推荐】ip2location 解析 IP 地址库