No version for distro humble. Known supported distros are highlighted in the buttons above.
No version for distro jazzy. Known supported distros are highlighted in the buttons above.
No version for distro rolling. Known supported distros are highlighted in the buttons above.

action package from openrobotics repo

ros2_ballbot ros2_cartpole ros2_double_integrator ros2_quadrotor ros2_robot_vacuum ros2_vacuum_gazebo ros2_vacuum_slam action common_utils composition executors gazebo_camera gazebo_spawner lifecycle params pointcloud_subsriber rviz service system_monitor tf2_demos timer topic tutorials_msgs urdf decomp_ros decomp_ros_msgs decomp_ros_utils decomp_test_node ros2_math casadi_cpp casadi_python casadi_tutorials nav2_linear_quadratic_regulator_controller motion_model mpc_controller pid_controller robotic_assets ros2_controller ros2_controller_msgs waypoint_generator behavior_tree bspline carlike_simulator fast_methods forest_map_generator gridmap_ros map_generator nav2_demos a_star_planner breadth_first_search_planner bug_planner cubic_spline_planner d_star_lite_planner d_star_planner depth_first_planner dijkstra_planner dubins_path_planner eta3_spline_planner flow_filed_planner frenet_optimal_trajectory_planner greedy_best_first_search_planner hybrid_a_star_planner informed_rrt_star_planner nav2_straightline_planner path_planning potential_field_planner quintic_polynomials_planner rrt_dubins_planner rrt_planner rrt_star_planner state_lattice_planner voronoi_planner wave_front_planner cgmres_nmpc_tracking lqr_speed_steer_control_tracking model_predictive_speed_steer_control_tracking path_tracking pure_pursuit_tracking rear_wheel_feedback_tracking stanley_controller_tracking ros2_navigation ros2_system_test sdf_tools trajectory local_sensing multi_map_server odom_visualization pose_utils quadrotor_msgs so3_disturbance_generator so3_quadrotor_simulator uav_utils visualization_tools voronoi_layer quad_behavior_tree quad_bringup quad_bt_navigator quad_common quad_controller quad_core quad_costmap quad_global_planner quad_local_planner quad_logger quad_map_server quad_msgs quad_nmpc_controller quad_planner quad_robot_driver quad_rviz_plugins a1_description a1_simulation quad_gazebo spirit_description spirit_gazebo spirit_simulation quad_system_tests quad_teleop quad_utils ros2_quadruped gazebo_examples sam_bot_description velodyne_description velodyne_gazebo_plugins velodyne_simulator

Package Summary

Tags No category tags.
Version 0.0.0
License TODO: License declaration
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/duyongquan/openrobotics.git
VCS Type git
VCS Version main
Last Updated 2024-01-16
Dev Status UNMAINTAINED
CI status No Continuous Integration
Released UNRELEASED
Tags No category tags.
Contributing Help Wanted (0)
Good First Issues (0)
Pull Requests to Review (0)

Package Description

TODO: Package description

Additional Links

No additional links.

Maintainers

  • quan

Authors

No additional authors.
ros2_tutorials —— action使用
Part I 客户端(Client & Server)

1 tutorial 1(member_functions_test)

1.1 功能介绍

客户端fibonacci请求,服务器fibonacci生成fibonacci数据

fibonacci: 1, 2, 3, 5, 8,13, …

1.2 代码

头文件tutorials_action_demo1_member_functions.hpp

class MinimalActionClient : public rclcpp::Node
{
public:
  using Fibonacci = tutorials_msgs::action::Fibonacci;
  using GoalHandleFibonacci = rclcpp_action::ClientGoalHandle<Fibonacci>;

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

  bool is_goal_done() const;

  void send_goal();

private:
  void goal_response_callback(GoalHandleFibonacci::SharedPtr goal_handle);

  void feedback_callback(
    GoalHandleFibonacci::SharedPtr,
    const std::shared_ptr<const Fibonacci::Feedback> feedback);

  void result_callback(const GoalHandleFibonacci::WrappedResult & result);

  rclcpp_action::Client<Fibonacci>::SharedPtr client_ptr_;
  rclcpp::TimerBase::SharedPtr timer_;
  bool goal_done_;
};  // class MinimalActionClient

//#####################################################################################

class MinimalActionServer : public rclcpp::Node
{
public:
  using Fibonacci = tutorials_msgs::action::Fibonacci;
  using GoalHandleFibonacci = rclcpp_action::ServerGoalHandle<Fibonacci>;

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

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_action::CancelResponse handle_cancel(
    const std::shared_ptr<GoalHandleFibonacci> goal_handle);

  void execute(const std::shared_ptr<GoalHandleFibonacci> goal_handle);

  void handle_accepted(const std::shared_ptr<GoalHandleFibonacci> goal_handle);
};  // class MinimalActionServer


tutorials_action_demo1_member_functions.cpp

