服务通信框架
创建流程
创建工作空间与功能包
创建了一个demo06_ws的工作空间,并创建了一个plumbing_server_client的功能包
创建srv文件与文件夹
在功能包中创建srv文件夹,并创建AddInts.srv文件
srv文件内容
#客户端请求时发送的两个数字
int32 num1
int32 num2
---
#服务端响应发送的数据
int32 sum
修改package.xml文件(配置文件1)
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
修改CMakeLists.txt文件(配置文件2)
主要修改4个地方:
修改功能包依赖的包列表
message_generation
message_runtime
修改自定义包依赖的包并申明自定义包
申明出AddInts.srv并修改AddInts.srv包依赖的的std_msgs包
# Generate services in the 'srv' folder
add_service_files(
FILES
AddInts.srv
)
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
编译成功
生产文件:
服务端程序
在功能包下的src文件夹内创建demo01_server.cpp,并写入程序
/*
需求:
编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器
服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,
客户端再解析
服务器实现:
1.包含头文件
2.初始化 ROS 节点
3.创建 ROS 句柄
4.创建 服务 对象
5.回调函数处理请求并产生响应
6.由于请求有多个,需要调用 ros::spin()
*/
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
// bool 返回值由于标志是否处理成功
bool doReq(plumbing_server_client::AddInts::Request& req,
plumbing_server_client::AddInts::Response& resp)
{
//1处理请求
int num1 = req.num1;
int num2 = req.num2;
ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);
//2组织响应
int sum = num1 + num2;
resp.sum = sum;
ROS_INFO("求和的结果:sum = %d",sum);
return true;
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
// 2.初始化 ROS 节点
ros::init(argc,argv,"AddInts_Server");
// 3.创建 ROS 句柄
ros::NodeHandle nh;
// 4.创建 服务 对象
ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
ROS_INFO("服务已经启动....");
// 5.回调函数处理请求并产生响应
// 6.由于请求有多个,需要调用 ros::spin()
ros::spin();
return 0;
}
客户端程序
在功能包下的src文件夹内创建demo02_client.cpp,并写入程序
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
/*
客户端实现:
1.包含头文件
2.初始化 ROS 节点
3.创建 ROS 句柄
4.创建 客户端 对象
5.提交请求并处理响应
6.ros::spin()
*/
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
// 2.初始化 ROS 节点
ros::init(argc,argv,"xiaomei");
// 3.创建 ROS 句柄
ros::NodeHandle nh;
// 4.创建 客户端 对象
ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("AddInts");
// 5.提交请求并处理响应
plumbing_server_client::AddInts ai;
//5.1提交请求
ai.request.num1 =100;
ai.request.num2 = 200;
//5.2处理响应
bool flag = client.call(ai);
if(flag)
{
ROS_INFO(" 响应成功!结果为:%d",ai.response.sum);
}
else
{
ROS_INFO("响应失败");
}
// 6.ros::spin()
ros::spin();
return 0;
}
修改cpp配置文件
修改CMakeLists.txt文件
add_executable(demo01_server src/demo01_server.cpp)
add_executable(demo02_client src/demo02_client.cpp)
add_dependencies(demo01_server ${PROJECT_NAME}_gencpp)
add_dependencies(demo02_client ${PROJECT_NAME}_gencpp)
target_link_libraries(demo01_server
${catkin_LIBRARIES}
)
target_link_libraries(demo02_client
${catkin_LIBRARIES}
)
运行效果
客户端优化
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
/*
客户端实现:
1.包含头文件
2.初始化 ROS 节点
3.创建 ROS 句柄
4.创建 客户端 对象
5.提交请求并处理响应
6.ros::spin()
*/
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
//参数的动态获取
if(argc != 3)
{
ROS_INFO("参数异常");
return 1;
}
// 2.初始化 ROS 节点
ros::init(argc,argv,"xiaomei");
// 3.创建 ROS 句柄
ros::NodeHandle nh;
// 4.创建 客户端 对象
ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("AddInts");
// 5.提交请求并处理响应
plumbing_server_client::AddInts ai;
//5.1提交请求
ai.request.num1 = atoi(argv[1]);
ai.request.num2 = atoi(argv[2]);
//5.2处理响应
//调用判断服务器状态的函数
//函数1
//client.waitForExistence();//等待服务器启动
//函数2
ros::service::waitForService("AddInts");//等待服务器启动
bool flag = client.call(ai);
if(flag)
{
ROS_INFO(" 响应成功!结果为:%d",ai.response.sum);
}
else
{
ROS_INFO("响应失败");
}
// 6.ros::spin()
//ros::spin();
return 0;
}