Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a53a95f

Browse files
committed
fix issue BehaviorTree#725 : SetBlackboard can copy entries
1 parent 12f75ea commit a53a95f

File tree

2 files changed

+48
-15
lines changed

2 files changed

+48
-15
lines changed

include/behaviortree_cpp/actions/set_blackboard_node.h

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ namespace BT
2626
* <SetBlackboard value="42" output_key="the_answer" />
2727
*
2828
* Will store the string "42" in the entry with key "the_answer".
29+
*
30+
* Alternatively, you can use it to copy one port inside another port:
31+
*
32+
* <SetBlackboard value="{src_port}" output_key="dst_port" />
33+
*
34+
* This will copy the type and content of {src_port} into {dst_port}
2935
*/
3036
class SetBlackboard : public SyncActionNode
3137
{
@@ -46,17 +52,36 @@ class SetBlackboard : public SyncActionNode
4652
private:
4753
virtual BT::NodeStatus tick() override
4854
{
49-
std::string key, value;
50-
if (!getInput("output_key", key))
55+
std::string output_key;
56+
if (!getInput("output_key", output_key))
5157
{
5258
throw RuntimeError("missing port [output_key]");
5359
}
54-
if (!getInput("value", value))
60+
61+
const std::string value_str = config().input_ports.at("value");
62+
63+
StringView stripped_key;
64+
if(isBlackboardPointer(value_str, &stripped_key))
5565
{
56-
throw RuntimeError("missing port [value]");
57-
}
66+
const auto input_key = std::string(stripped_key);
67+
std::shared_ptr<Blackboard::Entry> src_entry = config().blackboard->getEntry(input_key);
68+
std::shared_ptr<Blackboard::Entry> dst_entry = config().blackboard->getEntry(output_key);
5869

59-
config().blackboard->set(static_cast<std::string>(key), value);
70+
if(!src_entry)
71+
{
72+
throw RuntimeError("Can't find the port referred by [value]");
73+
}
74+
if(!dst_entry)
75+
{
76+
config().blackboard->createEntry(output_key, src_entry->info);
77+
dst_entry = config().blackboard->getEntry(output_key);
78+
}
79+
dst_entry->value = src_entry->value;
80+
}
81+
else
82+
{
83+
config().blackboard->set(output_key, value_str);
84+
}
6085

6186
return NodeStatus::SUCCESS;
6287
}

tests/gtest_blackboard.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -461,29 +461,37 @@ TEST(BlackboardTest, IssueSetBlackboard)
461461
ASSERT_EQ(42, tree.rootBlackboard()->get<int>("value"));
462462
}
463463

464+
struct Point {
465+
double x;
466+
double y;
467+
};
468+
464469
TEST(BlackboardTest, SetBlackboard_Issue725)
465470
{
466471
BT::BehaviorTreeFactory factory;
467472

468473
const std::string xml_text = R"(
469-
<root BTCPP_format="4" >
474+
<root BTCPP_format="4">
470475
<BehaviorTree ID="MainTree">
471-
<Sequence>
472-
<SetBlackboard value="hello world" output_key="value" />
473-
<SetBlackboard value="{value}" output_key="other_value" />
474-
<SaySomething message="{other_value}" />
475-
</Sequence>
476+
<SetBlackboard value="{first_point}" output_key="other_point" />
476477
</BehaviorTree>
477478
</root> )";
478479

479480
factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
480481
factory.registerBehaviorTreeFromText(xml_text);
481482
auto tree = factory.createTree("MainTree");
482-
const auto status = tree.tickWhileRunning();
483+
auto& blackboard = tree.subtrees.front()->blackboard;
484+
485+
const Point point = {2,7};
486+
blackboard->set("first_point", point);
487+
488+
const auto status = tree.tickOnce();
489+
490+
Point other_point = blackboard->get<Point>("other_point");
483491

484492
ASSERT_EQ(status, BT::NodeStatus::SUCCESS);
485-
ASSERT_EQ("hello world", tree.rootBlackboard()->get<std::string>("value"));
486-
ASSERT_EQ("hello world", tree.rootBlackboard()->get<std::string>("other_value"));
493+
ASSERT_EQ(other_point.x, point.x);
494+
ASSERT_EQ(other_point.y, point.y);
487495
}
488496

489497

0 commit comments

Comments
 (0)