Improvements in the GUI, Gcode Parser, Gcode Viewer and Bugfix in Cyclone Host. Now emulator works 100%

pull/6/head
carlosgs 2013-06-01 12:48:57 +02:00
parent 1b11c8b96b
commit ceb222b536
6 changed files with 57 additions and 91 deletions

View File

@ -139,7 +139,8 @@ def homeZXY():
sendCommand("G28 Y0\n",timeoutResend) # move Y to min endstop sendCommand("G28 Y0\n",timeoutResend) # move Y to min endstop
if Emulate: if Emulate:
time.sleep(2) time.sleep(2)
lastDrillPos = [0,0,0] lastDrillPos = [0,0,0]
print "Done homing"
def moveXYZ(X, Y, Z, F): def moveXYZ(X, Y, Z, F):
global lastDrillPos global lastDrillPos
@ -151,7 +152,7 @@ def moveXYZ(X, Y, Z, F):
dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2+(Z-lastDrillPos[2])**2)**0.5 # [mm] dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2+(Z-lastDrillPos[2])**2)**0.5 # [mm]
speed = float(F)/60.0 # [mm/s] speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed) time.sleep(float(dist)/speed)
lastDrillPos = [X,Y,Z] lastDrillPos = [X,Y,Z]
def moveXY(X, Y, F): def moveXY(X, Y, F):
global lastDrillPos global lastDrillPos
@ -163,7 +164,7 @@ def moveXY(X, Y, F):
dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2)**0.5 # [mm] dist = ((X-lastDrillPos[0])**2+(Y-lastDrillPos[1])**2)**0.5 # [mm]
speed = float(F)/60.0 # [mm/s] speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed) time.sleep(float(dist)/speed)
lastDrillPos = [X,Y,lastDrillPos[2]] lastDrillPos = [X,Y,lastDrillPos[2]]
def moveZ(Z, F): def moveZ(Z, F):
global lastDrillPos global lastDrillPos
@ -175,22 +176,28 @@ def moveZ(Z, F):
dist = abs(Z-lastDrillPos[2]) # [mm] dist = abs(Z-lastDrillPos[2]) # [mm]
speed = float(F)/60.0 # [mm/s] speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed) time.sleep(float(dist)/speed)
lastDrillPos = [lastDrillPos[0],lastDrillPos[1],Z] lastDrillPos = [lastDrillPos[0],lastDrillPos[1],Z]
def moveZrel(Z, F): def moveZrel(Z, F):
global lastDrillPos
# print "Moving Z relative:" # print "Moving Z relative:"
if F <= 0: if F <= 0:
print "ERROR: F <= 0" print "ERROR: F <= 0"
sendCommand("G91\n") # Set relative positioning sendCommand("G91\n") # Set relative positioning
moveZ(Z, F) sendCommand("G1 Z"+floats(Z)+" F"+floats(F)+"\n")
if Emulate:
dist = abs(Z) # [mm]
speed = float(F)/60.0 # [mm/s]
time.sleep(float(dist)/speed)
lastDrillPos = [lastDrillPos[0],lastDrillPos[1],lastDrillPos[2]+Z] # Relative movement
sendCommand("G90\n") # Set absolute positioning sendCommand("G90\n") # Set absolute positioning
def moveZrelSafe(Z, F): def moveZrelSafe(Z, F):
if F <= 0: if F <= 0:
print "ERROR: F <= 0" print "ERROR: F <= 0"
print "Moving Z", Z, "mm safely..."
sendCommand("M121\n") # Enable endstops (for protection! usually it should **NOT** hit neither the endstop nor the PCB) sendCommand("M121\n") # Enable endstops (for protection! usually it should **NOT** hit neither the endstop nor the PCB)
moveZrel(Z, F) moveZrel(Z, F)
print "Moving Z safely..."
dist = abs(Z-lastDrillPos[2]) # [mm] dist = abs(Z-lastDrillPos[2]) # [mm]
speed = float(F)/60.0 # [mm/s] speed = float(F)/60.0 # [mm/s]
wait = float(dist)/speed # [s] wait = float(dist)/speed # [s]

View File

