ROS服务数据的定义和使用
参考博客:古月居ROS21讲
自定义服务数据
自定义服务数据与之前自定义msg类似,只有少许区别
主要步骤如下:
- 定义srv文件
- 在package.xml文件中添加功能包依赖
- 在CMakeList.txt中添加编译选项
- 编译生成语言相关文件
区别在于srv文件中有"—“标志,因为服务需要处理的信息包括req和res(request和response),”—“以上为req的数据,”—"以下的为res的数据。
- 创建srv
进入/workspace_name/src/package_name/中,新建srv文件夹,并进入新建一个serverName.srv文件,本例使用Person.srv。
编辑srv:
string name
uint8 age
uint8 sex
uint8 male=1
uint8 female=2
uint8 unknown =0
---
string result
-
在package.xml文件中添加功能包依赖
-
修改CMakeList.txt
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
turtlesim
message_generation <====就是这
)
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# geometry_msgs# std_msgs
# )
add_service_files(FILES Person.srv) <====就是这
generate_message(DEPENDENCIES std_msgs) <====就是这
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_service
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime <====就是这
# DEPENDS system_lib
)
-编译
回到根目录,执行编译
编译完成后,在/devel/include/learning_service/文件夹下出现三个头文件
使用的时候只需要包含Person.h一个就可以了,因为"—"上下两部分分别形成了req和res两个头文件,而Person.h是综合的头文件,将两者全都包括了。
- 注册服务端和客户端
- 服务端
代码如下
#include <ros/ros.h>
#include <learning_service/Person.h>
bool personCallback(learning_service::Person::Request &req,learning_service::Person::Response &res){
ROS_INFO("Person: name:%s , age: %d ,sex:%d",req.name.c_str(),req.age,req.sex);
//res.result="OK";
res.result = "OK";
return true;
}
int main(int argc,char **argv){
ros::init(argc,argv,"person_server");
ros::NodeHandle node;
//创建一个名为/show_person的server,注册回调函数personCallback
ros::ServiceServer person_service=node.advertiseService("/show_person",personCallback);
ROS_INFO("Ready to show person information.");
ros::spin();
return 0;
}
- 客户端代码如下
#include <ros/ros.h>
#include <learning_service/Person.h>
int main(int argc,char **argv)
{
ros::init(argc,argv,"person_client");
ros::NodeHandle n;
ros::service::waitForService("/show_person");
ros::ServiceClient person_client = n.serviceClient<learning_service::Person>("/show_person");
learning_service::Person srv;
srv.request.name = "Tom";
srv.request.age =20;
srv.request.sex =learning_service::Person::Request::male;
ROS_INFO("Call service to show person [name: %s, age: %d, sex:%d]",srv.request.name.c_str(),srv.request.age,srv.request.sex);
person_client.call(srv);
ROS_INFO("Show person result : %s",srv.response.result.c_str());
return 0;
}
-
修改编译规则
打开CMakeList.txt,修改
这里面PROJECT_NAME 指的是learning_service,也就是功能包。
add_dependencies(node_name ${PROJECT_NAME}_gencpp) 的作用是添加动态依赖。 -
编译,成功之后应该会在devel/lib/learning_service/下面出现两个对应名字的可执行文件
-
设置环境变量
-
测试