在 ROS 2(Robot Operating System 2)中,Service 是一种用于实现一对一通信模式的通信机制。Service 允许一个节点(Service 请求方)向另一个节点(Service 提供方)发送请求,并接收该节点的响应。这种通信方式适用于需要在两个节点之间传递数据并获取响应的情况。
Service 与 Topic 不同。在 ROS 2 中,Topic 是一种发布-订阅(Publish-Subscribe)机制,允许多个节点同时订阅某个主题,并接收来自发布者的消息。而 Service 则更专注于点对点的通信模式,仅有一个请求方和一个提供方。
下面是一个简单的示例来说明 ROS 2 Service 的用法:
-
假设我们有一个场景,其中一个节点需要向另一个节点请求执行某项任务。
-
创建一个名为
AddTwoInts.srv的服务文件,定义一个 Service,该 Service 接收两个整数并返回它们的和:
# AddTwoInts.srv
int64 a
int64 b
---
int64 sum
- 编写一个 Service 提供方的节点(Service Server),它会等待来自请求方的请求并返回相应的结果。以下是一个简单的 Service 提供方示例:
#include "rclcpp/rclcpp.hpp"
#include "demo_msgs/srv/add_two_ints.hpp"
void handle_service_request(const std::shared_ptr<demo_msgs::srv::AddTwoInts::Request> request,
std::shared_ptr<demo_msgs::srv::AddTwoInts::Response> response)
{
response->sum = request->a + request->b;
}
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("service_provider");
auto service = node->create_service<demo_msgs::srv::AddTwoInts>("add_two_ints", &handle_service_request);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
- 编写一个 Service 请求方的节点(Service Client),它会向 Service 提供方发送请求,并等待并处理响应。以下是一个简单的 Service 请求方示例:
#include "rclcpp/rclcpp.hpp"
#include "demo_msgs/srv/add_two_ints.hpp"
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("service_client");
auto client = node->create_client<demo_msgs::srv::AddTwoInts>("add_two_ints");
auto request = std::make_shared<demo_msgs::srv::AddTwoInts::Request>();
request->a = 5;
request->b = 3;
while (!client->wait_for_service(std::chrono::seconds(1))) {
if (!rclcpp::ok()) {
RCLCPP_ERROR(node->get_logger(), "Interrupted while waiting for the service. Exiting.");
return 1;
}
RCLCPP_INFO(node->get_logger(), "Service not available, waiting...");
}
auto future = client->async_send_request(request);
if (rclcpp::spin_until_future_complete(node, future) == rclcpp::executor::FutureReturnCode::SUCCESS) {
auto response = future.get();
RCLCPP_INFO(node->get_logger(), "Result: %ld", response->sum);
} else {
RCLCPP_ERROR(node->get_logger(), "Failed to call service add_two_ints");
}
rclcpp::shutdown();
return 0;
}
在这个示例中,Service 提供方节点接收两个整数并返回它们的和,而 Service 请求方节点发送请求并等待结果。这展示了 ROS 2 中 Service 的基本用法。您可以根据实际需求扩展和修改这些示例。