Skip to content

Commit 563b7a4

Browse files
authored
Merge pull request #7 from ros-navigation/main
Up to date with main
2 parents cef28ac + ed0d59f commit 563b7a4

File tree

92 files changed

+1874
-596
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+1874
-596
lines changed

nav2_behavior_tree/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ list(APPEND plugin_libs nav2_goal_updated_condition_bt_node)
120120
add_library(nav2_is_path_valid_condition_bt_node SHARED plugins/condition/is_path_valid_condition.cpp)
121121
list(APPEND plugin_libs nav2_is_path_valid_condition_bt_node)
122122

123+
add_library(nav2_is_pose_occupied_condition_bt_node SHARED plugins/condition/is_pose_occupied_condition.cpp)
124+
list(APPEND plugin_libs nav2_is_pose_occupied_condition_bt_node)
125+
123126
add_library(nav2_time_expired_condition_bt_node SHARED plugins/condition/time_expired_condition.cpp)
124127
list(APPEND plugin_libs nav2_time_expired_condition_bt_node)
125128

@@ -255,6 +258,9 @@ list(APPEND plugin_libs nav2_compute_and_track_route_bt_node)
255258
add_library(nav2_compute_route_bt_node SHARED plugins/action/compute_route_action.cpp)
256259
list(APPEND plugin_libs nav2_compute_route_bt_node)
257260

261+
add_library(nav2_toggle_collision_monitor_service_bt_node SHARED plugins/action/toggle_collision_monitor_service.cpp)
262+
list(APPEND plugin_libs nav2_toggle_collision_monitor_service_bt_node)
263+
258264
foreach(bt_plugin ${plugin_libs})
259265
target_include_directories(${bt_plugin}
260266
PRIVATE

nav2_behavior_tree/include/nav2_behavior_tree/behavior_tree_engine.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ class BehaviorTreeEngine
8686
const std::string & file_path,
8787
BT::Blackboard::Ptr blackboard);
8888

89+
/**
90+
* @brief Extract BehaviorTree ID from BT file path or BT ID
91+
* @param file_or_id
92+
* @return std::string
93+
*/
94+
std::string extractBehaviorTreeID(const std::string & file_or_id);
95+
96+
/**
97+
* @brief Function to create a BT from a BehaviorTree ID
98+
* @param tree_id BehaviorTree ID
99+
* @param blackboard Blackboard for BT
100+
* @return BT::Tree Created behavior tree
101+
*/
102+
BT::Tree createTree(
103+
const std::string & tree_id,
104+
BT::Blackboard::Ptr blackboard);
105+
89106
/**
90107
* @brief Add Groot2 monitor to publish BT status changes
91108
* @param tree BT to monitor

nav2_behavior_tree/include/nav2_behavior_tree/bt_action_server.hpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,18 @@ class BtActionServer
9999

100100
/**
101101
* @brief Replace current BT with another one
102-
* @param bt_xml_filename The file containing the new BT, uses default filename if empty
103-
* @return bool true if the resulting BT correspond to the one in bt_xml_filename. false
102+
* @param bt_xml_filename_or_id The file containing the new BT, uses default filename if empty or BT ID
103+
* @return bool true if the resulting BT correspond to the one in bt_xml_filename_or_id. false
104104
* if something went wrong, and previous BT is maintained
105105
*/
106106
bool loadBehaviorTree(
107-
const std::string & bt_xml_filename = "");
107+
const std::string & bt_xml_filename_or_id = "");
108+
109+
/** @brief Extract BehaviorTree ID from XML file
110+
* @param filename The file containing the BT
111+
* @return std::string BehaviorTree ID if found, empty string otherwise
112+
*/
113+
std::string extractBehaviorTreeID(const std::string & file_or_id);
108114

109115
/**
110116
* @brief Getter function for BT Blackboard
@@ -119,18 +125,18 @@ class BtActionServer
119125
* @brief Getter function for current BT XML filename
120126
* @return string Containing current BT XML filename
121127
*/
122-
std::string getCurrentBTFilename() const
128+
std::string getCurrentBTFilenameOrID() const
123129
{
124-
return current_bt_xml_filename_;
130+
return current_bt_file_or_id_;
125131
}
126132

127133
/**
128-
* @brief Getter function for default BT XML filename
129-
* @return string Containing default BT XML filename
134+
* @brief Getter function for default BT XML filename or ID
135+
* @return string Containing default BT XML filename or ID
130136
*/
131-
std::string getDefaultBTFilename() const
137+
std::string getDefaultBTFilenameOrID() const
132138
{
133-
return default_bt_xml_filename_;
139+
return default_bt_xml_filename_or_id_;
134140
}
135141

