Implemented the gcode viewer as a module. Bugfix & code cleanup

pull/6/head
carlosgs 2013-05-29 18:16:18 +02:00
parent ce7c72bd00
commit 6375fbcab0
11 changed files with 20977 additions and 167 deletions

View File

@ -20,13 +20,13 @@ import os.path
def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode parser from Etch_Z_adjust.1.8.py (modified by Carlosgs to output toolpaths)
gcode_size = (0,0)
gcode_origin = (0,0)
gcode_sizeXY = (0,0)
gcode_originXY = (0,0)
travel_moves = []
etch_moves = []
if os.path.isfile(filePath) == False :
return etch_moves, travel_moves, gcode_origin, gcode_size
return etch_moves, travel_moves, gcode_originXY, gcode_sizeXY
gcode = open(filePath, "r")
@ -42,6 +42,7 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
X_dest = 0
Y_dest = 0
Z_dest = 10
F_dest = 10
path = []
@ -104,6 +105,8 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
Y_dest = float(get_num(line,char_ptr,num_chars))
elif char == 'Z' :
Z_dest = float(get_num(line,char_ptr,num_chars))
elif char == 'F' :
F_dest = float(get_num(line,char_ptr,num_chars))
char_ptr = char_ptr + 1
if G_dest == 0 or G_dest == 1 :
@ -113,9 +116,9 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
travel_moves.append(path)
path = []
etchMove = True # Set etch mode
path.append([X_dest,Y_dest,Z_dest])
path.append([X_dest,Y_dest,Z_dest,F_dest])
destPoint = [X_dest,Y_dest,Z_dest]
destPoint = [X_dest,Y_dest,Z_dest,F_dest]
if len(path) == 0 or isSame(destPoint,path[-1]) == False: # Don't add same point twice
path.append(destPoint)
@ -138,9 +141,9 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
etch_moves.append(path)
path = []
etchMove = False # Set travel mode
path.append([X_dest,Y_dest,Z_dest])
path.append([X_dest,Y_dest,Z_dest,F_dest])
destPoint = [X_dest,Y_dest,Z_dest]
destPoint = [X_dest,Y_dest,Z_dest,F_dest]
if len(path) == 0 or isSame(destPoint,path[-1]) == False: # Don't add same point twice
path.append(destPoint)
@ -149,16 +152,16 @@ def parseGcodeRaw(filePath, etch_definition = 0, close_shapes = 0): # Gcode pars
if is_first_X == False :
# then there were etch moves so get to work!
gcode_size = (X_max - X_min, Y_max - Y_min)
gcode_origin = (X_min, Y_min)
gcode_sizeXY = (X_max - X_min, Y_max - Y_min)
gcode_originXY = (X_min, Y_min)
print "Gcode XY origin:",str(gcode_origin)
print "Gcode XY length:",str(gcode_size)
print "Gcode XY origin:",str(gcode_originXY)
print "Gcode XY length:",str(gcode_sizeXY)
else : print "No etch moves found!"
gcode.close()
return etch_moves, travel_moves, gcode_origin, gcode_size
return etch_moves, travel_moves, gcode_originXY, gcode_sizeXY
def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the toolpath using closest neighbour (author: Carlosgs)
@ -170,7 +173,7 @@ def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the to
travel_moves = []
toolPosition = [origin[0], origin[1], travel_height]
toolPosition = [origin[0], origin[1], travel_height, 10]
minDistance = 1e9
@ -203,8 +206,8 @@ def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the to
firstPoint = path[0]
if distance > 0.01 : # This will join etching moves closer than 0.01 mm
travel_moves.append([toolPosition, [firstPoint[0], firstPoint[1], travel_height]]) # Travel to the initial point of the etching
if distance > 0.0001 : # This will join etching moves closer than 0.01 mm (sqrt(0.0001)=0.01)
travel_moves.append([toolPosition, [firstPoint[0], firstPoint[1], travel_height, firstPoint[3]] ]) # Travel to the initial point of the etching
if distance < minDistance :
minDistance = distance
@ -216,6 +219,6 @@ def optimize(etch_moves_in, origin=[0,0], travel_height = 5): # Optimizes the to
print "Minimum travel distance:", minDistance
travel_moves.append([toolPosition, [origin[0], origin[1], travel_height]]) # Return to the origin
travel_moves.append([toolPosition, [origin[0], origin[1], travel_height, 10]]) # Return to the origin
return etch_moves, travel_moves