@ -20,13 +20,13 @@ import os.path
def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode parser from Etch_Z_adjust.1.8.py (modified by Carlosgs to output toolpaths) def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode parser from Etch_Z_adjust.1.8.py (modified by Carlosgs to output toolpaths)
gcode_sizeXY = (0,0) gcode_maxXY = (0,0)
gcode_originXY = (0,0) gcode_minXY = (0,0)
travel_moves = [] travel_moves = []
etch_moves = [] etch_moves = []
if os.path.isfile(filePath) == False : if os.path.isfile(filePath) == False :
return etch_moves, travel_moves, gcode_originXY, gcode_sizeXY return etch_moves, travel_moves, gcode_minXY, gcode_maxXY
gcode = open(filePath, "r") gcode = open(filePath, "r")
@ -152,16 +152,17 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
if is_first_X == False : if is_first_X == False :
# then there were etch moves so get to work! # then there were etch moves so get to work!
gcode_sizeXY = (X_max - X_min, Y_max - Y_min) gcode_maxXY = [X_max, Y_max]
gcode_originXY = (X_min, Y_min) gcode_minXY = [X_min, Y_min]
print "Gcode XY origin:",str(gcode_originXY) print "Gcode XY min:",str(gcode_minXY)
print "Gcode XY length:",str(gcode_sizeXY) print "Gcode XY max:",str(gcode_maxXY)
else : print "No etch moves found!"
else :
print "No etch moves found!"
return etch_moves, travel_moves, [0,0], [0,0]
gcode.close() gcode.close()
return etch_moves, travel_moves, gcode_originXY, gcode_sizeXY return etch_moves, travel_moves, gcode_minXY, gcode_maxXY
def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the toolpath using closest neighbour (author: Carlosgs) def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the toolpath using closest neighbour (author: Carlosgs)

View File

