Open
Description
Describe the bug
In the following behavior tree, AlwaysRunning never succeeds even when _successIf="my_var != 0"
evaluates to true. (AlwaysRunning is a StatefulActionNode that always returns RUNNING; Echo just prints the variable; full repro below):
<root BTCPP_format="4">
<BehaviorTree ID="MainTree">
<Sequence name="root">
<Script code="my_var := 0; loop := 0"/>
<ReactiveSequence>
<Script code="loop += 1; my_var = (loop >= 3) ? 42 : 0"/>
<Echo message="{my_var}"/>
<AlwaysRunning _successIf="my_var != 0"/>
</ReactiveSequence>
</Sequence>
</BehaviorTree>
</root>
I would expect AlwaysRunning to return SUCCESS on the 3rd iteration, once my_var is set to 42, but the precondition never hits:
[1738296607.060]: root IDLE -> RUNNING
[1738296607.060]: Script IDLE -> SUCCESS
[1738296607.060]: ReactiveSequence IDLE -> RUNNING
[1738296607.060]: Script IDLE -> SUCCESS
ECHO: 0
[1738296607.060]: Echo IDLE -> SUCCESS
[1738296607.060]: AlwaysRunning IDLE -> RUNNING
[1738296607.060]: Script SUCCESS -> IDLE
[1738296607.060]: Echo SUCCESS -> IDLE
[1738296607.070]: Script IDLE -> SUCCESS
ECHO: 0
[1738296607.070]: Echo IDLE -> SUCCESS
[1738296607.070]: Script SUCCESS -> IDLE
[1738296607.070]: Echo SUCCESS -> IDLE
[1738296607.081]: Script IDLE -> SUCCESS
ECHO: 42
[1738296607.081]: Echo IDLE -> SUCCESS
[1738296607.081]: Script SUCCESS -> IDLE
[1738296607.081]: Echo SUCCESS -> IDLE
[1738296607.091]: Script IDLE -> SUCCESS
ECHO: 42
[1738296607.091]: Echo IDLE -> SUCCESS
[1738296607.091]: Script SUCCESS -> IDLE
[1738296607.091]: Echo SUCCESS -> IDLE
ad nauseam
How to Reproduce
#include <behaviortree_cpp/action_node.h>
#include <behaviortree_cpp/bt_factory.h>
#include <behaviortree_cpp/loggers/bt_cout_logger.h>
static const char* xml_text = R"(
<root BTCPP_format="4">
<BehaviorTree ID="MainTree">
<Sequence name="root">
<Script code="my_var := 0; loop := 0"/>
<ReactiveSequence>
<Script code="loop += 1; my_var = (loop >= 3) ? 42 : 0"/>
<Echo message="{my_var}"/>
<AlwaysRunning _successIf="my_var != 0"/>
</ReactiveSequence>
</Sequence>
</BehaviorTree>
</root>
)";
class AlwaysRunning : public BT::StatefulActionNode
{
public:
AlwaysRunning(const std::string& name) : StatefulActionNode(name, {})
{
}
private:
BT::NodeStatus onStart() override
{
return BT::NodeStatus::RUNNING;
}
BT::NodeStatus onRunning() override
{
return BT::NodeStatus::RUNNING;
}
void onHalted() override
{
}
};
class Echo : public BT::SyncActionNode
{
public:
Echo(const std::string& name, const BT::NodeConfig& config) : BT::SyncActionNode(name, config)
{
}
static BT::PortsList providedPorts()
{
return { BT::InputPort<std::string>("message") };
}
BT::NodeStatus tick() override
{
auto msg = getInput<int>("message");
if (!msg)
{
throw BT::RuntimeError("missing required input [message]: ", msg.error());
}
std::cout << "ECHO: " << msg.value() << std::endl;
return BT::NodeStatus::SUCCESS;
}
};
int main()
{
BT::BehaviorTreeFactory factory;
factory.registerNodeType<AlwaysRunning>("AlwaysRunning");
factory.registerNodeType<Echo>("Echo");
auto tree = factory.createTreeFromText(xml_text);
BT::StdCoutLogger logger(tree);
tree.tickWhileRunning();
return 0;
}
Metadata
Metadata
Assignees
Labels
No labels