136142
/**
@@ -245,8 +251,8 @@ class BtActionServer
245251
BT::Blackboard::Ptr blackboard_;
246252

247253
// The XML file that contains the Behavior Tree to create
248-
std::string current_bt_xml_filename_;
249-
std::string default_bt_xml_filename_;
254+
std::string current_bt_file_or_id_;
255+
std::string default_bt_xml_filename_or_id_;
250256
std::vector<std::string> search_directories_;
251257

252258
// The wrapper class for the BT functionality
@@ -283,7 +289,7 @@ class BtActionServer
283289
std::chrono::milliseconds wait_for_service_timeout_;
284290

285291
// should the BT be reloaded even if the same xml filename is requested?
286-
bool always_reload_bt_xml_ = false;
292+
bool always_reload_bt_ = false;
287293

288294
// Parameters for Groot2 monitoring
289295
bool enable_groot_monitoring_ = false;

nav2_behavior_tree/include/nav2_behavior_tree/bt_action_server_impl.hpp

Lines changed: 70 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <limits>
2222
#include <memory>
2323
#include <set>
24+
#include <unordered_set>
2425
#include <string>
2526
#include <vector>
2627

@@ -45,7 +46,7 @@ BtActionServer<ActionT, NodeT>::BtActionServer(
4546
OnCompletionCallback on_completion_callback,
4647
const std::vector<std::string> & search_directories)
4748
: action_name_(action_name),
48-
default_bt_xml_filename_(default_bt_xml_filename),
49+
default_bt_xml_filename_or_id_(default_bt_xml_filename),
4950
search_directories_(search_directories),
5051
plugin_lib_names_(plugin_lib_names),
5152
node_(parent),
@@ -60,21 +61,7 @@ BtActionServer<ActionT, NodeT>::BtActionServer(
6061
logger_ = node->get_logger();
6162
clock_ = node->get_clock();
6263

63-
// Declare this node's parameters
64-
if (!node->has_parameter("bt_loop_duration")) {
65-
node->declare_parameter("bt_loop_duration", 10);
66-
}
67-
if (!node->has_parameter("default_server_timeout")) {
68-
node->declare_parameter("default_server_timeout", 20);
69-
}
70-
if (!node->has_parameter("always_reload_bt_xml")) {
71-
node->declare_parameter("always_reload_bt_xml", false);
72-
}
73-
if (!node->has_parameter("wait_for_service_timeout")) {
74-
node->declare_parameter("wait_for_service_timeout", 1000);
75-
}
76-
77-
std::vector<std::string> error_code_name_prefixes = {
64+
std::vector<std::string> default_error_code_name_prefixes = {
7865
"assisted_teleop",
7966
"backup",
8067
"compute_path",
@@ -94,32 +81,26 @@ BtActionServer<ActionT, NodeT>::BtActionServer(
9481
" Please review migration guide and update your configuration.");
9582
}
9683

97-
if (!node->has_parameter("error_code_name_prefixes")) {
98-
const rclcpp::ParameterValue value = node->declare_parameter(
99-
"error_code_name_prefixes",
100-
rclcpp::PARAMETER_STRING_ARRAY);
101-
if (value.get_type() == rclcpp::PARAMETER_NOT_SET) {
102-
std::string error_code_name_prefixes_str;
103-
for (const auto & error_code_name_prefix : error_code_name_prefixes) {
104-
error_code_name_prefixes_str += " " + error_code_name_prefix;
105-
}
106-
RCLCPP_WARN_STREAM(
107-
logger_, "error_code_name_prefixes parameters were not set. Using default values of:"
108-
<< error_code_name_prefixes_str + "\n"
109-
<< "Make sure these match your BT and there are not other sources of error codes you"
110-
"reported to your application");
111-
rclcpp::Parameter error_code_name_prefixes_param("error_code_name_prefixes",
112-
error_code_name_prefixes);
113-
node->set_parameter(error_code_name_prefixes_param);
114-
} else {
115-
error_code_name_prefixes = value.get<std::vector<std::string>>();
116-
std::string error_code_name_prefixes_str;
117-
for (const auto & error_code_name_prefix : error_code_name_prefixes) {
118-
error_code_name_prefixes_str += " " + error_code_name_prefix;
119-
}
120-
RCLCPP_INFO_STREAM(logger_, "Error_code parameters were set to:"
121-
<< error_code_name_prefixes_str);
122-
}
84+
// Declare and get error code name prefixes parameter
85+
error_code_name_prefixes_ = node->declare_or_get_parameter(
86+
"error_code_name_prefixes",
87+
default_error_code_name_prefixes);
88+
89+
// Provide informative logging about error code prefixes
90+
std::string error_code_name_prefixes_str;
91+
for (const auto & error_code_name_prefix : error_code_name_prefixes_) {
92+
error_code_name_prefixes_str += " " + error_code_name_prefix;
93+
}
94+
95+
if (error_code_name_prefixes_ == default_error_code_name_prefixes) {
96+
RCLCPP_WARN_STREAM(
97+
logger_, "error_code_name_prefixes parameters were not set. Using default values of:"
98+
<< error_code_name_prefixes_str + "\n"
99+
<< "Make sure these match your BT and there are not other sources of error codes you"
100+
<< "reported to your application");
101+
} else {
102+
RCLCPP_INFO_STREAM(logger_, "Error_code parameters were set to:"
103+
<< error_code_name_prefixes_str);
123104
}
124105
}
125106

@@ -169,16 +150,17 @@ bool BtActionServer<ActionT, NodeT>::on_configure()
169150
nullptr, std::chrono::milliseconds(500), false);
170151

171152
// Get parameters for BT timeouts
172-
int bt_loop_duration;
173-
node->get_parameter("bt_loop_duration", bt_loop_duration);
174-
bt_loop_duration_ = std::chrono::milliseconds(bt_loop_duration);
175-
int default_server_timeout;
176-
node->get_parameter("default_server_timeout", default_server_timeout);
177-
default_server_timeout_ = std::chrono::milliseconds(default_server_timeout);
178-
int wait_for_service_timeout;
179-
node->get_parameter("wait_for_service_timeout", wait_for_service_timeout);
180-
wait_for_service_timeout_ = std::chrono::milliseconds(wait_for_service_timeout);
181-
node->get_parameter("always_reload_bt_xml", always_reload_bt_xml_);
153+
bt_loop_duration_ = std::chrono::milliseconds(
154+
node->declare_or_get_parameter("bt_loop_duration", 10));
155+
156+
default_server_timeout_ = std::chrono::milliseconds(
157+
node->declare_or_get_parameter("default_server_timeout", 20));
158+
159+
wait_for_service_timeout_ = std::chrono::milliseconds(
160+
node->declare_or_get_parameter("wait_for_service_timeout", 1000));
161+
162+
always_reload_bt_ = node->declare_or_get_parameter(
163+
"always_reload_bt_xml", false);
182164

183165
// Get error code id names to grab off of the blackboard
184166
error_code_name_prefixes_ = node->get_parameter("error_code_name_prefixes").as_string_array();
@@ -204,8 +186,8 @@ template<class ActionT, class NodeT>
204186
bool BtActionServer<ActionT, NodeT>::on_activate()
205187
{
206188
resetInternalError();
207-
if (!loadBehaviorTree(default_bt_xml_filename_)) {
208-
RCLCPP_ERROR(logger_, "Error loading XML file: %s", default_bt_xml_filename_.c_str());
189+
if (!loadBehaviorTree(default_bt_xml_filename_or_id_)) {
190+
RCLCPP_ERROR(logger_, "Error loading BT: %s", default_bt_xml_filename_or_id_.c_str());
209191
return false;
210192
}
211193
action_server_->activate();
@@ -228,7 +210,7 @@ bool BtActionServer<ActionT, NodeT>::on_cleanup()
228210
action_server_.reset();
229211
topic_logger_.reset();
230212
plugin_lib_names_.clear();
231-
current_bt_xml_filename_.clear();
213+
current_bt_file_or_id_.clear();
232214
blackboard_.reset();
233215
bt_->haltAllActions(tree_);
234216
bt_->resetGrootMonitor();
@@ -246,40 +228,49 @@ void BtActionServer<ActionT, NodeT>::setGrootMonitoring(
246228
}
247229

248230
template<class ActionT, class NodeT>
249-
bool BtActionServer<ActionT, NodeT>::loadBehaviorTree(const std::string & bt_xml_filename)
231+
bool BtActionServer<ActionT, NodeT>::loadBehaviorTree(const std::string & bt_xml_filename_or_id)
250232
{
251233
namespace fs = std::filesystem;
252234

253-
// Empty filename is default for backward compatibility
254-
auto filename = bt_xml_filename.empty() ? default_bt_xml_filename_ : bt_xml_filename;
235+
// Empty argument is default for backward compatibility
236+
auto file_or_id =
237+
bt_xml_filename_or_id.empty() ? default_bt_xml_filename_or_id_ : bt_xml_filename_or_id;
255238

256239
// Use previous BT if it is the existing one and always reload flag is not set to true
257-
if (!always_reload_bt_xml_ && current_bt_xml_filename_ == filename) {
258-
RCLCPP_DEBUG(logger_, "BT will not be reloaded as the given xml is already loaded");
240+
if (!always_reload_bt_ && current_bt_file_or_id_ == file_or_id) {
241+
RCLCPP_DEBUG(logger_, "BT will not be reloaded as the given xml or ID is already loaded");
259242
return true;
260243
}
261244

262245
// Reset any existing Groot2 monitoring
263246
bt_->resetGrootMonitor();
264247

265-
std::ifstream xml_file(filename);
266-
if (!xml_file.good()) {
267-
setInternalError(ActionT::Result::FAILED_TO_LOAD_BEHAVIOR_TREE,
268-
"Couldn't open BT XML file: " + filename);
269-
return false;
248+
bool is_bt_id = false;
249+
if ((file_or_id.length() < 4) ||
250+
file_or_id.substr(file_or_id.length() - 4) != ".xml")
251+
{
252+
is_bt_id = true;
270253
}
271254

272-
const auto canonical_main_bt = fs::canonical(filename);
273-
274-
// Register all XML behavior Subtrees found in the given directories
255+
std::unordered_set<std::string> used_bt_id;
275256
for (const auto & directory : search_directories_) {
276257
try {
277258
for (const auto & entry : fs::directory_iterator(directory)) {
278259
if (entry.path().extension() == ".xml") {
279-
// Skip registering the main tree file
280-
if (fs::equivalent(fs::canonical(entry.path()), canonical_main_bt)) {
260+
auto current_bt_id = bt_->extractBehaviorTreeID(entry.path().string());
261+
if (current_bt_id.empty()) {
262+
RCLCPP_ERROR(logger_, "Skipping BT file %s (missing ID)",
263+
entry.path().string().c_str());
281264
continue;
282265
}
266+
auto [it, inserted] = used_bt_id.insert(current_bt_id);
267+
if (!inserted) {
268+
RCLCPP_WARN(
269+
logger_,
270+
"Warning: Duplicate BT IDs found. Make sure to have all BT IDs unique! "
271+
"ID: %s File: %s",
272+
current_bt_id.c_str(), entry.path().string().c_str());
273+
}
283274
bt_->registerTreeFromFile(entry.path().string());
284275
}
285276
}
@@ -289,18 +280,21 @@ bool BtActionServer<ActionT, NodeT>::loadBehaviorTree(const std::string & bt_xml
289280
return false;
290281
}
291282
}
292-
293-
// Try to load the main BT tree
283+
// Try to load the main BT tree (by ID)
294284
try {
295-
tree_ = bt_->createTreeFromFile(filename, blackboard_);
285+
if(!is_bt_id) {
286+
tree_ = bt_->createTreeFromFile(file_or_id, blackboard_);
287+
} else {
288+
tree_ = bt_->createTree(file_or_id, blackboard_);
289+
}
290+
296291
for (auto & subtree : tree_.subtrees) {
297292
auto & blackboard = subtree->blackboard;
298293
blackboard->set("node", client_node_);
299294
blackboard->set<std::chrono::milliseconds>("server_timeout", default_server_timeout_);
300295
blackboard->set<std::chrono::milliseconds>("bt_loop_duration", bt_loop_duration_);
301296
blackboard->set<std::chrono::milliseconds>(
302-
"wait_for_service_timeout",
303-
wait_for_service_timeout_);
297+
"wait_for_service_timeout", wait_for_service_timeout_);
304298
}
305299
} catch (const std::exception & e) {
306300
setInternalError(ActionT::Result::FAILED_TO_LOAD_BEHAVIOR_TREE,
@@ -310,8 +304,7 @@ bool BtActionServer<ActionT, NodeT>::loadBehaviorTree(const std::string & bt_xml
310304

311305
// Optional logging and monitoring
312306
topic_logger_ = std::make_unique<RosTopicLogger>(client_node_, tree_);
313-
314-
current_bt_xml_filename_ = filename;
307+
current_bt_file_or_id_ = file_or_id;
315308

316309
if (enable_groot_monitoring_) {
317310
bt_->addGrootMonitoring(&tree_, groot_server_port_);

0 commit comments

Comments
 (0)