ros2动作编程-server

我们这一节开始学习ros2的动作编程,(预留动作编程原理)将创建运行一个动作服务器节点和动作客户端节点实现斐波那契数列的运算。
首先我们进入我们的消息功能包添加一个action文件夹幷在里面新建一个Fibonacci.action文件,内容如下:

#goal
int32 order
---
#result
int32[] sequence
---
#feedback
int32[] partial_sequence

除了上述动作文件中找到的目标(goal)、结果(result)和反馈(feedback)之外,动作基本上还使用两个额外的消息:取消(cancel)和状态(status)。取消(cancel)消息使用actionlib_msgs/GoalID,它在动作运行时可以取消动作客户端和单独节点上的动作的执行。状态(status)消息可以根据状态转换 (如PENDING、ACTIVE、PREEMPTED和SUCCEEDED )检查当前动作的状态。
并且需要在该功能包CMakeLists.txt添加编译规则

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Cardata.msg"
  "msg/Carcmd.msg"
  "srv/SrvTutorial.srv"

  "action/Fibonacci.action"#这次添加这一句
  DEPENDENCIES builtin_interfaces geometry_msgs std_msgs
)

在package.xml文件添加

  <depend>action_msgs</depend>

编译生成动作消息文件。

然后创建tutorials_action功能包来编写节点:

ln@ln-pctogo:~/ros2_ws$ ros2 pkg create tutorials_action --build-type ament_cmake --dependencies rclcpp rclcpp_action rclcpp_components oryxbot2_msgs

然后在src文件夹创建fibonacci_action_server.cpp,代码如下:

#include <memory>

#include "oryxbot2_msgs/action/fibonacci.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"
#include "rclcpp_components/register_node_macro.hpp"


class FibonacciAction : public rclcpp::Node
{

public:
  //类型重命名
  using Fibonacci = oryxbot2_msgs::action::Fibonacci;
  using GoalHandleFibonacci = rclcpp_action::ServerGoalHandle<Fibonacci>;

  //构造函数
  FibonacciAction(const rclcpp::NodeOptions & options = rclcpp::NodeOptions())
  : Node("fibonacci_action_server", options)
  {
    using namespace std::placeholders;
    //初始化动作服务器
    this->action_server_ = rclcpp_action::create_server<Fibonacci>(
      this->get_node_base_interface(),
      this->get_node_clock_interface(),
      this->get_node_logging_interface(),
      this->get_node_waitables_interface(),
      "fibonacci",
      std::bind(&FibonacciAction::handle_goal, this, _1, _2),
      std::bind(&FibonacciAction::handle_cancel, this, _1),
      std::bind(&FibonacciAction::handle_accepted, this, _1));
  }

private:
  //声明动作服务器
  rclcpp_action::Server<Fibonacci>::SharedPtr action_server_;

  rclcpp_action::GoalResponse handle_goal(
    const rclcpp_action::GoalUUID & uuid,
    std::shared_ptr<const Fibonacci::Goal> goal)
  {
    RCLCPP_INFO(this->get_logger(), "Received goal request with order %d", goal->order);
    (void)uuid;
    // Let's reject sequences that are over 9000
    if (goal->order > 9000) {
      return rclcpp_action::GoalResponse::REJECT;
    }
    return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
  }

  rclcpp_action::CancelResponse handle_cancel(
    const std::shared_ptr<GoalHandleFibonacci> goal_handle)
  {
    RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");
    (void)goal_handle;
    return rclcpp_action::CancelResponse::ACCEPT;
  }

  void handle_accepted(const std::shared_ptr<GoalHandleFibonacci> goal_handle)
  {
    using namespace std::placeholders;
    // this needs to return quickly to avoid blocking the executor, so spin up a new thread
    std::thread{std::bind(&FibonacciAction::execute, this, _1), goal_handle}.detach();
  }

