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.
|
# even if Carlosgs has been advised of the possibility of such damages.
|
||||||
|
|
||||||
# Begin configuration
|
# Begin configuration
|
||||||
BAUDRATE = 115200
|
from configuration import * # load settings
|
||||||
DEVICE = "/dev/ttyUSB0"
|
|
||||||
Emulate = 0
|
|
||||||
# End configuration
|
# End configuration
|
||||||
|
|
||||||
# Begin modules
|
# Begin modules
|
||||||
import sys
|
from misc import *
|
||||||
|
|
||||||
import numpy as np
|
import CycloneHost.Controller as cy
|
||||||
from scipy import interpolate
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
sys.path.append("../CycloneHost")
|
|
||||||
import CycloneHost as cy
|
|
||||||
# End modules
|
# End modules
|
||||||
|
|
||||||
|
# Load the Z data file
|
||||||
|
Z_probing_data = loadFromFile(Z_PROBING_FILE)
|
||||||
|
|
||||||
|
|
||||||
cy.connect(BAUDRATE, DEVICE, Emulate)
|
cy.connect(BAUDRATE, DEVICE, Emulate)
|
||||||
|
|
||||||
cy.sendCommand("G90\n") # Set absolute positioning
|
cy.sendCommand("G90\n") # Set absolute positioning
|
||||||
|
@ -37,49 +34,49 @@ cy.homeZXY() # Home all the axis
|
||||||
# (x,y)
|
# (x,y)
|
||||||
#grid_origin = (0,0) # Initial point of the grid [mm]
|
#grid_origin = (0,0) # Initial point of the grid [mm]
|
||||||
#grid_len = (135,84) # Distance to probe [mm]
|
#grid_len = (135,84) # Distance to probe [mm]
|
||||||
#grid_N = (12,6) # Number of points
|
#GRID_N_POINTS = (12,6) # Number of points
|
||||||
grid_origin = (0,0) # Initial point of the grid [mm]
|
#grid_origin = (0,0) # Initial point of the grid [mm]
|
||||||
grid_len = (80,60) # Distance to probe [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)
|
|
||||||
|
|
||||||
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 for speed up the first probe
|
||||||
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)
|
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)
|
# 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, 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
|
|
||||||
|
|
||||||
#x_points = [0.0, 17.5, 35.0, 52.5, 70.0]
|
#x_points = [0.0, 17.5, 35.0, 52.5, 70.0]
|
||||||
#y_points = [0.0, 13.333333333333334, 26.666666666666668, 40.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]]
|
#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
|
#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
|
# Show our grid
|
||||||
print "#--- Probing results [BEGIN COPY TO Send.py] ---"
|
print "#-------- Probing results ---------"
|
||||||
print "x_points = ", x_points
|
print "x_points = ", x_points
|
||||||
print "y_points = ", y_points
|
print "y_points = ", y_points
|
||||||
print "probe_result = ", probe_result
|
print "probe_result = ", probe_result
|
||||||
print "duration = ", duration
|
print "probe_duration = ", probe_duration
|
||||||
print "#--- [END COPY TO Send.py] ---"
|
print "#--------------------------------------"
|
||||||
|
|
||||||
|
# Display values
|
||||||
|
|
||||||
# Must be converted into arrays to use scipy
|
# Must be converted into arrays to use scipy
|
||||||
x_points = np.array(x_points)
|
x_points = np.array(x_points)
|
||||||
y_points = np.array(y_points)
|
y_points = np.array(y_points)
|
||||||
probe_result = np.array(probe_result)
|
probe_result = np.array(probe_result)
|
||||||
|
|
||||||
def pltShowNonBlocking():
|
plt.ion() # IMPORTANT: Enable real-time plotting
|
||||||
plt.ion() # Enable real-time plotting to avoid blocking behaviour for plt.show()
|
|
||||||
plt.show()
|
|
||||||
plt.ioff() # Disable real-time plotting
|
|
||||||
|
|
||||||
plt.figure()
|
plt.figure()
|
||||||
plt.pcolor(x_points, y_points, probe_result)
|
plt.pcolor(x_points, y_points, probe_result)
|
||||||
|
@ -91,11 +88,11 @@ pltShowNonBlocking()
|
||||||
# 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)
|
# Evaluate the interpolation in a 50x50 grid for display
|
||||||
y_points = np.linspace(min(y_points),max(y_points),100)
|
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)
|
z_points = Z_workbed_surface(y_points,x_points)
|
||||||
print z_points
|
#print z_points
|
||||||
|
|
||||||
plt.figure()
|
plt.figure()
|
||||||
plt.pcolor(x_points, y_points, z_points)
|
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
|
plt.axis('equal') # 1:1 aspect ratio
|
||||||
pltShowNonBlocking()
|
pltShowNonBlocking()
|
||||||
|
|
||||||
# TODO:
|
cy.close() # Close the connection with Cyclone
|
||||||
# - Export results to a file with a standarized format
|
|
||||||
# -
|
|
||||||
|
|
||||||
cy.close() # Close the serial port connection
|
|
||||||
|
|
||||||
raw_input("Press enter to exit...")
|
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
|
from scipy import interpolate
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
sys.path.append("../CycloneHost")
|
#sys.path.append("../CycloneHost")
|
||||||
import GcodeParser as gcp
|
import CycloneHost.GcodeParser as gcp
|
||||||
# End modules
|
# End modules
|
||||||
|
|
||||||
# Temporary path to speedup testing
|
# Temporary path to speedup testing
|
||||||
|
@ -30,7 +30,7 @@ import GcodeParser as gcp
|
||||||
#call(["pypy","./pygerber2gcode_cui_MOD.py"])
|
#call(["pypy","./pygerber2gcode_cui_MOD.py"])
|
||||||
#os.chdir("../../gcode_Z_adjust")
|
#os.chdir("../../gcode_Z_adjust")
|
||||||
|
|
||||||
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
filePath = "./GcodeGenerators/pyGerber2Gcode_CUI/out/"
|
||||||
fileName = "printshield" # sys.argv[1]
|
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)
|
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
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
from helper import *
|
from helper import *
|
||||||
# End modules
|
# 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
|
time.sleep(seconds_wait) # Wait some milliseconds between attempts
|
||||||
|
|
||||||
def sendLine(line):
|
def sendLine(line):
|
||||||
flushRecvBuffer()
|
|
||||||
if Emulate == 0:
|
if Emulate == 0:
|
||||||
|
flushRecvBuffer()
|
||||||
CNC_Machine.write(line)
|
CNC_Machine.write(line)
|
||||||
# print "SENT: ", line
|
# print "SENT: ", line
|
||||||
|
|
||||||
def recvLine():
|
def recvLine():
|
||||||
if Emulate:
|
if Emulate:
|
||||||
response = "ok Z30\n" # Asume OK + Z probing result
|
response = "ok\n" # Asume OK
|
||||||
else:
|
else:
|
||||||
response = CNC_Machine.readline()
|
response = CNC_Machine.readline()
|
||||||
# if response != '': print "RECV: ", response
|
# if response != '': print "RECV: ", response
|
||||||
|
@ -213,7 +215,9 @@ def probeZ():
|
||||||
#print "."
|
#print "."
|
||||||
time.sleep(seconds_wait) # Wait some milliseconds between attempts
|
time.sleep(seconds_wait) # Wait some milliseconds between attempts
|
||||||
response = recvLine()
|
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():
|
if response_vals[0][:2].lower() == OK_response.lower():
|
||||||
Zres = response_vals[1][2:] # Ignore the "Z:" and read the coordinate value
|
Zres = response_vals[1][2:] # Ignore the "Z:" and read the coordinate value
|
||||||
print "Result is Z=",Zres
|
print "Result is Z=",Zres
|
||||||
|
@ -226,7 +230,7 @@ def close():
|
||||||
if Emulate == 0:
|
if Emulate == 0:
|
||||||
CNC_Machine.close() # Close the serial port connection
|
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_X = float(grid_origin[0]) # Initial point of the grid [mm]
|
||||||
grid_origin_Y = float(grid_origin[1])
|
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]
|
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_X = grid_len_X/float(grid_N_X-1) # [mm]
|
||||||
grid_inc_Y = grid_len_Y/float(grid_N_Y-1)
|
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
|
y_val = float(y_i)*grid_inc_Y + grid_origin_Y # Calculate Y coordinate
|
||||||
moveXY(x_val, y_val, F_fastMove) # Move to position
|
moveXY(x_val, y_val, F_fastMove) # Move to position
|
||||||
probe_result[y_i][x_i] = probeZ() # Do the Z probing
|
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
|
# 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]
|
Z_offset = probe_result[0][0]
|
|
@ -1,5 +1,5 @@
|
||||||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||||
( 2013-07-17 10:49:14 )
|
( 2013-07-28 02:00:01 )
|
||||||
(Initialize)
|
(Initialize)
|
||||||
|
|
||||||
(Start form here)
|
(Start form here)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||||
( 2013-07-17 10:49:14 )
|
( 2013-07-28 02:00:01 )
|
||||||
(Initialize)
|
(Initialize)
|
||||||
|
|
||||||
(Start form here)
|
(Start form here)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||||
( 2013-07-17 10:49:14 )
|
( 2013-07-28 02:00:01 )
|
||||||
(Initialize)
|
(Initialize)
|
||||||
|
|
||||||
(Start form here)
|
(Start form here)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||||
( 2013-07-17 10:49:14 )
|
( 2013-07-28 02:00:01 )
|
||||||
(Initialize)
|
(Initialize)
|
||||||
|
|
||||||
(Start form here)
|
(Start form here)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(Generated by ./pygerber2gcode_cui_MOD.py )
|
(Generated by ./pygerber2gcode_cui_MOD.py )
|
||||||
( 2013-07-17 10:49:14 )
|
( 2013-07-28 02:00:01 )
|
||||||
(Initialize)
|
(Initialize)
|
||||||
|
|
||||||
(Start form here)
|
(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()
|
||||||
|
|