Skip to content

Commit 88df146

Browse files
committed
fis issue #592
1 parent 7463c73 commit 88df146

File tree

4 files changed

+124
-13
lines changed

4 files changed

+124
-13
lines changed

include/behaviortree_cpp/blackboard.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ class Blackboard
6363

6464
void enableAutoRemapping(bool remapping);
6565

66-
[[nodiscard]] const Entry* getEntry(const std::string& key) const;
66+
[[nodiscard]] const std::shared_ptr<Entry> getEntry(const std::string& key) const;
6767

68-
[[nodiscard]] Entry* getEntry(const std::string& key);
68+
[[nodiscard]] std::shared_ptr<Blackboard::Entry> getEntry(const std::string& key);
6969

7070
[[nodiscard]] AnyPtrLocked getAnyLocked(const std::string& key);
7171

include/behaviortree_cpp/scripting/operators.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ struct ExprAssignment : ExprBase
359359
}
360360
const auto& key = varname->name;
361361

362-
Blackboard::Entry* entry = env.vars->getEntry(key);
362+
auto entry = env.vars->getEntry(key);
363363
if( !entry )
364364
{
365365
// variable doesn't exist, create it if using operator assign_create

src/blackboard.cpp

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ void Blackboard::enableAutoRemapping(bool remapping)
88
autoremapping_ = remapping;
99
}
1010

11-
Blackboard::Entry *Blackboard::getEntry(const std::string &key)
12-
{
13-
// "Avoid Duplication in const and Non-const Member Function,"
14-
// on p. 23, in Item 3 "Use const whenever possible," in Effective C++, 3d ed
15-
return const_cast<Entry*>( static_cast<const Blackboard &>(*this).getEntry(key));
16-
}
17-
1811
AnyPtrLocked Blackboard::getAnyLocked(const std::string &key)
1912
{
2013
if(auto entry = getEntry(key))
@@ -43,13 +36,67 @@ Any *Blackboard::getAny(const std::string &key)
4336
return const_cast<Any*>(getAnyLocked(key).get());
4437
}
4538

46-
const Blackboard::Entry *Blackboard::getEntry(const std::string &key) const
39+
const std::shared_ptr<Blackboard::Entry> Blackboard::getEntry(const std::string &key) const
4740
{
4841
std::unique_lock<std::mutex> lock(mutex_);
4942
auto it = storage_.find(key);
50-
return (it == storage_.end()) ? nullptr : it->second.get();
43+
if(it != storage_.end()) {
44+
return it->second;
45+
}
46+
// not found. Try autoremapping
47+
if (auto parent = parent_bb_.lock())
48+
{
49+
auto remap_it = internal_to_external_.find(key);
50+
if (remap_it != internal_to_external_.cend())
51+
{
52+
auto const& new_key = remap_it->second;
53+
return parent->getEntry(new_key);
54+
}
55+
if(autoremapping_)
56+
{
57+
return parent->getEntry(key);
58+
}
59+
}
60+
return {};
5161
}
5262

63+
64+
std::shared_ptr<Blackboard::Entry> Blackboard::getEntry(const std::string &key)
65+
{
66+
std::unique_lock<std::mutex> lock(mutex_);
67+
auto it = storage_.find(key);
68+
if(it != storage_.end()) {
69+
return it->second;
70+
}
71+
72+
// not found. Try autoremapping
73+
if (auto parent = parent_bb_.lock())
74+
{
75+
auto remap_it = internal_to_external_.find(key);
76+
if (remap_it != internal_to_external_.cend())
77+
{
78+
auto const& new_key = remap_it->second;
79+
auto entry = parent->getEntry(new_key);
80+
if(entry)
81+
{
82+
storage_.insert({key, entry});
83+
}
84+
return entry;
85+
}
86+
if(autoremapping_)
87+
{
88+
auto entry = parent->getEntry(key);
89+
if(entry)
90+
{
91+
storage_.insert({key, entry});
92+
}
93+
return entry;
94+
}
95+
}
96+
return {};
97+
}
98+
99+
53100
const PortInfo* Blackboard::portInfo(const std::string& key)
54101
{
55102
std::unique_lock<std::mutex> lock(mutex_);

tests/gtest_subtree.cpp

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "behaviortree_cpp/bt_factory.h"
33
#include "../sample_nodes/dummy_nodes.h"
44
#include "../sample_nodes/movebase_node.h"
5+
#include "test_helper.hpp"
56

67
using namespace BT;
78

@@ -306,6 +307,7 @@ class ModifyPose : public BT::SyncActionNode
306307
}
307308
};
308309

