diff --git a/src/decorators/delay_node.cpp b/src/decorators/delay_node.cpp
index ea6f82ff2..add38d8a0 100644
--- a/src/decorators/delay_node.cpp
+++ b/src/decorators/delay_node.cpp
@@ -12,7 +12,7 @@ DelayNode::DelayNode(const std::string& name, unsigned milliseconds)
}
DelayNode::DelayNode(const std::string& name, const NodeConfig& config)
- : DecoratorNode(name, config), timer_id_(0), msec_(0)
+ : DecoratorNode(name, config), timer_id_(0), msec_(0), read_parameter_from_ports_(true)
{}
void DelayNode::halt()
diff --git a/tests/gtest_decorator.cpp b/tests/gtest_decorator.cpp
index 0a1d2951f..fea9c9e7d 100644
--- a/tests/gtest_decorator.cpp
+++ b/tests/gtest_decorator.cpp
@@ -220,3 +220,46 @@ TEST(Decorator, RunOnce)
// counters[1] contains the number of times TestB was ticked
ASSERT_EQ(counters[1], 5);
}
+
+// Test for DelayNode with XML: delay_msec port should be honored
+TEST(Decorator, DelayWithXML)
+{
+ BT::BehaviorTreeFactory factory;
+
+ const std::string xml_text = R"(
+
+
+
+
+
+
+ )";
+
+ auto tree = factory.createTreeFromText(xml_text);
+
+ // First tick should return RUNNING (delay not complete)
+ auto start = std::chrono::steady_clock::now();
+ NodeStatus status = tree.tickOnce();
+ ASSERT_EQ(status, NodeStatus::RUNNING);
+
+ // Wait for a short time, still should be RUNNING
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ status = tree.tickOnce();
+ ASSERT_EQ(status, NodeStatus::RUNNING);
+
+ // Poll until the delay completes (with timeout for safety)
+ while(status == NodeStatus::RUNNING)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ status = tree.tickOnce();
+ }
+ auto end = std::chrono::steady_clock::now();
+ auto elapsed = std::chrono::duration_cast(end - start);
+
+ // The child (AlwaysSuccess) should have been executed after the delay
+ ASSERT_EQ(status, NodeStatus::SUCCESS);
+ // Verify that at least ~200ms have passed (with small tolerance for timing jitter)
+ ASSERT_GE(elapsed.count(), 80);
+ // Ensure the test didn't take too long (sanity check)
+ ASSERT_LE(elapsed.count(), 200);
+}