More tests, improvements/fixes on the viewer, parser, sender, gerber2gcode... etc

pull/6/head
carlosgs 2013-05-31 00:41:43 +02:00
parent 960d4ab56e
commit 77652958c3
11 changed files with 13988 additions and 17328 deletions

View File

@ -45,7 +45,9 @@ DEVICE = "/dev/ttyUSB0"
Emulate = 0
# End configuration
millis_wait = 0.5 # Delay used when re-trying to send/receive from the serial port [seconds]
lastDrillPos = [0,0,0]
seconds_wait = 0.5 # Delay used when re-trying to send/receive from the serial port [seconds]
serial_timeout = 5 # Timeout for the serial port [seconds]
OK_response = "ok" # First two characters of an OK response (case insensitive)
@ -62,6 +64,7 @@ def connect(baudrate, device, emulate = 0):
Emulate = 0
else:
Emulate = 1
print "EMULATING MACHINE!"
print "Serial port opened, checking connection..."
time.sleep(2)
checkConnection()
@ -72,23 +75,22 @@ def flushRecvBuffer(): # We could also use flushInput(), but showing the data th
return
while CNC_Machine.inWaiting() > 0:
response = CNC_Machine.readline()
if response != '':
print "IGNO: ", response
time.sleep(millis_wait) # Wait some milliseconds between attempts
# if response != '': print "IGNO: ", response
time.sleep(seconds_wait) # Wait some milliseconds between attempts
def sendLine(line):
flushRecvBuffer()
if Emulate == 0:
CNC_Machine.write(line)
print "SENT: ", line
# print "SENT: ", line
def recvLine():
if Emulate:
response = "ok Z30\n" # Asume OK + Z probing result
else:
response = CNC_Machine.readline()
if response != '': print "RECV: ", response
else: print "RECV: Receive timed out!"
# if response != '': print "RECV: ", response
# else: print "RECV: Receive timed out!"
return response
def recvOK():
@ -97,64 +99,86 @@ def recvOK():
return 1
return 0
def waitForOK(): # This is a blocking function
print "Waiting for confirmation"
def waitForOK(command="",timeoutResend=30): # This is a blocking function
# print "Waiting for confirmation"
i = 0
cmnd = command[:3].lower()
timeoutResend = float(timeoutResend)
#timeoutResend = 5.0 # Resend command every 5 seconds, error recovery
#if cmnd == "g28": timeoutResend = 60.0 # Homing moves will take more than 5 seconds
i_timeout = int(timeoutResend/float(serial_timeout+seconds_wait))
# print "i_timeout",i_timeout
while recvOK() != 1:
print " Checking again..."
time.sleep(millis_wait) # Wait some milliseconds between attempts
print " Checking again... timeout:",i_timeout
time.sleep(seconds_wait) # Wait some milliseconds between attempts
if cmnd != "g30" and i >= i_timeout: # WARNING: Commands that take >5s may have problems here!
print " WATCHOUT! RESENDING:",command
sendLine(command)
i = 0
else:
i = i + 1
def sendCommand(command): # Send command and wait for OK
def sendCommand(command,timeoutResend=15): # Send command and wait for OK
sendLine(command)
waitForOK()
waitForOK(command,timeoutResend)
def checkConnection():
print "Checking the connection..."
# print "Checking the connection..."
sendLine("G21\n") # We check the connection setting millimiters as the unit and waiting for the OK response
time.sleep(0.5)
while recvOK() != 1:
sendLine("G21\n")
time.sleep(millis_wait) # Wait some milliseconds between attempts
time.sleep(seconds_wait) # Wait some milliseconds between attempts
def homeZXY():
global lastDrillPos
print "Homing all axis..."
sendCommand("G28 Z0\n") # move Z to min endstop
sendCommand("G28 X0\n") # move X to min endstop
sendCommand("G28 Y0\n") # move Y to min endstop
timeoutResend=30
sendCommand("G28 Z0\n",timeoutResend) # move Z to min endstop
sendCommand("G28 X0\n",timeoutResend) # move X to min endstop
sendCommand("G28 Y0\n",timeoutResend) # move Y to min endstop
if Emulate:
time.sleep(3)
lastDrillPos = [0,0,0]
def moveXYZ(X, Y, Z, F):
print "Moving to:"
global lastDrillPos
# print "Moving to:"
if F <= 0:
print "ERROR: F <= 0"
sendCommand("G1 X"+floats(X)+" Y"+floats(Y)+" Z"+floats(Z)+" F"+floats(F)+"\n")
if Emulate:
dist = (X**2+Y**2+Z**2)**0.5 # [mm]
speed = F/60 # [mm/s]
time.sleep(dist/speed)
dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2+(Z-lastDrillPos[2])**2)**0.5 # [mm]
speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed)
lastDrillPos = [X,Y,Z]
def moveXY(X, Y, F):
print "Moving to:"
global lastDrillPos
# print "Moving to:"
if F <= 0:
print "ERROR: F <= 0"
sendCommand("G1 X"+floats(X)+" Y"+floats(Y)+" F"+floats(F)+"\n")
if Emulate:
dist = (X**2+Y**2)**0.5 # [mm]
speed = F/60 # [mm/s]
time.sleep(dist/speed)
dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2)**0.5 # [mm]
speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed)
lastDrillPos = [X,Y,lastDrillPos[2]]
def moveZ(Z, F):
print "Moving Z absolute:"
global lastDrillPos
# print "Moving Z absolute:"
if F <= 0:
print "ERROR: F <= 0"
sendCommand("G1 Z"+floats(Z)+" F"+floats(F)+"\n")
if Emulate:
dist = abs(Z) # [mm]
speed = F/60 # [mm/s]
time.sleep(dist/speed)
dist = abs(Z-lastDrillPos[2]) # [mm]
speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed)
lastDrillPos = [lastDrillPos[0],lastDrillPos[1],Z]
def moveZrel(Z, F):
print "Moving Z relative:"
# print "Moving Z relative:"
if F <= 0:
print "ERROR: F <= 0"
sendCommand("G91\n") # Set relative positioning
@ -166,6 +190,12 @@ def moveZrelSafe(Z, F):
print "ERROR: F <= 0"
sendCommand("M121\n") # Enable endstops (for protection! usually it should **NOT** hit neither the endstop nor the PCB)
moveZrel(Z, F)
print "Moving Z safely..."
dist = abs(Z-lastDrillPos[2]) # [mm]
speed = float(F)/60.0 # [mm/s]
wait = float(dist)/speed # [s]
time.sleep(wait) # Wait for the movement to finish, this way the M121 command is effective
print " Done moving Z!"
sendCommand("M120\n") # Disable endstops (we only use them for homing)
def probeZ():
@ -174,7 +204,7 @@ def probeZ():
response = recvLine() # Read the response, it is a variable run time so we may need to make multiple attempts
while response == '':
#print "."
time.sleep(millis_wait) # Wait some milliseconds between attempts
time.sleep(seconds_wait) # Wait some milliseconds between attempts
response = recvLine()
response_vals = response.split() # Split the response (i.e. "ok Z:1.23")
if response_vals[0][:2].lower() == OK_response.lower():
@ -185,7 +215,7 @@ def probeZ():
def close():
# IMPORTANT: Before closing the serial port we must make a blocking move in order to wait for all the buffered commands to end
sendCommand("G28 Z0\n") # move Z to min endstop
homeZXY()
if Emulate == 0:
CNC_Machine.close() # Close the serial port connection

