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); +}