Contents Menu Expand Light mode Dark mode Auto light/dark mode
This is the documentation of ROS 2 PAL OS edge. For ROS 1, please visit the PAL OS 23.12 documentation.
PAL OS 25.01 documentation
Logo
PAL OS 25.01 documentation

Capabilities and API

  • 🏁 Getting started
  • πŸ›  Robot management
  • πŸ“œ Developing applications
  • βš™οΈ Robot hardware
  • πŸ‘‹ Gestures and motions
  • 🧭 Navigation
  • 🦾 Manipulation
  • πŸ‘₯ Social perception
  • πŸ’¬ Communication
  • πŸ˜„ Expressive interactions
  • πŸ’‘ Knowledge and reasoning
  • πŸ–₯️ User interfaces

Reference

  • PAL OS edge Highlights
  • Frequently Asked Questions
  • Glossary
  • Index
  • Index of tutorials
  • 🚧 Demos
  • List of ROS Topics
  • List of ROS Actions
  • List of ROS Services
  • List of ROS Nodes
  • List of ROS Parameters
Back to top

/navigate_through_posesΒΆ

Caution

This documentation page has been auto-generated.

It may be missing some details.

/navigate_through_poses Quick Facts

Category

🧭 Navigation

Message type

nav2_msgs/action/NavigateThroughPoses

Nav2 BT Navigator implemented by the nav2_bt_navigator package. Implements a navigation behavior from a starting point, through many intermediary hard pose constraints, to a final goal, using a specified Behavior Tree.

For more information on this Navigator, check the Nav2 NavigateThroughPoses documentation.

SERVER

  • bt_navigator

Quick snippetsΒΆ

Send a goal from the command-lineΒΆ
$ ros2 action send_goal /navigate_through_poses nav2_msgs/action/NavigateThroughPoses # press Tab to complete the message prototype

How to use in your codeΒΆ

Call the action from a Python scriptΒΆ
#!/usr/bin/env python

import rclpy
from rclpy.action import ActionClient
from rclpy.node import Node

from nav2_msgs.action import NavigateThroughPoses

class NavigateThroughPosesActionClient(Node):

    def __init__(self):
        super().__init__('navigate_through_poses_client')
        self._action_client = ActionClient(self, NavigateThroughPoses, '/navigate_through_poses')

    def send_goal(self, a, b):
        goal_msg = NavigateThroughPoses.Goal()

        # TODO: adapt to the action's parameters
        # check https://docs.ros2.org/latest/api/nav2_msgs/action/NavigateThroughPoses.html
        # for the possible goal parameters
        # goal_msg.a = a
        # goal_msg.b = b

        self._action_client.wait_for_server()

        return self._action_client.send_goal_async(goal_msg)

if __name__ == '__main__':
    rclpy.init(args=args)

    action_client = NavigateThroughPosesActionClient()

    # TODO: adapt to your action's parameters
    future = action_client.send_goal(a, b)

    rclpy.spin_until_future_complete(action_client, future)

    rclpy.shutdown()
Call the action from a C++ programΒΆ
#include <functional>
#include <future>
#include <memory>
#include <string>
#include <sstream>
#include <chrono>

#include "nav2_msgs/action/navigate_through_poses.hpp"

#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"
#include "rclcpp_components/register_node_macro.hpp"

using namespace std::chrono_literals;
using namespace std;

class NavigateThroughPosesActionClient : public rclcpp::Node
{
public:
  using NavigateThroughPoses = nav2_msgs::action::NavigateThroughPoses;
  using GoalHandleNavigateThroughPoses = rclcpp_action::ClientGoalHandle<NavigateThroughPoses>;

  explicit NavigateThroughPosesActionClient(const rclcpp::NodeOptions & options)
  : Node("navigate_through_poses_action_client", options)
  {
    this->client_ptr_ = rclcpp_action::create_client<NavigateThroughPoses>(
            this,
            "/navigate_through_poses");

    this->timer_ = this->create_wall_timer(
            500ms,
            bind(&NavigateThroughPosesActionClient::send_goal, this));
  }

  void send_goal()
  {
    using namespace std::placeholders;

    this->timer_->cancel();

    if (!this->client_ptr_->wait_for_action_server()) {
      RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");
      rclcpp::shutdown();
    }

    auto goal_msg = NavigateThroughPoses::Goal();

    // check https://docs.ros2.org/latest/api/nav2_msgs/action/NavigateThroughPoses.html
    // for the possible goal parameters
    // goal_msg.... = ...;

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

    auto send_goal_options = rclcpp_action::Client<NavigateThroughPoses>::SendGoalOptions();

    send_goal_options.goal_response_callback =
        bind(&NavigateThroughPosesActionClient::goal_response_callback, this, _1);

    send_goal_options.feedback_callback =
        bind(&NavigateThroughPosesActionClient::feedback_callback, this, _1, _2);

    send_goal_options.result_callback =
        bind(&NavigateThroughPosesActionClient::result_callback, this, _1);


    this->client_ptr_->async_send_goal(goal_msg, send_goal_options);
  }

private:
  rclcpp_action::Client<NavigateThroughPoses>::SharedPtr client_ptr_;
  rclcpp::TimerBase::SharedPtr timer_;

  void goal_response_callback(const GoalHandleNavigateThroughPoses::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 feedback_callback(
      GoalHandleNavigateThroughPoses::SharedPtr,
      const shared_ptr<const NavigateThroughPoses::Feedback> feedback)
  {
    stringstream ss;
    ss << "Next number in sequence received: ";
    for (auto number : feedback->partial_sequence) {
      ss << number << " ";
    }
    RCLCPP_INFO(this->get_logger(), ss.str().c_str());
  }

  void result_callback(const GoalHandleNavigateThroughPoses::WrappedResult & result)
  {
    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;
    }
    stringstream ss;
    ss << "Result received: ";
    for (auto number : result.result->sequence) {
      ss << number << " ";
    }
    RCLCPP_INFO(this->get_logger(), ss.str().c_str());
    rclcpp::shutdown();
  }
};  // class NavigateThroughPosesActionClient


RCLCPP_COMPONENTS_REGISTER_NODE(NavigateThroughPosesActionClient)
Copyright © 2024, PAL Robotics
Made with Sphinx and @pradyunsg's Furo
On this page
  • /navigate_through_poses
    • Quick snippets
    • How to use in your code
πŸ›  Getting support