Skip to content

Commit

Permalink
[exchange] bring back in dubious subblackboards from py_trees
Browse files Browse the repository at this point in the history
  • Loading branch information
stonier committed Oct 30, 2019
1 parent 0409c64 commit 4d6ea76
Showing 1 changed file with 73 additions and 2 deletions.
75 changes: 73 additions & 2 deletions py_trees_ros/blackboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# Imports
##############################################################################

import copy
import pickle
import py_trees
import py_trees.console as console
import py_trees_ros_interfaces.srv as py_trees_srvs # noqa
Expand All @@ -34,10 +36,79 @@
from . import utilities

##############################################################################
# SubView of a Blackboard
# Blackboard Helpers
##############################################################################


class SubBlackboard(object):
"""
Dynamically track the entire blackboard or part thereof and
flag when there have been changes. Not really happy with this class
(pickle problems) nor it's name (misleading).
"""
def __init__(self):
self.is_changed = False
self.variable_names = set()
self.pickled_storage = None

def update(self, variable_names: typing.Set[str]):
"""
Check for changes to the blackboard scoped to the provided set of
variable names (may be nested, e.g. battery.percentage). Checks
the entire blackboard when variable_names is None.
Args:
variable_names: constrain the scope to track for changes
"""
# TODO: can we pickle without doing a copy?
# TODO: can we use __repr__ as a means of not being prone to pickle
# i.e. put the work back on the user
# TODO: catch exceptions thrown by bad pickles
# TODO: use a better structure in the blackboard (e.g. JSON) so
# that this isn't brittle w.r.t. pickle failures
if variable_names is None:
storage = copy.deepcopy(py_trees.blackboard.Blackboard.storage)
self.variable_names = py_trees.blackboard.Blackboard.keys()
else:
storage = {}
for variable_name in variable_names:
try:
storage[variable_name] = copy.deepcopy(
py_trees.blackboard.Blackboard.get(variable_name)
)
except KeyError:
pass # silently just ignore the request
self.variable_names = variable_names
pickled_storage = pickle.dumps(storage, -1)
self.is_changed = pickled_storage != self.pickled_storage
self.pickled_storage = pickled_storage

def __str__(self):
"""
Convenient printed representation of the sub-blackboard that this
instance is currently tracking.
"""
max_length = 0
indent = " " * 4
s = ""
for name in self.variable_names:
max_length = len(name) if len(name) > max_length else max_length
for name in sorted(self.variable_names):
try:
value = py_trees.blackboard.Blackboard.get(name)
lines = ("%s" % value).split('\n')
if len(lines) > 1:
s += console.cyan + indent + '{0: <{1}}'.format(name, max_length + 1) + console.reset + ":\n"
for line in lines:
s += console.yellow + " %s" % line + console.reset + "\n"
else:
s += console.cyan + indent + '{0: <{1}}'.format(name, max_length + 1) + console.reset + ": " + console.yellow + "%s" % (value) + console.reset + "\n"
except KeyError:
value_string = "-"
s += console.cyan + indent + '{0: <{1}}'.format(name, max_length + 1) + console.reset + ": " + console.yellow + "%s" % (value_string) + console.reset + "\n"
return s.rstrip() # get rid of the trailing newline...print will take care of adding a new line


class BlackboardView(object):
"""
Utility class that enables tracking and publishing of relevant
Expand All @@ -60,7 +131,7 @@ def __init__(
):
self.topic_name = topic_name
self.variable_names = variable_names
self.sub_blackboard = py_trees.blackboard.SubBlackboard()
self.sub_blackboard = SubBlackboard()
self.sub_activity_stream = py_trees.blackboard.ActivityStream()
self.node = node
self.publisher = self.node.create_publisher(
Expand Down

0 comments on commit 4d6ea76

Please sign in to comment.