Работает экспорт из path в domain
This commit is contained in:
parent
9233cd9aa3
commit
b18a9421ab
1 changed files with 292 additions and 0 deletions
292
cg/freecad/Frames/pddl/path2pddl.py
Normal file
292
cg/freecad/Frames/pddl/path2pddl.py
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
import os
|
||||||
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
import json
|
||||||
|
|
||||||
|
#1. Экспорт фрикадовских операций
|
||||||
|
doc = App.ActiveDocument
|
||||||
|
file_path = doc.FileName
|
||||||
|
|
||||||
|
printer = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/pddl/Printer.FCStd'
|
||||||
|
endmill = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/pddl/MillingMachine.FCStd'
|
||||||
|
part1 = '/home/mark-voltov/GitProjects/framework/cg/freecad/Frames/pddl/PartDesignExample.FCStd'
|
||||||
|
#потенциально, можно здесь полностью задавать все описание сцены
|
||||||
|
|
||||||
|
toolslist = [printer, endmill]
|
||||||
|
partlist = [part1]
|
||||||
|
|
||||||
|
part = App.open(part1)
|
||||||
|
tool = App.open(endmill)
|
||||||
|
|
||||||
|
def pathCheck(part):
|
||||||
|
checker = False
|
||||||
|
for obj in part.Objects:
|
||||||
|
if hasattr(obj, 'TypeId') and obj.TypeId == 'Path::FeaturePython':
|
||||||
|
if obj.Label == 'Job':
|
||||||
|
checker = True
|
||||||
|
return checker
|
||||||
|
|
||||||
|
print(pathCheck(part))
|
||||||
|
|
||||||
|
operations_data = []
|
||||||
|
|
||||||
|
#нужно дополнить фиксированием принадлежности к телу
|
||||||
|
def is_entity_in_folder(part, entity, folder_name):
|
||||||
|
|
||||||
|
# Поиск папки с заданным именем
|
||||||
|
folder = None
|
||||||
|
for obj in part.Objects:
|
||||||
|
if obj.isDerivedFrom("App::DocumentObjectGroup") and obj.Label == folder_name:
|
||||||
|
folder = obj
|
||||||
|
break
|
||||||
|
|
||||||
|
# Если папка не найдена, вернуть False
|
||||||
|
if not folder:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Проверка наличия сущности внутри папки
|
||||||
|
return entity in folder.Group
|
||||||
|
|
||||||
|
|
||||||
|
#выделяем те сущности, которые являются операциями
|
||||||
|
def operationsInfoCollecting(part):
|
||||||
|
if pathCheck(part):
|
||||||
|
for obj in part.Objects:
|
||||||
|
if is_entity_in_folder(part, obj, 'Operations'):
|
||||||
|
operations_data.append({'Part_label': part.Label,
|
||||||
|
'Operation_name': obj.Label,
|
||||||
|
'Tool': obj.ToolController.Label,
|
||||||
|
'Duration': obj.CycleTime})
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('Операции не были обнаружены')
|
||||||
|
|
||||||
|
return operations_data
|
||||||
|
operations_data = operationsInfoCollecting(part)
|
||||||
|
print(operations_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Словарь для группировки операций по станкам
|
||||||
|
machines_operations = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def toolOperationCollector(tool):
|
||||||
|
#соберем отдельно список pddl-операций из файла станка и будем работать с ним отдельно
|
||||||
|
tool_operations = []
|
||||||
|
for obj in tool.Objects:
|
||||||
|
if hasattr(obj, 'PDDL') and hasattr(obj, 'Type') and obj.Type == 'DurativeAction':
|
||||||
|
tool_operations.append({'Label': obj.Label,
|
||||||
|
'Conditions': obj.Conditions,
|
||||||
|
'Duration': 0,
|
||||||
|
'Effects': obj.Effects,
|
||||||
|
'Parameters': obj.Parameters,
|
||||||
|
'Type': obj.Type
|
||||||
|
})
|
||||||
|
return tool_operations
|
||||||
|
|
||||||
|
print(toolOperationCollector(tool))
|
||||||
|
|
||||||
|
def operationGenerator(tool, operations_data):
|
||||||
|
|
||||||
|
tool_operations = toolOperationCollector(tool)
|
||||||
|
|
||||||
|
#отсеиваем все действия
|
||||||
|
pddl_actions = []
|
||||||
|
for part_operation in operations_data:
|
||||||
|
for tool_operation in tool_operations:
|
||||||
|
if tool_operation['Label'] == part_operation['Tool']:
|
||||||
|
pddl_actions.append({'Label': part_operation['Part_label'] + '_' + tool_operation['Label'],
|
||||||
|
'Partname': part_operation['Part_label'],
|
||||||
|
'Conditions': tool_operation['Conditions'],
|
||||||
|
'Duration': part_operation['Duration'],
|
||||||
|
'Effects': tool_operation['Effects'],
|
||||||
|
'Parameters': tool_operation['Parameters'],
|
||||||
|
'Type': tool_operation['Type']})
|
||||||
|
#здесь у нас появился список операций применительно к одному станку
|
||||||
|
#выполнив эту функцию для каждого станка, получим кучу операций для всего
|
||||||
|
return pddl_actions
|
||||||
|
|
||||||
|
print(operationGenerator(tool, operations_data))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#теперь нужно собрать все операции в один pddl
|
||||||
|
#нужно извлечь все действия и все не-действия, первое идет из tool_operations, второе - нужно отбирать из станков напрямую
|
||||||
|
|
||||||
|
def collectingNonActions(tool):
|
||||||
|
tool_non_operations = []
|
||||||
|
for obj in tool.Objects:
|
||||||
|
if hasattr(obj, 'PDDL') and hasattr(obj,'Type') and obj.Type != 'DurativeAction':
|
||||||
|
tool_non_operations.append(export_object_properties(obj))
|
||||||
|
return tool_non_operations
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def export_object_properties(obj):
|
||||||
|
obj_dict = {}
|
||||||
|
|
||||||
|
# Получение всех свойств объекта
|
||||||
|
properties = obj.PropertiesList
|
||||||
|
|
||||||
|
for prop_name in properties:
|
||||||
|
prop = obj.getPropertyByName(prop_name)
|
||||||
|
obj_dict[prop_name] = prop
|
||||||
|
|
||||||
|
return obj_dict
|
||||||
|
|
||||||
|
#у нас есть словари с действиями и недействиями
|
||||||
|
#собираем их в pddl
|
||||||
|
|
||||||
|
def time_in_sec(time_str):
|
||||||
|
|
||||||
|
# Разделяем часы, минуты и секунды
|
||||||
|
hours, minutes, seconds = map(int, time_str.split(":"))
|
||||||
|
# Переводим в секунды
|
||||||
|
time_in_seconds = (hours * 3600) + (minutes * 60) + seconds
|
||||||
|
return time_in_seconds
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#основной документ здесь - станок. Нужно поместить файл домена в папку с оборудованием
|
||||||
|
|
||||||
|
def export_to_file(tool, pddl_entities_list):
|
||||||
|
# filename = App.ActiveDocument.Name
|
||||||
|
file_path = endmill.rsplit("/", 1)[0] + '/domain.pddl'
|
||||||
|
# file_path = tool.FileName.rsplit("/", 1)[0] + 'domain.pddl'
|
||||||
|
filename = 'fabrication'
|
||||||
|
# doc = App.ActiveDocument
|
||||||
|
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
f.write('(define (domain '+ filename +')\n \n')
|
||||||
|
f.write('(:requirements :strips :typing :fluents :durative-actions)\n')
|
||||||
|
|
||||||
|
# Типы обьектов
|
||||||
|
#выбираем словари, которые соответствуют типу types
|
||||||
|
types_list = [d for d in pddl_entities_list if d.get("Type") == 'Types']
|
||||||
|
print('типы')
|
||||||
|
print(types_list)
|
||||||
|
|
||||||
|
f.write('(:types \n')
|
||||||
|
|
||||||
|
for obj in types_list:
|
||||||
|
for type in obj['Types']:
|
||||||
|
f.write(' ' + str(type) + ' \n')
|
||||||
|
f.write(')\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# предикаты
|
||||||
|
#выбираем словари, соответствующие предикатам
|
||||||
|
f.write(' (:predicates\n')
|
||||||
|
predicates_list = [d for d in pddl_entities_list if d.get("Type") == 'Predicate']
|
||||||
|
print('преды')
|
||||||
|
print(predicates_list)
|
||||||
|
for obj in predicates_list:
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
#действия:
|
||||||
|
#выбираем словари, соответствующие действиям
|
||||||
|
|
||||||
|
actions_list = [d for d in pddl_entities_list if d.get("Type") == 'Action']
|
||||||
|
print('акции')
|
||||||
|
print(actions_list)
|
||||||
|
for obj in actions_list:
|
||||||
|
|
||||||
|
|
||||||
|
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(' )\n')
|
||||||
|
|
||||||
|
f.write(' :effect (and \n')
|
||||||
|
|
||||||
|
for effect in obj['Effects']:
|
||||||
|
f.write(' (' + effect + ') \n')
|
||||||
|
# f.write(' ')
|
||||||
|
f.write(')\n')
|
||||||
|
|
||||||
|
f.write(' )\n')
|
||||||
|
|
||||||
|
# длительные действия:
|
||||||
|
#выбираем словари, соответствующие действиям
|
||||||
|
|
||||||
|
durative_actions_list = [d for d in pddl_entities_list if d.get("Type") == 'DurativeAction']
|
||||||
|
print('дакции')
|
||||||
|
print(durative_actions_list)
|
||||||
|
for obj in durative_actions_list:
|
||||||
|
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(time_in_sec(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')
|
||||||
|
|
||||||
|
tool_non_operations = []
|
||||||
|
tool_operations = []
|
||||||
|
|
||||||
|
operations_data = operationsInfoCollecting(part)
|
||||||
|
|
||||||
|
# tool = App.open(toolslist[1])
|
||||||
|
|
||||||
|
|
||||||
|
pddl_actions = operationGenerator(tool, operations_data)
|
||||||
|
|
||||||
|
tool_non_actions = collectingNonActions(tool)
|
||||||
|
print(tool_non_actions)
|
||||||
|
# tool_operations = pddl_actions #вот здесь должны быть уже обработанные данные, а не полуфабрикаты, как сейчас
|
||||||
|
|
||||||
|
pddl_entities_list = tool_non_actions + pddl_actions
|
||||||
|
print('все сущности')
|
||||||
|
print(pddl_entities_list)
|
||||||
|
|
||||||
|
print(export_to_file(tool, pddl_entities_list))
|
||||||
|
# print(export_to_file(pddl_entities_list))
|
Loading…
Add table
Add a link
Reference in a new issue