Utilities

Logging

Logging is implemented in logging.py.

Some logging mechanism is foreseen between this library and the logging routines of ROS2. This allows us to do two things:

  • logging to console when ROS2 is not present.
  • offer some granularity with logging classes by using categories. Code that logs gets a log object by specifying a category. Uses can set the logger that belongs to a category. Example of categories are default, state (logging entering and leaving of each state), service (logging of service calls to ROS2)

See the documentation of set_logger() below.

For example, your main could contain:

set_logger("default",my_node.get_logger())
set_logger("service",my_node.get_logger())
set_logger("state",my_node.get_logger())
This sets the ROS2 logger for all of the above categories.

betfsm_ros.expand_package_ref(pth)

expands all occurencies of $PACKAGENAME] to the ROS2 packages they refer to.

Parameters:
  • pth (str) –

    string to expand

betfsm_ros.expand_env_ref(pth)

expands all occurencies of $[ENVVAR] or $ENVVAR to the ROS2 packages they refer to. Parameters: pth: string to expand

betfsm_ros.expand_ref(pth)

Expands both package references and environment variables.

Parameters:
  • pth (str) –

    string to expand

betfsm.logger.set_logger(category, logger)

Use this to set the logger, either LogPrinter() or ROS2node.get_logger()

Parameters:
  • category (str) –

    arbitrary name. You can associate a specific LogPrinter to a name, You probably want to specify at least the "default" logger (if not LogPrinter() is used, i.e. to Console)

  • logger (Logger) –

    Logger to associate with this category.

betfsm.logger.get_logger(category='default')

Use this to get a logger

Parameters:
  • category (str, default: 'default' ) –

    arbitrary name. You can associate a specific LogPrinter to a name, if not specified, "default" is used.

making a list of outcomes unique

betfsm.cleanup_outcomes(outcomes)

cleans up a list of outcomes by elliminating duplicates.

Parameters:
  • outcomes (List[str]) –

    list of outcomes with possibly duplicate elements.

Returns:
  • List[str]

    list of outcomes with duplicate elements elliminated.

Hierarchical Path Syntax for Blackboard Access

The blackboard is a nested structure composed of dictionaries and lists. Values inside this structure can be accessed or modified using a path string, where components are separated by "/" (e.g. "users/list/0").

This extended syntax supports: - dictionary navigation - list indexing - list operations (length, append, insert, delete, pop) All operators are chosen to be URL‑safe and easy to type directly in a browser.

Basic rules

  • Each path component is separated by "/".
  • Dictionary keys are addressed by name: "config/system/mode"
  • List elements are addressed by numeric indices: "users/0/name"

List Operators

The following operators apply when the current node is a list:

  • "~len" Returns the length of the list. Example: "users/~len"

  • "~append" Appends a new value to the list. Example: "users/~append"

  • "~insert:N" Inserts a value at index N. Example: "users/~insert:2"

  • "~del:N" Deletes the element at index N. Example: "users/~del:1"

  • "~pop" Removes the last element Example: "users/~pop"

  • "N" (digit) Replaces or retrieves the element at index N. Example: "users/3"

Examples

    #  Get a nested dictionary value:
    get_path_value(bb, "settings/ui/theme")

    # Get the third item in a list:
    get_path_value(bb, "users/2")

    # Get the length of a list:
    get_path_value(bb, "users/~len")

    # Append a new user:
    set_path_value(bb, "users/~append", {"name": "Alice"})

    #Insert at index 1:
    set_path_value(bb, "users/~insert:1", {"name": "Bob"})

    # Replace element at index 3:
    set_path_value(bb, "users/3", {"name": "Charlie"})

    # Delete element at index 0:
    set_path_value(bb, "users/~del:0", None)

Notes

  • All operators are ASCII‑only and require no URL encoding.
  • Intermediate dictionaries or lists are created automatically when needed.
  • When replacing a list element by index, the list is auto‑extended with None values if the index is beyond the current length.

betfsm.dumps_blackboard(blackboard, indent_spaces=4)

Recursively constructs a formatted, indented string representing a hierarchical Python data structure.

betfsm.get_path_value(blackboard, path, default=None)

Gets a value in the blackboard at the given path,.

Parameters:
  • blackboard

    Blackboard Dict

  • path

    path to get the value of

  • default

    value to use if not found, by default = None

  • delimiter

    for the path, default='/'

Returns: value: the value at the given location

Note

See Utilities for a more extensive explanation of the mini-language to specify and manipulate the path.

betfsm.set_path_value(blackboard, path, value)

Sets a value in the blackboard at the given pat.

Parameters:
  • blackboard

    Blackboard Dict

  • path

    path to get the value of

  • value

    value to fill in.

Warning

if value is a Dict, only a shallow copy is made! So, if you later change an element of value, it will also change the Blackboard. you can use copy.deepcopy(subtree) to make a deep copy to avoid this.

Note

See Utilities for a more extensive explanation of the mini-language to specify and manipulate the path.

betfsm.get_path_location(blackboard, path, create_missing=True, delimiter='/')

Finds the parent container and key/index for a given path in the blackboard. Optionally creates missing dictionaries (not lists!) along the way.

Parameters:
  • blackboard (dict / list) –

    The root blackboard structure.

  • path (str) –

    The delimiter-separated path string.

  • create_missing (bool, default: True ) –

    If True, missing intermediate dicts are created.

  • delimiter (str, default: '/' ) –

    The path separator (default: '/').

Returns:
  • tuple

    (parent_container, final_key_or_index) if found/created successfully. (None,None) if the path is inconsistent, an index is out of bounds, or if it encounters a special syntax like '~len' as the target.