Module API¶
py_trees¶
This is the top-level namespace of the py_trees package.
py_trees.behaviour¶
The core behaviour template. All behaviours, standalone and composite, inherit from this class.
-
class
py_trees.behaviour.
Behaviour
(name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
object
Defines the basic properties and methods required of a node in a behaviour tree. When implementing your own behaviour, subclass this class.
Parameters: name (
str
) – the behaviour name, defaults to auto-generating from the class nameRaises: TypeError
– if the provided name is not a stringVariables: - id (
uuid.UUID
) – automagically generated unique identifier for the behaviour - name (
str
) – the behaviour name - blackboard (
Blackboard
) – key-value store for sharing data between behaviours - status (
Status
) – the behaviour status (INVALID
,RUNNING
,FAILURE
,SUCCESS
) - parent (
Behaviour
) – aComposite
instance if nested in a tree, otherwise None - children ([
Behaviour
]) – empty for regular behaviours, populated for composites - logger (
logging.Logger
) – a simple logging mechanism - feedback_message (
str
) – improve debugging with a simple message - blackbox_level (
BlackBoxLevel
) – a helper variable for dot graphs and runtime gui’s to collapse/explode entire subtrees dependent upon the blackbox level.
-
has_parent_with_instance_type
(instance_type)[source]¶ Moves up through this behaviour’s parents looking for a behaviour with the same instance type as that specified.
Parameters: instance_type ( str
) – instance type of the parent to matchReturns: whether a parent was found or not Return type: bool
-
has_parent_with_name
(name)[source]¶ Searches through this behaviour’s parents, and their parents, looking for a behaviour with the same name as that specified.
Parameters: name ( str
) – name of the parent to match, can be a regular expressionReturns: whether a parent was found or not Return type: bool
-
initialise
()[source]¶ Note
User Customisable Callback
Subclasses may override this method to perform any necessary initialising/clearing/resetting of variables when when preparing to enter this behaviour if it was not previously
RUNNING
. i.e. Expect this to trigger more than once!
-
iterate
(direct_descendants=False)[source]¶ Generator that provides iteration over this behaviour and all its children. To traverse the entire tree:
for node in my_behaviour.iterate(): print("Name: {0}".format(node.name))
Parameters: direct_descendants ( bool
) – only yield children one step away from this behaviour.Yields: Behaviour
– one of it’s children
-
setup
(**kwargs)[source]¶ Note
User Customisable Callback
Subclasses may override this method for any one-off delayed construction & validation that is necessary prior to ticking the tree. Such construction is best done here rather than in __init__ so that trees can be instantiated on the fly for easy rendering to dot graphs without imposing runtime requirements (e.g. establishing a middleware connection to a sensor or a driver to a serial port).
Equally as important, executing methods which validate the configuration of behaviours will increase confidence that your tree will successfully tick without logical software errors before actually ticking. This is useful both before a tree’s first tick and immediately after any modifications to a tree has been made between ticks.
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.
Parameters: **kwargs ( dict
) – distribute arguments to this behaviour and in turn, all of it’s childrenRaises: Exception
– if this behaviour has a fault in construction or configuration
-
setup_with_descendants
()[source]¶ Iterates over this child, it’s children (it’s children’s children, …) calling the user defined
setup()
on each in turn.
-
shutdown
()[source]¶ Note
User Customisable Callback
Subclasses may 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 destructionSee also
-
stop
(new_status=<Status.INVALID: 'INVALID'>)[source]¶ Parameters: new_status ( Status
) – the behaviour is transitioning to this new statusThis calls the user defined
terminate()
method and also resets the generator. It will finally set the new status once the user’sterminate()
function has been called.Warning
Override this method only in exceptional circumstances, prefer overriding
terminate()
instead.
-
terminate
(new_status)[source]¶ Note
User Customisable Callback
Subclasses may 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 tempoarary communication handles
Parameters: new_status ( Status
) – the behaviour is transitioning to this new statusWarning
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
()[source]¶ 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: Behaviour
– a reference to itselfWarning
Override this method only in exceptional circumstances, prefer overriding
update()
instead.
-
tick_once
()[source]¶ A direct means of calling tick on this object without using the generator mechanism.
-
tip
()[source]¶ Get the tip of this behaviour’s subtree (if it has one) after it’s last tick. This corresponds to the the deepest node that was running before the subtree traversal reversed direction and headed back to this node.
Returns: child behaviour, itself or None
if its status isINVALID
Return type: Behaviour
orNone
-
update
()[source]¶ Note
User Customisable Callback
Returns: the behaviour’s new status Status
Return type: Status
Subclasses may 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 on by the
tick()
mechanism.Tip
This method should be almost instantaneous and non-blocking
-
verbose_info_string
()[source]¶ Override to provide a one line informative string about the behaviour. This gets used in, e.g. dot graph rendering of the tree.
Tip
Use this sparingly. A good use case is for when the behaviour type and class name isn’t sufficient to inform the user about it’s mechanisms for controlling the flow of a tree tick (e.g. parallels with policies).
- id (
py_trees.behaviours¶
A library of fundamental behaviours for use.
-
class
py_trees.behaviours.
CheckBlackboardVariableExists
(variable_name, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviour.Behaviour
Check the blackboard to verify if a specific variable (key-value pair) exists. This is non-blocking, so will always tick with status
FAILURE
SUCCESS
.See also
WaitForBlackboardVariable
for the blocking counterpart to this behaviour.Parameters:
-
class
py_trees.behaviours.
CheckBlackboardVariableValue
(variable_name, expected_value, comparison_operator=<built-in function eq>, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviour.Behaviour
Inspect a blackboard variable and if it exists, check that it meets the specified criteria (given by operation type and expected value). This is non-blocking, so it will always tick with
SUCCESS
orFAILURE
.Parameters: Note
If the variable does not yet exist on the blackboard, the behaviour will return with status
FAILURE
.Tip
The python operator module includes many useful comparison operations.
-
class
py_trees.behaviours.
Count
(name='Count', fail_until=3, running_until=5, success_until=6, reset=True)[source]¶ Bases:
py_trees.behaviour.Behaviour
A counting behaviour that updates its status at each tick depending on the value of the counter. The status will move through the states in order -
FAILURE
,RUNNING
,SUCCESS
.This behaviour is useful for simple testing and demo scenarios.
Parameters: - name (
str
) – name of the behaviour - fail_until (
int
) – set status toFAILURE
until the counter reaches this value - running_until (
int
) – set status toRUNNING
until the counter reaches this value - success_until (
int
) – set status toSUCCESS
until the counter reaches this value - reset (
bool
) – whenever invalidated (usually by a sequence reinitialising, or higher priority interrupting)
Variables: count (
int
) – a simple counter which increments every tick-
terminate
(new_status)[source]¶ Note
User Customisable Callback
Subclasses may 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 tempoarary communication handles
Parameters: new_status ( Status
) – the behaviour is transitioning to this new statusWarning
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.
-
update
()[source]¶ Note
User Customisable Callback
Returns: the behaviour’s new status Status
Return type: Status
Subclasses may 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 on by the
tick()
mechanism.Tip
This method should be almost instantaneous and non-blocking
- name (
-
class
py_trees.behaviours.
Dummy
(name='Dummy')¶ Bases:
py_trees.behaviour.Behaviour
-
class
py_trees.behaviours.
Failure
(name='Failure')¶ Bases:
py_trees.behaviour.Behaviour
-
class
py_trees.behaviours.
Periodic
(name, n)[source]¶ Bases:
py_trees.behaviour.Behaviour
Simply periodically rotates it’s status over the
RUNNING
,SUCCESS
,FAILURE
states. That is,RUNNING
for N ticks,SUCCESS
for N ticks,FAILURE
for N ticks…Parameters: Note
It does not reset the count when initialising.
-
update
()[source]¶ Note
User Customisable Callback
Returns: the behaviour’s new status Status
Return type: Status
Subclasses may 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 on by the
tick()
mechanism.Tip
This method should be almost instantaneous and non-blocking
-
-
class
py_trees.behaviours.
Running
(name='Running')¶ Bases:
py_trees.behaviour.Behaviour
-
class
py_trees.behaviours.
SetBlackboardVariable
(variable_name, variable_value, overwrite=True, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviour.Behaviour
Set the specified variable on the blackboard.
Parameters:
-
class
py_trees.behaviours.
Success
(name='Success')¶ Bases:
py_trees.behaviour.Behaviour
-
class
py_trees.behaviours.
SuccessEveryN
(name, n)[source]¶ Bases:
py_trees.behaviour.Behaviour
This behaviour updates it’s status with
SUCCESS
once every N ticks,FAILURE
otherwise.Parameters: Tip
Use with decorators to change the status value as desired, e.g.
py_trees.decorators.FailureIsRunning()
-
update
()[source]¶ Note
User Customisable Callback
Returns: the behaviour’s new status Status
Return type: Status
Subclasses may 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 on by the
tick()
mechanism.Tip
This method should be almost instantaneous and non-blocking
-
-
class
py_trees.behaviours.
UnsetBlackboardVariable
(key, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviour.Behaviour
Unset the specified variable (key-value pair) from the blackboard.
This always returns
SUCCESS
regardless of whether the variable was already present or not.Parameters:
-
class
py_trees.behaviours.
WaitForBlackboardVariable
(variable_name, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviours.CheckBlackboardVariableExists
Wait for the blackboard variable to become available on the blackboard. This is blocking, so it will tick with status
SUCCESS
if the variable is found, andRUNNING
otherwise.See also
CheckBlackboardVariableExists
for the non-blocking counterpart to this behaviour.Parameters:
-
class
py_trees.behaviours.
WaitForBlackboardVariableValue
(variable_name, expected_value, comparison_operator=<built-in function eq>, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviours.CheckBlackboardVariableValue
Inspect a blackboard variable and if it exists, check that it meets the specified criteria (given by operation type and expected value). This is blocking, so it will always tick with
SUCCESS
orRUNNING
.See also
CheckBlackboardVariableValue
for the non-blocking counterpart to this behaviour.Note
If the variable does not yet exist on the blackboard, the behaviour will return with status
RUNNING
.Parameters:
py_trees.blackboard¶
Blackboards are not a necessary component of behaviour tree implementations, but are nonetheless, a fairly common mechanism for for sharing data between behaviours in the tree. See, for example, the design notes for blackboards in Unreal Engine.

Implementations vary widely depending on the needs of the framework using them. The simplest implementations take the form of a key-value store with global access, while more rigorous implementations scope access and form a secondary graph overlaying the tree graph connecting data ports between behaviours.
The implementation here strives to remain simple to use (so ‘rapid development’ does not become just ‘development’), yet sufficiently featured so that the magic behind the scenes (i.e. the data sharing on the blackboard) is exposed and helpful in debugging tree applications.
To be more concrete, the following is a list of features that this implementation either embraces or does not.
- [+] Centralised key-value store
- [+] Client based usage with registration of read/write intentions at construction
- [+] Activity stream that tracks read/write operations by behaviours
- [-] Sharing between tree instances
- [-] Exclusive locks for reading/writing
- [-] Priority policies for variable instantiations
-
class
py_trees.blackboard.
ActivityItem
(key, client_name, client_id, activity_type, previous_value=None, current_value=None)[source]¶ Bases:
object
Recorded data pertaining to activity on the blackboard.
Parameters: - key – name of the variable on the blackboard
- client_name (
str
) – convenient name of the client performing the operation - client_id (
UUID
) – unique id of the client performing the operation - activity_type (
ActivityType
) – type of activity - previous_value (
Optional
[Any
]) – of the given key (None if this field is not relevant) - current_value (
Optional
[Any
]) – current value for the given key (None if this field is not relevant)
-
__init__
(key, client_name, client_id, activity_type, previous_value=None, current_value=None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
__weakref__
¶ list of weak references to the object (if defined)
-
class
py_trees.blackboard.
ActivityStream
(maximum_size=500)[source]¶ Bases:
object
Storage container with convenience methods for manipulating the stored activity stream.
Variables: - (typing.List[ActivityItem] (data) – list of activity items, earliest first
- maximum_size (int) – pop items if this size is exceeded
-
__init__
(maximum_size=500)[source]¶ Initialise the stream with a maximum storage limit.
Parameters: maximum_size ( int
) – pop items from the stream if this size is exceeded
-
__weakref__
¶ list of weak references to the object (if defined)
-
push
(activity_item)[source]¶ Push the next activity item to the stream.
Parameters: activity_item ( ActivityItem
) – new item to append to the stream
-
class
py_trees.blackboard.
ActivityType
[source]¶ Bases:
enum.Enum
An enumerator representing the operation on a blackboard variable
-
ACCESSED
= 'ACCESSED'¶ Key accessed, either for reading, or modification of the value’s internal attributes (e.g. foo.bar).
-
ACCESS_DENIED
= 'ACCESS_DENIED'¶ Client did not have access to read/write a key.
-
INITIALISED
= 'INITIALISED'¶ Initialised a key-value pair on the blackboard
-
NO_KEY
= 'NO_KEY'¶ Tried to access a key that does not yet exist on the blackboard.
-
NO_OVERWRITE
= 'NO_OVERWRITE'¶ Tried to write but variable already exists and a no-overwrite request was respected.
-
READ
= 'READ'¶ Read from the blackboard
-
UNSET
= 'UNSET'¶ Key was removed from the blackboard
-
WRITE
= 'WRITE'¶ Wrote to the blackboard.
-
-
class
py_trees.blackboard.
Blackboard
[source]¶ Bases:
object
Centralised key-value store for sharing data between behaviours. This class is a coat-hanger for the centralised data store, metadata for it’s administration and static methods for interacting with it.
This api is intended for authors of debugging and introspection tools on the blackboard. Users should make use of the
BlackboardClient
.Variables: - Blackboard.clients (typing.Dict[uuid.UUID, Blackboard]) – clients, gathered by uuid
- Blackboard.storage (typing.Dict[str, typing.Any]) – key-value data store
- Blackboard.metadata (typing.Dict[str, KeyMetaData]) – key associated metadata
- Blackboard.activity_stream (ActivityStream) – logged activity
-
__weakref__
¶ list of weak references to the object (if defined)
-
static
clear
()[source]¶ Completely clear all key, value and client information from the blackboard. Also deletes the activity stream.
-
static
enable_activity_stream
(maximum_size=500)[source]¶ Enable logging of activities on the blackboard.
Parameters: maximum_size ( int
) – pop items from the stream if this size is exceededRaises: RuntimeError if the activity stream is already enabled
-
static
get
(variable_name)[source]¶ Extract the value associated with the given a variable name, can be nested, e.g. battery.percentage. This differs from the client get method in that it doesn’t pass through the client access checks. To be used for utility tooling (e.g. display methods) and not by users directly.
Parameters: variable_name ( str
) – of the variable to get, can be nested, e.g. battery.percentageRaises: KeyError
– if the variable or it’s nested attributes do not yet exist on the blackboardReturn type: Any
Returns: The stored value for the given variable
-
static
keys
()[source]¶ Get the set of blackboard keys.
Return type: Set
[str
]Returns: the complete set of keys registered by clients
-
static
keys_filtered_by_clients
(client_ids)[source]¶ Get the set of blackboard keys filtered by client ids.
Parameters: client_ids ( Union
[List
[str
],Set
[str
]]) – set of client uuid’s.Return type: Set
[str
]Returns: subset of keys that have been registered by the specified clients
-
static
keys_filtered_by_regex
(regex)[source]¶ Get the set of blackboard keys filtered by regex.
Parameters: regex ( str
) – a python regex stringReturn type: Set
[str
]Returns: subset of keys that have been registered and match the pattern
-
static
set
(variable_name, value)[source]¶ Set the value associated with the given a variable name, can be nested, e.g. battery.percentage. This differs from the client get method in that it doesn’t pass through the client access checks. To be used for utility tooling (e.g. display methods) and not by users directly.
Parameters: variable_name ( str
) – of the variable to set, can be nested, e.g. battery.percentageRaises: AttributeError
– if it is attempting to set a nested attribute tha does not exist.
-
class
py_trees.blackboard.
BlackboardClient
(*, name=None, unique_identifier=None, read=None, write=None)[source]¶ Bases:
object
Client to the key-value store for sharing data between behaviours.
Examples
Blackboard clients will accept a user-friendly name / unique identifier for registration on the centralised store or create them for you if none is provided.
provided = py_trees.blackboard.BlackboardClient( name="Provided", unique_identifier=uuid.uuid4() ) print(provided) generated = py_trees.blackboard.BlackboardClient() print(generated)
Client Instantiation
Register read/write access for keys on the blackboard. Note, registration is not initialisation.
blackboard = py_trees.blackboard.BlackboardClient( name="Client", read={"foo"}, write={"bar"} ) blackboard.register_key(key="foo", write=True) blackboard.foo = "foo" print(blackboard)
Variable Read/Write Registration
Disconnected instances will discover the centralised key-value store.
def check_foo(): blackboard = py_trees.blackboard.BlackboardClient(name="Reader", read={"foo"}) print("Foo: {}".format(blackboard.foo)) blackboard = py_trees.blackboard.BlackboardClient(name="Writer", write={"foo"}) blackboard.foo = "bar" check_foo()
To respect an already initialised key on the blackboard:
blackboard = BlackboardClient(name="Writer", read={"foo")) result = blackboard.set("foo", "bar", overwrite=False)
Store complex objects on the blackboard:
class Nested(object): def __init__(self): self.foo = None self.bar = None def __str__(self): return str(self.__dict__) writer = py_trees.blackboard.BlackboardClient( name="Writer", write={"nested"} ) reader = py_trees.blackboard.BlackboardClient( name="Reader", read={"nested"} ) writer.nested = Nested() writer.nested.foo = "foo" writer.nested.bar = "bar" foo = reader.nested.foo print(writer) print(reader)
Log and display the activity stream:
py_trees.blackboard.Blackboard.enable_activity_stream(maximum_size=100) blackboard_reader = py_trees.blackboard.BlackboardClient(name="Reader", read={"foo"}) blackboard_writer = py_trees.blackboard.BlackboardClient(name="Writer", write={"foo"}) blackboard_writer.foo = "bar" blackboard_writer.foo = "foobar" unused_result = blackboard_reader.foo print(py_trees.display.unicode_blackboard_activity_stream()) py_trees.blackboard.Blackboard.activity_stream.clear()
Display the blackboard on the console, or part thereof:
writer = py_trees.blackboard.BlackboardClient( name="Writer", write={"foo", "bar", "dude", "dudette"} ) reader = py_trees.blackboard.BlackboardClient( name="Reader", read={"foo", "bBlackboardClient( ) writer.foo = "foo" writer.bar = "bar" writer.dude = "bob" # all key-value pairs print(py_trees.display.unicode_blackboard()) # various filtered views print(py_trees.display.unicode_blackboard(key_filter={"foo"})) print(py_trees.display.unicode_blackboard(regex_filter="dud*")) print(py_trees.display.unicode_blackboard(client_filter={reader.unique_identifier})) # list the clients associated with each key print(py_trees.display.unicode_blackboard(display_only_key_metadata=True))
Behaviours register their own blackboard clients with the same name/id as the behaviour itself. This helps associate blackboard variables with behaviours, enabling various introspection and debugging capabilities on the behaviour trees.
Creating a custom behaviour with blackboard variables:
class Foo(py_trees.behaviours.Behaviour): def __init__(self, name): super().__init__(name=name) self.blackboard.register_key("foo", read=True) def update(self): self.feedback_message = self.blackboard.foo return py_trees.common.Status.Success
Rendering a dot graph for a behaviour tree, complete with blackboard variables:
# in code py_trees.display.render_dot_tree(py_trees.demos.blackboard.create_root()) # command line tools py-trees-render --with-blackboard-variables py_trees.demos.blackboard.create_root
And to demonstrate that it doesn’t become a tangled nightmare at scale, an example of a more complex tree:
With judicious use of the display methods / activity stream around the ticks of a tree (refer to
py_trees.visitors.DisplaySnapshotVisitor
for examplar code):See also
- py-trees-demo-blackboard
py_trees.visitors.DisplaySnapshotVisitor
py_trees.behaviours.SetBlackboardVariable
py_trees.behaviours.UnsetBlackboardVariable
py_trees.behaviours.CheckBlackboardVariableExists
py_trees.behaviours.WaitForBlackboardVariable
py_trees.behaviours.CheckBlackboardVariableValue
py_trees.behaviours.WaitForBlackboardVariableValue
Variables: - name (str) – client’s convenient, but not necessarily unique identifier
- unique_identifier (uuid.UUID) – client’s unique identifier
- read (typing.List[str]) – keys this client has permission to read
- write (typing.List[str]) – keys this client has permission to write
-
__getattr__
(name)[source]¶ Convenience attribute style referencing with checking against permissions.
Raises: AttributeError
– if the client does not have read access to the variableKeyError
– if the variable does not yet exist on the blackboard
-
__init__
(*, name=None, unique_identifier=None, read=None, write=None)[source]¶ Parameters: - name (
Optional
[str
]) – client’s convenient identifier (stringifies the uuid if None) - unique_identifier (
Optional
[UUID
]) – client’s unique identifier (auto-generates if None) - read (
Optional
[Set
[str
]]) – list of keys this client has permission to read - write (
Optional
[Set
[str
]]) – list of keys this client has permission to write
Raises: TypeError
– if the provided name/unique identifier is not of type str/uuid.UUIDValueError
– if the unique identifier has already been registered
- name (
-
__setattr__
(name, value)[source]¶ Convenience attribute style referencing with checking against permissions.
Raises: AttributeError
– if the client does not have write access to the variable
-
__weakref__
¶ list of weak references to the object (if defined)
-
exists
(name)[source]¶ Check if the specified variable exists on the blackboard.
Parameters: name ( str
) – name of the variable to get, can be nested, e.g. battery.percentageRaises: AttributeError
– if the client does not have read access to the variableReturn type: bool
-
get
(name)[source]¶ Method based accessor to the blackboard variables (as opposed to simply using ‘.<name>’).
Parameters: name (
str
) – name of the variable to get, can be nested, e.g. battery.percentageRaises: AttributeError
– if the client does not have read access to the variableKeyError
– if the variable or it’s nested attributes do not yet exist on the blackboard
Return type:
-
register_key
(key, read=False, write=False)[source]¶ Register a key on the blackboard to associate with this client.
Parameters:
-
set
(name, value, overwrite=True)[source]¶ Set, conditionally depending on whether the variable already exists or otherwise.
This is most useful when initialising variables and multiple elements seek to do so. A good policy to adopt for your applications in these situations is a first come, first served policy. Ensure global configuration has the first opportunity followed by higher priority behaviours in the tree and so forth. Lower priority behaviours would use this to respect the pre-configured setting and at most, just validate that it is acceptable to the functionality of it’s own behaviour.
Parameters: Return type: Returns: success or failure (overwrite is False and variable already set)
Raises: AttributeError
– if the client does not have write access to the variableKeyError
– if the variable does not yet exist on the blackboard
-
unregister
(clear=True)[source]¶ Unregister this blackboard client and if requested, clear key-value pairs if this client is the last user of those variables.
Parameters: clear ( bool
) – remove key-values pairs from the blackboard
-
unregister_all_keys
(clear=True)[source]¶ Unregister all keys currently registered by this blackboard client and if requested, clear key-value pairs if this client is the last user of those variables.
Parameters: clear ( bool
) – remove key-values pairs from the blackboard
-
class
py_trees.blackboard.
KeyMetaData
[source]¶ Bases:
object
Stores the aggregated metadata for a key on the blackboard.
-
__weakref__
¶ list of weak references to the object (if defined)
-
-
class
py_trees.blackboard.
SubBlackboard
[source]¶ Bases:
object
Dynamically track the entire blackboard or part thereof and flag when there have been changes. This is a useful class for building introspection tools around the blackboard.
-
__str__
()[source]¶ Convenient printed representation of the sub-blackboard that this instance is currently tracking.
-
__weakref__
¶ list of weak references to the object (if defined)
-
py_trees.common¶
Common definitions, methods and variables used by the py_trees library.
-
class
py_trees.common.
BlackBoxLevel
[source]¶ Bases:
enum.IntEnum
Whether a behaviour is a blackbox entity that may be considered collapsible (i.e. everything in its subtree will not be visualised) by visualisation tools.
Blackbox levels are increasingly persistent in visualisations.
Visualisations by default, should always collapse blackboxes that represent DETAIL.
-
BIG_PICTURE
= 3¶ A blackbox that represents a big picture part of the entire tree view.
-
COMPONENT
= 2¶ A blackbox that encapsulates a subgroup of functionalities as a single group.
-
DETAIL
= 1¶ A blackbox that encapsulates detailed activity.
-
NOT_A_BLACKBOX
= 4¶ Not a blackbox, do not ever collapse.
-
-
class
py_trees.common.
ClearingPolicy
[source]¶ Bases:
enum.IntEnum
Policy rules for behaviours to dictate when data should be cleared/reset.
-
NEVER
= 3¶ Never clear the data
-
ON_INITIALISE
= 1¶ Clear when entering the
initialise()
method.
-
-
class
py_trees.common.
Duration
[source]¶ Bases:
enum.Enum
Naming conventions.
-
UNTIL_THE_BATTLE_OF_ALFREDO
= inf¶ UNTIL_THE_BATTLE_OF_ALFREDO
is an alias forINFINITE
.
-
-
class
py_trees.common.
Name
[source]¶ Bases:
enum.Enum
Naming conventions.
-
AUTO_GENERATED
= 'AUTO_GENERATED'¶ AUTO_GENERATED
leaves it to the behaviour to generate a useful, informative name.
-
-
class
py_trees.common.
ParallelPolicy
[source]¶ Configurable policies for
Parallel
behaviours.-
class
SuccessOnAll
(synchronise=True)[source]¶ Return
SUCCESS
only when each and every child returnsSUCCESS
.
-
class
-
class
py_trees.common.
Status
[source]¶ Bases:
enum.Enum
An enumerator representing the status of a behaviour
-
FAILURE
= 'FAILURE'¶ Behaviour check has failed, or execution of its action finished with a failed result.
-
INVALID
= 'INVALID'¶ Behaviour is uninitialised and inactive, i.e. this is the status before first entry, and after a higher priority switch has occurred.
-
RUNNING
= 'RUNNING'¶ Behaviour is in the middle of executing some action, result still pending.
-
SUCCESS
= 'SUCCESS'¶ Behaviour check has passed, or execution of its action has finished with a successful result.
-
-
class
py_trees.common.
VisibilityLevel
[source]¶ Bases:
enum.IntEnum
Closely associated with the
BlackBoxLevel
for a behaviour. This sets the visibility level to be used for visualisations.Visibility levels correspond to reducing levels of visibility in a visualisation.
-
ALL
= 0¶ Do not collapse any behaviour.
-
BIG_PICTURE
= 3¶ Collapse any blackbox that isn’t marked with
BIG_PICTURE
.
-
-
common.
string_to_visibility_level
()¶ Will convert a string to a visibility level. Note that it will quietly return ALL if the string is not matched to any visibility level string identifier.
Parameters: level (str) – visibility level as a string Returns: visibility level enum Return type: VisibilityLevel
py_trees.composites¶
Composites are the factories and decision makers of a behaviour tree. They are responsible for shaping the branches.
![digraph selector {
graph [fontname="times-roman"];
node [fontname="times-roman"];
edge [fontname="times-roman"];
Sequence [fontcolor=black, shape=box, fontsize=11, style=filled, fillcolor=orange];
Selector [fontcolor=black, shape=octagon, fontsize=11, style=filled, fillcolor=cyan];
Chooser [fontcolor=black, shape=doubleoctagon, fontsize=11, style=filled, fillcolor=cyan];
Parallel [fontcolor=black, shape=parallelogram, fontsize=11, style=filled, fillcolor=gold];
}](_images/graphviz-71079279ecd501b2e388b939ee2001d9e335cbc5.png)
Tip
You should never need to subclass or create new composites.
Most patterns can be achieved with a combination of the above. Adding to this set exponentially increases the complexity and subsequently making it more difficult to design, introspect, visualise and debug the trees. Always try to find the combination you need to achieve your result before contemplating adding to this set. Actually, scratch that…just don’t contemplate it!
Composite behaviours typically manage children and apply some logic to the way they execute and return a result, but generally don’t do anything themselves. Perform the checks or actions you need to do in the non-composite behaviours.
Sequence
: execute children sequentiallySelector
: select a path through the tree, interruptible by higher prioritiesChooser
: like a selector, but commits to a path once started until it finishesParallel
: manage children concurrently
-
class
py_trees.composites.
Chooser
(name='Chooser', children=None)[source]¶ Bases:
py_trees.composites.Selector
Choosers are Selectors with Commitment
A variant of the selector class. Once a child is selected, it cannot be interrupted by higher priority siblings. As soon as the chosen child itself has finished it frees the chooser for an alternative selection. i.e. priorities only come into effect if the chooser wasn’t running in the previous tick.
Note
This is the only composite in py_trees that is not a core composite in most behaviour tree implementations. Nonetheless, this is useful in fields like robotics, where you have to ensure that your manipulator doesn’t drop it’s payload mid-motion as soon as a higher interrupt arrives. Use this composite sparingly and only if you can’t find another way to easily create an elegant tree composition for your task.
Parameters:
-
class
py_trees.composites.
Composite
(name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, children=None)[source]¶ Bases:
py_trees.behaviour.Behaviour
The parent class to all composite behaviours, i.e. those that have children.
Parameters: -
__init__
(name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, children=None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
add_child
(child)[source]¶ Adds a child.
Parameters: child ( Behaviour
) – child to addRaises: TypeError
– if the provided child is not an instance ofBehaviour
Returns: unique id of the child Return type: uuid.UUID
-
add_children
(children)[source]¶ Append a list of children to the current list.
Parameters: children ([ Behaviour
]) – list of children to add
-
insert_child
(child, index)[source]¶ Insert child at the specified index. This simply directly calls the python list’s
insert
method using the child and index arguments.Parameters: Returns: unique id of the child
Return type:
-
prepend_child
(child)[source]¶ Prepend the child before all other children.
Parameters: child ( Behaviour
) – child to insertReturns: unique id of the child Return type: uuid.UUID
-
remove_child
(child)[source]¶ Remove the child behaviour from this composite.
Parameters: child ( Behaviour
) – child to deleteReturns: index of the child that was removed Return type: int
Todo
Error handling for when child is not in this list
-
remove_child_by_id
(child_id)[source]¶ Remove the child with the specified id.
Parameters: child_id (uuid.UUID) – unique id of the child Raises: IndexError
– if the child was not found
-
stop
(new_status=<Status.INVALID: 'INVALID'>)[source]¶ There is generally two use cases that must be supported here.
1) Whenever the composite has gone to a recognised state (i.e.
FAILURE
or SUCCESS), or 2) when a higher level parent calls on it to truly stop (INVALID).In only the latter case will children need to be forcibly stopped as well. In the first case, they will have stopped themselves appropriately already.
Parameters: new_status ( Status
) – behaviour will transition to this new status
-
-
class
py_trees.composites.
Parallel
(name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, policy=<py_trees.common.ParallelPolicy.SuccessOnAll object>, children=None)[source]¶ Bases:
py_trees.composites.Composite
Parallels enable a kind of concurrency
Ticks every child every time the parallel is run (a poor man’s form of parallelism).
- Parallels will return
FAILURE
if any child returnsFAILURE
- Parallels with policy
SuccessOnAll
only returnsSUCCESS
if all children returnSUCCESS
- Parallels with policy
SuccessOnOne
returnSUCCESS
if at least one child returnsSUCCESS
and others areRUNNING
- Parallels with policy
SuccessOnSelected
only returnsSUCCESS
if a specified subset of children returnSUCCESS
Parallels with policy
SuccessOnSelected
will validate themselves just-in-time in thesetup()
andtick()
methods to check if the policy’s selected set of children is a subset of the children of this parallel. Doing this just-in-time is due to the fact that the parallel’s children may change after construction and even dynamically between ticks.See also
-
__init__
(name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, policy=<py_trees.common.ParallelPolicy.SuccessOnAll object>, children=None)[source]¶ Parameters: - name (
str
) – the composite behaviour name - policy (
ParallelPolicy
) – policy to use for deciding success or otherwise - children ([
Behaviour
]) – list of children to add
- name (
-
current_child
¶ In some cases it’s clear what the current child is, in others, there is an ambiguity as multiple could exist. If the latter is true, it will return the child relevant farthest down the list.
Returns: the child that is currently running, or None Return type: Behaviour
-
setup
(**kwargs)[source]¶ Detect before ticking whether the policy configuration is invalid.
Parameters: **kwargs (
dict
) – distribute arguments to this behaviour and in turn, all of it’s childrenRaises: RuntimeError
– if the parallel’s policy configuration is invalidException
– be ready to catch if any of the children raise an exception
-
stop
(new_status=<Status.INVALID: 'INVALID'>)[source]¶ For interrupts or any of the termination conditions, ensure that any running children are stopped.
Parameters: new_status ( Status
) – the composite is transitioning to this new status
-
tick
()[source]¶ Tick over the children.
Yields: Behaviour
– a reference to itself or one of its childrenRaises: RuntimeError
– if the policy configuration was invalid
-
validate_policy_configuration
()[source]¶ Policy configuration can be invalid if:
- Policy is SuccessOnSelected and no behaviours have been specified
- Policy is SuccessOnSelected and behaviours that are not children exist
Raises: RuntimeError
– if policy configuration was invalid
- Parallels will return
-
class
py_trees.composites.
Selector
(name='Selector', children=None)[source]¶ Bases:
py_trees.composites.Composite
Selectors are the Decision Makers
A selector executes each of its child behaviours in turn until one of them succeeds (at which point it itself returns
RUNNING
orSUCCESS
, or it runs out of children at which point it itself returnsFAILURE
. We usually refer to selecting children as a means of choosing between priorities. Each child and its subtree represent a decreasingly lower priority path.Note
Switching from a low -> high priority branch causes a stop(INVALID) signal to be sent to the previously executing low priority branch. This signal will percolate down that child’s own subtree. Behaviours should make sure that they catch this and destruct appropriately.
Make sure you do your appropriate cleanup in the
terminate()
methods! e.g. cancelling a running goal, or restoring a context.See also
The py-trees-demo-selector program demos higher priority switching under a selector.
Parameters: -
__init__
(name='Selector', children=None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
__repr__
()[source]¶ Simple string representation of the object.
Returns: string representation Return type: str
-
stop
(new_status=<Status.INVALID: 'INVALID'>)[source]¶ Stopping a selector requires setting the current child to none. Note that it is important to implement this here instead of terminate, so users are free to subclass this easily with their own terminate and not have to remember that they need to call this function manually.
Parameters: new_status ( Status
) – the composite is transitioning to this new status
-
-
class
py_trees.composites.
Sequence
(name='Sequence', children=None)[source]¶ Bases:
py_trees.composites.Composite
Sequences are the factory lines of Behaviour Trees
A sequence will progressively tick over each of its children so long as each child returns
SUCCESS
. If any child returnsFAILURE
orRUNNING
the sequence will halt and the parent will adopt the result of this child. If it reaches the last child, it returns with that result regardless.Note
The sequence halts once it sees a child is RUNNING and then returns the result. It does not get stuck in the running behaviour.
See also
The py-trees-demo-sequence program demos a simple sequence in action.
Parameters: -
__init__
(name='Sequence', children=None)[source]¶ Initialize self. See help(type(self)) for accurate signature.
-
current_child
¶ Have to check if there’s anything actually running first.
Returns: the child that is currently running, or None Return type: Behaviour
-
stop
(new_status=<Status.INVALID: 'INVALID'>)[source]¶ Stopping a sequence requires taking care of the current index. Note that is important to implement this here intead of terminate, so users are free to subclass this easily with their own terminate and not have to remember that they need to call this function manually.
Parameters: new_status ( Status
) – the composite is transitioning to this new status
-
py_trees.console¶
Simple colour definitions and syntax highlighting for the console.
Colour Definitions
The current list of colour definitions include:
Regular
: black, red, green, yellow, blue, magenta, cyan, white,Bold
: bold, bold_black, bold_red, bold_green, bold_yellow, bold_blue, bold_magenta, bold_cyan, bold_white
These colour definitions can be used in the following way:
import py_trees.console as console
print(console.cyan + " Name" + console.reset + ": " + console.yellow + "Dude" + console.reset)
-
py_trees.console.
colours
= ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']¶ List of all available colours.
-
py_trees.console.
console_has_colours
()[source]¶ Detects if the console (stdout) has colourising capability.
-
py_trees.console.
define_symbol_or_fallback
(original, fallback, encoding='UTF-8')[source]¶ Return the correct encoding according to the specified encoding. Used to make sure we get an appropriate symbol, even if the shell is merely ascii as is often the case on, e.g. Jenkins CI.
Parameters: Returns: either original or fallback depending on whether exceptions were thrown.
Return type:
-
py_trees.console.
has_colours
= False¶ Whether the loading program has access to colours or not.
-
py_trees.console.
has_unicode
(encoding='UTF-8')[source]¶ Define whether the specified encoding has unicode symbols. Usually used to check if the stdout is capable or otherwise (e.g. Jenkins CI can often be configured with unicode disabled).
Parameters: encoding ( str
, optional) – the encoding to check against.Returns: true if capable, false otherwise Return type: bool
-
py_trees.console.
logdebug
(message)[source]¶ Prefixes
[DEBUG]
and colours the message green.Parameters: message ( str
) – message to log.
-
py_trees.console.
logerror
(message)[source]¶ Prefixes
[ERROR]
and colours the message red.Parameters: message ( str
) – message to log.
-
py_trees.console.
logfatal
(message)[source]¶ Prefixes
[FATAL]
and colours the message bold red.Parameters: message ( str
) – message to log.
-
py_trees.console.
loginfo
(message)[source]¶ Prefixes
[ INFO]
to the message.Parameters: message ( str
) – message to log.
-
py_trees.console.
logwarn
(message)[source]¶ Prefixes
[ WARN]
and colours the message yellow.Parameters: message ( str
) – message to log.
-
py_trees.console.
read_single_keypress
()[source]¶ Waits for a single keypress on stdin.
This is a silly function to call if you need to do it a lot because it has to store stdin’s current setup, setup stdin for reading single keystrokes then read the single keystroke then revert stdin back after reading the keystroke.
Returns: the character of the key that was pressed Return type: int
Raises: KeyboardInterrupt
– if CTRL-C was pressed (keycode 0x03)
py_trees.decorators¶
Decorators are behaviours that manage a single child and provide common modifications to their underlying child behaviour (e.g. inverting the result). That is, they provide a means for behaviours to wear different ‘hats’ and this combinatorially expands the capabilities of your behaviour library.

An example:
![digraph life {
graph [fontname="times-roman"];
node [fontname="times-roman"];
edge [fontname="times-roman"];
Life [fillcolor=orange, fontcolor=black, fontsize=11, shape=box, style=filled];
Inverter [fillcolor=ghostwhite, fontcolor=black, fontsize=11, shape=ellipse, style=filled];
Life -> Inverter;
"Busy?" [fillcolor=gray, fontcolor=black, fontsize=11, shape=ellipse, style=filled];
Inverter -> "Busy?";
Timeout [fillcolor=ghostwhite, fontcolor=black, fontsize=11, shape=ellipse, style=filled];
Life -> Timeout;
"Have a Beer!" [fillcolor=gray, fontcolor=black, fontsize=11, shape=ellipse, style=filled];
Timeout -> "Have a Beer!";
}](_images/graphviz-48aa7f2f538fca61152ca1c401fe49093f74cd0d.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
import py_trees.decorators
import py_trees.display
if __name__ == '__main__':
root = py_trees.composites.Sequence(name="Life")
timeout = py_trees.decorators.Timeout(
name="Timeout",
child=py_trees.behaviours.Success(name="Have a Beer!")
)
failure_is_success = py_trees.decorators.Inverter(
name="Inverter",
child=py_trees.behaviours.Success(name="Busy?")
)
root.add_children([failure_is_success, timeout])
py_trees.display.render_dot_tree(root)
|
Decorators (Hats)
Decorators with very specific functionality:
py_trees.decorators.Condition
py_trees.decorators.EternalGuard
py_trees.decorators.Inverter
py_trees.decorators.OneShot
py_trees.decorators.StatusToBlackboard
py_trees.decorators.Timeout
And the X is Y family:
py_trees.decorators.FailureIsRunning
py_trees.decorators.FailureIsSuccess
py_trees.decorators.RunningIsFailure
py_trees.decorators.RunningIsSuccess
py_trees.decorators.SuccessIsFailure
py_trees.decorators.SuccessIsRunning
Decorators for Blocking Behaviours
It is worth making a note of the effect of decorators on
behaviours that return RUNNING
for
some time before finally returning SUCCESS
or FAILURE
(blocking behaviours) since
the results are often at first, surprising.
A decorator, such as py_trees.decorators.RunningIsSuccess()
on
a blocking behaviour will immediately terminate the underlying child and
re-intialise on it’s next tick. This is necessary to ensure the underlying
child isn’t left in a dangling state (i.e.
RUNNING
), but is often not what is being
sought.
The typical use case being attempted is to convert the blocking
behaviour into a non-blocking behaviour. If the underlying child has no
state being modified in either the initialise()
or terminate()
methods (e.g. machinery is
entirely launched at init or setup time), then conversion to a non-blocking
representative of the original succeeds. Otherwise, another approach is
needed. Usually this entails writing a non-blocking counterpart, or
combination of behaviours to affect the non-blocking characteristics.
-
class
py_trees.decorators.
Condition
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, status=<Status.SUCCESS: 'SUCCESS'>)[source]¶ Bases:
py_trees.decorators.Decorator
Encapsulates a behaviour and wait for it’s status to flip to the desired state. This behaviour will tick with
RUNNING
while waiting andSUCCESS
when the flip occurs.
-
class
py_trees.decorators.
Decorator
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.behaviour.Behaviour
A decorator is responsible for handling the lifecycle of a single child beneath
Parameters: - child (
Behaviour
) – the child to be decorated - name – the decorator name
Raises: -
stop
(new_status)[source]¶ As with other composites, it checks if the child is running and stops it if that is the case.
Parameters: new_status ( Status
) – the behaviour is transitioning to this new status
-
tick
()[source]¶ A decorator’s tick is exactly the same as a normal proceedings for a Behaviour’s tick except that it also ticks the decorated child node.
Yields: Behaviour
– a reference to itself or one of its children
-
tip
()[source]¶ Get the tip of this behaviour’s subtree (if it has one) after it’s last tick. This corresponds to the the deepest node that was running before the subtree traversal reversed direction and headed back to this node.
Returns: child behaviour, itself or None
if its status isINVALID
Return type: Behaviour
orNone
- child (
-
class
py_trees.decorators.
EternalGuard
(*, child, condition, blackboard_keys=[], name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
A decorator that continually guards the execution of a subtree. If at any time the guard’s condition check fails, then the child behaviour/subtree is invalidated.
Note
This decorator’s behaviour is stronger than the guard typical of a conditional check at the beginning of a sequence of tasks as it continues to check on every tick whilst the task (or sequence of tasks) runs.
Parameters: - child (
Behaviour
) – the child behaviour or subtree - condition (
Union
[Callable
[[Blackboard
],bool
],Callable
[[Blackboard
],Status
]]) – a functional check that determines execution or not of the subtree - blackboard_keys (
Set
[str
]) – provide read access for the conditional function to these keys - name (
str
) – the decorator name
Examples:
Simple conditional function returning True/False:
def check(): return True foo = py_trees.behaviours.Foo() eternal_guard = py_trees.decorators.EternalGuard( name="Eternal Guard, condition=check, child=foo )
Simple conditional function returning SUCCESS/FAILURE:
def check(): return py_trees.common.Status.SUCCESS foo = py_trees.behaviours.Foo() eternal_guard = py_trees.decorators.EternalGuard( name="Eternal Guard, condition=check, child=foo )
Conditional function that makes checks against data on the blackboard (the blackboard client with pre-configured access is provided by the EternalGuard instance):
def check(blackboard): return blackboard.velocity > 3.0 foo = py_trees.behaviours.Foo() eternal_guard = py_trees.decorators.EternalGuard( name="Eternal Guard, condition=check, blackboard_keys={"velocity"}, child=foo )
See also
- child (
-
class
py_trees.decorators.
FailureIsRunning
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Dont stop running.
-
class
py_trees.decorators.
FailureIsSuccess
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Be positive, always succeed.
-
class
py_trees.decorators.
Inverter
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
A decorator that inverts the result of a class’s update function.
-
class
py_trees.decorators.
OneShot
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, policy=<OneShotPolicy.ON_SUCCESSFUL_COMPLETION: [<Status.SUCCESS: 'SUCCESS'>]>)[source]¶ Bases:
py_trees.decorators.Decorator
A decorator that implements the oneshot pattern.
This decorator ensures that the underlying child is ticked through to completion just once and while doing so, will return with the same status as it’s child. Thereafter it will return with the final status of the underlying child.
Completion status is determined by the policy given on construction.
- With policy
ON_SUCCESSFUL_COMPLETION
, the oneshot will activate only when the underlying child returnsSUCCESS
(i.e. it permits retries). - With policy
ON_COMPLETION
, the oneshot will activate when the child returnsSUCCESS
||FAILURE
.
See also
-
terminate
(new_status)[source]¶ If returning
SUCCESS
for the first time, flag it so future ticks will block entry to the child.
- With policy
-
class
py_trees.decorators.
RunningIsFailure
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Got to be snappy! We want results…yesterday!
-
class
py_trees.decorators.
RunningIsSuccess
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Don’t hang around…
-
class
py_trees.decorators.
StatusToBlackboard
(*, child, variable_name, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Reflect the status of the decorator’s child to the blackboard.
Parameters:
-
class
py_trees.decorators.
SuccessIsFailure
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
Be depressed, always fail.
-
class
py_trees.decorators.
SuccessIsRunning
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>)[source]¶ Bases:
py_trees.decorators.Decorator
It never ends…
-
class
py_trees.decorators.
Timeout
(child, name=<Name.AUTO_GENERATED: 'AUTO_GENERATED'>, duration=5.0)[source]¶ Bases:
py_trees.decorators.Decorator
A decorator that applies a timeout pattern to an existing behaviour. If the timeout is reached, the encapsulated behaviour’s
stop()
method is called with statusFAILURE
otherwise it will simply directly tick and return with the same status as that of it’s encapsulated behaviour.
py_trees.display¶
Behaviour trees are significantly easier to design, monitor and debug with visualisations. Py Trees does provide minimal assistance to render trees to various simple output formats. Currently this includes dot graphs, strings or stdout.
-
py_trees.display.
ascii_blackboard
(key_filter=None, regex_filter=None, client_filter=None, keys_to_highlight=[], display_only_key_metadata=False, indent=0)[source]¶ Graffiti your console with ascii art for your blackboard.
Parameters: - key_filter (
Union
[Set
[str
],List
[str
],None
]) – filter on a set/list of blackboard keys - regex_filter (
Optional
[str
]) – filter on a python regex str - client_filter (
Union
[Set
[UUID
],List
[UUID
],None
]) – filter on a set/list of client uuids - keys_to_highlight (
List
[str
]) – list of keys to highlight - display_only_key_metadata (
bool
) – read/write access, … instead of values - indent (
int
) – the number of characters to indent the blackboard
Return type: Returns: a unicoded blackboard (i.e. in string form)
Note
registered variables that have not yet been set are marked with a ‘-‘
- key_filter (
-
py_trees.display.
ascii_symbols
= {'space': ' ', 'left_arrow': '<-', 'right_arrow': '->', 'left_right_arrow': '<->', 'bold': '', 'bold_reset': '', <class 'py_trees.composites.Sequence'>: '[-]', <class 'py_trees.composites.Selector'>: '[o]', <class 'py_trees.composites.Parallel'>: '[||]', <class 'py_trees.decorators.Decorator'>: '-^-', <class 'py_trees.behaviour.Behaviour'>: '-->', <Status.SUCCESS: 'SUCCESS'>: 'o', <Status.FAILURE: 'FAILURE'>: 'x', <Status.INVALID: 'INVALID'>: '-', <Status.RUNNING: 'RUNNING'>: '*'}¶ Symbols for a non-unicode, non-escape sequence capable console.
-
py_trees.display.
ascii_tree
(root, show_status=False, visited={}, previously_visited={}, indent=0)[source]¶ Graffiti your console with ascii art for your trees.
Parameters: - root (
Behaviour
) – the root of the tree, or subtree you want to show - show_status (
bool
) – always show status and feedback message (i.e. for every element, not just those visited) - visited (dict) – dictionary of (uuid.UUID) and status (
Status
) pairs for behaviours visited on the current tick - previously_visited (dict) – dictionary of behaviour id/status pairs from the previous tree tick
- indent (
int
) – the number of characters to indent the tree
Returns: an ascii tree (i.e. in string form)
Return type: Examples
Use the
SnapshotVisitor
andBehaviourTree
to generate snapshot information at each tick and feed that to a post tick handler that will print the traversed ascii tree complete with status and feedback messages.def post_tick_handler(snapshot_visitor, behaviour_tree): print( py_trees.display.unicode_tree( behaviour_tree.root, visited=snapshot_visitor.visited, previously_visited=snapshot_visitor.visited ) ) root = py_trees.composites.Sequence("Sequence") for action in ["Action 1", "Action 2", "Action 3"]: b = py_trees.behaviours.Count( name=action, fail_until=0, running_until=1, success_until=10) root.add_child(b) behaviour_tree = py_trees.trees.BehaviourTree(root) snapshot_visitor = py_trees.visitors.SnapshotVisitor() behaviour_tree.add_post_tick_handler( functools.partial(post_tick_handler, snapshot_visitor)) behaviour_tree.visitors.append(snapshot_visitor)
- root (
-
py_trees.display.
dot_tree
(root, visibility_level=<VisibilityLevel.DETAIL: 1>, collapse_decorators=False, with_blackboard_variables=False, with_qualified_names=False)[source]¶ Paint your tree on a pydot graph.
See also
Parameters: - root (
Behaviour
) – the root of a tree, or subtree - visibility_level (optional) – collapse subtrees at or under this level
- collapse_decorators (optional) – only show the decorator (not the child), defaults to False
- with_blackboard_variables (optional) – add nodes for the blackboard variables
- with_qualified_names (optional) – print the class information for each behaviour in each node, defaults to False
Returns: graph
Return type: pydot.Dot
Examples
# convert the pydot graph to a string object print("{}".format(py_trees.display.dot_graph(root).to_string()))
- root (
-
py_trees.display.
render_dot_tree
(root, visibility_level=<VisibilityLevel.DETAIL: 1>, collapse_decorators=False, name=None, target_directory='/home/docs/checkouts/readthedocs.org/user_builds/py-trees/checkouts/release-1.3.x/doc', with_blackboard_variables=False, with_qualified_names=False)[source]¶ Render the dot tree to .dot, .svg, .png. files in the current working directory. These will be named with the root behaviour name.
Parameters: - root (
Behaviour
) – the root of a tree, or subtree - visibility_level (
VisibilityLevel
) – collapse subtrees at or under this level - collapse_decorators (
bool
) – only show the decorator (not the child) - name (
Optional
[str
]) – name to use for the created files (defaults to the root behaviour name) - target_directory (
str
) – default is to use the current working directory, set this to redirect elsewhere - with_blackboard_variables (
bool
) – add nodes for the blackboard variables - with_qualified_names (
bool
) – print the class names of each behaviour in the dot node
Example
Render a simple tree to dot/svg/png file:
root = py_trees.composites.Sequence("Sequence") for job in ["Action 1", "Action 2", "Action 3"]: success_after_two = py_trees.behaviours.Count(name=job, fail_until=0, running_until=1, success_until=10) root.add_child(success_after_two) py_trees.display.render_dot_tree(root)
Tip
A good practice is to provide a command line argument for optional rendering of a program so users can quickly visualise what tree the program will execute.
- root (
-
py_trees.display.
unicode_blackboard
(key_filter=None, regex_filter=None, client_filter=None, keys_to_highlight=[], display_only_key_metadata=False, indent=0)[source]¶ Graffiti your console with unicode art for your blackboard.
Parameters: - key_filter (
Union
[Set
[str
],List
[str
],None
]) – filter on a set/list of blackboard keys - regex_filter (
Optional
[str
]) – filter on a python regex str - client_filter (
Union
[Set
[UUID
],List
[UUID
],None
]) – filter on a set/list of client uuids - keys_to_highlight (
List
[str
]) – list of keys to highlight - display_only_key_metadata (
bool
) – read/write access, … instead of values - indent (
int
) – the number of characters to indent the blackboard
Return type: Returns: a unicoded blackboard (i.e. in string form)
See also
Note
registered variables that have not yet been set are marked with a ‘-‘
- key_filter (
-
py_trees.display.
unicode_blackboard_activity_stream
(activity_stream=None, indent=0)[source]¶ Pretty print the blackboard stream to console.
Parameters: - activity_stream (
Optional
[List
[ActivityItem
]]) – the log of activity, if None, get the entire activity stream - indent (
int
) – the number of characters to indent the blackboard
- activity_stream (
-
py_trees.display.
unicode_symbols
= {'space': ' ', 'left_arrow': '←', 'right_arrow': '→', 'left_right_arrow': '↔', 'bold': '', 'bold_reset': '', <class 'py_trees.composites.Sequence'>: '[-]', <class 'py_trees.composites.Selector'>: '[o]', <class 'py_trees.composites.Parallel'>: '[‖]', <class 'py_trees.decorators.Decorator'>: '-^-', <class 'py_trees.behaviour.Behaviour'>: '-->', <Status.SUCCESS: 'SUCCESS'>: '✓', <Status.FAILURE: 'FAILURE'>: '✕', <Status.INVALID: 'INVALID'>: '-', <Status.RUNNING: 'RUNNING'>: '*'}¶ Symbols for a unicode, escape sequence capable console.
-
py_trees.display.
unicode_tree
(root, show_status=False, visited={}, previously_visited={}, indent=0)[source]¶ Graffiti your console with unicode art for your trees.
Parameters: - root (
Behaviour
) – the root of the tree, or subtree you want to show - show_status (
bool
) – always show status and feedback message (i.e. for every element, not just those visited) - visited (dict) – dictionary of (uuid.UUID) and status (
Status
) pairs for behaviours visited on the current tick - previously_visited (dict) – dictionary of behaviour id/status pairs from the previous tree tick
- indent (
int
) – the number of characters to indent the tree
Returns: a unicode tree (i.e. in string form)
Return type: - root (
-
py_trees.display.
xhtml_symbols
= {'space': '<text> </text>', 'left_arrow': '<text>←</text>', 'right_arrow': '<text>→</text>', 'left_right_arrow': '<text>↔</text>', 'bold': '<b>', 'bold_reset': '</b>', <class 'py_trees.composites.Sequence'>: '<text>[-]</text>', <class 'py_trees.composites.Selector'>: '<text>[o]</text>', <class 'py_trees.composites.Parallel'>: '<text style="color:green;">[‖]</text>', <class 'py_trees.decorators.Decorator'>: '<text>-^-</text>', <class 'py_trees.behaviour.Behaviour'>: '<text>--></text>', <Status.SUCCESS: 'SUCCESS'>: '<text style="color:green;">✓</text>', <Status.FAILURE: 'FAILURE'>: '<text style="color:red;">✕</text>', <Status.INVALID: 'INVALID'>: '<text style="color:darkgoldenrod;">-</text>', <Status.RUNNING: 'RUNNING'>: '<text style="color:blue;">*</text>'}¶ Symbols for embedding in html.
-
py_trees.display.
xhtml_tree
(root, show_status=False, visited={}, previously_visited={}, indent=0)[source]¶ Paint your tree on an xhtml snippet.
Parameters: - root (
Behaviour
) – the root of the tree, or subtree you want to show - show_status (
bool
) – always show status and feedback message (i.e. for every element, not just those visited) - visited (dict) – dictionary of (uuid.UUID) and status (
Status
) pairs for behaviours visited on the current tick - previously_visited (dict) – dictionary of behaviour id/status pairs from the previous tree tick
- indent (
int
) – the number of characters to indent the tree
Returns: an ascii tree (i.e. as a xhtml snippet)
Return type: Examples:
import py_trees a = py_trees.behaviours.Success() b = py_trees.behaviours.Success() c = c = py_trees.composites.Sequence(children=[a, b]) c.tick_once() f = open('testies.html', 'w') f.write('<html><head><title>Foo</title><body>') f.write(py_trees.display.xhtml_tree(c, show_status=True)) f.write("</body></html>")
- root (
py_trees.idioms¶
A library of subtree creators that build complex patterns of behaviours representing common behaviour tree idioms.
-
py_trees.idioms.
eternal_guard
(subtree, name='Eternal Guard', conditions=[], blackboard_variable_prefix=None)[source]¶ The eternal guard idiom implements a stronger guard than the typical check at the beginning of a sequence of tasks. Here they guard continuously while the task sequence is being executed. While executing, if any of the guards should update with status
FAILURE
, then the task sequence is terminated.Parameters: - subtree (
Behaviour
) – behaviour(s) that actually do the work - name (
str
) – the name to use on the root behaviour of the idiom subtree - conditions (
List
[Behaviour
]) – behaviours on which tasks are conditional - blackboard_variable_prefix (
Optional
[str
]) – applied to condition variable results stored on the blackboard (default: derived from the idiom name)
Return type: Returns: the root of the idiom subtree
See also
- subtree (
-
py_trees.idioms.
oneshot
(behaviour, name='Oneshot', variable_name='oneshot', policy=<OneShotPolicy.ON_SUCCESSFUL_COMPLETION: [<Status.SUCCESS: 'SUCCESS'>]>)[source]¶ Ensure that a particular pattern is executed through to completion just once. Thereafter it will just rebound with the completion status.
Note
Set the policy to configure the oneshot to keep trying if failing, or to abort further attempts regardless of whether it finished with status
FAILURE
.Parameters: - behaviour (
Behaviour
) – single behaviour or composited subtree to oneshot - name (
str
) – the name to use for the oneshot root (selector) - variable_name (
str
) – name for the variable used on the blackboard, may be nested - policy (
OneShotPolicy
) – execute just once regardless of success or failure, or keep trying if failing
Returns: the root of the oneshot subtree
Return type: See also
- behaviour (
-
py_trees.idioms.
pick_up_where_you_left_off
(name='Pickup Where You Left Off Idiom', tasks=[])[source]¶ Rudely interrupted while enjoying a sandwich, a caveman (just because they wore loincloths does not mean they were not civilised), picks up his club and fends off the sabre-tooth tiger invading his sanctum as if he were swatting away a gnat. Task accomplished, he returns to the joys of munching through the layers of his sandwich.
Note
There are alternative ways to accomplish this idiom with their pros and cons.
a) The tasks in the sequence could be replaced by a factory behaviour that dynamically checks the state of play and spins up the tasks required each time the task sequence is first entered and invalidates/deletes them when it is either finished or invalidated. That has the advantage of not requiring much of the blackboard machinery here, but disadvantage in not making visible the task sequence itself at all times (i.e. burying details under the hood).
b) A new composite which retains the index between initialisations can also achieve the same pattern with fewer blackboard shenanigans, but suffers from an increased logical complexity cost for your trees (each new composite increases decision making complexity (O(n!)).
Parameters: Returns: root of the generated subtree
Return type:
py_trees.meta¶
Meta methods to create behaviours without needing to create the behaviours themselves.
-
py_trees.meta.
create_behaviour_from_function
(func)[source]¶ Create a behaviour from the specified function, dropping it in for the Behaviour
update()
method. Ths function must include the self argument and return aStatus
value. It also automatically provides a drop-in for theterminate()
method that clears the feedback message. Other methods are left untouched.Parameters: func ( function
) – a drop-in for theupdate()
method
py_trees.timers¶
Time related behaviours.
-
class
py_trees.timers.
Timer
(name='Timer', duration=5.0)[source]¶ Bases:
py_trees.behaviour.Behaviour
Simple timer class that is
RUNNING
until the timer runs out, at which point it isSUCCESS
. This can be used in a wide variety of situations - pause, duration, timeout depending on how it is wired into the tree (e.g. pause in a sequence, duration/timeout in a parallel).The timer gets reset either upon entry (
initialise()
) if it hasn’t already been set and gets cleared when it either runs out, or the behaviour is interrupted by a higher priority or parent cancelling it.Parameters: Raises: TypeError
– if the provided duration is not a real numberNote
This succeeds the first time the behaviour is ticked after the expected finishing time.
Tip
Use the
RunningIsFailure()
decorator if you needFAILURE
until the timer finishes.
py_trees.trees¶
-
class
py_trees.trees.
BehaviourTree
(root)[source]¶ Bases:
object
Grow, water, prune your behaviour tree with this, the default reference implementation. It features a few enhancements to provide richer logging, introspection and dynamic management of the tree itself:
- Pre and post tick handlers to execute code automatically before and after a tick
- Visitor access to the parts of the tree that were traversed in a tick
- Subtree pruning and insertion operations
- Continuous tick-tock support
See also
The py-trees-demo-tree-stewardship program demonstrates the above features.
Parameters: root (
Behaviour
) – root node of the treeVariables: - count (
int
) – number of times the tree has been ticked. - root (
Behaviour
) – root node of the tree - visitors ([
visitors
]) – entities that visit traversed parts of the tree when it ticks - pre_tick_handlers ([
func
]) – functions that run before the entire tree is ticked - post_tick_handlers ([
func
]) – functions that run after the entire tree is ticked
Raises: TypeError
– if root variable is not an instance ofBehaviour
-
add_post_tick_handler
(handler)[source]¶ Add a function to execute after the tree has ticked. The function must have a single argument of type
BehaviourTree
.Some ideas that are often used:
- logging
- modifications on the tree itself (e.g. closing down a plan)
- sending data to visualisation tools
- introspect the state of the tree to make and send reports
Parameters: handler ( func
) – function
-
add_pre_tick_handler
(handler)[source]¶ Add a function to execute before the tree is ticked. The function must have a single argument of type
BehaviourTree
.Some ideas that are often used:
- logging (to file or stdout)
- modifications on the tree itself (e.g. starting a new plan)
Parameters: handler ( func
) – function
-
add_visitor
(visitor)[source]¶ Trees can run multiple visitors on each behaviour as they tick through a tree.
Parameters: visitor ( VisitorBase
) – sub-classed instance of a visitorSee also
-
insert_subtree
(child, unique_id, index)[source]¶ Insert a subtree as a child of the specified parent. If the parent is found, this directly calls the parent’s
insert_child()
method using the child and index arguments.Parameters: Returns: suceess or failure (parent not found) of the operation
Return type: Raises: Todo
Could use better, more informative error handling here. Especially if the insertion has its own error handling (e.g. index out of range). Could also use a different api that relies on the id of the sibling node it should be inserted before/after.
-
interrupt
()[source]¶ Interrupt tick-tock if it is tick-tocking. Note that this will permit a currently executing tick to finish before interrupting the tick-tock.
-
prune_subtree
(unique_id)[source]¶ Prune a subtree given the unique id of the root of the subtree.
Parameters: unique_id (uuid.UUID) – unique id of the subtree root Returns: success or failure of the operation Return type: bool
Raises: RuntimeError
– if unique id is the behaviour tree’s root node id
-
replace_subtree
(unique_id, subtree)[source]¶ Replace the subtree with the specified id for the new subtree. This is a common pattern where we’d like to swap out a whole sub-behaviour for another one.
Parameters: - Raises
- AssertionError: if unique id is the behaviour tree’s root node id
Returns: suceess or failure of the operation Return type: bool
-
setup
(timeout=<Duration.INFINITE: inf>, visitor=None, **kwargs)[source]¶ Crawls across the tree calling
setup()
on each behaviour.Visitors can optionally be provided to provide a node-by-node analysis on the result of each node’s
setup()
before the next node’ssetup()
is called. This is useful on trees with relatively long setup times to progressively report out on the current status of the operation.Parameters: - timeout (
float
) – time (s) to wait (use common.Duration.INFINITE to block indefinitely) - visitor (
VisitorBase
) – runnable entities on each node after it’s setup - **kwargs (
dict
) – distribute arguments to this behaviour and in turn, all of it’s children
Raises: Exception
– be ready to catch if any of the behaviours raise an exceptionRuntimeError
– in case setup() times out
- timeout (
-
shutdown
()[source]¶ Crawls across the tree calling
shutdown()
on each behaviour.Raises: Exception
– be ready to catch if any of the behaviours raise an exception
-
tick
(pre_tick_handler=None, post_tick_handler=None)[source]¶ Tick the tree just once and run any handlers before and after the tick. This optionally accepts some one-shot handlers (c.f. those added by
add_pre_tick_handler()
andadd_post_tick_handler()
which will be automatically run every time).The handler functions must have a single argument of type
BehaviourTree
.Parameters: - pre_tick_handler (
func
) – function to execute before ticking - post_tick_handler (
func
) – function to execute after ticking
- pre_tick_handler (
-
tick_tock
(period_ms, number_of_iterations=-1, pre_tick_handler=None, post_tick_handler=None)[source]¶ Tick continuously with period as specified. Depending on the implementation, the period may be more or less accurate and may drift in some cases (the default implementation here merely assumes zero time in tick and sleeps for this duration of time and consequently, will drift).
This optionally accepts some handlers that will be used for the duration of this tick tock (c.f. those added by
add_pre_tick_handler()
andadd_post_tick_handler()
which will be automatically run every time).The handler functions must have a single argument of type
BehaviourTree
.Parameters:
-
py_trees.trees.
setup
(root, timeout=<Duration.INFINITE: inf>, visitor=None, **kwargs)[source]¶ Crawls across a (sub)tree of behaviours calling
setup()
on each behaviour.Visitors can optionally be provided to provide a node-by-node analysis on the result of each node’s
setup()
before the next node’ssetup()
is called. This is useful on trees with relatively long setup times to progressively report out on the current status of the operation.Parameters: - root (
Behaviour
) – unmanaged (sub)tree root behaviour - timeout (
float
) – time (s) to wait (use common.Duration.INFINITE to block indefinitely) - visitor (
Optional
[VisitorBase
]) – runnable entities on each node after it’s setup - **kwargs – dictionary of arguments to distribute to all behaviours in the (sub) tree
Raises: Exception
– be ready to catch if any of the behaviours raise an exceptionRuntimeError
– in case setup() times out
- root (
py_trees.utilities¶
Assorted utility functions.
-
py_trees.utilities.
get_fully_qualified_name
(instance)[source]¶ Get at the fully qualified name of an object, e.g. an instance of a
Sequence
becomes ‘py_trees.composites.Sequence’.Parameters: instance ( object
) – an instance of any classReturns: the fully qualified name Return type: str
-
py_trees.utilities.
get_valid_filename
(s)[source]¶ Return the given string converted to a string that can be used for a clean filename (without extension). Remove leading and trailing spaces; convert other spaces and newlines to underscores; and remove anything that is not an alphanumeric, dash, underscore, or dot.
>>> utilities.get_valid_filename("john's portrait in 2004.jpg") 'johns_portrait_in_2004.jpg'
Parameters: program ( str
) – string to convert to a valid filenameReturns: a representation of the specified string as a valid filename Return type: str
-
py_trees.utilities.
static_variables
(**kwargs)[source]¶ This is a decorator that can be used with python methods to attach initialised static variables to the method.
@static_variables(counter=0) def foo(): foo.counter += 1 print("Counter: {}".format(foo.counter))
py_trees.visitors¶
Visitors are entities that can be passed to a tree implementation
(e.g. BehaviourTree
) and used to either visit
each and every behaviour in the tree, or visit behaviours as the tree is
traversed in an executing tick. At each behaviour, the visitor
runs its own method on the behaviour to do as it wishes - logging, introspecting, etc.
Warning
Visitors should not modify the behaviours they visit.
-
class
py_trees.visitors.
DebugVisitor
[source]¶ Bases:
py_trees.visitors.VisitorBase
Picks up and logs feedback messages and the behaviour’s status. Logging is done with the behaviour’s logger.
-
class
py_trees.visitors.
DisplaySnapshotVisitor
(display_blackboard=False, display_activity_stream=False)[source]¶ Bases:
py_trees.visitors.SnapshotVisitor
Visit the tree, capturing the visited path, it’s changes since the last tick and additionally print the snapshot to console.
Parameters: -
finalise
()[source]¶ Override this method if any work needs to be performed after ticks (i.e. showing data).
-
-
class
py_trees.visitors.
SnapshotVisitor
[source]¶ Bases:
py_trees.visitors.VisitorBase
Visits the ticked part of a tree, checking off the status against the set of status results recorded in the previous tick. If there has been a change, it flags it. This is useful for determining when to trigger, e.g. logging.
Variables: - changed (Bool) – flagged if there is a difference in the visited path or
Status
of any behaviour on the path - visited (dict) – dictionary of behaviour id (uuid.UUID) and status (
Status
) pairs from the current tick - previously_visited (dict) – dictionary of behaviour id (uuid.UUID) and status (
Status
) pairs from the previous tick - running_nodes ([uuid.UUID]) – list of id’s for behaviours which were traversed in the current tick
- previously_running_nodes ([uuid.UUID]) – list of id’s for behaviours which were traversed in the last tick
See also
The py-trees-demo-logging program demonstrates use of this visitor to trigger logging of a tree serialisation.
- changed (Bool) – flagged if there is a difference in the visited path or
-
class
py_trees.visitors.
VisitorBase
(full=False)[source]¶ Bases:
object
Parent template for visitor types.
Visitors are primarily designed to work with
BehaviourTree
but they can be used in the same way for other tree custodian implementations.Parameters: full ( bool
) – flag to indicate whether it should be used to visit only traversed nodes or the entire treeVariables: full ( bool
) – flag to indicate whether it should be used to visit only traversed nodes or the entire tree-
finalise
()[source]¶ Override this method if any work needs to be performed after ticks (i.e. showing data).
-