Description
Assume a tree consisting of a single Sequence
of StatefulActionNode
nodes, all belonging to class
class TickRemoteTree : public BT::StatefulActionNode
:
<root BTCPP_format="4">
<BehaviorTree ID="tree">
<Sequence>
<TickRemoteTree robot_name="A" var="1"/>
<TickRemoteTree robot_name="B" var="2"/>
<TickRemoteTree robot_name="A" var="10"/>
<TickRemoteTree robot_name="B" var="20"/>
<TickRemoteTree robot_name="A" var="100"/>
<TickRemoteTree robot_name="B" var="200"/>
</Sequence>
</BehaviorTree>
</root>
What I am trying to achieve is execute each TickRemoteTree
action sequentially, that is, make robot A sleep for 1 sec, then wake up, then make robot B sleep for 2 sec, then wake up, then make robot A sleep again for 10 sec, and so on. (Essentially the same thing as #242 (comment))
This tree sends a variable var
to robots A and B by calling a service that they provide. Assume that var
specifies the amount of time each robot should sleep. Since TickRemoteTree
is a StatefulActionNode
, each TickRemoteTree
node returns RUNNING
after being ticked, and execution should not continue further than each node, since all TickRemoteTree
are wrapped inside a Sequence
. After waking up, each robot calls a service called tockFromRemoteTree
that TickRemoteTree
provides, making the node able to escape from a RUNNING state and into a SUCCESS or FAILURE state.
However, it is clear I am misunderstanding some things because what happens in practice is that
- all six constructors get called sequentially
- when the first robot stops sleeping and calls the
tockFromRemoteTree
service with a SUCCESS state, the callbacks of all sixtockFromRemoteTree
services of all six nodes are called, one after another, and - the tree stops running with a SUCCESS state, having only made robot A sleep for 1 sec
It is as though all six nodes are pointers to a single changing object, but I would like to have six different objects.
Is this normal in the way I am structuring it? I cannot tell if the tree needs other types of sequences/decorators or the problem is at the C++ side. If not, how should I approach this given the library's available set of sequences and decorators? Or should I choose a more suitable class than StatefulActionNode
like CoroActionNode
?
EDIT 1
I am now beginning to understand that what is needed is some mix of both RosServiceNode
(I know, it belongs to a separate repository) and StatefulActionNode
, which seem to be complementary because the latter cannot deal with services on its own (at least to my understanding and programming level).
EDIT 2
What can I say.. this is why the RosActionNode
exists. But what if one needed to avoid actions altogether? (actions are unbridgeable between ROS 1 and ROS2). This issue seems to be more appropriate for the BehaviorTree.ROS2 repository so I am closing this issue here.