splintered-reality / py_trees

Python implementation of behaviour trees.
Other
415 stars 138 forks source link

What is the equivalent of Ports in py_trees #447

Open KabadagiOmkar opened 3 weeks ago

KabadagiOmkar commented 3 weeks ago

I've been looking for a good, idiomatic way to use behaviors as isolated functions that take input, and produce output. While exploring BehaviourTree.CPP, I found that its port functionality ports example aligns with what I need.

What would be the equivalent approach in py_trees?

I am really looking forward to using this in my next project but I am trying to understand the right way to approach this Input/Output problem instead of a whole global blackboard.

stonier commented 2 weeks ago

It's not too dissimilar. They both have a blackboard for storing key-value pairs.

BehaviorTree.CPP uses the notion of InputPort for defining read access to a key and OutputPort for defining write access to a key.

py_trees has a global blackboard and you can use it that way (great for simple use cases), but it has features that do similar things if you choose to use them. It phrases them in terms of registering read/write access on a key instead of input/output ports though. e.g.

blackboard.register_key(key="foo", access=py_trees.common.Access.WRITE)
blackboard.register_key(key="bar", access=py_trees.common.Access.READ)

You can get a dotgraph to see the data flow through the behaviors for a given tick (blue boxes and arrows):

data_flow

In addition, you get a runtime activity stream so you can see what keys are getting tickled on any given tick (this can really help with debugging, since you often accidentally skip a node earlier in the tree that is supposed to be writing to a key).

activity_stream

It also gives behaviors the option to create namespaced blackboard clients - this effectively gives you scoped access to the blackboard and can let you set up namespaces that act as private state for a behavior. You can also alias keys so that a globally shared key is more reasonably named internally (/parameters below is a good example of a private namespace for a behavior).

blackboard_namespaces

And finally, you can remap keys so a behavior tree integrator can get behaviors owned by different groups with different defaults for key names to communicate with each other.

What it doesn't have, is tree initialization from something like XML. That's always been a TODO, but I'm not sure I'm too keen on that, since it feels limiting compared to scripting a tree. NB: I might be missing some other features from BehaviorTree.CPP I'm unaware of.