working pddl

This commit is contained in:
Mark Voltov 2023-07-03 16:31:48 +03:00
parent 249f28721e
commit da7a3c995c
7 changed files with 610 additions and 63 deletions

View file

@ -1,60 +0,0 @@
# import FreeCAD as App
# doc = App.ActiveDocument
#генерируем 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))'
print(predicates)
# (: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))))

View file

@ -68,8 +68,13 @@ def materialExistenceCheck(doc):
#проверим, что материалы правильно описаны:
# Открываем файл JSON с требованиями и загружаем его содержимое
with open('material_requirements.json', 'r') as f:
material_requirements = json.load(f)
# with open('material_requirements.json', 'r') as f:
# material_requirements = json.load(f)
material_requirements = ["Density",
"DiffuseColor",
"EmissiveColor"
]
@ -158,4 +163,7 @@ def parse_values(value_str):
#todo:
# сделать проверку на солидовые тела
#укомпоновать все вспомогательные обьекты в отдельную штуку
#wip
#wip
#подготавливаем действия и состояния для PDDL
#

View file

@ -0,0 +1,69 @@
(define (problem my_problem)
(:domain roboarm)
(:objects
ur_manipulator_gripper - arm
printer - printer
world - zone
box1 box2 box3 box4 box5 box6 - part
asm0 asm1 asm2 asm3 asm4 asm5 asm6 - assembly
)
(:init
not(part_at box1 world)
not(part_at box2 world)
not(part_at box3 world)
not(part_at box4 world)
not(part_at box5 world)
not(part_at box6 world)
(part_of box1 asm1)
(part_of box2 asm2)
(part_of box3 asm3)
(part_of box4 asm4)
(part_of box5 asm5)
(part_of box6 asm6)
(assembly_order asm0 asm1)
(assembly_order asm1 asm2)
(assembly_order asm2 asm3)
(assembly_order asm3 asm4)
(assembly_order asm4 asm5)
(assembly_order asm5 asm6)
(printer_available printer)
(arm_available ur_manipulator_gripper)
(assembly_at asm0 world)
(assembled asm0)
)
(:goal (and
(assembled asm6)
))
)
; нужно указать желаемое конечное состояние
; (эффект в конце действия)
; в нашем случае, допустим, будет asm6
; чтобы включить принтер в процесс, у нас должны спавниться детали
; будет что-то типа (not part_at box1 workzone)
; и action print
; начальные условия: not part_at box workzone
; принтер доступен
; в ходе дела парт печатается, принтер не доступен
; в конце - принтер доступен, деталь в зоне
; нужно в генераторе добавить поддержку условий at start и at end
; но пока что это можно прописать текстом
; предикаты -
; рука доступна - рука
; сборка в зоне - сборка зона
; деталь часть сборки - деталь сборка
; собрана - сборка
; сборочный порядок - предсборка следсборка
; +
; деталь в зоне - деталь зона
; принтер доступен - принтер

View file

@ -0,0 +1,96 @@
(define (domain roboarm)
(:requirements :strips :typing)
(:types
zone
part
assembly
roboarm
printer
)
(:predicates
(arm_available ?a - roboarm)
(printer_available ?p - printer)
;касты на сборку
(assembly_at ?a - assembly ?z - zone)
(part_of ?part - part ?whole - assembly)
(assembled ?whole - assembly)
(assembly_order ?prev ?next - assembly)
(part_at ?part - part ?z - zone)
)
(:durative-action assemble
:parameters (?part - part ?prev ?next - assembly ?z - zone ?a - arm)
:duration ( = ?duration 5)
:condition (and
(at start (arm_available ?a))
(at start (assembly_order ?prev ?next))
(at start (part_of ?part ?next))
(at start (assembly_at ?prev ?z))
(at start (assembled ?prev))
)
:effect (and
(at start (not (arm_available ?a)))
(at end (assembly_at ?next ?z))
(at end (assembled ?next))
(at end (arm_available ?a))
)
)
(:durative-action print
:parameters (?part - part ?p - printer ?z - zone )
:duration ( = ?duration 10)
:condition (and
(at start (printer_available ?p))
(at_start (not (part_at ?part ?z)))
)
:effect (and
(at start (not (printer_available ?p)))
(at end (part_at ?part ?z))
(at end (printer_available ?a))
)
)
; (:action take
; :parameters (?r - roboarm ?w - workspace )
; :condition (and
; (roboarm_free ?r)
; (roboarm_available ?r)
; )
; :effect (and
; (not (roboarm_free ?r))
; (not (roboarm_available ?r))
; )
; )
; (:action assemble
; :parameters (?r - roboarm ?w - workspace ?a - assembly )
; :duration (= ?duration 5 )
; :condition (and
; (not(roboarm_free ?r))
; (not(roboarm_available ?r))
; )
; :effect (and
; (roboarm_free ?r)
; (roboarm_available ?r)
; (assembled ?a)
; )
; )
; (:goal (and
; (roboarm_free ?r)
; (assembled ?a)
; )
; ))
;

