compas_fab
compas_fab copied to clipboard
Add partial order plan datastructure
Create a partial order plan data structure that is compatible with RRC execution, and flexible enough to represent generic fabrication processes as a directed acyclic graph (ie tasks connected by their dependencies). This data structure could be used both for task generation and assembly sequencing.
Prototype available in https://github.com/dbt-ethz/A032-CE3DP/blob/master/CE3DP%20slicer/cSlicer/partial_order_plan.py
where'd the prototype run off to?
Ouh sorry, I totally missed your previous comment in a sea of notification emails. Looks like the link is private, here's a code snippet of the class:
from compas.utilities import DataEncoder
from compas.utilities import DataDecoder
class ProductionData(object):
def __init__(self, actions=[]):
self.actions = {action.id: action for action in actions}
def append_action(self, namespace, action, action_id=None, dependency_ids=None):
action_id = self.get_next_action_id() or action_id
dependency_ids = [action_id - 1] if dependency_ids is None else dependency_ids
partial_order_action = PartialOrderAction(action_id, namespace, action, dependency_ids)
self.actions[action_id] = partial_order_action
def get_next_action_id(self):
if len(self.actions) == 0:
return 1
return sorted(self.actions.keys())[-1] + 1
def get_namespaces(self):
return set(a.namespace for a in self.actions.values())
@property
def data(self):
return dict(
actions=[p.to_data() for p in self.actions.values()]
)
@classmethod
def from_data(cls, data):
return cls([PartialOrderAction.from_data(d) for d in data['actions']])
def to_data(self):
return self.data
class PartialOrderAction(object):
def __init__(self, action_id, namespace, action, dependency_ids):
self.id = action_id
self.namespace = namespace
self.action = action
self.dependency_ids = dependency_ids
def __str__(self):
return 'PartialOrderAction<id={}, namespace={}, action={}>'.format(self.id, self.namespace, self.action)
@property
def data(self):
return dict(
id=self.id,
namespace=self.namespace,
action=self.action.to_data(),
dependency_ids=self.dependency_ids,
)
@classmethod
def from_data(cls, data):
return cls(data['id'], data['namespace'], Action.from_data(data['action']), data['dependency_ids'])
def to_data(self):
return self.data
class Action(object):
def __init__(self, name, parameters={}):
self.name = name
self.parameters = parameters
def __str__(self):
return 'Action<name={}>'.format(self.name)
@property
def data(self):
return dict(
name=self.name,
parameters={param_key: DataEncoder().default(p) if hasattr(p, 'to_data') else p for param_key, p in self.parameters.items()},
)
@classmethod
def from_data(cls, data):
return cls(data['name'], {param_key: DataDecoder().object_hook(p) if hasattr(p, '__iter__') else p for param_key, p in data['parameters'].items()})
def to_data(self):
return self.data