2023-07-03 16:31:48 +03:00
|
|
|
|
import FreeCAD as App
|
2023-07-04 14:31:53 +03:00
|
|
|
|
import FreeCADGui as Gui
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
doc = App.ActiveDocument
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
#функции для создания обьектов PDDL
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
def add_types():
|
2023-07-04 20:18:23 +03:00
|
|
|
|
types = doc.addObject('App::FeaturePython', 'types')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
types.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL'
|
2023-07-04 20:18:23 +03:00
|
|
|
|
types.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Types'
|
2023-07-03 16:31:48 +03:00
|
|
|
|
types.addProperty("App::PropertyStringList", 'Types', 'PDDL')
|
2023-07-04 14:31:53 +03:00
|
|
|
|
sortEntity(types)
|
|
|
|
|
print('Types of objects added successfully')
|
|
|
|
|
return(types)
|
2023-07-04 20:18:23 +03:00
|
|
|
|
#слишком много types
|
2023-07-04 14:31:53 +03:00
|
|
|
|
|
|
|
|
|
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)
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
def add_action(name):
|
|
|
|
|
|
|
|
|
|
#создаем обьект по шаблону, потом заполним ее вручную
|
|
|
|
|
#
|
2023-07-04 14:31:53 +03:00
|
|
|
|
# name = input('Название действия:')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
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')
|
2023-07-04 14:31:53 +03:00
|
|
|
|
sortEntity(action)
|
|
|
|
|
print('Action ' + name + 'added successfully')
|
|
|
|
|
return(action)
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
def add_predicate(name, parms):
|
|
|
|
|
#вероятно, нужно создавать предикаты отдельно и функции отдельно
|
|
|
|
|
#ссылаться на них ссылками внутри обьектов
|
2023-07-03 16:31:48 +03:00
|
|
|
|
#нужно название предиката и вовлеченные в него сущности
|
|
|
|
|
# name = input('Название предиката:')
|
2023-07-04 14:31:53 +03:00
|
|
|
|
predicate = doc.addObject('App::FeaturePython', str(name))
|
2023-07-03 16:31:48 +03:00
|
|
|
|
predicate.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL'
|
|
|
|
|
predicate.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'Predicate'
|
2023-07-04 14:31:53 +03:00
|
|
|
|
# predicate.addProperty("App::PropertyStringList", 'Name', 'PDDL')
|
|
|
|
|
predicate.addProperty("App::PropertyStringList", 'Parameters', 'PDDL').Parameters = parms
|
|
|
|
|
sortEntity(predicate)
|
|
|
|
|
print('Predicate ' + name + 'added successfully')
|
|
|
|
|
return(predicate)
|
|
|
|
|
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
def add_durative_action(name):
|
|
|
|
|
|
|
|
|
|
# name = input('Название действия:')
|
|
|
|
|
action = doc.addObject('App::FeaturePython', str(name))
|
|
|
|
|
action.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL'
|
|
|
|
|
action.addProperty("App::PropertyString", 'Type', 'PDDL').Type = 'DurativeAction'
|
|
|
|
|
action.addProperty("App::PropertyStringList", 'Parameters', 'PDDL')
|
|
|
|
|
action.addProperty("App::PropertyStringList", 'Conditions', 'PDDL')
|
|
|
|
|
action.addProperty("App::PropertyStringList", 'Effects', 'PDDL')
|
2023-07-04 14:31:53 +03:00
|
|
|
|
action.addProperty('App::PropertyString', 'Duration', 'PDDL')
|
|
|
|
|
sortEntity(action)
|
|
|
|
|
print('Durative Action ' + name + ' added successfully')
|
|
|
|
|
return(action)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#цель задается не здесь, а в problem
|
|
|
|
|
# def add_goal(name):
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
# # 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
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
def export_to_file(file_path):
|
|
|
|
|
objs = doc.Objects
|
|
|
|
|
with open(file_path, 'w') as f:
|
2023-07-04 14:31:53 +03:00
|
|
|
|
f.write('(define (domain '+ filename +')\n \n')
|
|
|
|
|
f.write('(:requirements :strips :typing :fluents :durative-actions)\n')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
# Типы обьектов
|
|
|
|
|
types = doc.getObjectsByLabel('Types')[0]
|
|
|
|
|
f.write('(:types \n')
|
|
|
|
|
|
|
|
|
|
for obj_type in types.Types:
|
|
|
|
|
f.write(' ' + obj_type + ' \n')
|
|
|
|
|
f.write(')\n')
|
|
|
|
|
|
|
|
|
|
# предикаты
|
2023-07-04 14:31:53 +03:00
|
|
|
|
f.write(' (:predicates\n')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
for obj in objs:
|
|
|
|
|
if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'Predicate':
|
2023-07-04 14:31:53 +03:00
|
|
|
|
f.write(' ('+ obj.Label)
|
|
|
|
|
for params in obj.Parameters:
|
|
|
|
|
f.write(' ' + params)
|
|
|
|
|
f.write(')\n')
|
|
|
|
|
f.write(' )\n')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
# функции
|
|
|
|
|
f.write(' (:functions\n')
|
|
|
|
|
f.write(' )\n')
|
|
|
|
|
|
2023-07-03 16:31:48 +03:00
|
|
|
|
#действия:
|
|
|
|
|
for obj in objs:
|
|
|
|
|
if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'Action':
|
|
|
|
|
f.write('(:action ' + obj.Label + '\n')
|
|
|
|
|
f.write(' :parameters (')
|
|
|
|
|
for params in obj.Parameters:
|
|
|
|
|
f.write('' + params + ' ')
|
|
|
|
|
f.write(')\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')
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
# длительные действия:
|
2023-07-03 16:31:48 +03:00
|
|
|
|
for obj in objs:
|
2023-07-04 14:31:53 +03:00
|
|
|
|
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(' ')
|
2023-07-03 16:31:48 +03:00
|
|
|
|
f.write(')\n')
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
f.write(' )\n')
|
|
|
|
|
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
f.write(' )\n')
|
|
|
|
|
|
|
|
|
|
# def set_parameters()
|
|
|
|
|
|
|
|
|
|
def sortEntity(object):
|
|
|
|
|
#если нету директории, то создадим ее
|
2023-07-04 20:18:23 +03:00
|
|
|
|
# if len(doc.getObjectsByLabel(object.Type)) == 0 :
|
|
|
|
|
# pddl_group = doc.addObject("App::DocumentObjectGroup", object.Type)
|
|
|
|
|
# else:
|
|
|
|
|
pddl_group = doc.addObject("App::DocumentObjectGroup", object.Type)
|
|
|
|
|
|
|
|
|
|
if len(doc.getObjectsByLabel(object.Type)) == 0:
|
|
|
|
|
pddl_group = doc.addObject("App::DocumentObjectGroup", object.Type)
|
2023-07-04 14:31:53 +03:00
|
|
|
|
else:
|
2023-07-04 20:18:23 +03:00
|
|
|
|
pddl_group = doc.getObjectsByLabel(object.Type)[0]
|
|
|
|
|
pddl_group.addObject(object)
|
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
Gui.updateGui()
|
|
|
|
|
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
#сделаем задание обьектов прямо здесь
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filename = doc.Name
|
|
|
|
|
file_path = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/pddl/'+ str(filename) + '_domain.pddl'
|
|
|
|
|
|
|
|
|
|
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_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']
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|
|
|
|
|
|
2023-07-04 14:31:53 +03:00
|
|
|
|
export_to_file(file_path)
|
2023-07-03 16:31:48 +03:00
|
|
|
|
|