View File

@ -189,7 +189,7 @@ def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the to
if distance < closest :
closest = distance
closestMove_i = i
else : # We also consider that paths can be made in reverse
elif path[-1][2] == path[0][2]: # We also consider that paths can be made in reverse # Only in case there is no Z lift
firstPoint = path[-1] # We check the last point first
distance = (toolPosition[0]-firstPoint[0])**2 + (toolPosition[1]-firstPoint[1])**2 # We only check XY
if distance < closest :
@ -217,7 +217,7 @@ def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the to
toolPosition = path[-1] # Set our endpoint as the initial one for the next move
print "Minimum travel distance:", minDistance
print "Minimum XY travel distance:", minDistance**0.5
travel_moves.append([toolPosition, [origin[0], origin[1], travel_height, 10]]) # Return to the origin
return etch_moves, travel_moves

View File

@ -24,8 +24,12 @@ import GcodeParser as gcp
def plotPoints(path_list, color, linewidth): # Thanks to pprzemek (http://stackoverflow.com/questions/2282727/draw-points-using-matplotlib-pyplot-x1-y1-x2-y2)
for path in path_list :
a = np.array(path) # Give to plot() the points in the adequate format
line, = plt.plot(a[:,0], a[:,1], color, linewidth=linewidth*3)
#line.set_antialiased(False) # turn off antialising
if len(path) > 1:
line, = plt.plot(a[:,0], a[:,1], color, linewidth=linewidth*3)
#line.set_antialiased(False) # turn off antialising
else:
plt.plot(path[0][0], path[0][1], c=color, marker='x')
plt.plot(path[0][0], path[0][1], markersize=linewidth*5, c=color, marker='o', mfc='none')
def plotPath(etch_moves, travel_moves, etch_color, travel_color, etch_diam, travel_diam):
plotPoints(etch_moves, etch_color, etch_diam)

