1.Service
Service: ROS中的同步通信方法,Node间可以通过request-reply方式通信。
srv是Service通信的数据格式,定义在 .srv 文件中。
基本的srv文件范例:
注:srv文件只能嵌套msg文件。
2.Parameter Server
Parameter Server:存储各种参数的字典,可用命令行,.launch 文件和node(API)读写,以便于各个节点的使用。
roscore命令启动ros时,parameter server便已经被启动。
项目中一些不变的参数一般保存在 .YAML 文件里,YAML文件格式如下。
如下,在launch文件中,可以使用param、rosparam、arg对参数进行设置。
<launch>
<!--使用param,对单参数赋值-->
<param name="name" value="ture"/>
<!--使用rosparam,读取.yaml文件,对多参数赋值-->
<rosparam file="param.yaml" command="load"/>
<!--使用arg,对单参数赋值,在.launch文件内部使用-->
<arg name="name" default="value" />
</launch>
3.Service实践
(1) Service的C++实现
//创建package
~/catkin_ws/src
catkin_create_pkg service_demo roscpp std_msgs message_generation message_runtime
//创建srv文件
cd service_demo
mkdir srv && cd srv
touch phone_number.srv
phone_number.srv 文件:
注: 项目运行后会在“devel/include/servicedemo/”目录生成头文件:
- phone_number.h
- phone_numberRequest.h
- phone_numberResponse.h
修改CmakeLists.txt:
add_service_files(FILES phone_number.srv)
generate_messages(
DEPENDENCIES
std_msgs # Or other packages containing msgs
)
创建Server.cpp
# include<ros/ros.h>
# include<service_demo/phone_number.h>
// 用于处理的回调函数,回调函数需要引用形式传入Request和Response,Response为返回数据
bool handle_function(service_demo::phone_number::Request &req,service_demo::phone_number::Response &res){
ROS_INFO("Request from %s with age %d",req.name.c_str(),req.age);
// 构建正确的登录信息
std::string name = "rick";
int age = 69;
if(name == req.name and age == req.age){
res.phone_number = "C137";
}else{
res.phone_number = "not C137";
}
return true;
}
int main(int argc, char *argv[])
{
// 初始化节点,指定节点名称
ros::init(argc, argv, "server");
// 创建节点句柄,用于控制节点
ros::NodeHandle nh;
// 创建服务端,并指定服务名称
ros::ServiceServer service = nh.advertiseService("phone_number_get",handle_function);
// 循环执行
ros::spin();
return 0;
}
创建client.cpp
# include<ros/ros.h>
# include<service_demo/phone_number.h>
int main(int argc, char *argv[])
{
// 初始化节点并指定节点名称
ros::init(argc, argv, "client");
// 创建句柄
ros::NodeHandle nh;
// 创建客户端并指定其发送的服务端名称
ros::ServiceClient client = nh.serviceClient<service_demo::phone_number>("phone_number_get");
// 获取信息
std::string name;
int age;
std::cout<<"Input username:"<<std::endl;
std::cin>>name;
std::cout<<"Input age:"<<std::endl;
std::cin>>age;
// 新建一个消息,传入内容
service_demo::phone_number info;
info.request.name = name;
info.request.age = age;
// 注意这里call函数返回的就是在服务端定义的回调函数的返回值(true or false)
if (client.call(info))
{
ROS_INFO("%s",info.response.phone_number.c_str());
}else{
ROS_ERROR("Failed to call service");
}
return 0;
}
修改CMakeLists.txt:
//添加
add_executable(server src/server.cpp)
add_executable(client src/client.cpp)
add_dependencies(server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(server ${catkin_LIBRARIES})
target_link_libraries(client ${catkin_LIBRARIES})
运行:
// 编译
cd ~/catkin_ws
catkin_make
//运行,单独打开4个终端
roscore
rosrun service_demo server
rosrun service_demo client
rosrun rqt_graph rqt_graph
(2) Service的Python实现
待续…
4.相关命令