  //接收动作目标消息幷执行动作(此处为斐波那契数列)的函数
  void execute(const std::shared_ptr<GoalHandleFibonacci> goal_handle)
  {
    RCLCPP_INFO(this->get_logger(), "Executing goal");
    //循环周期 : 1HZ
    rclcpp::Rate loop_rate(1);
    const auto goal = goal_handle->get_goal();
    auto feedback = std::make_shared<Fibonacci::Feedback>();
    //斐波那契数列初始化设置,也添加了反馈第一个第二个消息-01
    auto & sequence = feedback->partial_sequence;
    sequence.push_back(0);
    sequence.push_back(1);
    auto result = std::make_shared<Fibonacci::Result>();

    //动作细节
    for (int i = 1; (i < goal->order) && rclcpp::ok(); ++i) {
      // 查询客户端是否取消动作
      if (goal_handle->is_canceling()) {
        result->sequence = sequence;
        goal_handle->canceled(result);//取消动作
        RCLCPP_INFO(this->get_logger(), "Goal canceled");
        return;
      }
      // Update sequence
      sequence.push_back(sequence[i] + sequence[i - 1]);
      // Publish feedback
      goal_handle->publish_feedback(feedback);
      RCLCPP_INFO(this->get_logger(), "Publish feedback");

      loop_rate.sleep();//周期
    }

    // Check if goal is done
    if (rclcpp::ok()) {
      result->sequence = sequence;
      goal_handle->succeed(result);
      RCLCPP_INFO(this->get_logger(), "Goal succeeded");
    }
  }

};

//主函数
int main(int argc, char ** argv)
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<FibonacciAction>());
    rclcpp::shutdown();
    return 0;
}

然后在CMakeLists.txt添加编译规则:

add_executable(fibonacci_action_server src/fibonacci_action_server.cpp)
ament_target_dependencies(fibonacci_action_server rclcpp rclcpp_action oryxbot2_msgs)

install(TARGETS
  fibonacci_action_server
  EXPORT export_${PROJECT_NAME}
  DESTINATION lib/${PROJECT_NAME})

编译幷source。
运行节点

ln@ln-pctogo:~/ros2_ws$ ros2 run tutorials_action fibonacci_action_server 

什么也没有发生,是因为没有人调用动作服务,下节我们将编写客户端节点来调用服务。

(功能包在github上,使用需要同时下载编译oryxbot2_msgs功能包。git地址: https://github.com/DylanLN/oryxbot_ws-ros2)

ROS2编程基础课程文档 ROS 2(机器人操作系统2)是用于机器人应用的开源开发套件。ROS 2之目的是为各行各业的开发人员提供标准的软件平台,从研究和原型设计再到部署和生产。 ROS 2建立在ROS 1的成功基础之上,ROS 1目前已在世界各地的无数机器人应用中得到应用。 特色 缩短上市时间 ROS 2提供了开发应用程序所需的机器人工具,库和功能,可以将时间花在对业务非常重要的工作上。因为它 是开源的,所以可以灵活地决定在何处以及如何使用ROS 2,以及根据实际的需求自由定制,使用ROS 2 可以大幅度提升产品和算法研发速度! 专为生产而设计 凭借在建立ROS 1作为机器人研发的事实上的全球标准方面的十年经验,ROS 2从一开始就被建立在工业级 基础上并可用于生产,包括高可靠性和安全关键系统。 ROS 2的设计选择、开发实践和项目管理基于行业利 益相关者的要求。 多平台支持 ROS 2在Linux,Windows和macOS上得到支持和测试,允许无缝开发和部署机器人自动化,后端管理和 用户界面。分层支持模型允许端口到新平台,例如实时和嵌入式操作系统,以便在获得兴趣和投资时引入和推 广。 丰富的应用领域 与之前的ROS 1一样,ROS 2可用于各种机器人应用,从室内到室外、从家庭到汽车、水下到太空、从消费 到工业。 没有供应商锁定 ROS 2建立在一个抽象层上,使机器人库和应用程序与通信技术隔离开来。抽象底层是通信代码的多种实现, 包括开源和专有解决方案。在抽象顶层,核心库和用户应用程序是可移植的。 建立在开放标准之上 ROS 2中的默认通信方法使用IDL、DDS和DDS-I RTPS等行业标准,这些标准已广泛应用于从工厂到航空 航天的各种工业应用中。 开源许可证 ROS 2代码在Apache 2.0许可下获得许可,在3条款(或“新”)BSD许可下使用移植的ROS 1代码。这两个 许可证允许允许使用软件,而不会影响用户的知识产权。 全球社区 超过10年的ROS项目通过发展一个由数十万开发人员和用户组成的全球社区,为机器人技术创建了一个庞大 的生态系统,他们为这些软件做出贡献并进行了改进。 ROS 2由该社区开发并为该社区开发,他们将成为未 来的管理者。 行业支持 正如ROS 2技术指导委员会成员所证明的那样,对ROS 2的行业支持很强。除了开发顶级产品外,来自世界 各地的大大小小公司都在投入资源为ROS 2做出开源贡献。 与ROS1的互操作性 ROS 2包括到ROS 1的桥接器,处理两个系统之间的双向通信。如果有一个现有的ROS 1应用程序, 可 以通过桥接器开始尝试使用ROS 2,并根据要求和可用资源逐步移植应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值