Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
remove_passed_goals_action.cpp
1 // Copyright (c) 2021 Samsung Research America
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string>
16 #include <memory>
17 #include <limits>
18 
19 #include "nav_msgs/msg/path.hpp"
20 #include "nav2_util/geometry_utils.hpp"
21 #include "nav2_ros_common/tf2_factories.hpp"
22 
23 #include "nav2_behavior_tree/plugins/action/remove_passed_goals_action.hpp"
24 
25 namespace nav2_behavior_tree
26 {
27 
28 RemovePassedGoals::RemovePassedGoals(
29  const std::string & name,
30  const BT::NodeConfiguration & conf)
31 : BT::ActionNodeBase(name, conf),
32  viapoint_achieved_radius_(0.5)
33 {}
34 
35 void RemovePassedGoals::initialize()
36 {
37  getInput("radius", viapoint_achieved_radius_);
38 
39  tf_ = config().blackboard->get<nav2::TransformBuffer::SharedPtr>("tf_buffer");
40  node_ = config().blackboard->get<nav2::LifecycleNode::SharedPtr>("node");
41  clock_ = node_->get_clock();
42  node_->get_parameter("transform_tolerance", transform_tolerance_);
43  transform_staleness_threshold_ = node_->declare_or_get_parameter(
44  "transform_staleness_threshold", 0.0);
45 
46  robot_base_frame_ = BT::deconflictPortAndParamFrame<std::string>(
47  node_, "robot_base_frame", this);
48 }
49 
50 inline BT::NodeStatus RemovePassedGoals::tick()
51 {
52  if (!BT::isStatusActive(status())) {
53  initialize();
54  }
55 
56  nav_msgs::msg::Goals goal_poses;
57  getInput("input_goals", goal_poses);
58 
59  if (goal_poses.goals.empty()) {
60  setOutput("output_goals", goal_poses);
61  return BT::NodeStatus::SUCCESS;
62  }
63 
64  using namespace nav2_util::geometry_utils; // NOLINT
65 
66  geometry_msgs::msg::PoseStamped current_pose;
67  if (!nav2_util::getFreshPose(
68  *tf_, goal_poses.goals[0].header.frame_id, robot_base_frame_, clock_->now(),
69  transform_staleness_threshold_, current_pose))
70  {
71  return BT::NodeStatus::FAILURE;
72  }
73 
74  // get the `waypoint_statuses` vector
75  std::vector<nav2_msgs::msg::WaypointStatus> waypoint_statuses;
76  auto waypoint_statuses_get_res = getInput("input_waypoint_statuses", waypoint_statuses);
77  if (!waypoint_statuses_get_res) {
78  RCLCPP_ERROR_ONCE(node_->get_logger(), "Missing [input_waypoint_statuses] port input!");
79  }
80 
81  double dist_to_goal;
82  while (goal_poses.goals.size() > 1) {
83  dist_to_goal = euclidean_distance(goal_poses.goals[0].pose, current_pose.pose);
84 
85  if (dist_to_goal > viapoint_achieved_radius_) {
86  break;
87  }
88 
89  // mark waypoint statuses before the goal is erased from goals
90  if (waypoint_statuses_get_res) {
91  auto cur_waypoint_index =
92  find_next_matching_goal_in_waypoint_statuses(waypoint_statuses, goal_poses.goals[0]);
93  if (cur_waypoint_index == -1) {
94  RCLCPP_ERROR_ONCE(node_->get_logger(), "Failed to find matching goal in waypoint_statuses");
95  return BT::NodeStatus::FAILURE;
96  }
97  waypoint_statuses[cur_waypoint_index].waypoint_status =
98  nav2_msgs::msg::WaypointStatus::COMPLETED;
99  }
100 
101  goal_poses.goals.erase(goal_poses.goals.begin());
102  }
103 
104  setOutput("output_goals", goal_poses);
105  // set `waypoint_statuses` output
106  setOutput("output_waypoint_statuses", waypoint_statuses);
107 
108  return BT::NodeStatus::SUCCESS;
109 }
110 
111 } // namespace nav2_behavior_tree
112 
113 #include "behaviortree_cpp/bt_factory.h"
114 BT_REGISTER_NODES(factory)
115 {
116  factory.registerNodeType<nav2_behavior_tree::RemovePassedGoals>("RemovePassedGoals");
117 }
A BT::ActionNodeBase that removes goals that the robot passed near to.