View File

@ -0,0 +1,102 @@
#!/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
import GcodeParser as gcp
# End modules
def plotPoints(path_list, color, linewidth): # Thanks to pprzemek (http://stackoverflow.com/questions/2282727/draw-points-using-matplotlib-pyplot-x1-y1-x2-y2)
for path in path_list :
a = np.array(path) # Give to plot() the points in the adequate format
line, = plt.plot(a[:,0], a[:,1], color, linewidth=linewidth*3)
#line.set_antialiased(False) # turn off antialising
def plotPath(etch_moves, travel_moves, etch_color, travel_color, etch_diam, travel_diam):
plotPoints(etch_moves, etch_color, etch_diam)
plotPoints(travel_moves, travel_color, travel_diam)
def view(filePath,fileName):
#filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
#fileName = "printshield" # sys.argv[1]
plt.figure()
drill_diam = 0.8
etch_diam = 0.1
etch2pass_diam = 0.5
etch3pass_diam = 1
edge_diam = 2.4
travel_diam = etch_diam
# b: blue
# g: green
# r: red
# c: cyan
# m: magenta
# y: yellow
# k: black
# w: white
drill_color = 'r'
etch_color = '#00DF00'
etch2pass_color = '#50EF00'
etch3pass_color = '#A0FF00'
edge_color = 'b'
travel_color = 'c'
plt.hold(True)
plt.title("Gcode viewer")
plt.axis('equal') # 1:1 aspect ratio
print "\n Loading etch..."
gcode_file = filePath+fileName+"_etch.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPath(etch_moves, travel_moves, etch_color, travel_color, etch_diam, travel_diam)
print "\n Loading etch (2nd pass)..."
gcode_file = filePath+fileName+"_etch2pass.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPath(etch_moves, travel_moves, etch2pass_color, travel_color, etch2pass_diam, travel_diam)
print "\n Loading etch (3nd pass)..."
gcode_file = filePath+fileName+"_etch3pass.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPath(etch_moves, travel_moves, etch3pass_color, travel_color, etch3pass_diam, travel_diam)
print "\n Loading drill..."
gcode_file = filePath+fileName+"_drill.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPath(etch_moves, travel_moves, drill_color, travel_color, drill_diam, travel_diam)
print "\n Loading edge..."
gcode_file = filePath+fileName+"_edge.gcode"
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPath(etch_moves, travel_moves, edge_color, travel_color, edge_diam, travel_diam)
plt.ion() # Enable real-time plotting to avoid blocking behaviour for pyplot
plt.show()
return plt

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -72,31 +72,31 @@ plt.axis('equal') # 1:1 aspect ratio
print "\n Loading etch..."
gcode_file = filePath+fileName+"_etch.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
plotPoints(etch_moves, etch_color, etch_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading etch (2nd pass)..."
gcode_file = filePath+fileName+"_etch2pass.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
plotPoints(etch_moves, etch2pass_color, etch2pass_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading etch (3nd pass)..."
gcode_file = filePath+fileName+"_etch3pass.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
plotPoints(etch_moves, etch3pass_color, etch3pass_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading drill..."
gcode_file = filePath+fileName+"_drill.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
plotPoints(etch_moves, drill_color, drill_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading edge..."
gcode_file = filePath+fileName+"_edge.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
plotPoints(etch_moves, edge_color, edge_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
@ -109,35 +109,35 @@ plt.axis('equal') # 1:1 aspect ratio
print "\n Loading etch..."
gcode_file = filePath+fileName+"_etch.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPoints(etch_moves, etch_color, etch_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading etch (2nd pass)..."
gcode_file = filePath+fileName+"_etch2pass.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPoints(etch_moves, etch2pass_color, etch2pass_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading etch (3nd pass)..."
gcode_file = filePath+fileName+"_etch3pass.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPoints(etch_moves, etch3pass_color, etch3pass_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading drill..."
gcode_file = filePath+fileName+"_drill.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPoints(etch_moves, drill_color, drill_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)
print "\n Loading edge..."
gcode_file = filePath+fileName+"_edge.gcode"
(etch_moves, travel_moves, grid_origin, grid_size) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves, gcode_originXY, grid_sizeXY) = gcp.parseGcodeRaw(gcode_file)
(etch_moves, travel_moves) = gcp.optimize(etch_moves)
plotPoints(etch_moves, edge_color, edge_diam)
plotPoints(travel_moves, travel_color, linewidth_travel_move)

View File

@ -0,0 +1,34 @@
#!/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
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")
filePath = "../GcodeGenerators/pyGerber2Gcode_CUI/out/"
fileName = "printshield" # sys.argv[1]
gcv.view(filePath,fileName)
raw_input("Press enter to exit...")

View File

@ -1,141 +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.
#
# CREDIT:
# Based on Etch_Z_adjust.1.8.py from http://www.cnczone.com/forums/pcb_milling/82628-cheap_simple_height-probing.html (multiple authors)
# Begin configuration
BAUDRATE = 115200
DEVICE = "/dev/ttyUSB0"
# End configuration
# Begin modules
import sys
sys.path.append("../CycloneHost")
import CycloneHost as cy
# End modules
fileToFeed = "../GcodeGenerators/pyGerber2Gcode_CUI/out/printshield_pcb.gcode" # sys.argv[1] # Will use this later on to load
gcode = open(fileToFeed, "r")
cy.connect(BAUDRATE, DEVICE)
cy.sendCommand("G90\n") # Set absolute positioning
cy.homeZXY() # Home all the axis
F_slowMove = 200 # Move speed [mm/min?]
F_fastMove = 700
initial_Z_lowering_distance = -15
cy.moveZ(initial_Z_lowering_distance,F_slowMove)
def get_num(line,char_ptr,num_chars):
char_ptr=char_ptr+1
numstr = ''
good = '-.0123456789'
while char_ptr < num_chars:
digit = line[char_ptr]
if good.find(digit) != -1:
numstr = numstr + digit
char_ptr = char_ptr + 1
else: break
return numstr
currentLine = 0.0
lines = gcode.readlines()
totalLines = len(lines)
for line in lines:
currentLine = currentLine + 1
print "Reading:", line, "({0:.1f}%)".format((currentLine / totalLines)*100)
cy.sendCommand(line)
# Height to consider etching
etch_definition = 0
grid_clearance = 0.01
# Check for max and min values in your ngc file
is_first_X = True
is_first_Y = True
is_first_Z = True
# check each line
line_ptr=0
num_lines=len(file_in)
while line_ptr < num_lines:
line = file_in[line_ptr]
X_start = X_dest
Y_start = Y_dest
Z_start = Z_dest
# check each character
char_ptr = 0
num_chars= len(line)
while char_ptr < num_chars:
char = line[char_ptr]
if '(;'.find(char) != -1:
break
elif char == 'G' :
G_dest = get_num(line,char_ptr,num_chars)
elif char == 'X' :
X_dest = float(get_num(line,char_ptr,num_chars))
elif char == 'Y' :
Y_dest = float(get_num(line,char_ptr,num_chars))
elif char == 'Z' :
Z_dest = float(get_num(line,char_ptr,num_chars))
char_ptr = char_ptr + 1
# if the line is an etch move, then replace the line with an etch call
if G_dest == '01' and Z_dest > etch_definition:
line = 'O200 call [%.4f] [%.4f] [%.4f] [%.4f]\n' % (X_start, Y_start, X_dest, Y_dest)
# and now check for max and min X and Y values
if is_first_X == True :
X_min = X_dest
X_max = X_dest
is_first_X = False
else : (X_min, X_max) = test_X(X_min, X_max)
if is_first_Y == True :
Y_min = Y_dest
Y_max = Y_dest
is_first_Y = False
else : (Y_min, Y_max) = test_Y(Y_min, Y_max)
file_out.append(line)
line_ptr=line_ptr+1
if is_first_X == False :
# then there were etch moves so get to work!
# first stretch the X and Y max and min values a _tiny_ amount so the grid is just outside all the etch points
X_min = X_min - grid_clearance
X_max = X_max + grid_clearance
Y_min = Y_min - grid_clearance
Y_max = Y_max + grid_clearance
# Use max and min values for the etch moves to work out the probe grid dimensions
X_span = X_max - X_min
X_grid_origin = X_min
Y_span = Y_max - Y_min
Y_grid_origin = Y_min
gcode.close()
cy.close() # Close the serial port connection