View File

@ -1,61 +1,54 @@
(Generated by ./pygerber2gcode_cui_MOD.py )
( 2013-05-30 00:31:03 )
( 2013-05-31 00:41:27 )
(Initialize)
(Start form here)
G0 Z2.000000
G0 X69.163215 Y58.401215
G1 Z-0.271429 F30.000000
G1 X13.029215 F50.000000
G0 Z0.500000
G0 X94.163215 Y58.401215
G1 Z-0.333333 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-0.542857 F30.000000
G1 X13.029215 F50.000000
G1 X94.163215 F50.000000
G1 Z-0.666667 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-0.814286 F30.000000
G1 X13.029215 F50.000000
G1 X94.163215 F50.000000
G1 Z-1.000000 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-1.085714 F30.000000
G1 X13.029215 F50.000000
G1 X94.163215 F50.000000
G1 Z-1.333333 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-1.357143 F30.000000
G1 X13.029215 F50.000000
G1 X94.163215 F50.000000
G1 Z-1.666667 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-1.628571 F30.000000
G1 X13.029215 F50.000000
G1 X94.163215 F50.000000
G1 Z-2.000000 F30.000000
G1 X38.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 X95.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 Z-1.900000 F30.000000
G1 X13.029215 F50.000000
G1 Y4.553215 F50.000000
G1 Y4.299215 F50.000000
G1 X70.433215 F50.000000
G1 Y58.401215 F50.000000
G1 X69.163215 F50.000000
G1 X94.163215 F50.000000
(Goto to Initial position)
G0 Z2.000000
G0 Z0.500000
G0 X0.000000 Y0.000000
G0 Z0.000000

View File

@ -21,16 +21,16 @@ OUT_EDGE_FILE = "printshield_edge.gcode"
INI_X=0.0
INI_Y=0.0
INI_Z=0.0
MOVE_HEIGHT=2.0
MOVE_HEIGHT=0.5
IN_INCH_FLAG=1
OUT_INCH_FLAG=0
MCODE_FLAG=0
XY_SPEED=100
Z_SPEED=60
LEFT_X=15.0
LEFT_X=40.0
LOWER_Y=5.0
DRILL_SPEED=30
DRILL_DEPTH=-1.7
DRILL_SPEED=40
DRILL_DEPTH=-2
CUT_DEPTH=-0.04
TOOL_D=0.1
TOOL_2PASS_D=0.5
@ -40,12 +40,12 @@ CAD_UNIT=0.00254
DRILL_UNIT=0.00254
EDGE_UNIT=0.00254
EDGE_TOOL_D=2.4
EDGE_DEPTH=-1.9
EDGE_DEPTH=-2
EDGE_SPEED=50
EDGE_Z_SPEED=30
MERGE_DRILL_DATA=0
Z_STEP_DRILL=-0.3
Z_STEP_EDGE=-0.5
Z_STEP_DRILL=-0.1
Z_STEP_EDGE=-0.4
GERBER_COLOR=BLACK
DRILL_COLOR=BLUE
EDGE_COLOR=GREEN YELLOW

View File

