New Software Release - Py Trees

About

py_trees and py_trees_ros were developed and used on robots at field tests around the world over the course of the last couple of years for Yujin Robot. I’m happy to announce that they’re now document complete with a great list of tutorials and ready to be consumed! A brief list of features:

  • All the bells and whistles’ you’d expect from a comprehensive behaviour tree library
  • Assemble trees in relatively simple and short python scripts
  • Additional ROS behaviours for common ROS operations (subscriber, move_base, …)
  • A ROS behaviour tree manager with status publisher for connection to an rqt monitoring plugin
  • Automatic bagging of the tree status when it changes
  • Replay bags in the rqt monitoring program to identify problems
  • Simple to mock with a robot layer for debugging, testing on CI and as a rapid simulation for use with web application development.

As you can probably infer, there was a focus on making sure we could easily debug problems, especially when they occurred at a remote test site without an engineer (the replay tool especially was very useful). On the other hand, a graphical designer frontend was not prioritised and never eventuated - scripting a python tree remained simple and flexible enough to suit our needs. We also had the trees pass a litmus test of being able to pass the work of building robot-specific behaviours and trees off to interns. It took three iterations of the core libraries to pass that point, but since then there has been negligible change in the core libraries.

Additionally, the trees started being used beyond the scenarios they were originally designed for. The control engineers started shifting all non-reactive control logic to the trees - it was just easier to follow patterns already implemented and to make use of the bagging/visualisation/replay tools, e.g. implementing an entire subtree for initialisation from a composition of context switches (small dyn. reconfigure changes), enabling/disabling of sensors and simple motions instead of having a separate c++ or python node that would handle the entire process as a custom state machine inside an action. Also, as the logic accumulated in the trees, the data to support it also centralised there, and it eventually became the natural portal point between robot and server/web applications.

Availability

All the py_trees packages (py_trees, py_trees_ros, py_trees_msgs, rqt_py_trees) are on the ros build farm and repository details on the ros wiki. You can also use the py_trees package itself directly from pip as a pure python module.

Getting Started

Get started at the py_trees_ros README. If you just want a quick glimpse of how they can be use in ROS, jump directly to the py_trees_ros tutorials.

2 Likes

This is an awesome piece of software and I’m looking forward to trying it.

There are a couple of other implementations of behaviour trees floating around in that other thread, one from @spmaniato and one from @facontidavide. Is there enough interest in trying to unify some of the messages and interfaces so these libraries (especially the tools) can be used together?

Aye, there’s a few floating around. Perhaps I can throw in a bit of a summary. Authors please feel free to embellish/correct me if I get something wrong!

Pat Goebel had the closest thing to what we needed with his pi trees. He was using it for his textbook and while it was a nice start, it was not as comprehensive as we would have liked. I also wanted to build it around python generators, so had a chat with him and decided to take inspiration from what he had and move it forward with py_trees.

@facontidavide was already starting work on his when we started, but there wasn’t much in his repo yet, and was in c++ targeting robot control. A bit orthogonal to our needs.

FlexBE looks great, and honestly I never did try it. At the time I was caught in the whiplash of trying to use SMACH to control the entire robot (which it really isn’t designed for) and was not keen to try another custom framework. Behaviour trees have worked for games and it seemed prudent to give that a good run before using or reinventing yet another framework. We were more than pleased with the result.

Alison from TRI also recently started a python behaviour trees framework (I am not sure if it is open yet). It doesn’t yet have as many bells and whistles, but it was reassuring to find that she ended up making a few similar decisions along the way. That one might be worth integrating with if it is (or will be) open.

I am glade to see that behavior trees are becoming popular.

With my implementation (that I haven’t officially released to the ROS community) I tried to put together the best of C++ and runtime configuration, rather than compile time hard-coding.
Additionally, I am trying to create a core implementation that has no ROS dependencies and a ROS wrapper around it.

I was planning to propose a presentation for Roscon 2017, but I didn’t make it; my fault for being late :stuck_out_tongue:

