Skip to content
Snippets Groups Projects
Commit cc48280e authored by mehtank's avatar mehtank
Browse files

Generate component compositional hierarchy tree

parent c6b3467b
Branches
No related merge requests found
......@@ -9,7 +9,7 @@ from os.path import realpath
from os.path import relpath
__version__ = "0.2.1"
__version__ = "0.2.2"
__author__ = 'UCLA LEMUR'
__credits__ = 'The Laboratory for Embedded Machines and Ubiquitous Robots'
......
......@@ -14,32 +14,51 @@ ROCOLIB_LIBRARY = dirname(realpath(__file__))
pyComponents = [ basename(f)[:-3] for f in glob(ROCOLIB_LIBRARY + "/[!_]*.py")]
yamlComponents = [ basename(f)[:-5] for f in glob(ROCOLIB_LIBRARY + "/*.yaml")]
allComponents = list(set(pyComponents + yamlComponents))
allComponents = set(pyComponents + yamlComponents)
def getSubcomponents(c):
try:
return set((x['classname'] for x in load_yaml(c).get('subcomponents', dict()).values()))
except FileNotFoundError:
return set()
def getComponentTree():
tree = []
ac = set(allComponents)
while ac:
leaves = []
for c in ac:
subcomponents = getSubcomponents(c)
if not subcomponents.intersection(ac):
leaves.append(c)
tree.append(sorted(leaves))
ac -= set(leaves)
return tree
def getComponent(c, **kwargs):
'''
Here we are doing Dynamic instantiation from string name of a class in dynamically imported module
Parameter c (str): component name e.g. 'Stool'
'''
if c in pyComponents:
# Load "module.submodule.MyClass"
obj = getattr(importlib.import_module("rocolib.library." + c), c)
# Instantiate the class (pass arguments to the constructor, if needed)
my_obj = obj()
elif c in yamlComponents:
my_obj = Component(f"{ROCOLIB_LIBRARY}/{c}.yaml")
else:
raise ValueError(f"Component {c} not found in library")
for k, v in kwargs.items():
if k == 'name':
my_obj.setName(v)
'''
Here we are doing Dynamic instantiation from string name of a class in dynamically imported module
Parameter c (str): component name e.g. 'Stool'
'''
if c in pyComponents:
# Load "module.submodule.MyClass"
obj = getattr(importlib.import_module("rocolib.library." + c), c)
# Instantiate the class (pass arguments to the constructor, if needed)
my_obj = obj()
elif c in yamlComponents:
my_obj = Component(f"{ROCOLIB_LIBRARY}/{c}.yaml")
else:
my_obj.setParameter(k, v)
if 'name' not in kwargs:
my_obj.setName(c)
raise ValueError(f"Component {c} not found in library")
for k, v in kwargs.items():
if k == 'name':
my_obj.setName(v)
else:
my_obj.setParameter(k, v)
if 'name' not in kwargs:
my_obj.setName(c)
return my_obj
return my_obj
def rebuild(built=None):
if built is None:
......@@ -71,7 +90,7 @@ def rebuildComponent(c, built=None, throw=True):
for sc in subcomponents:
rebuildComponent(sc, built)
# XXX TOOD: Test to make sure we don't call this script and then infinitely recurse!
# XXX TODO: Test to make sure we don't call this script and then infinitely recurse!
log.debug(f"Calling os.system: % python {ROCOLIB_LIBRARY}/{src}")
if system(f"python {ROCOLIB_LIBRARY}/{src}"):
success = False
......@@ -94,57 +113,3 @@ def getComponentPaths(c):
if src:
paths["builder"] = rocopath(join(ROCOLIB_LIBRARY, src))
return paths
# tag : [[required ports], [forbidden ports]]
tagDefinitions = {
'sensor': [["DataOutputPort"],[]],
'actuator': [["DataInputPort"],[]],
'mechanical': [["EdgePort"],[]],
'device': [["MountPort"],[]],
'UI': [[],["MountPort", "EdgePort"]]
}
def tag(ports):
tags = {}
portset = set(ports.keys())
for tag, (must, cant) in tagDefinitions.items():
if set(must).issubset(portset) and not len(set(cant).intersection(portset)):
tags[tag] = [port for ptype in must for port in ports[ptype] ]
return tags
_taggedComponents = {}
def getTags(x):
if x in _taggedComponents:
return _taggedComponents[x]
try:
c = getComponent(x)
except:
return None
if isinstance(c, Component):
interfaces = list(c.interfaces.keys())
ports = {}
for iname in interfaces:
i = c.getInterface(iname)
iclass = i.__class__.__name__
try:
ports[iclass].append(iname)
except KeyError:
ports[iclass] = [iname]
_taggedComponents[x] = tag(ports)
return tag(ports)
return None
def taggedComponents(components = None):
if components == None:
components = allComponents
for x in components:
if getTags(x):
yield x, getTags(x)
def filterComponents(tagList, components = None):
for x, tags in taggedComponents(components):
if set(tagList).issubset(set(tags.keys())):
yield x, [port for tag in tagList for port in tags[tag] ]
from rocolib.library import filterComponents
print("~~~")
print("Actuators")
print("~~~")
'''
print "All:"
for c in filterComponents(["actuator"]):
print "-", c
'''
print("Mechanical actuators:")
for c in filterComponents(["actuator", "mechanical"]):
print("-", c)
print("Physical interface devices:")
for c in filterComponents(["actuator", "device"]):
print("-", c)
print("Virtual UI widgets:")
for c in filterComponents(["actuator", "UI"]):
print("-", c)
print()
print("~~~")
print("Sensors")
print("~~~")
'''
print "All:"
for c in filterComponents(["sensor"]):
print "-", c
print "Mechanical feedback sensors:"
for c in filterComponents(["sensor", "mechanical"]):
print "-", c
'''
print("Environmental sensing devices:")
for c in filterComponents(["sensor", "device"]):
print("-", c)
print("Virtual UI widgets:")
for c in filterComponents(["sensor", "UI"]):
print("-", c)
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment