Newer
Older
#!/usr/bin/env python
import numpy as np
import ezdxf
import random
from pathfinding.core.diagonal_movement import DiagonalMovement
from pathfinding.core.grid import Grid
from pathfinding.finder.a_star import AStarFinder
import copy
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def __init__(self,path,dxf_file):
self.dwg=ezdxf.readfile(path+dxf_file)
self.msp=self.dwg.modelspace()
self.fail_flag=False #return True when path not found
self.create_layer('Cut',5)
self.create_layer('Circuit',1)
self.create_layer('Label',3)
self.create_layer('Fold',4)
self.create_layer('Pin_temp',6)
self.layer_rearrange() ## reagrrange cut and fold lines to corresponding layers
self.remove_wheels() ##remove wheel drawings for this design, no need to call for other designs
self.find_pin()
isolength=2.6 #mm
# self.connections_list=np.array([[0,0],[0,0]]).reshape(1,2,2)
# connection_amount=4
# for i in range(connection_amount):
# s=random.randint(0,len(self.center_arr)-1)
# e=random.randint(0,len(self.center_arr)-1)
# connections=np.array([[self.center_arr[s],self.center_arr[e]]]).reshape(1,2,2)
# self.connections_list=np.append(self.connections_list,connections,axis=0)
# self.connections_list=np.rint(self.connections_list)[1:]
############for testing and demo purpose #############
self.connections_list=self.test_connections()
# self.matrix_temp=copy.deepcopy(self.matrix)
# self.img=plt.imshow(self.matrix_temp,interpolation='nearest',cmap=cm.Spectral)
# ani=animation.FuncAnimation(self.fig,self.find_multi_path,interval=10)
# plt.show()
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
def create_layer(self,layer_name,color):
if not layer_name in self.dwg.layers:
self.dwg.layers.new(name=layer_name,dxfattribs={'color':color})
def layer_rearrange(self):
# put fold lines to the new layer 'Fold'
# put cut lines to the new layer 'Cut
for e in self.msp.query('LINE'):
if e.dxf.color!=5:
e.dxf.layer='Fold'
else:
e.dxf.layer='Cut'
def find_pin(self):
tolerance=0.05 #mm
pincutsize=1 #mm
pin_edge_arr=np.array([[0,0],[0,0]]).reshape(1,2,2)
self.center_arr=np.array([[0,0]])
for e in self.msp.query('LINE[layer=="Cut"]'):
length= sqrt((e.dxf.start[0]-e.dxf.end[0])**2+(e.dxf.start[1]-e.dxf.end[1])**2)
if length > pincutsize-tolerance and length < pincutsize + tolerance:
e.dxf.layer='Pin_temp'
if e.dxf.start[1]==e.dxf.end[1]: ##this line is horizontal
pin_edge=np.array([e.dxf.start,e.dxf.end])[:,:2]
pin_edge_arr=np.concatenate((pin_edge_arr,pin_edge.reshape(1,2,2)),axis=0)
pin_edge_arr=pin_edge_arr[1:]
# print(pin_edge_arr)
for i in range(len(pin_edge_arr)):
for e in np.delete(pin_edge_arr,i,axis=0):
if pin_edge_arr[i][0,1]-e[0,1]==1.0:
center_x=pin_edge_arr[i][0,0]-0.5
center_y=pin_edge_arr[i][0,1]-0.5
center=np.array([center_x,center_y]).reshape(1,2)
self.center_arr=np.append(self.center_arr,center,axis=0)
self.center_arr=np.unique(self.center_arr,axis=0)
self.center_arr=self.center_arr[1:]
#no need to call this function for other design
for e in self.msp.query('Arc LINE[layer=="Cut"]'):
if e.dxf.start[0]>=179:
self.msp.delete_entity(e)
def draw_on_pin(self,fulllength): #isolation
iso=self.dwg.blocks.new(name='ISO_BLK')
isolength=fulllength/2
iso.add_line((-isolength,isolength),(isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-isolength),(isolength,-isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-isolength),(-isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((isolength,-isolength),(isolength,isolength),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,-trace_w/2),(-(isolength+5),-trace_w/2),dxfattribs={'linetype':'DASHDOT'})
iso.add_line((-isolength,trace_w/2),(-(isolength+5),trace_w/2),dxfattribs={'linetype':'DASHDOT'})
for center_point in self.center_arr:
self.msp.add_blockref('ISO_BLK',center_point,dxfattribs={'layer':'Circuit'})
def read_dxf_as_matrix(self):
"""unit: mm
accuracy issue expected atm (mm round up)
"""
for line in self.msp.query('LINE[layer!="Fold" & layer!="Label" & layer!="Pin_temp"]'):
start=np.rint(line.dxf.start)
end=np.rint(line.dxf.end)
i=int(start[0])
j=int(start[1])
#can draw horizontal or vertical lines only
if j==end[1]: #this line is a horizontal line
while i!=end[0]:
if i<end[0]:
i+=1
else:
i-=1
while j!=end[1]:
if j<end[1]:
j+=1
else:
j-=1
def find_a_path(self,matrixws,start_point,end_point):
"""
find a path between two points on img=matrix
start_point and end_point shape: (2,)
"""
#DEBUG:
# if not np.array_equal(matrixws,self.matrix):
# print('Map updated')
grid = Grid(matrix=matrixws)
start=grid.node(int(start_point[0]),int(start_point[1]))
end=grid.node(int(end_point[0]),int(end_point[1]))
finder = AStarFinder(diagonal_movement=4)
path, runs = finder.find_path(start, end, grid)
return path
def draw_a_path(self,path,matrix,dxf=False):
""" draw a path on img=matrix, or on dxf file too"""
for i in range(len(path)-1):
self.msp.add_line(path[i],path[i+1],dxfattribs={
'layer':'Circuit',
'linetype':'DASHDOT'})
def get_cost(self,path):
print('one path not found')
self.fail_flag=True
"""connection list shape : NX2X2 """
print("==========Auto rounting start===========")
print 'episode:',episode+1,'(/',E,')==========='
random_ix=random.randint(0,len(self.connections_list)-1)
init_s=self.connections_list[random_ix]
current_solving=np.array([init_s]).reshape(1,2,2)
con_list_temp=np.delete(self.connections_list,random_ix,axis=0)
cur_path=self.find_a_path(self.matrix_temp,init_s[0],init_s[1])
self.draw_a_path(cur_path,self.matrix_temp)
# self.img.set_array(self.matrix_temp)
while len(con_list_temp)!=0:
random_ix=random.randint(0,len(con_list_temp)-1)
next_conn=con_list_temp[random_ix]
current_solving=np.append(current_solving,next_conn.reshape(1,2,2),axis=0)
con_list_temp=np.delete(con_list_temp,random_ix,axis=0)
curpath=self.find_a_path(self.matrix_temp,next_conn[0],next_conn[1])
self.draw_a_path(curpath,self.matrix_temp)
curpath_temp.append(curpath)
# self.img.set_array(self.matrix_temp)
if episode==0:
self.Q_buff=copy.deepcopy(self.Q)
if self.Q<=self.Q_buff:
self.Q_buff=copy.deepcopy(self.Q)
self.final_solving=current_solving
self.final_fail=self.fail_flag
print 'Current cost:',self.Q,'Best cost',self.Q_buff
if not self.final_fail:
for i in range(len(self.final_path)):
self.draw_a_path(self.final_path[i],self.matrix,True)
else:
print 'One or more path cannot be solved'
def test_connections(self):
y=97
x=90
arti_pin_array=np.empty((1,2))
center_pin_conn=np.empty((1,2))
pin_conn=np.empty((1,2,2))
for i in range(10):
arti_pin=(x+i,y)
arti_pin_array=np.append(arti_pin_array,[arti_pin],axis=0)
arti_pin_array=arti_pin_array[1:]
for i in range(len(self.center_arr)):
if self.center_arr[i][1]<60:
center_pin_conn=np.append(center_pin_conn,self.center_arr[i].reshape(1,2),axis=0)
if len(center_pin_conn)>10: break
center_pin_conn=center_pin_conn[1:]
for i in range(10):
pin_conn_temp=np.array([arti_pin_array[i],center_pin_conn[i]]).reshape(1,2,2)
pin_conn=np.append(pin_conn,pin_conn_temp,axis=0)
pin_conn=pin_conn[1:]
# def main():
path='/home/jingyan/Documents/summer_intern_lemur/roco_electrical/'
dxf_file='graph-silhouette.dxf'
router=auto_rounter(path,dxf_file)
# animation.FuncAnimation(edit.fig,plt.imshow(edit.matrix_temp))
# plt.show()