py_trees.display module

Display utilities for the command line.

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: List[str] | Set[str] | None = None, regex_filter: str | None = None, client_filter: Set[UUID] | List[UUID] | None = None, keys_to_highlight: List[str] | None = None, display_only_key_metadata: bool = False, indent: int = 0) str

Graffiti your console with ascii art for your blackboard.

Args:

key_filter: filter on a set/list of blackboard keys regex_filter: filter on a python regex str client_filter: filter on a set/list of client uuids keys_to_highlight: list of keys to highlight display_only_key_metadata: read/write access, … instead of values indent: the number of characters to indent the blackboard

Returns:

a unicoded blackboard (i.e. in string form)

Note

registered variables that have not yet been set are marked with a ‘-’

py_trees.display.ascii_symbols = {'behaviour': '-->', 'bold': '', 'bold_reset': '', 'decorator': '-^-', 'left_arrow': '<-', 'left_right_arrow': '<->', 'memory': 'M', 'parallel': '/_/', 'right_arrow': '->', 'selector_with_memory': '{o}', 'selector_without_memory': '[o]', 'sequence_with_memory': '{-}', 'sequence_without_memory': '[-]', 'space': ' ', 'synchronised': 's', Status.FAILURE: 'x', Status.INVALID: '-', Status.RUNNING: '*', Status.SUCCESS: 'o'}

Symbols for a non-unicode, non-escape sequence capable console.

py_trees.display.ascii_tree(root: Behaviour, show_only_visited: bool = False, show_status: bool = False, visited: Dict[UUID, Status] | None = None, previously_visited: Dict[UUID, Status] | None = None, indent: int = 0) str

Graffiti your console with ascii art for your trees.

Args:

root: the root of the tree, or subtree you want to show show_only_visited: show only visited behaviours show_status: 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: the number of characters to indent the tree

Returns:

str: an ascii tree (i.e. in string form)

Examples:

Use the SnapshotVisitor and BehaviourTree 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.

images/ascii_tree.png
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(name="Sequence", memory=True)
for action in ["Action 1", "Action 2", "Action 3"]:
    b = py_trees.behaviours.StatusQueue(
        name=action,
        queue=[py_trees.common.Status.RUNNING],
        eventually = py_trees.common.Status.SUCCESS
    )
    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)
py_trees.display.dot_tree(root: Behaviour, visibility_level: VisibilityLevel = VisibilityLevel.DETAIL, collapse_decorators: bool = False, with_blackboard_variables: bool = False, with_qualified_names: bool = False) pydot.Dot

Paint your tree on a pydot graph.

See also

render_dot_tree().

Args:

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:

pydot.Dot: graph

Examples:
# convert the pydot graph to a string object
print("{}".format(py_trees.display.dot_graph(root).to_string()))
py_trees.display.render_dot_tree(root: Behaviour, visibility_level: VisibilityLevel = VisibilityLevel.DETAIL, collapse_decorators: bool = False, name: str | None = None, target_directory: str | None = None, with_blackboard_variables: bool = False, with_qualified_names: bool = False) Dict[str, str]

Render the dot tree to dot, svg, png. files.

By default, these are saved in the current working directory and will be named with the root behaviour name.

Args:

root: the root of a tree, or subtree visibility_level: collapse subtrees at or under this level collapse_decorators: only show the decorator (not the child) name: name to use for the created files (defaults to the root behaviour name) target_directory: default is to use the current working directory, set this to redirect elsewhere with_blackboard_variables: add nodes for the blackboard variables with_qualified_names: 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(name="Sequence", memory=True)
for job in ["Action 1", "Action 2", "Action 3"]:
    success_after_two = py_trees.behaviours.StatusQueue(
        name=job,
        queue=[py_trees.common.Status.RUNNING],
        eventually = py_trees.common.Status.SUCCESS
    )
    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.

py_trees.display.unicode_blackboard(key_filter: List[str] | Set[str] | None = None, regex_filter: str | None = None, client_filter: Set[UUID] | List[UUID] | None = None, keys_to_highlight: List[str] | None = None, display_only_key_metadata: bool = False, indent: int = 0) str

