当前位置:   article > 正文

ROS 通信:service_ros2服务client 会阻塞其他进程

ros2服务client 会阻塞其他进程

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; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

创建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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

Reference

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

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号