@ -70,6 +70,15 @@ def view(filePath,fileName,showAll=0,showEtch=0,showEtch2=0,showEtch3=0,showDril
edge_color = 'b' edge_color = 'b'
travel_color = 'c' travel_color = 'c'
gcode_minXY_global = [1e9,1e9]
gcode_maxXY_global = [-1e9,-1e9]
def checkMinMax(gcode_minXY,gcode_maxXY):
if gcode_minXY[0] < gcode_minXY_global[0]: gcode_minXY_global[0] = gcode_minXY[0]
if gcode_minXY[1] < gcode_minXY_global[1]: gcode_minXY_global[1] = gcode_minXY[1]
if gcode_maxXY[0] > gcode_maxXY_global[0]: gcode_maxXY_global[0] = gcode_maxXY[0]
if gcode_maxXY[1] > gcode_maxXY_global[1]: gcode_maxXY_global[1] = gcode_maxXY[1]
if draw: if draw:
plt.title("Gcode viewer") plt.title("Gcode viewer")
plt.axis('equal') # 1:1 aspect ratio plt.axis('equal') # 1:1 aspect ratio
@ -78,40 +87,41 @@ def view(filePath,fileName,showAll=0,showEtch=0,showEtch2=0,showEtch3=0,showDril
if showAll or showEtch: if showAll or showEtch:
print "\n Loading etch..." print "\n Loading etch..."
gcode_file = filePath+fileName+"_etch.gcode" gcode_file = filePath+fileName+"_etch.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file) (etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves) (etch_moves, travel_moves) = gcp.optimize(etch_moves)
if draw: plotPath(etch_moves, travel_moves, etch_color, travel_color, etch_diam, travel_diam) if draw: plotPath(etch_moves, travel_moves, etch_color, travel_color, etch_diam, travel_diam)
checkMinMax(gcode_minXY,gcode_maxXY)
if showAll or showEtch2: if showAll or showEtch2:
print "\n Loading etch (2nd pass)..." print "\n Loading etch (2nd pass)..."
gcode_file = filePath+fileName+"_etch2pass.gcode" gcode_file = filePath+fileName+"_etch2pass.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file) (etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves) (etch_moves, travel_moves) = gcp.optimize(etch_moves)
if draw: plotPath(etch_moves, travel_moves, etch2pass_color, travel_color, etch2pass_diam, travel_diam) if draw: plotPath(etch_moves, travel_moves, etch2pass_color, travel_color, etch2pass_diam, travel_diam)
if showAll or showEtch3: if showAll or showEtch3:
print "\n Loading etch (3nd pass)..." print "\n Loading etch (3nd pass)..."
gcode_file = filePath+fileName+"_etch3pass.gcode" gcode_file = filePath+fileName+"_etch3pass.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file) (etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves) (etch_moves, travel_moves) = gcp.optimize(etch_moves)
if draw: plotPath(etch_moves, travel_moves, etch3pass_color, travel_color, etch3pass_diam, travel_diam) if draw: plotPath(etch_moves, travel_moves, etch3pass_color, travel_color, etch3pass_diam, travel_diam)
if showAll or showDrill: if showAll or showDrill:
print "\n Loading drill..." print "\n Loading drill..."
gcode_file = filePath+fileName+"_drill.gcode" gcode_file = filePath+fileName+"_drill.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file) (etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves) (etch_moves, travel_moves) = gcp.optimize(etch_moves)
if draw: plotPath(etch_moves, travel_moves, drill_color, travel_color, drill_diam, travel_diam) if draw: plotPath(etch_moves, travel_moves, drill_color, travel_color, drill_diam, travel_diam)
if showAll or showEdge: if showAll or showEdge:
print "\n Loading edge..." print "\n Loading edge..."
gcode_file = filePath+fileName+"_edge.gcode" gcode_file = filePath+fileName+"_edge.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file) (etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves) (etch_moves, travel_moves) = gcp.optimize(etch_moves)
if draw: plotPath(etch_moves, travel_moves, edge_color, travel_color, edge_diam, travel_diam) if draw: plotPath(etch_moves, travel_moves, edge_color, travel_color, edge_diam, travel_diam)
#if draw : plt.hold(False) #if draw : plt.hold(False)
if draw and newFigure: pltShowNonBlocking() if draw and newFigure: pltShowNonBlocking()
return (etch_moves, travel_moves) return (etch_moves, travel_moves, gcode_minXY_global, gcode_maxXY_global)

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View File

@ -25,6 +25,7 @@ import time
import numpy as np import numpy as np
from scipy import interpolate from scipy import interpolate
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib import cm
sys.path.append("../CycloneHost") sys.path.append("../CycloneHost")
import GcodeViewer as gcv import GcodeViewer as gcv
@ -56,7 +57,9 @@ def pltRefresh(fig):
fig.canvas.draw() fig.canvas.draw()
def pltShow(): def pltShow():
#plt.ion() # IMPORTANT: Enable real-time plotting
plt.draw() plt.draw()
#plt.ioff()
@ -93,14 +96,15 @@ def probingResults(): # quick and dirty temporal code
# Interpolation # Interpolation
Z_workbed_surface = interpolate.RectBivariateSpline(y_points, x_points, probe_result) Z_workbed_surface = interpolate.RectBivariateSpline(y_points, x_points, probe_result)
x_points = np.linspace(min(x_points),max(x_points),100) x_points = np.linspace(min(x_points),max(x_points),50)
y_points = np.linspace(min(y_points),max(y_points),100) y_points = np.linspace(min(y_points),max(y_points),50)
z_points = Z_workbed_surface(y_points,x_points) z_points = Z_workbed_surface(y_points,x_points)
# plt.figure() # plt.figure()
plt.hold(True) plt.hold(True)
plt.pcolor(x_points, y_points, z_points)
z_cf = plt.pcolor(x_points, y_points, z_points, alpha=0.2, cmap=cm.copper, edgecolors='k', linewidths=0) # Show Z probing height, with a light-tone colormap
plt.colorbar() plt.colorbar()
# plt.title("Z probing results (interpolated) [mm]") # plt.title("Z probing results (interpolated) [mm]")
plt.axis('equal') # 1:1 aspect ratio plt.axis('equal') # 1:1 aspect ratio
@ -111,30 +115,29 @@ def getZoffset(x,y):
plt.ion() # IMPORTANT: Enable real-time plotting plt.ion() # IMPORTANT: Enable real-time plotting
gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself (real-time plotting disabled)
probingResults() probingResults()
print "Must be zero:",floats(getZoffset(0,0)) print "Must be zero:",floats(getZoffset(0,0))
# Display the Gcode that is going to be etched # Display the Gcode that is going to be etched
(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEtch=1) (etch_moves, travel_moves, gcode_minXY_global, gcode_maxXY_global) = gcv.view(filePath,fileName,showEtch=1)
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEtch1=1) #(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEtch1=1)
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEtch2=1) #(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEtch2=1)
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showDrill=1) #(etch_moves, travel_moves) = gcv.view(filePath,fileName,showDrill=1)
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEdge=1) #(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEdge=1)
# Truncate the background to the dimensions of the PCB
x_dat = [gcode_minXY_global[0],gcode_minXY_global[0],gcode_maxXY_global[0],gcode_maxXY_global[0],gcode_minXY_global[0]]
y_dat = [gcode_minXY_global[1],gcode_maxXY_global[1],gcode_maxXY_global[1],gcode_minXY_global[1],gcode_minXY_global[1]]
plt.plot(x_dat,y_dat)
pltRefresh(gcodeviewer) # Draw the figure contents, still no window pltRefresh(gcodeviewer) # Draw the figure contents, still no window
pltShow() # Open the window showing our figure pltShow() # Open the window showing our figure
plt.show() # THIS SHOULD BE COMMENTED, USE FOR DEBUG #plt.show() # THIS SHOULD BE COMMENTED, USE FOR DEBUG
toolPos_point = [] toolPos_point = []
@ -211,8 +214,8 @@ Zlift = 1.0
Z_manual_offset = 0.0 Z_manual_offset = 0.0
maxDistance = 2**2 # [mm^2] 3mm (longer moves will be split to regulate Z) maxDistance = 2**2 # [mm^2] 2mm (longer moves will be split to regulate Z)
minDistance = 0.005**2 # [mm^2] 0.005mm is the smallest distance that will be sent minDistance = 0.001**2 # [mm^2] 0.001mm is the smallest distance that will be sent
def splitLongEtchMove(distance): def splitLongEtchMove(distance):
global toolPos_X, toolPos_Y, toolPos_Z, toolPos_F, X_dest, Y_dest, Z_dest, F_dest global toolPos_X, toolPos_Y, toolPos_Z, toolPos_F, X_dest, Y_dest, Z_dest, F_dest

