diff --git a/cg/freecad/Frames/pddl/Printer_domain.pddl b/cg/freecad/Frames/pddl/Printer_domain.pddl new file mode 100644 index 0000000..044c805 --- /dev/null +++ b/cg/freecad/Frames/pddl/Printer_domain.pddl @@ -0,0 +1,97 @@ +(define (domain Printer) + +(:requirements :strips :typing :fluents :durative-actions) +(:types + printer workspace - zone + part + arm + assembly + human + filament +) + (:predicates + (arm_available ?a - arm) + (part_at ?p - part ?z - zone) + (printer_ready ?p - printer) + (printer_checked ?p - printer) + (printer_at_work ?p - printer) + (part_of ?part - part ?whole - assembly) + (assembly_order ?prev ?next - assembly) + (assembled ?whole - assembly ?z - zone) + (observer_free ?h - human) + (filament_at ?f - filament ?z - zone) + ) + (:functions + ) +(:durative-action print + :parameters ( ?p - part ?pr - printer ) + :duration ( = ?duration 20) + :condition (and + (at start(printer_ready ?pr)) + ) + :effect (and + (at start (not (printer_ready ?pr))) + (at start (printer_at_work ?pr )) + (at end(part_at ?p ?pr)) + (at end (not (printer_at_work ?pr ))) +) + ) +(:durative-action remove + :parameters ( ?p - part ?pr - printer ?z - zone ?a - arm ) + :duration ( = ?duration 1) + :condition (and + (at start (part_at ?p ?pr)) + (at start (arm_available ?a)) + ) + :effect (and + (at start (not (arm_available ?a))) + (at end (part_at ?p ?z)) + (at end (arm_available ?a)) + (at end (printer_ready ?pr)) +) + ) +(:durative-action assemble + :parameters ( ?p - part ?prev ?next - assembly ?z - zone ?arm - arm ?w - workspace ) + :duration ( = ?duration 5) + :condition (and + (at start (assembled ?prev ?w)) + (at start (part_at ?p ?w)) + (at start (part_of ?p ?next)) + (at start (arm_available ?arm)) + (at start (assembly_order ?prev ?next)) + ) + :effect (and + (at start (not (arm_available ?arm))) + (at end (not (part_at ?p ?w))) + (at end (arm_available ?arm)) + (at end (assembled ?next ?w)) +) + ) +(:durative-action printer_check + :parameters ( ?p - printer ?h - human ) + :duration ( = ?duration 1) + :condition (and + (at start ( observer_free ?h )) + ) + :effect (and + (at start (not (observer_free ?h))) + (at end (observer_free ?h)) + (at end (printer_checked ?p)) +) + ) +(:durative-action printer_filament_load + :parameters ( ?p - printer ?h - human ?f - filament ?z - zone ) + :duration ( = ?duration 5) + :condition (and + (at start (printer_checked ?p)) + (at start (observer_free ?h)) + (at start (filament_at ?f ?z)) + ) + :effect (and + (at start (not(observer_free ?h))) + (at end (observer_free ?h)) + (at end (printer_ready ?p)) + (at end (not (filament_at ?f ?z))) +) + ) + ) diff --git a/cg/freecad/Frames/pddl/freecad2pddl.py b/cg/freecad/Frames/pddl/freecad2pddl.py index 9b4dabe..1c22950 100644 --- a/cg/freecad/Frames/pddl/freecad2pddl.py +++ b/cg/freecad/Frames/pddl/freecad2pddl.py @@ -1,43 +1,62 @@ import FreeCAD as App +import FreeCADGui as Gui doc = App.ActiveDocument -#функции для создания обьекта действия -#скорее всего, пойдем как-то по-тупому -#но вообще, тут прям жесть как нужен нормальный интерфейс +#функции для создания обьектов PDDL def add_types(): types = doc.addObject('App::FeaturePython', 'Types') types.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' + types.addProperty("App::PropertyStringList", 'Type', 'PDDL').Type = 'Types' types.addProperty("App::PropertyStringList", 'Types', 'PDDL') + sortEntity(types) + print('Types of objects added successfully') + return(types) + +def add_parameters(): + + params = doc.addObject('App::FeaturePython', 'Parameters') + params.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' + params.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Parameters' + params.addProperty('App::PropertyPythonObject', 'Parameters','PDDl') + sortEntity(params) + print('Domain parameters added successfully') + return(params) def add_action(name): #создаем обьект по шаблону, потом заполним ее вручную # - #в следующих сериях мы вытащим из нее все дерьмо - #name = input('Название действия:') + # name = input('Название действия:') action = doc.addObject('App::FeaturePython', str(name)) action.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' action.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Action' action.addProperty("App::PropertyStringList", 'Parameters', 'PDDL') action.addProperty("App::PropertyStringList", 'Conditions', 'PDDL') action.addProperty("App::PropertyStringList", 'Effects', 'PDDL') + sortEntity(action) + print('Action ' + name + 'added successfully') + return(action) -def add_predicate(): - #предикат - это одна штука на все +def add_predicate(name, parms): + #вероятно, нужно создавать предикаты отдельно и функции отдельно + #ссылаться на них ссылками внутри обьектов #нужно название предиката и вовлеченные в него сущности # name = input('Название предиката:') - predicate = doc.addObject('App::FeaturePython', 'Predicates') + predicate = doc.addObject('App::FeaturePython', str(name)) predicate.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' predicate.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Predicate' - predicate.addProperty("App::PropertyStringList", 'Name', 'PDDL') - predicate.addProperty("App::PropertyStringList", 'Parameters', 'PDDL') - + # predicate.addProperty("App::PropertyStringList", 'Name', 'PDDL') + predicate.addProperty("App::PropertyStringList", 'Parameters', 'PDDL').Parameters = parms + sortEntity(predicate) + print('Predicate ' + name + 'added successfully') + return(predicate) + def add_durative_action(name): @@ -48,23 +67,30 @@ def add_durative_action(name): action.addProperty("App::PropertyStringList", 'Parameters', 'PDDL') action.addProperty("App::PropertyStringList", 'Conditions', 'PDDL') action.addProperty("App::PropertyStringList", 'Effects', 'PDDL') - action.addProperty('App::PropertyStringList', 'Duration', 'PDDL') + action.addProperty('App::PropertyString', 'Duration', 'PDDL') + sortEntity(action) + print('Durative Action ' + name + ' added successfully') + return(action) + + +#цель задается не здесь, а в problem +# def add_goal(name): -def add_goal(name): - - # name = input('Название цели:') - goal = doc.addObject('App::FeaturePython', str(name)) - goal.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' - goal.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Goal' - goal.addProperty("App::PropertyStringList", 'Conditions', 'PDDL') - -file_path = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/domain.pddl' +# # name = input('Название цели:') +# goal = doc.addObject('App::FeaturePython', str(name)) +# goal.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL' +# goal.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Goal' +# goal.addProperty("App::PropertyStringList", 'Conditions', 'PDDL') + + + #сюда нужно поставить нормальную относительную ссылку +#лучше вообще сохранять это туда, где лежит директория с файлом freecad def export_to_file(file_path): objs = doc.Objects with open(file_path, 'w') as f: - f.write('(define (domain roboarm)\n \n') - f.write('(:requirements :strips :typing)\n') + f.write('(define (domain '+ filename +')\n \n') + f.write('(:requirements :strips :typing :fluents :durative-actions)\n') # Типы обьектов types = doc.getObjectsByLabel('Types')[0] @@ -75,17 +101,19 @@ def export_to_file(file_path): f.write(')\n') # предикаты - f.write('(:predicates\n') + f.write(' (:predicates\n') for obj in objs: if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'Predicate': - for names in obj.Name: - f.write(' (' + names + ' ') - for params in obj.Parameters: - f.write('(' + params + ') ') - - f.write(')\n') - f.write(' )\n') + f.write(' ('+ obj.Label) + for params in obj.Parameters: + f.write(' ' + params) + f.write(')\n') + f.write(' )\n') + # функции + f.write(' (:functions\n') + f.write(' )\n') + #действия: for obj in objs: if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'Action': @@ -111,223 +139,180 @@ def export_to_file(file_path): f.write(' )\n') - - # цели - f.write(' (:goal (and \n') + # длительные действия: for obj in objs: - if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'Goal': - f.write(' (') - for conds in obj.Conditions: - - f.write( conds + ' ') - - f.write(') ') + if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'DurativeAction': + f.write('(:durative-action ' + obj.Label + '\n') + f.write(' :parameters (') + for params in obj.Parameters: + f.write(' ' + params ) + f.write(' )\n') + f.write(' :duration ( = ?duration '+ str(obj.Duration) +')\n') + f.write(' :condition (and \n') + + for condition in obj.Conditions: + f.write(' (' + condition + ') \n') + # f.write(') ') + # f.write(')\n') + f.write(' )\n') + + f.write(' :effect (and \n') + + for effect in obj.Effects: + f.write(' (' + effect + ') \n') + # f.write(' ') f.write(')\n') - - f.write('))\n') - # f.write(' )\n') + + f.write(' )\n') + + f.write(' )\n') + +# def set_parameters() + +def sortEntity(object): + #если нету директории, то создадим ее + if doc.getObjectsByLabel(object.Type) == 0: + pddl_group = doc.addObject("App::DocumentObjectGroup", str(object.Type)) + else: + pddl_group = doc.getObject(str(object.Type)) + pddl_group.addObject(object) + Gui.updateGui() + + -#сделаем задание обьектов прямо здесь, без лишней головной боли - -add_types() -doc.getObject('Types').Types = ['roboarm', 'workspace', 'assemble'] - -add_action('take') -obj = doc.getObject('take') -obj.Parameters = ['?r - roboarm', '?w - workspace'] -obj.Conditions = ['roboarm_free ?r', 'roboarm_available ?r'] -obj.Effects = ['not (roboarm_free ?r)', 'not (roboarm_available ?r)'] +#сделаем задание обьектов прямо здесь -add_action('assemble') -obj = doc.getObject('assemble') -obj.Parameters = ['?r - roboarm' ,'?w - workspace', '?a - assembly'] -obj.Conditions = ['not(roboarm_free ?r)', 'not(roboarm_available ?r)'] -obj.Effects = ['roboarm_free ?r', 'roboarm_available ?r', 'assembled ?a'] +filename = doc.Name +file_path = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/pddl/'+ str(filename) + '_domain.pddl' -add_predicate() -obj = doc.getObject('Predicates') -obj.Name = ['roboarm_free', 'roboarm_available', 'assembled'] -obj.Parameters = ['?r - roboarm', '?w - workspace'] +obj = add_types() +obj.Types = ['printer workspace - zone', + 'part', + 'arm' , + 'assembly', + 'human', + 'filament'] + +obj = add_parameters() +obj.Parameters = { + 'arm':['?a'], + 'zone':['?z'], + 'part':['?part'], + 'assembly': ['?whole', '?prev', '?next'], + 'human':['?h'], + 'filament': ['?f'] + } + +#list_of_predicates +#temp -add_goal('goal') -doc.getObject('goal').Conditions = ['roboarm_free ?r', 'assembled ?a'] + +add_predicate('arm_available', '?a - arm' ) +add_predicate('part_at', '?p - part ?z - zone' ) +add_predicate('printer_ready', '?p - printer' ) +add_predicate('printer_checked', '?p - printer' ) +add_predicate('printer_at_work', '?p - printer' ) +add_predicate('part_of', '?part - part ?whole - assembly' ) +add_predicate('assembly_order', '?prev ?next - assembly' ) +add_predicate('assembled', '?whole - assembly ?z - zone' ) +add_predicate('observer_free', '?h - human' ) +add_predicate('filament_at', '?f - filament ?z - zone' ) + +# doc.getObject(name).Parameters = '?a - arm' + + + + +obj = add_durative_action('print') +obj.Parameters = ['?p - part', '?pr - printer'] +obj.Duration = '20' +obj.Conditions = ['at start(printer_ready ?pr)'] #должно быть at start и at end, todo +obj.Effects = ['at start (not (printer_ready ?pr))', + 'at start (printer_at_work ?pr )', + 'at end(part_at ?p ?pr)', + 'at end (not (printer_at_work ?pr ))'] + +obj = add_durative_action('remove') +obj.Parameters = ['?p - part', + '?pr - printer', + '?z - zone', + '?a - arm' + ] +obj.Duration = '1' +obj.Conditions = ['at start (part_at ?p ?pr)', + 'at start (arm_available ?a)'] +obj.Effects = ['at start (not (arm_available ?a))', + 'at end (part_at ?p ?z)', + 'at end (arm_available ?a)', + 'at end (printer_ready ?pr)'] + +obj = add_durative_action('assemble') +obj.Parameters = ['?p - part', + '?prev ?next - assembly', + '?z - zone', + '?arm - arm', + '?w - workspace' + ] +obj.Duration = '5' +obj.Conditions = ['at start (assembled ?prev ?w)', + 'at start (part_at ?p ?w)', + 'at start (part_of ?p ?next)', + 'at start (arm_available ?arm)', + 'at start (assembly_order ?prev ?next)'] +obj.Effects = ['at start (not (arm_available ?arm))', + 'at end (not (part_at ?p ?w))', + 'at end (arm_available ?arm)', + 'at end (assembled ?next ?w)'] + + +obj = add_durative_action('printer_check') +obj.Parameters = ['?p - printer', + '?h - human' + ] +obj.Duration = '1' +obj.Conditions = ['at start ( observer_free ?h )'] +obj.Effects = ['at start (not (observer_free ?h))', + 'at end (observer_free ?h)', + 'at end (printer_checked ?p)'] + + +obj = add_durative_action('printer_filament_load') +obj.Parameters = ['?p - printer', + '?h - human', + '?f - filament', + '?z - zone' + ] +obj.Duration = '5' +obj.Conditions = ['at start (printer_checked ?p)', + 'at start (observer_free ?h)', + 'at start (filament_at ?f ?z)' + # 'at start (not (printer_at_work ?p))' + ] +obj.Effects = ['at start (not(observer_free ?h))', + 'at end (observer_free ?h)', + 'at end (printer_ready ?p)', + 'at end (not (filament_at ?f ?z))'] + + +# add_action('assemble') +# obj = doc.getObject('assemble') +# obj.Parameters = ['?r - roboarm' ,'?w - workspace', '?a - assembly'] +# obj.Conditions = ['not(roboarm_free ?r)', 'not(roboarm_available ?r)'] +# obj.Effects = ['roboarm_free ?r', 'roboarm_available ?r', 'assembled ?a'] + +# add_predicate() +# obj = doc.getObject('Predicates') +# obj.Name = ['roboarm_free', 'roboarm_available', 'assembled'] +# obj.Parameters = ['?r - roboarm', '?w - workspace'] + + +# # add_goal('goal') +# doc.getObject('goal').Conditions = ['roboarm_free ?r', 'assembled ?a'] export_to_file(file_path) -# (:action load-material -# :parameters (?m - material ?c - component) -# :precondition (and (at ?m ?c) (compatible ?m ?c)) -# :effect (has-material ?m)) - - -# class PDDLExporter: -# def __init__(self): -# self.actions = [] -# self.predicates = [] -# self.object_types = [] -# self.goals = [] - -# def add_action(self, name, parameters, preconditions, effects): -# action = { -# 'name': name, -# 'parameters': parameters, -# 'preconditions': preconditions, -# 'effects': effects -# } -# self.actions.append(action) - -# def add_predicate(self, name, parameters, types): -# predicate = { -# 'name': name, -# 'parameters': parameters, -# 'types': types -# } -# self.predicates.append(predicate) - -# def add_object_type(self, name): -# self.object_types.append(name) - -# def add_goal(self, predicates): -# self.goals = predicates - -# def export_to_file(self, file_path): -# with open(file_path, 'w') as f: -# f.write('(define (domain my_domain)\n') -# f.write(' (:requirements :strips :typing)\n') - -# # Export object types -# f.write(' (:types ') -# for obj_type in self.object_types: -# f.write(obj_type + ' ') -# f.write(')\n') - -# # Export predicates -# f.write(' (:predicates\n') -# for predicate in self.predicates: -# f.write(' (' + predicate['name'] + ' ') -# for i, param in enumerate(predicate['parameters']): -# f.write('(' + param + ' ' + predicate['types'][i] + ') ') -# f.write(')\n') -# f.write(' )\n') - -# # Export actions -# for action in self.actions: -# f.write(' (:action ' + action['name'] + '\n') -# f.write(' :parameters (') -# for i, param in enumerate(action['parameters']): -# f.write('(' + param + ' ' + action['parameters'][param] + ') ') -# f.write(')\n') - -# f.write(' :precondition (and ') -# for precondition in action['preconditions']: -# f.write('(' + precondition['predicate'] + ' ') -# for i, param in enumerate(precondition['parameters']): -# f.write(param + ' ') -# f.write(') ') -# f.write(')\n') - -# f.write(' :effect (and ') -# for effect in action['effects']: -# f.write('(' + effect['predicate'] + ' ') -# for i, param in enumerate(effect['parameters']): -# f.write(param + ' ') -# f.write(') ') -# f.write(')\n') - -# f.write(' )\n') - -# # Export goals -# f.write(' (:goal (and ') -# for goal in self.goals: -# f.write('(' + goal['predicate'] + ' ') -# for i, param in enumerate(goal['parameters']): -# f.write(param + ' ') -# f.write(') ') -# f.write('))\n') - -# f.write(')\n') - -# # Пример использования -# exporter = PDDLExporter() - -# # Добавляем действия -# exporter.add_action('move', {'obj': 'object'}, [{'predicate': 'at', 'parameters': ['obj', 'loc']}], [{'predicate': 'at', 'parameters': ['obj', 'new-loc']}, {'predicate': 'not-at', 'parameters': ['obj', 'loc']}]) -# exporter.add_action('pick', {'obj': 'object', 'hand': 'hand'}, [{'predicate': 'at', 'parameters': ['obj', 'loc']}, {'predicate': 'empty', 'parameters': ['hand']}], [{'predicate': 'holding', 'parameters': ['obj', 'hand']}, {'predicate': 'not-at', 'parameters': ['obj', 'loc']}, {'predicate': 'not-empty', 'parameters': ['hand']}]) - -# # Добавляем предикаты -# exporter.add_predicate('at', ['obj', 'loc'], ['object', 'location']) -# exporter.add_predicate('not-at', ['obj', 'loc'], ['object', 'location']) -# exporter.add_predicate('empty', ['hand'], ['hand']) -# exporter.add_predicate('holding', ['obj', 'hand'], ['object', 'hand']) - -# # Добавляем типы объектов -# exporter.add_object_type('object') -# exporter.add_object_type('location') -# exporter.add_object_type('hand') - -# # Добавляем цели -# exporter.add_goal([{'predicate': 'at', 'parameters': ['obj', 'final-loc']}]) - -# # Экспортируем в файл PDDL domain -# exporter.export_to_file('domain.pddl') - - - -# #генерируем pddl -# #импортируем кучу обьектов из дерева построения freecad - -# #задаем шаблон на действие - -# # predicates = ';; Предикаты \n(:predicates \n(at ?c - component ?location - component) \n(printed ?c - component) \n(has-material ?m - material) \n(compatible ?m - material ?c - component))' - -# # # print(predicates) - - -# # predicates = - - -# (" ;; Предикаты \ -# '(:predicates (at ?c - component ?location - component)' \ -# '(printed ?c - component)' \ -# '(printed ?c - component))' - - - -# (:predicates -# (at ?c - component ?location - component) -# (printed ?c - component) -# (has-material ?m - material) -# (compatible ?m - material ?c - component))'' - - - -# ;; Предикаты -# (:predicates -# (at ?c - component ?location - component) -# (printed ?c - component) -# (has-material ?m - material) -# (compatible ?m - material ?c - component)) - -# ;; Действия -# (:action load-material -# :parameters (?m - material ?c - component) -# :precondition (and (at ?m ?c) (compatible ?m ?c)) -# :effect (has-material ?m)) - -# (:action unload-material -# :parameters (?m - material ?c - component) -# :precondition (has-material ?m) -# :effect (and (not (has-material ?m)) (at ?m ?c))) - -# (:action print-component -# :parameters (?c - component) -# :precondition (and (at ?c ?printer) (has-material ?m) (compatible ?m ?c)) -# :effect (printed ?c)) - -# ;; Цель -# (:goal (forall (?c - component) (printed ?c)))) diff --git a/cg/freecad/Frames/pddl/workingdomain.pddl b/cg/freecad/Frames/pddl/workingdomain.pddl index 149304c..cfd12b1 100644 --- a/cg/freecad/Frames/pddl/workingdomain.pddl +++ b/cg/freecad/Frames/pddl/workingdomain.pddl @@ -1,34 +1,45 @@ ;; Modified domain taken from ;; "Knowledge transfer in robot manipulation tasks" by Jacob O. Huckaby 2014 (define (domain robossembler) - (:requirements :strips :typing :adl :fluents :durative-actions) + (:requirements :strips :typing :adl :fluents :durative-actions ) (:types printer workspace - zone part arm assembly + human + filament ) (:predicates (arm_available ?a - arm) (part_at ?p - part ?z - zone) + (printer_ready ?p - printer) + (printer_checked ?p - printer) + (printer_at_work ?p - printer ) + (part_of ?part - part ?whole - assembly) (assembly_order ?prev ?next - assembly) (assembled ?whole - assembly ?z - zone) + (observer_free ?h - human) + + (filament_at ?f - filament ?z - zone) ) (:functions) (:durative-action print :parameters (?p - part ?pr - printer) - :duration ( = ?duration 10) + :duration ( = ?duration 20) :condition (and (at start(printer_ready ?pr)) ) :effect (and (at start (not (printer_ready ?pr))) + ; (at start (printer_at_work ?pr )) (at end(part_at ?p ?pr)) + ; (at end (not (printer_at_work ?pr ))) ) ) @@ -38,6 +49,7 @@ :condition (and (at start (part_at ?p ?pr)) (at start (arm_available ?a)) + ) :effect (and (at start (not (arm_available ?a))) @@ -64,4 +76,49 @@ (at end (assembled ?next ?w)) ) ) -);; end Domain ;;;;;;;;;;;;;;;;;;;;;;;; + + (:durative-action printer_check ; здесь мы подготавливаем сам механизм 3д-принтера + :parameters (?p - printer ?h - human) + :duration (= ?duration 1) + :condition (and + (at start ( observer_free ?h )) + ) + + :effect (and + (at start (not (observer_free ?h))) + (at end (observer_free ?h)) + (at end (printer_checked ?p)) + ) + + + ) + + (:durative-action printer_filament_load ; а здесь - заправляем пластик, чтобы он был готов к печати + :parameters (?p - printer ?h - human ?f - filament ?w - workspace) + :duration (= ?duration 5) + :condition (and + (at start (printer_checked ?p)) + (at start (observer_free ?h)) + (at start (filament_at ?f ?w)) ; филамент в зоне + ; (at start (not(printer_ready ?p))) + + ) + :effect (and + (at start (not(observer_free ?h))) + (at end (observer_free ?h)) + (at end (printer_ready ?p)) + (at end (not (filament_at ?f ?w))) + + ) + ) + + + + + + + + +) + +;; end Domain ;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/cg/freecad/Frames/pddl/workingproblem.pddl b/cg/freecad/Frames/pddl/workingproblem.pddl index 56716c6..abdd5c8 100644 --- a/cg/freecad/Frames/pddl/workingproblem.pddl +++ b/cg/freecad/Frames/pddl/workingproblem.pddl @@ -5,15 +5,25 @@ rasmt - arm printer1 printer2 printer3 - printer workspace1 - workspace + worker - human + filament1 filament2 filament3 - filament ;; information from CAD part1 part2 part3 part4 - part subasm0 subasm1 subasm2 subasm3 subasm4 - assembly ) (:init ;; information from Scene - (printer_ready printer1) - (printer_ready printer2) - (printer_ready printer3) + + (observer_free worker) + ; (not(printer_ready printer1)) + + ; (printer_ready printer2) + ; (printer_ready printer3) + (filament_at filament1 workspace1) + (filament_at filament2 workspace1) + (filament_at filament3 workspace1) + + (arm_available rasmt) ;; information from CAD (assembled subasm0 workspace1)