Skip to content

Commit 6729fb3

Browse files
committed
Set blackboard bug fix
Previous SetBlackboard action node did not update the sequence id, the timestamp when called on a pre-existing entry. Moreover, it allowed to bypass type checking.
1 parent 2a8a226 commit 6729fb3

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

include/behaviortree_cpp/actions/set_blackboard_node.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class SetBlackboardNode : public SyncActionNode
7878
config().blackboard->createEntry(output_key, src_entry->info);
7979
dst_entry = config().blackboard->getEntry(output_key);
8080
}
81-
dst_entry->value = src_entry->value;
81+
config().blackboard->set(output_key, src_entry->value);
8282
}
8383
else
8484
{

tests/gtest_blackboard.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,75 @@ TEST(BlackboardTest, TimestampedInterface)
654654
ASSERT_EQ(stamp_opt->seq, 2);
655655
ASSERT_GE(stamp_opt->time.count(), nsec_before);
656656
}
657+
658+
TEST(BlackboardTest, SetBlackboard_Upd_Ts_SeqId)
659+
{
660+
BT::BehaviorTreeFactory factory;
661+
662+
const std::string xml_text = R"(
663+
<root BTCPP_format="4">
664+
<BehaviorTree ID="MainTree">
665+
<Sequence>
666+
<Script code="other_point:=first_point" />
667+
<Sleep msec="5" />
668+
<SetBlackboard value="{second_point}" output_key="other_point" />
669+
</Sequence>
670+
</BehaviorTree>
671+
</root> )";
672+
673+
factory.registerBehaviorTreeFromText(xml_text);
674+
auto tree = factory.createTree("MainTree");
675+
auto& blackboard = tree.subtrees.front()->blackboard;
676+
677+
const Point point1 = { 2, 2 };
678+
const Point point2 = { 3, 3 };
679+
blackboard->set("first_point", point1);
680+
blackboard->set("second_point", point2);
681+
682+
tree.tickExactlyOnce();
683+
const auto entry_ptr = blackboard->getEntry("other_point");
684+
const auto ts1 = entry_ptr->stamp;
685+
const auto seq_id1 = entry_ptr->sequence_id;
686+
std::this_thread::sleep_for(std::chrono::milliseconds{5});
687+
tree.tickExactlyOnce();
688+
const auto ts2 = entry_ptr->stamp;
689+
const auto seq_id2 = entry_ptr->sequence_id;
690+
691+
ASSERT_GT(ts2.count(), ts1.count());
692+
ASSERT_GT(seq_id2, seq_id1);
693+
}
694+
695+
TEST(BlackboardTest, SetBlackboard_ChangeType)
696+
{
697+
BT::BehaviorTreeFactory factory;
698+
699+
const std::string xml_text = R"(
700+
<root BTCPP_format="4">
701+
<BehaviorTree ID="MainTree">
702+
<Sequence>
703+
<SetBlackboard value="{first_point}" output_key="other_point" />
704+
<Sleep msec="5" />
705+
<SetBlackboard value="{random_str}" output_key="other_point" />
706+
</Sequence>
707+
</BehaviorTree>
708+
</root> )";
709+
710+
factory.registerBehaviorTreeFromText(xml_text);
711+
auto tree = factory.createTree("MainTree");
712+
auto& blackboard = tree.subtrees.front()->blackboard;
713+
714+
const Point point = { 2, 7 };
715+
blackboard->set("first_point", point);
716+
blackboard->set("random_str", "Hello!");
717+
718+
// First tick should succeed
719+
ASSERT_NO_THROW(tree.tickExactlyOnce());
720+
const auto entry_ptr = blackboard->getEntry("other_point");
721+
std::this_thread::sleep_for(std::chrono::milliseconds{5});
722+
// Second tick should throw due to type mismatch
723+
EXPECT_THROW({
724+
tree.tickExactlyOnce();
725+
}, BT::LogicError);
726+
// EXPECT_EQ();
727+
728+
}

0 commit comments

Comments
 (0)