Nav2 Navigation Stack - lyrical  lyrical
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  node_->get_parameter("transform_tolerance", transform_tolerance_);
42 
43  robot_base_frame_ = BT::deconflictPortAndParamFrame<std::string>(
44  node_, "robot_base_frame", this);
45 }
46 
47 inline BT::NodeStatus RemovePassedGoals::tick()
48 {
49  if (!BT::isStatusActive(status())) {
50  initialize();
51  }
52 
53  nav_msgs::msg::Goals goal_poses;
54  getInput("input_goals", goal_poses);
55 
56  if (goal_poses.goals.empty()) {
57  setOutput("output_goals", goal_poses);
58  return BT::NodeStatus::SUCCESS;
59  }
60 
61  using namespace nav2_util::geometry_utils; // NOLINT
62 
63  geometry_msgs::msg::PoseStamped current_pose;
64  if (!nav2_util::getCurrentPose(
65  current_pose, *tf_, goal_poses.goals[0].header.frame_id, robot_base_frame_,
66  transform_tolerance_))
67  {
68  return BT::NodeStatus::FAILURE;
69  }
70 
71  // get the `waypoint_statuses` vector
72  std::vector<nav2_msgs::msg::WaypointStatus> waypoint_statuses;
73  auto waypoint_statuses_get_res = getInput("input_waypoint_statuses", waypoint_statuses);
74  if (!waypoint_statuses_get_res) {
75  RCLCPP_ERROR_ONCE(node_->get_logger(), "Missing [input_waypoint_statuses] port input!");
76  }
77 
78  double dist_to_goal;
79  while (goal_poses.goals.size() > 1) {
80  dist_to_goal = euclidean_distance(goal_poses.goals[0].pose, current_pose.pose);
81 
82  if (dist_to_goal > viapoint_achieved_radius_) {
83  break;
84  }
85 
86  // mark waypoint statuses before the goal is erased from goals
87  if (waypoint_statuses_get_res) {
88  auto cur_waypoint_index =
89  find_next_matching_goal_in_waypoint_statuses(waypoint_statuses, goal_poses.goals[0]);
90  if (cur_waypoint_index == -1) {
91  RCLCPP_ERROR_ONCE(node_->get_logger(), "Failed to find matching goal in waypoint_statuses");
92  return BT::NodeStatus::FAILURE;
93  }
94  waypoint_statuses[cur_waypoint_index].waypoint_status =
95  nav2_msgs::msg::WaypointStatus::COMPLETED;
96  }
97 
98  goal_poses.goals.erase(goal_poses.goals.begin());
99  }
100 
101  setOutput("output_goals", goal_poses);
102  // set `waypoint_statuses` output
103  setOutput("output_waypoint_statuses", waypoint_statuses);
104 
105  return BT::NodeStatus::SUCCESS;
106 }
107 
108 } // namespace nav2_behavior_tree
109 
110 #include "behaviortree_cpp/bt_factory.h"
111 BT_REGISTER_NODES(factory)
112 {
113  factory.registerNodeType<nav2_behavior_tree::RemovePassedGoals>("RemovePassedGoals");
114 }
A BT::ActionNodeBase that removes goals that the robot passed near to.