View File

@ -1,55 +0,0 @@
# -*- encoding: utf-8 -*-
# Based on http://scipy-user.10969.n7.nabble.com/2D-Interpolation-td4248.html
import scipy
import scipy.interpolate
def pltShowNonBlocking():
plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
plt.show()
plt.ioff() # Disable real-time plotting
# the two axes
x = scipy.array([0.0, 12.272727272727273, 24.545454545454547, 36.81818181818182, 49.09090909090909, 61.36363636363637, 73.63636363636364, 85.9090909090909, 98.18181818181819, 110.45454545454547, 122.72727272727273, 135.0])
y = scipy.array([0.0, 16.8, 33.6, 50.400000000000006, 67.2, 84.0])
# make some pretend data
gridy, gridx = scipy.meshgrid(x,y)
z = scipy.array([[0.0, 0.2, 0.4, 0.53, 0.58, 0.6, 0.56, 0.53, 0.5, 0.44, 0.33, 0.2], [-0.03, 0.07, 0.16, 0.26, 0.32, 0.33, 0.33, 0.33, 0.29, 0.23, 0.15, 0.05], [-0.07, 0.0, 0.05, 0.12, 0.16, 0.2, 0.2, 0.22, 0.2, 0.16, 0.08, 0.0], [-0.07, -0.03, 0.04, 0.11, 0.15, 0.19, 0.2, 0.22, 0.22, 0.19, 0.11, 0.04], [0.0, 0.04, 0.08, 0.19, 0.23, 0.29, 0.33, 0.36, 0.37, 0.32, 0.2, 0.11], [0.13, 0.2, 0.27, 0.37, 0.44, 0.51, 0.55, 0.61, 0.64, 0.55, 0.41, 0.22]])
# create a spline interpolator
spl = scipy.interpolate.RectBivariateSpline(y,x,z)
# make some new axes to interpolate to
nx = scipy.linspace(min(x),max(x),100)
ny = scipy.linspace(min(y),max(y),100)
# evaluate
nz = spl(ny, nx)
import matplotlib.pyplot as plt
plt.figure()
plt.pcolor(x, y, z)
plt.title("Datos [mm]")
plt.colorbar()
plt.axis('equal') # 1:1 aspect ratio
pltShowNonBlocking()
plt.figure()
plt.pcolor(nx, ny, nz)
plt.title("Datos interpolados [mm]")
plt.colorbar()
plt.axis('equal') # 1:1 aspect ratio
pltShowNonBlocking()
# Comprobación de que el error es mínimo
plt.figure()
plt.pcolor(x, y, spl(y,x) - z)
plt.title("Diferencia entre datos originales e interpolados (error) [mm]")
plt.colorbar()
plt.axis('equal') # 1:1 aspect ratio
pltShowNonBlocking()
raw_input("Press enter to exit...")