@ -794,7 +794,7 @@ def circle_points(cx,cy,r,points_num):
elif new_points_num > 50 :
new_points_num = 50
print "Modifyin CIRCLE points_num from",points_num,"to",new_points_num
print "Modifying CIRCLE points_num from",points_num,"to",new_points_num
points_num = new_points_num
# print "Circle: Radius:", str(r), "Points:", points_num
points=[]
@ -1291,19 +1291,21 @@ def drill_hole(cx,cy,r):
global MOVE_HEIGHT, gTMP_DRILL_X, gTMP_DRILL_Y, gTMP_DRILL_Z, DRILL_SPEED, DRILL_DEPTH, Z_STEP_DRILL, XY_SPEED
out_data = ""
gcode_tmp_flag = 0
# r = r/2.0 # REDUCE DRILL SIZE
z_step_n = int(float(DRILL_DEPTH)/float(Z_STEP_DRILL)) + 1
z_step = float(DRILL_DEPTH)/z_step_n
#print "r=" + str(r)
if(MOVE_HEIGHT != gTMP_DRILL_Z):
gTMP_DRILL_Z = MOVE_HEIGHT
out_data += "G0 Z" + floats(gTMP_DRILL_Z) + "\n"
out_data += "G0 X" + floats(cx+r) + " Y" + floats(cy) + "\n"
out_data += "G17\n" #Set XY plane
out_data += "G0 Z" + floats(gTMP_DRILL_Z) + " F" + floats(DRILL_SPEED) + "\n" # MOD
# out_data += "G0 X" + floats(cx+r) + " Y" + floats(cy) + "\n"\
out_data += "G0 X" + floats(cx) + " Y" + floats(cy) + "\n" # CENTER OF THE DRILL
# out_data += "G17\n" #Set XY plane
points = circle_points(cx,cy,r,100)
i = 1
while i <= z_step_n:
gTMP_DRILL_Z = i*z_step
out_data += "G0 Z" + floats(gTMP_DRILL_Z) + " F" + floats(DRILL_SPEED) + "\n"
# out_data += "G0 Z" + floats(gTMP_DRILL_Z) + " F" + floats(DRILL_SPEED) + "\n"
j = 0
cricle_data = "G1"
while j< len(points):
@ -1320,12 +1322,12 @@ def drill_hole(cx,cy,r):
if(gcode_tmp_flag):
#Goto initial X-Y position
cricle_data +=" F" + floats(XY_SPEED)
out_data += cricle_data + "\n"
# out_data += cricle_data + "\n" # DON'T MOVE XY WHILE DRILLING
cricle_data ="G1"
gcode_tmp_flag=0
j += 2
i += 1
out_data += "G0 Z" + floats(DRILL_DEPTH) + " F" + floats(DRILL_SPEED) + "\n" # MOD
gTMP_DRILL_X = cx+r
gTMP_DRILL_Y = cy
return out_data

View File

