目录
一、需求
编写服务通信,客户端会提交 2个整数至服务端,服务端求和并响应给客户端(客户——服务——客户)
如(1条消息) ROS学习笔记(九)_Lbuera的博客-CSDN博客 所说的,建立的连接都已经封装了,我们需要做的关键点就三个:服务端、客户端、数据
二、流程
- 编写服务端实现
- 编写客户端实现
- 编写配置文件
- 编译并执行
2.1 vscode配置
这一部分和msg那边的配置如出一辙,就是把相关头文件在vscode里声明,谨防误抛异常。
{
"configurations": [
{
"browse": {
"databaseFilename": "",
"limitSymbolsToIncludedHeaders": true
},
"includePath": [
"/opt/ros/noetic/include/**",
"/home/liuxin/liuxin/src/helloworld/include/**",
"/usr/include/**",
"/home/liuxin/DEMON3_WS/devel/include/**"//新添的
],
"name": "ROS"
}
],
"version": 4
}
2.2 服务端实现
服务端实现:解析客户端提交的数据,运算并产生响应。首先要创建相应的C++文件
2.2.1 流程
- 包含头文件;
- 初始化 ROS 节点
- 创建节点句柄
- 创建服务对象
- 回调函数处理请求并产生响应
- spin()
以上流程基本和之前的话题通信没啥区别,涉及到回调函数更像订阅方。
区别有以下几点
- 创建服务对象函数不一样
- 回调函数 处理请求并产生响应 不一样
重点在回调函数 以及请求并产生响应那边。
//1.包含头文件;
#include "ros/ros.h"
#include "plumbing_server_client/Addints.h"
/*这部分是处理数据的代码 */
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");//防止乱码
//2.初始化 ROS 节点
ros::init(argc,argv,"server");
//3.创建节点句柄
ros::NodeHandle nh;//相当于一个重命名 NodeHandle = nh
//4.创建服务对象
ros::ServiceServer server = nh.advertiseService("addInts",doNums);
ROS_INFO("服务器启动");
//6.spin()
ros::spin();
return 0;
}
我们把处理请求并产生响应也就是doNum也就是第4步那里的回调函数 重点拿出来聊一聊,代码如下:
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);
//2.组织响应:进行相应的操作
int sum = num1 + num2;
response.sum = sum;
ROS_INFO("求和结果:%d",sum);
return true;
}
- 返回值为bool类型,这个是创建服务对象那边的要求。固定的,不可改动
- 函数的参数分别来自客户端和服务端,具体含义如下
plumbing_server_client::Addints::Request &request
plumbing_server_client::Addints::Response &response
plumbing_server_client里的Addints里的Request (需求),
plumbing_server_client里的Addints里的Response(反馈)
Addints里是分Request和Response的
- 接收来自客户端的内容
1.处理请求:接收来自客户端的内容
int num1 = request.num1;
int num2 = request.num2;
把request里的num1给num1,把request里的num2给num2
- 处理接收到的数据
int sum = num1 + num2;
response.sum = sum;
ROS_INFO("求和结果:%d",sum);
int sum = num1 + num2;处理得到的数据
response.sum = sum;将数据response反馈到客户端
ROS_INFO("求和结果:%d",sum);
三、配置相关文件
还记得我们前面的总结么?为了测试我们每一部分的程序是否存在错误,在编写完一部分的程序之后,要进行相关CMakeLists的配置,然后用相关指定来测试程序是否符合要求。
add_executable(demo01_server src/demo01_server.cpp)
target_link_libraries(demo01_server
${catkin_LIBRARIES}
)
add_dependencies(demo01_server ${PROJECT_NAME}_gencpp)
这里是gencpp
四、执行与运行
启动测试那边有的说
rosservice call addInts 是rosservice call 话题 打出前面的代码 按Tab键 没反应可以多按一次。
我们可以改num1和num2的值 然后回车即可测试服务端的数据处理的那一部分。实验结果如下