Tutorials

Before We Start

So, you would like your robot to actually do something non-trivial?

Trivial? Ah, a sequence of timed actions - move forward 3s, rotate 90 degrees, move forward 3s, emit a greeting. This is open-loop and can be pre-programmed in a single script easily. Trivial. Shift gears!

Non-Trivial? Hmm, you’d like to dynamically plan navigational routes (waypoints), choose between actions depending on whether blocking obstacles are sensed, interrupt the current action if the battery is low … and this is just getting started. In short, decision making with priority interrupts and closed loops with peripheral systems (e.g. via sensing, HMI devices, web services). Now you’re talking!

Most roboticists will start scripting, but quickly run into a complexity barrier. They’ll often then reach for state machines which are great for control systems, but run into yet another complexity barrier attempting to handle priority interrupts and an exponentially increasing profusion of wires between states. Which brings you here, to behavour trees! Before we proceed though…

Where is the Robot? Ostensibly you’ll need one, at some point. More often than not though, it’s not available or it’s just not practical for rapid application development. Might be it’s only partially assembled, or new features are being developed in parallel (deadlines!). On the other hand, it may be available, but you cannot get enough time-share on the robot or it is not yet stable, resulting in a stream of unrelated issues lower down in the robotic stack that impede application development. So you make the sensible decision of moving to simulation.

Simulation or Mocked Robots? If you already have a robot simulation, it’s a great place to start. In the long run though, the investment of time to build a mock robot layer should, in most cases, pay itself off with a faster development cycle. Why? Testing an application is mostly about provoking and testing the many permutations and combinations o decision making. It’s not about the 20 minutes of travel from point A to point B in the building. With a mocked robot layer, you can emulate that travel at ludicrous speed and provide easy handles for mocking the problems that can arise.

So this is where the tutorials begin, with a very simple, mocked robot. They will then proceed to build up a behaviour tree application, one step at a time.

The Mock Robot

The tutorials here all run atop a very simple mock robot that encapsulates the following list of mocked components:

  • Battery

  • LED Strip

  • Docking Action Server

  • Move Base Action Server

  • Rotation Action Server

  • Safety Sensors Pipeline

Note

It should always be possible for the mock robot to be replaced by a gazebo simulated robot or the actual robot. Each of these underlying systems must implement exactly the same ROS API interface.

The tutorials take care of launching the mock robot, but it can be also launched on its own with:

$ ros2 launch py_trees_ros_tutorials mock_robot_launch.py

Tutorial 1 - Data Gathering

Tutorial 2 - Battery Check

Tutorial 3 - Introspect the Blackboard

About

Tutorial three is a repeat of Tutorial 2 - Battery Check. The purpose of this tutorial however is to introduce the tools provided to allow introspection of the blackboard from ROS. Publishers and services are provided by py_trees_ros.blackboard.Exchange which is embedded in a py_trees_ros.trees.BehaviourTree. Interaction with the exchange is over a set of services and dynamically created topics via the the py-trees-blackboard-watcher command line utility.

Running

$ ros2 launch py_trees_ros_tutorials tutorial_three_introspect_the_blackboard_launch.py

In another shell:

# watch the entire board
$ py-trees-blackboard-watcher
# watch with the recent activity log (activity stream)
$ py-trees-blackboard-watcher --activity
# watch variables associated with behaviours on the most recent tick's visited path
$ py-trees-blackboard-watcher --visited
# list variables available to watch
$ py-trees-blackboard-watcher --list
# watch a simple variable (slide the battery level on the dashboard to trigger a change)
$ py-trees-blackboard-watcher /battery_low_warning
# watch a variable with nested attributes
$ py-trees-blackboard-watcher /battery.percentage
../_images/tutorial-three-introspect-the-blackboard.gif

Tutorial 4 - Introspecting the Tree

About

Again, this is a repeat of Tutorial 2 - Battery Check. In addition to services and topics for the blackboard, the py_trees_ros.trees.BehaviourTree class provides services and topics for introspection of the tree state itself as well as a command line utility, py-trees-tree-watcher, to interact with these services and topics.

Running

Launch the tutorial:

$ ros2 launch py_trees_ros_tutorials tutorial_four_introspect_the_tree_launch.py

Using py-trees-tree-watcher on a private snapshot stream:

# stream the tree state on changes
$ py-trees-tree-watcher
# stream the tree state on changes with statistics
$ py-trees-tree-watcher -s
# stream the tree state on changes with most recent blackboard activity
$ py-trees-tree-watcher -a
# stream the tree state on changes with visited blackboard variables
$ py-trees-tree-watcher -b
# serialise to a dot graph (.dot/.png/.svg) and view in xdot if available
$ py-trees-tree-watcher --dot-graph
# not necessary here, but if there are multiple trees to choose from
$ py-trees-tree-watcher --namespace=/tree/snapshot_streams
../_images/tutorial-four-introspect-the-tree.gif

Using py-trees-tree-watcher on the default snapshot stream (~/snapshots):

# enable the default snapshot stream
$ ros2 param set /tree default_snapshot_stream True
$ ros2 param set /tree default_snapshot_blackboard_data True
$ ros2 param set /tree default_snapshot_blackboard_activity True
# connect to the stream
$ py-trees-tree-watcher -a -s -b /tree/snapshots

Using py_trees_ros_viewer to configure and visualise the stream:

# install
$ sudo apt install ros-<rosdistro>-py-trees-ros-viewer
# start the viewer
$ py-trees-tree-viewer
../_images/tutorial-four-py-trees-ros-viewer.png

Tutorial 5 - Action Clients

Tutorial 6 - Context Switching

Tutorial 7 - Docking, Cancelling, Failing

Tutorial 8 - Dynamic Application Loading

Tutorial 9 - Bagging Trees

Coming soon…