15 #include "nav2_behavior_tree/plugins/condition/is_goal_nearby_condition.hpp"
17 #include "nav2_util/geometry_utils.hpp"
18 #include "nav2_ros_common/tf2_factories.hpp"
19 #include "nav2_util/robot_utils.hpp"
21 namespace nav2_behavior_tree
24 IsGoalNearbyCondition::IsGoalNearbyCondition(
25 const std::string & condition_name,
const BT::NodeConfiguration & conf)
26 : BT::ConditionNode(condition_name, conf), transform_tolerance_(0.1)
28 node_ = config().blackboard->get<nav2::LifecycleNode::SharedPtr>(
"node");
29 clock_ = node_->get_clock();
30 tf_buffer_ = config().blackboard->get<nav2::TransformBuffer::SharedPtr>(
"tf_buffer");
31 node_->get_parameter(
"transform_tolerance", transform_tolerance_);
32 transform_staleness_threshold_ = node_->declare_or_get_parameter(
33 "transform_staleness_threshold", 0.0);
35 global_frame_ = BT::deconflictPortAndParamFrame<std::string>(node_,
"global_frame",
this);
36 robot_base_frame_ = BT::deconflictPortAndParamFrame<std::string>(node_,
"robot_base_frame",
this);
41 nav_msgs::msg::Path new_path;
42 double prox_thr = 0.0;
43 double max_robot_pose_search_dist = -1.0;
44 getInput(
"path", new_path);
45 getInput(
"proximity_threshold", prox_thr);
46 getInput(
"max_robot_pose_search_dist", max_robot_pose_search_dist);
48 if (new_path.poses.empty()) {
49 RCLCPP_WARN(node_->get_logger(),
"Path is empty");
50 return BT::NodeStatus::FAILURE;
53 bool path_pruning =
true;
54 if (max_robot_pose_search_dist < 0.0) {
58 if (!path_pruning || new_path != path_) {
60 closest_pose_detection_begin_ = path_.poses.begin();
63 geometry_msgs::msg::PoseStamped pose;
64 if (!nav2_util::getFreshPose(
65 *tf_buffer_, global_frame_, robot_base_frame_, clock_->now(), transform_staleness_threshold_,
68 RCLCPP_ERROR(node_->get_logger(),
"Failed to get current robot pose");
69 return BT::NodeStatus::FAILURE;
73 geometry_msgs::msg::PoseStamped robot_pose;
74 if (!nav2_util::transformPoseInTargetFrame(
75 pose, robot_pose, *tf_buffer_, path_.header.frame_id))
78 node_->get_logger(),
"Failed to transform robot pose to path frame '%s'",
79 path_.header.frame_id.c_str());
80 return BT::NodeStatus::FAILURE;
83 auto closest_pose_upper_bound = path_.poses.end();
85 closest_pose_upper_bound = nav2_util::geometry_utils::first_after_integrated_distance(
86 closest_pose_detection_begin_, path_.poses.end(), max_robot_pose_search_dist);
92 auto closest_pose_it = nav2_util::geometry_utils::min_by(
93 closest_pose_detection_begin_, closest_pose_upper_bound,
94 [&robot_pose](
const geometry_msgs::msg::PoseStamped & ps) {
95 return nav2_util::geometry_utils::euclidean_distance(robot_pose, ps);
98 closest_pose_detection_begin_ = closest_pose_it;
100 const std::size_t closest_index =
static_cast<std::size_t
>(closest_pose_it - path_.poses.begin());
101 const double remaining_length =
102 nav2_util::geometry_utils::calculate_path_length(path_, closest_index);
104 return (remaining_length < prox_thr) ? BT::NodeStatus::SUCCESS : BT::NodeStatus::FAILURE;
109 #include "behaviortree_cpp/bt_factory.h"
110 BT_REGISTER_NODES(factory)
A BT::ConditionNode that returns SUCCESS when remaining length of the current planned path is less th...
BT::NodeStatus tick() override
The main override required by a BT action.