ROS2編程基礎課程--Actions

      網友投稿 1451 2022-05-30

      Actions?行動

      About?關于

      Actions are a form of asynchronous communication in ROS.?Action clients?send goal requests to?action servers.?Action servers?send goal feedback and results to?action clients. For more detailed information about ROS actions, please refer to the?design article.

      行動是ROS中異步通信的一種形式。?Action客戶端將目標請求發送到操作服務器。?操作服務器將目標反饋和結果發送給操作客戶端。有關ROS操作的更多詳細信息,請參考設計文章。

      This document contains a list of tutorials related to actions. For reference, after completing all of the tutorials you should expect to have a ROS package that looks like the package?action_tutorials.

      本文檔包含與操作相關的教程列表。作為參考,在完成所有教程之后,需要有一個類似于action_tutorials的ROS包。

      Prequisites?預備基礎

      Install ROS (Dashing or later)?安裝ROS(Dashing或更高版本)

      Install colcon?安裝colcon

      Setup a workspace and create a package named?action_tutorials:

      設置工作區并創建名為action_tutorials的包:

      Remember to source your ROS 2 installation.?記得要安裝ROS 2。

      Linux / OSX:

      mkdir -p action_ws/src

      cd?action_ws/src

      ros2 pkg create action_tutorials

      Windows:

      mkdir -p action_ws\srccd action_ws\src

      ros2 pkg create action_tutorials

      Tutorials

      Creating an Action

      Writing an Action Server (C++)

      Writing an Action Client (C++)

      Writing an Action Server (Python)

      Writing an Action Client (Python)

      在完成文檔閱讀之后,學習源碼:

      Fibonacci.action

      int32 order

      ---

      int32[] sequence

      ---

      int32[] partial_sequence

      Server/member_functions.cpp

      #include

      #include

      #include "example_interfaces/action/fibonacci.hpp"

      #include "rclcpp/rclcpp.hpp"

      // TODO(jacobperron): Remove this once it is included as part of 'rclcpp.hpp'

      ROS2編程基礎課程--Actions

      #include "rclcpp_action/rclcpp_action.hpp"

      class MinimalActionServer : public rclcpp::Node

      {

      public:

      using Fibonacci = example_interfaces::action::Fibonacci;

      using GoalHandleFibonacci = rclcpp_action::ServerGoalHandle;

      explicit MinimalActionServer(const rclcpp::NodeOptions & options = rclcpp::NodeOptions())

      : Node("minimal_action_server", options)

      {

      using namespace std::placeholders;

      this->action_server_ = rclcpp_action::create_server(

      this->get_node_base_interface(),

      this->get_node_clock_interface(),

      this->get_node_logging_interface(),

      this->get_node_waitables_interface(),

      "fibonacci",

      std::bind(&MinimalActionServer::handle_goal, this, _1, _2),

      std::bind(&MinimalActionServer::handle_cancel, this, _1),

      std::bind(&MinimalActionServer::handle_accepted, this, _1));

      }

      private:

      rclcpp_action::Server::SharedPtr action_server_;

      rclcpp_action::GoalResponse handle_goal(

      const rclcpp_action::GoalUUID & uuid,

      std::shared_ptr 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 goal_handle)

      {

      RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");

      (void)goal_handle;

      return rclcpp_action::CancelResponse::ACCEPT;

      }

      void execute(const std::shared_ptr goal_handle)

      {

      RCLCPP_INFO(this->get_logger(), "Executing goal");

      rclcpp::Rate loop_rate(1);

      const auto goal = goal_handle->get_goal();

      auto feedback = std::make_shared();

      auto & sequence = feedback->sequence;

      sequence.push_back(0);

      sequence.push_back(1);

      auto result = std::make_shared();

      for (int i = 1; (i < goal->order) && rclcpp::ok(); ++i) {

      // Check if there is a cancel request

      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 Suceeded");

      }

      }

      void handle_accepted(const std::shared_ptr 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(&MinimalActionServer::execute, this, _1), goal_handle}.detach();

      }

      }; ?// class MinimalActionServer

      int main(int argc, char ** argv)

      {

      rclcpp::init(argc, argv);

      auto action_server = std::make_shared();

      rclcpp::spin(action_server);

      rclcpp::shutdown();

      return 0;

      }

      Client/member_functions.cpp

      #include

      #include

      #include

      #include

      #include "example_interfaces/action/fibonacci.hpp"

      #include "rclcpp/rclcpp.hpp"

      // TODO(jacobperron): Remove this once it is included as part of 'rclcpp.hpp'

      #include "rclcpp_action/rclcpp_action.hpp"

      class MinimalActionClient : public rclcpp::Node

      {

      public:

      using Fibonacci = example_interfaces::action::Fibonacci;

      using GoalHandleFibonacci = rclcpp_action::ClientGoalHandle;

      explicit MinimalActionClient(const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions())

      : Node("minimal_action_client", node_options), goal_done_(false)

      {

      this->client_ptr_ = rclcpp_action::create_client(

      this->get_node_base_interface(),

      this->get_node_graph_interface(),

      this->get_node_logging_interface(),

      this->get_node_waitables_interface(),

      "fibonacci");

      this->timer_ = this->create_wall_timer(

      std::chrono::milliseconds(500),

      std::bind(&MinimalActionClient::send_goal, this));

      }

      bool is_goal_done() const

      {

      return this->goal_done_;

      }

      void send_goal()

      {

      using namespace std::placeholders;

      this->timer_->cancel();

      this->goal_done_ = false;

      if (!this->client_ptr_) {

      RCLCPP_ERROR(this->get_logger(), "Action client not initialized");

      }

      if (!this->client_ptr_->wait_for_action_server(std::chrono::seconds(10))) {

      RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");

      this->goal_done_ = true;

      return;

      }

      auto goal_msg = Fibonacci::Goal();

      goal_msg.order = 10;

      RCLCPP_INFO(this->get_logger(), "Sending goal");

      auto send_goal_options = rclcpp_action::Client::SendGoalOptions();

      send_goal_options.goal_response_callback =

      std::bind(&MinimalActionClient::goal_response_callback, this, _1);

      send_goal_options.feedback_callback =

      std::bind(&MinimalActionClient::feedback_callback, this, _1, _2);

      send_goal_options.result_callback =

      std::bind(&MinimalActionClient::result_callback, this, _1);

      auto goal_handle_future = this->client_ptr_->async_send_goal(goal_msg, send_goal_options);

      }

      private:

      rclcpp_action::Client::SharedPtr client_ptr_;

      rclcpp::TimerBase::SharedPtr timer_;

      bool goal_done_;

      void goal_response_callback(std::shared_future future)

      {

      auto goal_handle = future.get();

      if (!goal_handle) {

      RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");

      } else {

      RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");

      }

      }

      void feedback_callback(

      GoalHandleFibonacci::SharedPtr,

      const std::shared_ptr feedback)

      {

      RCLCPP_INFO(

      this->get_logger(),

      "Next number in sequence received: %" PRId64,

      feedback->sequence.back());

      }

      void result_callback(const GoalHandleFibonacci::WrappedResult & result)

      {

      this->goal_done_ = true;

      switch (result.code) {

      case rclcpp_action::ResultCode::SUCCEEDED:

      break;

      case rclcpp_action::ResultCode::ABORTED:

      RCLCPP_ERROR(this->get_logger(), "Goal was aborted");

      return;

      case rclcpp_action::ResultCode::CANCELED:

      RCLCPP_ERROR(this->get_logger(), "Goal was canceled");

      return;

      default:

      RCLCPP_ERROR(this->get_logger(), "Unknown result code");

      return;

      }

      RCLCPP_INFO(this->get_logger(), "Result received");

      for (auto number : result.result->sequence) {

      RCLCPP_INFO(this->get_logger(), "%" PRId64, number);

      }

      }

      }; ?// class MinimalActionClient

      int main(int argc, char ** argv)

      {

      rclcpp::init(argc, argv);

      auto action_client = std::make_shared();

      while (!action_client->is_goal_done()) {

      rclcpp::spin_some(action_client);

      }

      rclcpp::shutdown();

      return 0;

      }

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:初探數通網絡開放可編程
      下一篇:SpringBoot工程初始搭建過程全紀錄
      相關文章
      亚洲av永久中文无码精品| 亚洲一本一道一区二区三区| 亚洲国产欧洲综合997久久| 亚洲成年人免费网站| 亚洲a在线视频视频| 亚洲AV无码一区二区三区系列 | 亚洲三级在线观看| 亚洲三级在线免费观看| 亚洲中文久久精品无码1| 亚洲免费视频观看| 精品亚洲成在人线AV无码| 亚洲伊人久久大香线蕉啊| 亚洲天堂中文字幕在线观看| 亚洲人成在线中文字幕| www.亚洲日本| 亚洲欧美国产国产一区二区三区| 亚洲精品人成网线在线播放va| 亚洲第一街区偷拍街拍| 无码天堂亚洲国产AV| 亚洲成av人片一区二区三区 | 亚洲日本视频在线观看| 精品亚洲成在人线AV无码| 色噜噜亚洲男人的天堂| 亚洲人成网站在线播放2019| 亚洲AV无码一区二区三区牲色 | 国产青草亚洲香蕉精品久久 | 亚洲精品一区二区三区四区乱码| 亚洲国产精品一区二区久| 亚洲av专区无码观看精品天堂| 在线a亚洲老鸭窝天堂av高清| 亚洲国产成人手机在线观看| 日韩亚洲精品福利| 中文字幕亚洲不卡在线亚瑟| 亚洲国产精品VA在线观看麻豆| 亚洲国产一区二区a毛片| 亚洲另类自拍丝袜第1页| 色老板亚洲视频免在线观| 国产尤物在线视精品在亚洲| 中文字幕不卡亚洲| 亚洲日本一区二区三区| 亚洲制服在线观看|