Skip to content

Commit ee25e83

Browse files
Tony NajjarSteveMacenski
Tony Najjar
authored andcommitted
Fix Goal updater QoS (#3719)
* Fix GoalUpdater QoS * Fixes
1 parent 004058e commit ee25e83

File tree

2 files changed

+86
-18
lines changed

2 files changed

+86
-18
lines changed

nav2_behavior_tree/plugins/decorator/goal_updater_node.cpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ GoalUpdater::GoalUpdater(
4646
sub_option.callback_group = callback_group_;
4747
goal_sub_ = node_->create_subscription<geometry_msgs::msg::PoseStamped>(
4848
goal_updater_topic,
49-
10,
49+
rclcpp::SystemDefaultsQoS(),
5050
std::bind(&GoalUpdater::callback_updated_goal, this, _1),
5151
sub_option);
5252
}
@@ -59,8 +59,17 @@ inline BT::NodeStatus GoalUpdater::tick()
5959

6060
callback_group_executor_.spin_some();
6161

62-
if (rclcpp::Time(last_goal_received_.header.stamp) > rclcpp::Time(goal.header.stamp)) {
63-
goal = last_goal_received_;
62+
if (last_goal_received_.header.stamp != rclcpp::Time(0)) {
63+
auto last_goal_received_time = rclcpp::Time(last_goal_received_.header.stamp);
64+
auto goal_time = rclcpp::Time(goal.header.stamp);
65+
if (last_goal_received_time > goal_time) {
66+
goal = last_goal_received_;
67+
} else {
68+
RCLCPP_WARN(
69+
node_->get_logger(), "The timestamp of the received goal (%f) is older than the "
70+
"current goal (%f). Ignoring the received goal.",
71+
last_goal_received_time.seconds(), goal_time.seconds());
72+
}
6473
}
6574

6675
setOutput("output_goal", goal);

nav2_behavior_tree/test/plugins/decorator/test_goal_updater_node.cpp

+74-15
Original file line numberDiff line numberDiff line change
@@ -95,42 +95,101 @@ TEST_F(GoalUpdaterTestFixture, test_tick)
9595
</root>)";
9696

9797
tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText(xml_txt, config_->blackboard));
98+
auto goal_updater_pub =
99+
node_->create_publisher<geometry_msgs::msg::PoseStamped>("goal_update", 10);
98100

99101
// create new goal and set it on blackboard
100102
geometry_msgs::msg::PoseStamped goal;
101103
goal.header.stamp = node_->now();
102104
goal.pose.position.x = 1.0;
103105
config_->blackboard->set("goal", goal);
104106

105-
// tick until node succeeds
106-
while (tree_->rootNode()->status() != BT::NodeStatus::SUCCESS) {
107-
tree_->rootNode()->executeTick();
108-
}
109-
107+
// tick tree without publishing updated goal and get updated_goal
108+
tree_->rootNode()->executeTick();
110109
geometry_msgs::msg::PoseStamped updated_goal;
111110
config_->blackboard->get("updated_goal", updated_goal);
111+
}
112112

113-
EXPECT_EQ(updated_goal, goal);
113+
TEST_F(GoalUpdaterTestFixture, test_older_goal_update)
114+
{
115+
// create tree
116+
std::string xml_txt =
117+
R"(
118+
<root main_tree_to_execute = "MainTree" >
119+
<BehaviorTree ID="MainTree">
120+
<GoalUpdater input_goal="{goal}" output_goal="{updated_goal}">
121+
<AlwaysSuccess/>
122+
</GoalUpdater>
123+
</BehaviorTree>
124+
</root>)";
125+
126+
tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText(xml_txt, config_->blackboard));
127+
auto goal_updater_pub =
128+
node_->create_publisher<geometry_msgs::msg::PoseStamped>("goal_update", 10);
129+
130+
// create new goal and set it on blackboard
131+
geometry_msgs::msg::PoseStamped goal;
132+
goal.header.stamp = node_->now();
133+
goal.pose.position.x = 1.0;
134+
config_->blackboard->set("goal", goal);
114135

136+
// publish updated_goal older than goal
115137
geometry_msgs::msg::PoseStamped goal_to_update;
116-
goal_to_update.header.stamp = node_->now();
138+
goal_to_update.header.stamp = rclcpp::Time(goal.header.stamp) - rclcpp::Duration(1, 0);
117139
goal_to_update.pose.position.x = 2.0;
118140

141+
goal_updater_pub->publish(goal_to_update);
142+
tree_->rootNode()->executeTick();
143+
geometry_msgs::msg::PoseStamped updated_goal;
144+
config_->blackboard->get("updated_goal", updated_goal);
145+
146+
// expect to succeed and not update goal
147+
EXPECT_EQ(tree_->rootNode()->status(), BT::NodeStatus::SUCCESS);
148+
EXPECT_EQ(updated_goal, goal);
149+
}
150+
151+
TEST_F(GoalUpdaterTestFixture, test_get_latest_goal_update)
152+
{
153+
// create tree
154+
std::string xml_txt =
155+
R"(
156+
<root main_tree_to_execute = "MainTree" >
157+
<BehaviorTree ID="MainTree">
158+
<GoalUpdater input_goal="{goal}" output_goal="{updated_goal}">
159+
<AlwaysSuccess/>
160+
</GoalUpdater>
161+
</BehaviorTree>
162+
</root>)";
163+
164+
tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText(xml_txt, config_->blackboard));
119165
auto goal_updater_pub =
120166
node_->create_publisher<geometry_msgs::msg::PoseStamped>("goal_update", 10);
121167

122-
auto start = node_->now();
123-
while ((node_->now() - start).seconds() < 0.5) {
124-
tree_->rootNode()->executeTick();
125-
goal_updater_pub->publish(goal_to_update);
168+
// create new goal and set it on blackboard
169+
geometry_msgs::msg::PoseStamped goal;
170+
goal.header.stamp = node_->now();
171+
goal.pose.position.x = 1.0;
172+
config_->blackboard->set("goal", goal);
126173

127-
rclcpp::spin_some(node_);
128-
}
174+
// publish updated_goal older than goal
175+
geometry_msgs::msg::PoseStamped goal_to_update_1;
176+
goal_to_update_1.header.stamp = node_->now();
177+
goal_to_update_1.pose.position.x = 2.0;
178+
179+
geometry_msgs::msg::PoseStamped goal_to_update_2;
180+
goal_to_update_2.header.stamp = node_->now();
181+
goal_to_update_2.pose.position.x = 3.0;
129182

183+
goal_updater_pub->publish(goal_to_update_1);
184+
goal_updater_pub->publish(goal_to_update_2);
185+
tree_->rootNode()->executeTick();
186+
geometry_msgs::msg::PoseStamped updated_goal;
130187
config_->blackboard->get("updated_goal", updated_goal);
131188

132-
EXPECT_NE(updated_goal, goal);
133-
EXPECT_EQ(updated_goal, goal_to_update);
189+
// expect to succeed
190+
EXPECT_EQ(tree_->rootNode()->status(), BT::NodeStatus::SUCCESS);
191+
// expect to update goal with latest goal update
192+
EXPECT_EQ(updated_goal, goal_to_update_2);
134193
}
135194

136195
int main(int argc, char ** argv)

0 commit comments

Comments
 (0)