Open AlexKaravaev opened 3 years ago
Perhaps you haven't written anything to the blackboard yet? Registering a key just informs the blackboard what access the client has to the specified variable. It doesn't actually populate the variable, you'll have to write to the blackboard first.
Example program:
#!/usr/bin/env python
import py_trees
class Stop:
def __init__(self):
self.data = 5
blackboard = py_trees.blackboard.Client(name="stop_client")
blackboard.register_key(key="/stop", access=py_trees.common.Access.WRITE)
print(f"{py_trees.display.unicode_blackboard()}")
blackboard.stop = Stop()
print(f"Stop : {blackboard.get('stop.data')}")
print(f"{py_trees.display.unicode_blackboard()}")
With output:
Blackboard Data
/stop: -
Stop : 5
Blackboard Data
/stop: <__main__.Stop object at 0x7f7693a29400>
The '-' indicates that it's a registered variable, but hasn't been populated yet.
No, it was definitely written to. I am not able to come up right now with MWE, but I had set-up like this:
1) 1st terminal launching ros2 node and registering value at blackboard 2) 2st terminal publishing value to topic and behavior from 1st terminal(node) writes it to blackboard 3) 3st trying to access this variable from another node using just py_trees will not succeed. However, using cli tool(blackboard-watcher or something like that, do not remember name exactly) shows that blackboard value is populated. Also, using py_trees_ros.blackboard.blackboardWatcher works too, but I don't like that way, because it creates additional overhead of creating and subscribing to topic.
You're trying to access the blackboard from a process in the 1st terminal from a separate process in the 3rd terminal?
The blackboard is in-memory (RAM) storage accessible only if you're in the same process. If you are in a different process, you absolutely need some kind of middleware (pubs and subs) to ferry the data.
py_trees.blackboard.Blackboard.Client
py-trees-blackboard-watcher
or py_trees_ros.blackboard.BlackboardWatcher
.Admittedly, I hadn't expected anyone to want to use something like BlackboardWatcher
directly. I'd written that purely to service the py-trees-blackboard-watcher
debugging tool, but it's not very usable on it's own (just look at all the glue in py_trees_ros.programs.blackboard_watcher.py
).
What you might be wanting is something convenient that (partially) mirrors the blackboard in that other process so, for example, you can make use of the py_trees.blackboard.Client
api. For that, I imagine it would be a new class (e.g. MirrorBlackboard
) that hides all of the middleware ugliness, initialisation and termination logic, but reconstructs the blackboard for pure pythonic access in that process. Is this sounding more along the lines of what you are looking for?
Okay, I see. I thought that key-value storage for blackboard is accessible for all of the system(like a small DB).
Just out of the curiosity, why you have chosen to do blackboard only accessible within the process? Because, I was looking for kind of 'ros parameter server' blackboard. I just want to separate parameters and values that are indented to change the behavior of the agent(these goes to blackboard) and pure configurational stuff, like baudrate, map size etc..(these goes to parameter server).
For me particular use case was like this: I have robot and want to add the functionality of stopping/going forward. I made a web-page with GUI button for that. Ideally, I want to write from that web-page to the blackboard value True/False to the /stop blackboard variable. On the robot ros2 is running and controls all the things within the robot. One of the nodes, that is maintaining behavior will read that variable and report robot to be stopped.
Your last proposal is about mirroring the blackboard could be the solution, but I for me it is a little bit clunky, with adding all the middleware things like creating topic for value retrieval. If there would be a way to get the blackboard variable from different process with ros2 service call for example, it would be much more convenient, I think. Unless, off course, there are some underlying reasons of not doing so.
Just FYI I really liked py-trees in terms of things it can do with behavior trees and after all I think it's like one and only ros-compatible python-solution out there. I have encountered paper about behaviour trees frameworks review and your project was I think literally the only one which is written in python and compatible with ros and still maintained.
Late reply, but for completeness...
Just out of the curiosity, why you have chosen to do blackboard only accessible within the process?
There are many non-ros applications of blackboards and they all need blackboards, so the initial design had to work for a core library that does not have ROS (or some other higher level framework).
py_trees_ros
is intended to provide conveniences, exactly like the watcher and the kind of blackboard 'server' we were talking about here. Such a 'server' would be a nice addition. Why not already? Simply just effort and not having a use case come along that wanted it.
Hi there!
I am struggling to get blackboard variable from one of my nodes, approaches I've tried: 1) Creating blackboard client in node init
And then getting variable like this
But it tells me that ther is no such variable, though I can get it from running
py-trees-blackboard-watcher
2) Creating blackboard watcher
But this way it creates new topic and the way for me to get blackboard variable is to subscribe to this topic.
Can you please tell me, what way will be the best to get the data inside blackboard variable?