Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
remove_in_collision_goals_action.cpp
1 // Copyright (c) 2024 Angsa Robotics
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 "nav2_behavior_tree/plugins/action/remove_in_collision_goals_action.hpp"
20 #include "nav2_behavior_tree/bt_utils.hpp"
21 #include "tf2/utils.hpp"
22 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
23 #include "nav2_util/geometry_utils.hpp"
24 
25 namespace nav2_behavior_tree
26 {
27 
29  const std::string & service_node_name,
30  const BT::NodeConfiguration & conf)
31 : BtServiceNode<nav2_msgs::srv::GetCosts>(service_node_name, conf,
32  "/global_costmap/get_cost_global_costmap")
33 {}
34 
35 
37 {
38  getInput("use_footprint", use_footprint_);
39  getInput("cost_threshold", cost_threshold_);
40  getInput("input_goals", input_goals_);
41  getInput("consider_unknown_as_obstacle", consider_unknown_as_obstacle_);
42 
43  if (input_goals_.goals.empty()) {
44  setOutput("output_goals", input_goals_);
45  should_send_request_ = false;
46  return;
47  }
48  request_ = std::make_shared<nav2_msgs::srv::GetCosts::Request>();
49  request_->use_footprint = use_footprint_;
50 
51  for (const auto & goal : input_goals_.goals) {
52  request_->poses.push_back(goal);
53  }
54 }
55 
56 BT::NodeStatus RemoveInCollisionGoals::on_completion(
57  std::shared_ptr<nav2_msgs::srv::GetCosts::Response> response)
58 {
59  if (!response->success) {
60  RCLCPP_ERROR(
61  node_->get_logger(),
62  "GetCosts service call failed");
63  setOutput("output_goals", input_goals_);
64  return BT::NodeStatus::FAILURE;
65  }
66 
67  // get the `waypoint_statuses` vector
68  std::vector<nav2_msgs::msg::WaypointStatus> waypoint_statuses;
69  auto waypoint_statuses_get_res = getInput("input_waypoint_statuses", waypoint_statuses);
70  if (!waypoint_statuses_get_res) {
71  RCLCPP_ERROR(node_->get_logger(), "Missing [input_waypoint_statuses] port input!");
72  }
73 
74  nav_msgs::msg::Goals valid_goal_poses;
75  for (size_t i = 0; i < response->costs.size(); ++i) {
76  if ((response->costs[i] == 255 && !consider_unknown_as_obstacle_) ||
77  response->costs[i] < cost_threshold_)
78  {
79  valid_goal_poses.goals.push_back(input_goals_.goals[i]);
80  } else if (waypoint_statuses_get_res) {
81  using namespace nav2_util::geometry_utils; // NOLINT
82  auto cur_waypoint_index =
83  find_next_matching_goal_in_waypoint_statuses(waypoint_statuses, input_goals_.goals[i]);
84  if (cur_waypoint_index == -1) {
85  RCLCPP_ERROR(node_->get_logger(), "Failed to find matching goal in waypoint_statuses");
86  return BT::NodeStatus::FAILURE;
87  }
88  waypoint_statuses[cur_waypoint_index].waypoint_status =
89  nav2_msgs::msg::WaypointStatus::SKIPPED;
90  }
91  }
92  // Inform if all goals have been removed
93  if (valid_goal_poses.goals.empty()) {
94  RCLCPP_INFO(
95  node_->get_logger(),
96  "All goals are in collision and have been removed from the list");
97  }
98  setOutput("output_goals", valid_goal_poses);
99  // set `waypoint_statuses` output
100  setOutput("output_waypoint_statuses", waypoint_statuses);
101 
102  return BT::NodeStatus::SUCCESS;
103 }
104 
105 } // namespace nav2_behavior_tree
106 
107 #include "behaviortree_cpp/bt_factory.h"
108 BT_REGISTER_NODES(factory)
109 {
110  factory.registerNodeType<nav2_behavior_tree::RemoveInCollisionGoals>("RemoveInCollisionGoals");
111 }
Abstract class representing a service based BT node.
A nav2_behavior_tree::BtServiceNode class that removes goals that are in collision in on the global c...
void on_tick() override
The main override required by a BT service.
RemoveInCollisionGoals(const std::string &service_node_name, const BT::NodeConfiguration &conf)
A constructor for nav2_behavior_tree::RemoveInCollisionGoals.