Генерация последовательностей сборки через кластеризацию и оптимизацию

This commit is contained in:
MarkVoltov 2024-12-02 00:48:29 +03:00
parent deee7b4329
commit 862a61b1e7
3 changed files with 141 additions and 20 deletions

View file

@ -0,0 +1,82 @@
import networkx as nx
class GraphProcessor:
graph = None
def __init__(self, adjacency_matrix):
self.adjacency_matrix = adjacency_matrix
self.graph = self.load_graph_from_data()
def load_graph_from_data(self):
G = nx.Graph()
for part1, neighbors in self.adjacency_matrix.items():
for neighbor in neighbors:
G.add_edge(part1, neighbor)
return G
class EdgeBetweensClustering:
def __init__(self, graph):
self.graph = graph.copy()
self.clusters = []
def cluster(self):
while self.graph.number_of_edges() > 0:
edge_betweens = nx.edge_betweenness_centrality(self.graph)
max_betweens_edge = max(edge_betweens, key=edge_betweens.get)
self.graph.remove_edge(*max_betweens_edge)
components = list(nx.connected_components(self.graph))
if components not in self.clusters:
self.clusters.append(components)
return []
def get_clusters(self):
return self.clusters
class ClusterisationSequenceUseCase:
def call(self, adjacency_matrix):
graph_processor = GraphProcessor(adjacency_matrix)
G = graph_processor.load_graph_from_data()
ebc = EdgeBetweensClustering(G)
ebc.cluster()
clusters = ebc.get_clusters()
for i in range(len(clusters)):
for j in range(len(clusters[i])):
clusters[i][j] = list(clusters[i][j])
# Создание списка последовательностей сборки
assembly_sequences = []
for cluster in clusters:
sequence = []
for component in cluster:
sequence.extend(component)
assembly_sequences.append(sequence)
return assembly_sequences
# # Вызов функции
# adjacency_matrix = {
# 'body_down': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
# 'sol_gear': ['body_down', 'output_shaft', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002'],
# 'output_shaft': ['sol_gear', 'planet_gear', 'planet_gear003', 'planet_gear004', 'planet_gear005', 'planet_gear002', 'body_up'],
# 'planet_gear': ['body_down', 'sol_gear', 'output_shaft'],
# 'planet_gear003': ['body_down', 'sol_gear', 'output_shaft'],
# 'planet_gear004': ['body_down', 'sol_gear', 'output_shaft'],
# 'planet_gear005': ['body_down', 'sol_gear', 'output_shaft'],
# 'planet_gear002': ['body_down', 'sol_gear', 'output_shaft'],
# 'body_up': ['body_down', 'output_shaft', 'bolt', 'bolt2', 'bolt3', 'bolt4'],
# 'bolt': ['body_down', 'body_up'],
# 'bolt2': ['body_down', 'body_up'],
# 'bolt3': ['body_down', 'body_up'],
# 'bolt4': ['body_down', 'body_up']
# }
# print(adjacency_matrix)
# use_case = ClusterisationSequenceUseCase()
# assembly_sequences = use_case.call(adjacency_matrix)
# print(assembly_sequences)

View file

@ -7,6 +7,7 @@ import json
import FreeCAD as App
from geometric_feasibility_predicate.main import main as asm_analysis
from constraints_operator import collect_assembly_settings
from clusterisation_sequences import ClusterisationSequenceUseCase
# === Для работы с json-файлами. Работает. ===
@ -94,42 +95,80 @@ def simplify_adjacency_matrix(assembly_settings, adjacency_matrix):
}
for part in adjacency_matrix["allParts"]:
if part not in fasteners:
simplified_matrix["allParts"].append(part)
neighbors = [
neighbor for neighbor in adjacency_matrix["matrix"].get(part, [])
if neighbor not in fasteners
]
if neighbors or part not in fasteners:
simplified_matrix["matrix"][part] = neighbors
# Добавляем все детали, включая крепеж, в simplified_matrix["allParts"]
simplified_matrix["allParts"].append(part)
# Получаем соседей, исключая только крепежные элементы
neighbors = [
neighbor for neighbor in adjacency_matrix["matrix"].get(part, [])
if neighbor not in fasteners
]
# Если у части есть соседи, добавляем их в матрицу
if neighbors:
simplified_matrix["matrix"][part] = neighbors
return simplified_matrix
def restore_full_sequence(assembly_settings, sequence):
full_sequence = []
sequence_set = set(sequence)
for item in sequence:
full_sequence.append(item)
def restore_full_sequence(assembly_settings, sequences):
full_sequences = []
for sequence in sequences:
full_sequence = []
sequence_set = set(sequence)
# Сначала добавляем все детали в полную последовательность
for item in sequence:
full_sequence.append(item)
# Теперь добавляем крепежные элементы после элемента с наибольшим порядковым номером
for setting in assembly_settings:
if setting.get("Type") == "fastener_set":
parent = setting["Parent"]
child = setting["Child"]
if parent in sequence_set and child in sequence_set:
full_sequence.append(setting["Fasteners"])
fasteners = setting["Fasteners"]
# Проверяем, если родитель и ребенок в последовательности
if (parent in sequence_set) and (child in sequence_set):
# Находим индексы родителя и ребенка в полной последовательности
parent_index = full_sequence.index(parent)
child_index = full_sequence.index(child)
# Находим максимальный индекс между родителем и ребенком
max_index = max(parent_index, child_index)
# Проверяем, содержатся ли крепежные элементы уже в последовательности
if not any(fastener in full_sequence for fastener in fasteners):
# Добавляем крепежные элементы после элемента child
full_sequence[max_index + 1:max_index + 1] = fasteners
full_sequences.append(full_sequence)
return full_sequences
return full_sequence
def main():
App.open('/home/markvoltov/GitProjects/framework/test_models/test_reductor.FCStd')
if App.ActiveDocument:
intersection_geometry, sequences, topologyMatrix = asm_analysis()
print(sequences)
assembly_settings = collect_assembly_settings()
print(assembly_settings)
simplified_matrix = simplify_adjacency_matrix(assembly_settings, topologyMatrix)
assembly_sequences = ClusterisationSequenceUseCase().call(topologyMatrix['matrix'])
# print('Последовательности 1', assembly_sequences)
assembly_sequences_simplified= ClusterisationSequenceUseCase().call(simplified_matrix['matrix'])
# print('Последовательности 2',assembly_sequences_simplified)
assembly_sequences_restored = restore_full_sequence(assembly_settings, assembly_sequences_simplified)
print('Последовательности 3',assembly_sequences_restored)
else:
print('Ошибка. Нет активного документа!')

Binary file not shown.