7.ROS编程学习:自定义服务数据c++调用
目录
一、准备工作——配置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++调用相关推荐
- 12.ROS编程学习:ROS常用指令
目录 rosnode 1.rosnode list--list active nodes 2.rosnode ping--test connectivity to node 3.rosnode inf ...
- ROS 学习笔记(三):自定义服务数据srv+server+client 示例运行
ROS 学习笔记(三):自定义服务数据srv+Server+Client 示例运行 一.自定义服务数据: 1.向功能包添加自定义服务文件(AddTwoInts.srv) cd ~/catkin_ws/ ...
- ROS应用开发入门 服务数据的定义和使用
ROS是机器人操作系统的简称,本文介绍ROS应用开发入门,服务数据的定义和使用.客户端和服务端 之间通讯都使用服务数据(service data).本文先定义一个服务数据,编译成功后,用一个服务端和一 ...
- 13.ROS编程学习:话题发布控制乌龟
目录 准备工作 c++控制乌龟运动 python控制乌龟运动 参考学习资料:赵虚左的课程+古月的ROS机器人开发实践P56的例程. 准备工作 打开ROS乌龟仿真器 roscore rosrun tur ...
- C++网络编程学习:服务端多线程分离业务处理高负载
网络编程学习记录 使用的语言为C/C++ 源码支持的平台为:Windows / Linux 笔记一:建立基础TCP服务端/客户端 点我跳转 笔记二:网络数据报文的收发 点我跳转 笔记三:升级为se ...
- C++网络编程学习:网络数据报文的收发
网络编程学习记录 使用的语言为C/C++ 源码支持的平台为:Windows 笔记一:建立基础TCP服务端/客户端 点我跳转 笔记二:网络数据报文的收发 点我跳转 笔记三:升级为select网络模型 ...
- 1.ROS编程学习:helloworld的c++与python实现
目录 一.c++实现 1.创建工作空间 3.CMakeLists.txt配置 4.catkin_make编译 5.source一下,配置环境变量 6.roscore+rosrun 二.python实现 ...
- 3.ROS编程学习:话题通信python
目录 1.建立scripts文件夹与python文件 2.发布者实现 3.订阅者实现 4.CMakeList.txt配置 5.添加可执行权限 6.运行roscore+rosrun 7.计算图 8.注意 ...
- 【RK3399Pro学习笔记】十一、ROS服务数据的定义与使用
目录 自定义服务数据 定义srv文件 在package.xml中添加功能包依赖 在CMakeLists.txt添加编译选项 编译生成语言相关文件 使用 C++ 编写程序 person_server.c ...
最新文章
- centos7 安装apache+php+memcache
- sqlite3admin触发器创建
- 相似度--欧氏距离(归一化)
- 实录分享 | 计算未来轻沙龙:大规模数据存储与挖掘(PPT下载)
- 教你一招如何使用几行代码实现zookeeper作为springcloud的服务注册中心
- 很棒的HTML5效果实例
- 我不看好data2vec这类多模态融合的研究
- 前端基础-html-文本格式化标签
- 55 MM配置-评估和科目设置-定义账户分类参考
- 2021深圳杯数学建模D题概览
- 计算机网络hdcp是什么意思,韩立平:笔记本电脑上hdcp是干什么的?
- No module named ‘_ssl‘
- python尼姆游戏_python实现聪明的尼姆游戏(人机对战)
- 「星火计划沙龙视频」云原生数据湖专场
- 新印的钞票如何流入市场?
- html像素测量尺,屏幕尺子:ruul.Screen ruler
- QML入门教程:一、QML和QtQuick简介以及QML实例
- 致微软利润下滑的七宗罪:Vista失败Xbox失守
- 百度网盘 技巧(资源搜索等)
- 智能照明c语言程序,C-BUS智能照明系统.ppt