Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
path_longer_on_approach.cpp
1 // Copyright (c) 2022 Neobotix GmbH
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 <vector>
18 #include "nav2_util/geometry_utils.hpp"
19 
20 #include "nav2_behavior_tree/plugins/decorator/path_longer_on_approach.hpp"
21 
22 namespace nav2_behavior_tree
23 {
24 
26  const std::string & name,
27  const BT::NodeConfiguration & conf)
28 : BT::DecoratorNode(name, conf)
29 {
30  node_ = config().blackboard->get<rclcpp::Node::SharedPtr>("node");
31 }
32 
33 bool PathLongerOnApproach::isPathUpdated(
34  nav_msgs::msg::Path & new_path,
35  nav_msgs::msg::Path & old_path)
36 {
37  return old_path.poses.size() != 0 &&
38  new_path.poses.size() != 0 &&
39  new_path.poses.size() != old_path.poses.size() &&
40  old_path.poses.back().pose.position == new_path.poses.back().pose.position;
41 }
42 
43 bool PathLongerOnApproach::isRobotInGoalProximity(
44  nav_msgs::msg::Path & old_path,
45  double & prox_leng)
46 {
47  return nav2_util::geometry_utils::calculate_path_length(old_path, 0) < prox_leng;
48 }
49 
50 bool PathLongerOnApproach::isNewPathLonger(
51  nav_msgs::msg::Path & new_path,
52  nav_msgs::msg::Path & old_path,
53  double & length_factor)
54 {
55  return nav2_util::geometry_utils::calculate_path_length(new_path, 0) >
56  length_factor * nav2_util::geometry_utils::calculate_path_length(
57  old_path, 0);
58 }
59 
60 inline BT::NodeStatus PathLongerOnApproach::tick()
61 {
62  getInput("path", new_path_);
63  getInput("prox_len", prox_len_);
64  getInput("length_factor", length_factor_);
65 
66  if (first_time_ == false) {
67  if (old_path_.poses.empty() || new_path_.poses.empty() ||
68  old_path_.poses.back().pose != new_path_.poses.back().pose)
69  {
70  first_time_ = true;
71  }
72  }
73 
74  setStatus(BT::NodeStatus::RUNNING);
75 
76  // Check if the path is updated and valid, compare the old and the new path length,
77  // given the goal proximity and check if the new path is longer
78  if (isPathUpdated(new_path_, old_path_) && isRobotInGoalProximity(old_path_, prox_len_) &&
79  isNewPathLonger(new_path_, old_path_, length_factor_) && !first_time_)
80  {
81  const BT::NodeStatus child_state = child_node_->executeTick();
82  switch (child_state) {
83  case BT::NodeStatus::RUNNING:
84  return child_state;
85  case BT::NodeStatus::SUCCESS:
86  case BT::NodeStatus::FAILURE:
87  old_path_ = new_path_;
88  resetChild();
89  return child_state;
90  default:
91  old_path_ = new_path_;
92  return BT::NodeStatus::FAILURE;
93  }
94  }
95  old_path_ = new_path_;
96  first_time_ = false;
97  return BT::NodeStatus::SUCCESS;
98 }
99 
100 } // namespace nav2_behavior_tree
101 
102 #include "behaviortree_cpp_v3/bt_factory.h"
103 BT_REGISTER_NODES(factory)
104 {
105  factory.registerNodeType<nav2_behavior_tree::PathLongerOnApproach>("PathLongerOnApproach");
106 }
A BT::DecoratorNode that ticks its child everytime when the length of the new path is smaller than th...
PathLongerOnApproach(const std::string &name, const BT::NodeConfiguration &conf)
A constructor for nav2_behavior_tree::PathLongerOnApproach.
BT::NodeStatus tick() override
The main override required by a BT action.