📅  最后修改于: 2023-12-03 15:04:55.738000             🧑  作者: Mango
在ROS2中,服务(Service)是一种允许节点之间进行请求-响应通信的机制。其操作类似于ROS1中的服务。在本文中,我们将介绍如何在ROS2中使用服务。
在ROS2中,您可以使用ROS2的colcon构建系统或ament工具创建服务。服务消息是使用ROS2的接口定义语言(IDL)在colcon下生成的,这种语言使生成的消息类型跨语言兼容。
以下是您可以使用的步骤:
定义您的服务消息的IDL,例如,在my_robot_interfaces
包中定义名为SetSpeed
的服务:
# 服务请求消息
int64 speed
# 服务响应消息
---
bool success
使用ament,通过以下命令生成服务消息:
ament build --bundle-visual-studio --isolated --cmake-args -DCMAKE_BUILD_TYPE=Release
在my_robot_interfaces/srv
中生成SetSpeed.srv
的头文件和源文件。
接下来,创建一个新节点以设置机器人速度:
#include "my_robot_interfaces/srv/set_speed.hpp"
#include "rclcpp/rclcpp.hpp"
/* 根据 SetSpeed.srv 建立节点 */
class SetSpeedNode : public rclcpp::Node
{
public:
SetSpeedNode() : Node("set_speed_node")
{
/* 创建服务 */
auto set_speed_service = create_service<my_robot_interfaces::srv::SetSpeed>(
"set_speed", std::bind(&SetSpeedNode::set_speed_callback, this, _1, _2, _3));
}
private:
void set_speed_callback(
const std::shared_ptr<rmw_request_id_t> request_header,
const std::shared_ptr<my_robot_interfaces::srv::SetSpeed::Request> request,
std::shared_ptr<my_robot_interfaces::srv::SetSpeed::Response> response)
{
/* 调用设备的API设置机器人的速度 */
bool success = setRobotSpeed(request->speed);
response->success = success;
}
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<SetSpeedNode>());
rclcpp::shutdown();
return 0;
}
在上面的代码中,我们创建了一个节点,并用set_speed
作为服务名称。我们还定义了一个set_speed_callback
回调函数,该回调函数会将服务请求中的速度发送到设备API以设置机器人的速度,并将成功的状态设置为响应消息。
运行服务节点:
ros2 run my_robot_interfaces set_speed_node
现在我们已经创建了一个服务,我们还需要知道如何使用它。在ROS2中,您可以使用ros::ServiceClient
进行服务调用。
#include "my_robot_interfaces/srv/set_speed.hpp"
#include "rclcpp/rclcpp.hpp"
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("service_client");
/* 创建服务客户端 */
auto client = node->create_client<my_robot_interfaces::srv::SetSpeed>("set_speed");
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(), "未能连接到服务,重试...");
}
/* 创建服务请求 */
auto request = std::make_shared<my_robot_interfaces::srv::SetSpeed::Request>();
request->speed = 20;
/* 调用服务 */
auto future = client->async_send_request(request);
if (rclcpp::spin_until_future_complete(node, future) == rclcpp::executor::FutureReturnCode::SUCCESS) {
auto response = future.get();
if (response->success) {
RCLCPP_INFO(node->get_logger(), "设备成功地设置机器人的速度");
} else {
RCLCPP_ERROR(node->get_logger(), "设备未能设置机器人的速度");
}
} else {
RCLCPP_ERROR(node->get_logger(), "服务调用失败。");
}
rclcpp::shutdown();
return 0;
}
在上述代码中,我们使用create_client
方法创建了一个服务客户端。我们填充了请求中的速度,并使用async_send_request
方法发送请求。
使用spin_until_future_complete
方法使节点机一直保持活动状态,以等待服务的响应。如果返回值是SUCCESS
,则我们将获取响应对象并检查请求是否成功。
这就是关于在ROS2中使用服务的全部内容。您可以使用上面提供的代码模板开始创建自己的服务。务必注意,ROS2的服务机制与ROS1不同,您需要检查ROS2文档以获取更多相关信息。