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 attachedblackboard clients
- ~py_trees.behaviours.Behaviour.status (
Status
): the behaviour status - ~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 variablefor dot graphs and runtime gui’s to collapse/explode entire subtrees dependent upon the blackbox level.
- ~py_trees.behaviours.Behaviour.id (
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 notRUNNING
.… 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 useinitialise()
?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 insetup()
and a just-in-time check to ensure the server is still available ininitialise()
.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
See also
- 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
orINVALID
.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
toFAILURE
||SUCCESS
) or it got interrupted by a higher priority branch (switching toINVALID
). Remember that theinitialise()
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.See also
- 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()
andterminate()
methods as well as making the actual call to the user’supdate()
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
See also
- 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.