py_trees icon indicating copy to clipboard operation
py_trees copied to clipboard

Best practices to handle namespacing to avoid blackboard key conflicts?

Open advaypakhale opened this issue 7 months ago • 4 comments

Hi everyone, we are a university robotics team which recently switched over from BehaviorTree.CPP to py_trees, and while starting over, we wanted to do things the right way. Just wanted to check in with the community to see if there are any best practices for handling blackboard key conflicts, especially in situations where there are many trees defined across many individual python files.

Currently, we foresee a problem where a key might be poorly named something like "pose", and this might conflict with another key defined with the same name somewhere else (especially when we are implementing quick hot fixes during competitions where good variable naming isn't the top priority).

The py_trees.blackboard.Client does provide a namespace parameter, but then again most common blackboard behaviours in py_trees and py_trees_ros do not expose the namespace parameter of the underlying blackboard client so that it can be set.

What we are currently doing is:

  1. Define a global NAMESPACE variable in each python file defining a tree, based on directory structure (this is consistent in our case).
  2. Use a helper function (that essentially calls py_trees.blackboard.Blackboard.absolute_name) on all key names before being passed to any behaviours, that prepends the namespace to the key name. However, this can get a bit annoying at times.
  3. For our own custom behaviours, we designed them to accept a namespace parameter, which the internal blackboard client is initialised with. This way we don't have to apply the helper function to key names every time.

We aren't a 100% happy with this though, especially because of all the repetitive calling of the helper function which clutters up the code quickly. If anyone could share any experience or ideas they have had with a similar issue, that would be much appreciated. Thank you!

advaypakhale avatar May 20 '25 16:05 advaypakhale

I'm not saying this is best practice, but I created a wrapper around blackboards, that created namespaced clients (motion, perception, and state). I then tell people to name variables appropriately with the appropriate client. This seems heavy have, but I've learned from experience sometimes you need to be.

erichlf avatar May 20 '25 16:05 erichlf

I'm not saying this is best practice, but I created a wrapper around blackboards, that created namespaced clients (motion, perception, and state). I then tell people to name variables appropriately with the appropriate client. This seems heavy have, but I've learned from experience sometimes you need to be.

Thanks for your input! We considered doing something similar by subclassing or modifying some of the more commonly used blackboard related behaviours with a small tweak to pass in a namespace parameter that then gets passed to the blackboard client. But in the end we limited this change to only our custom behaviours and not those that py_trees or py_trees_ros provide, because risks us missing out on upstream bug fixes.

Awesome job with py_trees_parser btw!

advaypakhale avatar May 20 '25 17:05 advaypakhale

I wrapped the Blackboard class; I didn't derive from it.

erichlf avatar May 20 '25 17:05 erichlf

We've done something very similar -- inherited the py_trees.behaviour.Behaviour class to look more like BehaviorTree.CPP, including setting input and output ports that wrap the use of the blackboard.

This was useful mostly to reduce boilerplate, but needed more care to properly handle namespaces at the "sub-tree" level (which BTW PyTrees also doesn't have officially). This resulted in us also subclassing composites such as Sequence, Fallback, and Parallel, and adding specific add_child() implementations that ensure the blackboard keys in those children have consistent namespacing. I can't claim that the solution we have for namespacing is my favorite, but it works!

sea-bass avatar May 26 '25 16:05 sea-bass