import time # import pandas as pd from lxml import etree from collections import Counter from . import preload_datas_functions as preload # import preload_datas_functions as preload class FeatureParser: """ 解析Feature.xml文件 """ def __init__(self, xml_file): self.root = etree.parse(xml_file).getroot() self.size = self._get_size() self.holes = self._get_holes() self.slots = self._get_slot() self.open_slots = self._get_open_slot() self.vectors = self._get_vectors() def _get_size(self): size = self.root.find('Size') return { 'length': float(size.get('Length')), 'width': float(size.get('Width')), 'height': float(size.get('Height')) } def _get_vectors(self): vectors = {} for item in self.root.findall('.//Item'): vector = item.find('Vector') if vector is not None: key = (vector.get('i'), vector.get('j'), vector.get('k')) vectors[key] = vectors.get(key, 0) + 1 return vectors def get_vector_counts(self): return len(self.vectors) def _get_holes(self): holes = [] hole_element = self.root.find('Hole') if hole_element is not None: for item in self.root.find('Hole').iter('Item'): hole = {} # 每个hole是一个字典 hole['id'] = int(item.get('ID')) hole['name'] = item.get('Name') hole['red'] = int(item.get('Red')) hole['green'] = int(item.get('Green')) hole['blue'] = int(item.get('Blue')) # 处理circles circles = [] for circle in item.iter('Circle'): circles.append({ 'x': float(circle.get('x')), 'y': float(circle.get('y')), 'z': float(circle.get('z')), 'rad': float(circle.get('rad')) }) hole['circles'] = circles # 处理bottom bottoms = [] for bottom in item.iter('Bottom'): bottoms.append({ 'x': float(bottom.get('x')), 'y': float(bottom.get('y')), 'z': float(bottom.get('z')), 'rad': float(bottom.get('rad')) }) hole['bottoms'] = bottoms # 处理vector for vector in item.iter('Vector'): hole['vector'] = { 'i': float(vector.get('i')), 'j': float(vector.get('j')), 'k': float(vector.get('k')) } # 创建元组并添加到列表中 z_rad_tuples = [] max_z = None non_zero_rads = set() # 使用set来存储rad值,自动去重 for circle in circles: z = float(circle.get('z')) rad = float(circle.get('rad')) if max_z is None or z > max_z: max_z = z if rad != 0: non_zero_rads.add(rad) for rad in non_zero_rads: z_rad_tuple = (max_z, rad) z_rad_tuples.append(z_rad_tuple) hole['z_rad_tuples'] = z_rad_tuples holes.append(hole) # 添加到holes列表中 return holes def _get_slot(self): """ 获取slot信息 """ slots = [] slot_a_list = [] slot_element = self.root.find('Slot') if slot_element is not None: for item in self.root.find('Slot').iter('Item'): slot = {} slot['id'] = int(item.get('ID')) slot['name'] = item.get('Name') slot['red'] = int(item.get('Red')) slot['green'] = int(item.get('Green')) slot['blue'] = int(item.get('Blue')) # 获取Volume和Area信息 volume = item.find('Volume') if volume is not None: slot['volume'] = float(volume.get('value')) area = item.find('Area') if area is not None: slot['area'] = float(area.get('value')) slot_a_list.append(slot['area']) # 处理lines lines = [] for line in item.iter('Line'): lines.append({ 'type': line.get('Type'), # 'type' : 'line' or 'arc 'x1': float(line.get('x1')), 'y1': float(line.get('y1')), 'z1': float(line.get('z1')), 'x2': float(line.get('x2')), 'y2': float(line.get('y2')), 'z2': float(line.get('z2')) }) slot['lines'] = lines # 处理Arc arcs = [] for arc in item.iter('Arc'): arcs.append({ 'type': arc.get('Type'), 'x1': float(arc.get('x1')), 'y1': float(arc.get('y1')), 'z1': float(arc.get('z1')), 'x2': float(arc.get('x2')), 'y2': float(arc.get('y2')), 'z2': float(arc.get('z2')), 'x3': float(arc.get('x3')), 'y3': float(arc.get('y3')), 'z3': float(arc.get('z3')) }) slot['arcs'] = arcs slot['a'] = slot_a_list slots.append(slot) return slots def _get_open_slot(self): """ 获取open_slot信息 """ open_slots = [] open_slot_v_list = [] open_slot_element = self.root.find('OpenSlot') if open_slot_element is not None: for item in self.root.find('OpenSlot').iter('Item'): open_slot = {} open_slot['id'] = int(item.get('ID')) open_slot['name'] = item.get('Name') open_slot['red'] = int(item.get('Red')) open_slot['green'] = int(item.get('Green')) open_slot['blue'] = int(item.get('Blue')) # 获取Volume和Area信息 volume = item.find('Volume') if volume is not None: open_slot['volume'] = float(volume.get('value')) area = item.find('Area') if area is not None: open_slot['area'] = float(area.get('value')) # open_slot_v_list.append(round(open_slot['volume'] / open_slot['area'], 3)) open_slot_v_list.append(open_slot['area']) # 处理lines lines = [] for line in item.iter('Line'): lines.append({ 'type': line.get('Type'), # 'type' : 'line' or 'arc 'x1': float(line.get('x1')), 'y1': float(line.get('y1')), 'z1': float(line.get('z1')), 'x2': float(line.get('x2')), 'y2': float(line.get('y2')), 'z2': float(line.get('z2')) }) open_slot['lines'] = lines # 处理Arc arcs = [] for arc in item.iter('Arc'): arcs.append({ 'type': arc.get('Type'), 'x1': float(arc.get('x1')), 'y1': float(arc.get('y1')), 'z1': float(arc.get('z1')), 'x2': float(arc.get('x2')), 'y2': float(arc.get('y2')), 'z2': float(arc.get('z2')), 'x3': float(arc.get('x3')), 'y3': float(arc.get('y3')), 'z3': float(arc.get('z3')) }) open_slot['arcs'] = arcs open_slot['v'] = open_slot_v_list open_slots.append(open_slot) return open_slots def hole_time(parser): """ 计算孔的工时 :return: """ # 判断是否有孔 if parser.holes is not None: # 遍历所有的孔,获取孔径和孔深度,然后调用函数查询工时 hole_total_time = 0 nums = 1 expand_hole = '否' j_time = 0 j_hole_nums = 0 hole_nums = 0 for hole in parser.holes: for z_rad_tuple in hole['z_rad_tuples']: if (2 * z_rad_tuple[1] * z_rad_tuple[0] <= 3750) and (2 * z_rad_tuple[1] <= 25): hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = preload.get_suitable_hole_working_hours(preload.df_hole_duration, 2 * z_rad_tuple[1], z_rad_tuple[0]) # if per_time_minute is None: # raise Exception('孔径为%s,深度为%s的孔没有找到对应的工时' % (2 * z_rad_tuple[1], z_rad_tuple[0])) # print('per_time_minute', per_time_minute) expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif (2 * z_rad_tuple[1] * z_rad_tuple[0] <= 3750) and (2 * z_rad_tuple[1] > 25): hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.0003 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif 3750 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 50000: hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.0003 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif 50000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 100000: hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.00018 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif 100000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 150000: hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.00016 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif 150000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 200000: hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.00015 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time elif 200000 < 2 * z_rad_tuple[1] * z_rad_tuple[0] <= 250000: hole_nums += 1 # print('z_rad_tuple', z_rad_tuple) per_time_minute = 0.0002 * 2 * z_rad_tuple[1] * z_rad_tuple[0] expand_hole_end = 0.6 if expand_hole == '是' else 1 per_time = (per_time_minute * 1 * expand_hole_end + j_time * j_hole_nums * expand_hole_end) / 60 hole_total_time += per_time else: raise Exception('孔径为%s,深度为%s的孔没有找到对应的工时' % (2 * z_rad_tuple[1], z_rad_tuple[0])) print('孔工时', round(hole_total_time * nums * 2) / 2) print('共有%s个孔,其中%s为台阶孔' % (len(parser.holes), hole_nums - len(parser.holes))) return round(hole_total_time * nums * 2) / 2 else: return 0 def slot_time(parser): # 判断是否有槽 if parser.slots is not None: # 遍历所有的槽,获取槽的长度,然后调用函数查询工时 slot_total_time = 0 nums = 1 finish_time = 0 process_time = 0 process_total_time = 0 slot_a = parser.slots[0]['a'] slot_a_counter = Counter(slot_a) slot_a_counter_result = dict(slot_a_counter) for i in slot_a_counter_result: for slot in parser.slots: if slot['area'] == i: # # 计算长度(第一条线和第三条线的X轴距离) # length = abs(slot['lines'][0]['y1'] - slot['lines'][2]['y1']) # # 计算宽度(第一条线和第二条线的Y轴距离) # width = abs(slot['lines'][1]['x1'] - slot['lines'][3]['x1']) # # 计算面积 # area = length * width # 槽深度 depth = round(slot['volume'] / slot['area'], 3) # 沟通刀具暂定为12 finish_tool_diameter = 12 if 200 < slot['area'] <= 5000: finish_time = 0 # 加工穴数待定(取得每一个槽的穴数和装夹次数,那这个数量?目前暂时按1来算,待有统计数据之后再说) rough_part_nums = slot_a_counter_result[slot['area']] rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 # 调用函数计算槽的工时 slot_total_time = preload.get_suitable_rough_working_hours(preload.df_rough_duration, depth) # if nums > 20: # process_time = round( # (nums * 0.6 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # elif nums > 10: # process_time = round( # (nums * 0.7 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # elif nums > 6: # process_time = round( # (nums * 0.8 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # elif nums > 4: # process_time = round( # (nums * 0.9 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # elif nums > 1: # process_time = round( # (nums * 0.95 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # else: # process_time = round( # (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( # finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 process_time = round( (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # print('slot_total_time', slot_total_time) elif slot['area'] <= 200: slot_total_time = 0 rough_part_nums = slot_a_counter_result[slot['area']] rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 # 调用函数计算槽的工时 finish_time = preload.get_suitable_finish_working_hours(preload.df_finish_duration, depth, finish_tool_diameter) process_time = round( (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # print('finish_time', finish_time) else: rough_part_nums = slot_a_counter_result[slot['area']] rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 process_time = round( (nums * 1 * ((0.00016 * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 process_total_time += process_time print('槽工时', process_total_time) return process_total_time else: return 0 def open_slot_time(parser): # 判断是否有开口槽 if parser.open_slots is not None: # 遍历所有的开口槽,获取槽宽和槽长,然后调用函数查询工时 open_slot_total_time = 0 nums = 1 finish_time = 0 open_slot_process_time = 0 open_slot_v = parser.open_slots[0]['v'] counter = Counter(open_slot_v) result = dict(counter) transiant_time = 0 for i in result: for open_slot in parser.open_slots: if open_slot['area'] == i: depth = round(open_slot['volume'] / open_slot['area'], 3) # 沟通刀具暂定为12 finish_tool_diameter = 12 if 200 < open_slot['area'] <= 5000: finish_time = 0 # 加工穴数待定(取得每一个槽的穴数和装夹次数,那这个数量?目前暂时按1来算,待有统计数据之后再说) rough_part_nums = result[open_slot['area']] rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 # 调用函数计算槽的工时 slot_total_time = preload.get_suitable_rough_working_hours(preload.df_rough_duration, depth) open_slot_process_time = round( (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # print('slot_total_time', slot_total_time) elif open_slot['area'] <= 200: slot_total_time = 0 rough_part_nums = 1 rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 # 调用函数计算槽的工时 finish_time = preload.get_suitable_finish_working_hours(preload.df_finish_duration, depth, finish_tool_diameter) open_slot_process_time = round( (nums * 1 * ((slot_total_time * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 # print('finish_time', finish_time) else: rough_part_nums = 1 rough_clamping_times = 1 finishi_part_nums = 1 finish_clamping_times = 1 open_slot_process_time = round( (nums * 1 * ((0.00016 * rough_part_nums + rough_clamping_times * 20) + ( finish_time * finishi_part_nums + finish_clamping_times * 25)) / 60) * 2) / 2 transiant_time += open_slot_process_time print('开口槽工时', transiant_time) return transiant_time else: return 0 if __name__ == '__main__': time1 = time.time() parser = FeatureParser( 'D:\\ccccccccccccccccccccccccccccccccccccccccccccccc\\aa\\JKM001-260.200.30_FeatureTable.xml') # print('parser', parser.holes) # print('parser.slots', parser.slots) # print('parser.open_slots', parser.open_slots) print('总工时', hole_time(parser) + slot_time(parser) + open_slot_time(parser)) time2 = time.time() print('耗时:', time2 - time1)