Graffiti your console with unicode art for your blackboard.

Args:

key_filter: filter on a set/list of blackboard keys regex_filter: filter on a python regex str client_filter: filter on a set/list of client uuids keys_to_highlight: list of keys to highlight display_only_key_metadata: read/write access, … instead of values indent: the number of characters to indent the blackboard

Returns:

a unicoded blackboard (i.e. in string form)

Note

registered variables that have not yet been set are marked with a ‘-’

py_trees.display.unicode_blackboard_activity_stream(activity_stream: List[ActivityItem] | None = None, indent: int = 0, show_title: bool = True) str

Pretty print the blackboard stream to console.

Args:

activity_stream: the log of activity, if None, get the entire activity stream indent: the number of characters to indent the blackboard show_title: include the title in the output

py_trees.display.unicode_symbols = {'behaviour': '-->', 'bold': '', 'bold_reset': '', 'decorator': '-^-', 'left_arrow': '←', 'left_right_arrow': '↔', 'memory': 'Ⓜ', 'parallel': '/_/', 'right_arrow': '→', 'selector_with_memory': '{o}', 'selector_without_memory': '[o]', 'sequence_with_memory': '{-}', 'sequence_without_memory': '[-]', 'space': ' ', 'synchronised': '⚡', Status.FAILURE: '✕', Status.INVALID: '-', Status.RUNNING: '*', Status.SUCCESS: '✓'}

Symbols for a unicode, escape sequence capable console.

py_trees.display.unicode_tree(root: Behaviour, show_only_visited: bool = False, show_status: bool = False, visited: Dict[UUID, Status] | None = None, previously_visited: Dict[UUID, Status] | None = None, indent: int = 0) str

Graffiti your console with unicode art for your trees.

Args:

root: the root of the tree, or subtree you want to show show_only_visited: show only visited behaviours show_status: 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: the number of characters to indent the tree

Returns:

str: a unicode tree (i.e. in string form)

py_trees.display.xhtml_symbols = {'behaviour': '<text>--></text>', 'bold': '<b>', 'bold_reset': '</b>', 'decorator': '<text>-^-</text>', 'left_arrow': '<text>&#x2190;</text>', 'left_right_arrow': '<text>&#x2194;</text>', 'memory': '<text>&#x24C2;</text>', 'parallel': '<text style="color:green;">/_/</text>', 'right_arrow': '<text>&#x2192;</text>', 'selector_with_memory': '<text>{o}</text>', 'selector_without_memory': '<text>[o]</text>', 'sequence_with_memory': '<text>{-}</text>', 'sequence_without_memory': '<text>[-]</text>', 'space': '<text>&#xa0;</text>', 'synchronised': '<text>&#9889;</text>', Status.FAILURE: '<text style="color:red;">&#x2715;</text>', Status.INVALID: '<text style="color:darkgoldenrod;">-</text>', Status.RUNNING: '<text style="color:blue;">*</text>', Status.SUCCESS: '<text style="color:green;">&#x2713;</text>'}

Symbols for embedding in html.

py_trees.display.xhtml_tree(root: Behaviour, show_only_visited: bool = False, show_status: bool = False, visited: Dict[UUID, Status] | None = None, previously_visited: Dict[UUID, Status] | None = None, indent: int = 0) str

Paint your tree on an xhtml snippet.

Args:

root: the root of the tree, or subtree you want to show show_only_visited: show only visited behaviours show_status: always show status and feedback message (i.e. for every element, not just those visited) visited: dictionary of (uuid.UUID) and status

(Status) pairs for behaviours visited on the current tick

previously_visited: dictionary of behaviour id/status pairs from the previous tree tick indent: the number of characters to indent the tree

Returns:

an ascii tree (i.e. as a xhtml snippet)

Examples:
import py_trees
a = py_trees.behaviours.Success()
b = py_trees.behaviours.Success()
c = c = py_trees.composites.Sequence(name="Sequence", memory=True, 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>")