310+
309311
TEST(SubTree, StringConversions_Issue530)
310312
{
311313
const char* xml_text = R"(
@@ -327,6 +329,26 @@ TEST(SubTree, StringConversions_Issue530)
327329
tree.tickOnce();
328330
}
329331

332+
class NaughtyNav2Node : public BT::SyncActionNode
333+
{
334+
public:
335+
NaughtyNav2Node(const std::string& name, const BT::NodeConfiguration& config) :
336+
BT::SyncActionNode(name, config)
337+
{
338+
std::cout << "CTOR:" << config.blackboard->get<std::string>("ros_node") << std::endl;
339+
}
340+
341+
BT::NodeStatus tick() override
342+
{
343+
std::cout << "tick:" << config().blackboard->get<std::string>("ros_node") << std::endl;
344+
return BT::NodeStatus::SUCCESS;
345+
}
346+
static BT::PortsList providedPorts()
347+
{
348+
return {};
349+
}
350+
};
351+
330352
TEST(SubTree, SubtreeIssue563)
331353
{
332354
static const char* xml_text = R"(
@@ -352,17 +374,59 @@ TEST(SubTree, SubtreeIssue563)
352374
<Sequence>
353375
<SaySomething message="{the_message}" />
354376
<Script code=" reply:='done' "/>
377+
<NaughtyNav2Node/>
355378
</Sequence>
356379
</BehaviorTree>
357380
358381
</root>)";
359382

360383
BehaviorTreeFactory factory;
361384
factory.registerNodeType<DummyNodes::SaySomething>("SaySomething");
385+
factory.registerNodeType<NaughtyNav2Node>("NaughtyNav2Node");
386+
362387
factory.registerBehaviorTreeFromText(xml_text);
363-
Tree tree = factory.createTree("Tree1");
388+
389+
auto blackboard = BT::Blackboard::create();
390+
blackboard->set<std::string>("ros_node", "nav2_shouldnt_do_this");
391+
392+
Tree tree = factory.createTree("Tree1", blackboard);
364393

365394
auto ret = tree.tickOnce();
366395
ASSERT_EQ(ret, NodeStatus::SUCCESS);
396+
}
397+
367398

399+
TEST(SubTree, SubtreeIssue592)
400+
{
401+
static const char* xml_text = R"(
402+
<root BTCPP_format="4" >
403+
404+
<BehaviorTree ID="Outer_Tree">
405+
<Sequence>
406+
<Script code="variable := 'test'"/>
407+
<SubTree ID="Inner_Tree"
408+
variable="{variable}"
409+
_autoremap="false"/>
410+
</Sequence>
411+
</BehaviorTree>
412+
413+
<BehaviorTree ID="Inner_Tree">
414+
<Sequence>
415+
<TestA _skipIf="variable != 'test'"/>
416+
</Sequence>
417+
</BehaviorTree>
418+
419+
</root>)";
420+
421+
422+
BehaviorTreeFactory factory;
423+
std::array<int, 1> counters;
424+
RegisterTestTick(factory, "Test", counters);
425+
426+
factory.registerBehaviorTreeFromText(xml_text);
427+
Tree tree = factory.createTree("Outer_Tree");
428+
429+
auto ret = tree.tickWhileRunning();
430+
ASSERT_EQ(ret, NodeStatus::SUCCESS);
431+
ASSERT_EQ(counters[0], 1);
368432
}

0 commit comments

Comments
 (0)