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 tf_buffer_ = config().blackboard->get<nav2::TransformBuffer::SharedPtr>(
"tf_buffer");
30 node_->get_parameter(
"transform_tolerance", transform_tolerance_);
32 global_frame_ = BT::deconflictPortAndParamFrame<std::string>(node_,
"global_frame",
this);
33 robot_base_frame_ = BT::deconflictPortAndParamFrame<std::string>(node_,
"robot_base_frame",
this);
38 nav_msgs::msg::Path new_path;
39 double prox_thr = 0.0;
40 double max_robot_pose_search_dist = -1.0;
41 getInput(
"path", new_path);
42 getInput(
"proximity_threshold", prox_thr);
43 getInput(
"max_robot_pose_search_dist", max_robot_pose_search_dist);
45 if (new_path.poses.empty()) {
46 RCLCPP_WARN(node_->get_logger(),
"Path is empty");
47 return BT::NodeStatus::FAILURE;
50 bool path_pruning =
true;
51 if (max_robot_pose_search_dist < 0.0) {
55 if (!path_pruning || new_path != path_) {
57 closest_pose_detection_begin_ = path_.poses.begin();
60 geometry_msgs::msg::PoseStamped pose;
61 if (!nav2_util::getCurrentPose(
62 pose, *tf_buffer_, global_frame_, robot_base_frame_, transform_tolerance_))
64 RCLCPP_ERROR(node_->get_logger(),
"Failed to get current robot pose");
65 return BT::NodeStatus::FAILURE;
69 geometry_msgs::msg::PoseStamped robot_pose;
70 if (!nav2_util::transformPoseInTargetFrame(
71 pose, robot_pose, *tf_buffer_, path_.header.frame_id))
74 node_->get_logger(),
"Failed to transform robot pose to path frame '%s'",
75 path_.header.frame_id.c_str());
76 return BT::NodeStatus::FAILURE;
79 auto closest_pose_upper_bound = path_.poses.end();
81 closest_pose_upper_bound = nav2_util::geometry_utils::first_after_integrated_distance(
82 closest_pose_detection_begin_, path_.poses.end(), max_robot_pose_search_dist);
88 auto closest_pose_it = nav2_util::geometry_utils::min_by(
89 closest_pose_detection_begin_, closest_pose_upper_bound,
90 [&robot_pose](
const geometry_msgs::msg::PoseStamped & ps) {
91 return nav2_util::geometry_utils::euclidean_distance(robot_pose, ps);
94 closest_pose_detection_begin_ = closest_pose_it;
96 const std::size_t closest_index =
static_cast<std::size_t
>(closest_pose_it - path_.poses.begin());
97 const double remaining_length =
98 nav2_util::geometry_utils::calculate_path_length(path_, closest_index);
100 return (remaining_length < prox_thr) ? BT::NodeStatus::SUCCESS : BT::NodeStatus::FAILURE;
105 #include "behaviortree_cpp/bt_factory.h"
106 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.