Code cleanup, added Z probing data export and global config file
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# AUTHOR:
|
||||
# Carlosgs (http://carlosgs.es)
|
||||
# LICENSE:
|
||||
# Attribution - Share Alike - Creative Commons (http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
#
|
||||
# DISCLAIMER:
|
||||
# This software is provided "as is", and you use the software at your own risk. Under no
|
||||
# circumstances shall Carlosgs be liable for direct, indirect, special, incidental, or
|
||||
# consequential damages resulting from the use, misuse, or inability to use this software,
|
||||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
|
||||
# Begin configuration
|
||||
from configuration import * # load settings
|
||||
# End configuration
|
||||
|
||||
# Begin modules
|
||||
from misc import *
|
||||
|
||||
import CycloneHost.GcodeViewer as gcv
|
||||
# End modules
|
||||
|
||||
# Gcode generation
|
||||
import os
|
||||
from subprocess import call
|
||||
original_dir = os.getcwd()
|
||||
os.chdir("./GcodeGenerators/pyGerber2Gcode_CUI/")
|
||||
call(["python","./pygerber2gcode_cui_MOD.py"])
|
||||
# call(["pypy","./pygerber2gcode_cui_MOD.py"]) # If you have "pypy" installed go ahead!
|
||||
os.chdir(original_dir)
|
||||
|
||||
|
||||
Z_PROBING_FILE = "Z_probing_data.p"
|
||||
|
||||
|
||||
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
|
||||
gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself (real-time plotting disabled)
|
||||
|
||||
|
||||
|
||||
|
||||
filePath = "./GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
fileName = "GNBoard" # sys.argv[1]
|
||||
|
||||
(etch_moves, travel_moves, gcode_minXY_global, gcode_maxXY_global) = gcv.view(filePath,fileName,showAll=1)
|
||||
|
||||
# Save the dimensions for the Z probing
|
||||
Z_probing_data = {}
|
||||
Z_probing_data['grid_origin'] = gcode_minXY_global
|
||||
(grid_len_X,grid_len_Y) = (gcode_maxXY_global[0]-gcode_minXY_global[0], gcode_maxXY_global[1]-gcode_minXY_global[1])
|
||||
|
||||
# We take in account panelizing
|
||||
grid_len_X *= N_copies_X
|
||||
grid_len_X += N_copies_X*margin_copies_X
|
||||
|
||||
grid_len_Y *= N_copies_Y
|
||||
grid_len_Y += N_copies_Y*margin_copies_Y
|
||||
|
||||
print "PANELIZING: There will be",str(N_copies_X)+"x"+str(N_copies_Y),"copies of this board"
|
||||
|
||||
Z_probing_data['grid_len'] = (grid_len_X,grid_len_Y)
|
||||
|
||||
saveToFile(Z_probing_data,Z_PROBING_FILE)
|
||||
|
||||
pltRefresh(gcodeviewer) # Draw the figure contents, still no window
|
||||
pltShow() # Open the window showing our figure
|
||||
|
||||
raw_input("Press enter to exit...")
|
||||
|
|
@ -12,22 +12,19 @@
|
|||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
|
||||
# Begin configuration
|
||||
BAUDRATE = 115200
|
||||
DEVICE = "/dev/ttyUSB0"
|
||||
Emulate = 0
|
||||
from configuration import * # load settings
|
||||
# End configuration
|
||||
|
||||
# Begin modules
|
||||
import sys
|
||||
from misc import *
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
sys.path.append("../CycloneHost")
|
||||
import CycloneHost as cy
|
||||
import CycloneHost.Controller as cy
|
||||
# End modules
|
||||
|
||||
# Load the Z data file
|
||||
Z_probing_data = loadFromFile(Z_PROBING_FILE)
|
||||
|
||||
|
||||
cy.connect(BAUDRATE, DEVICE, Emulate)
|
||||
|
||||
cy.sendCommand("G90\n") # Set absolute positioning
|
||||
|
@ -37,49 +34,49 @@ cy.homeZXY() # Home all the axis
|
|||
# (x,y)
|
||||
#grid_origin = (0,0) # Initial point of the grid [mm]
|
||||
#grid_len = (135,84) # Distance to probe [mm]
|
||||
#grid_N = (12,6) # Number of points
|
||||
grid_origin = (0,0) # Initial point of the grid [mm]
|
||||
grid_len = (80,60) # Distance to probe [mm]
|
||||
grid_N = (5,5) # Number of points (AT LEAST 4 IN EACH DIRECTION, OTHERWISE INTERPOLATION WILL FAIL)
|
||||
#GRID_N_POINTS = (12,6) # Number of points
|
||||
#grid_origin = (0,0) # Initial point of the grid [mm]
|
||||
#grid_len = (80,60) # Distance to probe [mm]
|
||||
|
||||
Zlift = 0.5 # mm
|
||||
# Use the max values generated when loading the gerber files
|
||||
grid_origin = Z_probing_data['grid_origin']
|
||||
grid_len = Z_probing_data['grid_len']
|
||||
|
||||
F_slowMove = 100
|
||||
|
||||
# Warning: Do not lower too much or you will potentially cause damage!
|
||||
initial_Z_lowering_distance = -10
|
||||
# Initial Z lowering for speed up the first probe
|
||||
cy.moveZrelSafe(initial_Z_lowering_distance,F_slowMove) # Move Z towards the PCB (saves some probing time for the first coord)
|
||||
|
||||
(x_points, y_points, probe_result, Z_offset, duration) = cy.probeGrid(grid_origin, grid_len, grid_N, Zlift)
|
||||
|
||||
#x_points = [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_points = [0.0, 16.8, 33.6, 50.400000000000006, 67.2, 84.0]
|
||||
#probe_result = [[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]]
|
||||
#duration = 346.076061
|
||||
# Do the probing itself
|
||||
(x_points, y_points, probe_result, Z_offset, probe_duration) = cy.probeGrid(grid_origin, grid_len, GRID_N_POINTS, Zlift)
|
||||
|
||||
#x_points = [0.0, 17.5, 35.0, 52.5, 70.0]
|
||||
#y_points = [0.0, 13.333333333333334, 26.666666666666668, 40.0]
|
||||
#probe_result = [[0.0, 0.28000000000000114, 0.490000000000002, 0.5599999999999987, 0.5199999999999996], [0.0, 0.1700000000000017, 0.33000000000000185, 0.41000000000000014, 0.41000000000000014], [-0.030000000000001137, 0.08999999999999986, 0.21999999999999886, 0.3000000000000007, 0.33000000000000185], [-0.08999999999999986, 0.03999999999999915, 0.16000000000000014, 0.26000000000000156, 0.28999999999999915]]
|
||||
#duration = 102.808573
|
||||
|
||||
# Save the values to the Z probing file
|
||||
Z_probing_data['x_points'] = x_points
|
||||
Z_probing_data['y_points'] = y_points
|
||||
Z_probing_data['probe_result'] = probe_result
|
||||
Z_probing_data['probe_duration'] = probe_duration
|
||||
saveToFile(Z_probing_data,Z_PROBING_FILE)
|
||||
|
||||
# Show our grid
|
||||
print "#--- Probing results [BEGIN COPY TO Send.py] ---"
|
||||
print "#-------- Probing results ---------"
|
||||
print "x_points = ", x_points
|
||||
print "y_points = ", y_points
|
||||
print "probe_result = ", probe_result
|
||||
print "duration = ", duration
|
||||
print "#--- [END COPY TO Send.py] ---"
|
||||
print "probe_duration = ", probe_duration
|
||||
print "#--------------------------------------"
|
||||
|
||||
# Display values
|
||||
|
||||
# Must be converted into arrays to use scipy
|
||||
x_points = np.array(x_points)
|
||||
y_points = np.array(y_points)
|
||||
probe_result = np.array(probe_result)
|
||||
|
||||
def pltShowNonBlocking():
|
||||
plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
|
||||
plt.show()
|
||||
plt.ioff() # Disable real-time plotting
|
||||
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
|
||||
plt.figure()
|
||||
plt.pcolor(x_points, y_points, probe_result)
|
||||
|
@ -91,11 +88,11 @@ pltShowNonBlocking()
|
|||
# Interpolation
|
||||
Z_workbed_surface = interpolate.RectBivariateSpline(y_points, x_points, probe_result)
|
||||
|
||||
x_points = np.linspace(min(x_points),max(x_points),100)
|
||||
y_points = np.linspace(min(y_points),max(y_points),100)
|
||||
|
||||
# Evaluate the interpolation in a 50x50 grid for display
|
||||
x_points = np.linspace(min(x_points),max(x_points),50)
|
||||
y_points = np.linspace(min(y_points),max(y_points),50)
|
||||
z_points = Z_workbed_surface(y_points,x_points)
|
||||
print z_points
|
||||
#print z_points
|
||||
|
||||
plt.figure()
|
||||
plt.pcolor(x_points, y_points, z_points)
|
||||
|
@ -104,11 +101,7 @@ plt.title("Z probing results (interpolated) [mm]")
|
|||
plt.axis('equal') # 1:1 aspect ratio
|
||||
pltShowNonBlocking()
|
||||
|
||||
# TODO:
|
||||
# - Export results to a file with a standarized format
|
||||
# -
|
||||
|
||||
cy.close() # Close the serial port connection
|
||||
cy.close() # Close the connection with Cyclone
|
||||
|
||||
raw_input("Press enter to exit...")
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# AUTHOR:
|
||||
# Carlosgs (http://carlosgs.es)
|
||||
# LICENSE:
|
||||
# Attribution - Share Alike - Creative Commons (http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
#
|
||||
# DISCLAIMER:
|
||||
# This software is provided "as is", and you use the software at your own risk. Under no
|
||||
# circumstances shall Carlosgs be liable for direct, indirect, special, incidental, or
|
||||
# consequential damages resulting from the use, misuse, or inability to use this software,
|
||||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
|
||||
# Begin configuration
|
||||
from configuration import * # load settings
|
||||
# End configuration
|
||||
|
||||
# Begin modules
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import cm
|
||||
|
||||
from misc import *
|
||||
|
||||
import CycloneHost.GcodeViewer as gcv
|
||||
import CycloneHost.Controller as cy
|
||||
from CycloneHost.helper import *
|
||||
# End modules
|
||||
|
||||
|
||||
def probingResults(): # quick and dirty temporal code
|
||||
global Z_workbed_surface, x_points, y_points
|
||||
|
||||
# Load the Z data file
|
||||
Z_probing_data = loadFromFile(Z_PROBING_FILE)
|
||||
|
||||
x_points = Z_probing_data['x_points']
|
||||
y_points = Z_probing_data['y_points']
|
||||
probe_result = Z_probing_data['probe_result']
|
||||
probe_duration = Z_probing_data['probe_duration']
|
||||
|
||||
# Must be converted into arrays to use scipy
|
||||
x_points = np.array(x_points)
|
||||
y_points = np.array(y_points)
|
||||
probe_result = np.array(probe_result)
|
||||
|
||||
# Setup interpolation object
|
||||
Z_workbed_surface = interpolate.RectBivariateSpline(y_points, x_points, probe_result)
|
||||
|
||||
# Evaluate the interpolation in a 50x50 grid for display
|
||||
x_points = np.linspace(min(x_points),max(x_points),50)
|
||||
y_points = np.linspace(min(y_points),max(y_points),50)
|
||||
z_points = Z_workbed_surface(y_points,x_points)
|
||||
|
||||
# This will show the Z probing result behind the actual PCB layout, for reference
|
||||
plt.hold(True)
|
||||
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.axis('equal') # 1:1 aspect ratio
|
||||
|
||||
def getZoffset(x,y): # Returns the offset using interpolation
|
||||
return Z_workbed_surface(y,x)[0][0]
|
||||
|
||||
|
||||
|
||||
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
|
||||
gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself (real-time plotting disabled)
|
||||
|
||||
# Load the probing results (this will plot the copper level in the background too)
|
||||
probingResults()
|
||||
#print "Must be zero, otherwise the interpolation is wrong!:",floats(getZoffset(0,0))
|
||||
|
||||
# Display the Gcode that is going to be etched
|
||||
(etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcv.view(filePath,fileName,0,showEtch,showEtch,showEtch2,showDrill,showEdge)
|
||||
#(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,showDrill=1)
|
||||
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEdge=1)
|
||||
|
||||
(boardSizeX,boardSizeY,gcode_minXY_global, gcode_maxXY_global) = gcv.boardSize(filePath,fileName)
|
||||
|
||||
# Show delimiter rectangle
|
||||
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
|
||||
pltShow() # Open the window showing our figure
|
||||
|
||||
#plt.show() # THIS SHOULD BE COMMENTED, USE FOR DEBUG
|
||||
|
||||
toolPos_point = []
|
||||
|
||||
def toolPos_draw(x, y, etching=0):
|
||||
if etching:
|
||||
color = 'r'
|
||||
else:
|
||||
color = 'g'
|
||||
toolPos_point.set_data(x, y)
|
||||
toolPos_point.set_color(color)
|
||||
gcodeviewer.canvas.draw()
|
||||
|
||||
toolRefreshSteps = 1
|
||||
toolRefresh = 0
|
||||
def toolPos_refresh(x, y, etching=0):
|
||||
global toolRefresh
|
||||
if toolRefresh >= toolRefreshSteps:
|
||||
toolPos_draw(toolPos_X, toolPos_Y, etching)
|
||||
toolRefresh = 0
|
||||
toolRefresh = toolRefresh + 1
|
||||
|
||||
def drawTool(x, y):
|
||||
global toolPos_point
|
||||
pltSetFig(gcodeviewer)
|
||||
toolPos_point, = plt.plot(0, 0, markersize=12, c='g', marker='x')
|
||||
pltShowNonBlocking()
|
||||
|
||||
|
||||
cy.connect(BAUDRATE, DEVICE, Emulate)
|
||||
|
||||
cy.sendCommand("G90\n") # Set absolute positioning
|
||||
|
||||
cy.homeZXY() # Home all the axis
|
||||
|
||||
drawTool(10, 20) # Show a marker on the gcode plot
|
||||
|
||||
|
||||
# Move to the origin of the grid
|
||||
cy.moveXY(x_points[0], y_points[0], F_fastMove)
|
||||
|
||||
|
||||
# Warning: Do not lower too much or you will potentially cause damage!
|
||||
initial_Z_lowering_distance = -10
|
||||
cy.moveZrelSafe(initial_Z_lowering_distance,F_slowMove) # Move Z towards the PCB (saves some probing time for the first coord)
|
||||
|
||||
Z_origin_offset = cy.probeZ()
|
||||
print "Z offset:", Z_origin_offset
|
||||
|
||||
|
||||
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
|
||||
|
||||
# Move Z up 5mm, once we have the Z=0 reference. We will then pause to allow user remove electrodes and turn on the spindle
|
||||
cy.moveZrelSafe(5,F_slowMove)
|
||||
toolPos_Z = 5
|
||||
|
||||
pltSetFig(gcodeviewer)
|
||||
|
||||
def splitLongEtchMove(distance):
|
||||
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
|
||||
|
||||
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_global_offset
|
||||
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
|
||||
|
||||
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...")
|
||||
|
||||
def doPath(X_offset=0, Y_offset=0):
|
||||
global toolPos_X, toolPos_Y, toolPos_Z, toolPos_F, X_dest, Y_dest, Z_dest, F_dest
|
||||
for path in etch_moves :
|
||||
toolRefresh = 0
|
||||
toolPos_draw(toolPos_X, toolPos_Y, etching=0)
|
||||
cy.moveZ(Z_origin_offset+getZoffset(X_dest, Y_dest)+Z_global_offset+Zlift_milling,F_fastMove) # Raise and move to next point
|
||||
X_dest = path[0][0]+X_offset
|
||||
Y_dest = path[0][1]+Y_offset
|
||||
F_dest = F_fastMove
|
||||
print " Traveling to:", str([X_dest, Y_dest]), "at Z:", Z_global_offset+Zlift_milling
|
||||
cy.moveXY(X_dest, Y_dest, F_dest)
|
||||
toolPos_draw(X_dest, Y_dest, etching=0)
|
||||
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_global_offset,F_dest)
|
||||
# print "Speed:",F_dest
|
||||
print " Etching at Z:",Z_dest+Z_global_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]+X_offset
|
||||
Y_dest = coord[1]+Y_offset
|
||||
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 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_global_offset
|
||||
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
|
||||
|
||||
# Panelizing supported!
|
||||
for x_i in range(N_copies_X):
|
||||
for y_i in range(N_copies_Y):
|
||||
doPath(x_i*(boardSizeX+margin_copies_X), y_i*(boardSizeY+margin_copies_Y))
|
||||
|
||||
cy.homeZXY() # It is important to send a blocking command in the end
|
||||
cy.close() # Close the connection with Cyclone
|
||||
|
||||
raw_input("Done. Press enter to exit...")
|
||||
|
|
@ -20,8 +20,8 @@ import numpy as np
|
|||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
sys.path.append("../CycloneHost")
|
||||
import GcodeParser as gcp
|
||||
#sys.path.append("../CycloneHost")
|
||||
import CycloneHost.GcodeParser as gcp
|
||||
# End modules
|
||||
|
||||
# Temporary path to speedup testing
|
||||
|
@ -30,7 +30,7 @@ import GcodeParser as gcp
|
|||
#call(["pypy","./pygerber2gcode_cui_MOD.py"])
|
||||
#os.chdir("../../gcode_Z_adjust")
|
||||
|
||||
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
filePath = "./GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
fileName = "printshield" # sys.argv[1]
|
||||
|
||||
def plotPoints(path_list, color, linewidth): # Thanks to pprzemek (http://stackoverflow.com/questions/2282727/draw-points-using-matplotlib-pyplot-x1-y1-x2-y2)
|
|
@ -36,6 +36,8 @@ import serial
|
|||
import time
|
||||
from datetime import datetime
|
||||
|
||||
import random
|
||||
|
||||
from helper import *
|
||||
# End modules
|
||||
|
||||
|
@ -79,14 +81,14 @@ def flushRecvBuffer(): # We could also use flushInput(), but showing the data th
|
|||
time.sleep(seconds_wait) # Wait some milliseconds between attempts
|
||||
|
||||
def sendLine(line):
|
||||
flushRecvBuffer()
|
||||
if Emulate == 0:
|
||||
flushRecvBuffer()
|
||||
CNC_Machine.write(line)
|
||||
# print "SENT: ", line
|
||||
|
||||
def recvLine():
|
||||
if Emulate:
|
||||
response = "ok Z30\n" # Asume OK + Z probing result
|
||||
response = "ok\n" # Asume OK
|
||||
else:
|
||||
response = CNC_Machine.readline()
|
||||
# if response != '': print "RECV: ", response
|
||||
|
@ -213,7 +215,9 @@ def probeZ():
|
|||
#print "."
|
||||
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 Emulate:
|
||||
response = "ok Z"+str(random.gauss(0, 0.25))+"\n" # Generate random measure
|
||||
response_vals = response.split() # Split the response (i.e. "ok Z1.23")
|
||||
if response_vals[0][:2].lower() == OK_response.lower():
|
||||
Zres = response_vals[1][2:] # Ignore the "Z:" and read the coordinate value
|
||||
print "Result is Z=",Zres
|
||||
|
@ -226,7 +230,7 @@ def close():
|
|||
if Emulate == 0:
|
||||
CNC_Machine.close() # Close the serial port connection
|
||||
|
||||
def probeGrid(grid_origin, grid_len, grid_N, Zlift):
|
||||
def probeGrid(grid_origin, grid_len, grid_N, Zlift, F_fastMove = 400, F_slowMove = 100):
|
||||
grid_origin_X = float(grid_origin[0]) # Initial point of the grid [mm]
|
||||
grid_origin_Y = float(grid_origin[1])
|
||||
|
||||
|
@ -238,9 +242,6 @@ def probeGrid(grid_origin, grid_len, grid_N, Zlift):
|
|||
|
||||
Z_probing_lift = float(Zlift) # lift between Z probings [mm]
|
||||
|
||||
F_fastMove = 400
|
||||
F_slowMove = 100
|
||||
|
||||
grid_inc_X = grid_len_X/float(grid_N_X-1) # [mm]
|
||||
grid_inc_Y = grid_len_Y/float(grid_N_Y-1)
|
||||
|
||||
|
@ -269,7 +270,7 @@ def probeGrid(grid_origin, grid_len, grid_N, Zlift):
|
|||
y_val = float(y_i)*grid_inc_Y + grid_origin_Y # Calculate Y coordinate
|
||||
moveXY(x_val, y_val, F_fastMove) # Move to position
|
||||
probe_result[y_i][x_i] = probeZ() # Do the Z probing
|
||||
moveZrel(Z_probing_lift, F_fastMove/2) # Lift the probe
|
||||
moveZrel(Z_probing_lift, F_slowMove) # Lift the probe
|
||||
|
||||
# Once we have all the points, we set the origin as (0,0) and offset the rest of values
|
||||
Z_offset = probe_result[0][0]
|
|
@ -1,5 +1,5 @@
|
|||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||
( 2013-07-17 10:49:14 )
|
||||
( 2013-07-28 02:00:01 )
|
||||
(Initialize)
|
||||
|
||||
(Start form here)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||
( 2013-07-17 10:49:14 )
|
||||
( 2013-07-28 02:00:01 )
|
||||
(Initialize)
|
||||
|
||||
(Start form here)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||
( 2013-07-17 10:49:14 )
|
||||
( 2013-07-28 02:00:01 )
|
||||
(Initialize)
|
||||
|
||||
(Start form here)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||
( 2013-07-17 10:49:14 )
|
||||
( 2013-07-28 02:00:01 )
|
||||
(Initialize)
|
||||
|
||||
(Start form here)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||
( 2013-07-17 10:49:14 )
|
||||
( 2013-07-28 02:00:01 )
|
||||
(Initialize)
|
||||
|
||||
(Start form here)
|
||||
|
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 368 KiB After Width: | Height: | Size: 368 KiB |
|
@ -0,0 +1,52 @@
|
|||
(dp0
|
||||
S'grid_origin'
|
||||
p1
|
||||
(lp2
|
||||
F3.297658
|
||||
aF3.626859
|
||||
asS'x_points'
|
||||
p3
|
||||
(lp4
|
||||
F3.297658
|
||||
aF58.531658
|
||||
aF113.765658
|
||||
aF168.999658
|
||||
asS'probe_result'
|
||||
p5
|
||||
(lp6
|
||||
(lp7
|
||||
F0.0
|
||||
aF0.08471062654900002
|
||||
aF-0.012802879406
|
||||
aF-0.054829865624999974
|
||||
aa(lp8
|
||||
F-0.15824762003099999
|
||||
aF-0.3110290969378
|
||||
aF-0.173515592025
|
||||
aF-0.3831273821244
|
||||
aa(lp9
|
||||
F-0.3498082559894
|
||||
aF-0.21671980311199998
|
||||
aF-0.269577201459
|
||||
aF-0.25634579014500003
|
||||
aa(lp10
|
||||
F-0.13268774191599997
|
||||
aF-0.208003410758
|
||||
aF-0.29902468787299996
|
||||
aF-0.136466972969
|
||||
aasS'grid_len'
|
||||
p11
|
||||
(F165.702
|
||||
F119.09299999999999
|
||||
tp12
|
||||
sS'probe_duration'
|
||||
p13
|
||||
F132.826867
|
||||
sS'y_points'
|
||||
p14
|
||||
(lp15
|
||||
F3.626859
|
||||
aF43.324525666666666
|
||||
aF83.02219233333332
|
||||
aF122.71985899999999
|
||||
as.
|
|
@ -0,0 +1,41 @@
|
|||
# Begin configuration
|
||||
BAUDRATE = 115200
|
||||
DEVICE = "/dev/ttyUSB0"
|
||||
Emulate = True # Won't connect to the machine, will emulate the commands!
|
||||
|
||||
# For GenerateGcode and Send
|
||||
filePath = "./GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
fileName = "GNBoard"
|
||||
# Note: Don't forget to edit ./GcodeGenerators/pyGerber2Gcode_CUI/pygerber2gcode_cui_MOD.conf to match the name and board files
|
||||
|
||||
# For Zprobe
|
||||
GRID_N_POINTS = (4,4) # Number of points (AT LEAST 4 IN EACH DIRECTION, OTHERWISE INTERPOLATION WILL FAIL)
|
||||
Zlift = 0.5 # mm # Lift between probings, it is relative so should be enough
|
||||
|
||||
# For Zprobe and Send
|
||||
F_fastMove = 700 # mm/s
|
||||
F_slowMove = 200 # mm/s
|
||||
initial_Z_lowering_distance = -5 # Warning: Do not lower too much or you will potentially cause damage!
|
||||
|
||||
N_copies_X = 2 # Panelizing options!
|
||||
N_copies_Y = 2
|
||||
margin_copies_X = 5 # mm
|
||||
margin_copies_Y = 5 # mm
|
||||
|
||||
# For Send
|
||||
# IMPORTANT: Select the gcode that is to be milled (only one at a time)
|
||||
showEtch=1
|
||||
showEtch2=0
|
||||
showEtch3=0
|
||||
showDrill=0
|
||||
showEdge=0 # Caution, buggy!
|
||||
|
||||
Zlift_milling = 1.0 # mm
|
||||
Z_global_offset = 0 #-0.018 go deeper!
|
||||
|
||||
maxDistance = 1**2 # [mm^2] 2mm (longer moves will be split to regulate Z)
|
||||
minDistance = 0.001**2 # [mm^2] 0.001mm is the smallest distance that will be sent
|
||||
|
||||
Z_PROBING_FILE = "Z_probing_data.p"
|
||||
# End configuration
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# AUTHOR:
|
||||
# Carlosgs (http://carlosgs.es)
|
||||
# LICENSE:
|
||||
# Attribution - Share Alike - Creative Commons (http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
#
|
||||
# DISCLAIMER:
|
||||
# This software is provided "as is", and you use the software at your own risk. Under no
|
||||
# circumstances shall Carlosgs be liable for direct, indirect, special, incidental, or
|
||||
# consequential damages resulting from the use, misuse, or inability to use this software,
|
||||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
|
||||
# Begin configuration
|
||||
BAUDRATE = 115200
|
||||
DEVICE = "/dev/ttyUSB0"
|
||||
Emulate = 0
|
||||
# End configuration
|
||||
|
||||
# Begin modules
|
||||
import sys
|
||||
from datetime import datetime
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import cm
|
||||
|
||||
sys.path.append("../CycloneHost")
|
||||
import GcodeViewer as gcv
|
||||
import CycloneHost as cy
|
||||
from helper import *
|
||||
# End modules
|
||||
|
||||
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
fileName = "GNBoard" # sys.argv[1]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def pltShowNonBlocking():
|
||||
#plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
|
||||
plt.draw()
|
||||
#plt.ioff() # Disable real-time plotting
|
||||
|
||||
def pltNewFig():
|
||||
fig = plt.figure()
|
||||
#plt.draw()
|
||||
return fig
|
||||
|
||||
def pltSetFig(fig):
|
||||
plt.figure(fig.number)
|
||||
|
||||
def pltRefresh(fig):
|
||||
fig.canvas.draw()
|
||||
|
||||
def pltShow():
|
||||
#plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
plt.draw()
|
||||
#plt.ioff()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def probingResults(): # quick and dirty temporal code
|
||||
global Z_workbed_surface, x_points, y_points
|
||||
# x_points = [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_points = [0.0, 16.8, 33.6, 50.400000000000006, 67.2, 84.0]
|
||||
# probe_result = [[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]]
|
||||
# duration = 346.076061
|
||||
|
||||
# DTMF board
|
||||
# x_points = [0.0, 17.5, 35.0, 52.5, 70.0]
|
||||
# y_points = [0.0, 13.333333333333334, 26.666666666666668, 40.0]
|
||||
# probe_result = [[0.0, 0.28000000000000114, 0.490000000000002, 0.5599999999999987, 0.5199999999999996], [0.0, 0.1700000000000017, 0.33000000000000185, 0.41000000000000014, 0.41000000000000014], [-0.030000000000001137, 0.08999999999999986, 0.21999999999999886, 0.3000000000000007, 0.33000000000000185], [-0.08999999999999986, 0.03999999999999915, 0.16000000000000014, 0.26000000000000156, 0.28999999999999915]]
|
||||
# duration = 102.808573
|
||||
|
||||
# x_points = [70.0, 87.5, 105.0, 122.5, 140.0]
|
||||
# y_points = [0.0, 13.333333333333334, 26.666666666666668, 40.0]
|
||||
# probe_result = [[0.0, -0.15000000000000213, -0.28000000000000114, -0.38000000000000256, -0.4299999999999997], [-0.08000000000000185, -0.20000000000000284, -0.33999999999999986, -0.4400000000000013, -0.490000000000002], [-0.15000000000000213, -0.26000000000000156, -0.370000000000001, -0.46000000000000085, -0.5100000000000016], [-0.21000000000000085, -0.26000000000000156, -0.35999999999999943, -0.4400000000000013, -0.490000000000002]]
|
||||
# duration = 105.028261
|
||||
|
||||
# x_points = [0.0, 20.0, 40.0, 60.0, 80.0]
|
||||
# y_points = [0.0, 15.0, 30.0, 45.0, 60.0]
|
||||
# probe_result = [[0.0, 0.259999999999998, 0.620000000000001, 0.75, 0.6799999999999997], [-0.019999999999999574, 0.21999999999999886, 0.4400000000000013, 0.5399999999999991, 0.5], [-0.05999999999999872, 0.19000000000000128, 0.370000000000001, 0.46000000000000085, 0.4299999999999997], [-0.05999999999999872, 0.16999999999999815, 0.34999999999999787, 0.4400000000000013, 0.4299999999999997], [-0.05000000000000071, 0.21000000000000085, 0.3999999999999986, 0.509999999999998, 0.509999999999998]]
|
||||
# duration = 123.918331
|
||||
|
||||
# x_points = [85.0, 91.25, 97.5, 103.75, 110.0]
|
||||
# y_points = [0.0, 6.25, 12.5, 18.75, 25.0]
|
||||
# probe_result = [[0.0, -0.11999999999999744, -0.2099999999999973, -0.28999999999999915, -0.379999999999999], [-0.05999999999999872, -0.16999999999999815, -0.2699999999999996, -0.34999999999999787, -0.4299999999999997], [-0.11999999999999744, -0.21999999999999886, -0.3099999999999987, -0.389999999999997, -0.46999999999999886], [-0.1599999999999966, -0.259999999999998, -0.34999999999999787, -0.41999999999999815, -0.5], [-0.18999999999999773, -0.2799999999999976, -0.35999999999999943, -0.4299999999999997, -0.509999999999998]]
|
||||
# duration = 97.203638
|
||||
|
||||
# x_points = [85.0, 96.25, 107.5, 118.75, 130.0]
|
||||
# y_points = [30.0, 42.5, 55.0, 67.5, 80.0]
|
||||
# probe_result = [[0.0, -0.12999999999999545, -0.259999999999998, -0.39000000000000057, -0.490000000000002], [-0.00999999999999801, -0.14000000000000057, -0.240000000000002, -0.37999999999999545, -0.46999999999999886], [0.020000000000003126, -0.0799999999999983, -0.19999999999999574, -0.30999999999999517, -0.3999999999999986], [0.030000000000001137, -0.01999999999999602, -0.14000000000000057, -0.22999999999999687, -0.3200000000000003], [0.14999999999999858, 0.10000000000000142, -0.01999999999999602, -0.12999999999999545, -0.22999999999999687]]
|
||||
# duration = 119.124925
|
||||
|
||||
# x_points = [107.0, 113.25, 119.5, 125.75, 132.0]
|
||||
# y_points = [0.0, 7.5, 15.0, 22.5, 30.0]
|
||||
# probe_result = [[0.0, -0.09000000000000341, -0.17999999999999972, -0.2600000000000051, -0.37000000000000455], [-0.0800000000000054, -0.13000000000000256, -0.22000000000000597, -0.3100000000000023, -0.45000000000000284], [-0.09000000000000341, -0.1700000000000017, -0.2600000000000051, -0.35999999999999943, -0.5399999999999991], [-0.10999999999999943, -0.19000000000000483, -0.2700000000000031, -0.38000000000000256, -0.5800000000000054], [-0.12000000000000455, -0.19000000000000483, -0.2700000000000031, -0.38000000000000256, -0.5800000000000054]]
|
||||
# duration = 109.872153
|
||||
|
||||
x_points = [0.0, 20.0, 40.0, 60.0, 80.0]
|
||||
y_points = [0.0, 15.0, 30.0, 45.0, 60.0]
|
||||
probe_result = [[0.0, 0.23000000000000043, 0.5500000000000007, 0.6400000000000006, 0.5600000000000023], [-0.019999999999999574, 0.19000000000000128, 0.41000000000000014, 0.46000000000000085, 0.40000000000000213], [-0.06999999999999673, 0.1700000000000017, 0.3500000000000014, 0.38000000000000256, 0.3200000000000003], [-0.08999999999999986, 0.16000000000000014, 0.33999999999999986, 0.370000000000001, 0.3100000000000023], [-0.11999999999999744, 0.20000000000000284, 0.39000000000000057, 0.4400000000000013, 0.39000000000000057]]
|
||||
duration = 127.59102
|
||||
|
||||
# Show our grid
|
||||
# print "--- Probing results ---"
|
||||
# print "-> X points:", x_points
|
||||
# print "-> Y points:", y_points
|
||||
# print "-> Grid:", probe_result
|
||||
# print "-> Duration:", duration
|
||||
|
||||
# Must be converted into arrays to use scipy
|
||||
x_points = np.array(x_points)
|
||||
y_points = np.array(y_points)
|
||||
probe_result = np.array(probe_result)
|
||||
|
||||
# plt.figure()
|
||||
# plt.pcolor(x_points, y_points, probe_result)
|
||||
# plt.colorbar()
|
||||
# plt.title("Z probing results [mm]")
|
||||
# plt.axis('equal') # 1:1 aspect ratio
|
||||
# pltShowNonBlocking()
|
||||
|
||||
# Interpolation
|
||||
Z_workbed_surface = interpolate.RectBivariateSpline(y_points, x_points, probe_result)
|
||||
|
||||
x_points = np.linspace(min(x_points),max(x_points),50)
|
||||
y_points = np.linspace(min(y_points),max(y_points),50)
|
||||
|
||||
z_points = Z_workbed_surface(y_points,x_points)
|
||||
|
||||
# plt.figure()
|
||||
plt.hold(True)
|
||||
|
||||
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.title("Z probing results (interpolated) [mm]")
|
||||
plt.axis('equal') # 1:1 aspect ratio
|
||||
# pltShowNonBlocking()
|
||||
|
||||
def getZoffset(x,y):
|
||||
return Z_workbed_surface(y,x)[0][0]
|
||||
|
||||
|
||||
|
||||
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
|
||||
gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself (real-time plotting disabled)
|
||||
|
||||
probingResults()
|
||||
print "Must be zero:",floats(getZoffset(0,0))
|
||||
|
||||
# Display the Gcode that is going to be etched
|
||||
(etch_moves, travel_moves, gcode_minXY, gcode_maxXY) = gcv.view(filePath,fileName,showEdge=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,showDrill=1)
|
||||
#(etch_moves, travel_moves) = gcv.view(filePath,fileName,showEdge=1)
|
||||
|
||||
(boardSizeX,boardSizeY,gcode_minXY_global, gcode_maxXY_global) = gcv.boardSize(filePath,fileName)
|
||||
|
||||
# Show delimiter rectangle
|
||||
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
|
||||
pltShow() # Open the window showing our figure
|
||||
|
||||
#plt.show() # THIS SHOULD BE COMMENTED, USE FOR DEBUG
|
||||
|
||||
toolPos_point = []
|
||||
|
||||
def toolPos_draw(x, y, etching=0):
|
||||
if etching:
|
||||
color = 'r'
|
||||
else:
|
||||
color = 'g'
|
||||
toolPos_point.set_data(x, y)
|
||||
toolPos_point.set_color(color)
|
||||
gcodeviewer.canvas.draw()
|
||||
|
||||
toolRefreshSteps = 1
|
||||
toolRefresh = 0
|
||||
def toolPos_refresh(x, y, etching=0):
|
||||
global toolRefresh
|
||||
if toolRefresh >= toolRefreshSteps:
|
||||
toolPos_draw(toolPos_X, toolPos_Y, etching)
|
||||
toolRefresh = 0
|
||||
toolRefresh = toolRefresh + 1
|
||||
|
||||
def drawTool(x, y):
|
||||
global toolPos_point
|
||||
pltSetFig(gcodeviewer)
|
||||
toolPos_point, = plt.plot(0, 0, markersize=12, c='g', marker='x')
|
||||
pltShowNonBlocking()
|
||||
|
||||
F_slowMove = 200 # Move speed [mm/min]
|
||||
F_fastMove = 700
|
||||
|
||||
F_drillMove = 50
|
||||
F_edgeMove = 25
|
||||
F_etchMove = 100
|
||||
|
||||
|
||||
cy.connect(BAUDRATE, DEVICE, Emulate)
|
||||
|
||||
cy.sendCommand("G90\n") # Set absolute positioning
|
||||
|
||||
cy.homeZXY() # Home all the axis
|
||||
|
||||
drawTool(10, 20) # Show a marker on the gcode plot
|
||||
|
||||
|
||||
# Move to the origin of the grid
|
||||
cy.moveXY(x_points[0], y_points[0], F_fastMove)
|
||||
|
||||
|
||||
# Warning: Do not lower too much or you will potentially cause damage!
|
||||
initial_Z_lowering_distance = -10
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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(5,F_slowMove)
|
||||
toolPos_Z = 5
|
||||
|
||||
pltSetFig(gcodeviewer)
|
||||
|
||||
Zlift = 1.0
|
||||
|
||||
Z_manual_offset = -0.018
|
||||
|
||||
maxDistance = 1**2 # [mm^2] 2mm (longer moves will be split to regulate Z)
|
||||
minDistance = 0.001**2 # [mm^2] 0.001mm is the smallest distance that will be sent
|
||||
|
||||
def splitLongEtchMove(distance):
|
||||
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
|
||||
|
||||
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_dest_tmp)
|
||||
toolPos_refresh(X_dest_tmp, Y_dest_tmp, etching=1)
|
||||
|
||||
# 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...")
|
||||
|
||||
def doPath(X_offset=0, Y_offset=0):
|
||||
global toolPos_X, toolPos_Y, toolPos_Z, toolPos_F, X_dest, Y_dest, Z_dest, F_dest
|
||||
for path in etch_moves :
|
||||
toolRefresh = 0
|
||||
toolPos_draw(toolPos_X, toolPos_Y, etching=0)
|
||||
cy.moveZ(Z_origin_offset+getZoffset(X_dest, Y_dest)+Z_manual_offset+Zlift,F_fastMove) # Raise and move to next point
|
||||
X_dest = path[0][0]+X_offset
|
||||
Y_dest = path[0][1]+Y_offset
|
||||
F_dest = F_fastMove
|
||||
print " Traveling to:", str([X_dest, Y_dest]), "at Z:", Z_manual_offset+Zlift
|
||||
cy.moveXY(X_dest, Y_dest, F_dest)
|
||||
toolPos_draw(X_dest, Y_dest, etching=0)
|
||||
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 " Etching at 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]+X_offset
|
||||
Y_dest = coord[1]+Y_offset
|
||||
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 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_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
|
||||
|
||||
# --- Panelizing options! ---
|
||||
N_copies_X = 1
|
||||
N_copies_Y = 1
|
||||
marginX = 5
|
||||
marginY = 5
|
||||
# --- --- ---
|
||||
for x_i in range(N_copies_X):
|
||||
for y_i in range(N_copies_Y):
|
||||
doPath(x_i*(boardSizeX+marginX), y_i*(boardSizeY+marginY))
|
||||
|
||||
cy.homeZXY()
|
||||
cy.close() # Close the serial port connection
|
||||
|
||||
raw_input("Done. Press enter to exit...")
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# AUTHOR:
|
||||
# Carlosgs (http://carlosgs.es)
|
||||
# LICENSE:
|
||||
# Attribution - Share Alike - Creative Commons (http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
#
|
||||
# DISCLAIMER:
|
||||
# This software is provided "as is", and you use the software at your own risk. Under no
|
||||
# circumstances shall Carlosgs be liable for direct, indirect, special, incidental, or
|
||||
# consequential damages resulting from the use, misuse, or inability to use this software,
|
||||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
|
||||
# Begin modules
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import cm
|
||||
|
||||
sys.path.append("../CycloneHost")
|
||||
import GcodeViewer as gcv
|
||||
# End modules
|
||||
|
||||
# Temporary path to speedup testing
|
||||
import os
|
||||
from subprocess import call
|
||||
os.chdir("../GcodeGenerators/pyGerber2Gcode_CUI/")
|
||||
call(["pypy","./pygerber2gcode_cui_MOD.py"])
|
||||
os.chdir("../../gcode_Z_adjust")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def pltShowNonBlocking():
|
||||
#plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
|
||||
plt.draw()
|
||||
#plt.ioff() # Disable real-time plotting
|
||||
|
||||
def pltNewFig():
|
||||
fig = plt.figure()
|
||||
#plt.draw()
|
||||
return fig
|
||||
|
||||
def pltSetFig(fig):
|
||||
plt.figure(fig.number)
|
||||
|
||||
def pltRefresh(fig):
|
||||
fig.canvas.draw()
|
||||
|
||||
def pltShow():
|
||||
#plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
plt.draw()
|
||||
#plt.ioff()
|
||||
|
||||
|
||||
|
||||
|
||||
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
|
||||
gcodeviewer = pltNewFig() # Define a new figure, this doesnt open a window by itself (real-time plotting disabled)
|
||||
|
||||
|
||||
|
||||
|
||||
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||
fileName = "GNBoard" # sys.argv[1]
|
||||
|
||||
gcv.view(filePath,fileName,showAll=1)
|
||||
|
||||
|
||||
|
||||
pltRefresh(gcodeviewer) # Draw the figure contents, still no window
|
||||
pltShow() # Open the window showing our figure
|
||||
|
||||
raw_input("Press enter to exit...")
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import cm
|
||||
|
||||
import pickle # For file saving
|
||||
|
||||
# Misc functions:
|
||||
|
||||
def saveToFile(data,path):
|
||||
with open(path, 'wb') as path_file:
|
||||
ret = pickle.dump(data, path_file)
|
||||
path_file.close()
|
||||
return ret
|
||||
raise Exception("Could not save " + path)
|
||||
|
||||
def loadFromFile(path):
|
||||
with open(path) as path_file:
|
||||
ret = pickle.load(path_file)
|
||||
path_file.close()
|
||||
return ret
|
||||
raise Exception("Could not load " + path)
|
||||
|
||||
|
||||
def pltShowNonBlocking():
|
||||
#plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
|
||||
plt.draw()
|
||||
#plt.ioff() # Disable real-time plotting
|
||||
|
||||
def pltNewFig():
|
||||
fig = plt.figure()
|
||||
#plt.draw()
|
||||
return fig
|
||||
|
||||
def pltSetFig(fig):
|
||||
plt.figure(fig.number)
|
||||
|
||||
def pltRefresh(fig):
|
||||
fig.canvas.draw()
|
||||
|
||||
def pltShow():
|
||||
#plt.ion() # IMPORTANT: Enable real-time plotting
|
||||
plt.draw()
|
||||
#plt.ioff()
|
||||
|