Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the easiest way to get blackboard variable from rclpy node? #171

Open
AlexKaravaev opened this issue Feb 18, 2021 · 5 comments
Open

Comments

@AlexKaravaev
Copy link

AlexKaravaev commented Feb 18, 2021

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
	
		self.blackboard = py_trees.blackboard.Client(name="stop_client")
		self.blackboard.register_key(key="/stop", access=py_trees.common.Access.WRITE)

And then getting variable like this

self.get_logger().info(f"Stop ? {self.blackboard.get('/stop.data')}")

But it tells me that ther is no such variable, though I can get it from running py-trees-blackboard-watcher

  1. Creating blackboard watcher
		self.blackboard_watcher = py_trees_ros.blackboard.BlackboardWatcher(
        	namespace_hint=""
    	)
		self.blackboard_watcher.setup(timeout_sec=2.0)

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?

@stonier
Copy link
Member

stonier commented Feb 22, 2021

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.

@AlexKaravaev
Copy link
Author

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.

@stonier
Copy link
Member

stonier commented Feb 24, 2021

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.

  • IntraProcess (Same Process): py_trees.blackboard.Blackboard.Client
  • InterProcess (Different Process): using the ros middleware via 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?

@AlexKaravaev
Copy link
Author

AlexKaravaev commented Feb 25, 2021

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.

@stonier
Copy link
Member

stonier commented May 30, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants