Skip to content

Commit 57a2663

Browse files
committed
Test and fix issue #653: AnyTypeAllowed by default
1 parent 6276766 commit 57a2663

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

include/behaviortree_cpp/actions/set_blackboard_node.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,9 @@ class SetBlackboard : public SyncActionNode
3838

3939
static PortsList providedPorts()
4040
{
41-
return {InputPort("value", "Value represented as a string. convertFromString must be "
42-
"implemented."),
41+
return {InputPort("value", "Value to be written int othe output_key"),
4342
BidirectionalPort("output_key", "Name of the blackboard entry where the "
44-
"value "
45-
"should be written")};
43+
"value should be written")};
4644
}
4745

4846
private:

include/behaviortree_cpp/basic_types.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,28 +357,28 @@ std::pair<std::string, PortInfo> CreatePort(PortDirection direction,
357357
}
358358

359359
//----------
360-
template <typename T = void> [[nodiscard]]
360+
template <typename T = PortInfo::AnyTypeAllowed> [[nodiscard]]
361361
inline std::pair<std::string, PortInfo> InputPort(StringView name,
362362
StringView description = {})
363363
{
364364
return CreatePort<T>(PortDirection::INPUT, name, description);
365365
}
366366

367-
template <typename T = void> [[nodiscard]]
367+
template <typename T = PortInfo::AnyTypeAllowed> [[nodiscard]]
368368
inline std::pair<std::string, PortInfo> OutputPort(StringView name,
369369
StringView description = {})
370370
{
371371
return CreatePort<T>(PortDirection::OUTPUT, name, description);
372372
}
373373

374-
template <typename T = void> [[nodiscard]]
374+
template <typename T = PortInfo::AnyTypeAllowed> [[nodiscard]]
375375
inline std::pair<std::string, PortInfo> BidirectionalPort(StringView name,
376376
StringView description = {})
377377
{
378378
return CreatePort<T>(PortDirection::INOUT, name, description);
379379
}
380380
//----------
381-
template <typename T = void> [[nodiscard]]
381+
template <typename T = PortInfo::AnyTypeAllowed> [[nodiscard]]
382382
inline std::pair<std::string, PortInfo> InputPort(StringView name, const T& default_value,
383383
StringView description)
384384
{
@@ -387,7 +387,7 @@ inline std::pair<std::string, PortInfo> InputPort(StringView name, const T& defa
387387
return out;
388388
}
389389

390-
template <typename T = void> [[nodiscard]]
390+
template <typename T = PortInfo::AnyTypeAllowed> [[nodiscard]]
391391
inline std::pair<std::string, PortInfo> BidirectionalPort(StringView name,
392392
const T& default_value,
393393
StringView description)

include/behaviortree_cpp/blackboard.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,20 @@ class Blackboard
124124
{
125125
// create a new entry
126126
Any new_value(value);
127-
PortInfo new_port(PortDirection::INOUT, new_value.type(),
128-
GetAnyFromStringFunctor<T>());
129127
lock.unlock();
130-
auto entry = createEntryImpl(key, new_port);
128+
std::shared_ptr<Blackboard::Entry> entry;
129+
// if a new generic port is created with a string, it's type should be AnyTypeAllowed
130+
if constexpr (std::is_same_v<std::string, T>)
131+
{
132+
entry = createEntryImpl(key, PortInfo(PortDirection::INOUT));
133+
}
134+
else {
135+
PortInfo new_port(PortDirection::INOUT, new_value.type(),
136+
GetAnyFromStringFunctor<T>());
137+
entry = createEntryImpl(key, new_port);
138+
}
131139
lock.lock();
140+
132141
storage_.insert( {key, entry} );
133142
entry->value = new_value;
134143
}

src/blackboard.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,16 @@ Blackboard::createEntryImpl(const std::string& key, const PortInfo& info)
174174
auto storage_it = storage_.find(key);
175175
if(storage_it != storage_.end())
176176
{
177-
const auto old_type = storage_it->second->port_info.type();
178-
if (old_type != info.type() &&
179-
old_type != typeid(BT::PortInfo::AnyTypeAllowed) &&
180-
info.type() != typeid(BT::PortInfo::AnyTypeAllowed))
177+
const auto& prev_info = storage_it->second->port_info;
178+
if (prev_info.type() != info.type() &&
179+
prev_info.isStronglyTyped() &&
180+
info.isStronglyTyped())
181181
{
182182
auto msg = StrCat("Blackboard entry [", key, "]: once declared, the type of a port"
183-
" shall not change. Previously declared type [", BT::demangle(old_type),
184-
"], current type [", BT::demangle(typeid(info.type())), "]");
183+
" shall not change. Previously declared type [",
184+
BT::demangle(prev_info.type()),
185+
"], current type [",
186+
BT::demangle(info.type()), "]");
185187

186188
throw LogicError(msg);
187189
}

tests/gtest_subtree.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,3 +459,52 @@ TEST(SubTree, Issue623_String_to_Pose2d)
459459
auto tree = factory.createTreeFromText(xml_text);
460460
tree.tickWhileRunning();
461461
}
462+
463+
464+
class Assert : public BT::SyncActionNode
465+
{
466+
public:
467+
Assert(const std::string& name, const BT::NodeConfiguration& config)
468+
: BT::SyncActionNode(name, config) {}
469+
470+
static BT::PortsList providedPorts() {
471+
return {BT::InputPort<bool>("condition")};
472+
}
473+
474+
private:
475+
virtual BT::NodeStatus tick() override {
476+
if (getInput<bool>("condition").value())
477+
return BT::NodeStatus::SUCCESS;
478+
else
479+
return BT::NodeStatus::FAILURE;
480+
}
481+
};
482+
483+
TEST(SubTree, Issue653_SetBlackboard)
484+
{
485+
// clang-format off
486+
487+
static const char* xml_text = R"(
488+
<root main_tree_to_execute = "MainTree" BTCPP_format="4">
489+
<BehaviorTree ID="MainTree">
490+
<Sequence>
491+
<SubTree ID="Init" test="{test}" />
492+
<Assert condition="{test}" />
493+
</Sequence>
494+
</BehaviorTree>
495+
496+
<BehaviorTree ID="Init">
497+
<SetBlackboard output_key="test" value="true"/>
498+
</BehaviorTree>
499+
</root>
500+
)";
501+
502+
// clang-format on
503+
504+
BehaviorTreeFactory factory;
505+
factory.registerNodeType<Assert>("Assert");
506+
auto tree = factory.createTreeFromText(xml_text);
507+
tree.tickWhileRunning();
508+
}
509+
510+

0 commit comments

Comments
 (0)