MinimalActionClient::MinimalActionClient(const rclcpp::NodeOptions & node_options)
: Node("minimal_action_client", node_options),
  goal_done_(false)
{
    this->client_ptr_ = rclcpp_action::create_client<Fibonacci>(
        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 MinimalActionClient::is_goal_done() const
{
    return this->goal_done_;
}

void MinimalActionClient::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<Fibonacci>::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);
}

void MinimalActionClient::goal_response_callback(GoalHandleFibonacci::SharedPtr goal_handle)
{
    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 MinimalActionClient::feedback_callback(
    GoalHandleFibonacci::SharedPtr,
    const std::shared_ptr<const Fibonacci::Feedback> feedback)
{
    RCLCPP_INFO(
        this->get_logger(),
        "Next number in sequence received: %" PRId32, feedback->sequence.back());
}

void MinimalActionClient::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(), "%" PRId32, number);
    }
}

//#####################################################################################

MinimalActionServer::MinimalActionServer(const rclcpp::NodeOptions & options)
: Node("minimal_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(&MinimalActionServer::handle_goal, this, _1, _2),
        std::bind(&MinimalActionServer::handle_cancel, this, _1),
        std::bind(&MinimalActionServer::handle_accepted, this, _1));
}


rclcpp_action::GoalResponse MinimalActionServer::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 MinimalActionServer::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 MinimalActionServer::execute(const std::shared_ptr<GoalHandleFibonacci> 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<Fibonacci::Feedback>();
    auto & sequence = feedback->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) {
      // 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 Succeeded");
    }
}

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

测试文件tutorials_action_demo1_member_functions_client_test.cpp

#include "action/tutorials_action_demo1_member_functions.hpp"

// int main(int argc, char * argv[])
// {
//   rclcpp::init(argc, argv);

//   rclcpp::executors::MultiThreadedExecutor executor;
//   auto action_server = std::make_shared<ros2_tutorials::action::MinimalActionServer>();
//   auto action_client = std::make_shared<ros2_tutorials::action::MinimalActionClient>();

//   while (!action_client->is_goal_done()) {
//     executor.add_node(action_server);
//     executor.add_node(action_client);
//   }

//   executor.spin();
//   rclcpp::shutdown();
//   return 0;
// }

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);

  auto action_server = std::make_shared<ros2_tutorials::action::MinimalActionClient>();

  rclcpp::spin(action_server);

  rclcpp::shutdown();
  return 0;
}

测试文件tutorials_action_demo1_member_functions_server_test.cpp

#include "action/tutorials_action_demo1_member_functions.hpp"

// int main(int argc, char * argv[])
// {
//   rclcpp::init(argc, argv);

//   rclcpp::executors::MultiThreadedExecutor executor;
//   auto action_server = std::make_shared<ros2_tutorials::action::MinimalActionServer>();
//   auto action_client = std::make_shared<ros2_tutorials::action::MinimalActionClient>();

//   while (!action_client->is_goal_done()) {
//     executor.add_node(action_server);
//     executor.add_node(action_client);
//   }

//   executor.spin();
//   rclcpp::shutdown();
//   return 0;
// }

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);

  auto action_server = std::make_shared<ros2_tutorials::action::MinimalActionServer>();

  rclcpp::spin(action_server);

  rclcpp::shutdown();
  return 0;
}


1.3 编译

colcon build  --packages-up-to action

1.4 运行

source环境变量

source install/setup.zsh

ros2 launch action tutorials.action.demo1_member_function_test.launch.py

1.5 运行结果

topic_tutorial.topic.initial_env_test

CHANGELOG
No CHANGELOG found.

Wiki Tutorials

This package does not provide any links to tutorials in it's rosindex metadata. You can check on the ROS Wiki Tutorials page for the package.

Package Dependencies

System Dependencies

No direct system dependencies.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged action at Robotics Stack Exchange

No version for distro noetic. Known supported distros are highlighted in the buttons above.
No version for distro ardent. Known supported distros are highlighted in the buttons above.
No version for distro bouncy. Known supported distros are highlighted in the buttons above.
No version for distro crystal. Known supported distros are highlighted in the buttons above.
No version for distro eloquent. Known supported distros are highlighted in the buttons above.
No version for distro dashing. Known supported distros are highlighted in the buttons above.
No version for distro galactic. Known supported distros are highlighted in the buttons above.
No version for distro foxy. Known supported distros are highlighted in the buttons above.
No version for distro iron. Known supported distros are highlighted in the buttons above.
No version for distro lunar. Known supported distros are highlighted in the buttons above.
No version for distro jade. Known supported distros are highlighted in the buttons above.
No version for distro indigo. Known supported distros are highlighted in the buttons above.
No version for distro hydro. Known supported distros are highlighted in the buttons above.
No version for distro kinetic. Known supported distros are highlighted in the buttons above.
No version for distro melodic. Known supported distros are highlighted in the buttons above.