py_trees.behaviour module

The core behaviour template for all py_tree behaviours.

class py_trees.behaviour.Behaviour(name: str)

Bases: ABC

A parent class for all user definable tree behaviours.

Args:

name: the behaviour name, defaults to auto-generating from the class name

Raises:

TypeError: if the provided name is not a string

Attributes:
~py_trees.behaviours.Behaviour.id (uuid.UUID): automagically generated unique identifier

for the behaviour

~py_trees.behaviours.Behaviour.name (str): the behaviour name ~py_trees.behaviours.Behaviour.blackboards (typing.List[py_trees.blackboard.Client]): collection of attached

blackboard clients

~py_trees.behaviours.Behaviour.status (Status): the behaviour status

(INVALID, RUNNING, FAILURE, SUCCESS)

~py_trees.behaviours.Behaviour.parent (Behaviour): a

Composite instance if nested in a tree, otherwise None

~py_trees.behaviours.Behaviour.children ([Behaviour]): empty for regular

behaviours, populated for composites

~py_trees.behaviours.Behaviour.logger (logging.Logger): a simple logging mechanism ~py_trees.behaviours.Behaviour.feedback_message(str): improve debugging with a simple message ~py_trees.behaviours.Behaviour.blackbox_level (BlackBoxLevel): a helper variable

for dot graphs and runtime gui’s to collapse/explode entire subtrees dependent upon the blackbox level.

See also

  • Skeleton Behaviour Template

  • The Lifecycle Demo

  • The Action Behaviour Demo

attach_blackboard_client(name: str | None = None, namespace: str | None = None) Client

Create and attach a blackboard to this behaviour.

Args:

name: human-readable (not necessarily unique) name for the client namespace: sandbox the client to variables behind this namespace

Returns:

a handle to the attached blackboard client

has_parent_with_instance_type(instance_type: Type[Behaviour]) bool

Search this behaviour’s ancestors for one of the specified type.

Args:

instance type of the parent to match

Returns:

whether a parent was found or not

has_parent_with_name(name: str) bool

Search this behaviour’s ancestors for one with the specified name.

Args:

name: name of the parent to match, can be a regular expression

Returns:

whether a parent was found or not

initialise() None

Execute user specified instructions prior to commencement of a new round of activity.

Users should override this method to perform any necessary initialising/clearing/resetting of variables prior to a new round of activity for the behaviour.

This method is automatically called via the py_trees.behaviour.Behaviour.tick() method whenever the behaviour is not RUNNING.

… note:: This method can be called more than once in the lifetime of a tree!

iterate(direct_descendants: bool = False) Iterator[Behaviour]

Iterate over this child and it’s children.

This utilises python generators for looping. To traverse the entire tree:

for node in my_behaviour.iterate():
    print("Name: {0}".format(node.name))
Args:

direct_descendants (bool): only yield children one step away from this behaviour.

Yields:

Behaviour: one of it’s children

setup(**kwargs: Any) None

Set up and verify infrastructure (middleware connections, etc) is available.

Users should override this method for any configuration and/or validation that is necessary prior to ticking the tree. Such construction is best done here rather than in __init__ since there is no guarantee at __init__ that the infrastructure is ready or even available (e.g. you may be just rendering dot graphs of the trees, no robot around).

Examples:
  • establishing a middleware connection to a sensor or driver

  • ensuring a sensor or driver is in a ‘ready’ state

This method will typically be called before a tree’s first tick as this gives the application time to check and verify that everything is in a ready state before executing. This is especially important given that a tree does not always tick every behaviour and if not checked up-front, it may be some time before discovering a behaviour was in a broken state.

Tip

When to use __init__(), setup() and when to use initialise()?

Use __init__() for configuration of non-runtime dependencies (e.g. no middleware).

Use setup() for one-offs or to get early signal that everything (e.g. middleware) is ready to go.

Use initialise() for just-in-time configurations and/or checks.

There are times when it makes sense to do all three. For example, pythonic variable configuration in __init__(), middleware service client creation / server existence checks in setup() and a just-in-time check to ensure the server is still available in initialise().

Tip

Faults are notified to the user of the behaviour via exceptions. Choice of exception to use is left to the user.

Warning

The kwargs argument is for distributing objects at runtime to behaviours before ticking. For example, a simulator instance with which behaviours can interact with the simulator’s python api, a ros2 node for setting up communications. Use sparingly, as this is not proof against keyword conflicts amongst disparate libraries of behaviours.

Args:
**kwargs: distribute arguments to this

behaviour and in turn, all of it’s children

Raises:

Exception: if this behaviour has a fault in construction or configuration

setup_with_descendants() None

Call setup on this child, it’s children (it’s children’s children, ).

shutdown() None

Destroy setup infrastructure (the antithesis of setup).

Users should override this method for any custom destruction of infrastructure usually brought into being in setup().

Raises:

Exception: of whatever flavour the child raises when errors occur on destruction

stop(new_status: Status) None

Stop the behaviour with the specified status.

Args:

new_status: the behaviour is transitioning to this new status

This is called to bring the current round of activity for the behaviour to completion, typically resulting in a final status of SUCCESS, FAILURE or INVALID.

Warning

Users should not override this method to provide custom termination behaviour. The terminate() method has been provided for that purpose.

terminate(new_status: Status) None

Execute user specified instructions when the behaviour is stopped.

Users should override this method to clean up. It will be triggered when a behaviour either finishes execution (switching from RUNNING to FAILURE || SUCCESS) or it got interrupted by a higher priority branch (switching to INVALID). Remember that the initialise() method will handle resetting of variables before re-entry, so this method is about disabling resources until this behaviour’s next tick. This could be a indeterminably long time. e.g.

  • cancel an external action that got started

  • shut down any temporary communication handles

Args:

new_status (Status): the behaviour is transitioning to this new status

Warning

Do not set self.status = new_status here, that is automatically handled by the stop() method. Use the argument purely for introspection purposes (e.g. comparing the current state in self.status with the state it will transition to in new_status.

tick() Iterator[Behaviour]

Tick the behaviour.

This function is a generator that can be used by an iterator on an entire behaviour tree. It handles the logic for deciding when to call the user’s initialise() and terminate() methods as well as making the actual call to the user’s update() method that determines the behaviour’s new status once the tick has finished. Once done, it will then yield itself (generator mechanism) so that it can be used as part of an iterator for the entire tree.

for node in my_behaviour.tick():
    print("Do something")

Note

This is a generator function, you must use this with yield. If you need a direct call, prefer tick_once() instead.

Yields:

a reference to itself

Warning

Users should not override this method to provide custom tick behaviour. The update() method has been provided for that purpose.

tick_once() None

Tick the object without iterating step-by-step over the children (i.e. without generators).

tip() Behaviour | None

Get the tip of this behaviour’s subtree (if it has one).

This corresponds to the the deepest node that was running before the subtree traversal reversed direction and headed back to this node.

Returns:

The deepest node (behaviour) that was running before subtree traversal reversed direction, or None if this behaviour’s status is INVALID.

abstract update() Status

Execute user specified instructions when the behaviour is ticked.

Users should override this method to perform any logic required to arrive at a decision on the behaviour’s new status. It is the primary worker function called by the tick() mechanism.

Returns:

the behaviour’s new status Status

Tip

This method should be almost instantaneous and non-blocking

visit(visitor: Any) None

Introspect on this behaviour with a visitor.

This is functionality that enables external introspection into the behaviour. It gets used by the tree manager classes to collect information as ticking traverses a tree.

Args:

visitor: the visiting class, must have a run(Behaviour) method.