Skip to content

Commit be4ba1f

Browse files
committed
fix issue #507
1 parent f9b0a88 commit be4ba1f

File tree

4 files changed

+74
-28
lines changed

4 files changed

+74
-28
lines changed

include/behaviortree_cpp/decorators/subtree_node.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,15 @@ namespace BT
5050
class SubTreeNode : public DecoratorNode
5151
{
5252
public:
53-
SubTreeNode(const std::string& instance_name);
53+
SubTreeNode(const std::string& name, const NodeConfig& config);
5454

5555
virtual ~SubTreeNode() override = default;
5656

57+
static PortsList providedPorts();
58+
5759
private:
5860
virtual BT::NodeStatus tick() override;
5961

60-
static PortsList providedPorts()
61-
{
62-
return {InputPort<bool>("_autoremap", false,
63-
"If true, all the ports with the same name will be "
64-
"remapped")};
65-
}
66-
6762
virtual NodeType type() const override final
6863
{
6964
return NodeType::SUBTREE;

src/decorators/subtree_node.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
#include "behaviortree_cpp/decorators/subtree_node.h"
22

3-
BT::SubTreeNode::SubTreeNode(const std::string& instance_name) :
4-
DecoratorNode(instance_name, {})
3+
BT::SubTreeNode::SubTreeNode(const std::string& name,
4+
const NodeConfig &config) :
5+
DecoratorNode(name, config)
56
{
67
setRegistrationID("SubTree");
78
}
89

10+
BT::PortsList BT::SubTreeNode::providedPorts()
11+
{
12+
auto port = PortInfo(PortDirection::INPUT, typeid(bool),
13+
GetAnyFromStringFunctor<bool>());
14+
port.setDefaultValue("false");
15+
port.setDescription("If true, all the ports with the same name "
16+
"will be remapped");
17+
18+
return {{"_autoremap", port}};
19+
}
20+
921
BT::NodeStatus BT::SubTreeNode::tick()
1022
{
1123
NodeStatus prev_status = status();

src/xml_parsing.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,32 @@ TreeNode::Ptr XMLParser::Pimpl::createNodeFromXML(const XMLElement* element,
537537
NodeConfig config;
538538
config.blackboard = blackboard;
539539

540+
//---------------------------------------------
541+
auto AddPrePostConditions = [&](auto& config) {
542+
auto AddCondition = [&](auto& conditions, const char* attr_name, auto ID) {
543+
if (auto script = element->Attribute(attr_name))
544+
{
545+
conditions.insert({ID, std::string(script)});
546+
}
547+
};
548+
AddCondition(config.pre_conditions, "_successIf", PreCond::SUCCESS_IF);
549+
AddCondition(config.pre_conditions, "_failureIf", PreCond::FAILURE_IF);
550+
AddCondition(config.pre_conditions, "_skipIf", PreCond::SKIP_IF);
551+
AddCondition(config.pre_conditions, "_while", PreCond::WHILE_TRUE);
552+
553+
AddCondition(config.post_conditions, "_onSuccess", PostCond::ON_SUCCESS);
554+
AddCondition(config.post_conditions, "_onFailure", PostCond::ON_FAILURE);
555+
AddCondition(config.post_conditions, "_onHalted", PostCond::ON_HALTED);
556+
AddCondition(config.post_conditions, "_post", PostCond::ALWAYS);
557+
};
558+
540559
//---------------------------------------------
541560
TreeNode::Ptr new_node;
542561

543562
if (node_type == NodeType::SUBTREE)
544563
{
545-
new_node = std::make_unique<SubTreeNode>(instance_name);
564+
AddPrePostConditions(config);
565+
new_node = factory.instantiateTreeNode(instance_name, toStr(NodeType::SUBTREE), config);
546566
}
547567
else
548568
{
@@ -638,23 +658,7 @@ TreeNode::Ptr XMLParser::Pimpl::createNodeFromXML(const XMLElement* element,
638658
}
639659
}
640660

641-
auto AddCondition = [&](auto& conditions, const char* attr_name, auto ID) {
642-
if (auto script = element->Attribute(attr_name))
643-
{
644-
conditions.insert({ID, std::string(script)});
645-
}
646-
};
647-
648-
AddCondition(config.pre_conditions, "_successIf", PreCond::SUCCESS_IF);
649-
AddCondition(config.pre_conditions, "_failureIf", PreCond::FAILURE_IF);
650-
AddCondition(config.pre_conditions, "_skipIf", PreCond::SKIP_IF);
651-
AddCondition(config.pre_conditions, "_while", PreCond::WHILE_TRUE);
652-
653-
AddCondition(config.post_conditions, "_onSuccess", PostCond::ON_SUCCESS);
654-
AddCondition(config.post_conditions, "_onFailure", PostCond::ON_FAILURE);
655-
AddCondition(config.post_conditions, "_onHalted", PostCond::ON_HALTED);
656-
AddCondition(config.post_conditions, "_post", PostCond::ALWAYS);
657-
661+
AddPrePostConditions(config);
658662
new_node = factory.instantiateTreeNode(instance_name, type_ID, config);
659663
}
660664

tests/gtest_skipping.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,38 @@ TEST(SkippingLogic, SkipAll)
5858
ASSERT_EQ(counters[2], 0);
5959
ASSERT_EQ(status, NodeStatus::SKIPPED);
6060
}
61+
62+
63+
TEST(SkippingLogic, SkipSubtree)
64+
{
65+
BehaviorTreeFactory factory;
66+
std::array<int, 3> counters;
67+
RegisterTestTick(factory, "Test", counters);
68+
69+
const std::string xml_text = R"(
70+
71+
<root BTCPP_format="4" >
72+
<BehaviorTree ID="main">
73+
<Sequence>
74+
<TestA/>
75+
<Script code=" data:=true "/>
76+
<SubTree ID="sub" _skipIf="data"/>
77+
</Sequence>
78+
</BehaviorTree>
79+
80+
<BehaviorTree ID="sub">
81+
<TestB/>
82+
</BehaviorTree>
83+
</root>)";
84+
85+
factory.registerBehaviorTreeFromText(xml_text);
86+
auto tree = factory.createTree("main");
87+
88+
tree.rootBlackboard()->set("A", 1);
89+
90+
const auto status = tree.tickWhileRunning();
91+
ASSERT_EQ(counters[0], 1);
92+
ASSERT_EQ(counters[1], 0);
93+
ASSERT_EQ(status, NodeStatus::SUCCESS);
94+
}
95+

0 commit comments

Comments
 (0)