提示:学习记录
前言
学习服务通信机制
一、服务通信
服务通信:基于请求响应
的模式,用于偶然的、对实时性有要求、有一定逻辑处理需求的数据传输场景;
二、流程步骤
0、server注册
1、client注册
2、rosmaster实现信息匹配
3、client发送请求request
4、server发送响应respond
1.定义srv文件
代码如下(示例):
使用---
把请求和响应分隔开;
2.编辑配置文件
秘诀:xml文件添俩行,txt文件添二行加二段
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_service_files(
FILES
AddInts.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES plumbing_server_client
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
3.编译后生成中间文件路径可以添加进入相关配置文件配置vscode
,“xxx/xxx工作空间/devel/include/***”
4.程序编写(c++)
1.服务端
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
/**
* @brief 服务端实现
* 解析客户端提交的数据,并运算产生响应
* 1、包含头文件
* 2、初始化ros节点
* 3、创建节点句柄
* 4、创建服务对象
* 5、处理请求并产生响应
* 6、spin()一定要加,循环则是spinOnce
* @param argc
* @param argv
* @return int
*/
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("求和结果sum=%d",sum);
return true;
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ROS_INFO("服务端已启动");
// * 2、初始化ros节点
ros::init(argc, argv, "HeiShui"); //保证名称唯一
// * 3、创建节点句柄
ros::NodeHandle nh;
// * 4、创建服务对象 服务起了个话题名称addInts
ros::ServiceServer server = nh.advertiseService("addInts",doNums);
// * 5、处理请求并产生响应
// * 6、spin()一定要加,循环则是spinOnce
ros::spin();
return 0;
}
2.客户端
在这里插入代码片
3.配置CMakeList.txt
4.执行
总结
出现错误:问题1.rosservice call关键字后加话题名称,但并没有tab补齐,弹幕说空一格再2下tab补齐也没有出现:
解决办法:首先尝试使用加斜线的方式,并按下2次tab查找当前话题,但并没有成功;自定义消息或者服务信息,调用时出现错误ERROR: Unable to load type [xxx]:可能的原因是当前使用的终端的工作环境没有更新导致无法找到自定义的消息。执行更新终端的工作环境,网上搜索到的相关经验,但是我已经配置了工作环境,所以并不是该种问题,反思创建AddInts时一开始写成Addints,编译后把i换成了跟老师一样的大写,因此/devel目录下出现addints相关的头文件,但后续用的时AddInts相关头文件,因此决定删除整个功能包,重新尝试:
rosservice call /AddInts 后可以tab补齐,功能正常,成功解决问题!
问题2:
出现错误:[ WARN] [1664201474.083411553]: Shutdown request received.
[ WARN] [1664201474.084911617]: Reason given for shutdown: [[/HeiShui] Reason: new node registered with same name]
解决办法:粗心大意,原因是CMakeLists.txt之中add_executable(demo02_client src/demo01_server.cpp)
重复指向同一个cpp文件,因此运行时发生冲突;修改后解决问题。
问题3:
解决办法:原因是在服务通信之中,属于异步通信,因此在通信时,服务端应该优先客户端运行。
这里也要提一下后面提到的客户端挂起选项:
问题5:错误类型error: invalid conversion from ‘char*’ to ‘plumbing_server_client::AddIntsRequest_<std::allocator >::_num1_type’ {aka ‘int’} [-fpermissive]
35 | ai.request.num1 = argv[1];
解决办法:学会使用argc与argv进行动态传参,但没有对argv[]进行一个字符串的转化:
结束!