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