@ -13,7 +13,7 @@
# Begin configuration
BAUDRATE = 115200
DEVICE = "/dev/ttyUSB0"
DEVICE = "/dev/ttyUSB2"
Emulate = 1
# End configuration
@ -29,13 +29,14 @@ import matplotlib.pyplot as plt
sys.path.append("../CycloneHost")
import GcodeViewer as gcv
import CycloneHost as cy
from helper import *
# End modules
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
fileName = "printshield" # sys.argv[1]
# Display the Gcode that is going to be etched
(etch_moves, travel_moves, gcodeviewer) = gcv.view(filePath,fileName,showEtch=1)
(etch_moves, travel_moves, gcodeviewer) = gcv.view(filePath,fileName,showEdge=1)
figId = gcodeviewer.number
def pltShowNonBlocking():
@ -69,12 +70,12 @@ def drawTool(x, y):
toolPos_point, = plt.plot(0, 0, markersize=12, c='g', marker='x')
pltShowNonBlocking()
F_slowMove = 200 # Move speed [mm/min?]
F_slowMove = 200 # Move speed [mm/min]
F_fastMove = 700
F_etchMove = F_slowMove
F_drillMove = 50
F_edgeMove = 25
F_etchMove = 100
cy.connect(BAUDRATE, DEVICE, Emulate)
@ -89,7 +90,7 @@ drawTool(10, 20) # Show a marker on the gcode plot
# Warning: Do not lower too much or you will potentially cause damage!
initial_Z_lowering_distance = -20
#cy.moveZrelSafe(initial_Z_lowering_distance,F_slowMove/2) # Move Z towards the PCB (saves some probing time for the first coord)
cy.moveZrelSafe(initial_Z_lowering_distance,F_slowMove/2) # Move Z towards the PCB (saves some probing time for the first coord)
Z_origin_offset = cy.probeZ()
print "Z offset:", Z_origin_offset
@ -144,7 +145,7 @@ def getZoffset(x,y):
probingResults()
#print "Zero:",str(getZoffset(0,0))
print "Must be zero:",floats(getZoffset(0,0))
@ -154,90 +155,113 @@ probingResults()
toolPos_X = 0
toolPos_Y = 0
toolPos_Z = 0
toolPos_F = F_fastMove
X_dest = 0
Y_dest = 0
Z_dest = 0
F_dest = F_fastMove
cy.moveZrelSafe(10,F_slowMove)
toolPos_Z = 10
cy.moveZrelSafe(5,F_slowMove)
toolPos_Z = 5
plt.figure(figId)
Zlift = 0.5
Zlift = 1.0
Z_manual_offset = 0.02+10
Z_manual_offset = 0.0
maxDistance = 1**2 # [mm^2] 5mm (longer moves will be split to regulate Z)
maxDistance = 3**2 # [mm^2] 3mm (longer moves will be split to regulate Z)
minDistance = 0.005**2 # [mm^2] 0.005mm is the smallest distance that will be sent
def splitLongEtchMove(distance):
global toolPos_X, toolPos_Y, toolPos_Z, X_dest, Y_dest, Z_dest
global toolPos_X, toolPos_Y, toolPos_Z, toolPos_F, X_dest, Y_dest, Z_dest, F_dest
X_dest_tmp = toolPos_X
Y_dest_tmp = toolPos_Y
Z_dest_tmp = toolPos_Z
F_dest_tmp = toolPos_Z
#distance = distance**0.5 # [mm]
N_steps = int((distance/maxDistance)**0.5) # **must be** >= 1
print "Splitting", distance**0.5, "mm segment into", N_steps, "steps"
print "Orig:", toolPos_X, toolPos_Y, toolPos_Z, "Dest:", X_dest, Y_dest, Z_dest
# print "Orig:", toolPos_X, toolPos_Y, toolPos_Z, "Dest:", X_dest, Y_dest, Z_dest
X_step = (X_dest-toolPos_X)/float(N_steps)
Y_step = (Y_dest-toolPos_Y)/float(N_steps)
Z_step = (Z_dest-toolPos_Z)/float(N_steps)
F_step = (F_dest-toolPos_F)/float(N_steps)
for i in range(N_steps) :
X_dest_tmp = toolPos_X + X_step
Y_dest_tmp = toolPos_Y + Y_step
Z_dest_tmp = toolPos_Z + Z_step
F_dest_tmp = toolPos_F + F_step
Z_real = Z_dest_tmp+Z_origin_offset+getZoffset(X_dest_tmp, Y_dest_tmp)+Z_manual_offset
cy.moveXYZ(X_dest_tmp, Y_dest_tmp, Z_real, F_etchMove)
cy.moveXYZ(X_dest_tmp, Y_dest_tmp, Z_real, F_dest_tmp)
toolPos_refresh(X_dest_tmp, Y_dest_tmp, etching=1)
print "Move:",X_dest_tmp, Y_dest_tmp, Z_dest_tmp
# print "Move:",X_dest_tmp, Y_dest_tmp, Z_dest_tmp
toolPos_X = X_dest_tmp
toolPos_Y = Y_dest_tmp
toolPos_Z = Z_dest_tmp
toolPos_F = F_dest_tmp
raw_input("Turn on the spindle and press enter to begin...")
for path in etch_moves :
toolRefresh = 0
toolPos_draw(toolPos_X, toolPos_Y, etching=0)
cy.moveZrel(Zlift,F_fastMove) # Raise and move to next point
cy.moveZ(Z_origin_offset+getZoffset(X_dest, Y_dest)+Z_manual_offset+Zlift,F_fastMove) # Raise and move to next point
print " travel Z:",Z_manual_offset+Zlift
X_dest = path[0][0]
Y_dest = path[0][1]
cy.moveXY(X_dest, Y_dest, F_fastMove)
F_dest = F_fastMove
cy.moveXY(X_dest, Y_dest, F_dest)
toolPos_draw(X_dest, Y_dest, etching=0)
cy.moveZrel(-Zlift,F_slowMove)
Z_dest = path[0][2]
if Z_dest > 0:
F_dest = F_slowMove
else:
F_dest = path[0][3] # We set the original speed if it is etching/drill
cy.moveZ(Z_dest+Z_origin_offset+getZoffset(X_dest, Y_dest)+Z_manual_offset,F_dest)
print "Speed:",F_dest
print " drill Z:",Z_dest+Z_manual_offset
toolPos_X = X_dest
toolPos_Y = Y_dest
toolPos_Z = Z_dest # Not sure..
toolPos_F = F_dest
# print path
for coord in path[1:] :
X_dest = coord[0]
Y_dest = coord[1]
Z_dest = coord[2]
F_dest = coord[3]
distance = (X_dest-toolPos_X)**2+(Y_dest-toolPos_Y)**2
if distance >= maxDistance :
splitLongEtchMove(distance)
if distance < minDistance :
if distance < minDistance and (Z_dest-toolPos_Z)**2 < 0.001**2 : # Make sure it is not a Z movement
print "Ignoring", distance**0.5, "mm segment!"
continue
Z_real = Z_dest+Z_origin_offset+getZoffset(X_dest, Y_dest)+Z_manual_offset
cy.moveXYZ(X_dest, Y_dest, Z_real, F_etchMove)
cy.moveXYZ(X_dest, Y_dest, Z_real, F_dest)
print "Coords: Speed:",F_dest
toolPos_refresh(X_dest, Y_dest, etching=1)
toolPos_X = X_dest
toolPos_Y = Y_dest
toolPos_Z = Z_dest
toolPos_F = F_dest
cy.homeZXY()
cy.close() # Close the serial port connection
raw_input("Done. Press enter to exit...")