diff --git a/nav2_bt_navigator/behavior_trees/parallel.xml b/nav2_bt_navigator/behavior_trees/parallel.xml new file mode 100644 index 0000000000000000000000000000000000000000..1f8aa31802569f2e7b0f7882492663d4dbc74624 --- /dev/null +++ b/nav2_bt_navigator/behavior_trees/parallel.xml @@ -0,0 +1,33 @@ +<!-- + This Behavior Tree first computes a path using the global planner (ComputePathToPose). + Then, it runs two sub-branches in parallel. The first sub-branch is a FollowPath + operation (the local planner). In parallel, there is a rate controlled execution of + FollowPath (the global planner). Each time a new path is computed, the path update + is sent to the local planner. The right branch, which is the rate controlled + ComputePathToPose, always returns RUNNING. Because the Parallel node uses a + threshold of 1, whenever the FollowPath returns SUCCESS or FAILURE, the parallel + node will return this result. + + The path endpoints (input to the global planner) and the resulting path (output of + the global planner and input to the local planner) are passed on the blackboard. + + The rate at which the ComputePathToPose operation is invoked can be controlled with + the hz parameter to the RateController node. +--> + +<root main_tree_to_execute="MainTree"> + <BehaviorTree ID="MainTree"> + <SequenceStar name="root"> + <ComputePathToPose endpoints="${endpoints}" path="${path}"/> + <Parallel threshold_M="1"> + <FollowPath path="${path}"/> + <Sequence> + <RateController hz="2"> + <ComputePathToPose endpoints="${endpoints}" path="${path}"/> + </RateController> + <UpdatePath/> + </Sequence> + </Parallel> + </SequenceStar> + </BehaviorTree> +</root> diff --git a/nav2_bt_navigator/behavior_trees/simple_sequential.xml b/nav2_bt_navigator/behavior_trees/simple_sequential.xml new file mode 100644 index 0000000000000000000000000000000000000000..21e740fe1a688d3d882d16de244b5175c0b1dff2 --- /dev/null +++ b/nav2_bt_navigator/behavior_trees/simple_sequential.xml @@ -0,0 +1,16 @@ +<!-- + This Behavior Tree does the bare minimum - it invokes ComputePathToPose to + compute a path using the global planner. It then invokes the local planner + (FollowPath) with this path. The path endpoints (input to the global planner) + and the resulting path (output of the global planner and input to the local + planner) are passed on the blackboard. +--> + +<root main_tree_to_execute="MainTree"> + <BehaviorTree ID="MainTree"> + <SequenceStar name="root"> + <ComputePathToPose endpoints="${endpoints}" path="${path}"/> + <FollowPath path="${path}"/> + </SequenceStar> + </BehaviorTree> +</root> diff --git a/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp b/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp index f9af1c31f09b5d7ca8ca5802691c0085d5264ec0..785c4c6620617a365c7b860783083affd9f20870 100644 --- a/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp +++ b/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp @@ -15,6 +15,7 @@ #ifndef NAV2_BT_NAVIGATOR__BT_NAVIGATOR_HPP_ #define NAV2_BT_NAVIGATOR__BT_NAVIGATOR_HPP_ +#include <string> #include <memory> #include "nav2_tasks/navigate_to_pose_task.hpp" #include "nav2_robot/robot.hpp" @@ -33,6 +34,7 @@ public: private: std::unique_ptr<nav2_robot::Robot> robot_; std::unique_ptr<nav2_tasks::NavigateToPoseTaskServer> task_server_; + std::string bt_xml_filename_; }; } // namespace nav2_bt_navigator diff --git a/nav2_bt_navigator/include/nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp b/nav2_bt_navigator/include/nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp index 378695755f06526be8c3066db5e919a2694a8f94..d6250fd75f7673e6083f6bd96063b4338e306c08 100644 --- a/nav2_bt_navigator/include/nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp +++ b/nav2_bt_navigator/include/nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp @@ -15,8 +15,10 @@ #ifndef NAV2_BT_NAVIGATOR__NAVIGATE_TO_POSE_BEHAVIOR_TREE_HPP_ #define NAV2_BT_NAVIGATOR__NAVIGATE_TO_POSE_BEHAVIOR_TREE_HPP_ +#include <memory> #include "rclcpp/rclcpp.hpp" #include "nav2_tasks/behavior_tree_engine.hpp" +#include "nav2_tasks/follow_path_task.hpp" namespace nav2_bt_navigator { @@ -26,6 +28,11 @@ class NavigateToPoseBehaviorTree : public nav2_tasks::BehaviorTreeEngine public: explicit NavigateToPoseBehaviorTree(rclcpp::Node::SharedPtr node); NavigateToPoseBehaviorTree() = delete; + +private: + // Support for a BT SimpleActionNode that updates the FollowPath task + BT::NodeStatus updatePath(BT::TreeNode & tree_node); + std::unique_ptr<nav2_tasks::FollowPathTaskClient> follow_path_task_client_; }; } // namespace nav2_bt_navigator diff --git a/nav2_bt_navigator/src/bt_navigator.cpp b/nav2_bt_navigator/src/bt_navigator.cpp index 3cc69a499a6c366c27510568ff79d9490f632a8b..8ad0fcbbd53ee76374fdd536f9a10a6d40b5f7c8 100644 --- a/nav2_bt_navigator/src/bt_navigator.cpp +++ b/nav2_bt_navigator/src/bt_navigator.cpp @@ -14,7 +14,8 @@ #include <string> #include <memory> -#include <sstream> +#include <fstream> +#include <streambuf> #include "nav2_bt_navigator/bt_navigator.hpp" #include "nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp" #include "nav2_tasks/compute_path_to_pose_task.hpp" @@ -27,7 +28,7 @@ namespace nav2_bt_navigator { BtNavigator::BtNavigator() -: Node("NavigateToPoseNode") +: Node("BtNavigator") { auto temp_node = std::shared_ptr<rclcpp::Node>(this, [](rclcpp::Node *) {}); @@ -55,35 +56,41 @@ BtNavigator::navigateToPose(const nav2_tasks::NavigateToPoseCommand::SharedPtr c // Create the blackboard that will be shared by all of the nodes in the tree BT::Blackboard::Ptr blackboard = BT::Blackboard::create<BT::BlackboardLocal>(); - // Put together the PathEndPoints message for the ComputePathToPose + // Put together the PathEndPoints message for the ComputePathToPose task auto endpoints = std::make_shared<nav2_tasks::ComputePathToPoseCommand>(); endpoints->start = current->pose.pose; endpoints->goal = command->pose; endpoints->tolerance = 2.0; // TODO(mjeronimo): this will come in the command message - // The path returned from ComputePath and sent to FollowPath + // The path returned from ComputePath and sent to the FollowPath task auto path = std::make_shared<nav2_tasks::ComputePathToPoseResult>(); // Set the shared data (commands/results) blackboard->set<nav2_tasks::ComputePathToPoseCommand::SharedPtr>("endpoints", endpoints); blackboard->set<nav2_tasks::ComputePathToPoseResult::SharedPtr>("path", path); // NOLINT - std::string xml_text = - R"( -<root main_tree_to_execute="MainTree"> - <BehaviorTree ID="MainTree"> - <SequenceStar name="root"> - <ComputePathToPose endpoints="${endpoints}" path="${path}"/> - <FollowPath path="${path}"/> - </SequenceStar> - </BehaviorTree> -</root>)"; + // Get the filename to use from the parameter + get_parameter_or<std::string>("bt_xml_filename", bt_xml_filename_, + std::string("bt_navigator.xml")); - RCLCPP_INFO(get_logger(), "Behavior tree XML: %s", xml_text.c_str()); + // Read the input BT XML file into a string + std::ifstream xml_file(bt_xml_filename_); + + if (!xml_file.good()) { + RCLCPP_ERROR(get_logger(), "Couldn't open input XML file: %s", bt_xml_filename_.c_str()); + return TaskStatus::FAILED; + } + + std::string xml_string((std::istreambuf_iterator<char>(xml_file)), + std::istreambuf_iterator<char>()); + + RCLCPP_INFO(get_logger(), "Behavior Tree file: '%s'", bt_xml_filename_.c_str()); + RCLCPP_INFO(get_logger(), "Behavior Tree XML: %s", xml_string.c_str()); // Create and run the behavior tree NavigateToPoseBehaviorTree bt(shared_from_this()); - TaskStatus result = bt.run(blackboard, xml_text, + + TaskStatus result = bt.run(blackboard, xml_string, std::bind(&nav2_tasks::NavigateToPoseTaskServer::cancelRequested, task_server_.get())); RCLCPP_INFO(get_logger(), "Completed navigation: result: %d", result); diff --git a/nav2_bt_navigator/src/navigate_to_pose_behavior_tree.cpp b/nav2_bt_navigator/src/navigate_to_pose_behavior_tree.cpp index 60cc60d6efd751e137df7204eb538e66e5253af4..3fa8e078f71bbb7a0c210925ad77b48462280771 100644 --- a/nav2_bt_navigator/src/navigate_to_pose_behavior_tree.cpp +++ b/nav2_bt_navigator/src/navigate_to_pose_behavior_tree.cpp @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <memory> #include "rclcpp/rclcpp.hpp" #include "nav2_bt_navigator/navigate_to_pose_behavior_tree.hpp" #include "nav2_tasks/compute_path_to_pose_action.hpp" #include "nav2_tasks/follow_path_action.hpp" +#include "nav2_tasks/rate_controller_node.hpp" using namespace std::chrono_literals; @@ -28,6 +30,27 @@ NavigateToPoseBehaviorTree::NavigateToPoseBehaviorTree(rclcpp::Node::SharedPtr n // Register our custom action nodes so that they can be included in XML description factory_.registerNodeType<nav2_tasks::ComputePathToPoseAction>("ComputePathToPose"); factory_.registerNodeType<nav2_tasks::FollowPathAction>("FollowPath"); + + // Register our custom decorator nodes + factory_.registerNodeType<nav2_tasks::RateController>("RateController"); + + // Register our Simple Action nodes + factory_.registerSimpleAction("UpdatePath", + std::bind(&NavigateToPoseBehaviorTree::updatePath, this, std::placeholders::_1)); + + // The parallel node is not yet registered in the BehaviorTree.CPP library + factory_.registerNodeType<BT::ParallelNode>("Parallel"); + + follow_path_task_client_ = std::make_unique<nav2_tasks::FollowPathTaskClient>(node); +} + +BT::NodeStatus NavigateToPoseBehaviorTree::updatePath(BT::TreeNode & tree_node) +{ + // Get the updated path from the blackboard and send to the FollowPath task server + auto path = tree_node.blackboard()->template get<nav2_tasks::ComputePathToPoseResult::SharedPtr>( + "path"); + follow_path_task_client_->sendUpdate(path); + return BT::NodeStatus::RUNNING; } } // namespace nav2_bt_navigator diff --git a/nav2_dwb_controller/dwb_controller/src/dwb_controller.cpp b/nav2_dwb_controller/dwb_controller/src/dwb_controller.cpp index 01363ddb2cad29f28de3bad43c92d64e33939b26..42c79c01239b5e0541462b1d92a2518fd363da59 100644 --- a/nav2_dwb_controller/dwb_controller/src/dwb_controller.cpp +++ b/nav2_dwb_controller/dwb_controller/src/dwb_controller.cpp @@ -55,6 +55,26 @@ DwbController::~DwbController() TaskStatus DwbController::followPath(const nav2_tasks::FollowPathCommand::SharedPtr command) { +#if 0 + // TODO(mjeronimo): Integrate the following example code into the + // main loop below + + while (true) { + + ... + + if (task_server_->updateRequested()) { + auto new_path = std::make_shared<nav2_tasks::FollowPathCommand>(); + task_server_->getCommandUpdate(new_path); + task_server_->setUpdated(); + + // Update the target path + } + + ... + } +#endif + RCLCPP_INFO(get_logger(), "Starting controller"); try { auto path = nav_2d_utils::pathToPath2D(*command); diff --git a/nav2_simple_navigator/src/simple_navigator.cpp b/nav2_simple_navigator/src/simple_navigator.cpp index 6fc13577649fcc8297be744c2e465b652682960d..f81a1a4241682f63efc8cf2e2417dca17fbee21f 100644 --- a/nav2_simple_navigator/src/simple_navigator.cpp +++ b/nav2_simple_navigator/src/simple_navigator.cpp @@ -40,6 +40,7 @@ SimpleNavigator::SimpleNavigator() controller_client_ = std::make_unique<nav2_tasks::FollowPathTaskClient>(temp_node); task_server_ = std::make_unique<nav2_tasks::NavigateToPoseTaskServer>(temp_node); + task_server_->setExecuteCallback( std::bind(&SimpleNavigator::navigateToPose, this, std::placeholders::_1)); } diff --git a/nav2_tasks/include/nav2_tasks/behavior_tree_engine.hpp b/nav2_tasks/include/nav2_tasks/behavior_tree_engine.hpp index 99de593dd9be10540cfc53c5862dbce1e43e4e11..2c0f30bf423a9a64287591ae419ca2aa7480c6b7 100644 --- a/nav2_tasks/include/nav2_tasks/behavior_tree_engine.hpp +++ b/nav2_tasks/include/nav2_tasks/behavior_tree_engine.hpp @@ -36,7 +36,7 @@ public: BT::Blackboard::Ptr & blackboard, const std::string & behavior_tree_xml, std::function<bool()> cancelRequested, - std::chrono::milliseconds loopTimeout = std::chrono::milliseconds(100)); + std::chrono::milliseconds loopTimeout = std::chrono::milliseconds(10)); protected: // The ROS node to use for any task clients diff --git a/nav2_tasks/include/nav2_tasks/bt_action_node.hpp b/nav2_tasks/include/nav2_tasks/bt_action_node.hpp index ef045a66a2d536df428c2090f4776587d6198c9c..df4e0ff21a1659935c1a09e3cfb9a675db8814a2 100644 --- a/nav2_tasks/include/nav2_tasks/bt_action_node.hpp +++ b/nav2_tasks/include/nav2_tasks/bt_action_node.hpp @@ -52,7 +52,7 @@ public: // as getting values from the shared blackboard. A BT node can't get values // from the blackboard in the constructor since the BT library doesn't set // the blackboard until *after* the tree is build - virtual void init() {} + virtual void onInit() {} BT::NodeStatus tick() override { @@ -69,7 +69,7 @@ public: task_client_ = std::make_unique<nav2_tasks::TaskClient<CommandMsg, ResultMsg>>(node_); // Give the derived class a chance to do some initialization - init(); + onInit(); initialized_ = true; } diff --git a/nav2_tasks/include/nav2_tasks/compute_path_to_pose_action.hpp b/nav2_tasks/include/nav2_tasks/compute_path_to_pose_action.hpp index dfcb898c3cab9206e99b01a27a54c46933fbc198..f95390a7d895b4864627fbf25a8c8548b0feb926 100644 --- a/nav2_tasks/include/nav2_tasks/compute_path_to_pose_action.hpp +++ b/nav2_tasks/include/nav2_tasks/compute_path_to_pose_action.hpp @@ -35,7 +35,7 @@ public: { } - void init() override + void onInit() override { command_ = blackboard()->template get<nav2_tasks::ComputePathToPoseCommand::SharedPtr>("endpoints"); diff --git a/nav2_tasks/include/nav2_tasks/follow_path_action.hpp b/nav2_tasks/include/nav2_tasks/follow_path_action.hpp index d612a5199e18d799dcbe4ad1eb67ae557f1c47b0..bce737fa8ceb65fb6e9d347d3aa88b69a5df9883 100644 --- a/nav2_tasks/include/nav2_tasks/follow_path_action.hpp +++ b/nav2_tasks/include/nav2_tasks/follow_path_action.hpp @@ -32,8 +32,12 @@ public: explicit FollowPathAction(const std::string & action_name) : BtActionNode<FollowPathCommand, FollowPathResult>(action_name) { - // Create the input and output messages - command_ = std::make_shared<nav2_tasks::FollowPathCommand>(); + } + + void onInit() override + { + // Set up the input and output messages + command_ = blackboard()->template get<nav2_tasks::ComputePathToPoseResult::SharedPtr>("path"); result_ = std::make_shared<nav2_tasks::FollowPathResult>(); } }; diff --git a/nav2_tasks/include/nav2_tasks/rate_controller_node.hpp b/nav2_tasks/include/nav2_tasks/rate_controller_node.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ba9316bf991d9a9f71e3f0e9af216cf5f30785d7 --- /dev/null +++ b/nav2_tasks/include/nav2_tasks/rate_controller_node.hpp @@ -0,0 +1,97 @@ +// Copyright (c) 2018 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef NAV2_TASKS__RATE_CONTROLLER_NODE_HPP_ +#define NAV2_TASKS__RATE_CONTROLLER_NODE_HPP_ + +#include <string> +#include <chrono> +#include "behavior_tree_core/decorator_node.h" + +namespace nav2_tasks +{ + +class RateController : public BT::DecoratorNode +{ +public: + RateController(const std::string & name, const BT::NodeParameters & params) + : BT::DecoratorNode(name, params) + { + unsigned int hz = 1; + getParam<unsigned int>("hz", hz); + period_ = 1.0 / hz; + } + + // Any BT node that accepts parameters must provide a requiredNodeParameters method + static const BT::NodeParameters & requiredNodeParameters() + { + static BT::NodeParameters params = {{"hz", "10"}}; + return params; + } + +private: + BT::NodeStatus tick() override; + + std::chrono::time_point<std::chrono::high_resolution_clock> start_; + double period_; +}; + +inline BT::NodeStatus RateController::tick() +{ + if (status() == BT::NodeStatus::IDLE) { + // Reset the starting point since we're starting a new iteration of + // the rate controller (moving from IDLE to RUNNING) + start_ = std::chrono::high_resolution_clock::now(); + } + + setStatus(BT::NodeStatus::RUNNING); + + // Determine how long its been since we've started this iteration + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed = now - start_; + + // Now, get that in seconds + typedef std::chrono::duration<float> float_seconds; + auto seconds = std::chrono::duration_cast<float_seconds>(elapsed); + + // If we've exceed the specified period, execute the child node + if (seconds.count() >= period_) { + const BT::NodeStatus child_state = child_node_->executeTick(); + + switch (child_state) { + case BT::NodeStatus::SUCCESS: + child_node_->setStatus(BT::NodeStatus::IDLE); + RCLCPP_DEBUG(rclcpp::get_logger("RateController"), "seconds.count: %lf", seconds.count()); + + // Reset the timer + start_ = std::chrono::high_resolution_clock::now(); + return BT::NodeStatus::SUCCESS; + + case BT::NodeStatus::RUNNING: + return BT::NodeStatus::RUNNING; + + case BT::NodeStatus::FAILURE: + default: + // We'll try again next time + child_node_->setStatus(BT::NodeStatus::IDLE); + return BT::NodeStatus::RUNNING; + } + } + + return status(); +} + +} // namespace nav2_tasks + +#endif // NAV2_TASKS__RATE_CONTROLLER_NODE_HPP_ diff --git a/nav2_tasks/include/nav2_tasks/task_client.hpp b/nav2_tasks/include/nav2_tasks/task_client.hpp index b5919fd8163d2b9c832b68d9590098d6943fa520..756424c61dc42f94b565f44a13c79f6d423eae25 100644 --- a/nav2_tasks/include/nav2_tasks/task_client.hpp +++ b/nav2_tasks/include/nav2_tasks/task_client.hpp @@ -49,6 +49,7 @@ public: // Create the publishers commandPub_ = node_->create_publisher<CommandMsg>(taskName + "_command"); + updatePub_ = node_->create_publisher<CommandMsg>(taskName + "_update"); cancelPub_ = node_->create_publisher<CancelMsg>(taskName + "_cancel"); // Create the subscribers @@ -72,6 +73,13 @@ public: commandPub_->publish(msg); } + void sendUpdate(const typename CommandMsg::SharedPtr msg) + { + resultReceived_ = false; + statusReceived_ = false; + updatePub_->publish(msg); + } + // An in-flight operation can be canceled void cancel() { @@ -134,7 +142,10 @@ public: if (cvResult_.wait_for(lock, std::chrono::milliseconds(100), [&] {return resultReceived_ == true;})) { - result = resultMsg_; + // Copy only the data, not the pointer since the pointer may have been used in + // a BT blackboard + *result = *resultMsg_; + resultReceived_ = false; return SUCCEEDED; } @@ -199,6 +210,7 @@ protected: // The client's publishers: the command and cancel messages typename rclcpp::Publisher<CommandMsg>::SharedPtr commandPub_; + typename rclcpp::Publisher<CommandMsg>::SharedPtr updatePub_; rclcpp::Publisher<CancelMsg>::SharedPtr cancelPub_; // The client's subscriptions: result, feedback, and status diff --git a/nav2_tasks/include/nav2_tasks/task_server.hpp b/nav2_tasks/include/nav2_tasks/task_server.hpp index f90c4b168df28c965c2a6390006380dd955d332d..3a5e9dcb6906bc080141c7ee71f14a9fb767e9ca 100644 --- a/nav2_tasks/include/nav2_tasks/task_server.hpp +++ b/nav2_tasks/include/nav2_tasks/task_server.hpp @@ -38,13 +38,18 @@ public: : node_(node), workerThread_(nullptr), commandReceived_(false), + updateReceived_(false), cancelReceived_(false), eptr_(nullptr) { std::string taskName = getTaskName<CommandMsg, ResultMsg>(); + commandSub_ = node_->create_subscription<CommandMsg>(taskName + "_command", std::bind(&TaskServer::onCommandReceived, this, std::placeholders::_1)); + updateSub_ = node_->create_subscription<CommandMsg>(taskName + "_update", + std::bind(&TaskServer::onUpdateReceived, this, std::placeholders::_1)); + cancelSub_ = node_->create_subscription<std_msgs::msg::Empty>(taskName + "_cancel", std::bind(&TaskServer::onCancelReceived, this, std::placeholders::_1)); @@ -83,6 +88,21 @@ public: cancelReceived_ = false; } + void getCommandUpdate(typename CommandMsg::SharedPtr & command) + { + *command = *updateMsg_; + } + + bool updateRequested() + { + return updateReceived_; + } + + void setUpdated() + { + updateReceived_ = false; + } + void setResult(const ResultMsg & result) { resultMsg_ = result; @@ -99,6 +119,7 @@ protected: ExecuteCallback execute_callback_; typename CommandMsg::SharedPtr commandMsg_; + typename CommandMsg::SharedPtr updateMsg_; ResultMsg resultMsg_; // These messages are internal to the TaskClient implementation @@ -187,10 +208,8 @@ protected: std::mutex commandMutex_; bool commandReceived_; std::condition_variable cvCommand_; - - // Variables to handle the communication of the cancel request to the execute thread + std::atomic<bool> updateReceived_; std::atomic<bool> cancelReceived_; - std::condition_variable cvCancel_; // The callbacks for our subscribers void onCommandReceived(const typename CommandMsg::SharedPtr msg) @@ -204,14 +223,20 @@ protected: cvCommand_.notify_one(); } + void onUpdateReceived(const typename CommandMsg::SharedPtr msg) + { + updateMsg_ = msg; + updateReceived_ = true; + } + void onCancelReceived(const CancelMsg::SharedPtr /*msg*/) { cancelReceived_ = true; - cvCancel_.notify_one(); } // The subscribers: command and cancel typename rclcpp::Subscription<CommandMsg>::SharedPtr commandSub_; + typename rclcpp::Subscription<CommandMsg>::SharedPtr updateSub_; rclcpp::Subscription<CancelMsg>::SharedPtr cancelSub_; // The publishers for the result from this task diff --git a/nav2_tasks/src/behavior_tree_engine.cpp b/nav2_tasks/src/behavior_tree_engine.cpp index aa3aa0c1f676ef32d8e69d35ca6f3f45755defee..d9d13cd46d0c63c6f414cda6fd96a88c1005ed28 100644 --- a/nav2_tasks/src/behavior_tree_engine.cpp +++ b/nav2_tasks/src/behavior_tree_engine.cpp @@ -40,7 +40,7 @@ TaskStatus BehaviorTreeEngine::run( { // Set a couple values that all of the action nodes expect/require blackboard->set<rclcpp::Node::SharedPtr>("node", node_); - blackboard->set<std::chrono::milliseconds>("node_loop_timeout", std::chrono::milliseconds(100)); // NOLINT + blackboard->set<std::chrono::milliseconds>("node_loop_timeout", std::chrono::milliseconds(10)); // NOLINT // The complete behavior tree that results from parsing the incoming XML. When the tree goes // out of scope, all the nodes are destroyed