Wake me up! Event-based ticking

Almost at the top of my TODO list, there is a feature that I think some people may like/need.

As anybody knows, you should tick periodically your root node in a loop. My suggestion is to do it a 1 KHz (1 msec sleep between ticks).

Some people (usually those that DO NOT use behavior trees) may criticize this and say: “OMG, this is polling, you tick the entire tree!”.

Of course this misses the point of how ControlNode is implemented and the fact that you will actually poll only a single RUNNING action and the related Conditions in the ReactiveSequence nodes.

Anyway, to finally overcome these criticisms, I am planning to add to the API the ability for a Node to send a “signal” that “something changed” and that the entire tree should be ticked immediately.

Something as simple as method called TreeNode::emitTreeChangedEvent().

In this way, we can claim that BT.CPP is actually event driven (supposing of course that conscienscious users emit the event):

What do you think?

1 Like

We have BT condition nodes which create ROS subscribers to various topics. The callbacks compute and cache the response for the next tick method, making the tick method exceptionally fast. If the tree’s tick frequency is faster than the topic frequency, many of the ticks will return the same result, making for redundant and “wasted” ticks. A way for the ROS subscriber callback to emit a “changed event” seems useful to make the tree more efficient, only ticking when a ROS callback is triggered.

It would also make it more reactive for trees that are ticked at a much lower rate like 10 Hz, as they could additionally tick in reaction to one of these events, before the next period comes around.

As it stands, this could probably be created a std::function<void()> that ticks the tree and placing this onto the blackboard. A BT node could read this from the blackboard and invoke it whenever their internal state has changed, triggering a new tick of the entire tree. A little hacky but could be worth experimenting with.

Implementation wise, do not worry. I know exactly how to implement this in a way that is not hacky and as efficient as the operative system allow me to be (microseconds).

Spoiler alert : using std::condition_variable

Implementation pushed to master and documentation and tutorials updated accordingly!!!

See for instance tutorial 5.

Did you mean tutorial 4?

Both tutorials, actually.
Now that I think about it, I wonder if “wait_for” makes more sense than “sleep”