This thread reminded me: is behavior3.com related to anything here?

I’m not trying to hijack this thread (very nice release @Daniel_Stonier), I’m actually interested to see whether fi we could do something with the editor and multi-agent parts of behavior3.

Apparently the editor serialises trees to a JSON format. I don’t know if that is something that could be used to programmatically construct trees @Daniel_Stonier?

I have my own editor that is very similar to theirs, even if it is written in C++/Qt.
In terms of common format, their format has some data and metadata missing, IMHO.

multi-agent parts of behavior3

Gaming is really focused on this aspect of behaviour trees because they are trying to control hundreds, if not thousands of npc characters that all interact with each other. This leads to all kinds of wonderful multi-tree co-ordination techniques and parallelising optimisations to make sure that it remains manageable and latency stays low.

If you’re just looking to co-ordinate a single robot’s behaviour though, this is a non-issue and greatly simplifies the behaviour tree implementation. There is just one agent and the complexity is typically only in the order of hundreds of behaviours. No parallelisation nor multi-agent co-ordination is required. If you’re starting to consider thousands of behaviours, or looking for a higher level robot fleet co-ordinator with an extreme number of robots, then you might start thinking about behaviour trees ala professional gaming considerations. I mention this briefly here.

If your use case is instead to handle a few or few tens of robots, I do not think anything special is required. Any behaviour trees implementation (incl. py_trees and behaviour3.com) could easily do so with a few simple mechanisms that fit whatever use case they have and the variety here is quite considerable. e.g. if behaviour3 has the implementation described in their 2013 ICRA paper then it has a rather special means of decorating a synchronisation that fits their use case.

My own two cents, I think people try to over-coordinate at this level - I much prefer keeping it very simple and adding as much autonomy to the robots themselves so they can engage and interact robustly without a hive mind instructing them every step of the way. Given that multiple robots are at the mercy of wireless communications this is an imperative consideration.

Apparently the editor serialises trees to a JSON format. I don’t know if that is something that could be used to programmatically construct trees @Daniel_Stonier?

The behaviour3.com format has string based key-value dictionary types that could be used to store esoteric information that the py_trees serialisations have. That means a converter or loader should be trivial. Having said that, it probably wouldn’t be that useful since you’d have to manually plug all of this information in (i.e. you lose the benefit of the gui) and can’t properly visualise it. py_trees dot graph visualisations of a python create_tree function are just as good (latex style workflow). The editor though might have ways of extending its functionality, or could probably be forked and hacked on directly as a good starting point. For us though, this starts to sound like a great deal of work with little benefit over the py_trees dot graph generator approach (which also happens to fit neatly into a CI workflow to generate graphs of your tree/subtree/behaviour library).

I do like how behaviour3 has focused on a serialisable format and used that as a focus for multi-language implementation. I would like at some point to write a c++ version of py_trees, but I doubt it would be the right thing to do - a c++ version should have requirements that would enable it to meet ‘gaming’ considerations, especially that of low latency. Similar scripting implementations of py_trees would be a nice thing though.

You are most probably right about the fact that a single robot doesn’t need a low latency, low overhead implementation.
I am happy to admit that I implemented my own version because I prefer C++ over Python.
To be fair, a lot of design tradeoff and complexity come from the fact that I want to create the tree at run-time, instead of compilation time, using a definition stored in a XML (could be JSON or whatever).
This would be a non-issue on Python.

NEVERTHELESS:

  1. I have strong feelings about having a BehaviorTree core library with NO ROS dependencies. NONE at all. ROS can be used seamlessly, though.
  2. Since all my Actions are written in C++, the only way to interact with Python would be through IPC, ROS services/topics, or Python/C++ wrappers. It feels more natural for ME to do everything in C++.
  3. The infamous BT blackboard would be harder to use in a Python/C++ mixed environment.

I am not trying to make a point here, simply to say that it feels easier for me to do everything in a single language.