20 #include "behaviortree_cpp/decorator_node.h"
22 #include "nav2_behavior_tree/plugins/decorator/goal_updater_node.hpp"
24 #include "rclcpp/callback_group.hpp"
25 #include "rclcpp/logging.hpp"
26 #include "rclcpp/time.hpp"
28 namespace nav2_behavior_tree
31 using std::placeholders::_1;
34 const std::string & name,
35 const BT::NodeConfiguration & conf)
36 : BT::DecoratorNode(name, conf),
37 goal_updater_topic_(
"goal_update"),
38 goals_updater_topic_(
"goals_update")
42 config().blackboard->template get<std::chrono::milliseconds>(
"bt_loop_duration");
45 void GoalUpdater::initialize()
47 createROSInterfaces();
50 void GoalUpdater::createROSInterfaces()
52 node_ = config().blackboard->get<nav2::LifecycleNode::SharedPtr>(
"node");
53 callback_group_ = node_->create_callback_group(
54 rclcpp::CallbackGroupType::MutuallyExclusive,
56 callback_group_executor_.add_callback_group(callback_group_, node_->get_node_base_interface());
58 std::string goal_updater_topic_new;
59 std::string goals_updater_topic_new;
60 node_->get_parameter_or<std::string>(
"goal_updater_topic", goal_updater_topic_new,
"goal_update");
61 node_->get_parameter_or<std::string>(
62 "goals_updater_topic", goals_updater_topic_new,
66 if (goal_updater_topic_new != goal_updater_topic_ || !goal_sub_) {
67 goal_updater_topic_ = goal_updater_topic_new;
68 goal_sub_ = node_->create_subscription<geometry_msgs::msg::PoseStamped>(
70 std::bind(&GoalUpdater::callback_updated_goal,
this, _1),
74 if (goals_updater_topic_new != goals_updater_topic_ || !goals_sub_) {
75 goals_updater_topic_ = goals_updater_topic_new;
76 goals_sub_ = node_->create_subscription<nav_msgs::msg::Goals>(
78 std::bind(&GoalUpdater::callback_updated_goals,
this, _1),
84 inline BT::NodeStatus GoalUpdater::tick()
86 if (!BT::isStatusActive(status())) {
90 geometry_msgs::msg::PoseStamped goal;
91 nav_msgs::msg::Goals goals;
93 getInput(
"input_goal", goal);
94 getInput(
"input_goals", goals);
96 callback_group_executor_.spin_all(bt_loop_duration_);
98 if (last_goal_received_set_) {
99 if (last_goal_received_.header.stamp == builtin_interfaces::msg::Time{}) {
102 node_->get_logger(),
"The received goal has no timestamp. Ignoring.");
103 setOutput(
"output_goal", goal);
105 auto last_goal_received_time = rclcpp::Time(last_goal_received_.header.stamp);
106 auto goal_time = rclcpp::Time(goal.header.stamp);
107 if (last_goal_received_time >= goal_time) {
108 setOutput(
"output_goal", last_goal_received_);
111 node_->get_logger(),
"The timestamp of the received goal (%f) is older than the "
112 "current goal (%f). Ignoring the received goal.",
113 last_goal_received_time.seconds(), goal_time.seconds());
114 setOutput(
"output_goal", goal);
118 setOutput(
"output_goal", goal);
121 if (last_goals_received_set_) {
122 if (last_goals_received_.goals.empty()) {
123 setOutput(
"output_goals", goals);
124 }
else if (last_goals_received_.header.stamp == builtin_interfaces::msg::Time{}) {
126 node_->get_logger(),
"The received goals array has no timestamp. Ignoring.");
127 setOutput(
"output_goals", goals);
129 auto last_goals_received_time = rclcpp::Time(last_goals_received_.header.stamp);
130 auto goals_time = rclcpp::Time(goals.header.stamp);
131 if (last_goals_received_time >= goals_time) {
132 setOutput(
"output_goals", last_goals_received_);
135 node_->get_logger(),
"The timestamp of the received goals (%f) is older than the "
136 "current goals (%f). Ignoring the received goals.",
137 last_goals_received_time.seconds(), goals_time.seconds());
138 setOutput(
"output_goals", goals);
142 setOutput(
"output_goals", goals);
145 return child_node_->executeTick();
149 GoalUpdater::callback_updated_goal(
const geometry_msgs::msg::PoseStamped::ConstSharedPtr & msg)
151 last_goal_received_ = *msg;
152 last_goal_received_set_ =
true;
156 GoalUpdater::callback_updated_goals(
const nav_msgs::msg::Goals::ConstSharedPtr & msg)
158 last_goals_received_ = *msg;
159 last_goals_received_set_ =
true;
164 #include "behaviortree_cpp/bt_factory.h"
165 BT_REGISTER_NODES(factory)
A QoS profile for standard reliable topics with a history of 10 messages.
A BT::DecoratorNode that subscribes to a goal topic and updates the current goal on the blackboard.
GoalUpdater(const std::string &xml_tag_name, const BT::NodeConfiguration &conf)
A constructor for nav2_behavior_tree::GoalUpdater.