From 5ec2e9bf8fcb54e22944b3b573b63abe8dd5ca51 Mon Sep 17 00:00:00 2001 From: Tony Najjar Date: Sat, 4 Apr 2026 11:29:24 +0000 Subject: [PATCH 1/3] Add support for custom sleep override function in Tree class Signed-off-by: Tony Najjar --- include/behaviortree_cpp/bt_factory.h | 16 ++++++++++++++++ src/bt_factory.cpp | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/include/behaviortree_cpp/bt_factory.h b/include/behaviortree_cpp/bt_factory.h index 242fa17fc..e859cfde3 100644 --- a/include/behaviortree_cpp/bt_factory.h +++ b/include/behaviortree_cpp/bt_factory.h @@ -122,6 +122,13 @@ class Tree [[nodiscard]] TreeNode* rootNode() const; + /// Function signature for a custom sleep override. + /// The function receives the desired sleep duration and a reference to the + /// WakeUpSignal so it can check for early wake-up. + /// Return true if woken up before the timeout, false if the full duration elapsed. + using SleepOverrideFunc = + std::function; + /** * @brief Sleep for a certain amount of time. This sleep could be interrupted by the methods * TreeNode::emitWakeUpSignal() or Tree::emitWakeUpSignal() @@ -137,6 +144,14 @@ class Tree */ void emitWakeUpSignal(); + /** + * @brief Set a custom sleep override function. When set, Tree::sleep() + * will delegate to this function instead of using the default + * WakeUpSignal::waitFor(). This allows integrating with external clock + * sources (e.g. ROS sim time) while preserving wake-up signal support. + */ + void setSleepOverride(SleepOverrideFunc func); + ~Tree(); /// Tick the root of the tree once, even if a node invoked @@ -196,6 +211,7 @@ class Tree friend class BehaviorTreeFactory; std::shared_ptr wake_up_; + SleepOverrideFunc sleep_override_; enum TickOption { diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp index 42cf43307..ce554c6d3 100644 --- a/src/bt_factory.cpp +++ b/src/bt_factory.cpp @@ -655,6 +655,10 @@ TreeNode* Tree::rootNode() const bool Tree::sleep(std::chrono::system_clock::duration timeout) { + if(sleep_override_) + { + return sleep_override_(timeout, *wake_up_); + } return wake_up_->waitFor( std::chrono::duration_cast(timeout)); } @@ -664,6 +668,11 @@ void Tree::emitWakeUpSignal() wake_up_->emitSignal(); } +void Tree::setSleepOverride(SleepOverrideFunc func) +{ + sleep_override_ = std::move(func); +} + Tree::~Tree() { haltTree(); From de7390b5d7acded73dde571ef01b8b0b960f11b2 Mon Sep 17 00:00:00 2001 From: Tony Najjar Date: Sat, 4 Apr 2026 12:23:01 +0000 Subject: [PATCH 2/3] lint Signed-off-by: Tony Najjar --- include/behaviortree_cpp/bt_factory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/behaviortree_cpp/bt_factory.h b/include/behaviortree_cpp/bt_factory.h index e859cfde3..2817ede0b 100644 --- a/include/behaviortree_cpp/bt_factory.h +++ b/include/behaviortree_cpp/bt_factory.h @@ -127,7 +127,7 @@ class Tree /// WakeUpSignal so it can check for early wake-up. /// Return true if woken up before the timeout, false if the full duration elapsed. using SleepOverrideFunc = - std::function; + std::function; /** * @brief Sleep for a certain amount of time. This sleep could be interrupted by the methods From e60501df1bf7d117a97a34d689dc9bb9cb848d8e Mon Sep 17 00:00:00 2001 From: Tony Najjar Date: Sun, 5 Apr 2026 19:51:18 +0000 Subject: [PATCH 3/3] version 2 Signed-off-by: Tony Najjar --- include/behaviortree_cpp/bt_factory.h | 18 +++++------------- src/bt_factory.cpp | 8 ++------ 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/include/behaviortree_cpp/bt_factory.h b/include/behaviortree_cpp/bt_factory.h index 2817ede0b..0ba3c86bb 100644 --- a/include/behaviortree_cpp/bt_factory.h +++ b/include/behaviortree_cpp/bt_factory.h @@ -122,13 +122,6 @@ class Tree [[nodiscard]] TreeNode* rootNode() const; - /// Function signature for a custom sleep override. - /// The function receives the desired sleep duration and a reference to the - /// WakeUpSignal so it can check for early wake-up. - /// Return true if woken up before the timeout, false if the full duration elapsed. - using SleepOverrideFunc = - std::function; - /** * @brief Sleep for a certain amount of time. This sleep could be interrupted by the methods * TreeNode::emitWakeUpSignal() or Tree::emitWakeUpSignal() @@ -145,12 +138,12 @@ class Tree void emitWakeUpSignal(); /** - * @brief Set a custom sleep override function. When set, Tree::sleep() - * will delegate to this function instead of using the default - * WakeUpSignal::waitFor(). This allows integrating with external clock - * sources (e.g. ROS sim time) while preserving wake-up signal support. + * @brief Returns the shared WakeUpSignal used by this tree. + * This can be used to check for preemption externally, e.g. when + * implementing custom sleep logic with a different clock source. + * Returns nullptr if the tree has not been initialized yet. */ - void setSleepOverride(SleepOverrideFunc func); + [[nodiscard]] std::shared_ptr wakeUpSignal() const; ~Tree(); @@ -211,7 +204,6 @@ class Tree friend class BehaviorTreeFactory; std::shared_ptr wake_up_; - SleepOverrideFunc sleep_override_; enum TickOption { diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp index ce554c6d3..acd907a31 100644 --- a/src/bt_factory.cpp +++ b/src/bt_factory.cpp @@ -655,10 +655,6 @@ TreeNode* Tree::rootNode() const bool Tree::sleep(std::chrono::system_clock::duration timeout) { - if(sleep_override_) - { - return sleep_override_(timeout, *wake_up_); - } return wake_up_->waitFor( std::chrono::duration_cast(timeout)); } @@ -668,9 +664,9 @@ void Tree::emitWakeUpSignal() wake_up_->emitSignal(); } -void Tree::setSleepOverride(SleepOverrideFunc func) +std::shared_ptr Tree::wakeUpSignal() const { - sleep_override_ = std::move(func); + return wake_up_; } Tree::~Tree()