整线优化第一版论文定稿工程
增加了整线批量测试 修改了现有min-max模型路径 修改了遗传算法整体框架 估计器增加异常数据剔除 封装优化结果类 修改供料器扫描算法中重复吸嘴组的判定
This commit is contained in:
114
generator.py
114
generator.py
@ -8,10 +8,10 @@ from base_optimizer.optimizer_common import *
|
||||
|
||||
class DataMgr:
|
||||
def __init__(self):
|
||||
self.min_placement_points = 100
|
||||
self.max_placement_points = 800
|
||||
self.min_placement_points = 10
|
||||
self.max_placement_points = 1000
|
||||
|
||||
self.max_component_types = 40
|
||||
self.max_component_types = 30
|
||||
self.default_feeder_limit = 1
|
||||
self.max_nozzle_types = 4
|
||||
|
||||
@ -21,7 +21,7 @@ class DataMgr:
|
||||
self.counter = 0
|
||||
self.update = 1
|
||||
self.pre_file = None
|
||||
self.part_col = ["part", "desc", "fdr", "nz", 'camera', 'group', 'feeder-limit', 'points']
|
||||
self.part_col = ["part", "fdr", "nz", 'fdn', 'points']
|
||||
self.component_data = pd.DataFrame(columns=self.part_col) # the component list update for several rounds
|
||||
|
||||
def generator(self, mode='Train'):
|
||||
@ -29,7 +29,7 @@ class DataMgr:
|
||||
if boundary[0] < boundary[-1]:
|
||||
boundary[0], boundary[-1] = boundary[-1], boundary[0]
|
||||
|
||||
nozzle_type_list = random.sample(['CN065', 'CN220', 'CN040', 'CN140'], self.max_nozzle_types)
|
||||
nozzle_type_list = random.sample(['CN065', 'CN020', 'CN040', 'CN140'], self.max_nozzle_types)
|
||||
# determine the nozzle type of component
|
||||
if self.counter % self.get_update_round() == 0 or mode == 'test':
|
||||
self.component_data = self.component_data.loc[[]]
|
||||
@ -38,9 +38,9 @@ class DataMgr:
|
||||
selected_nozzle = random.sample(nozzle_type_list, total_nozzles)
|
||||
for cp_idx in range(min(random.randint(1, self.max_component_types), total_points)):
|
||||
part, nozzle = 'C' + str(cp_idx), random.choice(selected_nozzle)
|
||||
self.component_data = pd.concat([self.component_data, pd.DataFrame(
|
||||
[part, '', 'SM8', nozzle, '飞行相机1', 'CHIP-Rect', self.default_feeder_limit, 0],
|
||||
index=self.part_col).T], ignore_index=True)
|
||||
self.component_data = pd.concat(
|
||||
[self.component_data, pd.DataFrame([part, 'SM8', nozzle, 1, 0], index=self.part_col).T],
|
||||
ignore_index=True)
|
||||
|
||||
random_fractions = np.random.rand(len(self.component_data))
|
||||
normalized_fractions = random_fractions / random_fractions.sum()
|
||||
@ -119,8 +119,8 @@ class DataMgr:
|
||||
|
||||
def encode(self, cp_points: defaultdict[str], cp_nozzle: defaultdict[str], board_width, board_height):
|
||||
assert len(cp_points.keys()) == len(cp_nozzle.keys())
|
||||
assert len(cp_nozzle.keys()) <= self.max_component_types and len(
|
||||
set(cp_nozzle.values())) <= self.max_nozzle_types
|
||||
assert len(set(cp_nozzle.values())) <= self.max_nozzle_types
|
||||
|
||||
# === general info ===
|
||||
total_points = sum(points for points in cp_points.values())
|
||||
total_component_types, total_nozzle_types = len(cp_points.keys()), len(set(cp_nozzle.values()))
|
||||
@ -147,20 +147,6 @@ class DataMgr:
|
||||
|
||||
data.extend(nozzle_slice)
|
||||
|
||||
# === component info ===
|
||||
# cp_items = [[component, points] for component, points in cp_points.items()]
|
||||
# cp_items = sorted(cp_items, key=lambda x: (x[1], nz2idx[cp_nozzle[x[0]]] * 0.1 + x[1]), reverse=True)
|
||||
# for component, points in cp_items:
|
||||
# nozzle = cp_nozzle[component]
|
||||
#
|
||||
# data_slice = [0 for _ in range(self.max_nozzle_types)]
|
||||
# data_slice[nz2idx[nozzle]] = points
|
||||
# data.extend(data_slice)
|
||||
#
|
||||
# assert self.max_component_types >= total_component_types
|
||||
# for _ in range(self.max_component_types - total_component_types):
|
||||
# data.extend([0 for _ in range(self.max_nozzle_types)])
|
||||
|
||||
# === component info ===
|
||||
comp_data_slice = defaultdict(list)
|
||||
for idx in range(self.max_nozzle_types):
|
||||
@ -178,7 +164,10 @@ class DataMgr:
|
||||
data.extend(data_slice)
|
||||
|
||||
for idx in range(self.max_nozzle_types):
|
||||
comp_data_slice[idx].extend([0 for _ in range(self.max_component_types - len(comp_data_slice[idx]))])
|
||||
if len(comp_data_slice[idx]) <= self.max_component_types:
|
||||
comp_data_slice[idx].extend([0 for _ in range(self.max_component_types - len(comp_data_slice[idx]))])
|
||||
else:
|
||||
comp_data_slice[idx] = comp_data_slice[idx][:self.max_component_types]
|
||||
data.extend(comp_data_slice[idx])
|
||||
|
||||
return data
|
||||
@ -404,17 +393,14 @@ class DataMgr:
|
||||
ignore_index=True)
|
||||
return pcb_data, component_data
|
||||
|
||||
def loader(self, file_path):
|
||||
input_data, output_data = [], [] # 输入数据包含元件点数、吸嘴信息等,输出信息包含组装时间
|
||||
# cycle_data, nozzle_change_data, anc_move_data, pickup_data, point_data = [], [], [], [], []
|
||||
# pick_move_data, place_move_data = [], []
|
||||
def loader(self, file_path, data_filter=True, hinter=False):
|
||||
cp_data, point_data, time_data = [], [], []
|
||||
with open(file_path, 'r') as file:
|
||||
line = file.readline()
|
||||
while line:
|
||||
items = line.split('\t')
|
||||
|
||||
cp_points, cp_nozzle = defaultdict(int), defaultdict(str)
|
||||
# cp_width, cp_height = defaultdict(float), defaultdict(float)
|
||||
for cp_idx in range((len(items) - 12) // 3):
|
||||
points = int(items[14 + cp_idx * 3])
|
||||
if points == 0:
|
||||
@ -423,35 +409,59 @@ class DataMgr:
|
||||
component_type, nozzle_type = items[12 + cp_idx * 3], items[13 + cp_idx * 3]
|
||||
cp_points[component_type], cp_nozzle[component_type] = points, nozzle_type
|
||||
|
||||
# cp_width[component_type], cp_height[component_type] = float(items[15 + cp_idx * 5]), float(
|
||||
# items[16 + cp_idx * 5])
|
||||
|
||||
if len(cp_points.keys()) > 20 or len(cp_points.keys()) < 5:
|
||||
line = file.readline()
|
||||
continue
|
||||
|
||||
board_width, board_height = float(items[7]), float(items[8])
|
||||
|
||||
# cycle_data.append(float(items[1]))
|
||||
# nozzle_change_data.append(float(items[2]))
|
||||
# anc_move_data.append(float(items[3]))
|
||||
# pickup_data.append(float(items[4]))
|
||||
# pick_move_data.append(float(items[5]))
|
||||
# place_move_data.append(float(items[6]))
|
||||
# point_data.append(sum(pt for pt in cp_points.values()))
|
||||
cycle, nozzle_change_data, pickup_data = float(items[1]), float(items[2]), float(items[4])
|
||||
point_data.append(sum(int(items[14 + cp_idx * 3]) for cp_idx in range((len(items) - 12) // 3)))
|
||||
|
||||
# assembly time data
|
||||
output_data.append(float(items[0]))
|
||||
time_data.append(float(items[0]))
|
||||
|
||||
cp_data.append([cp_points, cp_nozzle, board_width, board_height])
|
||||
|
||||
# train_data.append(self.encode(cp_points, cp_nozzle, float(items[7]), float(items[8])))
|
||||
input_data.append([cp_points, cp_nozzle, board_width, board_height])
|
||||
# train_data[-1].extend([cycle_data[-1], nozzle_change_data[-1], anc_move_data[-1], pickup_data[-1]])
|
||||
line = file.readline()
|
||||
|
||||
# return train_data, time_data, cycle_data, nozzle_change_data, anc_move_data, pickup_data, pick_move_data, \
|
||||
# place_move_data, point_data
|
||||
if data_filter:
|
||||
cph_data = [point_data[idx] / time_data[idx] * 3600 for idx in range(len(time_data))]
|
||||
|
||||
return [input_data, output_data]
|
||||
w_quart = 0.6
|
||||
Q1, Q3 = np.percentile(np.array(cph_data), 25), np.percentile(np.array(cph_data), 75)
|
||||
|
||||
indices = [i for i in range(len(cph_data)) if
|
||||
Q1 - w_quart * (Q3 - Q1) <= cph_data[i] <= Q3 + w_quart * (Q3 - Q1)]
|
||||
|
||||
filter_cp_data, filter_time_data = [], []
|
||||
for idx in indices:
|
||||
filter_cp_data.append(cp_data[idx])
|
||||
filter_time_data.append(time_data[idx])
|
||||
else:
|
||||
filter_cp_data, filter_time_data = cp_data, time_data
|
||||
|
||||
if hinter:
|
||||
print(
|
||||
f"# of sample: {len(cp_data)}, outlier : {(1 - len(filter_cp_data) / len(cp_data)) * 100: .2f}%, "
|
||||
f"mean: {np.average(filter_time_data): .2f}, median: {np.median(filter_time_data): .2f}, "
|
||||
f"max: {np.max(filter_time_data): .2f}, min: {np.min(filter_time_data): .2f}, "
|
||||
f"std. dev: {np.std(filter_time_data): .2f}")
|
||||
return [filter_cp_data, filter_time_data]
|
||||
|
||||
def metric(self, file_path):
|
||||
metric_data, time_data = [], []
|
||||
with open(file_path, 'r') as file:
|
||||
line = file.readline()
|
||||
while line:
|
||||
items = line.split('\t')
|
||||
|
||||
# cycle, nozzle change, anc move, pick up, pick distance, place distance, point
|
||||
metric_data.append([float(items[i]) for i in list(range(1, 7))])
|
||||
metric_data[-1].extend([sum(int(items[14 + cp_idx * 3]) for cp_idx in range((len(items) - 12) // 3))])
|
||||
|
||||
# assembly time data
|
||||
time_data.append(float(items[0]))
|
||||
|
||||
line = file.readline()
|
||||
|
||||
return [metric_data, time_data]
|
||||
|
||||
def neural_encode(self, input_data):
|
||||
train_data = []
|
||||
@ -468,7 +478,7 @@ class DataMgr:
|
||||
# train_data.append(
|
||||
# [len(cp_points.keys()), len(cp_nozzle.keys()), sum(cp_points.values()), board_width, board_height])
|
||||
# return train_data
|
||||
#
|
||||
|
||||
# def get_feature(self):
|
||||
# return 5
|
||||
|
||||
|
Reference in New Issue
Block a user