赞
踩
与基于publisher/subscriber的通信机制topic相比,services/clients通信机制是一种双向,一对一的可靠通信机制。
client发送一个“request”到service,service会反馈一个“response”给client,这时的client就需要知道service的名称才能完成这种问答形式的通信机制。
同时还需要注意一点, service的响应要尽可能的快,因为client在没有得到反馈之前是处于停止状态的,直到它收到反馈才重新开始运行。所有如果一个service需要较长时间去处理大量的数据才能得出结果,这时应该选择action-server/action-client这种通信机制。
编译生成service msg的头文件。
对应的头文件在~/catkin_ws/devel/include/example_service
头文件的名称与.srv
文件的名称相同,与publisher/subscriber通信中定义的messages类型相比,在example_service文件夹里除了生成ExampleServiceMsg,h这个头文件外,还生成了另外两个头文件,分别是ExampleServiceMsgRequest.h和ExampleServiceMsgResponse.h,这两个头文件其实都包含在ExampleServiceMsg.h中,所以之后的调用只需要添加ExampleServiceMsg.h即可。
#include <ros/ros.h>
#include <string>
#include <iostream>
#include <example_service/ExampleServiceMsg.h>
using namespace std;
bool callback(example_service::ExampleServiceMsgRequest& request, example_service::ExampleServiceMsgResponse& response);
int main(int argc, char** argv) {
ros::init(argc, argv, "example_service"); //初始化节点,以example_service命名
ros::NodeHandle nh;
ros::ServiceServer service = nh.advertiseService("lookup_by_name", call_back); //创建一个service,名称为lookup_by_name
ROS_INFO("Ready to look up names");
ros::spin();
}
bool callback(example_service::ExampleServiceMsgRequest& request, example_service::ExampleServiceMsgResponse& response) {
ROS_INFO("callback activated");
string in_name(request.name);
response.on_the_list = false;
if (in_name.compare("Bob") == 0) {
ROS_INFO("asked about Bob");
response.age = 32;
response.good_guy = false;
response.on_the_list = true;
responst.nickname = "BobTheTerrible";
}
if (in_name.compare("Ted")==0) {
ROS_INFO("asked about Ted");
response.age = 21;
response.good_guy=true;
response.on_the_list=true;
response.nickname="Ted the Benevolent";
}
return true;
}
#include <ros/ros.h>
#include <string>
#include <iostream>
#include <example_service/ExampleServiceMsg.h>
using namespace std;
int main(int argc, char** argv) {
ros::init(argc, argv, "example_client");
ros::NodeHandle nh;
//下面这一行很重要,它创建个serviceClient与已经创建的service(look_up_name)进行通信
ros::ServiceClient client = nh.serviceClient<example_service::ExampleServiceMsg>("lookup_my_name");
example_service::ExampleServiceMsg srv;
bool found_on_list = false;
string in_name;
while (ros::ok()) {
cout << endl;
cout << "enter a name (x to quit): ";
cin >> in_name;
if (in_name.compare("x") == 0)
return 0;
srv.request.name = in_name;
// 注意下面的client.call(srv), 这个call会与已创建的service完成信息交换,是一个布尔类型的判断
if (client.call(srv)) {
if (srv.reponse.on_the_list) {
cout << srv.request.name << " is known as " << srv.response.nickname << endl;
cout << "He is " << srv.response.age << " years old." << endl;
if (srv.response.good_guy)
cout << "He is reported to be a good guy." << endl;
else
cout << "Avoid him; he is not a good guy." << endl;
} else {
cout << srv.request.name << "is not in my database." << endl;
}
} else {
ROS_ERROR("Fail to call service look_up_name.");
return 1;
}
}
return 0;
}
https://blog.csdn.net/Will_Ye/article/details/79541060
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。