If a port is accessed in the constructor of a node, the autoremapping feature of the SubtreePlus is not working.
Please consider my testcase below which implements a SaySomethingInConstructor which is basically the same node as the SaySomething Node except, that the message port is accessed in the constructor.
The value of this port is written to the blackboard before the tree is generated in the test body.
This feature would be quite useful since the BtActionNode of the Nav2 stack is doing exactly this with the node and the server_timeout port.
class SaySomethingInConstructor : public BT::SyncActionNode
{
public:
SaySomethingInConstructor(const std::string& name, const BT::NodeConfiguration& config)
: BT::SyncActionNode(name, config)
{
auto msg = getInput<std::string>("message");
if (!msg) {
throw BT::RuntimeError("missing required input [message]: ", msg.error());
}
std::cout << "Robot says: " << msg.value() << std::endl;
}
// You must override the virtual function tick()
BT::NodeStatus tick() override
{
std::cout << "tick! " << std::endl;
return BT::NodeStatus::SUCCESS;
}
// It is mandatory to define this static method.
static BT::PortsList providedPorts() { return {BT::InputPort<std::string>("message")}; }
};
TEST(SubTree, SubtreePlusD)
{
BT::NodeConfiguration config;
config.blackboard = BT::Blackboard::create();
static const char* xml_text = R"(
<root main_tree_to_execute = "MainTree" >
<BehaviorTree ID="MainTree">
<Sequence>
<SubTreePlus ID="mySubtree" __autoremap="1" message="{message}"/> <!-- This works -->
<SubTreePlus ID="mySubtree" __autoremap="1"/> <!-- This does not work -->
</Sequence>
</BehaviorTree>
<BehaviorTree ID="mySubtree">
<SaySomethingInConstructor message="{message}" />
</BehaviorTree>
</root> )";
BT::BehaviorTreeFactory factory;
factory.registerNodeType<SaySomethingInConstructor>("SaySomethingInConstructor");
config.blackboard->set("message", "hello");
BT::Tree tree = factory.createTreeFromText(xml_text, config.blackboard);
auto ret = tree.tickRoot();
ASSERT_EQ(ret, BT::NodeStatus::SUCCESS);
}
If a port is accessed in the constructor of a node, the autoremapping feature of the SubtreePlus is not working.
Please consider my testcase below which implements a
SaySomethingInConstructorwhich is basically the same node as theSaySomethingNode except, that themessageport is accessed in the constructor.The value of this port is written to the blackboard before the tree is generated in the test body.
This feature would be quite useful since the
BtActionNodeof the Nav2 stack is doing exactly this with thenodeand theserver_timeoutport.