View file

@ -0,0 +1,333 @@
import FreeCAD as App
doc = App.ActiveDocument
#функции для создания обьекта действия
#скорее всего, пойдем как-то по-тупому
#но вообще, тут прям жесть как нужен нормальный интерфейс
def add_types():
types = doc.addObject('App::FeaturePython', 'Types')
types.addProperty("App::PropertyString", 'PDDL', 'PDDL').PDDL = 'PDDL'
types.addProperty("App::PropertyStringList", 'Types', 'PDDL')
def add_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 = 'Action'
action.addProperty("App::PropertyStringList", 'Parameters', 'PDDL')
action.addProperty("App::PropertyStringList", 'Conditions', 'PDDL')
action.addProperty("App::PropertyStringList", 'Effects', 'PDDL')
def add_predicate():
#предикат - это одна штука на все
#нужно название предиката и вовлеченные в него сущности
# name = input('Название предиката:')
predicate = doc.addObject('App::FeaturePython', 'Predicates')
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')
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')
action.addProperty('App::PropertyStringList', 'Duration', 'PDDL')
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'
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')
# Типы обьектов
types = doc.getObjectsByLabel('Types')[0]
f.write('(:types \n')
for obj_type in types.Types:
f.write(' ' + obj_type + ' \n')
f.write(')\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')
#действия:
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')
# цели
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(') ')
f.write(')\n')
f.write('))\n')
# f.write(' )\n')
#сделаем задание обьектов прямо здесь, без лишней головной боли
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']
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))))

View file

@ -0,0 +1,67 @@
;; 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)
(:types
printer workspace - zone
part
arm
assembly
)
(:predicates
(arm_available ?a - arm)
(part_at ?p - part ?z - zone)
(printer_ready ?p - printer)
(part_of ?part - part ?whole - assembly)
(assembly_order ?prev ?next - assembly)
(assembled ?whole - assembly ?z - zone)
)
(:functions)
(:durative-action print
:parameters (?p - part ?pr - printer)
:duration ( = ?duration 10)
:condition (and
(at start(printer_ready ?pr))
)
:effect (and
(at start (not (printer_ready ?pr)))
(at end(part_at ?p ?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 ?w - workspace ?arm - arm)
: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))
)
)
);; end Domain ;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -0,0 +1,34 @@
(define (problem p1)
(:domain robossembler)
(:objects
;; information from Scene
rasmt - arm
printer1 printer2 printer3 - printer
workspace1 - workspace
;; 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)
(arm_available rasmt)
;; information from CAD
(assembled subasm0 workspace1)
(part_of part1 subasm1)
(part_of part2 subasm2)
(part_of part3 subasm3)
(part_of part4 subasm4)
(assembly_order subasm0 subasm1)
(assembly_order subasm1 subasm2)
(assembly_order subasm2 subasm3)
(assembly_order subasm3 subasm4)
)
(:goal (and
;; information from CAD
(assembled subasm4 workspace1)
)
)
)