ROS 通信:service

Introduction

与基于publisher/subscriber的通信机制topic相比,services/clients通信机制是一种双向,一对一的可靠通信机制。
client发送一个“request”到service,service会反馈一个“response”给client,这时的client就需要知道service的名称才能完成这种问答形式的通信机制。
同时还需要注意一点, service的响应要尽可能的快,因为client在没有得到反馈之前是处于停止状态的,直到它收到反馈才重新开始运行。所有如果一个service需要较长时间去处理大量的数据才能得出结果,这时应该选择action-server/action-client这种通信机制。

创建service msg

编译生成service msg的头文件。
对应的头文件在~/catkin_ws/devel/include/example_service
头文件的名称与.srv文件的名称相同,与publisher/subscriber通信中定义的messages类型相比,在example_service文件夹里除了生成ExampleServiceMsg,h这个头文件外,还生成了另外两个头文件,分别是ExampleServiceMsgRequest.h和ExampleServiceMsgResponse.h,这两个头文件其实都包含在ExampleServiceMsg.h中,所以之后的调用只需要添加ExampleServiceMsg.h即可。

创建server node

#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; 
}

创建client node

#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;
}

Reference

https://blog.csdn.net/Will_Ye/article/details/79541060

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值