@@ -147,7 +147,13 @@ class FibonacciAction : public nav2_behavior_tree::BtActionNode<test_msgs::actio
147147
148148 BT::NodeStatus on_cancelled () override
149149 {
150- config ().blackboard ->set (" sequence" , result_.result ->sequence );
150+ // Check if result is available before accessing it
151+ if (result_.result ) {
152+ config ().blackboard ->set (" sequence" , result_.result ->sequence );
153+ } else {
154+ // Set empty sequence if no result available
155+ config ().blackboard ->set (" sequence" , std::vector<int >());
156+ }
151157 config ().blackboard ->set (" on_cancelled_triggered" , true );
152158 return BT::NodeStatus::SUCCESS;
153159 }
@@ -486,6 +492,94 @@ TEST_F(BTActionNodeTestFixture, test_server_cancel)
486492 // is at least 1000000 x 50 ms
487493 EXPECT_EQ (ticks, 7 );
488494}
495+ TEST_F (BTActionNodeTestFixture, test_run_id_initialization_and_persistence)
496+ {
497+ // create tree with is_global="true" to enable RunID checking
498+ std::string xml_txt =
499+ R"(
500+ <root BTCPP_format="4">
501+ <BehaviorTree ID="MainTree">
502+ <Fibonacci order="100" is_global="true" />
503+ </BehaviorTree>
504+ </root>)" ;
505+
506+ config_->blackboard ->set <std::chrono::milliseconds>(" server_timeout" , 200ms);
507+ config_->blackboard ->set <std::chrono::milliseconds>(" bt_loop_duration" , 10ms);
508+
509+ // Set initial RunID
510+ config_->blackboard ->set <uint64_t >(" run_id" , 1 );
511+
512+ tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText (xml_txt, config_->blackboard ));
513+ action_server_->setHandleGoalSleepDuration (2ms);
514+ action_server_->setServerLoopRate (50ms); // Slower server rate
515+
516+ // First tick should initialize with run_id = 1
517+ auto result = tree_->tickOnce ();
518+ EXPECT_EQ (result, BT::NodeStatus::RUNNING);
519+
520+ // Subsequent ticks with same RunID should continue without re-initialization
521+ result = tree_->tickOnce ();
522+ EXPECT_EQ (result, BT::NodeStatus::RUNNING);
523+
524+ // Clean up by halting the tree
525+ tree_->haltTree ();
526+ }
527+
528+ TEST_F (BTActionNodeTestFixture, test_run_id_changes_trigger_reinitialization)
529+ {
530+ std::string xml_txt =
531+ R"(
532+ <root BTCPP_format="4">
533+ <BehaviorTree ID="MainTree">
534+ <Fibonacci order="50" is_global="true" />
535+ </BehaviorTree>
536+ </root>)" ;
537+
538+ config_->blackboard ->set <std::chrono::milliseconds>(" server_timeout" , 200ms);
539+ config_->blackboard ->set <std::chrono::milliseconds>(" bt_loop_duration" , 10ms);
540+
541+ tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText (xml_txt, config_->blackboard ));
542+ action_server_->setHandleGoalSleepDuration (2ms);
543+ action_server_->setServerLoopRate (50ms);
544+
545+ // Test with multiple run_id changes
546+ for (uint64_t run_id = 1 ; run_id <= 3 ; ++run_id) {
547+ config_->blackboard ->set <uint64_t >(" run_id" , run_id);
548+
549+ // Halt tree to reset state
550+ tree_->haltTree ();
551+
552+ // First tick with new run_id should start new execution
553+ auto result = tree_->tickOnce ();
554+ EXPECT_EQ (result, BT::NodeStatus::RUNNING) << " Failed on run_id: " << run_id;
555+ }
556+
557+ // Final cleanup
558+ tree_->haltTree ();
559+ }
560+
561+ TEST_F (BTActionNodeTestFixture, test_run_id_non_global_mode_unaffected)
562+ {
563+ // Test without is_global flag (should use old behavior)
564+ std::string xml_txt =
565+ R"(
566+ <root BTCPP_format="4">
567+ <BehaviorTree ID="MainTree">
568+ <Fibonacci order="2" />
569+ </BehaviorTree>
570+ </root>)" ;
571+
572+ config_->blackboard ->set <std::chrono::milliseconds>(" server_timeout" , 20ms);
573+ config_->blackboard ->set <std::chrono::milliseconds>(" bt_loop_duration" , 10ms);
574+
575+ tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText (xml_txt, config_->blackboard ));
576+ action_server_->setHandleGoalSleepDuration (2ms);
577+ action_server_->setServerLoopRate (10ns);
578+
579+ // Should work normally without RunID checking
580+ auto result = tree_->tickOnce ();
581+ EXPECT_EQ (result, BT::NodeStatus::RUNNING);
582+ }
489583
490584int main (int argc, char ** argv)
491585{
0 commit comments