diff --git a/.gitignore b/.gitignore
index 66f2656dcc..b8c0121598 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,8 @@ cscope.*
oprofile*
*.log
position.txt
-*.9
+# *.9
*.glade.h
# Ignore test results
*.result
+
diff --git a/README_es.md b/README_es.md
new file mode 100644
index 0000000000..52b66df7e9
--- /dev/null
+++ b/README_es.md
@@ -0,0 +1,25 @@
+# LinuxCNC
+
+LinuxCNC controla máquinas CNC. Puede manejar fresadoras, tornos, impresoras 3D, cortadores láser, cortadores de plasma, brazos de robot, hexápodos y otras. http://linuxcnc.org/
+
+# DESCARGO DE RESPONSABILIDAD
+
+** LOS AUTORES DE ESTE SOFTWARE NO ACEPTAN ABSOLUTAMENTE NINGUNA RESPONSABILIDAD POR NINGÚN DAÑO O PÉRDIDA RESULTANTE DE SU USO. **
+
+** ES _EXTREMADAMENTE_ IMPRUDENTE CONFIAR LA SEGURIDAD SOLO AL SOFTWARE. **
+
+** Cualquier maquinaria capaz de dañar a las personas debe tener prevista la desconexion completa de energía de todos los motores, etc., antes de que las personas entren en cualquier área peligrosa.
+
+** Toda la maquinaria debe estar diseñada para cumplir con las normas y códigos de seguridad locales y nacionales, y los autores de este software no pueden, y no lo hacen, asumir cualquier responsabilidad derivada de dicho cumplimiento. **
+
+
+Este software se lanza bajo licencia GPLv2, con algunas partes bajo LGPL. Vea el archivo COPYING para más detalles.
+
+La traduccion al español de este software queda adherida a este descargo y a las licencias GPLv2 y partes LGPL.
+
+
+# El proceso de construcción
+
+Consulte el archivo 'docs/src/code/building-linuxcnc.txt' para obtener información sobre cómo construir y ejecutar el software, o vea:
+
+http://linuxcnc.org/docs/devel/html/code/building-linuxcnc.html
diff --git a/VERSION b/VERSION
index 7a280f505b..f8cac27e8d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1,2 @@
2.9.0~pre0
+
diff --git a/configs/apps/README_es b/configs/apps/README_es
new file mode 100644
index 0000000000..cf66120708
--- /dev/null
+++ b/configs/apps/README_es
@@ -0,0 +1,11 @@
+info: crear archivo de información del sistema
+
+Directorios:
+
+gladevcp -- widgets de demostración
+halrun ---- inicia halrun en xterm
+latency --- aplicaciones para investigar latencia
+parport --- pruebas de puerto paralelo
+pyvcp ----- demostraciones
+xhc-hbo4 -- prueba de volante usb inalámbrico
+
diff --git a/configs/apps/gladevcp/README.changes_es b/configs/apps/gladevcp/README.changes_es
new file mode 100644
index 0000000000..c5f7dd9079
--- /dev/null
+++ b/configs/apps/gladevcp/README.changes_es
@@ -0,0 +1,63 @@
+Nota sobre los cambios API de los manejadores de clase y persistence.py:
+
+Manejadores de clase:
+=====================
+
+El parámetro 'panel' se eliminó de get_handlers() ya que no es necesario.
+En consecuencia, el manejador del método __init__() no recibe este
+parámetro:
+
+class HandlerClass:
+ ...
+ def __init__(self, halcomp,builder,useropts):
+ self.halcomp = halcomp
+ self.builder = builder
+
+def get_handlers(halcomp,builder,useropts):
+
+ return [HandlerClass(halcomp,builder,useropts)]
+
+Acceso a widgets en manejadores de clases:
+==========================================
+
+Para un widget con nombre, use:
+ w = self.builder.get_object("widgetname")
+
+Para recuperar una lista de todos los widgets en el archivo UI, use:
+ wl = self.builder.get_objects()
+
+Esto funciona independientemente de si la interfaz de usuario está en formato libglade o GtkBuilder.
+
+persistence.py
+==============
+El manejador del parámetro builder se ha simplificado. Se elimina
+de los métodos save_state y restore_state, y se agrega en su lugar al método
+IniFile.__init__(). Por lo tanto, utilicelo de la siguiente manera:
+
+class HandlerClass:
+ ...
+
+ def on_destroy(self,obj,data=None):
+ # note: save_state(
2
+ 1
+ 211
@@ -222,8 +224,6 @@ NOTE: if forward motion goes past the end of the cut then reverse motion cannot
2
- 1
- 211
@@ -463,7 +463,7 @@ NOTE: if forward motion goes past the end of the cut then reverse motion cannot
TrueFalse
- <b>Height Change</b>
+ <b>Height Override</b>True
diff --git a/configs/by_machine/plasmac/plasmac_control.py b/configs/by_machine/plasmac/plasmac_control.py
index c930982162..1851c8c25a 100644
--- a/configs/by_machine/plasmac/plasmac_control.py
+++ b/configs/by_machine/plasmac/plasmac_control.py
@@ -29,10 +29,6 @@
class HandlerClass:
- def configure_widgets(self):
- if int(linuxcnc.version.split('.')[0] + linuxcnc.version.split('.')[1]) < 29:
- self.builder.get_object('pausedmotion-frame').hide()
-
def periodic(self):
self.s.poll()
if self.feed_override != self.s.feedrate:
@@ -45,12 +41,12 @@ def periodic(self):
self.builder.get_object('torch-pulse-start').set_sensitive(True)
else:
self.builder.get_object('torch-pulse-start').set_sensitive(False)
- if hal.get_value('halui.program.is-paused') or hal.get_value('plasmac.paused-motion-speed'):
- self.builder.get_object('forward').set_sensitive(True)
- self.builder.get_object('reverse').set_sensitive(True)
+ if (hal.get_value('halui.program.is-paused') or \
+ hal.get_value('plasmac.paused-motion-speed')) and \
+ not hal.get_value('plasmac.cut-recovery'):
+ self.builder.get_object('pausedmotion-frame').show()
else:
- self.builder.get_object('forward').set_sensitive(False)
- self.builder.get_object('reverse').set_sensitive(False)
+ self.builder.get_object('pausedmotion-frame').hide()
if hal.get_value('halui.machine.is-on'):
self.builder.get_object('height-frame').set_sensitive(True)
else:
@@ -155,7 +151,6 @@ def __init__(self, halcomp,builder,useropts):
self.maxFeed = int(float(self.i.find("DISPLAY", "MAX_FEED_OVERRIDE") or '1') * 100)
self.maxRapid = int(float(self.i.find("DISPLAY", "MAX_RAPID_OVERRIDE") or '1') * 100)
self.oldMode = 9
- self.configure_widgets()
self.feed_override = 0
self.rapid_override = 0
self.torch_height = 0
diff --git a/configs/by_machine/plasmac/plasmac_gcode.py b/configs/by_machine/plasmac/plasmac_gcode.py
index b09b7d3587..0637d52cd2 100755
--- a/configs/by_machine/plasmac/plasmac_gcode.py
+++ b/configs/by_machine/plasmac/plasmac_gcode.py
@@ -27,34 +27,48 @@
import gtk
import shutil
import time
+import hal
from subprocess import Popen, PIPE
ini = linuxcnc.ini(os.environ['INI_FILE_NAME'])
-
-codeError = False
-overCut = False
-holeActive = False
-holeEnable = False
-imperial = [25.4, 6]
-lastX = 0
-lastY = 0
+cmd = linuxcnc.command()
inCode = sys.argv[1]
materialFile = ini.find('EMC', 'MACHINE').lower() + '_material.cfg'
tmpMmaterialFile = ini.find('EMC', 'MACHINE').lower() + '_material.tmp'
runFile = materialFile.replace('material','run')
-metric = [1, 4]
-minDiameter = 32
-scale, precision = imperial if ini.find('TRAJ', 'LINEAR_UNITS').lower() == 'inch' else metric
+cutType = int(Popen('halcmd getp plasmac_run.cut-type', stdout = PIPE, shell = True).communicate()[0])
+currentMat = int(Popen('halcmd getp plasmac_run.material-change-number', stdout = PIPE, shell = True).communicate()[0])
+metric = ['mm', 4]
+imperial = ['in', 6]
+units, precision = imperial if ini.find('TRAJ', 'LINEAR_UNITS').lower() == 'inch' else metric
+if units == 'mm':
+ minDiameter = 32
+ ocLength = 4
+else:
+ minDiameter = 1.26
+ ocLength = 0.157
+newMaterial = []
+line = ''
+rapidLine = ''
+lastX = 0
+lastY = 0
+lineNum = 0
+holeVelocity = 60
+material = [0, False]
+codeError = False
+codeWarn = False
+overCut = False
+holeActive = False
+holeEnable = False
+arcEnable = False
+customDia = False
+customLen = False
torchEnable = True
-velocity = 60
pierceOnly = False
scribing = False
-rapidLine = ''
-thisMaterial = 0
offsetG41 = False
-cutType = int(Popen('halcmd getp plasmac_run.cut-type', stdout = PIPE, shell = True).communicate()[0])
feedWarning = False
-#pauseAtEnd = 2
+
# error dialog
def dialog_error(mode, title, error):
md = gtk.MessageDialog(None,
@@ -68,40 +82,104 @@ def dialog_error(mode, title, error):
md.run()
md.destroy()
+# set hole type
+def set_hole_type():
+ global holeType, holeEnable, overCut, arcEnable, lineNum
+ holeType = line.split('=')[1][0]
+ if holeType == '1':
+ holeEnable = True
+ overCut = False
+ arcEnable = False
+ print('(velocity reduction for small holes)')
+ elif holeType == '2':
+ holeEnable = overCut = True
+ arcEnable = False
+ print('(velocity reduction for small holes)')
+ lineNum += 1
+ print('(overcut for small holes)')
+ elif holeType == '3':
+ holeEnable = arcEnable = True
+ overCut = False
+ print('(velocity reduction for small holes and arcs)')
+ elif holeType == '4':
+ holeEnable = arcEnable = overCut = True
+ print('(velocity reduction for small holes and arcs)')
+ lineNum += 1
+ print('(overcut for small holes)')
+ else:
+ holeEnable = arcEnable = overCut = False
+ print('(disable small hole sensing)')
+
# check if arc is a hole
def check_if_hole():
- global lastX, lastY
- endX = lastX
- endY = lastY
- if 'x' in line: endX = get_position('x')
- if 'y' in line: endY = get_position('y')
+ global lastX, lastY, minDiameter, lineNum
+ endX = get_position('x') if 'x' in line else lastX
+ endY = get_position('y') if 'y' in line else lastY
+ I = J = isHole = 0
+ if 'i' in line: I = get_position('i')
+ if 'j' in line: J = get_position('j')
if lastX == endX and lastY == endY:
- I = J = 0
- if 'i' in line: I = get_position('i')
- if 'j' in line: J = get_position('j')
- radius = get_hole_radius(I, J)
- print(line)
- if overCut and radius <= (minDiameter / 2 / scale):
- overburn(I, J, radius)
+ isHole = True
+ radius = get_hole_radius(I, J, isHole)
+ print(line)
+ if isHole and overCut and radius <= (minDiameter / 2):
+ overburn(I, J, radius)
+ return
else:
- print(line)
lastX = endX
lastY = endY
+# get hole radius and set velocity percentage
+def get_hole_radius(I, J, isHole):
+ global holeActive, lineNum
+ if offsetG41:
+ radius = math.sqrt((I ** 2) + (J ** 2))
+ else:
+ #radius = math.sqrt((I ** 2) + (J ** 2)) + (materialDict[material[0]][1] / 2)
+ radius = math.sqrt((I ** 2) + (J ** 2))
+ # velocity reduction required
+ if radius <= (minDiameter / 2) and (isHole or arcEnable):
+ if offsetG41:
+ lineNum += 1
+ codeWarn = True
+ print(';m67 e3 q0 (inactive due to g41)')
+ wng = '\nCannot reduce velocity\n'
+ wng += 'with cutter compensation active.\n'
+ wng += '\nWarning for line #{}\n'.format(lineNum)
+ dialog_error(gtk.MESSAGE_WARNING,'WARNING', wng)
+ elif not holeActive:
+ lineNum += 1
+ print('m67 e3 q{0} (diameter:{1:0.3f}, velocity:{0}%)'.format(holeVelocity, radius * 2))
+ holeActive = True
+ if line.startswith('g2') and isHole:
+ codeWarn = True
+ wng = '\nThis cut appears to be a hole.\n'
+ wng += 'Did you mean to cut clockwise?\n'
+ wng += '\nWarning for line {}\n'.format(lineNum)
+ dialog_error(gtk.MESSAGE_WARNING,'WARNING', wng)
+ # no velocity reduction required
+ else:
+ if holeActive:
+ lineNum += 1
+ print('m67 e3 q0 (arc complete, velocity 100%)')
+ holeActive = False
+ return radius
+
# turn torch off and move 4mm (0.157) past hole end
def overburn(I, J, radius):
- global lastX, lastY, torchEnable, lineNum
+ global lastX, lastY, torchEnable, ocLength, lineNum
centerX = lastX + I
centerY = lastY + J
- cosA = math.cos(oclength / radius)
- sinA = math.sin(oclength / radius)
+ cosA = math.cos(ocLength / radius)
+ sinA = math.sin(ocLength / radius)
cosB = ((lastX - centerX) / radius)
sinB = ((lastY - centerY) / radius)
lineNum += 1
if offsetG41:
- print(';;; m62 p3 (((inactive due to g41)))')
- wng = 'Cannot enable/disable torch\n'
- wng += 'With cutter compensation active\n'
+ codeWarn = True
+ print(';m62 p3 (inactive due to g41)')
+ wng = '\nCannot enable/disable torch\n'
+ wng += 'with cutter compensation active.\n'
wng += '\nWarning for line #{}\n'.format(lineNum)
dialog_error(gtk.MESSAGE_WARNING,'WARNING', wng)
else:
@@ -122,38 +200,6 @@ def overburn(I, J, radius):
lastX = endX
lastY = endY
-# get hole radius and set velocity percentage
-def get_hole_radius(I, J):
- global holeActive, lineNum
- if offsetG41:
- radius = math.sqrt((I ** 2) + (J ** 2))
- else:
- radius = math.sqrt((I ** 2) + (J ** 2)) + (materialDict[thisMaterial][1] / 2)
- # velocity reduction required
- if radius <= (minDiameter / 2 / scale):
- if offsetG41:
- print(';;; m67 e3 q0 (((inactive due to g41)))')
- lineNum += 1
- wng = 'Cannot reduce velocity\n'
- wng += 'With cutter compensation active\n'
- wng += '\nWarning for line #{}\n'.format(lineNum)
- dialog_error(gtk.MESSAGE_WARNING,'WARNING', wng)
- else:
- print('m67 e3 q{0} (diameter:{1:0.3f}, velocity:{0}%)'.format(velocity, radius * 2))
- lineNum += 1
- if line.startswith('g2'):
- wng = 'This cut appears to be a hole\n'
- wng += 'Did you mean to cut clockwise?\n'
- wng += '\nWarning for line {}\n'.format(lineNum)
- dialog_error(gtk.MESSAGE_WARNING,'WARNING', wng)
- holeActive = True
- # no velocity reduction required
- else:
- if holeActive:
- print('m67 e3 q0 (arc complete, velocity 100%)')
- holeActive = False
- return radius
-
# get axis position
def get_position(axis):
tmp1 = line.split(axis)[1].replace(' ','')
@@ -171,11 +217,9 @@ def get_position(axis):
break
return float(tmp2)
-# get the last X and Y positions
-def get_last_position(Xpos, Ypos):
- if line.startswith('g') or \
- line.startswith('x') or \
- line.startswith('y'):
+# set the last X and Y positions
+def set_last_position(Xpos, Ypos):
+ if line[0] in ['g','x','y']:
if 'x' in line:
if get_position('x') is not None:
Xpos = get_position('x')
@@ -213,9 +257,10 @@ def comment_out_z_commands():
else:
newline += bit
if holeActive:
+ lineNum += 1
print('m67 e3 q0 (arc complete, velocity 100%)')
holeActive = False
- print('{} {})'.format(newline, newz))
+ return '{} {})'.format(newline, newz)
# check if math used or explicit values
def check_math(axis):
@@ -223,45 +268,149 @@ def check_math(axis):
tmp1 = line.split(axis)[1]
if tmp1.startswith('[') or tmp1.startswith('#'):
codeError = True
- wng = 'PlasmaC GCode parser\n'
- wng += 'requires explicit values\n'
+ wng = '\nPlasmaC GCode parser\n'
+ wng += 'requires explicit values.\n'
wng += '\nError near line #{}\n'.format(lineNum)
wng += '\nDisable hole sensing\n'
- wng += 'or edit GCode file to suit\n'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
+ wng += 'or edit GCode file to suit.\n'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+
+# do material change
+def do_material_change():
+ if '(' in line:
+ c = line.split('(', 1)[0]
+ elif ';' in line:
+ c = line.split(';', 1)[0]
+ else:
+ c = line
+ a, b = c.split('p', 1)
+ m = ''
+ # get the material number
+ for mNum in b.strip():
+ if mNum in '0123456789':
+ m += mNum
+ material[0] = int(m)
+ material[1] = True
+ if material[0] not in materialDict:
+ codeError = True
+ wng = '\nMaterial {} is missing from:\n'.format(material[0])
+ wng += '{}\n'.format(materialFile)
+ wng += '\nError near line #{}\n'.format(lineNum)
+ wng += '\nAdd a new material\n'
+ wng += 'or edit GCode file to suit.'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ print(line)
+ quit()
+ Popen('halcmd setp plasmac_run.material-change-number {}'.format(material[0]), stdout = PIPE, shell = True)
+ print(line)
+
+# check if matarial edit required
+def check_material_edit():
+ newMaterial = []
+ th = 0
+ kw = jh = jd = ca = cv = pe = gp = cm = 0.0
+ # try:
+ if 'ph=' in line and 'pd=' in line and 'ch=' in line and 'fr=' in line:
+ if '(o=0' in line:
+ nu = 0
+ na = 'Temporary'
+ newMaterial.append(0)
+ elif '(o=1' in line and 'nu=' in line and 'na=' in line:
+ newMaterial.append(1)
+ elif '(o=2' in line and 'nu=' in line and 'na=' in line:
+ newMaterial.append(2)
+ if newMaterial[0] in [0, 1, 2]:
+ for item in line.split('(')[1].split(')')[0].split(','):
+ # mandatory items
+ if 'nu=' in item:
+ nu = int(item.split('=')[1])
+ elif 'na=' in item:
+ na = item.split('=')[1].strip()
+ elif 'ph=' in item:
+ ph = float(item.split('=')[1])
+ elif 'pd=' in item:
+ pd = float(item.split('=')[1])
+ elif 'ch=' in item:
+ ch = float(item.split('=')[1])
+ elif 'fr=' in item:
+ fr = float(item.split('=')[1])
+ # optional items
+ elif 'kw=' in item:
+ kw = float(item.split('=')[1])
+ elif 'th=' in item:
+ th = int(item.split('=')[1])
+ elif 'jh=' in item:
+ jh = float(item.split('=')[1])
+ elif 'jd=' in item:
+ jd = float(item.split('=')[1])
+ elif 'ca=' in item:
+ ca = float(item.split('=')[1])
+ elif 'cv=' in item:
+ cv = float(item.split('=')[1])
+ elif 'pe=' in item:
+ pe = float(item.split('=')[1])
+ elif 'gp=' in item:
+ gp = float(item.split('=')[1])
+ elif 'cm=' in item:
+ cm = float(item.split('=')[1])
+ for i in [nu,na,kw,th,ph,pd,jh,jd,ch,fr,ca,cv,pe,gp,cm]:
+ newMaterial.append(i)
+ if newMaterial[0] == 0:
+ write_temp_default_material(newMaterial)
+ elif nu in materialDict and newMaterial[0] == 1:
+ wng = '\nCannot add new Material #{}\n'.format(nu)
+ wng += '\nMaterial number is in use\n'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ else:
+ rewrite_material_file(newMaterial)
+ else:
+ codeError = True
+ wng = '\nCannot add or edit material from G-Code file.\n'
+ wng += '\nInvalid parameter or value in:'
+ wng += '{}\n'.format(line)
+ wng += 'This material will not be processed'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ # except:
+ # codeError = True
+ # wng = '\nCannot add or edit material from G-Code file.\n'
+ # wng += '\nInvalid/missing parameter or value in:\n\n'
+ # wng += '{}\n'.format(line)
+ # wng += 'This material will not be processed'
+ # dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
# write temporary materials file
-def write_temp_material(data):
+def write_temp_default_material(data):
with open(tmpMmaterialFile, 'w') as fWrite:
fWrite.write('#plasmac temp default material file, format is:\n')
fWrite.write('#name = value\n\n')
- fWrite.write('kerf-width={}\n'.format(data[2]))
- fWrite.write('thc-enable={}\n'.format(data[3]))
- fWrite.write('pierce-height={}\n'.format(data[4]))
- fWrite.write('pierce-delay={}\n'.format(data[5]))
- fWrite.write('puddle-jump-height={}\n'.format(data[6]))
- fWrite.write('puddle-jump-delay={}\n'.format(data[7]))
- fWrite.write('cut-height={}\n'.format(data[8]))
- fWrite.write('cut-feed-rate={}\n'.format(data[9]))
- fWrite.write('cut-amps={}\n'.format(data[10]))
- fWrite.write('cut-volts={}\n'.format(data[11]))
- fWrite.write('pause-at-end={}\n'.format(data[12]))
- fWrite.write('gas-pressure={}\n'.format(data[13]))
- fWrite.write('cut-mode={}\n'.format(data[14]))
+ fWrite.write('kerf-width={}\n'.format(data[3]))
+ fWrite.write('thc-enable={}\n'.format(data[4]))
+ fWrite.write('pierce-height={}\n'.format(data[5]))
+ fWrite.write('pierce-delay={}\n'.format(data[6]))
+ fWrite.write('puddle-jump-height={}\n'.format(data[7]))
+ fWrite.write('puddle-jump-delay={}\n'.format(data[8]))
+ fWrite.write('cut-height={}\n'.format(data[9]))
+ fWrite.write('cut-feed-rate={}\n'.format(data[10]))
+ fWrite.write('cut-amps={}\n'.format(data[11]))
+ fWrite.write('cut-volts={}\n'.format(data[12]))
+ fWrite.write('pause-at-end={}\n'.format(data[13]))
+ fWrite.write('gas-pressure={}\n'.format(data[14]))
+ fWrite.write('cut-mode={}\n'.format(data[15]))
fWrite.write('\n')
Popen('halcmd setp plasmac_run.temp-material 1', stdout = PIPE, shell = True)
matDelay = time.time()
while 1:
if time.time() > matDelay + 3:
- wng = 'Temporary materials was not loaded in a timely manner:\n\n'
- wng += 'Try to reload the G-Code file.\n'
- dialog_error(gtk.MESSAGE_ERROR, 'MATERIAL ERROR', wng)
+ codeWarn = True
+ wng = '\nTemporary materials was not loaded in a timely manner:\n'
+ wng += '\nTry to reload the G-Code file.\n'
+ dialog_error(gtk.MESSAGE_WARNING, 'WARNING', wng)
break
if Popen('halcmd getp plasmac_run.temp-material', stdout = PIPE, shell = True).communicate()[0] == 'FALSE\n':
break
# rewrite the material file
-def rewrite_materials(newMats):
+def rewrite_material_file(newMaterial):
copyFile = '{}.bkp'.format(materialFile)
shutil.copy(materialFile, copyFile)
inFile = open(copyFile, 'r')
@@ -277,53 +426,53 @@ def rewrite_materials(newMats):
while 1:
if line.strip().startswith('[MATERIAL_NUMBER_'):
mNum = int(line.split('NUMBER_')[1].replace(']',''))
- if mNum in newMats:
- add_edit_material(mNum, newMats[mNum], outFile)
- if mNum not in newMats:
+ if mNum == newMaterial[1]:
+ add_edit_material(newMaterial, outFile)
+ if mNum != newMaterial[1]:
outFile.write(line)
line = inFile.readline()
if not line:
break
- for mat in sorted(newMats):
- if newMats[mat][0] == 1 or mat not in materialDict:
- add_edit_material(mat, newMats[mat], outFile)
+ if newMaterial[1] not in materialDict:
+ add_edit_material(newMaterial, outFile)
inFile.close()
outFile.close()
Popen('halcmd setp plasmac_run.material-reload 1', stdout = PIPE, shell = True)
- get_defaults()
get_materials()
matDelay = time.time()
while 1:
if time.time() > matDelay + 3:
- wng = 'Materials were not reloaded in a timely manner:\n\n'
- wng += 'Try a manual Reload or reload the G-Code file.\n'
- dialog_error(gtk.MESSAGE_ERROR, 'MATERIAL ERROR', wng)
+ codeWarn = True
+ wng = '\nMaterials were not reloaded in a timely manner:\n'
+ wng += '\nTry a manual Reload or reload the G-Code file.\n'
+ dialog_error(gtk.MESSAGE_WARNING, 'WARNING', wng)
break
if Popen('halcmd getp plasmac_run.material-reload', stdout = PIPE, shell = True).communicate()[0] == 'FALSE\n':
break
# add a new material or or edit an existing material
-def add_edit_material(num, data, outFile):
- outFile.write('[MATERIAL_NUMBER_{}]\n'.format(num))
- outFile.write('NAME = {}\n'.format(data[1]))
- outFile.write('KERF_WIDTH = {}\n'.format(data[2]))
- outFile.write('THC = {}\n'.format(data[3]))
- outFile.write('PIERCE_HEIGHT = {}\n'.format(data[4]))
- outFile.write('PIERCE_DELAY = {}\n'.format(data[5]))
- outFile.write('PUDDLE_JUMP_HEIGHT = {}\n'.format(data[6]))
- outFile.write('PUDDLE_JUMP_DELAY = {}\n'.format(data[7]))
- outFile.write('CUT_HEIGHT = {}\n'.format(data[8]))
- outFile.write('CUT_SPEED = {}\n'.format(data[9]))
- outFile.write('CUT_AMPS = {}\n'.format(data[10]))
- outFile.write('CUT_VOLTS = {}\n'.format(data[11]))
- outFile.write('PAUSE_AT_END = {}\n'.format(data[12]))
- outFile.write('GAS_PRESSURE = {}\n'.format(data[13]))
- outFile.write('CUT_MODE = {}\n'.format(data[14]))
+def add_edit_material(material, outFile):
+ outFile.write('[MATERIAL_NUMBER_{}]\n'.format(material[1]))
+ outFile.write('NAME = {}\n'.format(material[2]))
+ outFile.write('KERF_WIDTH = {}\n'.format(material[3]))
+ outFile.write('THC = {}\n'.format(material[4]))
+ outFile.write('PIERCE_HEIGHT = {}\n'.format(material[5]))
+ outFile.write('PIERCE_DELAY = {}\n'.format(material[6]))
+ outFile.write('PUDDLE_JUMP_HEIGHT = {}\n'.format(material[7]))
+ outFile.write('PUDDLE_JUMP_DELAY = {}\n'.format(material[8]))
+ outFile.write('CUT_HEIGHT = {}\n'.format(material[9]))
+ outFile.write('CUT_SPEED = {}\n'.format(material[10]))
+ outFile.write('CUT_AMPS = {}\n'.format(material[11]))
+ outFile.write('CUT_VOLTS = {}\n'.format(material[12]))
+ outFile.write('PAUSE_AT_END = {}\n'.format(material[13]))
+ outFile.write('GAS_PRESSURE = {}\n'.format(material[14]))
+ outFile.write('CUT_MODE = {}\n'.format(material[15]))
outFile.write('\n')
-#get the default feed rate and kerf width
-def get_defaults():
- global fRate, kWidth
+
+# create a dict of material numbers and kerf widths
+def get_materials():
+ global materialDict
with open(runFile, 'r') as rFile:
fRate = kWidth = 0.0
for line in rFile:
@@ -331,10 +480,6 @@ def get_defaults():
fRate = float(line.split('=')[1])
if line.startswith('kerf-width'):
kWidth = float(line.split('=')[1])
-
-# create a dict of material numbers and kerf widths
-def get_materials():
- global fRate, kWidth, materialDict
mNumber = 0
with open(materialFile, 'r') as mFile:
materialDict = {mNumber: [fRate, kWidth]}
@@ -358,103 +503,48 @@ def get_materials():
elif line.startswith('KERF_WIDTH'):
kWidth = float(line.split('=')[1].strip())
-# start processing
-get_defaults()
-get_materials()
-
-# first pass check for material file edits
-with open(inCode, 'r') as fRead:
- newMats = {}
- tmpDefault = []
- for line in fRead:
- # if end of program
- if line.lower().strip().startswith('m2') or line.lower().strip().startswith('m30'):
- break
- tmpDict = {}
- tmpList = []
- th = 0
- kw = jh = jd = ca = cv = pe = gp = cm = 0.0
- try:
- if 'ph=' in line and 'pd=' in line and 'ch=' in line and 'fr=' in line:
- if '(o=0' in line and not tmpDefault:
- nu = 0
- na = 'Temporary'
- tmpList.append(0)
- elif '(o=1' in line and 'nu=' in line and 'na=' in line:
- tmpList.append(1)
- elif '(o=2' in line and 'nu=' in line and 'na=' in line:
- tmpList.append(2)
- if tmpList[0] in [0, 1, 2]:
- for item in line.split('(')[1].split(')')[0].split(','):
- # mandatory items
- if 'nu=' in item:
- nu = int(item.split('=')[1])
- elif 'na=' in item:
- na = item.split('=')[1].strip()
- elif 'ph=' in item:
- ph = float(item.split('=')[1])
- elif 'pd=' in item:
- pd = float(item.split('=')[1])
- elif 'ch=' in item:
- ch = float(item.split('=')[1])
- elif 'fr=' in item:
- fr = float(item.split('=')[1])
- # optional items
- elif 'kw=' in item:
- kw = float(item.split('=')[1])
- elif 'th=' in item:
- th = int(item.split('=')[1])
- elif 'jh=' in item:
- jh = float(item.split('=')[1])
- elif 'jd=' in item:
- jd = float(item.split('=')[1])
- elif 'ca=' in item:
- ca = float(item.split('=')[1])
- elif 'cv=' in item:
- cv = float(item.split('=')[1])
- elif 'pe=' in item:
- pe = float(item.split('=')[1])
- elif 'gp=' in item:
- gp = float(item.split('=')[1])
- elif 'cm=' in item:
- cm = float(item.split('=')[1])
- for i in [na,kw,th,ph,pd,jh,jd,ch,fr,ca,cv,pe,gp,cm]:
- tmpList.append(i)
- if tmpList[0] == 0:
- tmpDefault = tmpList
- elif nu in materialDict and tmpList[0] == 1:
- wng = 'Cannot add new Material #{}\n\n'.format(nu)
- wng += 'Material number is in use\n'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE MATERIALS ERROR', wng)
- else:
- newMats[nu] = tmpList
+def check_f_word(inFeed):
+ if not material[1]:
+ material[0] = currentMat
+ global feedWarning
+ rawFeed = ''
+ codeFeed = 0.0
+ while len(inFeed) and (inFeed[0].isdigit() or inFeed[0] == '.'):
+ rawFeed = rawFeed + inFeed[0]
+ inFeed = inFeed[1:].lstrip()
+ if rawFeed:
+ codeFeed = float(rawFeed)
+ if codeFeed != float(materialDict[material[0]][0]):
+ cutFeed = materialDict[material[0]][0]
+ dec = 0 if units == 'mm' else 1
+ if not feedWarning:
+ if cutFeed and cutFeed != codeFeed:
+ wng = '\nGcode feed rate is F{:0.{}f}\n'.format(codeFeed, dec)
+ wng += '\nMaterial #{} feed rate is F{:0.{}f}\n'.format(material[0], cutFeed, dec)
+ wng += '\nTHC calculations will be based on the\n'
+ wng += 'material #{} feed rate which may cause issues.\n'.format(material[0])
else:
- wng = 'Cannot add or edit material from G-Code file.\n\n'
- wng += 'Invalid parameter or value in:'
- wng += '{}\n'.format(line)
- wng += 'This material will not be processed'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE MATERIALS ERROR', wng)
- except:
- wng = 'Cannot add or edit material from G-Code file.\n\n'
- wng += 'Invalid/missing parameter or value in:\n\n'
- wng += '{}\n'.format(line)
- wng += 'This material will not be processed'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE MATERIALS ERROR', wng)
- if newMats:
- rewrite_materials(newMats)
- if tmpDefault:
- write_temp_material(tmpDefault)
+ wng = '\nGcode feed rate is F{:0.{}f}\n'.format(codeFeed, dec)
+ wng += '\nMaterial #{} feed rate is F{:0.{}f}\n'.format(material[0], cutFeed, dec)
+ wng += '\nThis will cause the THC calculations\n'
+ wng += 'to use the motion.requested-vel HAL pin\n'
+ wng += 'which is not recommended.\n'
+ wng += '\nThe recommended settings are to use\n'
+ wng += 'F#<_hal[plasmac.cut-feed-rate]>\n'
+ wng += 'in the G-Code file and a valid cut feed rate\n'
+ wng += 'in the material cut parameters.\n'
+ wng += '\nFirst warning near line #{}\n'.format(lineNum)
+ wng += '\nPlease check all feed rates.\n'.format(material[0])
+ dialog_error(gtk.MESSAGE_WARNING, 'WARNING', wng)
+ feedWarning = True
-# second pass, check for valid material numbers and distance modes
-with open(inCode, 'r')as fRead:
- lineNum = 0
- material = 0
- firstMaterial = False
- oclength = 4
+# start processing the gcode file
+get_materials()
+with open(inCode, 'r') as fRead:
for line in fRead:
lineNum += 1
- # convert to lower case and remove whitespace and spaces
- line = line.lower().strip().replace(' ','')
+ # remove whitespace
+ line = line.strip()
# remove line numbers
if line.lower().startswith('n'):
line = line[1:]
@@ -462,289 +552,200 @@ def get_materials():
line = line[1:].lstrip()
if not line:
break
- # if line is a comment get next line
+ # check for a material edit
+ if line.startswith('(o='):
+ check_material_edit()
+ continue
+ # if line is a comment then print it and get next line
if line.startswith(';') or line.startswith('('):
+ print(line)
continue
- # if end of program
- if line.startswith('m2') or line.startswith('m30'):
- break
- # get overcut length
- if line.startswith('#'):
- oclength = float(line.split('=')[1])
- # get cut type
- elif (line.startswith('#') and line.split('=')[1][0] == '1') or cutType == 1:
- pierceOnly = True
- # are we scribing
- elif line.startswith('m3$1s'):
- scribing = True
- # cannot scribe and pierce together
- elif pierceOnly and scribing:
- codeError = True
- wng = 'scribe is invalid for pierce only mode\n'
- wng += '\nError near line #{}\n'.format(lineNum)
- wng += '\nEdit GCode file to suit'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
- scribing = False
- # if material change
- elif line.startswith('m190'):
- if '(' in line:
- c = line.split('(', 1)[0]
- elif ';' in line:
- c = line.split(';', 1)[0]
- else:
- c = line
- a, b = c.split('p', 1)
- m = ''
- # get the material number
- for mNum in b.strip():
- if mNum in '0123456789':
- m += mNum
- material = int(m)
- if material not in materialDict:
- codeError = True
- wng = 'Material {} is missing from:\n'.format(material)
- wng += '{}\n'.format(materialFile)
- wng += '\nError near line #{}\n'.format(lineNum)
- wng += '\nAdd a new material\n'
- wng += 'or edit GCode file to suit'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
- if not firstMaterial:
- firstMaterial = True
- Popen('halcmd setp plasmac_run.first-material {}'.format(material), stdout = PIPE, shell = True)
- # set units
- elif 'g21' in line:
- scale, precision = metric
- elif 'g20' in line:
- scale, precision = imperial
+ # if a ; comment at end of line, convert line to lower case and remove spaces, preserve comment as is
+ elif ';' in line:
+ a,b = line.split(';', 1)
+ line = '{} ({})'.format(a.strip().lower().replace(' ',''),b)
+ # if a () comment at end of line, convert line to lower case and remove spaces, preserve comment as is
+ elif '(' in line:
+ a,b = line.split('(', 1)
+ line = '{} ({}'.format(a.strip().lower().replace(' ',''),b)
+ # if any other line, convert line to lower case and remove spaces
+ else:
+ line = line.lower().replace(' ','')
+ # remove leading 0's from G & M codes
+ if (line.lower().startswith('g') or \
+ line.lower().startswith('m')) and \
+ len(line) > 2:
+ while line[1] == '0':
+ if line[2].isdigit():
+ line = line[:1] + line[2:]
+ else:
+ break
+ # set default units
+ if 'g21' in line and units == 'in':
+ if not customDia:
+ minDiameter = 32
+ if not customLen:
+ ocLength = 4
+ elif 'g20' in line and units == 'mm':
+ if not customDia:
+ minDiameter = 1.26
+ if not customLen:
+ ocLength = 0.157
# check for g41 offset set
- elif 'g41' in line:
+ if 'g41' in line:
offsetG41 = True
# check for g41 offset cleared
elif 'g40' in line:
offsetG41 = False
+ # are we scribing
+ if line.startswith('m3$1s'):
+ if pierceOnly:
+ codeWarn = True
+ wng = '\nScribe is invalid for pierce only mode.\n'
+ wng += '\nError near line #{}\n'.format(lineNum)
+ wng += '\nEdit GCode file to suit.'
+ dialog_error(gtk.MESSAGE_WARNING, 'WARNING', wng)
+ scribing = False
+ else:
+ scribing = True
+ print(line)
+ continue
+ # if pierce only mode
+ if pierceOnly:
+ if line.startswith('g0'):
+ rapidLine = line
+ continue
+ if line.startswith('m3') and not line.startswith('m3$1'):
+ pierces += 1
+ print('\n(Pierce #{})'.format(pierces))
+ print(rapidLine)
+ print('M3 $0 S1')
+ print('G91')
+ print('G1 X.000001')
+ print('G90\nM5 $0')
+ rapidLine = ''
+ continue
+ if not pierces or line.startswith('o') or line.startswith('#'):
+ print(line)
+ continue
+ # test for pierce only mode
+ if (line.startswith('#') and line.split('=')[1][0] == '1') or (not pierceOnly and cutType == 1):
+ if scribing:
+ codeWarn = True
+ wng = '\nPierce only mode is invalid while scribing.\n'
+ wng += '\nError near line #{}\n'.format(lineNum)
+ wng += '\nEdit GCode file to suit.'
+ dialog_error(gtk.MESSAGE_WARNING, 'WARNING', wng)
+ else:
+ pierceOnly = True
+ pierces = 0
+ rapidLine = ''
+ print('(pierce only mode)')
+ if not cutType == 1:
+ continue
+ if line.startswith('#'):
+ ocLength = float(line.split('=')[1])
+ customLen = True
+ print('(overcut length = {})'.format(ocLength))
+ continue
# if hole sensing code
- elif line.startswith('#'):
- if line.split('=')[1][0] == '1':
- holeEnable = True
- elif line.split('=')[1][0] == '2':
- holeEnable = overCut = True
+ if line.startswith('#'):
+ set_hole_type()
+ continue
+ # if hole diameter command
+ if line.startswith('#') or line.startswith('#') or line.startswith('#'):
+ if (';') in line:
+ minDiameter = float(line.split('=')[1].split(';')[0])
+ customDia = True
+ elif ('(') in line:
+ minDiameter = float(line.split('=')[1].split('(')[0])
+ customDia = True
else:
- holeEnable = overCut = False
- # if unsupported distance mode
- elif holeEnable and 'g91' in line and not 'g91.1' in line:
+ minDiameter = float(line.split('=')[1])
+ customDia = True
+ print('(small hole diameter = {})'.format(minDiameter))
+ if '#'):
+ holeVelocity = float(line.split('=')[1].split(';')[0])
+ print('(small hole velocity = {})'.format(holeVelocity))
+ continue
+ # if material change
+ if line.startswith('m190'):
+ do_material_change()
+ if not 'm66' in line:
+ continue
+ # wait for material change
+ if 'm66' in line:
+ if offsetG41:
codeError = True
- wng = 'PlasmaC GCode parser only\n'
- wng += 'supports Distance Mode G90\n'
+ wng = '\nCannot validate a material change\n'
+ wng += 'with cutter compensation acive\n'
wng += '\nError near line #{}\n'.format(lineNum)
- wng += '\nEdit GCode file to suit'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
- # if unsupported arc distance mode
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ print(line)
+ continue
+ # check if unsupported distance mode
+ if holeEnable and 'g91' in line and not 'g91.1' in line:
+ codeError = True
+ wng = '\nPlasmaC GCode parser only\n'
+ wng += 'supports Distance Mode G90\n'
+ wng += '\nError near line #{}\n'.format(lineNum)
+ wng += '\nEdit GCode file to suit.'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ # check if unsupported arc distance mode
elif holeEnable and 'g90.1' in line:
codeError = True
- wng = 'PlasmaC GCode parser only\n'
+ wng = '\nPlasmaC GCode parser only\n'
wng += 'supports Arc Distance Mode G91.1\n'
wng += '\nError near line #{}\n'.format(lineNum)
- wng += '\nEdit GCode file to suit'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
- elif holeEnable and 'x' in line: check_math('x')
- elif holeEnable and 'y' in line: check_math('y')
- elif holeEnable and 'i' in line: check_math('i')
- elif holeEnable and 'j' in line: check_math('j')
- elif holeEnable and 'diameter>' in line:
- if not line.startswith('# for metric\n'
- wng += '# for imperial\n'
- wng += '\nEdit GCode file to suit'
- dialog_error(gtk.MESSAGE_ERROR, 'GCODE ERROR', wng)
- elif 'f' in line and material in materialDict:
- inFeed = line.split('f')[1].strip()
- rawFeed = ''
- codeFeed = 0.0
- while len(inFeed) and (inFeed[0].isdigit() or inFeed[0] == '.'):
- rawFeed = rawFeed + inFeed[0]
- inFeed = inFeed[1:].lstrip()
- if rawFeed:
- codeFeed = float(rawFeed)
- if codeFeed != float(materialDict[material][0]):
- cutFeed = materialDict[material][0]
- dec = 0 if scale == 1 else 1
-
-# FIX_ME if state tag ups pin released in master branch
- if linuxcnc.version.startswith('2.9.') or True:
- if not feedWarning:
- if cutFeed and cutFeed != codeFeed:
- wng = 'Gcode feed rate is F{:0.{}f}\n'.format(codeFeed, dec)
- wng += '\nMaterial #{} feed rate is F{:0.{}f}\n'.format(material, cutFeed, dec)
- wng += '\nTHC calculations will be based on the\n'
- wng += 'material #{} feed rate which may cause issues.\n'.format(material)
- else:
- wng = 'Gcode feed rate is F{:0.{}f}\n'.format(codeFeed, dec)
- wng += '\nMaterial #{} feed rate is F{:0.{}f}\n'.format(material, cutFeed, dec)
- wng += '\nThis will cause the THC calculations\n'
- wng += 'to use the motion.requested-vel HAL pin\n'
- wng += 'which is not recommended.\n'
- wng += '\nThe recommended settings are to use\n'
- wng += 'F#<_hal[plasmac.cut-feed-rate]>\n'
- wng += 'in the G-Code file and a valid cut feed rate\n'
- wng += 'in the material cut parameters.\n'
- wng += '\nFirst warning near line #{}\n'.format(lineNum)
- wng += '\nPlease check all feed rates.\n'.format(material)
- dialog_error(gtk.MESSAGE_WARNING, 'Feed Rate WARNING', wng)
- feedWarning = True
- else:
- pass
-
-# third pass, process every line
-# if full cut
-if not pierceOnly:
- with open(inCode, 'r') as fRead:
- if codeError:
- lineNum = 1
- print ('M2 (End due to GCode error)')
- else:
- lineNum = 0
- offsetG41 = False
- for line in fRead:
- lineNum += 1
- # remove whitespace
- line = line.strip()
- # remove line numbers
- if line.lower().startswith('n'):
- line = line[1:]
- while line[0].isdigit() or line[0] == '.':
- line = line[1:].lstrip()
- if not line:
- break
- # remove leading 0's from G & M codes
- if (line.lower().startswith('g') or \
- line.lower().startswith('m')) and \
- len(line) > 2:
- while line[1] == '0':
- if line[2].isdigit():
- line = line[:1] + line[2:]
- else:
- break
- # if a material edit line throw it away
- if 'o=' in line and 'nu=' in line and 'na=' in line and 'ph=' in line and \
- 'pd=' in line and 'ch=' in line and 'fr=' in line:
- continue
- # if a commented line then print it and get next line
- if line.startswith(';') or line.startswith('('):
- print line
- continue
- # if a ; comment at end of line preprocess it
- elif ';' in line:
- a,b = line.split(';', 1)
- line = '{} ({})'.format(a.strip().lower(),b)
- # if a () comment at end of line preprocess it
- elif '(' in line:
- a,b = line.split('(', 1)
- line = '{} ({}'.format(a.strip().lower(),b)
- # if any other line preprocess it
- else:
- line = line.lower()
- # if material change
- if line.startswith('m190'):
- if '(' in line:
- a, b = line.split('p', 1)
- b, c = b.split('(', 1)
- else:
- a, b = line.split('p', 1)
- m = ''
- # get the material number
- for mNum in b.strip():
- if mNum in '0123456789':
- m += mNum
- material = int(m)
- thisMaterial = material
- print('; material = {}'.format(material))
- print(';thisMaterial = {}'.format(thisMaterial))
- print(line)
- # if material change with cutter compensation
- elif 'm66' in line and offsetG41:
- wng = 'Cannot complete a material change\n'
- wng += 'with cutter compensation acive\n'
- wng += '\nError near line #{}\n'.format(lineNum)
+ wng += '\nEdit GCode file to suit.'
dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
- print ';;; {} (((inactive due to g41)))'.format(line.strip())
- # check for g41 offset set
- elif 'g41' in line:
- offsetG41 = True
- print(line)
- # check for g41 offset cleared
- elif 'g40' in line:
- offsetG41 = False
- print(line)
- # if hole sense command
- elif line.startswith('#'):
- if line.split('=')[1].replace(' ','')[0] == '2':
- holeEnable = overCut = True
- print('{} (overcut for holes)'.format('# = 2'))
- elif line.split('=')[1].replace(' ','')[0] == '1':
- holeEnable = True
- overCut = False
- print('{} (velocity reduction for holes)'.format('# = 1'))
- else:
- holeEnable = overCut = False
- print('{} (disable hole sensing)'.format('# = 0'))
- # if diameter command
- elif '_diameter>' in line:
- if line.startswith('# (end of cut pause)')
- # pauseAtEnd = 2
+ continue
+ # if torch off, flag it then print it
+ if line.startswith('m62p3') or line.startswith('m64p3'):
+ torchEnable = False
+ print(line)
+ continue
+ # if torch on, flag it then print it
+ if line.startswith('m63p3') or line.startswith('m65p3'):
+ torchEnable = True
+ print(line)
+ continue
+ # if spindle off
+ if line.startswith('m5'):
+ if len(line) == 2 or (len(line) > 2 and not line[2].isdigit()):
print(line)
# restore velocity if required
if holeActive:
@@ -756,84 +757,50 @@ def get_materials():
lineNum += 1
print('m65 p3 (enable torch)')
torchEnable = True
- # if program end
- elif line.startswith('m2') or line.startswith('m30') or line.startswith('%'):
- # restore velocity if required
- if holeActive:
- print('m68 e3 q0 (arc complete, velocity 100%)')
- holeActive = False
- lineNum += 1
- # if torch off, allow torch on
- if not torchEnable:
- print('m65 p3 (enable torch)')
- torchEnable = True
- lineNum += 1
- # restore hole sensing to default
- if holeEnable:
- print('# = 0 (disable hole sensing)')
- holeEnable = False
- lineNum += 1
- print(line)
- # any other line
else:
- if holeEnable:
- # restore velocity if required
- if holeActive:
- print('m67 e3 q0 (arc complete, velocity 100%)')
- holeActive = False
- lastX, lastY = get_last_position(lastX, lastY)
print(line)
-#if pierce only
-else:
- print('(Piercing Only)')
- spindleOn = False
- pierces = 0
- with open(inCode, 'r') as fRead:
- # print all lines up to the first spindle on
- for line in fRead:
- # remove whitespace
- line = line.strip()
- # remove line numbers
- if line.lower().startswith('n'):
- line = line[1:]
- while line[0].isdigit() or line[0] == '.':
- line = line[1:].lstrip()
- # if a rapid move
- if line.lower().startswith('g0'):
- rapidLine = line
- # if a spindle on
- elif line.lower().replace(' ','').startswith('m3') and not \
- line.lower().replace(' ','').startswith('m3$1'):
- spindleOn = True
- break
- elif not '#' in line:
- print(line)
- #find all other spindle ons
- for line in fRead:
- if spindleOn:
- pierces += 1
- print('\n(Pierce #{})'.format(pierces))
- print(rapidLine)
- print('M3 $0 S1')
- print('G91')
- print('G1 X.000001')
- print('G90\nM5')
- rapidLine = ''
- spindleOn = False
- # remove whitespace
- line = line.strip()
- # remove line numbers
- if line.lower().startswith('n'):
- line = line[1:]
- while line[0].isdigit() or line[0] == '.':
- line = line[1:].strip()
- # if a rapid move
- if line.lower().startswith('g0'):
- rapidLine = line
- # if a spindle on
- elif line.lower().replace(' ','').startswith('m3'):
- spindleOn = True
+ continue
+ # if program end
+ if line.startswith('m2') or line.startswith('m30') or line.startswith('%'):
+ # restore velocity if required
+ if holeActive:
+ lineNum += 1
+ print('m68 e3 q0 (arc complete, velocity 100%)')
+ holeActive = False
+ # if torch off, allow torch on
+ if not torchEnable:
+ lineNum += 1
+ print('m65 p3 (enable torch)')
+ torchEnable = True
+ # restore hole sensing to default
+ if holeEnable:
+ lineNum += 1
+ print('(disable hole sensing)')
+ holeEnable = False
+ print(line)
+ if codeError:
+ wng = '\nThis GCode file has one or more errors\n'
+ wng += 'that will affect the quality of the process.\n'
+ wng += '\nIt is recommended that all errors are fixed\n'
+ wng += 'before running this file.'
+ dialog_error(gtk.MESSAGE_ERROR, 'ERROR', wng)
+ continue
+ # check feed rate
+ if 'f' in line:
+ inFeed = line.split('f')[1]
+ if not inFeed.startswith('#<_hal[plasmac.cut-feed-rate]>'):
+ check_f_word(inFeed)
+ # restore velocity if required
+ if holeActive:
+ lineNum += 1
+ print('m67 e3 q0 (arc complete, velocity 100%)')
+ holeActive = False
+ # set last X/Y position
+ if holeEnable and len(line):
+ lastX, lastY = set_last_position(lastX, lastY)
+ print(line)
+if pierceOnly:
print('')
if rapidLine:
print('{}'.format(rapidLine))
- print('M30 (END)')
+ print('M2 (END)')
diff --git a/configs/by_machine/plasmac/plasmac_run.hal b/configs/by_machine/plasmac/plasmac_run.hal
index c9e42a56ac..14d29f6682 100644
--- a/configs/by_machine/plasmac/plasmac_run.hal
+++ b/configs/by_machine/plasmac/plasmac_run.hal
@@ -10,6 +10,8 @@ net plasmac:cut-feed-rate plasmac_run.cut-feed-rate-f => plas
net plasmac:cut-height plasmac_run.cut-height-f => plasmac.cut-height
net plasmac:cut-volts plasmac_run.cut-volts-f => plasmac.cut-volts
net plasmac:kerfcross-enable plasmac_run.kerfcross-enable => plasmac.kerfcross-enable
+net plasmac:mesh-enable plasmac_run.mesh-enable => plasmac.mesh-enable
+net plasmac:ignore-arc-ok-1 plasmac_run.ignore-arc-ok => plasmac.ignore-arc-ok-1
net plasmac:ohmic-probe-enable plasmac_run.ohmic-probe-enable => plasmac.ohmic-probe-enable
net plasmac:pause-at-end plasmac_run.pause-at-end-f => plasmac.pause-at-end
net plasmac:pierce-delay plasmac_run.pierce-delay-f => plasmac.pierce-delay
diff --git a/configs/by_machine/plasmac/plasmac_run.py b/configs/by_machine/plasmac/plasmac_run.py
index e86f60fbf9..260bf10d00 100644
--- a/configs/by_machine/plasmac/plasmac_run.py
+++ b/configs/by_machine/plasmac/plasmac_run.py
@@ -139,19 +139,38 @@ def get_material(self):
t_number = 0
t_name = 'Default'
self.materialName = t_name
- k_width = (self.builder.get_object('kerf-width').get_value())
- thc_enable = self.builder.get_object('thc-enable').get_active()
- p_height = self.builder.get_object('pierce-height').get_value()
- p_delay = self.builder.get_object('pierce-delay').get_value()
- pj_height = self.builder.get_object('puddle-jump-height').get_value()
- pj_delay = self.builder.get_object('puddle-jump-delay').get_value()
- c_height = self.builder.get_object('cut-height').get_value()
- c_speed = self.builder.get_object('cut-feed-rate').get_value()
- c_amps = self.builder.get_object('cut-amps').get_value()
- c_volts = self.builder.get_object('cut-volts').get_value()
- pause = self.builder.get_object('pause-at-end').get_value()
- g_press = self.builder.get_object('gas-pressure').get_value()
- c_mode = self.builder.get_object('cut-mode').get_value()
+ inDict = {'kerf-width':0.0,
+ 'thc-enable':False,
+ 'pierce-height':0.0,
+ 'pierce-delay':0.0,
+ 'puddle-jump-height':0.0,
+ 'puddle-jump-delay':0.0,
+ 'cut-height':0.0,
+ 'cut-feed-rate':0.0,
+ 'cut-amps':0.0,
+ 'cut-volts':0.0,
+ 'pause-at-end':0.0,
+ 'gas-pressure':0.0,
+ 'cut-mode':0.0,
+ }
+ with open(self.configFile) as inFile:
+ for line in inFile:
+ if '=' in line:
+ (key, val) = line.strip().split('=')
+ inDict[key] = val
+ k_width = float(inDict['kerf-width'])
+ thc_enable = True if inDict['thc-enable'] == 'True' else False
+ p_height = float(inDict['pierce-height'])
+ p_delay = float(inDict['pierce-delay'])
+ pj_height = float(inDict['puddle-jump-height'])
+ pj_delay = float(inDict['puddle-jump-delay'])
+ c_height = float(inDict['cut-height'])
+ c_speed = float(inDict['cut-feed-rate'])
+ c_amps = float(inDict['cut-amps'])
+ c_volts = float(inDict['cut-volts'])
+ pause = float(inDict['pause-at-end'])
+ g_press = float(inDict['gas-pressure'])
+ c_mode = float(inDict['cut-mode'])
t_item = 0
self.write_materials(t_number,t_name,k_width,thc_enable,p_height,p_delay,pj_height,pj_delay,c_height,c_speed,c_amps,c_volts,pause,g_press,c_mode,t_item)
with open(self.materialFile, 'r') as f_in:
@@ -237,29 +256,11 @@ def get_material(self):
self.builder.get_object('material').set_active(0)
self.getMaterialBusy = 0
- def on_save_clicked(self,widget,data=None):
- self.save_settings()
- active = int(self.builder.get_object('material').get_active_text().split(': ', 1)[0])
- self.materialFileDict[active][0] = self.materialName
- self.materialFileDict[active][1] = self.builder.get_object('kerf-width').get_value()
- self.materialFileDict[active][2] = self.builder.get_object('thc-enable').get_active()
- self.materialFileDict[active][3] = self.builder.get_object('pierce-height').get_value()
- self.materialFileDict[active][4] = self.builder.get_object('pierce-delay').get_value()
- self.materialFileDict[active][5] = self.builder.get_object('puddle-jump-height').get_value()
- self.materialFileDict[active][6] = self.builder.get_object('puddle-jump-delay').get_value()
- self.materialFileDict[active][7] = self.builder.get_object('cut-height').get_value()
- self.materialFileDict[active][8] = self.builder.get_object('cut-feed-rate').get_value()
- self.materialFileDict[active][9] = self.builder.get_object('cut-amps').get_value()
- self.materialFileDict[active][10] = self.builder.get_object('cut-volts').get_value()
- self.materialFileDict[active][11] = self.builder.get_object('pause-at-end').get_value()
- self.materialFileDict[active][12] = self.builder.get_object('gas-pressure').get_value()
- self.materialFileDict[active][13] = self.builder.get_object('cut-mode').get_value()
-
def on_reload_clicked(self,widget,data=None):
self.materialUpdate = True
material = self.builder.get_object('material').get_active()
if widget:
- self.load_settings()
+ self.load_config_file()
self.materialFileDict = {}
self.materialNumList = []
self.get_material()
@@ -358,7 +359,7 @@ def on_new_clicked(self, widget):
outFile.write('CUT_MODE = {}\n\n'.format(self.materialFileDict[active][13]))
outFile.close()
self.materialUpdate = True
- self.load_settings()
+ self.load_config_file()
self.materialFileDict = {}
self.materialNumList = []
self.get_material()
@@ -413,36 +414,12 @@ def on_delete_clicked(self, widget):
outFile.write(line)
outFile.close()
self.materialUpdate = True
- self.load_settings()
+ self.load_config_file()
self.materialFileDict = {}
self.materialNumList = []
self.get_material()
self.materialUpdate = False
- def on_thc_auto_toggled(self,button):
- if button.get_active():
- self.builder.get_object('thc-enable').set_sensitive(True)
- self.builder.get_object('thc-enable-label').set_text('THC Enable')
-
- def on_thc_on_toggled(self,button):
- if button.get_active():
- self.halcomp['thc-enable-out'] = 1
- self.builder.get_object('thc-enable').set_sensitive(False)
- self.builder.get_object('thc-enable-label').set_text('THC ENABLED')
-
- def on_thc_off_toggled(self,button):
- if button.get_active():
- self.halcomp['thc-enable-out'] = 0
-
- self.builder.get_object('thc-enable').set_sensitive(False)
- self.builder.get_object('thc-enable-label').set_text('THC DISABLED')
-
- def first_material_changed(self, halpin):
- material = halpin.get()
- if not self.material_exists(material):
- return
- self.builder.get_object('material').set_active(self.materialList.index(material))
-
def material_change_number_changed(self,halpin):
if self.getMaterialBusy:
return
@@ -522,6 +499,9 @@ def on_setupFeedRate_value_changed(self, widget):
self.builder.get_object('probe-feed-rate-adj').configure(self.builder.get_object('probe-feed-rate').get_value(),0,self.builder.get_object('setup-feed-rate').get_value(),1,0,0)
def on_single_cut_pressed(self, widget):
+ self.builder.get_object('single-cut').set_sensitive(False)
+ while gtk.events_pending():
+ gtk.main_iteration()
self.builder.get_object('x-single-cut').update()
self.builder.get_object('y-single-cut').update()
x = self.builder.get_object('x-single-cut').get_value()
@@ -530,15 +510,12 @@ def on_single_cut_pressed(self, widget):
self.s.poll()
if not self.s.estop and self.s.enabled and self.s.homed.count(1) == self.s.joints and self.s.interp_state == linuxcnc.INTERP_IDLE:
self.c.mode(linuxcnc.MODE_MDI)
- self.c.wait_complete()
self.c.mdi('M3 $0 S1')
self.c.mdi('G91')
self.c.mdi('G1 X{} Y{} F#<_hal[plasmac.cut-feed-rate]>'.format(x, y))
- self.c.wait_complete()
self.c.mdi('G90')
- self.c.mdi('M5')
- self.c.wait_complete()
- self.c.mdi('M30')
+ self.c.mdi('M5 $0')
+ self.c.mdi('M2')
else:
print('current mode prevents a single cut')
@@ -566,6 +543,8 @@ def configure_widgets(self):
self.builder.get_object('puddle-jump-delay-adj').configure(0,0,9,0.01,0,0)
self.builder.get_object('thc-enable').set_active(1)
self.builder.get_object('use-auto-volts').set_active(1)
+ self.builder.get_object('mesh-enable').set_active(0)
+ self.builder.get_object('ignore-arc-ok').set_active(0)
if self.i.find('TRAJ', 'LINEAR_UNITS').lower() == 'mm':
self.builder.get_object('kerf-width').set_digits(2)
self.builder.get_object('kerf-width-adj').configure(0.5,0,5,0.01,0,0)
@@ -616,9 +595,11 @@ def set_theme(self):
gtk.settings_get_default().set_property('gtk-font-name', font)
gtk.settings_get_default().set_property('gtk-theme-name', theme)
- def load_settings(self):
+ def load_config_file(self):
for item in widget_defaults(select_widgets(self.builder.get_objects(), hal_only=True,output_only = True)):
- self.configDict[item] = '0'
+ # we don't save mesh mode or ignore arc ok
+ if item not in ['mesh-enable', 'ignore-arc-ok']:
+ self.configDict[item] = '0'
self.configDict['thc-mode'] = '0'
convertFile = False
if os.path.exists(self.configFile):
@@ -649,6 +630,8 @@ def load_settings(self):
except:
self.dialog_error('Configuration Error', 'The plasmac configuration file, {} is invalid ***'.format(self.configFile))
print('*** plasmac configuration file, {} is invalid ***'.format(self.configFile))
+ self.builder.get_object('mesh-enable').set_active(0)
+ self.builder.get_object('ignore-arc-ok').set_active(0)
for item in self.configDict:
if item == 'material':
self.builder.get_object(item).set_active(0)
@@ -662,9 +645,9 @@ def load_settings(self):
self.builder.get_object(item).set_value(float(self.configDict.get(item)))
else:
if self.i.find('PLASMAC', 'PM_PORT'):
- print('*** {} missing from {}'.format(item,self.configFile))
- elif not item in ['gas-pressure', 'cut-mode']:
print('*** {} missing from {}'.format(item,self.configFile))
+ elif not item in ['gas-pressure', 'cut-mode']:
+ print('*** {} missing from {}'.format(item ,self.configFile))
elif isinstance(self.builder.get_object(item), gladevcp.hal_widgets.HAL_CheckButton):
if item in tmpDict:
# keep pmx485 alive if it was on when reload pressed
@@ -679,113 +662,215 @@ def load_settings(self):
print('*** {} missing from {}'.format(item,self.configFile))
if convertFile:
print('*** converting {} to new format'.format(self.configFile))
- self.save_settings()
+ self.new_config_file()
else:
- self.save_settings()
+ self.new_config_file()
print('*** creating new run tab configuration file, {}'.format(self.configFile))
- def save_settings(self):
+ def new_config_file(self):
+ try:
+ with open(self.configFile, 'w') as f_out:
+ f_out.write('#plasmac run tab/panel configuration file, format is:\n#name = value\n\n')
+ for key in sorted(self.configDict.iterkeys()):
+ if key == 'material-number' or key in ['mesh-mode', 'ignore-arc-ok']:
+ pass
+ elif isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_SpinButton):
+ self.builder.get_object(key).update()
+ value = self.builder.get_object(key).get_value()
+ f_out.write(key + '=' + str(value) + '\n')
+ elif isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_CheckButton):
+ value = self.builder.get_object(key).get_active()
+ f_out.write(key + '=' + str(value) + '\n')
+ elif key == 'thc-mode':
+ if self.builder.get_object('thc-auto').get_active():
+ f_out.write(key + '=thc-auto\n')
+ if self.builder.get_object('thc-on').get_active():
+ f_out.write(key + '=thc-on\n')
+ if self.builder.get_object('thc-off').get_active():
+ f_out.write(key + '=thc-off\n')
+ except:
+ self.dialog_error('Config File Error', 'Error opening {}'.format(self.configFile))
+ print('*** error opening {}'.format(self.configFile))
+
+ def on_save_clicked(self,widget,data=None):
material = hal.get_value('plasmac_run.material-change-number')
position = self.builder.get_object('material').get_active()
- if material == 0:
- try:
- with open(self.configFile, 'w') as f_out:
- f_out.write('#plasmac run tab/panel configuration file, format is:\n#name = value\n\n')
- for key in sorted(self.configDict.iterkeys()):
- if key == 'material-number': # or key == 'kerf-width':
- pass
- elif isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_SpinButton):
- self.builder.get_object(key).update()
- value = self.builder.get_object(key).get_value()
- f_out.write(key + '=' + str(value) + '\n')
- elif isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_CheckButton):
- value = self.builder.get_object(key).get_active()
- f_out.write(key + '=' + str(value) + '\n')
- elif key == 'torchPulseTime':
- value = self.builder.get_object(key).get_value()
- f_out.write(key + '=' + str(value) + '\n')
- elif key == 'thc-mode':
- if self.builder.get_object('thc-auto').get_active():
- f_out.write(key + '=thc-auto\n')
- if self.builder.get_object('thc-on').get_active():
- f_out.write(key + '=thc-on\n')
- if self.builder.get_object('thc-off').get_active():
- f_out.write(key + '=thc-off\n')
- except:
- self.dialog_error('Config File Error', 'Error opening {}'.format(self.configFile))
- print('*** error opening {}'.format(self.configFile))
- if material != 0:
- for key in sorted(self.configDict.iterkeys()):
+ sd = gtk.Dialog('SAVE',
+ self.W,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ ('Material', 3, 'Settings', 2, 'Both', 1, 'Cancel', 0))
+ sd.set_position(gtk.WIN_POS_MOUSE)
+ sd.set_keep_above(True)
+ label = gtk.Label('\nSelect the item to save\n')
+ sd.vbox.add(label)
+ label.show()
+ response = sd.run()
+ sd.destroy()
+ if not response:
+ return
+ elif response == 1:
+ self.save_defaults('settings', self.settingsWidgets)
+ if material == 0:
+ self.save_defaults('material', self.materialWidgets)
+ else:
+ self.save_material(material, position)
+ elif response == 2:
+ self.save_defaults('settings', self.settingsWidgets)
+ elif response == 3:
+ if material == 0:
+ self.save_defaults('material', self.materialWidgets)
+ else:
+ self.save_material(material, position)
+
+ def save_defaults(self, mode, widgets):
+ for key in sorted(self.configDict.iterkeys()):
+ if isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_SpinButton):
+ self.builder.get_object(key).update()
+ # try:
+ inDict = {}
+ with open(self.configFile) as inFile:
+ for line in inFile:
+ if '=' in line:
+ (key, val) = line.strip().split('=')
+ inDict[key] = val
+ outFile = open('{}'.format(self.configFile), 'w')
+ outFile.write('#plasmac run tab/panel configuration file, format is:\n')
+ outFile.write('#name = value\n\n')
+ for key in sorted(self.configDict.iterkeys()):
+ if key in widgets:
if isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_SpinButton):
self.builder.get_object(key).update()
- shutil.copy(self.materialFile,'{}.tmp'.format(self.materialFile))
- inFile = open('{}.tmp'.format(self.materialFile), 'r')
- outFile = open('{}'.format(self.materialFile), 'w')
- while 1:
- line = inFile.readline()
- if not line: break
- elif line.startswith('[MATERIAL_NUMBER_') and \
- material == int(line.strip().strip(']').split('[MATERIAL_NUMBER_')[1]):
- outFile.write(line)
- break
- else:
- outFile.write(line)
- while 1:
- line = inFile.readline()
- if not line: break
- elif line.startswith('[MATERIAL_NUMBER_'):
- outFile.write(line)
- break
- elif line.startswith('NAME'):
- outFile.write(line)
- elif line.startswith('KERF_WIDTH'):
- outFile.write('KERF_WIDTH = {}\n'.format(self.builder.get_object('kerf-width').get_value()))
- elif line.startswith('THC'):
- if self.builder.get_object('thc-enable').get_active():
- thc = 1
- else:
- thc = 0
- outFile.write('THC = {}\n'.format(thc))
- elif line.startswith('PIERCE_HEIGHT'):
- outFile.write('PIERCE_HEIGHT = {}\n'.format(self.builder.get_object('pierce-height').get_value()))
- elif line.startswith('PIERCE_DELAY'):
- outFile.write('PIERCE_DELAY = {}\n'.format(self.builder.get_object('pierce-delay').get_value()))
- elif line.startswith('PUDDLE_JUMP_HEIGHT'):
- outFile.write('PUDDLE_JUMP_HEIGHT = {}\n'.format(self.builder.get_object('puddle-jump-height').get_value()))
- elif line.startswith('PUDDLE_JUMP_DELAY'):
- outFile.write('PUDDLE_JUMP_DELAY = {}\n'.format(self.builder.get_object('puddle-jump-delay').get_value()))
- elif line.startswith('CUT_HEIGHT'):
- outFile.write('CUT_HEIGHT = {}\n'.format(self.builder.get_object('cut-height').get_value()))
- elif line.startswith('CUT_SPEED'):
- outFile.write('CUT_SPEED = {}\n'.format(self.builder.get_object('cut-feed-rate').get_value()))
- elif line.startswith('CUT_AMPS'):
- outFile.write('CUT_AMPS = {}\n'.format(self.builder.get_object('cut-amps').get_value()))
- elif line.startswith('CUT_VOLTS'):
- outFile.write('CUT_VOLTS = {}\n'.format(self.builder.get_object('cut-volts').get_value()))
- elif line.startswith('PAUSE_AT_END'):
- outFile.write('PAUSE_AT_END = {}\n'.format(self.builder.get_object('pause-at-end').get_value()))
- elif line.startswith('GAS_PRESSURE'):
- outFile.write('GAS_PRESSURE = {}\n'.format(self.builder.get_object('gas-pressure').get_value()))
- elif line.startswith('CUT_MODE'):
- outFile.write('CUT_MODE = {}\n'.format(self.builder.get_object('cut-mode').get_value()))
- else:
- outFile.write(line)
- while 1:
- line = inFile.readline()
- if not line: break
+ outFile.write('{}={}\n'.format(key, str(self.builder.get_object(key).get_value())))
+ elif isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_CheckButton):
+ outFile.write('{}={}\n'.format(key, str(self.builder.get_object(key).get_active())))
+ elif key == 'thc-mode':
+ if self.builder.get_object('thc-auto').get_active():
+ outFile.write('{}=thc-auto\n'.format(key))
+ if self.builder.get_object('thc-on').get_active():
+ outFile.write('{}=thc-on\n'.format(key))
+ if self.builder.get_object('thc-off').get_active():
+ outFile.write('{}=thc-off\n'.format(key))
+ elif key in inDict:
+ outFile.write('{}={}\n'.format(key, inDict[key]))
+# else:
+# print '*** cannot save unknown parameter:', key
+ outFile.close()
+ if mode == 'material':
+ self.set_saved_material()
+ # except:
+ # self.dialog_error('Config File Error', 'Error opening {}'.format(self.configFile))
+ # print('*** error opening {}'.format(self.configFile))
+
+ def save_material(self, material, position):
+ for key in sorted(self.configDict.iterkeys()):
+ if isinstance(self.builder.get_object(key), gladevcp.hal_widgets.HAL_SpinButton):
+ self.builder.get_object(key).update()
+ shutil.copy(self.materialFile,'{}.tmp'.format(self.materialFile))
+ inFile = open('{}.tmp'.format(self.materialFile), 'r')
+ outFile = open('{}'.format(self.materialFile), 'w')
+ while 1:
+ line = inFile.readline()
+ if not line: break
+ elif line.startswith('[MATERIAL_NUMBER_') and \
+ material == int(line.strip().strip(']').split('[MATERIAL_NUMBER_')[1]):
outFile.write(line)
- inFile.close()
- outFile.close()
- self.materialUpdate = True
- self.load_settings()
- self.materialFileDict = {}
- self.get_material()
- self.builder.get_object('material').set_active(position)
- self.materialUpdate = False
+ break
+ else:
+ outFile.write(line)
+ while 1:
+ line = inFile.readline()
+ if not line: break
+ elif line.startswith('[MATERIAL_NUMBER_'):
+ outFile.write(line)
+ break
+ elif line.startswith('NAME'):
+ outFile.write(line)
+ elif line.startswith('KERF_WIDTH'):
+ outFile.write('KERF_WIDTH = {}\n'.format(self.builder.get_object('kerf-width').get_value()))
+ elif line.startswith('THC'):
+ if self.builder.get_object('thc-enable').get_active():
+ thc = 1
+ else:
+ thc = 0
+ outFile.write('THC = {}\n'.format(thc))
+ elif line.startswith('PIERCE_HEIGHT'):
+ outFile.write('PIERCE_HEIGHT = {}\n'.format(self.builder.get_object('pierce-height').get_value()))
+ elif line.startswith('PIERCE_DELAY'):
+ outFile.write('PIERCE_DELAY = {}\n'.format(self.builder.get_object('pierce-delay').get_value()))
+ elif line.startswith('PUDDLE_JUMP_HEIGHT'):
+ outFile.write('PUDDLE_JUMP_HEIGHT = {}\n'.format(self.builder.get_object('puddle-jump-height').get_value()))
+ elif line.startswith('PUDDLE_JUMP_DELAY'):
+ outFile.write('PUDDLE_JUMP_DELAY = {}\n'.format(self.builder.get_object('puddle-jump-delay').get_value()))
+ elif line.startswith('CUT_HEIGHT'):
+ outFile.write('CUT_HEIGHT = {}\n'.format(self.builder.get_object('cut-height').get_value()))
+ elif line.startswith('CUT_SPEED'):
+ outFile.write('CUT_SPEED = {}\n'.format(self.builder.get_object('cut-feed-rate').get_value()))
+ elif line.startswith('CUT_AMPS'):
+ outFile.write('CUT_AMPS = {}\n'.format(self.builder.get_object('cut-amps').get_value()))
+ elif line.startswith('CUT_VOLTS'):
+ outFile.write('CUT_VOLTS = {}\n'.format(self.builder.get_object('cut-volts').get_value()))
+ elif line.startswith('PAUSE_AT_END'):
+ outFile.write('PAUSE_AT_END = {}\n'.format(self.builder.get_object('pause-at-end').get_value()))
+ elif line.startswith('GAS_PRESSURE'):
+ outFile.write('GAS_PRESSURE = {}\n'.format(self.builder.get_object('gas-pressure').get_value()))
+ elif line.startswith('CUT_MODE'):
+ outFile.write('CUT_MODE = {}\n'.format(self.builder.get_object('cut-mode').get_value()))
+ else:
+ outFile.write(line)
+ while 1:
+ line = inFile.readline()
+ if not line: break
+ outFile.write(line)
+ inFile.close()
+ outFile.close()
+ os.remove('{}.tmp'.format(self.materialFile))
+ self.materialUpdate = True
+ self.materialFileDict = {}
+ self.get_material()
+ self.builder.get_object('material').set_active(position)
+ self.materialUpdate = False
+ self.set_saved_material()
+
+ def set_saved_material(self):
+ active = int(self.builder.get_object('material').get_active_text().split(': ', 1)[0])
+ self.materialFileDict[active][0] = self.materialName
+ self.materialFileDict[active][1] = self.builder.get_object('kerf-width').get_value()
+ self.materialFileDict[active][2] = self.builder.get_object('thc-enable').get_active()
+ self.materialFileDict[active][3] = self.builder.get_object('pierce-height').get_value()
+ self.materialFileDict[active][4] = self.builder.get_object('pierce-delay').get_value()
+ self.materialFileDict[active][5] = self.builder.get_object('puddle-jump-height').get_value()
+ self.materialFileDict[active][6] = self.builder.get_object('puddle-jump-delay').get_value()
+ self.materialFileDict[active][7] = self.builder.get_object('cut-height').get_value()
+ self.materialFileDict[active][8] = self.builder.get_object('cut-feed-rate').get_value()
+ self.materialFileDict[active][9] = self.builder.get_object('cut-amps').get_value()
+ self.materialFileDict[active][10] = self.builder.get_object('cut-volts').get_value()
+ self.materialFileDict[active][11] = self.builder.get_object('pause-at-end').get_value()
+ self.materialFileDict[active][12] = self.builder.get_object('gas-pressure').get_value()
+ self.materialFileDict[active][13] = self.builder.get_object('cut-mode').get_value()
def periodic(self):
- if self.builder.get_object('thc-auto').get_active():
- self.halcomp['thc-enable-out'] = self.builder.get_object('thc-enable').get_active()
+ if self.builder.get_object('mesh-enable').get_active() or hal.get_value('plasmac:ignore-arc-ok-0') or hal.get_value('plasmac:ignore-arc-ok-1'):
+ self.halcomp['thc-enable-out'] = False
+ self.builder.get_object('thc-enable-label').set_text('THC DISABLED')
+ self.builder.get_object('thc-enable').set_sensitive(False)
+ else:
+ if self.builder.get_object('thc-auto').get_active():
+ self.builder.get_object('thc-enable').set_sensitive(True)
+ if self.builder.get_object('thc-enable').get_active():
+ self.halcomp['thc-enable-out'] = True
+ self.builder.get_object('thc-enable-label').set_text('THC ENABLED')
+ else:
+ self.halcomp['thc-enable-out'] = False
+ self.builder.get_object('thc-enable-label').set_text('THC DISABLED')
+ elif self.builder.get_object('thc-on').get_active():
+ self.halcomp['thc-enable-out'] = True
+ self.builder.get_object('thc-enable').set_sensitive(False)
+ self.builder.get_object('thc-enable-label').set_text('THC ENABLED')
+ elif self.builder.get_object('thc-off').get_active():
+ self.halcomp['thc-enable-out'] = False
+ self.builder.get_object('thc-enable').set_sensitive(False)
+ self.builder.get_object('thc-enable-label').set_text('THC DISABLED')
+
mode = hal.get_value('plasmac.mode')
if mode != self.oldMode:
if mode == 0:
@@ -894,6 +979,15 @@ def periodic(self):
if hal.get_value('pmx485.current_min') > 0 and hal.get_value('pmx485.current_max') > 0:
self.builder.get_object('cut-amps').set_range(hal.get_value('pmx485.current_min'), hal.get_value('pmx485.current_max'))
self.pmx485Connected = True
+ if hal.get_value('plasmac.mesh-enable') and not self.meshMode:
+ self.oldCutMode = self.builder.get_object('cut-mode').get_value()
+ self.builder.get_object('cut-mode').set_value(2)
+ self.builder.get_object('cut-mode').set_sensitive(False)
+ self.meshMode = True
+ elif not hal.get_value('plasmac.mesh-enable') and self.meshMode:
+ self.builder.get_object('cut-mode').set_value(self.oldCutMode)
+ self.builder.get_object('cut-mode').set_sensitive(True)
+ self.meshMode = False
else:
self.fault = '0000'
self.pmx485Started = False
@@ -923,6 +1017,8 @@ def pmx485_check(self):
self.builder.get_object('gas-pressure').connect('value-changed', self.pmx485_pressure_changed)
self.pressure = self.builder.get_object('gas-pressure').get_value()
self.connTimer = 0
+ self.meshMode = False
+ self.oldCutMode = 1
else:
self.builder.get_object('gas-pressure').hide()
self.builder.get_object('gas-pressure-label').hide()
@@ -1072,13 +1168,16 @@ def upgrade_check(self):
iniFile = os.environ['INI_FILE_NAME']
iniPath = os.path.dirname(iniFile)
try:
- basePath = os.path.realpath(os.path.dirname(os.readlink('{}/plasmac'.format(iniPath))))
+ basePath = os.path.realpath(os.path.dirname('{}/plasmac'.format(iniPath)))
except:
try:
- basePath = os.path.realpath(os.path.dirname(os.readlink('{}/M190'.format(iniPath))))
+ basePath = os.path.realpath(os.path.dirname(os.readlink('{}/plasmac'.format(iniPath))))
except:
- print('\nlink to plasmac source files cannot be found\n')
- sys.exit(0)
+ try:
+ basePath = os.path.realpath(os.path.dirname(os.readlink('{}/M190'.format(iniPath))))
+ except:
+ print('\nlink to plasmac source files cannot be found\n')
+ sys.exit(0)
cmd = '{}/configurator.py'.format(basePath)
os.execv(cmd,[cmd, 'upgrade', iniFile])
sys.exit(0)
@@ -1095,14 +1194,12 @@ def __init__(self, halcomp,builder,useropts):
self.materialNumberPin = hal_glib.GPin(halcomp.newpin('material-change-number', hal.HAL_S32, hal.HAL_IN))
self.materialChangePin = hal_glib.GPin(halcomp.newpin('material-change', hal.HAL_S32, hal.HAL_IN))
self.materialTimeoutPin = hal_glib.GPin(halcomp.newpin('material-change-timeout', hal.HAL_BIT, hal.HAL_IN))
- self.firstMaterialPin = hal_glib.GPin(halcomp.newpin('first-material', hal.HAL_S32, hal.HAL_IN))
self.materialReloadPin = hal_glib.GPin(halcomp.newpin('material-reload', hal.HAL_BIT, hal.HAL_IN))
self.tempMaterialPin = hal_glib.GPin(halcomp.newpin('temp-material', hal.HAL_BIT, hal.HAL_IN))
self.thcEnablePin = hal_glib.GPin(halcomp.newpin('thc-enable-out', hal.HAL_BIT, hal.HAL_OUT))
self.materialNumberPin.connect('value-changed', self.material_change_number_changed)
self.materialChangePin.connect('value-changed', self.material_change_changed)
self.materialTimeoutPin.connect('value-changed', self.material_change_timeout)
- self.firstMaterialPin.connect('value-changed', self.first_material_changed)
self.materialReloadPin.connect('value-changed', self.on_material_reload_pin)
self.tempMaterialPin.connect('value-changed', self.on_temp_material_pin)
self.idlePin = hal_glib.GPin(halcomp.newpin('program-is-idle', hal.HAL_BIT, hal.HAL_IN))
@@ -1125,8 +1222,20 @@ def __init__(self, halcomp,builder,useropts):
self.materialUpdate = False
self.autoChange = False
self.fault = '0000'
+ self.settingsWidgets = ['cornerlock-enable', 'kerfcross-enable', \
+ 'ohmic-probe-enable', 'powermax-enable', \
+ 'thc-mode', 'use-auto-volts', \
+ 'x-single-cut', 'y-single-cut', \
+ 'mesh-enable', 'ignore-arc-ok']
+ self.materialWidgets = ['cut-amps', 'cut-feed-rate',\
+ 'cut-height', 'cut-mode', \
+ 'cut-volts', 'gas-pressure', \
+ 'kerf-width', 'pause-at-end', \
+ 'pierce-delay', 'pierce-height', \
+ 'puddle-jump-delay', 'puddle-jump-height', \
+ 'thc-enable']
self.configure_widgets()
- self.load_settings()
+ self.load_config_file()
self.check_material_file()
self.get_material()
self.set_theme()
diff --git a/configs/by_machine/plasmac/plasmac_run_panel.glade b/configs/by_machine/plasmac/plasmac_run_panel.glade
index 6efdf814b2..acae276a95 100644
--- a/configs/by_machine/plasmac/plasmac_run_panel.glade
+++ b/configs/by_machine/plasmac/plasmac_run_panel.glade
@@ -704,7 +704,6 @@ set to 0 to disable
THC is disabledTruethc-auto
- True
@@ -721,7 +720,6 @@ set to 0 to disable
THC is enabled/disabled from the cut parametersTrueTrue
- True
@@ -738,7 +736,6 @@ set to 0 to disable
THC is enabledTruethc-auto
- True
@@ -1079,6 +1076,116 @@ turn off to use cut volts from parameters
3
+
+
+ True
+ False
+ 0
+ out
+
+
+ True
+ False
+
+
+ True
+ False
+ 5
+ 2
+ 2
+
+
+ True
+ False
+ True
+ enable expanded metal cutting by disabling THC and ignoring Arc-OK after motion starts
+ 0
+ 2
+ Mesh Mode
+
+
+ 1
+ 2
+
+
+
+
+
+ 20
+ True
+ True
+ False
+ True
+ enable expanded metal cutting by disabling THC and ignoring Arc-OK after motion starts
+ True
+
+
+
+
+
+
+
+ True
+ False
+ status of powermax communications
+ 0
+
+
+ 2
+ 3
+
+
+
+
+ True
+ False
+ True
+ Arc-OK is not required to start cutting motion
+ 1
+ 2
+ Ignore ArcOK
+
+
+ 3
+ 4
+
+
+
+
+
+ 20
+ True
+ True
+ False
+ True
+ Arc-OK is not required to start cutting motion
+ True
+
+
+ 4
+ 5
+
+
+
+
+
+
+
+
+
+ True
+ False
+ <b>Cutting Mode</b>
+ True
+
+
+
+
+ False
+ False
+ 4
+
+ True
@@ -1121,7 +1228,6 @@ turn off to use cut volts from parameters
FalseTrueenable/disable powermax communications
- TrueTrue
@@ -1156,7 +1262,7 @@ turn off to use cut volts from parameters
FalseFalse
- 4
+ 5
@@ -1167,7 +1273,7 @@ turn off to use cut volts from parameters
TrueTrue
- 5
+ 6
@@ -1261,7 +1367,7 @@ Note: this also saves current cut parameters as the default
FalseFalse
- 6
+ 7
diff --git a/configs/by_machine/plasmac/plasmac_run_tab.glade b/configs/by_machine/plasmac/plasmac_run_tab.glade
index b32eb6cd4a..de2ca5f6e2 100644
--- a/configs/by_machine/plasmac/plasmac_run_tab.glade
+++ b/configs/by_machine/plasmac/plasmac_run_tab.glade
@@ -825,7 +825,6 @@ Note: this also saves current cut parameters as the default
TrueTruethc-auto
- True
@@ -842,7 +841,6 @@ Note: this also saves current cut parameters as the default
THC is enabled/disabled from the cut parametersTrueTrue
- True
@@ -860,7 +858,6 @@ Note: this also saves current cut parameters as the default
TrueTruethc-auto
- True
@@ -1201,6 +1198,116 @@ turn off to use cut volts from parameters
2
+
+
+ True
+ False
+ 0
+ out
+
+
+ True
+ False
+
+
+ True
+ False
+ 5
+ 2
+ 2
+
+
+ True
+ False
+ True
+ enable expanded metal cutting by disabling THC and ignoring Arc-OK after motion starts
+ 0
+ 2
+ Mesh Mode
+
+
+ 1
+ 2
+
+
+
+
+
+ 20
+ True
+ True
+ False
+ True
+ enable expanded metal cutting by disabling THC and ignoring Arc-OK after motion starts
+ True
+
+
+
+
+
+
+
+ True
+ False
+ status of powermax communications
+ 0
+
+
+ 2
+ 3
+
+
+
+
+ True
+ False
+ True
+ Arc-OK is not required to start cutting motion
+ 1
+ 2
+ Ignore ArcOK
+
+
+ 3
+ 4
+
+
+
+
+
+ 20
+ True
+ True
+ False
+ True
+ Arc-OK is not required to start cutting motion
+ True
+
+
+ 4
+ 5
+
+
+
+
+
+
+
+
+
+ True
+ False
+ <b>Cutting Mode</b>
+ True
+
+
+
+
+ False
+ False
+ 3
+
+ True
@@ -1278,7 +1385,7 @@ turn off to use cut volts from parameters
FalseFalse
- 3
+ 4
@@ -1289,7 +1396,7 @@ turn off to use cut volts from parameters
TrueTrue
- 4
+ 5
diff --git a/configs/by_machine/plasmac/plasmac_wizards.glade b/configs/by_machine/plasmac/plasmac_wizards.glade
index 3e1e177f8e..988c4c30ae 100644
--- a/configs/by_machine/plasmac/plasmac_wizards.glade
+++ b/configs/by_machine/plasmac/plasmac_wizards.glade
@@ -5,288 +5,86 @@
False
-
+ TrueFalse
-
+ TrueFalse
-
+ TrueFalse
- 11
- 6
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- True
- Lines and Arcs
-
-
-
- 2
- 2
-
-
-
-
- True
- True
- True
- Circle
-
-
-
- 2
- 4
- 2
-
-
-
-
- True
- True
- True
- Triangle
-
-
-
- 4
- 6
- 2
-
-
-
-
- True
- True
- True
- Rectangle
-
-
-
- 2
- 2
- 4
-
-
-
-
- True
- True
- True
- Regular Polygon
-
-
-
- 2
- 4
- 2
- 4
-
-
-
-
- New
- True
- True
- True
- Begin new group
-
-
-
- 4
- 6
- 9
- 10
-
-
-
-
- Array
- True
- True
- True
- Create array from existing G-Code
-
-
-
- 2
- 4
- 9
- 10
-
-
-
-
- Settings
- True
- True
- True
- Global Settings
-
-
-
- 2
- 10
- 11
-
-
-
-
- True
- True
- True
- Bolt Circle
-
-
-
- 4
- 6
- 2
- 4
-
-
-
-
- True
- True
- True
- Slot
-
-
-
- 2
- 4
- 6
-
-
-
-
- True
- True
- True
- Star
-
-
-
- 2
- 4
- 4
- 6
-
-
-
-
- True
- True
- True
- Gusset
-
-
-
- 4
- 6
- 4
- 6
-
-
-
-
- Rotate
- True
- True
- True
- Rotate existing G-Code
-
-
-
- 2
- 9
- 10
-
-
-
-
+ True
- True
- True
- Sector
-
+ False
+ 5
+ 2
+ 2
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Conversational
+ True
+ True
+ True
+
+
+
- 2
- 6
- 8
+ True
+ True
+ 0False
- False
+ True0
-
+ TrueFalse
@@ -296,221 +94,213 @@
1
-
-
- False
- False
- 0
-
-
-
-
- True
- False
-
-
- True
- True
- 1
-
-
-
-
- True
- False
-
+ TrueFalse
- 10
- 4
- True
-
+ True
- True
- True
- user button 10
+ False
+ 5
+ 2
+ 2
+ 2
+ True
+
+
+ button 15
+ True
+ True
+ True
+ user button 15
configured from the ini file
-
-
-
-
- 2
- 2
-
-
-
-
- True
- True
- True
- user button 11
+
+
+
+
+ 1
+ 2
+
+
+
+
+ button 16
+ True
+ True
+ True
+ user button 16
configured from the ini file
-
-
-
-
- 2
- 2
- 4
-
-
-
-
- True
- True
- True
- user button 12
+
+
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+ button 17
+ True
+ True
+ True
+ user button 17
configured from the ini file
-
-
-
-
- 2
- 4
- 6
-
-
-
-
- True
- True
- True
- user button 13
+
+
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+ button 18
+ True
+ True
+ True
+ user button 18
configured from the ini file
-
-
-
-
- 2
- 6
- 8
-
-
-
-
- True
- True
- True
- user button 14
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ button 19
+ True
+ True
+ True
+ user button 19
configured from the ini file
-
-
-
-
- 2
- 8
- 10
-
-
-
-
- True
- True
- True
- user button 15
+
+
+
+
+ 1
+ 2
+ 4
+ 5
+
+
+
+
+ button 10
+ True
+ True
+ True
+ user button 10
configured from the ini file
-
-
-
-
- 2
- 4
- 2
-
-
-
-
- True
- True
- True
- user button 16
+
+
+
+
+
+
+ button 11
+ True
+ True
+ True
+ user button 11
configured from the ini file
-
-
-
-
- 2
- 4
- 2
- 4
-
-
-
-
- True
- True
- True
- user button 17
+
+
+
+
+ 1
+ 2
+
+
+
+
+ button 12
+ True
+ True
+ True
+ user button 12
configured from the ini file
-
-
-
-
- 2
- 4
- 4
- 6
-
-
-
-
- True
- True
- True
- user button 18
+
+
+
+
+ 2
+ 3
+
+
+
+
+ button 13
+ True
+ True
+ True
+ user button 13
configured from the ini file
-
-
-
-
- 2
- 4
- 6
- 8
-
-
-
-
- True
- True
- True
- user button 19
+
+
+
+
+ 3
+ 4
+
+
+
+
+ button 14
+ True
+ True
+ True
+ user button 14
configured from the ini file
-
-
+
+
+
+
+ 4
+ 5
+
+
- 2
- 4
- 8
- 10
+ True
+ True
+ 0False
- False
- 0
-
-
-
-
- True
- False
-
-
- TrueTrue
- 1
+ 2False
+ False
+ 0
+
+
+
+
+ True
+ False
+
+
+ TrueTrue
- 2
+ 1
diff --git a/configs/by_machine/plasmac/plasmac_wizards.py b/configs/by_machine/plasmac/plasmac_wizards.py
index 42b78bbaff..f4dce18bd8 100644
--- a/configs/by_machine/plasmac/plasmac_wizards.py
+++ b/configs/by_machine/plasmac/plasmac_wizards.py
@@ -3,7 +3,7 @@
'''
plasmac_wizards.py
-Copyright (C) 2019 Phillip A Carter
+Copyright (C) 2019, 2020 Phillip A Carter
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -31,19 +31,8 @@
from subprocess import Popen, PIPE
sys.path.append('./wizards')
-import w_settings
-import w_array
-import w_line
-import w_circle
-import w_triangle
-import w_rectangle
-import w_polygon
-import w_bolt_circle
-import w_slot
-import w_star
-import w_gusset
-import w_rotate
-import w_sector
+import w_main
+import w_cut_recovery
class wizards:
@@ -56,25 +45,14 @@ def __init__(self, halcomp,builder,useropts):
self.prefFile = self.i.find('EMC', 'MACHINE') + '.pref'
self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
self.configFile = self.i.find('EMC', 'MACHINE').lower() + '_wizards.cfg'
- self.builder.get_object('hbox1').connect('destroy', self.on_shutdown)
- self.tmpDir = ('/tmp/plasmac_wizards')
- if not os.path.isdir(self.tmpDir):
- os.mkdir(self.tmpDir)
- self.fWizard = '{}/wizard.ngc'.format(self.tmpDir)
+ self.cutRecovering = False
self.check_settings()
self.set_theme()
- for wizard in ['line', 'circle', 'triangle', 'rectangle', 'polygon', 'bolt-circle', 'slot', 'star', 'gusset', 'sector']:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
- filename='./wizards/images/{}-thumb.png'.format(wizard),
- width=60,
- height=60)
- image = gtk.Image()
- image.set_from_pixbuf(pixbuf)
- self.builder.get_object('{}'.format(wizard)).set_image(image)
self.button_setup()
self.builder.get_object('button10').connect('realize', self.set_style)
self.initialized = True
self.filter = './plasmac/plasmac_gcode.py'
+ self.wizardButton = self.builder.get_object('wizard-b')
gobject.timeout_add(100, self.periodic)
def set_theme(self):
@@ -106,7 +84,7 @@ def check_settings(self):
f_out.write('origin=False\n')
f_out.write('lead-in=0.16\n')
f_out.write('lead-out=0\n')
- f_out.write('hole-diameter=1.25\n')
+ f_out.write('hole-diameter=1.26\n')
else:
f_out.write('preamble=G21 G64P0.1 {}\n'.format(ambles))
f_out.write('postamble=G21 G64P0.1 {}\n'.format(ambles))
@@ -115,137 +93,31 @@ def check_settings(self):
f_out.write('lead-out=0\n')
f_out.write('hole-diameter=32\n')
f_out.write('hole-speed=60\n')
+ f_out.write('window-width=890\n')
+ f_out.write('window-height=582\n')
+ f_out.write('grid-size=0\n')
+ f_out.write('font-size=9\n')
except:
self.dialog_error('Error opening {}'.format(self.configFile))
- def dialog_error(self, eWizard, error):
+ def dialog_error(self, error):
md = gtk.MessageDialog(self.W,
gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR,
gtk.BUTTONS_CLOSE,
- '{} WIZARD ERROR\n\n{}'.format(eWizard, error))
+ error)
md.set_keep_above(True)
md.set_position(gtk.WIN_POS_CENTER_ALWAYS)
md.run()
md.destroy()
- def on_shutdown(self, widget):
- shutil.rmtree(self.tmpDir)
-
- def on_new_pressed(self, widget):
- if os.path.exists(self.fWizard):
- os.remove(self.fWizard)
-
- def on_array_pressed(self, widget):
- self.s.poll()
- if os.path.basename(self.s.file) == os.path.basename(self.fWizard):
- reload(w_array)
- array = w_array.array()
- error = array.do_array(self.fWizard, self.tmpDir, True)
- if error:
- self.dialog_error('ARRAY', error)
- elif self.s.file:
- reload(w_array)
- array = w_array.array()
- error = array.do_array(self.s.file, self.tmpDir, False)
- if error:
- self.dialog_error('ARRAY', error)
- else:
- self.dialog_error('ARRAY', 'No file available to create array from')
-
- def on_settings_pressed(self, widget):
- reload(w_settings)
- settings = w_settings.settings()
- error = settings.do_settings()
- if error:
- self.dialog_error('LINE', error)
-
- def on_line_pressed(self, widget):
- reload(w_line)
- line = w_line.line()
- error = line.do_line(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('LINE', error)
-
- def on_circle_pressed(self, widget):
- reload(w_circle)
- circle = w_circle.circle()
- error = circle.do_circle(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('CIRCLE', error)
-
- def on_triangle_pressed(self, widget):
- reload(w_triangle)
- triangle = w_triangle.triangle()
- error = triangle.do_triangle(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('TRIANGLE', error)
-
- def on_rectangle_pressed(self, widget):
- reload(w_rectangle)
- rectangle = w_rectangle.rectangle()
- error = rectangle.do_rectangle(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('RECTANGLE', error)
-
- def on_polygon_pressed(self, widget):
- reload(w_polygon)
- polygon = w_polygon.polygon()
- error = polygon.do_polygon(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('POLYGON', error)
-
- def on_bolt_circle_pressed(self, widget):
- reload(w_bolt_circle)
- bolt_circle = w_bolt_circle.bolt_circle()
- error = bolt_circle.do_bolt_circle(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('BOLT CIRCLE', error)
-
- def on_slot_pressed(self, widget):
- reload(w_slot)
- slot = w_slot.slot()
- error = slot.do_slot(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('SLOT', error)
-
- def on_star_pressed(self, widget):
- reload(w_star)
- star = w_star.star()
- error = star.do_star(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('STAR', error)
-
- def on_gusset_pressed(self, widget):
- reload(w_gusset)
- gusset = w_gusset.gusset()
- error = gusset.do_gusset(self.fWizard, self.tmpDir)
- if error:
- self.dialog_error('GUSSET', error)
-
- def on_sector_pressed(self, widget):
- reload(w_sector)
- sector = w_sector.sector()
- error = sector.do_sector(self.fWizard, self.tmpDir)
+ def on_wizard_b_clicked(self, widget):
+ self.wizardButton.set_sensitive(False)
+ reload(w_main)
+ main_wiz = w_main.main_wiz()
+ error = main_wiz.main_show(self)
if error:
- self.dialog_error('SECTOR', error)
-
- def on_rotate_pressed(self, widget):
- self.s.poll()
- if os.path.basename(self.s.file) == os.path.basename(self.fWizard):
- inFile = self.fWizard
- mode = 'wizard'
- elif self.s.file:
- inFile = self.s.file
- mode = 'file'
- else:
- self.dialog_error('ROTATE', 'No file available to rotate')
- return
- reload(w_rotate)
- rotate = w_rotate.rotate()
- error = rotate.do_rotate(self.fWizard, inFile, self.tmpDir)
- if error:
- self.dialog_error('ROTATE', error)
+ self.dialog_error('Error in conversational dialog')
def button_setup(self):
self.iniButtonName = ['Names','','','','','','','','','']
@@ -273,11 +145,7 @@ def button_setup(self):
if code == 'cut-type':
self.cutButton = 'button{}'.format(button)
if 'change-consumables' in code:
- ccParm = self.i.find('PLASMAC','BUTTON_' + str(button) + '_CODE').replace('change-consumables','').replace(' ','').lower() or None
- if ccParm:
- self.consumable_change_setup(ccParm)
- else:
- self.dialog_error('Parameters required for consumable change\n\nCheck .ini file settings\n')
+ self.ccParm = self.i.find('PLASMAC','BUTTON_' + str(button) + '_CODE').replace('change-consumables','').replace(' ','').lower() or None
try:
if pic:
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
@@ -295,21 +163,38 @@ def on_button_pressed(self, button):
bNum = int(button.get_name().split('button')[1])
commands = self.iniButtonCode[bNum]
if not commands: return
- if 'change-consumables' in commands.lower():
+ if 'cut-recovery' in commands.lower() and hal.get_value('halui.program.is-paused') and \
+ not hal.get_value('plasmac.cut-recovery') and not hal.get_value('plasmac.cut-recovering'):
+ cut_wiz = w_cut_recovery.recovery()
+ error = cut_wiz.create_widgets()
+ if error:
+ self.dialog_error('Error in cut recovery dialog')
+ elif 'change-consumables' in commands.lower():
+ self.consumable_change_setup()
if hal.get_value('axis.x.eoffset-counts') or hal.get_value('axis.y.eoffset-counts'):
hal.set_p('plasmac.consumable-change', '0')
hal.set_p('plasmac.x-offset', '0')
hal.set_p('plasmac.y-offset', '0')
else:
- hal.set_p('plasmac.xy-feed-rate', str(int(self.ccF)))
- if self.ccX or self.ccX == 0:
- hal.set_p('plasmac.x-offset', '{:.0f}'.format((self.ccX - self.s.position[0]) / hal.get_value('plasmac.offset-scale')))
+ if self.ccF == 'None' or self.ccF < 1:
+ self.dialog_error('Invalid feed rate for consumable change\n\nCheck .ini file settings\n\nBUTTON_{}_CODE'.format(str(button)))
+ return
else:
- hal.set_p('plasmac.x-offset', '0')
- if self.ccY or self.ccY == 0:
- hal.set_p('plasmac.y-offset', '{:.0f}'.format((self.ccY - self.s.position[1]) / hal.get_value('plasmac.offset-scale')))
- else:
- hal.set_p('plasmac.y-offset', '0')
+ hal.set_p('plasmac.xy-feed-rate', str(float(self.ccF)))
+ if self.ccX == 'None':
+ self.ccX = self.s.position[0]
+ if self.ccX < round(float(self.i.find('AXIS_X', 'MIN_LIMIT')), 6) + (10 * hal.get_value('halui.machine.units-per-mm')):
+ self.ccX = round(float(self.i.find('AXIS_X', 'MIN_LIMIT')), 6) + (10 * hal.get_value('halui.machine.units-per-mm'))
+ elif self.ccX > round(float(self.i.find('AXIS_X', 'MAX_LIMIT')), 6) - (10 * hal.get_value('halui.machine.units-per-mm')):
+ self.ccX = round(float(self.i.find('AXIS_X', 'MAX_LIMIT')), 6) - (10 * hal.get_value('halui.machine.units-per-mm'))
+ if self.ccY == 'None':
+ self.ccY = self.s.position[1]
+ if self.ccY < round(float(self.i.find('AXIS_Y', 'MIN_LIMIT')), 6) + (10 * hal.get_value('halui.machine.units-per-mm')):
+ self.ccY = round(float(self.i.find('AXIS_Y', 'MIN_LIMIT')), 6) + (10 * hal.get_value('halui.machine.units-per-mm'))
+ elif self.ccY > round(float(self.i.find('AXIS_Y', 'MAX_LIMIT')), 6) - (10 * hal.get_value('halui.machine.units-per-mm')):
+ self.ccY = round(float(self.i.find('AXIS_Y', 'MAX_LIMIT')), 6) - (10 * hal.get_value('halui.machine.units-per-mm'))
+ hal.set_p('plasmac.x-offset', '{:.0f}'.format((self.ccX - self.s.position[0]) / hal.get_value('plasmac.offset-scale')))
+ hal.set_p('plasmac.y-offset', '{:.0f}'.format((self.ccY - self.s.position[1]) / hal.get_value('plasmac.offset-scale')))
hal.set_p('plasmac.consumable-change', '1')
elif commands.lower() == 'ohmic-test':
hal.set_p('plasmac.ohmic-test','1')
@@ -355,16 +240,18 @@ def on_button_pressed(self, button):
self.c.program_open(self.outFile)
hal.set_p('plasmac_run.cut-type','0')
elif 'load' in commands.lower():
+ path = self.i.find('DISPLAY', 'PROGRAM_PREFIX') or os.environ['LINUXCNC_NCFILES_DIR']
lFile = commands.split('load')[1].strip()
if self.gui == 'axis':
- Popen('axis-remote {}/{}'.format(os.environ['LINUXCNC_NCFILES_DIR'], lFile), stdout = PIPE, shell = True)
+ Popen('axis-remote {}/{}'.format(path, lFile), stdout = PIPE, shell = True)
elif self.gui == 'gmoccapy':
- self.c.program_open('{}/{}'.format(os.environ['LINUXCNC_NCFILES_DIR'], lFile))
+ self.c.program_open('{}/{}'.format(path, lFile))
else:
for command in commands.split('\\'):
if command.strip()[0] == '%':
command = command.strip().strip('%') + '&'
- Popen(command,stdout=PIPE,stderr=PIPE, shell=True)
+ msg = Popen(command,stdout=PIPE,stderr=PIPE, shell=True)
+ print(msg.communicate()[0])
else:
if '{' in command:
newCommand = subCommand = ''
@@ -408,24 +295,24 @@ def on_button_released(self, button):
self.probeButton.set_style(self.buttonPlain)
self.probeButton = ''
- def consumable_change_setup(self, ccParm):
- self.ccX = self.ccY = self.ccF = ''
+ def consumable_change_setup(self):
+ self.ccX = self.ccY = self.ccF = 'None'
X = Y = F = ''
ccAxis = [X, Y, F]
ccName = ['x', 'y', 'f']
for loop in range(3):
count = 0
- if ccName[loop] in ccParm:
+ if ccName[loop] in self.ccParm:
while 1:
- if not ccParm[count]: break
- if ccParm[count] == ccName[loop]:
+ if not self.ccParm[count]: break
+ if self.ccParm[count] == ccName[loop]:
count += 1
break
count += 1
while 1:
- if count == len(ccParm): break
- if ccParm[count].isdigit() or ccParm[count] in '.-':
- ccAxis[loop] += ccParm[count]
+ if count == len(self.ccParm): break
+ if self.ccParm[count].isdigit() or self.ccParm[count] in '.-':
+ ccAxis[loop] += self.ccParm[count]
else:
break
count += 1
@@ -435,22 +322,6 @@ def consumable_change_setup(self, ccParm):
self.ccY = float(ccAxis[loop])
elif ccName[loop] == 'f' and ccAxis[loop]:
self.ccF = float(ccAxis[loop])
- if self.ccX and \
- (self.ccX < round(float(self.i.find('AXIS_X', 'MIN_LIMIT')), 6) or \
- self.ccX > round(float(self.i.find('AXIS_X', 'MAX_LIMIT')), 6)):
- self.dialog_error('X out of limits for consumable change\n\nCheck .ini file settings\n')
- print('x out of bounds for consumable change\n')
- raise SystemExit()
- if self.ccY and \
- (self.ccY < round(float(self.i.find('AXIS_Y', 'MIN_LIMIT')), 6) or \
- self.ccY > round(float(self.i.find('AXIS_Y', 'MAX_LIMIT')), 6)):
- self.dialog_error('Y out of limits for consumable change\n\nCheck .ini file settings\n')
- print('y out of bounds for consumable change\n')
- raise SystemExit()
- if not self.ccF:
- self.dialog_error('invalid feed rate for consumable change\n\nCheck .ini file settings\n')
- print('invalid consumable change feed rate\n')
- raise SystemExit()
def set_style(self,button):
self.buttonPlain = self.builder.get_object('button10').get_style().copy()
@@ -465,62 +336,73 @@ def periodic(self):
self.s.poll()
isIdleHomed = True
isIdleOn = True
- if hal.get_value('halui.program.is-idle') and hal.get_value('halui.machine.is-on'):
- if hal.get_value('plasmac.arc-ok-out'):
- isIdleOn = False
- for joint in range(0,int(self.i.find('KINS','JOINTS'))):
- if not self.s.homed[joint]:
- isIdleHomed = False
- break
- else:
- isIdleHomed = False
- isIdleOn = False
- for n in range(10,20):
- if 'load' in self.iniButtonCode[n]:
- pass
- elif 'change-consumables' in self.iniButtonCode[n]:
- if hal.get_value('halui.program.is-paused'):
- self.builder.get_object('button' + str(n)).set_sensitive(True)
- else:
- self.builder.get_object('button' + str(n)).set_sensitive(False)
- elif 'ohmic-test' in self.iniButtonCode[n]:
- if isIdleOn or hal.get_value('halui.program.is-paused'):
- self.builder.get_object('button' + str(n)).set_sensitive(True)
- else:
- self.builder.get_object('button' + str(n)).set_sensitive(False)
- elif not 'cut-type' in self.iniButtonCode[n] and not self.iniButtonCode[n].startswith('%'):
- if isIdleHomed:
- self.builder.get_object('button' + str(n)).set_sensitive(True)
- else:
- self.builder.get_object('button' + str(n)).set_sensitive(False)
- # decrement probe timer if active
- if self.probeTimer:
- if hal.get_value('plasmac.probe-test-error') and not self.probePressed:
- self.probeTimer = 0
- elif time.time() >= self.probeStart + 1:
- self.probeStart += 1
- self.probeTimer -= 1
- self.probeButton.set_label(str(int(self.probeTimer)))
- self.probeButton.set_style(self.buttonRed)
- if not self.probeTimer and not self.probePressed:
- hal.set_p('plasmac.probe-test','0')
- self.probeButton.set_label(self.probeText)
- self.probeButton.set_style(self.buttonPlain)
- if self.gui == 'gmoccapy':
- if self.inFile and self.inFile != self.s.file:
- if not 'PlaSmaC' in self.s.file or 'PlaSmaC0' in self.s.file:
- self.builder.get_object(self.cutButton).set_style(self.buttonPlain)
- self.builder.get_object(self.cutButton).set_label('Pierce & Cut')
- self.cutType = 0
- elif 'PlaSmaC1' in self.s.file:
- self.builder.get_object(self.cutButton).set_style(self.buttonOrange)
- self.builder.get_object(self.cutButton).set_label('Pierce Only')
- self.cutType = 1
- if (hal.get_value('axis.x.eoffset') or hal.get_value('axis.y.eoffset')) and not hal.get_value('halui.program.is-paused'):
- hal.set_p('plasmac.consumable-change', '0')
- hal.set_p('plasmac.x-offset', '0')
- hal.set_p('plasmac.y-offset', '0')
- hal.set_p('plasmac.xy-feed-rate', '0')
+ if hal.component_exists('halui'):
+ if hal.get_value('plasmac:program-is-idle'):
+ hal.set_p('plasmac.cut-recovery', '0')
+ if hal.get_value('halui.machine.is-on'):
+ if hal.get_value('plasmac.arc-ok-out'):
+ isIdleOn = False
+ for joint in range(0,int(self.i.find('KINS','JOINTS'))):
+ if not self.s.homed[joint]:
+ isIdleHomed = False
+ break
+ else:
+ isIdleHomed = False
+ isIdleOn = False
+ for n in range(10,20):
+ if 'load' in self.iniButtonCode[n]:
+ pass
+ elif 'change-consumables' in self.iniButtonCode[n]:
+ if hal.get_value('halui.program.is-paused') and \
+ hal.get_value('plasmac.stop-type-out') > 1 and \
+ not hal.get_value('plasmac.cut-recovering'):
+ self.builder.get_object('button' + str(n)).set_sensitive(True)
+ else:
+ self.builder.get_object('button' + str(n)).set_sensitive(False)
+ elif 'cut-recovery' in self.iniButtonCode[n]:
+ if hal.get_value('halui.program.is-paused') and hal.get_value('plasmac.motion-type') > 1 and \
+ not hal.get_value('plasmac.consumable-changing'):
+ self.builder.get_object('button' + str(n)).set_sensitive(True)
+ else:
+ self.builder.get_object('button' + str(n)).set_sensitive(False)
+ elif 'ohmic-test' in self.iniButtonCode[n]:
+ if isIdleOn or hal.get_value('halui.program.is-paused'):
+ self.builder.get_object('button' + str(n)).set_sensitive(True)
+ else:
+ self.builder.get_object('button' + str(n)).set_sensitive(False)
+ elif not 'cut-type' in self.iniButtonCode[n] and not self.iniButtonCode[n].startswith('%'):
+ if isIdleHomed:
+ self.builder.get_object('button' + str(n)).set_sensitive(True)
+ else:
+ self.builder.get_object('button' + str(n)).set_sensitive(False)
+ # decrement probe timer if active
+ if self.probeTimer:
+ if hal.get_value('plasmac.probe-test-error') and not self.probePressed:
+ self.probeTimer = 0
+ elif time.time() >= self.probeStart + 1:
+ self.probeStart += 1
+ self.probeTimer -= 1
+ self.probeButton.set_label(str(int(self.probeTimer)))
+ self.probeButton.set_style(self.buttonRed)
+ if not self.probeTimer and not self.probePressed:
+ hal.set_p('plasmac.probe-test','0')
+ self.probeButton.set_label(self.probeText)
+ self.probeButton.set_style(self.buttonPlain)
+ if self.gui == 'gmoccapy':
+ if self.inFile and self.inFile != self.s.file:
+ if not 'PlaSmaC' in self.s.file or 'PlaSmaC0' in self.s.file:
+ self.builder.get_object(self.cutButton).set_style(self.buttonPlain)
+ self.builder.get_object(self.cutButton).set_label('Pierce & Cut')
+ self.cutType = 0
+ elif 'PlaSmaC1' in self.s.file:
+ self.builder.get_object(self.cutButton).set_style(self.buttonOrange)
+ self.builder.get_object(self.cutButton).set_label('Pierce Only')
+ self.cutType = 1
+ if (hal.get_value('axis.x.eoffset') or hal.get_value('axis.y.eoffset')) and not hal.get_value('halui.program.is-paused'):
+ hal.set_p('plasmac.consumable-change', '0')
+ hal.set_p('plasmac.x-offset', '0')
+ hal.set_p('plasmac.y-offset', '0')
+ hal.set_p('plasmac.xy-feed-rate', '0')
return True
def get_handlers(halcomp,builder,useropts):
diff --git a/configs/by_machine/plasmac/test/plasmac_test.py b/configs/by_machine/plasmac/test/plasmac_test.py
index 1852f9da73..bcf4678857 100755
--- a/configs/by_machine/plasmac/test/plasmac_test.py
+++ b/configs/by_machine/plasmac/test/plasmac_test.py
@@ -123,16 +123,29 @@ def __init__(self):
self.halcomp.ready()
sp.Popen(['halcmd net plasmac:torch-on plasmactest.torch-on'], shell=True)
self.torch.connect('value-changed', self.torch_changed)
- if not hal.pin_has_writer('plasmac.arc-ok-in'):
- sp.Popen(['halcmd net p_test:arc-ok-in plasmactest.arcOk plasmac.arc-ok-in'], shell=True)
+ # test if using debounce on arc ok input (configs prior to 4 Sep 2020)
+ arcDb = int(self.lcnc.iniFile.find('PLASMAC', 'DBOUNCE') or '0')
+ if arcDb:
+ if not hal.pin_has_writer('db_arc-ok.in'):
+ sp.Popen(['halcmd net p_test:arc-ok-in plasmactest.arcOk db_arc-ok.in'], shell=True)
+ if not hal.pin_has_writer('db_float.in'):
+ sp.Popen(['halcmd net p_test:float-switch plasmactest.floatSwitch db_float.in'], shell=True)
+ if not hal.pin_has_writer('db_breakaway.in'):
+ sp.Popen(['halcmd net p_test:breakaway-switch plasmactest.breakawaySwitch db_breakaway.in'], shell=True)
+ if not hal.pin_has_writer('db_ohmic.in'):
+ sp.Popen(['halcmd net p_test:ohmic-probe plasmactest.ohmicProbe db_ohmic.in'], shell=True)
+ else:
+ if not hal.pin_has_writer('plasmac.arc-ok-in'):
+ sp.Popen(['halcmd net p_test:arc-ok-in plasmactest.arcOk plasmac.arc-ok-in'], shell=True)
+ if not hal.pin_has_writer('debounce.0.0.in'):
+ sp.Popen(['halcmd net p_test:float-switch plasmactest.floatSwitch debounce.0.0.in'], shell=True)
+ if not hal.pin_has_writer('debounce.0.1.in'):
+ sp.Popen(['halcmd net p_test:breakaway-switch plasmactest.breakawaySwitch debounce.0.1.in'], shell=True)
+ if not hal.pin_has_writer('debounce.0.2.in'):
+ sp.Popen(['halcmd net p_test:ohmic-probe plasmactest.ohmicProbe debounce.0.2.in'], shell=True)
+
if not hal.pin_has_writer('plasmac.arc-voltage-in'):
sp.Popen(['halcmd net p_test:arc-voltage-in plasmactest.arcVoltage plasmac.arc-voltage-in'], shell=True)
- if not hal.pin_has_writer('debounce.0.0.in'):
- sp.Popen(['halcmd net p_test:float-switch plasmactest.floatSwitch debounce.0.0.in'], shell=True)
- if not hal.pin_has_writer('debounce.0.1.in'):
- sp.Popen(['halcmd net p_test:breakaway-switch plasmactest.breakawaySwitch debounce.0.1.in'], shell=True)
- if not hal.pin_has_writer('debounce.0.2.in'):
- sp.Popen(['halcmd net p_test:ohmic-probe plasmactest.ohmicProbe debounce.0.2.in'], shell=True)
if not hal.pin_has_writer('plasmac.move-down'):
sp.Popen(['halcmd net p_test:move-down plasmactest.moveDown plasmac.move-down'], shell=True)
if not hal.pin_has_writer('plasmac.move-up'):
diff --git a/configs/by_machine/plasmac/versions.html b/configs/by_machine/plasmac/versions.html
index 94c1a02773..b52ef7e671 100644
--- a/configs/by_machine/plasmac/versions.html
+++ b/configs/by_machine/plasmac/versions.html
@@ -19,6 +19,182 @@
PlasmaC Updates
+ v0.177 - 2020 Sep 29
+
+
fix intermittent nan error on startup
+
fix material selection in gcode filter
+
+
+ v0.176 - 2020 Sep 19
+
+
added hal pin to allow preview refresh
+
+
+ v0.175 - 2020 Sep 16
+
+
fix cut-recovery direction buttons
+
+
+ v0.174 - 2020 Sep 13
+
+
fix control panel inconsistencies
+
+
+ v0.173 - 2020 Sep 11
+
+
use dbounce in lieu of debounce for new configs
+
+
+ v0.172 - 2020 Sep 09
+
+
fix configurator upgrade error for filter path
+
fix thc default in materialverter
+
+
+ v0.171 - 2020 Sep 07
+
+
compress config backup
+
fix gcode file load
+
fix wizard spindle codes
+
fix sample scribe code
+
+
+ v0.170 - 2020 Sep 02
+
+
add speed adjustment for final probe up
+
fix scibe error in filter file
+
update user guide
+
+
+ v0.169 - 2020 Aug 30
+
+
fix offset disable error from v0.162
+
+
+ v0.168 - 2020 Aug 28
+
+
fix reset offsets after power cycle
+
comment out halui.machine.is-on for new configs
+
+
+ v0.167 - 2020 Aug 27
+
+
reset offsets after power cycle
+
+
+ v0.166 - 2020 Aug 26
+
+
fix offset clear for low home height
+
fix configurator upgrade
+
plasmac run panel and tab tooltips
+
use tcl file for postgui
+
+
+ v0.165 - 2020 Aug 24
+
+
add cut recovery
+
+
+ v0.164 - 2020 Aug 23
+
+
fix version reporting for upgrades
+
+
+ v0.163 - 2020 Aug 18
+
+
prevent multiple conversational instances
+
save current position in conversational
+
+
+ v0.162 - 2020 Aug 17
+
+
disable z offset when not required
+
fix thc active for mode 2
+
prevent queued single cut commands
+
+
+ v0.161 - 2020 Aug 15
+
+
fix conversational settings save and load
+
doc update for height per volt
+
+
+ v0.160 - 2020 Aug 12
+
+
rework mesh mode
+
rework gcode filter
+
update user guide
+
+
+ v0.159 - 2020 Aug 10
+
+
mesh mode update for rs485
+
user guide update
+
+
+ v0.158 - 2020 Aug 08
+
+
fix conversational kerf offsets
+
+
+ v0.157 - 2020 Aug 07
+
+
fix probing for ohmic probe offset
+
+
+ v0.156 - 2020 Aug 07
+
+
set conversational origin to 0,0
+
don't save mesh mode enable
+
+
+ v0.155 - 2020 Aug 06
+
+
update some conversational shapes
+
+
+ v0.154 - 2020 Aug 05
+
+
conversational tidy up
+
fix grid scale for conversational
+
add quit button to conversational
+
doc typo and help updates
+
+
+ v0.153 - 2020 Aug 03
+
+
add mesh mode for expanded metal
+
+
+ v0.152 - 2020 Aug 02
+
+
conversational updates
+
gmoccapy wizard blank file path error
+
+
+ v0.151 - 2020 Aug 01
+
+
disable x/y offsets when not required
+
+
+ v0.150 - 2020 Jul 31
+
+
new interface for conversational shape library
+
consumable change updates
+
+
+ v0.149 - 2020 Jul 29
+
+
add a save dialog to the run panel
+
+
+ v0.148 - 2020 Jul 29
+
+
consumable change fixes and error handling
+
remove print statement from configurator
+
change stop type for breakaway during rapid move
+
+
v0.147 - 2020 Jul 27
fix symlinks to plasmac_connections.hal
@@ -31,6 +207,7 @@
PlasmaC Updates
allow consumable change during rapid motion
change gcode feed rate warnings
+Note: PlasmaC now uses the axis.x.eoffset and axis.y.eoffset HAL pins
v0.145 - 2020 Jul 24
@@ -51,6 +228,7 @@
PlasmaC Updates
user guide update
fix torch pulse interlock
+Note: PlasmaC now uses the motion.motion-type HAL pin
v0.142 - 2020 Jul 13
diff --git a/configs/by_machine/plasmac/wizards/blank.ngc b/configs/by_machine/plasmac/wizards/blank.ngc
index b82b327ae6..7cc33c7817 100644
--- a/configs/by_machine/plasmac/wizards/blank.ngc
+++ b/configs/by_machine/plasmac/wizards/blank.ngc
@@ -1,4 +1,4 @@
;DO NOT DELETE
;this is required by Gmoccapy
;for loading shape wizard library files
-M30
+M2
diff --git a/configs/by_machine/plasmac/wizards/images/array-thumb.png b/configs/by_machine/plasmac/wizards/images/array-thumb.png
new file mode 100644
index 0000000000..bf9c246f62
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/array-thumb.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_down.png b/configs/by_machine/plasmac/wizards/images/arrow_down.png
new file mode 100644
index 0000000000..78d35a3c95
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_down.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_left.png b/configs/by_machine/plasmac/wizards/images/arrow_left.png
new file mode 100644
index 0000000000..07ef884c81
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_left.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_left_down.png b/configs/by_machine/plasmac/wizards/images/arrow_left_down.png
new file mode 100644
index 0000000000..0e56eb9538
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_left_down.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_left_up.png b/configs/by_machine/plasmac/wizards/images/arrow_left_up.png
new file mode 100644
index 0000000000..7f72176b52
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_left_up.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_right.png b/configs/by_machine/plasmac/wizards/images/arrow_right.png
new file mode 100644
index 0000000000..ca64f20a9d
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_right.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_right_down.png b/configs/by_machine/plasmac/wizards/images/arrow_right_down.png
new file mode 100644
index 0000000000..f646437d93
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_right_down.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_right_up.png b/configs/by_machine/plasmac/wizards/images/arrow_right_up.png
new file mode 100644
index 0000000000..9d18f426a1
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_right_up.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/arrow_up.png b/configs/by_machine/plasmac/wizards/images/arrow_up.png
new file mode 100644
index 0000000000..47a5581abd
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/arrow_up.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/bolt-circle-thumb.png b/configs/by_machine/plasmac/wizards/images/bolt_circle-thumb.png
similarity index 100%
rename from configs/by_machine/plasmac/wizards/images/bolt-circle-thumb.png
rename to configs/by_machine/plasmac/wizards/images/bolt_circle-thumb.png
diff --git a/configs/by_machine/plasmac/wizards/images/gusset.png b/configs/by_machine/plasmac/wizards/images/gusset.png
index 8b32a9d994..9d5471d7dd 100644
Binary files a/configs/by_machine/plasmac/wizards/images/gusset.png and b/configs/by_machine/plasmac/wizards/images/gusset.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/polygon-thumb.png b/configs/by_machine/plasmac/wizards/images/polygon-thumb.png
index 62037d6e31..2680b2a358 100644
Binary files a/configs/by_machine/plasmac/wizards/images/polygon-thumb.png and b/configs/by_machine/plasmac/wizards/images/polygon-thumb.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/rectangle.png b/configs/by_machine/plasmac/wizards/images/rectangle.png
index ad6343140e..731fe6a551 100644
Binary files a/configs/by_machine/plasmac/wizards/images/rectangle.png and b/configs/by_machine/plasmac/wizards/images/rectangle.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/rotate-thumb.png b/configs/by_machine/plasmac/wizards/images/rotate-thumb.png
new file mode 100644
index 0000000000..f1567de1cb
Binary files /dev/null and b/configs/by_machine/plasmac/wizards/images/rotate-thumb.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/slot.png b/configs/by_machine/plasmac/wizards/images/slot.png
index 7dddb93a97..e616f765ee 100644
Binary files a/configs/by_machine/plasmac/wizards/images/slot.png and b/configs/by_machine/plasmac/wizards/images/slot.png differ
diff --git a/configs/by_machine/plasmac/wizards/images/triangle.png b/configs/by_machine/plasmac/wizards/images/triangle.png
index ad784330e8..a09c7c7216 100644
Binary files a/configs/by_machine/plasmac/wizards/images/triangle.png and b/configs/by_machine/plasmac/wizards/images/triangle.png differ
diff --git a/configs/by_machine/plasmac/wizards/w_array.py b/configs/by_machine/plasmac/wizards/w_array.py
index 5cd472964a..956507e849 100644
--- a/configs/by_machine/plasmac/wizards/w_array.py
+++ b/configs/by_machine/plasmac/wizards/w_array.py
@@ -28,7 +28,7 @@
import hal
from subprocess import Popen,PIPE
-class array:
+class array_wiz:
def __init__(self):
self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
@@ -36,124 +36,75 @@ def __init__(self):
self.s = linuxcnc.stat()
self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
- self.fNgc = ''
- self.fCode = ''
self.previewed = False
- self.data_changed = True
-
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- error)
- md.run()
- md.destroy()
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- if fName == '{}/wizard.ngc'.format(self.tmpDir):
- self.c.program_open(fName)
- else:
- if self.previewed:
- os.remove(self.outFile)
- self.outFile = '{}/array_{}.ngc'.format(self.tmpDir, time.time())
- shutil.copyfile(fName, self.outFile)
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(self.outFile)
- else:
- print('Unknown GUI in .ini file')
-
- def cancel(self, widget):
- if self.shapeMode:
- self.load_file(self.fOriginal)
- elif self.previewed:
- if self.gui == 'axis':
- self.load_file(self.fOriginal)
- elif self.gui == 'gmoccapy':
- self.c.program_open(self.fOriginal)
- os.remove(self.outFile)
+ def array_cancel(self, widget):
+ shutil.copyfile(self.parent.fNgcBkp, self.parent.fNgc)
+ if widget is not None:
+ self.parent.preview.load(self.parent.fNgc)
self.previewed = False
- self.W.destroy()
- return None
- def accept_array(self, widget):
- if not self.previewed or self.data_changed:
- self.dialog_error('Preview is required')
- return None
- elif os.path.exists(self.fCode):
- if self.gui == 'gmoccapy':
- self.c.program_open(self.fNgc)
- os.remove(self.outFile)
- elif os.path.exists(self.fOriginal) and self.fNgc:
- shutil.copyfile(self.fNgc, self.fOriginal)
- self.load_file(self.fOriginal)
- else:
- self.dialog_error('Cannot find required files')
- self.previewed = False
- self.W.destroy()
- for fName in ['original.ngc', 'shape.ngc', 'shape.tmp', 'wizard.ngc']:
- if os.path.exists('{}/{}'.format(self.tmpDir, fName)):
- os.remove('{}/{}'.format(self.tmpDir, fName))
- return None
- def preview_array(self, event):
- if self.xCEntry.get_text():
+ def array_accept(self, widget):
+ shutil.copyfile(self.parent.fNgc, self.parent.fNgcBkp)
+ self.parent.preview.load(self.parent.fNgc)
+
+ def array_preview(self, event):
+ try:
columns = int(self.xCEntry.get_text())
- else:
- columns = 0
- if self.yCEntry.get_text():
+ except:
+ columns = 1
+ try:
rows = int(self.yCEntry.get_text())
- else:
- rows = 0
- if self.xOEntry.get_text():
+ except:
+ rows = 1
+ try:
xOffset = float(self.xOEntry.get_text())
- else:
+ except:
xOffset = 0
- if self.yOEntry.get_text():
+ try:
yOffset = float(self.yOEntry.get_text())
- else:
+ except:
yOffset = 0
+ try:
+ xOrgOffset = float(self.xOrgEntry.get_text())
+ except:
+ xOrgOffset = 0
+ try:
+ yOrgOffset = float(self.yOrgEntry.get_text())
+ except:
+ yOrgOffset = 0
if columns > 0 and rows > 0 and (columns == 1 or (columns > 1 and xOffset <> 0)) and (rows == 1 or (rows > 1 and yOffset <> 0)):
- self.fCode = '{}/array_code.ngc'.format(self.tmpDir)
- if self.shapeMode:
- fPre = '{}/array_preamble.ngc'.format(self.tmpDir)
- fPst = '{}/array_postamble.ngc'.format(self.tmpDir)
- outCod = open(self.fCode, 'w')
- outPre = open(fPre, 'w')
- outPst = open(fPst, 'w')
- inWiz = open(self.fOriginal, 'r')
+ self.array_cancel(None)
+ if self.parent.arrayMode == 'wizard':
+ fPre = []
+ fPst = []
+ outCod = open(self.parent.fTmp, 'w')
+ inWiz = open(self.parent.fNgc, 'r')
while(1):
d = inWiz.readline()
if d.startswith('(wizard'):
outCod.write(d)
break
- outPre.write(d)
+ fPre.append(d)
while(1):
d = inWiz.readline()
- if d.startswith('(postamble'):
- outPst.write(d)
+ if '(postamble' in d:
+ fPst.append(d)
break
outCod.write(d)
while(1):
d = inWiz.readline()
if not d: break
- outPst.write(d)
+ fPst.append(d)
outCod.close()
- outPre.close()
- outPst.close()
inWiz.close()
- self.fNgc = '{}/array.ngc'.format(self.tmpDir)
- outNgc = open(self.fNgc, 'w')
- inPre = open(fPre, 'r')
- for line in inPre:
+ outNgc = open(self.parent.fNgc, 'w')
+ for line in fPre:
outNgc.write(line)
- inPre.close()
for row in range(rows):
for column in range(columns):
outNgc.write('\n(row:{} column:{})\n'.format(row + 1, column + 1))
- inCod = open(self.fCode, 'r')
+ inCod = open(self.parent.fTmp, 'r')
for line in inCod:
raw = line.strip().lower()
if raw.startswith('g0') or raw.startswith('g1') or raw.startswith('g2') or raw.startswith('g3'):
@@ -165,47 +116,20 @@ def preview_array(self, event):
else:
e = d
f = ''
- outNgc.write('{}x{} y{} {}\n'.format(a, float(c) + column * xOffset, float(e) + row * yOffset, f))
+ outNgc.write('{}x{} y{} {}\n'.format \
+ (a, (float(c) + column * xOffset) + xOrgOffset, (float(e) + row * yOffset) + yOrgOffset, f))
else:
outNgc.write(line)
inCod.close()
- inPst = open(fPst, 'r')
- for line in inPst:
+ for line in fPst:
outNgc.write(line)
- inPst.close()
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
else:
self.s.poll()
mUnits = self.s.linear_units
- if self.previewed:
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_NONE,
- 'ARRAY\n\nCalculating.....')
- md.set_keep_above(True)
- md.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- md.set_default_size(200, 100)
- md.show_all()
- self.c.program_open(self.fOriginal)
- watchdog = time.time() + 5
- while(1):
- self.s.poll()
- if os.path.basename(self.s.file) == os.path.basename(self.fOriginal):
- n = time.time() + 1
- while(1):
- if time.time() > n:
- break
- while gtk.events_pending():
- gtk.main_iteration()
- break
- if time.time() > watchdog:
- md.destroy()
- self.dialog_error('Array file error')
- return
- shutil.copyfile(self.s.file, self.fCode)
- inCod = open(self.fCode, 'r')
+ shutil.copyfile(self.parent.fNgc, self.parent.fTmp)
+ inCod = open(self.parent.fTmp, 'r')
units = 1
for line in inCod:
if 'G21' in line.upper().replace(' ', '') and mUnits != 1:
@@ -214,16 +138,21 @@ def preview_array(self, event):
if 'G20' in line.upper().replace(' ', '') and mUnits == 1:
units = 0.03937
break
- self.fNgc = '{}/array.ngc'.format(self.tmpDir)
- outNgc = open(self.fNgc, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
xIndex = [5221,5241,5261,5281,5301,5321,5341,5361,5381][0]
outNgc.write('# = #{}\n'.format(xIndex))
outNgc.write('# = #{}\n'.format(xIndex + 1))
for row in range(rows):
for column in range(columns):
outNgc.write('\n(row:{} column:{})\n'.format(row + 1, column + 1))
- outNgc.write('G10 L2 P0 X[{} + #] Y[{} + #]\n'.format(column * xOffset * units, row * yOffset * units))
- inCod = open(self.fCode, 'r')
+ if self.parent.arrayMode == 'external':
+ outNgc.write('G10 L2 P0 X[{} + #] Y[{} + #]\n'.format\
+ ((column * xOffset * units) + xOrgOffset, (row * yOffset * units) + yOrgOffset))
+ else:
+ # check this down the track for arraying external arrays multiole time
+ outNgc.write('G10 L2 P0 X{} Y{} ($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$)\n'.format\
+ ((column * xOffset * units) + xOrgOffset, (row * yOffset * units) + yOrgOffset))
+ inCod = open(self.parent.fTmp, 'r')
for line in inCod:
a = b = c = ''
a = line.upper().replace(' ', '')
@@ -231,16 +160,17 @@ def preview_array(self, event):
b = a.replace('M2', '')
c = b.replace('M30', '')
outNgc.write(c)
+ elif '(postamble)' in line:
+ pass
else:
outNgc.write(line)
inCod.close()
outNgc.write('G10 L2 P0 X# Y#\n')
- outNgc.write('M30\n')
+ outNgc.write('M2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
if self.previewed:
md.destroy()
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if columns <= 0:
@@ -251,75 +181,98 @@ def preview_array(self, event):
msg += 'Column Offset is required\n\n'
if yOffset == 0 and rows > 1:
msg += 'Row Offset is required'
- self.dialog_error(msg)
+ self.parent.dialog_error('ARRAY', msg)
return
self.previewed = True
- self.data_changed = False
+ self.add.set_sensitive(True)
- def data_change(self, widget):
- self.data_changed = True
+ def auto_preview(self, widget):
+ try:
+ if int(self.xCEntry.get_text()) == 1 or (int(self.xCEntry.get_text()) > 1 and self.xOEntry.get_text()) and \
+ int(self.yCEntry.get_text()) == 1 or (int(self.yCEntry.get_text()) > 1 and self.yOEntry.get_text()):
+ self.array_preview('auto')
+ except:
+ pass
- def do_array(self, fWizard, tmpDir, mode):
- self.tmpDir = tmpDir
- original = '{}/original.ngc'.format(tmpDir)
- shutil.copyfile(fWizard, original)
- self.fOriginal = original
- self.shapeMode = mode
- self.W = gtk.Dialog('Array',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
- xCLabel = gtk.Label('Columns')
+ def array_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
+ try:
+ shutil.copyfile(inFile, self.parent.fNgcBkp)
+ except:
+ pass
+ CLabel = gtk.Label('Columns')
+ CLabel.set_alignment(0.5, 1.0)
+ self.parent.entries.attach(CLabel, 2, 3, 0, 1)
+ xCLabel = gtk.Label('Number')
xCLabel.set_alignment(0.95, 0.5)
- xCLabel.set_width_chars(10)
- t.attach(xCLabel, 0, 1, 0, 1)
+ self.parent.entries.attach(xCLabel, 0, 1, 1, 2)
self.xCEntry = gtk.Entry()
- self.xCEntry.set_width_chars(10)
+ self.xCEntry.set_width_chars(8)
self.xCEntry.set_text('1')
- self.xCEntry.connect('changed', self.data_change)
- t.attach(self.xCEntry, 1, 2, 0, 1)
- xOLabel = gtk.Label('Column\nOffset')
- xOLabel.set_alignment(0.95, 0.5)
- xOLabel.set_justify(gtk.JUSTIFY_RIGHT)
- xOLabel.set_width_chars(10)
- t.attach(xOLabel, 2, 3, 0, 1)
+ self.xCEntry.connect('activate', self.auto_preview)
+ self.xCEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xCEntry, 1, 2, 1, 2)
+ xOLabel = gtk.Label('Offset')
+ xOLabel.set_alignment(0.05, 0.5)
+ self.parent.entries.attach(xOLabel, 4, 5, 1, 2)
self.xOEntry = gtk.Entry()
- self.xOEntry.set_width_chars(10)
- self.xOEntry.connect('changed', self.data_change)
- t.attach(self.xOEntry, 3, 4, 0, 1)
- yCLabel = gtk.Label('Rows')
+ self.xOEntry.set_width_chars(8)
+ self.xOEntry.connect('activate', self.auto_preview)
+ self.xOEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xOEntry, 3, 4, 1, 2)
+ RLabel = gtk.Label('Rows')
+ RLabel.set_alignment(0.5, 1.0)
+ self.parent.entries.attach(RLabel, 2, 3, 2, 3)
+ yCLabel = gtk.Label('Number')
yCLabel.set_alignment(0.95, 0.5)
- yCLabel.set_width_chars(10)
- t.attach(yCLabel, 0, 1, 1, 2)
+ self.parent.entries.attach(yCLabel, 0, 1, 3, 4)
self.yCEntry = gtk.Entry()
- self.yCEntry.set_width_chars(10)
+ self.yCEntry.set_width_chars(8)
self.yCEntry.set_text('1')
- self.yCEntry.connect('changed', self.data_change)
- t.attach(self.yCEntry, 1, 2, 1, 2)
- yOLabel = gtk.Label('Row\nOffset')
- yOLabel.set_alignment(0.95, 0.5)
- yOLabel.set_justify(gtk.JUSTIFY_RIGHT)
- yOLabel.set_width_chars(10)
- t.attach(yOLabel, 2, 3, 1, 2)
+ self.yCEntry.connect('activate', self.auto_preview)
+ self.yCEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.yCEntry, 1, 2, 3, 4)
+ yOLabel = gtk.Label('Offset')
+ yOLabel.set_alignment(0.05, 0.5)
+ self.parent.entries.attach(yOLabel, 4, 5, 3, 4)
self.yOEntry = gtk.Entry()
- self.yOEntry.set_width_chars(10)
- self.xOEntry.connect('changed', self.data_change)
- t.attach(self.yOEntry, 3, 4, 1, 2)
+ self.yOEntry.set_width_chars(8)
+ self.yOEntry.connect('activate', self.auto_preview)
+ self.yOEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.yOEntry, 3, 4, 3, 4)
+ OrgLabel = gtk.Label('Origin')
+ OrgLabel.set_alignment(0.5, 1.0)
+ self.parent.entries.attach(OrgLabel, 2, 3, 4, 5)
+ xOrgLabel = gtk.Label('X Offset')
+ xOrgLabel.set_alignment(0.95, 0.5)
+ self.parent.entries.attach(xOrgLabel, 0, 1, 5, 6)
+ self.xOrgEntry = gtk.Entry()
+ self.xOrgEntry.set_width_chars(8)
+ self.xOrgEntry.set_text('0')
+ self.xOrgEntry.connect('activate', self.auto_preview)
+ self.xOrgEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xOrgEntry, 1, 2, 5, 6)
+ yOrgLabel = gtk.Label('Y Offset')
+ yOrgLabel.set_alignment(0.05, 0.5)
+ self.parent.entries.attach(yOrgLabel, 4, 5, 5, 6)
+ self.yOrgEntry = gtk.Entry()
+ self.yOrgEntry.set_width_chars(8)
+ self.yOrgEntry.set_text('0')
+ self.yOrgEntry.connect('activate', self.auto_preview)
+ self.yOrgEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.yOrgEntry, 3, 4, 5, 6)
self.preview = gtk.Button('Preview')
- self.preview.connect('pressed', self.preview_array)
- t.attach(self.preview, 1, 2, 3, 4)
- accept = gtk.Button('Accept')
- accept.connect('pressed', self.accept_array)
- t.attach(accept, 2, 3, 3, 4)
- cancel = gtk.Button('Cancel')
- cancel.connect('pressed', self.cancel)
- t.attach(cancel, 3, 4, 3, 4)
+ self.preview.connect('pressed', self.array_preview)
+ self.parent.entries.attach(self.preview, 0, 1, 12, 13)
+ self.add = gtk.Button('Add')
+ self.add.connect('pressed', self.array_accept)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.array_cancel)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
self.xCEntry.grab_focus()
- self.W.show_all()
- response = self.W.run()
diff --git a/configs/by_machine/plasmac/wizards/w_bolt_circle.py b/configs/by_machine/plasmac/wizards/w_bolt_circle.py
index 0fd5287e51..895001f2d3 100644
--- a/configs/by_machine/plasmac/wizards/w_bolt_circle.py
+++ b/configs/by_machine/plasmac/wizards/w_bolt_circle.py
@@ -29,82 +29,12 @@
import hal
from subprocess import Popen,PIPE
-class bolt_circle:
+class bolt_circle_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def bolt_circle_preview(self, event):
if self.dEntry.get_text():
cRadius = float(self.dEntry.get_text()) / 2
else:
@@ -134,7 +64,7 @@ def send_preview(self, event):
up = math.radians(90)
left = math.radians(180)
down = math.radians(270)
- if hRadius < self.sRadius:
+ if hRadius < self.parent.holeRadius:
sHole = True
else:
sHole = False
@@ -152,40 +82,31 @@ def send_preview(self, event):
leadIn = hRadius
if leadInOffset > hRadius:
leadInOffset = hRadius
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xC = float(self.xSEntry.get_text())
- else:
- xC = float(self.xSEntry.get_text()) + cRadius
- else:
- if self.centre.get_active():
- xC = xPos
- else:
- xC = xPos + cRadius
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yC = float(self.ySEntry.get_text())
- else:
- yC = float(self.ySEntry.get_text()) + cRadius
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ xC = float(self.xSEntry.get_text())
else:
- if self.centre.get_active():
- yC = yPos
- else:
- yC = yPos + cRadius
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
+ xC = float(self.xSEntry.get_text()) + cRadius
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ yC = float(self.ySEntry.get_text())
else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ yC = float(self.ySEntry.get_text()) + cRadius
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
for hole in range(holes):
outTmp.write('\n(wizard bolt circle, hole #{})\n'.format(hole + 1))
xhC = xC + cRadius * math.cos(hAngle * hole + angle)
@@ -193,7 +114,7 @@ def send_preview(self, event):
xS = xhC - hRadius + ijDiff
yS = yhC
if sHole:
- outTmp.write('m67 E3 Q{}\n'.format(self.hSpeed))
+ outTmp.write('m67 E3 Q{}\n'.format(self.parent.holeSpeed))
xlStart = xS + leadIn
ylStart = yhC
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
@@ -217,24 +138,22 @@ def send_preview(self, event):
Torch = False
outTmp.write('m62 p3 (disable torch)\n')
self.over_cut(xS, yS, hRadius - ijDiff, hRadius - ijDiff, outTmp)
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
if sHole:
outTmp.write('M68 E3 Q0 (reset feed rate to 100%)\n')
if not torch:
torch = True
outTmp.write('m65 p3 (enable torch)\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if cRadius == 0:
@@ -243,14 +162,13 @@ def send_preview(self, event):
msg += 'Hole Diameter is required\n\n'
if holes == 0:
msg += '# of Holes are required'
- self.dialog_error(msg)
+ self.parent.dialog_error('BOLT-CIRCLE', msg)
def over_cut(self, lastX, lastY, IJ, radius, outTmp):
- scale = 0.039370 if self.i.find('TRAJ', 'LINEAR_UNITS').lower() == 'inch' else 1.0
try:
oclength = float(self.ocEntry.get_text())
except:
- oclength = 4 * scale
+ oclength = 0
centerX = lastX + IJ
centerY = lastY
cosA = math.cos(oclength / radius)
@@ -261,46 +179,39 @@ def over_cut(self, lastX, lastY, IJ, radius, outTmp):
endY = centerY + radius * ((sinB * cosA) + (cosB * sinA))
outTmp.write('g3 x{0:.6f} y{1:.6f} i{2:.6f} j{3:.6f}\n'.format(endX, endY, IJ, 0))
- def diameter_changed(self,widget):
+ def entry_changed(self, widget):
+ self.parent.entry_changed(widget)
+ # check if small hole valid
try:
rad = float(self.hdEntry.get_text()) / 2
except:
rad = 0
- if rad >= self.sRadius:
+ if rad >= self.parent.holeRadius:
self.overcut.set_active(False)
- self.ocEntry.set_text('')
self.overcut.set_sensitive(False)
self.ocEntry.set_sensitive(False)
else:
self.overcut.set_sensitive(True)
self.ocEntry.set_sensitive(True)
- def do_bolt_circle(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.sRadius = 0.0
- self.hSpeed = 100
- self.W = gtk.Dialog('Bolt Circle',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
- offsetLabel = gtk.Label('Offset')
- offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 0, 1, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 1, 2, 0, 1)
+ def auto_preview(self, widget):
+ if self.dEntry.get_text() and self.hdEntry.get_text() and self.hEntry.get_text():
+ self.bolt_circle_preview('auto')
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
+
+ def bolt_circle_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
ocBox = gtk.HBox()
self.ocBlank = gtk.Label(' ')
ocBox.pack_start(self.ocBlank, expand = True, fill = True)
self.overcut = gtk.CheckButton('Over Cut')
self.overcut.set_sensitive(False)
+ self.overcut.connect('toggled', self.auto_preview)
ocBox.pack_start(self.overcut)
ocLabel = gtk.Label('OC Length')
ocLabel.set_alignment(0.95, 0.5)
@@ -309,115 +220,123 @@ def do_bolt_circle(self, fWizard, tmpDir):
self.ocEntry = gtk.Entry()
self.ocEntry.set_width_chars(5)
self.ocEntry.set_sensitive(False)
+ self.ocEntry.set_text(str(4 * self.parent.scale))
+ self.ocEntry.connect('activate', self.auto_preview)
+ self.ocEntry.connect('changed', self.entry_changed)
ocBox.pack_start(self.ocEntry)
- t.attach(ocBox, 2, 5, 0, 1)
+ self.parent.entries.attach(ocBox, 0, 3, 0, 1)
+ offsetLabel = gtk.Label('Offset')
+ offsetLabel.set_alignment(0.95, 0.5)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
- loLabel = gtk.Label('Lead Out')
- loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
- self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
dLabel = gtk.Label('Diameter')
dLabel.set_alignment(0.95, 0.5)
- dLabel.set_width_chars(10)
- t.attach(dLabel, 0, 1, 6, 7)
+ dLabel.set_width_chars(8)
+ self.parent.entries.attach(dLabel, 0, 1, 6, 7)
self.dEntry = gtk.Entry()
- self.dEntry.set_width_chars(10)
- t.attach(self.dEntry, 1, 2, 6, 7)
- hdLabel = gtk.Label('Hole Diameter')
+ self.dEntry.set_width_chars(8)
+ self.dEntry.connect('activate', self.auto_preview)
+ self.dEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.dEntry, 1, 2, 6, 7)
+ hdLabel = gtk.Label('Hole Dia')
hdLabel.set_alignment(0.95, 0.5)
- hdLabel.set_width_chars(10)
- t.attach(hdLabel, 0, 1, 7, 8)
+ hdLabel.set_width_chars(8)
+ self.parent.entries.attach(hdLabel, 0, 1, 7, 8)
self.hdEntry = gtk.Entry()
- self.hdEntry.set_width_chars(10)
- self.hdEntry.connect('changed', self.diameter_changed)
- t.attach(self.hdEntry, 1, 2, 7, 8)
+ self.hdEntry.set_width_chars(8)
+ self.hdEntry.connect('activate', self.auto_preview)
+ self.hdEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.hdEntry, 1, 2, 7, 8)
hLabel = gtk.Label('# of holes')
hLabel.set_alignment(0.95, 0.5)
- hLabel.set_width_chars(10)
- t.attach(hLabel, 0, 1, 8, 9)
+ hLabel.set_width_chars(8)
+ self.parent.entries.attach(hLabel, 0, 1, 8, 9)
self.hEntry = gtk.Entry()
- self.hEntry.set_width_chars(10)
- t.attach(self.hEntry, 1, 2, 8, 9)
+ self.hEntry.set_width_chars(8)
+ self.hEntry.connect('activate', self.auto_preview)
+ self.hEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.hEntry, 1, 2, 8, 9)
aLabel = gtk.Label('Start Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 9, 10)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 9, 10)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
+ self.aEntry.set_width_chars(8)
self.aEntry.set_text('0')
- t.attach(self.aEntry, 1, 2, 9, 10)
- cALabel = gtk.Label('Circle Angle')
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 9, 10)
+ cALabel = gtk.Label('Circle Ang')
cALabel.set_alignment(0.95, 0.5)
- cALabel.set_width_chars(10)
- t.attach(cALabel, 2, 3, 9, 10)
+ cALabel.set_width_chars(8)
+ self.parent.entries.attach(cALabel, 2, 3, 9, 10)
self.cAEntry = gtk.Entry()
- self.cAEntry.set_width_chars(10)
+ self.cAEntry.set_width_chars(8)
self.cAEntry.set_text('360')
- t.attach(self.cAEntry, 3, 4, 9, 10)
+ self.cAEntry.connect('activate', self.auto_preview)
+ self.cAEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.cAEntry, 3, 4, 9, 10)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 11, 12)
+ preview.connect('pressed', self.bolt_circle_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 11, 12)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 11, 12)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/bolt-circle.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('hole-diameter'):
- self.sRadius = float(line.strip().split('=')[1]) / 2
- elif line.startswith('hole-speed'):
- self.hSpeed = float(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.dEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_circle.py b/configs/by_machine/plasmac/wizards/w_circle.py
index fda9562d4c..1aa72174cb 100644
--- a/configs/by_machine/plasmac/wizards/w_circle.py
+++ b/configs/by_machine/plasmac/wizards/w_circle.py
@@ -29,83 +29,12 @@
import hal
from subprocess import Popen,PIPE
-class circle:
+class circle_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.check_entries()
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def circle_preview(self, event):
if self.dEntry.get_text():
radius = float(self.dEntry.get_text()) / 2
else:
@@ -128,26 +57,25 @@ def send_preview(self, event):
leadOutOffset = math.sin(math.radians(45)) * float(self.loEntry.get_text())
else:
leadOutOffset = 0
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xC = float(self.xSEntry.get_text())
- else:
- xC = float(self.xSEntry.get_text()) + radius
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ xC = float(self.xSEntry.get_text())
else:
- if self.centre.get_active():
- xC = xPos
- else:
- xC = xPos + radius
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yC = float(self.ySEntry.get_text())
+ if self.outside.get_active():
+ xC = float(self.xSEntry.get_text()) + radius + kOffset
else:
- yC = float(self.ySEntry.get_text()) + radius
+ xC = float(self.xSEntry.get_text()) + radius - kOffset
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ yC = float(self.ySEntry.get_text())
else:
- if self.centre.get_active():
- yC = yPos
+ if self.outside.get_active():
+ yC = float(self.ySEntry.get_text()) + radius + kOffset
else:
- yC = yPos + radius
+ yC = float(self.ySEntry.get_text()) + radius - kOffset
xS = xC - ijOffset - ijDiff
yS = yC - ijOffset - ijDiff
right = math.radians(0)
@@ -158,33 +86,28 @@ def send_preview(self, event):
dir = [left, down]
else:
dir = [right, up]
- if radius <= self.sRadius:
+ if radius <= self.parent.holeRadius:
sHole = True
if leadInOffset > radius:
leadInOffset = radius
else:
sHole = False
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if sHole:
- speed = 0.6
- else:
- speed = 1.0
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard circle)\n')
if sHole:
- outTmp.write('M67 E3 Q60 (reduce feed rate to 60%)\n')
+ outTmp.write('M67 E3 Q{} (reduce feed rate to 60%)\n'.format(self.parent.holeSpeed))
if leadInOffset > 0:
if sHole and not self.outside.get_active():
xlStart = xS + leadInOffset * math.cos(angle)
@@ -222,33 +145,30 @@ def send_preview(self, event):
Torch = False
outTmp.write('m62 p3 (disable torch)\n')
self.over_cut(xS, yS, ijOffset + ijDiff, radius, outTmp)
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
if sHole:
outTmp.write('M68 E3 Q0 (reset feed rate to 100%)\n')
if not torch:
torch = True
outTmp.write('m65 p3 (enable torch)\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
- self.dialog_error('Diameter is required')
+ self.parent.dialog_error('CIRCLE', 'Diameter is required')
def over_cut(self, lastX, lastY, IJ, radius, outTmp):
- scale = 0.039370 if self.i.find('TRAJ', 'LINEAR_UNITS').lower() == 'inch' else 1.0
try:
oclength = float(self.ocEntry.get_text())
except:
- oclength = 4 * scale
+ oclength = 0
centerX = lastX + IJ
centerY = lastY + IJ
cosA = math.cos(oclength / radius)
@@ -267,10 +187,9 @@ def over_cut(self, lastX, lastY, IJ, radius, outTmp):
dir = '3'
outTmp.write('g{0} x{1:.6f} y{2:.6f} i{3:.6f} j{3:.6f}\n'.format(dir, endX, endY, IJ))
- def outside_toggled(self,widget):
+ def outside_toggled(self, widget):
if widget.get_active():
self.overcut.set_active(False)
- self.ocEntry.set_text('')
self.overcut.set_sensitive(False)
self.ocEntry.set_sensitive(False)
else:
@@ -278,9 +197,10 @@ def outside_toggled(self,widget):
rad = float(self.dEntry.get_text()) / 2
except:
rad = 0
- if rad <= self.sRadius:
+ if rad <= self.parent.holeRadius:
self.overcut.set_sensitive(True)
self.ocEntry.set_sensitive(True)
+ self.auto_preview('auto')
def overcut_toggled(self,widget):
if widget.get_active():
@@ -292,31 +212,18 @@ def overcut_toggled(self,widget):
rad = float(self.dEntry.get_text()) / 2
except:
rad = 0
- if (self.outside.get_active() and lolen) or not rad or rad > self.sRadius:
+ if (self.outside.get_active() and lolen) or not rad or rad > self.parent.holeRadius:
self.overcut.set_active(False)
+ self.auto_preview('auto')
- def ocentry_changed(self,widget):
- if self.outside.get_active():
- self.ocEntry.set_text('')
-
- def check_entries(self):
- try:
- rad = float(self.dEntry.get_text()) / 2
- except:
- rad = 0
- if rad > self.sRadius:
- self.overcut.set_active(False)
- if rad <= self.sRadius and self.overcut.get_active():
- self.loEntry.set_text('')
-
- def diameter_changed(self,widget):
+ def entry_changed(self, widget):
+ self.parent.entry_changed(widget)
try:
rad = float(self.dEntry.get_text()) / 2
except:
rad = 0
- if rad > self.sRadius:
+ if rad >= self.parent.holeRadius:
self.overcut.set_active(False)
- self.ocEntry.set_text('')
self.overcut.set_sensitive(False)
self.ocEntry.set_sensitive(False)
else:
@@ -324,130 +231,130 @@ def diameter_changed(self,widget):
self.overcut.set_sensitive(True)
self.ocEntry.set_sensitive(True)
- def do_circle(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.sRadius = 0.0
- self.hSpeed = 100
- self.W = gtk.Dialog('Circle',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def auto_preview(self, widget):
+ if self.dEntry.get_text() and float(self.dEntry.get_text()) > 0:
+ self.circle_preview('auto')
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
+
+ def circle_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
self.outside.connect('toggled',self.outside_toggled)
- t.attach(self.outside, 1, 2, 0, 1)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
dLabel = gtk.Label('Diameter')
dLabel.set_alignment(0.95, 0.5)
- dLabel.set_width_chars(10)
- t.attach(dLabel, 0, 1, 6, 7)
+ dLabel.set_width_chars(8)
+ self.parent.entries.attach(dLabel, 0, 1, 6, 7)
self.dEntry = gtk.Entry()
- self.dEntry.set_width_chars(10)
- self.dEntry.connect('changed', self.diameter_changed)
- t.attach(self.dEntry, 1, 2, 6, 7)
+ self.dEntry.set_width_chars(8)
+ self.dEntry.connect('activate', self.auto_preview)
+ self.dEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.dEntry, 1, 2, 6, 7)
ocDesc = gtk.Label('Over Cut')
ocDesc.set_alignment(0.95, 0.5)
- ocDesc.set_width_chars(10)
- t.attach(ocDesc, 0, 1, 7, 8)
+ ocDesc.set_width_chars(8)
+ self.parent.entries.attach(ocDesc, 0, 1, 7, 8)
self.overcut = gtk.CheckButton('')
self.overcut.connect('toggled', self.overcut_toggled)
self.overcut.set_sensitive(False)
- t.attach(self.overcut, 1, 2, 7, 8)
+ self.parent.entries.attach(self.overcut, 1, 2, 7, 8)
ocLabel = gtk.Label('OC Length')
ocLabel.set_alignment(0.95, 0.5)
- ocLabel.set_width_chars(10)
- t.attach(ocLabel, 0, 1, 8, 9)
+ ocLabel.set_width_chars(8)
+ self.parent.entries.attach(ocLabel, 0, 1, 8, 9)
self.ocEntry = gtk.Entry()
- self.ocEntry.set_width_chars(10)
+ self.ocEntry.set_width_chars(8)
self.ocEntry.set_sensitive(False)
- self.ocEntry.connect('changed', self.ocentry_changed)
- t.attach(self.ocEntry, 1, 2, 8, 9)
+ self.ocEntry.set_text(str(4 * self.parent.scale))
+ self.ocEntry.connect('activate', self.auto_preview)
+ self.ocEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.ocEntry, 1, 2, 8, 9)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 9, 10)
+ preview.connect('pressed', self.circle_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 9, 10)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 9, 10)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/circle.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('hole-diameter'):
- self.sRadius = float(line.strip().split('=')[1]) / 2
- elif line.startswith('hole-speed'):
- self.hSpeed = float(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.dEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_cut_recovery.py b/configs/by_machine/plasmac/wizards/w_cut_recovery.py
new file mode 100644
index 0000000000..0f40db27bc
--- /dev/null
+++ b/configs/by_machine/plasmac/wizards/w_cut_recovery.py
@@ -0,0 +1,395 @@
+#!/usr/bin/env python
+
+'''
+w_cut_recovery.py
+
+Copyright (C) 2020 Phillip A Carter
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+'''
+
+import os
+import gtk
+import hal
+import linuxcnc
+import gobject
+import time
+
+class recovery:
+
+ def __init__(self):
+ self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
+ self.s = linuxcnc.stat()
+ self.c = linuxcnc.command()
+ try:
+ # we need this to connect to hal
+ if not hal.component_exists('dummy'):
+ self.h = hal.component('dummy')
+ self.h.ready()
+ except:
+ print('Error connecting to HAL instance')
+ self.exit()
+ # no point in continuing if not paused
+ if not hal.get_value('halui.program.is-paused'):
+ print('Cannot load cut recovery because program is not paused')
+ self.exit()
+ self.clear_offsets()
+ self.xOrig = hal.get_value('axis.x.eoffset-counts')
+ self.yOrig = hal.get_value('axis.y.eoffset-counts')
+ self.zOrig = hal.get_value('axis.z.eoffset-counts')
+ self.oScale = hal.get_value('plasmac.offset-scale')
+ self.xMin = float(self.i.find('AXIS_X', 'MIN_LIMIT'))
+ self.xMax = float(self.i.find('AXIS_X', 'MAX_LIMIT'))
+ self.yMin = float(self.i.find('AXIS_Y', 'MIN_LIMIT'))
+ self.yMax = float(self.i.find('AXIS_Y', 'MAX_LIMIT'))
+ self.zMin = float(self.i.find('AXIS_Z', 'MIN_LIMIT'))
+ self.zMax = float(self.i.find('AXIS_Z', 'MAX_LIMIT'))
+ self.cancelWait = False
+ self.resumeWait = False
+ gobject.timeout_add(200, self.periodic)
+
+ def periodic(self):
+
+ # if we are not paused then we have resumed
+ if self.resumeWait and not hal.get_value('plasmac.x-offset-counts') and not hal.get_value('plasmac.y-offset-counts'):
+ self.resumeWait = False
+
+
+ # hide if required
+ # if hal.get_value('plasmac.state-out') < 23 and \
+ # (hal.get_value('plasmac.cut-recovery') or hal.get_value('plasmac.cut-recovering')):
+ # self.W.hide()
+ # if we are stopped and the offsets are cleared then we should exit
+ if hal.get_value('plasmac:program-is-idle') and not hal.get_value('plasmac.x-offset-counts') and not hal.get_value('plasmac.y-offset-counts'):
+ hal.set_p('plasmac.cut-recovery', '0')
+ self.exit()
+ return False
+ # if we cancelled and the offsets are cleared then cut recovery must be finished
+ if self.cancelWait and not hal.get_value('plasmac.x-offset-counts') and not hal.get_value('plasmac.y-offset-counts'):
+ self.cancelWait = False
+ hal.set_p('plasmac.cut-recovery', '0')
+ self.exit()
+ # if we return to cutting then cut recovery must be finished
+ if hal.get_value('plasmac.state-out') == 11:
+ hal.set_p('plasmac.cut-recovery', '0')
+ self.exit()
+ return False
+ # hide/show the reverse run controls
+ if hal.get_value('plasmac.x-offset-counts') or hal.get_value('plasmac.y-offset-counts'):
+ self.feed_disable()
+ # if self.resumeWait:
+ if hal.get_value('plasmac.state-out') < 23 :
+ self.buttons_disable()
+ else:
+ if not self.cancelWait or not self.resumeWait:
+ self.feed_enable()
+ self.buttons_enable()
+ self.info.set_text('Move\n{}'.format(hal.get_value('plasmac_run.kerf-width-f')))
+ return True
+
+ def dialog_error(self, error):
+ md = gtk.MessageDialog(self.W,
+ gtk.DIALOG_DESTROY_WITH_PARENT,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE,
+ error)
+ md.run()
+ md.destroy()
+
+ def rev_pressed(self, widget):
+ self.paused_motion(-1)
+
+ def rev_released(self, widget):
+ self.paused_motion(0)
+
+ def fwd_pressed(self, widget):
+ self.paused_motion(1)
+
+ def fwd_released(self, widget):
+ self.paused_motion(0)
+
+ def paused_motion(self, direction):
+ speed = float(self.rate.get_value()) * 0.01 * direction
+ hal.set_p('plasmac.paused-motion-speed',str(speed))
+
+ def XminusYplus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.xMin:
+ msg = 'X axis motion would trip X mimimum limit'
+ self.dialog_error(msg)
+ return
+ move1 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.yMax:
+ msg = 'Y axis motion would trip Y maximum limit'
+ self.dialog_error(msg)
+ return
+ move2 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move1)))
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move2)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def Yplus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.yMax:
+ msg = 'Y axis motion would trip Y maximum limit'
+ self.dialog_error(msg)
+ return
+ move = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def XplusYplus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.xMax:
+ msg = 'X axis motion would trip X maximum limit'
+ self.dialog_error(msg)
+ return
+ move1 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.yMax:
+ msg = 'Y axis motion would trip Y maximum limit'
+ self.dialog_error(msg)
+ return
+ move2 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move1)))
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move2)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def Xminus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.xMin:
+ msg = 'X axis motion would trip X mimimum limit'
+ self.dialog_error(msg)
+ return
+ move = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def Xplus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.xMax:
+ msg = 'X axis motion would trip X maximum limit'
+ self.dialog_error(msg)
+ return
+ move = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def XminusYminus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.xMin:
+ msg = 'X axis motion would trip X mimimum limit'
+ self.dialog_error(msg)
+ return
+ move1 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.yMin:
+ msg = 'Y axis motion would trip Y minimum limit'
+ self.dialog_error(msg)
+ return
+ move2 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move1)))
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move2)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def Yminus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.yMin:
+ msg = 'Y axis motion would trip Y minimum limit'
+ self.dialog_error(msg)
+ return
+ move = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def XplusYminus_pressed(self, widget):
+ if hal.get_value('plasmac.axis-x-position') + \
+ hal.get_value('axis.x.eoffset-counts') * self.oScale + \
+ hal.get_value('plasmac_run.kerf-width-f') > self.xMax:
+ msg = 'X axis motion would trip X maximum limit'
+ self.dialog_error(msg)
+ return
+ move1 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * 1)
+ if hal.get_value('plasmac.axis-y-position') + \
+ hal.get_value('axis.y.eoffset-counts') * self.oScale - \
+ hal.get_value('plasmac_run.kerf-width-f') < self.yMin:
+ msg = 'Y axis motion would trip Y minimum limit'
+ self.dialog_error(msg)
+ return
+ move2 = int(hal.get_value('plasmac_run.kerf-width-f') / self.oScale * -1)
+ hal.set_p('plasmac.x-offset', '{}'.format(str(hal.get_value('axis.x.eoffset-counts') + move1)))
+ hal.set_p('plasmac.y-offset', '{}'.format(str(hal.get_value('axis.y.eoffset-counts') + move2)))
+ hal.set_p('plasmac.cut-recovery', '1')
+
+ def zPlus_pressed(self, widget):
+ msg = 'Z axis motion not enable yet'
+ self.dialog_error(msg)
+
+ def zMinus_pressed(self, widget):
+ msg = 'Z axis motion not enable yet'
+ self.dialog_error(msg)
+
+ def resume_pressed(self, widget):
+ self.s.poll()
+ if not self.s.paused:
+ return
+ # self.W.hide()
+ if self.s.task_mode != linuxcnc.MODE_AUTO:
+ msg = 'LinuxCNC is not in auto mode'
+ self.dialog_error(msg)
+ self.exit()
+ self.c.auto(linuxcnc.AUTO_RESUME)
+ while not hal.get_value('halui.program.is-running'):
+ pass
+ self.resumeWait = True
+ self.clear_offsets()
+
+ def cancel_pressed(self, widget):
+ self.W.hide()
+ self.clear_offsets()
+ self.cancelWait = True
+
+ def on_window_delete_event(self, window, event):
+ self.exit()
+
+ def exit(self):
+ if hal.get_value('plasmac.x-offset-counts') or hal.get_value('plasmac.y-offset-counts'):
+ self.clear_offsets()
+ self.W.destroy()
+
+ def clear_offsets(self):
+ hal.set_p('plasmac.x-offset', '0')
+ hal.set_p('plasmac.y-offset', '0')
+
+ def feed_enable(self):
+ self.rev.set_sensitive(True)
+ self.feed.set_sensitive(True)
+ self.fwd.set_sensitive(True)
+
+ def feed_disable(self):
+ self.rev.set_sensitive(False)
+ self.feed.set_sensitive(False)
+ self.fwd.set_sensitive(False)
+
+ def buttons_enable(self):
+ self.XminusYplus.set_sensitive(True)
+ self.Yplus.set_sensitive(True)
+ self.XplusYplus.set_sensitive(True)
+ self.Xminus.set_sensitive(True)
+ self.Xplus.set_sensitive(True)
+ self.XminusYminus.set_sensitive(True)
+ self.Yminus.set_sensitive(True)
+ self.XplusYminus.set_sensitive(True)
+ self.resume.set_sensitive(True)
+ self.cancel.set_sensitive(True)
+
+ def buttons_disable(self):
+ self.XminusYplus.set_sensitive(False)
+ self.Yplus.set_sensitive(False)
+ self.XplusYplus.set_sensitive(False)
+ self.Xminus.set_sensitive(False)
+ self.Xplus.set_sensitive(False)
+ self.XminusYminus.set_sensitive(False)
+ self.Yminus.set_sensitive(False)
+ self.XplusYminus.set_sensitive(False)
+ self.resume.set_sensitive(False)
+ self.cancel.set_sensitive(False)
+
+ def create_widgets(self):
+ self.W = gtk.Window()
+ self.W.set_title('Cut Recovery')
+ self.W.set_position(gtk.WIN_POS_MOUSE)
+ self.W.set_keep_above(True)
+ self.W.connect('delete_event', self.on_window_delete_event)
+ self.T = gtk.Table()
+ self.T.set_homogeneous(True)
+ self.W.add(self.T)
+ self.rev = gtk.Button('Rev')
+ self.rev.connect('pressed', self.rev_pressed)
+ self.rev.connect('released', self.rev_released)
+ self.T.attach(self.rev, 0, 1, 0, 2)
+ self.rate = gtk.Adjustment(value=50, lower=1, upper=100, step_incr=1, page_incr=10, page_size=0)
+ self.rate.emit('value_changed')
+ self.feed = gtk.HScale(adjustment = self.rate)
+ self.feed.set_digits(0)
+ self.T.attach(self.feed, 1, 4, 0, 2)
+ self.fwd = gtk.Button('Fwd')
+ self.fwd.connect('pressed', self.fwd_pressed)
+ self.fwd.connect('released', self.fwd_released)
+ self.T.attach(self.fwd, 4, 5, 0, 2)
+ self.XminusYplus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_left_up.png')
+ self.XminusYplus.add(image)
+ self.XminusYplus.connect('pressed', self.XminusYplus_pressed)
+ self.T.attach(self.XminusYplus, 1, 2, 3, 5)
+ self.Yplus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_up.png')
+ self.Yplus.add(image)
+ self.Yplus.connect('pressed', self.Yplus_pressed)
+ self.T.attach(self.Yplus, 2, 3, 3, 5)
+ self.XplusYplus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_right_up.png')
+ self.XplusYplus.add(image)
+ self.XplusYplus.connect('pressed', self.XplusYplus_pressed)
+ self.T.attach(self.XplusYplus, 3, 4, 3, 5)
+ self.Xminus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_left.png')
+ self.Xminus.add(image)
+ self.Xminus.connect('pressed', self.Xminus_pressed)
+ self.T.attach(self.Xminus, 1, 2, 5, 7)
+ self.info = gtk.Label()
+ self.info.set_justify(gtk.JUSTIFY_CENTER)
+ self.T.attach(self.info, 2, 3, 5, 7)
+ self.Xplus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_right.png')
+ self.Xplus.add(image)
+ self.Xplus.connect('pressed', self.Xplus_pressed)
+ self.T.attach(self.Xplus, 3, 4, 5, 7)
+ self.XminusYminus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_left_down.png')
+ self.XminusYminus.add(image)
+ self.XminusYminus.connect('pressed', self.XminusYminus_pressed)
+ self.T.attach(self.XminusYminus, 1, 2, 7, 9)
+ self.Yminus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_down.png')
+ self.Yminus.add(image)
+ self.Yminus.connect('pressed', self.Yminus_pressed)
+ self.T.attach(self.Yminus, 2, 3, 7, 9)
+ self.XplusYminus = gtk.Button()
+ image = gtk.image_new_from_file('./wizards/images/arrow_right_down.png')
+ self.XplusYminus.add(image)
+ self.XplusYminus.connect('pressed', self.XplusYminus_pressed)
+ self.T.attach(self.XplusYminus, 3, 4, 7, 9)
+ self.resume = gtk.Button('Resume\nCut')
+ for child in self.resume.children():
+ child.set_justify(gtk.JUSTIFY_CENTER)
+ self.resume.connect('pressed', self.resume_pressed)
+ self.T.attach(self.resume, 0, 1, 10, 12)
+ self.cancel = gtk.Button('Cancel')
+ self.cancel.connect('pressed', self.cancel_pressed)
+ self.T.attach(self.cancel, 4, 5, 10, 12)
+ hal.set_p('plasmac_run.preview-tab', '1')
+ self.W.show_all()
diff --git a/configs/by_machine/plasmac/wizards/w_gusset.py b/configs/by_machine/plasmac/wizards/w_gusset.py
index ea5e7b870e..7841a2355e 100644
--- a/configs/by_machine/plasmac/wizards/w_gusset.py
+++ b/configs/by_machine/plasmac/wizards/w_gusset.py
@@ -29,90 +29,17 @@
import hal
from subprocess import Popen,PIPE
-class gusset:
+class gusset_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def gusset_preview(self, event):
+ width = height = 0
if self.wEntry.get_text():
width = float(self.wEntry.get_text())
- else:
- width = xPos
if self.hEntry.get_text():
height = float(self.hEntry.get_text())
- else:
- height = xPos
if width > 0 and height > 0:
right = math.radians(0)
up = math.radians(90)
@@ -121,21 +48,37 @@ def send_preview(self, event):
if self.aEntry.get_text():
angle = math.radians(float(self.aEntry.get_text()))
else:
- angle = 0.0
+ angle = up
if self.rEntry.get_text():
radius = float(self.rEntry.get_text())
+ if radius > height or radius > width:
+ msg = 'Radius must be less than width and height\n\n'
+ self.parent.dialog_error('GUSSET', msg)
+ return
else:
radius = 0.0
- bLength = (width - radius) / 2
- sLength = height - radius
- if self.xSEntry.get_text():
- xS = float(self.xSEntry.get_text()) + (bLength + radius) * math.cos(right)
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.outside.get_active():
+ x0 = float(self.xSEntry.get_text()) + kOffset
+ y0 = float(self.ySEntry.get_text()) + kOffset
else:
- xS = xPos + (bLength + radius) * math.cos(right)
- if self.ySEntry.get_text():
- yS = float(self.ySEntry.get_text()) + (bLength + radius) * math.sin(right)
+ x0 = float(self.xSEntry.get_text()) - kOffset
+ y0 = float(self.ySEntry.get_text()) - kOffset
+ x1 = x0 + width * math.cos(right)
+ y1 = y0 + width * math.sin(right)
+ x2 = x0 + height * math.cos(angle)
+ y2 = y0 + height * math.sin(angle)
+ hypotLength = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
+ if x2 <= x1:
+ hypotAngle = left - math.atan((y2 - y1) / (x1 - x2))
else:
- yS = yPos + (bLength + radius) * math.sin(right)
+ hypotAngle = right - math.atan((y2 - y1) / (x1 - x2))
+ xS = x1 + (hypotLength / 2) * math.cos(hypotAngle)
+ yS = y1 + (hypotLength / 2) * math.sin(hypotAngle)
if self.liEntry.get_text():
leadInOffset = math.sin(math.radians(45)) * float(self.liEntry.get_text())
else:
@@ -145,29 +88,34 @@ def send_preview(self, event):
else:
leadOutOffset = 0
if self.outside.get_active():
- dir = [down, right]
- else:
- dir = [up, left]
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
+ if y2 >= y0:
+ dir = [up, right]
+ else:
+ dir = [down, left]
else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ if y2 >= y0:
+ dir = [down, left]
+ else:
+ dir = [up, right]
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard gusset)\n')
if leadInOffset > 0:
- xlCentre = xS + (leadInOffset * math.cos(dir[0]))
- ylCentre = yS + (leadInOffset * math.sin(dir[0]))
- xlStart = xlCentre + (leadInOffset * math.cos(dir[1]))
- ylStart = ylCentre + (leadInOffset * math.sin(dir[1]))
+ xlCentre = xS + (leadInOffset * math.cos(hypotAngle - dir[0]))
+ ylCentre = yS + (leadInOffset * math.sin(hypotAngle - dir[0]))
+ xlStart = xlCentre + (leadInOffset * math.cos(hypotAngle - dir[1]))
+ ylStart = ylCentre + (leadInOffset * math.sin(hypotAngle - dir[1]))
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
if self.offset.get_active():
outTmp.write('g41.1 d#<_hal[plasmac_run.kerf-width-f]>\n')
@@ -177,185 +125,221 @@ def send_preview(self, event):
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xS, yS))
outTmp.write('m3 $0 s1\n')
if self.outside.get_active():
- x1 = xS + bLength * math.cos(left)
- y1 = yS + bLength * math.sin(left)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
- x2 = xS + (bLength + radius) * math.cos(left)
- y2 = yS + (bLength + radius) * math.sin(left)
if radius > 0:
- x3 = x2 + radius * math.cos(angle)
- y3 = y2 + radius * math.sin(angle)
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x3, y3 , x2 - x1, y2 - y1))
- x4 = x2 + (sLength + radius) * math.cos(angle)
- y4 = y2 + (sLength + radius) * math.sin(angle)
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x4, y4))
- x5 = xS + bLength * math.cos(right)
- y5 = yS + bLength * math.sin(right)
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x5, y5))
+ x3 = x0 + radius
+ y3 = y0
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x3, y3))
+ x4 = x0 + radius * math.cos(angle)
+ y4 = y0 + radius * math.sin(angle)
+ if self.rButton.child.get_text().startswith('Radius'):
+ if y2 >= y0:
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x4, y4 , x0 - x3, y0 - y3))
+ else:
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x4, y4 , x0 - x3, y0 - y3))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x4, y4))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x0, y0))
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
else:
- x1 = xS + bLength * math.cos(right)
- y1 = yS + bLength * math.sin(right)
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
- x4 = xS + (bLength + radius) * math.cos(left)
- y4 = yS + (bLength + radius) * math.sin(left)
- x2 = x4 + (sLength + radius) * math.cos(angle)
- y2 = y4 + (sLength + radius) * math.sin(angle)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
- x3 = x4 + radius * math.cos(angle)
- y3 = y4 + radius * math.sin(angle)
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x3, y3))
if radius > 0:
- x5 = x4 + radius * math.cos(right)
- y5 = y4 + radius * math.sin(right)
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x5, y5 , x4 - x3, y4 - y3))
+ x3 = x0 + radius
+ y3 = y0
+ x4 = x0 + radius * math.cos(angle)
+ y4 = y0 + radius * math.sin(angle)
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x4, y4))
+ if self.rButton.child.get_text().startswith('Radius'):
+ if y2 >= y0:
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x3, y3 , x0 - x4, y0 - y4))
+ else:
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(x3, y3 , x0 - x4, y0 - y4))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x3, y3))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x0, y0))
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
if leadOutOffset > 0:
if self.outside.get_active():
- dir = [down, left]
+ if y2 >= y0:
+ dir = [up, left]
+ else:
+ dir = [down, right]
else:
- dir = [up, right]
- xlCentre = xS + (leadOutOffset * math.cos(dir[0]))
- ylCentre = yS + (leadOutOffset * math.sin(dir[0]))
- xlEnd = xlCentre + (leadOutOffset * math.cos(dir[1]))
- ylEnd = ylCentre + (leadOutOffset * math.sin(dir[1]))
+ if y2 >= y0:
+ dir = [down, right]
+ else:
+ dir = [up, left]
+ xlCentre = xS + (leadOutOffset * math.cos(hypotAngle - dir[0]))
+ ylCentre = yS + (leadOutOffset * math.sin(hypotAngle - dir[0]))
+ xlEnd = xlCentre + (leadOutOffset * math.cos(hypotAngle - dir[1]))
+ ylEnd = ylCentre + (leadOutOffset * math.sin(hypotAngle - dir[1]))
outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xS, ylCentre - yS))
if self.offset.get_active():
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if width <= 0:
msg += 'A positive width value is required\n\n'
if height <= 0:
msg += 'A positive height value is required\n\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('GUSSET', msg)
+
+ def rad_button_pressed(self, button):
+ if button.child.get_text()[:3] == 'Rad':
+ button.child.set_text('Chamfer')
+ else:
+ button.child.set_text('Radius')
+ self.auto_preview('local')
+
+ def auto_preview(self, widget):
+ if self.wEntry.get_text() and self.hEntry.get_text():
+ self.gusset_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), None)
- def do_gusset(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Gusset',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def gusset_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
wLabel = gtk.Label('Width')
wLabel.set_alignment(0.95, 0.5)
- wLabel.set_width_chars(10)
- t.attach(wLabel, 0, 1, 5, 6)
+ wLabel.set_width_chars(8)
+ self.parent.entries.attach(wLabel, 0, 1, 5, 6)
self.wEntry = gtk.Entry()
- self.wEntry.set_width_chars(10)
- t.attach(self.wEntry, 1, 2, 5, 6)
+ self.wEntry.set_width_chars(8)
+ self.wEntry.connect('activate', self.auto_preview)
+ self.wEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.wEntry, 1, 2, 5, 6)
hLabel = gtk.Label('Height')
hLabel.set_alignment(0.95, 0.5)
- hLabel.set_width_chars(10)
- t.attach(hLabel, 0, 1, 6, 7)
+ hLabel.set_width_chars(8)
+ self.parent.entries.attach(hLabel, 0, 1, 6, 7)
self.hEntry = gtk.Entry()
- self.hEntry.set_width_chars(10)
- t.attach(self.hEntry, 1, 2, 6, 7)
- rLabel = gtk.Label('Radius')
- rLabel.set_alignment(0.95, 0.5)
- rLabel.set_width_chars(10)
- t.attach(rLabel, 0, 1, 7, 8)
+ self.hEntry.set_width_chars(8)
+ self.hEntry.connect('activate', self.auto_preview)
+ self.hEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.hEntry, 1, 2, 6, 7)
+ self.rButton = gtk.Button('Radius')
+ self.rButton.connect('pressed', self.rad_button_pressed)
+ self.parent.entries.attach(self.rButton, 0, 1, 7, 8)
self.rEntry = gtk.Entry()
- self.rEntry.set_width_chars(10)
+ self.rEntry.set_width_chars(8)
self.rEntry.set_text('0')
- t.attach(self.rEntry, 1, 2, 7, 8)
+ self.rEntry.connect('activate', self.auto_preview)
+ self.rEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.rEntry, 1, 2, 7, 8)
aLabel = gtk.Label('Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 8, 9)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 8, 9)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
+ self.aEntry.set_width_chars(8)
self.aEntry.set_text('90')
- t.attach(self.aEntry, 1, 2, 8, 9)
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed',self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 8, 9)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 10, 11)
+ preview.connect('pressed', self.gusset_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 10, 11)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 10, 11)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/gusset.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.wEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_line.py b/configs/by_machine/plasmac/wizards/w_line.py
index b63000aac6..ef26998122 100644
--- a/configs/by_machine/plasmac/wizards/w_line.py
+++ b/configs/by_machine/plasmac/wizards/w_line.py
@@ -30,82 +30,13 @@
import numpy
from subprocess import Popen,PIPE
-class line:
+class line_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
-
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- os.remove(self.fTmp)
- os.remove(self.fNgc)
- self.add.set_sensitive(False)
- self.cont.set_sensitive(False)
self.add_segment = 0
- self.line_type_changed(self.lType)
+ self.gcodeSave = ''
+ self.savedX = ''
+ self.savedY = ''
def continue_shape(self, event):
self.xS = self.xE
@@ -115,63 +46,70 @@ def continue_shape(self, event):
self.add_segment = 1
self.line_type_changed(self.lType)
- def send_preview(self, event):
+ def line_preview(self, event):
if self.add_segment == 0:
try:
+ if not self.entry1.get_text():
+ self.entry1.set_text('{:0.3f}'.format(self.parent.xOrigin))
self.xS = float(self.entry1.get_text())
+ if not self.entry2.get_text():
+ self.entry2.set_text('{:0.3f}'.format(self.parent.yOrigin))
self.yS = float(self.entry2.get_text())
except:
msg = 'Invalid entry detected\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('LINE', msg)
return
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard line)\n')
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(self.xS, self.yS))
outTmp.write('m3 $0 s1\n')
try:
if self.lType.get_active_text() == 'line point to point':
+ self.savedX = self.entry4.get_text()
+ self.savedY = self.entry5.get_text()
self.do_line_point_to_point(float(self.entry4.get_text()), float(self.entry5.get_text()))
elif self.lType.get_active_text() == 'line by angle':
if not float(self.entry4.get_text()):
raise Exception('length cannot be 0')
self.do_line_by_angle(float(self.entry4.get_text()), float(self.entry5.get_text()))
- elif self.lType.get_active_text() == 'arc 3 points':
+ elif self.lType.get_active_text() == 'arc 3p':
+ self.savedX = self.entry7.get_text()
+ self.savedY = self.entry8.get_text()
self.do_arc_3_points(float(self.entry4.get_text()), float(self.entry5.get_text()), \
float(self.entry7.get_text()), float(self.entry8.get_text()))
- elif self.lType.get_active_text() == 'arc 2 points & radius':
+ elif self.lType.get_active_text() == 'arc 2p & radius':
+ self.savedX = self.entry4.get_text()
+ self.savedY = self.entry5.get_text()
self.do_arc_2_points_radius(float(self.entry4.get_text()), float(self.entry5.get_text()), \
float(self.entry7.get_text()))
- elif self.lType.get_active_text() == 'arc by angle & radius':
+ elif self.lType.get_active_text() == 'arc angle & radius':
self.do_arc_by_angle_radius(float(self.entry4.get_text()), float(self.entry5.get_text()), \
float(self.entry7.get_text()))
except Exception as e:
msg = 'Invalid new entry detected\n\n'
msg += str(e)
- self.dialog_error(msg)
+ self.parent.dialog_error('LINE', msg)
outNgc.close()
outTmp.close()
return
elif self.add_segment >= 1:
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- inTmp = open(self.fNgc, 'r')
- outTmp = open(self.fTmp, 'w')
+ inTmp = open(self.parent.fNgc, 'r')
+ outTmp = open(self.parent.fTmp, 'w')
while(1):
line = inTmp.readline()
- if line == self.gcodeLine:
+ if not line or line == self.gcodeLine:
break
else:
outTmp.write(line)
@@ -184,48 +122,52 @@ def send_preview(self, event):
else:
outTmp.write(line)
inTmp.close()
- shutil.copyfile(self.fTmp, self.fNgc)
- outNgc = open(self.fNgc, 'w')
+ shutil.copyfile(self.parent.fTmp, self.parent.fNgc)
+ outNgc = open(self.parent.fNgc, 'w')
try:
if self.lType.get_active_text() == 'line point to point':
+ self.savedX = self.entry1.get_text()
+ self.savedY = self.entry2.get_text()
self.do_line_point_to_point(float(self.entry1.get_text()), float(self.entry2.get_text()))
elif self.lType.get_active_text() == 'line by angle':
if not float(self.entry1.get_text()):
raise Exception('Length cannot be 0')
self.do_line_by_angle(float(self.entry1.get_text()), float(self.entry2.get_text()))
- elif self.lType.get_active_text() == 'arc 3 points':
+ elif self.lType.get_active_text() == 'arc 3p':
+ self.savedX = self.entry4.get_text()
+ self.savedY = self.entry5.get_text()
self.do_arc_3_points(float(self.entry1.get_text()), float(self.entry2.get_text()), \
float(self.entry4.get_text()), float(self.entry5.get_text()))
- elif self.lType.get_active_text() == 'arc 2 points & radius':
+ elif self.lType.get_active_text() == 'arc 2p & radius':
+ self.savedX = self.entry1.get_text()
+ self.savedY = self.entry2.get_text()
self.do_arc_2_points_radius(float(self.entry1.get_text()), float(self.entry2.get_text()), \
float(self.entry4.get_text()))
- elif self.lType.get_active_text() == 'arc by angle & radius':
+ elif self.lType.get_active_text() == 'arc angle & radius':
self.do_arc_by_angle_radius(float(self.entry1.get_text()), float(self.entry2.get_text()), \
float(self.entry4.get_text()))
except Exception as e:
msg = 'Invalid add entry detected\n\n'
msg += str(e)
- self.dialog_error(msg)
+ self.parent.dialog_error('LINE', msg)
outNgc.close()
outTmp.close()
return
outTmp.write(self.gcodeLine)
outTmp.write('M5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
self.cont.set_sensitive(True)
if self.add_segment == 1:
self.add_segment = 2
- hal.set_p('plasmac_run.preview-tab', '1')
def do_line_point_to_point(self, inX, inY):
self.xE = inX
@@ -237,6 +179,8 @@ def do_line_by_angle(self, inL, inA):
self.xE = self.xS + (inL * math.cos(angle))
self.yE = self.yS + (inL * math.sin(angle))
self.gcodeLine = 'g1 x{:.6f} y{:.6f}\n'.format(self.xE, self.yE)
+ self.savedX = str(self.xE)
+ self.savedY = str(self.yE)
def do_arc_3_points(self, inX1, inY1, inXE, inYE):
self.xE = inXE
@@ -269,12 +213,14 @@ def do_arc_2_points_radius(self, inXE, inYE, radius):
yLineCentre = (self.yS + self.yE) / 2
xArcCentre = xLineCentre + length * math.cos(angle + dir)
yArcCentre = yLineCentre + length * math.sin(angle + dir)
- self.gcodeLine = 'g{} x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(arcType, self.xE, self.yE, xArcCentre - self.xS, yArcCentre - self.yS)
+ self.gcodeLine = ('g{} x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(arcType, self.xE, self.yE, xArcCentre - self.xS, yArcCentre - self.yS))
def do_arc_by_angle_radius(self, inL, inA, inR):
angle = math.radians(inA)
xE = self.xS + (inL * math.cos(angle))
yE = self.yS + (inL * math.sin(angle))
+ self.savedX = str(xE)
+ self.savedY = str(yE)
self.do_arc_2_points_radius(xE, yE, inR)
def line_type_changed(self, widget):
@@ -282,21 +228,36 @@ def line_type_changed(self, widget):
self.set_line_point_to_point()
elif widget.get_active_text() == 'line by angle':
self.set_line_by_angle()
- elif widget.get_active_text() == 'arc 3 points':
+ elif widget.get_active_text() == 'arc 3p':
self.set_arc_3_points()
- elif widget.get_active_text() == 'arc 2 points & radius':
+ elif widget.get_active_text() == 'arc 2p & radius':
self.set_arc_2_points_radius()
- elif widget.get_active_text() == 'arc by angle & radius':
+ elif widget.get_active_text() == 'arc angle & radius':
self.set_arc_by_angle_radius()
-
+
+ def auto_preview(self, widget):
+ if ((self.add_segment == 0) and \
+ ((self.lType.get_active_text() == 'line point to point' and self.entry4.get_text() and self.entry5.get_text()) or \
+ (self.lType.get_active_text() == 'line by angle' and self.entry4.get_text() and self.entry5.get_text()) or \
+ (self.lType.get_active_text() == 'arc 3p' and self.entry4.get_text() and self.entry5.get_text() and self.entry7.get_text() and self.entry8.get_text()) or \
+ (self.lType.get_active_text() == 'arc 2p & radius' and self.entry4.get_text() and self.entry5.get_text() and self.entry7.get_text()) or \
+ (self.lType.get_active_text() == 'arc angle & radius' and self.entry4.get_text() and self.entry5.get_text() and self.entry7.get_text()))) or \
+ ((self.add_segment >= 1 and self.entry1.get_text() and self.entry2.get_text()) and \
+ ((self.lType.get_active_text() == 'line point to point') or \
+ (self.lType.get_active_text() == 'line by angle') or \
+ (self.lType.get_active_text() == 'arc 3p' and self.entry4.get_text() and self.entry5.get_text()) or \
+ (self.lType.get_active_text() == 'arc 2p & radius' and self.entry4.get_text()) or \
+ (self.lType.get_active_text() == 'arc angle & radius' and self.entry4.get_text()))):
+ self.line_preview('auto')
+
def set_line_point_to_point(self):
self.image.set_from_pixbuf(self.pixLinePoint)
if self.add_segment > 0:
self.entry1.grab_focus()
self.label1.set_text('End X')
- self.entry1.set_text('')
+ self.entry1.set_text('{:0.3f}'.format(float(self.savedX)))
self.label2.set_text('End Y')
- self.entry2.set_text('')
+ self.entry2.set_text('{:0.3f}'.format(float(self.savedY)))
self.label3.hide()
self.entry3.hide()
self.label4.hide()
@@ -312,11 +273,10 @@ def set_line_point_to_point(self):
self.g3Arc.hide()
self.g2Arc.hide()
else:
- self.entry4.grab_focus()
self.label1.set_text('Start X')
- self.entry1.set_text(self.xOrigin)
+ self.entry1.set_text('{:0.3f}'.format(0))
self.label2.set_text('Start Y')
- self.entry2.set_text(self.yOrigin)
+ self.entry2.set_text('{:0.3f}'.format(0))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('End X')
@@ -335,6 +295,7 @@ def set_line_point_to_point(self):
self.entry8.hide()
self.g3Arc.hide()
self.g2Arc.hide()
+ self.entry4.grab_focus()
def set_line_by_angle(self):
self.image.set_from_pixbuf(self.pixLineAngle)
@@ -361,9 +322,9 @@ def set_line_by_angle(self):
else:
self.entry4.grab_focus()
self.label1.set_text('Start X')
- self.entry1.set_text(self.xOrigin)
+ self.entry1.set_text('{:0.3f}'.format(0))
self.label2.set_text('Start Y')
- self.entry2.set_text(self.yOrigin)
+ self.entry2.set_text('{:0.3f}'.format(0))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('Length')
@@ -388,18 +349,18 @@ def set_arc_3_points(self):
if self.add_segment > 0:
self.entry1.grab_focus()
self.label1.set_text('Next X')
- self.entry1.set_text('')
+ self.entry1.set_text('{:0.3f}'.format(float(self.savedX)))
self.label2.set_text('Next Y')
- self.entry2.set_text('')
+ self.entry2.set_text('{:0.3f}'.format(float(self.savedY)))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('End X')
self.label4.show()
- self.entry4.set_text('')
+ self.entry4.set_text('{:0.3f}'.format(float(self.savedX)))
self.entry4.show()
self.label5.set_text('End Y')
self.label5.show()
- self.entry5.set_text('')
+ self.entry5.set_text('{:0.3f}'.format(float(self.savedY)))
self.entry5.show()
self.label6.hide()
self.entry6.hide()
@@ -412,9 +373,9 @@ def set_arc_3_points(self):
else:
self.entry4.grab_focus()
self.label1.set_text('Start X')
- self.entry1.set_text(self.xOrigin)
+ self.entry1.set_text('{:0.3f}'.format(0))
self.label2.set_text('Start Y')
- self.entry2.set_text(self.yOrigin)
+ self.entry2.set_text('{:0.3f}'.format(0))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('Next X')
@@ -443,9 +404,9 @@ def set_arc_2_points_radius(self):
if self.add_segment > 0:
self.entry1.grab_focus()
self.label1.set_text('End X')
- self.entry1.set_text('')
+ self.entry1.set_text('{:0.3f}'.format(float(self.savedX)))
self.label2.set_text('End Y')
- self.entry2.set_text('')
+ self.entry2.set_text('{:0.3f}'.format(float(self.savedY)))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('Radius')
@@ -460,18 +421,18 @@ def set_arc_2_points_radius(self):
self.entry7.hide()
self.label8.hide()
self.entry7.hide()
- self.t.remove(self.g3Arc)
- self.t.remove(self.g2Arc)
- self.t.attach(self.g3Arc, 0, 1, 5, 6)
- self.t.attach(self.g2Arc, 1, 2, 5, 6)
+ self.parent.entries.remove(self.g3Arc)
+ self.parent.entries.remove(self.g2Arc)
+ self.parent.entries.attach(self.g3Arc, 0, 1, 5, 6)
+ self.parent.entries.attach(self.g2Arc, 1, 2, 5, 6)
self.g3Arc.show()
self.g2Arc.show()
else:
self.entry4.grab_focus()
self.label1.set_text('Start X')
- self.entry1.set_text(self.xOrigin)
+ self.entry1.set_text('{:0.3f}'.format(0))
self.label2.set_text('Start Y')
- self.entry2.set_text(self.yOrigin)
+ self.entry2.set_text('{:0.3f}'.format(0))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('End X')
@@ -490,10 +451,10 @@ def set_arc_2_points_radius(self):
self.entry7.show()
self.label8.hide()
self.entry8.hide()
- self.t.remove(self.g3Arc)
- self.t.remove(self.g2Arc)
- self.t.attach(self.g3Arc, 0, 1, 8, 9)
- self.t.attach(self.g2Arc, 1, 2, 8, 9)
+ self.parent.entries.remove(self.g3Arc)
+ self.parent.entries.remove(self.g2Arc)
+ self.parent.entries.attach(self.g3Arc, 0, 1, 8, 9)
+ self.parent.entries.attach(self.g2Arc, 1, 2, 8, 9)
self.g3Arc.show()
self.g2Arc.show()
@@ -519,18 +480,18 @@ def set_arc_by_angle_radius(self):
self.entry7.hide()
self.label8.hide()
self.entry7.hide()
- self.t.remove(self.g3Arc)
- self.t.remove(self.g2Arc)
- self.t.attach(self.g3Arc, 0, 1, 5, 6)
- self.t.attach(self.g2Arc, 1, 2, 5, 6)
+ self.parent.entries.remove(self.g3Arc)
+ self.parent.entries.remove(self.g2Arc)
+ self.parent.entries.attach(self.g3Arc, 0, 1, 5, 6)
+ self.parent.entries.attach(self.g2Arc, 1, 2, 5, 6)
self.g3Arc.show()
self.g2Arc.show()
else:
self.entry4.grab_focus()
self.label1.set_text('Start X')
- self.entry1.set_text(self.xOrigin)
+ self.entry1.set_text('{:0.3f}'.format(0))
self.label2.set_text('Start Y')
- self.entry2.set_text(self.yOrigin)
+ self.entry2.set_text('{:0.3f}'.format(0))
self.label3.hide()
self.entry3.hide()
self.label4.set_text('Length')
@@ -549,108 +510,128 @@ def set_arc_by_angle_radius(self):
self.entry7.show()
self.label8.hide()
self.entry8.hide()
- self.t.remove(self.g3Arc)
- self.t.remove(self.g2Arc)
- self.t.attach(self.g3Arc, 0, 1, 8, 9)
- self.t.attach(self.g2Arc, 1, 2, 8, 9)
+ self.parent.entries.remove(self.g3Arc)
+ self.parent.entries.remove(self.g2Arc)
+ self.parent.entries.attach(self.g3Arc, 0, 1, 8, 9)
+ self.parent.entries.attach(self.g2Arc, 1, 2, 8, 9)
self.g3Arc.show()
self.g2Arc.show()
- def do_line(self, fWizard, tmpDir):
+ def undo_shape(self, event):
+ self.parent.undo_shape(None, self.add)
self.add_segment = 0
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Lines and Arcs',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- self.t = gtk.Table(1, 1, True)
- self.t.set_row_spacings(6)
- self.W.vbox.add(self.t)
+ self.line_type_changed(self.lType)
+ if len(self.gcodeSave):
+ self.gcodeLine = self.gcodeSave
+
+ def add_shape_to_file(self, event):
+ self.gcodeSave = self.gcodeLine
+ self.parent.add_shape_to_file(self.add, None, None, None)
+ self.add_segment = 0
+ self.line_type_changed(self.lType)
+
+ def line_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace - 2)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
self.lType = gtk.combo_box_new_text()
self.lType.append_text('line point to point')
self.lType.append_text('line by angle')
- self.lType.append_text('arc 3 points')
- self.lType.append_text('arc 2 points & radius')
- self.lType.append_text('arc by angle & radius')
- self.lType.set_active(0)
+ self.lType.append_text('arc 3p')
+ self.lType.append_text('arc 2p & radius')
+ self.lType.append_text('arc angle & radius')
self.lType.connect('changed', self.line_type_changed)
- self.t.attach(self.lType, 0, 2, 0, 1)
+ self.parent.entries.attach(self.lType, 0, 3, 0, 1)
self.label1 = gtk.Label()
self.label1.set_alignment(0.95, 0.5)
- self.label1.set_width_chars(10)
- self.t.attach(self.label1, 0, 1, 1, 2)
+ self.label1.set_width_chars(8)
+ self.parent.entries.attach(self.label1, 0, 1, 1, 2)
self.entry1 = gtk.Entry()
- self.entry1.set_width_chars(10)
- self.t.attach(self.entry1, 1, 2, 1, 2)
+ self.entry1.set_width_chars(8)
+ self.entry1.connect('activate', self.auto_preview)
+ self.entry1.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry1, 1, 2, 1, 2)
self.label2 = gtk.Label()
self.label2.set_alignment(0.95, 0.5)
- self.label2.set_width_chars(10)
- self.t.attach(self.label2, 0, 1, 2, 3)
+ self.label2.set_width_chars(8)
+ self.parent.entries.attach(self.label2, 0, 1, 2, 3)
self.entry2 = gtk.Entry()
- self.entry2.set_width_chars(10)
- self.t.attach(self.entry2, 1, 2, 2, 3)
+ self.entry2.set_width_chars(8)
+ self.entry2.connect('activate', self.auto_preview)
+ self.entry2.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry2, 1, 2, 2, 3)
self.label3 = gtk.Label()
self.label3.set_alignment(0.95, 0.5)
- self.label3.set_width_chars(10)
- self.t.attach(self.label3, 0, 1, 3, 4)
+ self.label3.set_width_chars(8)
+ self.parent.entries.attach(self.label3, 0, 1, 3, 4)
self.entry3 = gtk.Entry()
- self.entry3.set_width_chars(10)
- self.t.attach(self.entry3, 1, 2, 3, 4)
+ self.entry3.set_width_chars(8)
+ self.entry3.connect('activate', self.auto_preview)
+ self.entry3.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry3, 1, 2, 3, 4)
self.label4 = gtk.Label()
self.label4.set_alignment(0.95, 0.5)
- self.label4.set_width_chars(10)
- self.t.attach(self.label4, 0, 1, 4, 5)
+ self.label4.set_width_chars(8)
+ self.parent.entries.attach(self.label4, 0, 1, 4, 5)
self.entry4 = gtk.Entry()
- self.entry4.set_width_chars(10)
- self.t.attach(self.entry4, 1, 2, 4, 5)
+ self.entry4.set_width_chars(8)
+ self.entry4.connect('activate', self.auto_preview)
+ self.entry4.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry4, 1, 2, 4, 5)
self.label5 = gtk.Label()
self.label5.set_alignment(0.95, 0.5)
- self.label5.set_width_chars(10)
- self.t.attach(self.label5, 0, 1, 5, 6)
+ self.label5.set_width_chars(8)
+ self.parent.entries.attach(self.label5, 0, 1, 5, 6)
self.entry5 = gtk.Entry()
- self.entry5.set_width_chars(10)
- self.t.attach(self.entry5, 1, 2, 5, 6)
+ self.entry5.set_width_chars(8)
+ self.entry5.connect('activate', self.auto_preview)
+ self.entry5.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry5, 1, 2, 5, 6)
self.label6 = gtk.Label()
self.label6.set_alignment(0.95, 0.5)
- self.label6.set_width_chars(10)
- self.t.attach(self.label6, 0, 1, 6, 7)
+ self.label6.set_width_chars(8)
+ self.parent.entries.attach(self.label6, 0, 1, 6, 7)
self.entry6 = gtk.Entry()
- self.entry6.set_width_chars(10)
- self.t.attach(self.entry6, 1, 2, 6, 7)
+ self.entry6.set_width_chars(8)
+ self.entry6.connect('activate', self.auto_preview)
+ self.entry6.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry6, 1, 2, 6, 7)
self.label7 = gtk.Label()
self.label7.set_alignment(0.95, 0.5)
- self.label7.set_width_chars(10)
- self.t.attach(self.label7, 0, 1, 7, 8)
+ self.label7.set_width_chars(8)
+ self.parent.entries.attach(self.label7, 0, 1, 7, 8)
self.entry7 = gtk.Entry()
- self.entry7.set_width_chars(10)
- self.t.attach(self.entry7, 1, 2, 7, 8)
+ self.entry7.set_width_chars(8)
+ self.entry7.connect('activate', self.auto_preview)
+ self.entry7.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry7, 1, 2, 7, 8)
self.label8 = gtk.Label()
self.label8.set_alignment(0.95, 0.5)
- self.label8.set_width_chars(10)
- self.t.attach(self.label8, 0, 1, 8, 9)
+ self.label8.set_width_chars(8)
+ self.parent.entries.attach(self.label8, 0, 1, 8, 9)
self.entry8 = gtk.Entry()
- self.entry8.set_width_chars(10)
- self.t.attach(self.entry8, 1, 2, 8, 9)
+ self.entry8.set_width_chars(8)
+ self.entry8.connect('activate', self.auto_preview)
+ self.entry8.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.entry8, 1, 2, 8, 9)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- self.t.attach(preview, 0, 1, 10, 11)
+ preview.connect('pressed', self.line_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.cont = gtk.Button('Continue')
self.cont.set_sensitive(False)
self.cont.connect('pressed', self.continue_shape)
- self.t.attach(self.cont, 1, 2, 10, 11)
+ self.parent.entries.attach(self.cont, 1, 2, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- self.t.attach(self.add, 2, 3, 10, 11)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- self.t.attach(end, 4, 5, 10, 11)
- self.g2Arc = gtk.RadioButton(None, 'Clockwise')
- self.g3Arc = gtk.RadioButton(self.g2Arc, 'Counter Clock')
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.undo_shape)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
+ self.g2Arc = gtk.RadioButton(None, 'Clock')
+ self.g2Arc.connect('toggled', self.auto_preview)
+ self.g3Arc = gtk.RadioButton(self.g2Arc, 'Counter')
self.pixLinePoint = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/line-point.png',
width=240,
@@ -672,17 +653,18 @@ def do_line(self, fWizard, tmpDir):
width=240,
height=240)
self.image = gtk.Image()
- self.t.attach(self.image, 2, 5, 0, 8)
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- self.s.poll()
- self.xOrigin = str(self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0])
- self.yOrigin = str(self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1])
- self.set_line_point_to_point()
- response = self.W.run()
+ self.parent.entries.attach(self.image, 2, 5, 1, 9)
+ self.parent.undo_shape(None, self.add)
+ self.lType.set_active(0)
+ self.parent.W.show_all()
+ self.entry4.grab_focus()
+ self.label3.hide()
+ self.entry3.hide()
+ self.label6.hide()
+ self.entry6.hide()
+ self.label7.hide()
+ self.entry7.hide()
+ self.label8.hide()
+ self.entry8.hide()
+ self.g3Arc.hide()
+ self.g2Arc.hide()
diff --git a/configs/by_machine/plasmac/wizards/w_main.py b/configs/by_machine/plasmac/wizards/w_main.py
new file mode 100644
index 0000000000..67cbd3eb21
--- /dev/null
+++ b/configs/by_machine/plasmac/wizards/w_main.py
@@ -0,0 +1,473 @@
+#!/usr/bin/env python
+
+'''
+w_main.py
+
+Copyright (C) 2020 Phillip A Carter
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+'''
+
+import os
+import gtk
+import time
+import math
+import linuxcnc
+import shutil
+import hal
+import gobject
+from subprocess import Popen,PIPE
+import gremlin
+
+import w_array
+import w_line
+import w_circle
+import w_triangle
+import w_rectangle
+import w_polygon
+import w_bolt_circle
+import w_slot
+import w_star
+import w_gusset
+import w_rotate
+import w_sector
+import w_settings
+
+class main_wiz:
+
+ def __init__(self):
+ self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
+ self.c = linuxcnc.command()
+ self.s = linuxcnc.stat()
+ self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
+ self.savePath = self.i.find('DISPLAYaqw', 'PROGRAM_PREFIX') or \
+ '{}/linuxcnc/nc_files'.format(os.path.expanduser("~"))
+ self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ self.scale = 0.03937000787402 if self.i.find('TRAJ', 'LINEAR_UNITS').lower() == 'inch' else 1.0
+ self.preview = preview(self.i)
+ self.preview.program_alpha = True
+ self.preview.set_cone_basesize(0.1)
+ self.preview.mouse_btn_mode = 6
+ if self.scale == 1.0:
+ self.preview.metric_units = True
+ else:
+ self.preview.metric_units = False
+ self.rowSpace = 2
+ self.tmpDir = ('/tmp/plasmac_wizards')
+ if not os.path.isdir(self.tmpDir):
+ os.mkdir(self.tmpDir)
+ self.fTmp = '{}/temp.ngc'.format(self.tmpDir)
+ self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
+ self.fNgcBkp = '{}/backup.ngc'.format(self.tmpDir)
+ gobject.timeout_add(100, self.periodic)
+
+ def periodic(self):
+ # exit if linuxcnc not running
+ if not hal.component_exists('plasmac_run'):
+ self.parent.wizardButton.set_sensitive(True)
+ self.W.destroy()
+ return True
+
+ def dialog_error(self, wizard, error):
+ md = gtk.MessageDialog(self.W,
+ gtk.DIALOG_DESTROY_WITH_PARENT,
+ gtk.MESSAGE_ERROR,
+ gtk.BUTTONS_CLOSE,
+ '{} WIZARD ERROR\n\n{}'.format(wizard, error))
+ md.set_keep_above(True)
+ md.set_position(gtk.WIN_POS_CENTER_ALWAYS)
+ md.run()
+ md.destroy()
+
+ def entry_changed(self, widget):
+ if widget.get_text():
+ if widget.get_text()[len(widget.get_text()) - 1] not in '-.0123456789':
+ widget.set_text(widget.get_text()[:len(widget.get_text()) - 1])
+
+ def undo_shape(self, event, button):
+ if os.path.exists(self.fNgcBkp):
+ shutil.copyfile(self.fNgcBkp, self.fNgc)
+ self.preview.load(self.fNgc)
+ if button:
+ button.set_sensitive(False)
+
+ def add_shape_to_file(self, button, xS, yS, oS):
+ shutil.copyfile(self.fNgc, self.fNgcBkp)
+ if xS is not None:
+ self.xSaved = xS
+ if yS is not None:
+ self.ySaved = yS
+ if oS is not None:
+ self.oSaved = oS
+ if button:
+ button.set_sensitive(False)
+
+ def enable_buttons(self):
+ self.new.set_sensitive(True)
+ self.save.set_sensitive(True)
+ self.settings.set_sensitive(True)
+ self.send.set_sensitive(True)
+
+ def disable_buttons(self):
+ self.new.set_sensitive(False)
+ self.save.set_sensitive(False)
+ self.settings.set_sensitive(False)
+ self.send.set_sensitive(False)
+
+ def on_new_clicked(self, widget):
+ outNgc = open(self.fNgc, 'w')
+ outNgc.write('(new wizard)\nM2\n')
+ outNgc.close()
+ shutil.copyfile(self.fNgc, self.fTmp)
+ shutil.copyfile(self.fNgc, self.fNgcBkp)
+ # if self.gui == 'axis':
+ # Popen('axis-remote {}'.format(self.fNgc), stdout = PIPE, shell = True)
+ # elif self.gui == 'gmoccapy':
+ # self.c.program_open(self.fNgc)
+ # time.sleep(0.1)
+ self.preview.load(self.fNgc)
+
+ def on_save_clicked(self, widget):
+ with open(self.fNgc) as inFile:
+ for line in inFile:
+ if '(new wizard)' in line:
+ self.dialog_error('SAVE', 'The empty file: {}\n\ncannot be saved'.format(os.path.basename(self.fNgc)))
+ return
+ dlg = gtk.FileChooserDialog('Save..', None, gtk.FILE_CHOOSER_ACTION_SAVE,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+ filter = gtk.FileFilter()
+ filter.set_name('NGC files')
+ filter.add_pattern("*.ngc")
+ dlg.add_filter(filter)
+ dlg.set_do_overwrite_confirmation(True)
+ dlg.set_current_folder(self.savePath)
+ dlg.set_current_name("shape.ngc")
+ # toggle = gtk.CheckButton('Open file read-only')
+ # dlg.set_extra_widget(toggle)
+ response = dlg.run()
+ fileName = dlg.get_filename()
+ dlg.destroy()
+ if response == gtk.RESPONSE_OK:
+ shutil.copyfile(self.fNgc, fileName)
+
+ def on_settings_clicked(self, widget):
+ self.disable_buttons()
+ reload(w_settings)
+ settings = w_settings.settings_wiz()
+ settings.settings_show(self)
+
+ def on_line_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_line)
+ line = w_line.line_wiz()
+ line.line_show(self)
+
+ def on_circle_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_circle)
+ circle = w_circle.circle_wiz()
+ circle.circle_show(self)
+
+ def on_triangle_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_triangle)
+ triangle = w_triangle.triangle_wiz()
+ triangle.triangle_show(self)
+
+ def on_rectangle_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_rectangle)
+ rectangle = w_rectangle.rectangle_wiz()
+ rectangle.rectangle_show(self)
+
+ def on_polygon_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_polygon)
+ polygon = w_polygon.polygon_wiz()
+ polygon.polygon_show(self)
+
+ def on_bolt_circle_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_bolt_circle)
+ bolt_circle = w_bolt_circle.bolt_circle_wiz()
+ bolt_circle.bolt_circle_show(self)
+
+ def on_slot_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_slot)
+ slot = w_slot.slot_wiz()
+ slot.slot_show(self)
+
+ def on_star_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_star)
+ star = w_star.star_wiz()
+ star.star_show(self)
+
+ def on_gusset_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_gusset)
+ gusset = w_gusset.gusset_wiz()
+ gusset.gusset_show(self)
+
+ def on_sector_clicked(self, widget):
+ self.enable_buttons()
+ reload(w_sector)
+ sector = w_sector.sector_wiz()
+ sector.sector_show(self)
+
+ def on_rotate_clicked(self, widget):
+ self.enable_buttons()
+ with open(self.fNgc) as inFile:
+ for line in inFile:
+ if '(new wizard)' in line:
+ self.dialog_error('ROTATE', 'The empty file: {}\n\ncannot be rotated'.format(os.path.basename(self.fNgc)))
+ return
+ reload(w_rotate)
+ rotate = w_rotate.rotate_wiz()
+ rotate.rotate_show(self)
+
+ def on_array_clicked(self, widget):
+ self.enable_buttons()
+ with open(self.fNgc) as inFile:
+ for line in inFile:
+ if '(new wizard)' in line:
+ self.dialog_error('ARRAY', 'The empty file: {}\n\ncannot be arrayed'.format(os.path.basename(self.fNgc)))
+ return
+ elif '(wizard' in line:
+ self.arrayMode = 'wizard'
+ break
+ elif '# 800:
+ self.rowSpace = 8
+ elif h > 700:
+ self.rowSpace = 4
+ else:
+ self.rowSpace = 2
+ self.W.resize(w, h)
+# print('0 resized window to: {}'.format(self.W.get_size()))
+
+ def main_show(self, parent):
+ self.parent = parent
+ self.W = gtk.Dialog('PlasmaC Conversational',
+ None,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ buttons = None)
+ self.W.set_keep_above(True)
+ self.W.set_position(gtk.WIN_POS_CENTER)
+ self.W.set_default_size(890, 663)
+ self.W.connect('delete_event', self.on_delete_event)
+ top = gtk.HBox(True, 2)
+ bottom = gtk.HBox()
+ self.W.vbox.pack_start(top, expand = False, fill = True)
+ self.W.vbox.pack_start(bottom, expand = True, fill = True)
+ self.left = gtk.VBox()
+ right = gtk.Frame()
+ bottom.pack_start(self.left, expand = False, fill = True)
+ bottom.pack_start(right, expand = True, fill = True)
+ self.line = gtk.Button()
+ self.line.connect('clicked', self.on_line_clicked)
+ self.circle = gtk.Button()
+ self.circle.connect('clicked', self.on_circle_clicked)
+ self.triangle = gtk.Button()
+ self.triangle.connect('clicked', self.on_triangle_clicked)
+ self.rectangle = gtk.Button()
+ self.rectangle.connect('clicked', self.on_rectangle_clicked)
+ self.polygon = gtk.Button()
+ self.polygon.connect('clicked', self.on_polygon_clicked)
+ self.bolt_circle = gtk.Button()
+ self.bolt_circle.connect('clicked', self.on_bolt_circle_clicked)
+ self.slot = gtk.Button()
+ self.slot.connect('clicked', self.on_slot_clicked)
+ self.star = gtk.Button()
+ self.star.connect('clicked', self.on_star_clicked)
+ self.gusset = gtk.Button()
+ self.gusset.connect('clicked', self.on_gusset_clicked)
+ self.sector = gtk.Button()
+ self.sector.connect('clicked', self.on_sector_clicked)
+ self.rotate = gtk.Button()
+ self.rotate.connect('clicked', self.on_rotate_clicked)
+ self.array = gtk.Button()
+ self.array.connect('clicked', self.on_array_clicked)
+ buttons = [self.line, self.circle, self.triangle, self.rectangle, \
+ self.polygon, self.bolt_circle, self.slot, self.star, \
+ self.gusset, self.sector, self.rotate, self.array]
+ bunames = ['line', 'circle', 'triangle', 'rectangle', 'polygon', \
+ 'bolt_circle', 'slot', 'star', 'gusset', 'sector', \
+ 'rotate', 'array']
+ for wizard in bunames:
+ if bunames.index(wizard) <= 11:
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
+ filename='./wizards/images/{}-thumb.png'.format(wizard),
+ width=60,
+ height=60)
+ image = gtk.Image()
+ image.set_from_pixbuf(pixbuf)
+ buttons[bunames.index(wizard)].set_image(image)
+ top.add(buttons[bunames.index(wizard)])
+ right.add(self.preview)
+ self.entries = gtk.Table(1, 1, True)
+ self.entries.set_row_spacings(self.rowSpace)
+ self.left.pack_start(self.entries, expand = False, fill = True)
+ spaceFrame = gtk.Frame()
+ spaceFrame.set_shadow_type(gtk.SHADOW_NONE)
+ self.left.pack_start(spaceFrame, expand = True, fill = True)
+ self.button_frame = gtk.Frame()
+ self.button_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ self.left.pack_start(self.button_frame, expand = False, fill = True)
+ self.button_box = gtk.Table(1, 5, True)
+ self.button_frame.add(self.button_box)
+ bLabel1 = gtk.Label()
+ bLabel1.set_width_chars(9)
+ self.button_box.attach(bLabel1, 0, 1, 0, 1)
+ self.new = gtk.Button('New')
+ self.new.connect('clicked', self.on_new_clicked)
+ self.button_box.attach(self.new, 0, 1, 0, 1)
+ self.save = gtk.Button('Save')
+ self.save.connect('clicked', self.on_save_clicked)
+ self.button_box.attach(self.save, 1, 2, 0, 1)
+ self.settings = gtk.Button('Settings')
+ self.settings.connect('clicked', self.on_settings_clicked)
+ self.button_box.attach(self.settings, 2, 3, 0, 1)
+ self.quit = gtk.Button('Quit')
+ self.quit.connect('clicked', self.on_quit_clicked)
+ self.button_box.attach(self.quit, 3, 4, 0, 1)
+ self.send = gtk.Button('Send')
+ self.send.connect('clicked', self.on_send_clicked)
+ self.button_box.attach(self.send, 4, 5, 0, 1)
+ if self.scale == 1:
+ unitCode = ['21', '0.25', 32]
+ else:
+ unitCode = ['20', '0.004', 1.26]
+ self.preamble = 'G{} G64P{} G40 G49 G80 G90 G92.1 G94 G97'.format(unitCode[0], unitCode[1])
+ self.postamble = 'G{} G64P{} G40 G49 G80 G90 G92.1 G94 G97'.format(unitCode[0], unitCode[1])
+ self.origin = False
+ self.leadin = 0
+ self.leadout = 0
+ self.holeRadius = unitCode[2] / 2.0
+ self.holeSpeed = 60.0
+ wWidth = 890
+ wHeight = 582
+ gSize = 0
+ fSize = '9'
+ if os.path.exists(self.configFile):
+ f_in = open(self.configFile, 'r')
+ try:
+ for line in f_in:
+ if line.startswith('preamble'):
+ self.preamble = line.strip().split('=')[1]
+ elif line.startswith('postamble'):
+ self.postamble = line.strip().split('=')[1]
+ elif line.startswith('origin') and line.strip().split('=')[1] == 'True':
+ self.origin = True
+ elif line.startswith('lead-in'):
+ self.leadIn = line.strip().split('=')[1]
+ elif line.startswith('lead-out'):
+ self.leadOut = line.strip().split('=')[1]
+ elif line.startswith('hole-diameter'):
+ self.holeRadius = float(line.strip().split('=')[1]) / 2
+ elif line.startswith('hole-speed'):
+ self.holeSpeed = float(line.strip().split('=')[1])
+ elif line.startswith('window-width'):
+ wWidth = int(line.strip().split('=')[1])
+ elif line.startswith('window-height'):
+ wHeight = int(line.strip().split('=')[1])
+ elif line.startswith('grid-size'):
+ # glcanon has a reversed scale to just about everything else... :(
+ gSize = float(line.strip().split('=')[1]) * (0.03937000787402 / self.scale)
+ elif line.startswith('font-size'):
+ fSize = line.strip().split('=')[1]
+ except:
+ print('Using default wizard settings')
+ if wWidth and wHeight:
+ self.resize_window(wWidth, wHeight)
+ if gSize:
+ self.preview.grid_size = gSize
+ gtk.settings_get_default().set_property('gtk-font-name', 'sans {}'.format(fSize))
+ self.W.show_all()
+ self.s.poll()
+ if self.s.file:
+ try:
+ shutil.copyfile(self.s.file, self.fNgc)
+ shutil.copyfile(self.s.file, self.fNgcBkp)
+ self.preview.load(self.fNgc)
+ except:
+ self.on_new_clicked(None)
+ else:
+ self.on_new_clicked(None)
+ #hal.set_p('plasmac_run.preview-tab', '1')
+ self.s.poll()
+ self.xOrigin = float(self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0])
+ self.yOrigin = float(self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1])
+ self.xSaved = '0.000'
+ self.ySaved = '0.000'
+ self.oSaved = self.origin
+ self.on_line_clicked(None)
+ response = self.W.run()
+
+ @staticmethod
+ def gcode_error(errMsg):
+ print('G-CODE ERROR: {}'.format(errMsg))
+
+class preview(gremlin.Gremlin):
+ def __init__(self, inifile):
+ gremlin.Gremlin.__init__(self, inifile)
+
+ def dro_format(self,s,spd,dtg,limit,homed,positions,axisdtg,g5x_offset,g92_offset,tlo_offset):
+ return limit, homed, [''], ['']
+
+ def report_gcode_error(self, result, seq, filename):
+ import gcode
+ error_str = gcode.strerror(result)
+ error = 'G-Code error in {} near line {}: {}'.format(os.path.basename(filename), str(seq), gcode.strerror(result))
+ main_wiz.gcode_error(error)
diff --git a/configs/by_machine/plasmac/wizards/w_polygon.py b/configs/by_machine/plasmac/wizards/w_polygon.py
index 8d0bf10c63..e3efe7d41f 100644
--- a/configs/by_machine/plasmac/wizards/w_polygon.py
+++ b/configs/by_machine/plasmac/wizards/w_polygon.py
@@ -29,82 +29,12 @@
import hal
from subprocess import Popen,PIPE
-class polygon:
+class polygon_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def polygon_preview(self, event):
if self.sEntry.get_text():
sides = int(self.sEntry.get_text())
else:
@@ -121,26 +51,18 @@ def send_preview(self, event):
radius = 0
if sides >= 3 and radius > 0:
ijOffset = radius * math.sin(math.radians(45))
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xS = float(self.xSEntry.get_text())
- else:
- xS = float(self.xSEntry.get_text()) + radius * math.cos(math.radians(0))
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ xS = float(self.xSEntry.get_text())
else:
- if self.centre.get_active():
- xS = xPos
- else:
- xS = xPos + radius * math.cos(math.radians(0))
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yS = float(self.ySEntry.get_text())
- else:
- yS = float(self.ySEntry.get_text()) + radius * math.sin(math.radians(90))
+ xS = float(self.xSEntry.get_text()) + radius * math.cos(math.radians(0))
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ yS = float(self.ySEntry.get_text())
else:
- if self.centre.get_active():
- yS = yPos
- else:
- yS = yPos + radius * math.sin(math.radians(90))
+ yS = float(self.ySEntry.get_text()) + radius * math.sin(math.radians(90))
if self.liEntry.get_text():
leadInOffset = float(self.liEntry.get_text()) / (2 * math.pi * (90.0 / 360))
else:
@@ -170,20 +92,19 @@ def send_preview(self, event):
dir = [down, right]
else:
dir = [up, left]
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard polygon {})\n'.format(sides))
if leadInOffset > 0:
xlCentre = xCentre + (leadInOffset * math.cos(angle + dir[0]))
@@ -216,154 +137,172 @@ def send_preview(self, event):
ylEnd = ylCentre + (leadOutOffset * math.sin(angle + dir[1]))
outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xCentre, ylCentre - yCentre))
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if sides < 3:
msg += 'Sides must be 3 or more\n\n'
if radius <= 0:
msg += 'Diameter is required'
- self.dialog_error(msg)
+ self.parent.dialog_error('POLYGON', msg)
def mode_changed(self, widget):
if self.mCombo.get_active() == 2:
self.dLabel.set_text('Side Length')
else:
self.dLabel.set_text('Diameter')
+ self.auto_preview('auto')
+
+ def auto_preview(self, widget):
+ if self.sEntry.get_text() and self.dEntry.get_text():
+ self.polygon_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
- def do_polygon(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Polygon',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def polygon_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace - 2)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cLabel = gtk.Label('Cut Type')
cLabel.set_alignment(0.95, 0.5)
- cLabel.set_width_chars(10)
- t.attach(cLabel, 0, 1, 0, 1)
+ cLabel.set_width_chars(8)
+ self.parent.entries.attach(cLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
oLabel = gtk.Label('Offset')
oLabel.set_alignment(0.95, 0.5)
- oLabel.set_width_chars(10)
- t.attach(oLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ oLabel.set_width_chars(8)
+ self.parent.entries.attach(oLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
sLabel = gtk.Label('Sides')
sLabel.set_alignment(0.95, 0.5)
- sLabel.set_width_chars(10)
- t.attach(sLabel, 0, 1, 6, 7)
+ sLabel.set_width_chars(8)
+ self.parent.entries.attach(sLabel, 0, 1, 6, 7)
self.sEntry = gtk.Entry()
- self.sEntry.set_width_chars(10)
- t.attach(self.sEntry, 1, 2, 6, 7)
+ self.sEntry.set_width_chars(8)
+ self.sEntry.connect('activate', self.auto_preview)
+ self.sEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.sEntry, 1, 2, 6, 7)
self.mCombo = gtk.combo_box_new_text()
- self.mCombo.append_text('Circumscribed Diameter')
- self.mCombo.append_text('Inscribed Diameter')
+ self.mCombo.append_text('Circumscribed')
+ self.mCombo.append_text('Inscribed')
self.mCombo.append_text('Side Length')
self.mCombo.set_active(0)
self.mCombo.connect('changed', self.mode_changed)
- t.attach(self.mCombo, 0, 2, 7, 8)
+ self.parent.entries.attach(self.mCombo, 0, 2, 7, 8)
self.dLabel = gtk.Label('Diameter')
self.dLabel.set_alignment(0.95, 0.5)
- self.dLabel.set_width_chars(10)
- t.attach(self.dLabel, 0, 1, 8, 9)
+ self.dLabel.set_width_chars(8)
+ self.parent.entries.attach(self.dLabel, 0, 1, 8, 9)
self.dEntry = gtk.Entry()
- self.dEntry.set_width_chars(10)
- t.attach(self.dEntry, 1, 2, 8, 9)
+ self.dEntry.set_width_chars(8)
+ self.dEntry.connect('activate', self.auto_preview)
+ self.dEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.dEntry, 1, 2, 8, 9)
aLabel = gtk.Label('Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 9, 10)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 9, 10)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
+ self.aEntry.set_width_chars(8)
self.aEntry.set_text('0')
- t.attach(self.aEntry, 1, 2, 9, 10)
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 9, 10)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 11, 12)
+ preview.connect('pressed', self.polygon_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 11, 12)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 11, 12)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/polygon.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.sEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_rectangle.py b/configs/by_machine/plasmac/wizards/w_rectangle.py
index 1caf49c656..b12c7bd780 100644
--- a/configs/by_machine/plasmac/wizards/w_rectangle.py
+++ b/configs/by_machine/plasmac/wizards/w_rectangle.py
@@ -29,82 +29,12 @@
import hal
from subprocess import Popen,PIPE
-class rectangle:
+class rectangle_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def rectangle_preview(self, event):
xLB = yLR = xLT = yLL = 0
if self.xLEntry.get_text() and self.yLEntry.get_text():
try:
@@ -112,11 +42,11 @@ def send_preview(self, event):
msg = 'A positive X Length is required\n\n'
msg += 'and\n\n'
msg += 'A positive Y Length is required\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
except:
msg = 'Invalid X Length or Y Length\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
if self.r1Entry.get_text():
radius1 = float(self.r1Entry.get_text())
@@ -137,22 +67,22 @@ def send_preview(self, event):
if radius1 + radius2 > float(self.xLEntry.get_text()):
msg = 'Radius 1 plus Radius 2 ({})\n\n'.format(radius1 + radius2)
msg += 'can not be greater than {}\n'.format(float(self.xLEntry.get_text()))
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
if radius1 + radius3 > float(self.yLEntry.get_text()):
msg = 'Radius 1 plus Radius 3 ({})\n\n'.format(radius1 + radius3)
msg += 'can not be greater than {}\n'.format(float(self.yLEntry.get_text()))
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
if radius2 + radius4 > float(self.yLEntry.get_text()):
msg = 'Radius 2 plus Radius 4 ({})\n\n'.format(radius2 + radius4)
msg += 'can not be greater than {}\n'.format(float(self.yLEntry.get_text()))
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
if radius3 > float(self.xLEntry.get_text()) / 2 or radius4 > float(self.xLEntry.get_text()) / 2:
msg = 'Neither Radius 3 nor Radius 4\n\n'
msg += 'can be greater than {}\n'.format(float(self.xLEntry.get_text()) / 2)
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
return
if self.xLEntry.get_text():
xLB = float(self.xLEntry.get_text()) - (radius3 + radius4)
@@ -163,6 +93,8 @@ def send_preview(self, event):
yLL = float(self.yLEntry.get_text()) - (radius1 + radius3)
yC = float(self.yLEntry.get_text()) / 2
if xLB >= 0 and yLR >= 0 and xLT >= 0 and yLL >= 0:
+ blLength = math.sqrt(xC ** 2 + (yC * 2) ** 2)
+ blAngle = math.atan((yC * 2) / xC)
if self.angEntry.get_text():
angle = math.radians(float(self.angEntry.get_text()))
else:
@@ -179,327 +111,449 @@ def send_preview(self, event):
up = math.radians(90)
left = math.radians(180)
down = math.radians(270)
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xS = float(self.xSEntry.get_text()) + yC * math.cos(angle + down)
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ if self.outside.get_active():
+ xS = float(self.xSEntry.get_text()) + ((yC - radius2) * math.cos(angle + up)) + (xC * math.cos(angle + right))
else:
- xS = float(self.xSEntry.get_text()) + xC * math.cos(angle + right)
+ xS = float(self.xSEntry.get_text()) + yC * math.cos(angle + up)
else:
- if self.centre.get_active():
- xS = xPos + yC * math.cos(angle + down)
+ if self.outside.get_active():
+ xS = (float(self.xSEntry.get_text()) + kOffset) + (float(self.xLEntry.get_text()) * math.cos(angle + up)) + (float(self.xLEntry.get_text()) * math.cos(angle + right))
else:
- xS = xPos + xC * math.cos(angle + right)
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yS = float(self.ySEntry.get_text()) + yC * math.sin(angle + down)
+ xS = (float(self.xSEntry.get_text()) - kOffset) + (blLength * math.cos(angle + right + blAngle))
+
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ if self.outside.get_active():
+ yS = float(self.ySEntry.get_text()) + (yC - radius2 * math.sin(angle + up)) + (xC * math.sin(angle + right))
else:
- yS = float(self.ySEntry.get_text()) + xC * math.sin(angle + right)
+ yS = float(self.ySEntry.get_text()) + yC * math.sin(angle + up)
else:
- if self.centre.get_active():
- yS = yPos + yC * math.sin(angle + down)
+ if self.outside.get_active():
+ yS = (float(self.ySEntry.get_text()) + kOffset) + ((float(self.yLEntry.get_text()) - radius2) * math.sin(angle + up)) + (float(self.xLEntry.get_text()) * math.sin(angle + right))
else:
- yS = yPos + xC * math.sin(angle + right)
- if self.outside.get_active():
- dir = [down, right, left]
- else:
- dir = [up, left, right]
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ yS = (float(self.ySEntry.get_text()) - kOffset) + (blLength * math.sin(angle + right + blAngle))
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard rectangle)\n')
- if leadInOffset > 0:
- xlCentre = xS + (leadInOffset * math.cos(angle + dir[0]))
- ylCentre = yS + (leadInOffset * math.sin(angle + dir[0]))
- xlStart = xlCentre + (leadInOffset * math.cos(angle + dir[1]))
- ylStart = ylCentre + (leadInOffset * math.sin(angle + dir[1]))
- outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
- if self.offset.get_active():
- outTmp.write('g41.1 d#<_hal[plasmac_run.kerf-width-f]>\n')
- outTmp.write('m3 $0 s1\n')
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xS, yS , xlCentre - xlStart, ylCentre - ylStart))
- else:
- outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xS, yS))
- outTmp.write('m3 $0 s1\n')
if self.outside.get_active():
- x1 = xS + (float(self.xLEntry.get_text()) / 2 - radius3) * math.cos(angle + dir[2])
- y1 = yS + (float(self.xLEntry.get_text()) / 2 - radius3) * math.sin(angle + dir[2])
+ if leadInOffset > 0:
+ xlCentre = xS + (leadInOffset * math.cos(angle + right))
+ ylCentre = yS + (leadInOffset * math.sin(angle + right))
+ xlStart = xlCentre + (leadInOffset * math.cos(angle + up))
+ ylStart = ylCentre + (leadInOffset * math.sin(angle + up))
+ outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
+ if self.offset.get_active():
+ outTmp.write('g41.1 d#<_hal[plasmac_run.kerf-width-f]>\n')
+ outTmp.write('m3 $0 s1\n')
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xS, yS , xlCentre - xlStart, ylCentre - ylStart))
+ else:
+ outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xS, yS))
+ outTmp.write('m3 $0 s1\n')
+ x1 = xS + yLR * math.cos(angle + down)
+ y1 = yS + yLR * math.sin(angle + down)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
- if radius3 > 0:
- xrCentre = x1 + (radius3 * math.cos(angle + up))
- yrCentre = y1 + (radius3 * math.sin(angle + up))
- xrEnd = xrCentre + (radius3 * math.cos(angle + left))
- yrEnd = yrCentre + (radius3 * math.sin(angle + left))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
- x2 = xrEnd + yLL * math.cos(angle + up)
- y2 = yrEnd + yLL * math.sin(angle + up)
+ if radius4 > 0:
+ if self.r4Button.child.get_text().startswith('iRadius'):
+ xrCentre = x1 + (radius4 * math.cos(angle + down))
+ yrCentre = y1 + (radius4 * math.sin(angle + down))
+ xrEnd = xrCentre + (radius4 * math.cos(angle + left))
+ yrEnd = yrCentre + (radius4 * math.sin(angle + left))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ else:
+ xrCentre = x1 + (radius4 * math.cos(angle + left))
+ yrCentre = y1 + (radius4 * math.sin(angle + left))
+ xrEnd = xrCentre + (radius4 * math.cos(angle + down))
+ yrEnd = yrCentre + (radius4 * math.sin(angle + down))
+ if self.r4Button.child.get_text().startswith('Radius'):
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x2 = xrEnd + xLB * math.cos(angle + left)
+ y2 = yrEnd + xLB * math.sin(angle + left)
else:
- x2 = x1 + yLL * math.cos(angle + up)
- y2 = y1 + yLL * math.sin(angle + up)
+ x2 = x1 + xLB * math.cos(angle + left)
+ y2 = y1 + xLB * math.sin(angle + left)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
- if radius1 > 0:
- xrCentre = x2 + (radius1 * math.cos(angle + right))
- yrCentre = y2 + (radius1 * math.sin(angle + right))
- xrEnd = xrCentre + (radius1 * math.cos(angle + up))
- yrEnd = yrCentre + (radius1 * math.sin(angle + up))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
- x3 = xrEnd + xLT * math.cos(angle + right)
- y3 = yrEnd + xLT * math.sin(angle + right)
+ if radius3 > 0:
+ if self.r3Button.child.get_text().startswith('iRadius'):
+ xrCentre = x2 + (radius3 * math.cos(angle + left))
+ yrCentre = y2 + (radius3 * math.sin(angle + left))
+ xrEnd = xrCentre + (radius3 * math.cos(angle + up))
+ yrEnd = yrCentre + (radius3 * math.sin(angle + up))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
+ else:
+ xrCentre = x2 + (radius3 * math.cos(angle + up))
+ yrCentre = y2 + (radius3 * math.sin(angle + up))
+ xrEnd = xrCentre + (radius3 * math.cos(angle + left))
+ yrEnd = yrCentre + (radius3 * math.sin(angle + left))
+ if self.r3Button.child.get_text().startswith('Radius'):
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x3 = xrEnd + yLL * math.cos(angle + up)
+ y3 = yrEnd + yLL * math.sin(angle + up)
else:
- x3 = x2 + xLT * math.cos(angle + right)
- y3 = y2 + xLT * math.sin(angle + right)
+ x3 = x2 + yLL * math.cos(angle + up)
+ y3 = y2 + yLL * math.sin(angle + up)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x3, y3))
- if radius2 > 0:
- xrCentre = x3 + (radius2 * math.cos(angle + down))
- yrCentre = y3 + (radius2 * math.sin(angle + down))
- xrEnd = xrCentre + (radius2 * math.cos(angle + right))
- yrEnd = yrCentre + (radius2 * math.sin(angle + right))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
- x4 = xrEnd + yLR * math.cos(angle + down)
- y4 = yrEnd + yLR * math.sin(angle + down)
+ if radius1 > 0:
+ if self.r1Button.child.get_text().startswith('iRadius'):
+ xrCentre = x3 + (radius1 * math.cos(angle + up))
+ yrCentre = y3 + (radius1 * math.sin(angle + up))
+ xrEnd = xrCentre + (radius1 * math.cos(angle + right))
+ yrEnd = yrCentre + (radius1 * math.sin(angle + right))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
+ else:
+ xrCentre = x3 + (radius1 * math.cos(angle + right))
+ yrCentre = y3 + (radius1 * math.sin(angle + right))
+ xrEnd = xrCentre + (radius1 * math.cos(angle + up))
+ yrEnd = yrCentre + (radius1 * math.sin(angle + up))
+ if self.r1Button.child.get_text().startswith('Radius'):
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x4 = xrEnd + xLT * math.cos(angle + right)
+ y4 = yrEnd + xLT * math.sin(angle + right)
else:
- x4 = x3 + yLR * math.cos(angle + down)
- y4 = y3 + yLR * math.sin(angle + down)
+ x4 = x3 + xLT * math.cos(angle + right)
+ y4 = y3 + xLT * math.sin(angle + right)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x4, y4))
- if radius4 > 0:
- xrCentre = x4 + (radius4 * math.cos(angle + left))
- yrCentre = y4 + (radius4 * math.sin(angle + left))
- xrEnd = xrCentre + (radius4 * math.cos(angle + down))
- yrEnd = yrCentre + (radius4 * math.sin(angle + down))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ if radius2 > 0:
+ if self.r2Button.child.get_text().startswith('iRadius'):
+ xrCentre = x4 + (radius2 * math.cos(angle + right))
+ yrCentre = y4 + (radius2 * math.sin(angle + right))
+ xrEnd = xrCentre + (radius2 * math.cos(angle + down))
+ yrEnd = yrCentre + (radius2 * math.sin(angle + down))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ else:
+ xrCentre = x4 + (radius2 * math.cos(angle + down))
+ yrCentre = y4 + (radius2 * math.sin(angle + down))
+ xrEnd = xrCentre + (radius2 * math.cos(angle + right))
+ yrEnd = yrCentre + (radius2 * math.sin(angle + right))
+ if self.r2Button.child.get_text().startswith('Radius'):
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
else:
- x1 = xS + (float(self.xLEntry.get_text()) / 2 - radius4) * math.cos(angle + dir[2])
- y1 = yS + (float(self.xLEntry.get_text()) / 2 - radius4) * math.sin(angle + dir[2])
+ if leadInOffset > 0:
+ xlCentre = xS + (leadInOffset * math.cos(angle + down))
+ ylCentre = yS + (leadInOffset * math.sin(angle + down))
+ xlStart = xlCentre + (leadInOffset * math.cos(angle + right))
+ ylStart = ylCentre + (leadInOffset * math.sin(angle + right))
+ outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
+ if self.offset.get_active():
+ outTmp.write('g41.1 d#<_hal[plasmac_run.kerf-width-f]>\n')
+ outTmp.write('m3 $0 s1\n')
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xS, yS , xlCentre - xlStart, ylCentre - ylStart))
+ else:
+ outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xS, yS))
+ outTmp.write('m3 $0 s1\n')
+ x1 = xS + (xLT / 2) * math.cos(angle + left)
+ y1 = yS + (xLT / 2) * math.sin(angle + left)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
- if radius4 > 0:
- xrCentre = x1 + (radius4 * math.cos(angle + up))
- yrCentre = y1 + (radius4 * math.sin(angle + up))
- xrEnd = xrCentre + (radius4 * math.cos(angle + right))
- yrEnd = yrCentre + (radius4 * math.sin(angle + right))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
- x2 = xrEnd + yLR * math.cos(angle + up)
- y2 = yrEnd + yLR * math.sin(angle + up)
+ if radius1 > 0:
+ if self.r1Button.child.get_text().startswith('iRadius'):
+ xrCentre = x1 + (radius1 * math.cos(angle + left))
+ yrCentre = y1 + (radius1 * math.sin(angle + left))
+ xrEnd = xrCentre + (radius1 * math.cos(angle + down))
+ yrEnd = yrCentre + (radius1 * math.sin(angle + down))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ else:
+ xrCentre = x1 + (radius1 * math.cos(angle + down))
+ yrCentre = y1 + (radius1 * math.sin(angle + down))
+ xrEnd = xrCentre + (radius1 * math.cos(angle + left))
+ yrEnd = yrCentre + (radius1 * math.sin(angle + left))
+ if self.r1Button.child.get_text().startswith('Radius'):
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x2 = xrEnd + yLL * math.cos(angle + down)
+ y2 = yrEnd + yLL * math.sin(angle + down)
else:
- x2 = x1 + yLR * math.cos(angle + up)
- y2 = y1 + yLR * math.sin(angle + up)
+ x2 = x1 + yLL * math.cos(angle + down)
+ y2 = y1 + yLL * math.sin(angle + down)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
- if radius2 > 0:
- xrCentre = x2 + (radius2 * math.cos(angle + left))
- yrCentre = y2 + (radius2 * math.sin(angle + left))
- xrEnd = xrCentre + (radius2 * math.cos(angle + up))
- yrEnd = yrCentre + (radius2 * math.sin(angle + up))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
- x3 = xrEnd + xLT * math.cos(angle + left)
- y3 = yrEnd + xLT * math.sin(angle + left)
+ if radius3 > 0:
+ if self.r3Button.child.get_text().startswith('iRadius'):
+ xrCentre = x3 + (radius3 * math.cos(angle + down))
+ yrCentre = y3 + (radius3 * math.sin(angle + down))
+ xrEnd = xrCentre + (radius3 * math.cos(angle + right))
+ yrEnd = yrCentre + (radius3 * math.sin(angle + right))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
+ else:
+ xrCentre = x2 + (radius3 * math.cos(angle + right))
+ yrCentre = y2 + (radius3 * math.sin(angle + right))
+ xrEnd = xrCentre + (radius3 * math.cos(angle + down))
+ yrEnd = yrCentre + (radius3 * math.sin(angle + down))
+ if self.r3Button.child.get_text().startswith('Radius'):
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x3 = xrEnd + xLB * math.cos(angle + right)
+ y3 = yrEnd + xLB * math.sin(angle + right)
else:
- x3 = x2 + xLT * math.cos(angle + left)
- y3 = y2 + xLT * math.sin(angle + left)
+ x3 = x2 + xLB * math.cos(angle + right)
+ y3 = y2 + xLB * math.sin(angle + right)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x3, y3))
- if radius1 > 0:
- xrCentre = x3 + (radius1 * math.cos(angle + down))
- yrCentre = y3 + (radius1 * math.sin(angle + down))
- xrEnd = xrCentre + (radius1 * math.cos(angle + left))
- yrEnd = yrCentre + (radius1 * math.sin(angle + left))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
- x4 = xrEnd + yLL * math.cos(angle + down)
- y4 = yrEnd + yLL * math.sin(angle + down)
+ if radius4 > 0:
+ if self.r4Button.child.get_text().startswith('iRadius'):
+ xrCentre = x3 + (radius4 * math.cos(angle + right))
+ yrCentre = y3 + (radius4 * math.sin(angle + right))
+ xrEnd = xrCentre + (radius4 * math.cos(angle + up))
+ yrEnd = yrCentre + (radius4 * math.sin(angle + up))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
+ else:
+ xrCentre = x3 + (radius4 * math.cos(angle + up))
+ yrCentre = y3 + (radius4 * math.sin(angle + up))
+ xrEnd = xrCentre + (radius4 * math.cos(angle + right))
+ yrEnd = yrCentre + (radius4 * math.sin(angle + right))
+ if self.r4Button.child.get_text().startswith('Radius'):
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x3, yrCentre - y3))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
+ x4 = xrEnd + yLR * math.cos(angle + up)
+ y4 = yrEnd + yLR * math.sin(angle + up)
else:
- x4 = x3 + yLL * math.cos(angle + down)
- y4 = y3 + yLL * math.sin(angle + down)
+ x4 = x3 + yLR * math.cos(angle + up)
+ y4 = y3 + yLR * math.sin(angle + up)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x4, y4))
- if radius3 > 0:
- xrCentre = x4 + (radius3 * math.cos(angle + right))
- yrCentre = y4 + (radius3 * math.sin(angle + right))
- xrEnd = xrCentre + (radius3 * math.cos(angle + down))
- yrEnd = yrCentre + (radius3 * math.sin(angle + down))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ if radius2 > 0:
+ if self.r2Button.child.get_text().startswith('iRadius'):
+ xrCentre = x4 + (radius2 * math.cos(angle + up))
+ yrCentre = y4 + (radius2 * math.sin(angle + up))
+ xrEnd = xrCentre + (radius2 * math.cos(angle + left))
+ yrEnd = yrCentre + (radius2 * math.sin(angle + left))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ else:
+ xrCentre = x4 + (radius2 * math.cos(angle + left))
+ yrCentre = y4 + (radius2 * math.sin(angle + left))
+ xrEnd = xrCentre + (radius2 * math.cos(angle + up))
+ yrEnd = yrCentre + (radius2 * math.sin(angle + up))
+ if self.r2Button.child.get_text().startswith('Radius'):
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x4, yrCentre - y4))
+ else:
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xrEnd, yrEnd))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
- if leadOutOffset > 0:
- if self.outside.get_active():
- dir = [down, left]
+ if leadOutOffset > 0: # and not (self.outside.get_active() and radius2):
+ if self.outside.get_active() and not radius2:
+ dir = ['g2', down, right]
+ elif self.outside.get_active() and radius2:
+ dir = ['g3', right, down]
else:
- dir = [up, right]
- xlCentre = xS + (leadOutOffset * math.cos(angle + dir[0]))
- ylCentre = yS + (leadOutOffset * math.sin(angle + dir[0]))
- xlEnd = xlCentre + (leadOutOffset * math.cos(angle + dir[1]))
- ylEnd = ylCentre + (leadOutOffset * math.sin(angle + dir[1]))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xS, ylCentre - yS))
+ dir = ['g3', down, left]
+ xlCentre = xS + (leadOutOffset * math.cos(angle + dir[1]))
+ ylCentre = yS + (leadOutOffset * math.sin(angle + dir[1]))
+ xlEnd = xlCentre + (leadOutOffset * math.cos(angle + dir[2]))
+ ylEnd = ylCentre + (leadOutOffset * math.sin(angle + dir[2]))
+ outTmp.write('{} x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(dir[0], xlEnd, ylEnd , xlCentre - xS, ylCentre - yS))
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = 'A positive X Length is required\n\n'
msg += 'and\n\n'
msg += 'A positive Y Length is required\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('RECTANGLE', msg)
+
+ def rad_button_pressed(self, button, value):
+ if button.child.get_text()[:3] == 'Rad':
+ button.child.set_text('Chamfer {}'.format(value))
+ elif button.child.get_text()[:3] == 'Cha':
+ button.child.set_text('iRadius {}'.format(value))
+ else:
+ button.child.set_text('Radius {}'.format(value))
+ self.auto_preview('local')
+
+ def auto_preview(self, widget):
+ if self.xLEntry.get_text() and self.yLEntry.get_text():
+ self.rectangle_preview('auto')
- def do_rectangle(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Rectangle',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
+
+ def rectangle_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
xLLabel = gtk.Label('X length')
xLLabel.set_alignment(0.95, 0.5)
- xLLabel.set_width_chars(10)
- t.attach(xLLabel, 0, 1, 6, 7)
+ xLLabel.set_width_chars(8)
+ self.parent.entries.attach(xLLabel, 0, 1, 6, 7)
self.xLEntry = gtk.Entry()
- self.xLEntry.set_width_chars(10)
- t.attach(self.xLEntry, 1, 2, 6, 7)
+ self.xLEntry.set_width_chars(8)
+ self.xLEntry.connect('activate', self.auto_preview)
+ self.xLEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xLEntry, 1, 2, 6, 7)
yLLabel = gtk.Label('Y length')
yLLabel.set_alignment(0.95, 0.5)
- yLLabel.set_width_chars(10)
- t.attach(yLLabel, 0, 1, 7, 8)
+ yLLabel.set_width_chars(8)
+ self.parent.entries.attach(yLLabel, 0, 1, 7, 8)
self.yLEntry = gtk.Entry()
- self.yLEntry.set_width_chars(10)
- t.attach(self.yLEntry, 1, 2, 7, 8)
+ self.yLEntry.set_width_chars(8)
+ self.yLEntry.connect('activate', self.auto_preview)
+ self.yLEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.yLEntry, 1, 2, 7, 8)
angLabel = gtk.Label('Angle')
angLabel.set_alignment(0.95, 0.5)
- angLabel.set_width_chars(10)
- t.attach(angLabel, 0, 1, 8, 9)
+ angLabel.set_width_chars(8)
+ self.parent.entries.attach(angLabel, 0, 1, 8, 9)
self.angEntry = gtk.Entry()
- self.angEntry.set_width_chars(10)
+ self.angEntry.set_width_chars(8)
self.angEntry.set_text('0')
- t.attach(self.angEntry, 1, 2, 8, 9)
- r1Label = gtk.Label('Radius 1')
- r1Label.set_alignment(0.95, 0.5)
- r1Label.set_width_chars(10)
- t.attach(r1Label, 0, 1, 9, 10)
+ self.angEntry.connect('activate', self.auto_preview)
+ self.angEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.angEntry, 1, 2, 8, 9)
+ self.r1Button = gtk.Button('Radius 1')
+ self.r1Button.connect('pressed', self.rad_button_pressed, '1')
+ self.parent.entries.attach(self.r1Button, 0, 1, 9, 10)
self.r1Entry = gtk.Entry()
- self.r1Entry.set_width_chars(10)
- self.r1Entry.set_text('0')
- t.attach(self.r1Entry, 1, 2, 9, 10)
- r2Label = gtk.Label('Radius 2')
- r2Label.set_alignment(0.95, 0.5)
- r2Label.set_width_chars(10)
- t.attach(r2Label, 2, 3, 9, 10)
+ self.r1Entry.set_width_chars(8)
+ self.r1Entry.connect('activate', self.auto_preview)
+ self.r1Entry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.r1Entry, 1, 2, 9, 10)
+ self.r2Button = gtk.Button('Radius 2')
+ self.r2Button.connect('pressed', self.rad_button_pressed, '2')
+ self.parent.entries.attach(self.r2Button, 2, 3, 9, 10)
self.r2Entry = gtk.Entry()
- self.r2Entry.set_width_chars(10)
- self.r2Entry.set_text('0')
- t.attach(self.r2Entry, 3, 4, 9, 10)
- r3Label = gtk.Label('Radius 3')
- r3Label.set_alignment(0.95, 0.5)
- r3Label.set_width_chars(10)
- t.attach(r3Label, 0, 1, 10, 11)
+ self.r2Entry.set_width_chars(8)
+ self.r2Entry.connect('activate', self.auto_preview)
+ self.r2Entry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.r2Entry, 3, 4, 9, 10)
+ self.r3Button = gtk.Button('Radius 3')
+ self.r3Button.connect('pressed', self.rad_button_pressed, '3')
+ self.parent.entries.attach(self.r3Button, 0, 1, 10, 11)
self.r3Entry = gtk.Entry()
- self.r3Entry.set_width_chars(10)
- self.r3Entry.set_text('0')
- t.attach(self.r3Entry, 1, 2, 10, 11)
- r4Label = gtk.Label('Radius 4')
- r4Label.set_alignment(0.95, 0.5)
- r4Label.set_width_chars(10)
- t.attach(r4Label, 2, 3, 10, 11)
+ self.r3Entry.set_width_chars(8)
+ self.r3Entry.connect('activate', self.auto_preview)
+ self.r3Entry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.r3Entry, 1, 2, 10, 11)
+ self.r4Button = gtk.Button('Radius 4')
+ self.r4Button.connect('pressed', self.rad_button_pressed, '4')
+ self.parent.entries.attach(self.r4Button, 2, 3, 10, 11)
self.r4Entry = gtk.Entry()
- self.r4Entry.set_width_chars(10)
- self.r4Entry.set_text('0')
- t.attach(self.r4Entry, 3, 4, 10, 11)
+ self.r4Entry.set_width_chars(8)
+ self.r4Entry.connect('activate', self.auto_preview)
+ self.r4Entry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.r4Entry, 3, 4, 10, 11)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 12, 13)
+ preview.connect('pressed', self.rectangle_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 12, 13)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 12, 13)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/rectangle.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.xLEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_rotate.py b/configs/by_machine/plasmac/wizards/w_rotate.py
index 881799e988..af5dbf63df 100644
--- a/configs/by_machine/plasmac/wizards/w_rotate.py
+++ b/configs/by_machine/plasmac/wizards/w_rotate.py
@@ -23,14 +23,14 @@
import os
import gtk
import time
+import math
import linuxcnc
import shutil
import hal
from subprocess import Popen,PIPE
import re
-import math
-class rotate:
+class rotate_wiz:
def __init__(self):
self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
@@ -38,54 +38,22 @@ def __init__(self):
self.s = linuxcnc.stat()
self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
- self.fNgc = ''
- self.fCode = ''
self.previewed = False
- self.data_changed = True
-
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE,
- error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
- def cancel(self, widget):
- if os.path.exists(self.fWizard):
- shutil.copyfile(self.fOriginal, self.fWizard)
- if self.previewed:
- if self.gui == 'axis':
- self.load_file(self.fOriginal)
- elif self.gui == 'gmoccapy':
- self.c.program_open(self.fOriginal)
- os.remove(self.outFile)
+ def rotate_cancel(self, widget):
+ shutil.copyfile(self.parent.fNgcBkp, self.parent.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.previewed = False
- self.W.destroy()
- return None
- def accept_rotate(self, widget):
- shutil.copyfile(self.fNgc, self.fWizard)
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
+ def rotate_accept(self, widget):
+ shutil.copyfile(self.parent.fNgc, self.parent.fNgcBkp)
+ self.parent.preview.load(self.parent.fNgc)
- def preview_rotate(self, event):
+ def rotate_preview(self, event):
if self.aEntry.get_text():
angle = float(self.aEntry.get_text())
else:
- angle = 90
+ angle = 0
if self.xOEntry.get_text():
xOffset = float(self.xOEntry.get_text())
else:
@@ -94,39 +62,11 @@ def preview_rotate(self, event):
yOffset = float(self.yOEntry.get_text())
else:
yOffset = 0
- self.fCode = '{}/rotate_code.ngc'.format(self.tmpDir)
- self.s.poll()
- if self.previewed:
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_INFO,
- gtk.BUTTONS_NONE,
- 'ROTATE\n\nCalculating.....')
- md.set_keep_above(True)
- md.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- md.set_default_size(200, 100)
- md.show_all()
- self.c.program_open(self.fOriginal)
- watchdog = time.time() + 5
- while(1):
- self.s.poll()
- if os.path.basename(self.s.file) == os.path.basename(self.fOriginal):
- n = time.time() + 1
- while(1):
- if time.time() > n:
- break
- while gtk.events_pending():
- gtk.main_iteration()
- break
- if time.time() > watchdog:
- md.destroy()
- self.dialog_error('Rotate file error')
- return
- outNgc = open(self.fNgc, 'w')
- inCod = open(self.fOriginal, 'r')
+ outNgc = open(self.parent.fNgc, 'w')
+ inCod = open(self.parent.fNgcBkp, 'r')
for line in inCod:
if line.strip().lower().startswith('g'):
- rLine = self.rotate_object(line)
+ rLine = self.rotate_object(angle, xOffset, yOffset, line)
if rLine is not None:
outNgc.write(rLine)
else:
@@ -135,15 +75,13 @@ def preview_rotate(self, event):
outNgc.write(line)
inCod.close()
outNgc.close()
- self.load_file(self.fNgc)
- if self.previewed:
- md.destroy()
- hal.set_p('plasmac_run.preview-tab', '1')
+ self.parent.preview.load(self.parent.fNgc)
+ # if self.previewed:
+ # md.destroy()
self.previewed = True
- self.data_changed = False
- self.accept.set_sensitive(True)
+ self.add.set_sensitive(True)
- def rotate_object(self, line):
+ def rotate_object(self, angle, xOffset, yOffset, line):
REGCODE = re.compile('([a-z]-?[0-9]+\.?([0-9]+)?)|\(.*\)')
inLine = line.strip()
self.comment = ''
@@ -155,7 +93,7 @@ def rotate_object(self, line):
parts = list([ list(cmd)[0] for cmd in REGCODE.findall(inLine) ])
if len(parts) == 0 or parts[0] not in ['g0', 'g1', 'g2', 'g3']:
return line
- angle = math.radians(float(self.aEntry.get_text()))
+ angle = math.radians(angle)
params = {'x':0.0, 'y':0.0, 'i':0.0, 'j':0.0,}
used = ''
for p in parts:
@@ -175,74 +113,63 @@ def rotate_object(self, line):
used += 'j'
newLine = ('{}'.format(parts[0]))
if not 'x' in used and not 'y' in used:
- self.dialog_error('Cannot decipher G-Code correctly')
+ self.parent.dialog_error('ROTATE', 'Cannot decipher G-Code correctly')
return None
if 'x' in used:
- newLine += (' x{:.6f}'.format(params['x'] * math.cos(angle) - params['y'] * math.sin(angle) + float(self.xOEntry.get_text())))
+ newLine += (' x{:.6f}'.format(params['x'] * math.cos(angle) - params['y'] * math.sin(angle) + xOffset))
if 'y' in used:
- newLine += (' y{:.6f}'.format(params['y'] * math.cos(angle) + params['x'] * math.sin(angle) + float(self.yOEntry.get_text())))
+ newLine += (' y{:.6f}'.format(params['y'] * math.cos(angle) + params['x'] * math.sin(angle) + yOffset))
if parts[0] in {'g2', 'g3'}:
newLine += (' i{:.6f}'.format(params['i'] * math.cos(angle) - params['j'] * math.sin(angle)))
newLine += (' j{:.6f}'.format(params['j'] * math.cos(angle) + params['i'] * math.sin(angle)))
return ('{}\n'.format(newLine))
- def data_change(self, widget):
- self.data_changed = True
-
- def do_rotate(self, fWizard, inFile, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.fOriginal = '{}/original.ngc'.format(tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- shutil.copyfile(inFile, self.fOriginal)
- self.W = gtk.Dialog('Rotate',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def rotate_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
+ try:
+ shutil.copyfile(inFile, self.parent.fNgcBkp)
+ except:
+ pass
aLabel = gtk.Label('Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 0, 1)
+ self.parent.entries.attach(aLabel, 1, 2, 1, 2)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
- self.aEntry.set_text('90')
- self.aEntry.connect('changed', self.data_change)
- t.attach(self.aEntry, 1, 2, 0, 1)
+ self.aEntry.set_width_chars(8)
+ self.aEntry.set_text('0')
+ self.aEntry.connect('activate', self.rotate_preview)
+ self.aEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 2, 3, 1, 2)
xOLabel = gtk.Label('X Offset')
xOLabel.set_alignment(0.95, 0.5)
- xOLabel.set_justify(gtk.JUSTIFY_RIGHT)
- xOLabel.set_width_chars(10)
- t.attach(xOLabel, 0, 1, 1, 2)
+ self.parent.entries.attach(xOLabel, 1, 2, 3, 4)
self.xOEntry = gtk.Entry()
- self.xOEntry.set_width_chars(10)
+ self.xOEntry.set_width_chars(8)
self.xOEntry.set_text('0')
- self.xOEntry.connect('changed', self.data_change)
- t.attach(self.xOEntry, 1, 2, 1, 2)
+ self.xOEntry.connect('activate', self.rotate_preview)
+ self.xOEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xOEntry, 2, 3, 3, 4)
yOLabel = gtk.Label('Y Offset')
yOLabel.set_alignment(0.95, 0.5)
- yOLabel.set_width_chars(10)
- t.attach(yOLabel, 0, 1, 2, 3)
+ self.parent.entries.attach(yOLabel, 1, 2, 5, 6)
self.yOEntry = gtk.Entry()
- self.yOEntry.set_width_chars(10)
+ self.yOEntry.set_width_chars(8)
self.yOEntry.set_text('0')
- self.yOEntry.connect('changed', self.data_change)
- t.attach(self.yOEntry, 1, 2, 2, 3)
+ self.yOEntry.connect('activate', self.rotate_preview)
+ self.yOEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.yOEntry, 2, 3, 5, 6)
self.preview = gtk.Button('Preview')
- self.preview.connect('pressed', self.preview_rotate)
- t.attach(self.preview, 1, 2, 3, 4)
- self.accept = gtk.Button('Accept')
- self.accept.connect('pressed', self.accept_rotate)
- self.accept.set_sensitive(False)
- t.attach(self.accept, 2, 3, 3, 4)
- cancel = gtk.Button('Cancel')
- cancel.connect('pressed', self.cancel)
- t.attach(cancel, 3, 4, 3, 4)
+ self.preview.connect('pressed', self.rotate_preview)
+ self.parent.entries.attach(self.preview, 0, 1, 12, 13)
+ self.add = gtk.Button('Add')
+ self.add.connect('pressed', self.rotate_accept)
+ self.add.set_sensitive(False)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.rotate_cancel)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
self.aEntry.grab_focus()
- self.W.show_all()
- response = self.W.run()
diff --git a/configs/by_machine/plasmac/wizards/w_sector.py b/configs/by_machine/plasmac/wizards/w_sector.py
index d4defcbf56..6c1d8688c8 100644
--- a/configs/by_machine/plasmac/wizards/w_sector.py
+++ b/configs/by_machine/plasmac/wizards/w_sector.py
@@ -29,120 +29,70 @@
import hal
from subprocess import Popen,PIPE
-class sector:
+class sector_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
-# validate entries
+ def sector_preview(self, event):
+ msg = ''
try:
- leadInOffset = math.sin(math.radians(45)) * float(self.liEntry.get_text())
- leadOutOffset = math.sin(math.radians(45)) * float(self.loEntry.get_text())
- radius = float(self.rEntry.get_text())
- sAngle = math.radians(float(self.sEntry.get_text()))
-# angle = math.radians(float(self.aEntry.get_text()) + 270)
- angle = math.radians(float(self.aEntry.get_text()))
+ if self.liEntry.get_text():
+ leadInOffset = math.sin(math.radians(45)) * float(self.liEntry.get_text())
+ else:
+ leadInOffset = 0.0
except:
- msg = 'Valid numerical entries required for:\n\n'
msg += 'Lead In\n'
+ try:
+ if self.loEntry.get_text():
+ leadOutOffset = math.sin(math.radians(45)) * float(self.loEntry.get_text())
+ else:
+ leadOutOffset = 0.0
+ except:
msg += 'Lead Out\n'
+ try:
+ radius = float(self.rEntry.get_text())
+ except:
msg += 'Radius\n'
+ try:
+ sAngle = math.radians(float(self.sEntry.get_text()))
+ except:
msg += 'Sector Angle\n'
+ try:
+ if self.aEntry.get_text():
+ angle = math.radians(float(self.aEntry.get_text()))
+ else:
+ angle = 0.0
+ except:
+ msg = 'Valid numerical entries required for:\n\n'
msg += 'Angle\n'
- self.dialog_error(msg)
+ if msg:
+ errMsg = 'Valid numerical entries required for:\n\n{}'.format(msg)
+ self.parent.dialog_error('SECTOR', errMsg)
return
if radius == 0 or sAngle == 0:
msg = 'Valid numerical entries required for:\n\n'
msg += 'Radius\n'
msg += 'Sector Angle\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('SECTOR', msg)
return
if self.offset.get_active() and leadInOffset <= 0:
msg = 'A Lead In is required if\n\n'
msg += 'kerf width offset is enabled\n'
- self.dialog_error(msg)
+ self.parent.dialog_error('SECTOR', msg)
return
- self.s.poll()
-# get current x/y position
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
# set origin position
- if self.xSEntry.get_text():
- xO = float(self.xSEntry.get_text())
- else:
- xO = xPos
- if self.ySEntry.get_text():
- yO = float(self.ySEntry.get_text())
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.outside.get_active():
+ xO = float(self.xSEntry.get_text()) + kOffset
+ yO = float(self.ySEntry.get_text()) + kOffset
else:
- yO = yPos
+ xO = float(self.xSEntry.get_text()) - kOffset
+ yO = float(self.ySEntry.get_text()) - kOffset
# set start point
xS = xO + (radius * 0.75) * math.cos(angle)
yS = yO + (radius * 0.75) * math.sin(angle)
@@ -170,24 +120,21 @@ def send_preview(self, event):
yOC = yS + (leadOutOffset * math.sin(angle + dir[0]))
xOE = xOC + (leadOutOffset * math.cos(angle + dir[2]))
yOE = yOC + (leadOutOffset * math.sin(angle + dir[2]))
-
# setup files and write g-code
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard sector)\n')
-
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xIS, yIS))
outTmp.write('m3 $0 s1\n')
if self.offset.get_active():
@@ -207,127 +154,144 @@ def send_preview(self, event):
outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xOE, yOE, xOC - xS, yOC - yS))
if self.offset.get_active():
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
- def do_sector(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
+ def auto_preview(self, widget):
+ if self.rEntry.get_text() and self.sEntry.get_text():
+ self.sector_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), None)
+
+ def sector_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
self.sRadius = 0.0
self.hSpeed = 100
- self.W = gtk.Dialog('Sector',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
rLabel = gtk.Label('Radius')
rLabel.set_alignment(0.95, 0.5)
- rLabel.set_width_chars(10)
- t.attach(rLabel, 0, 1, 5, 6)
+ rLabel.set_width_chars(8)
+ self.parent.entries.attach(rLabel, 0, 1, 5, 6)
self.rEntry = gtk.Entry()
- self.rEntry.set_width_chars(10)
- t.attach(self.rEntry, 1, 2, 5, 6)
+ self.rEntry.set_width_chars(8)
+ self.rEntry.connect('activate', self.auto_preview)
+ self.rEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.rEntry, 1, 2, 5, 6)
sLabel = gtk.Label('Sector Angle')
sLabel.set_alignment(0.95, 0.5)
- sLabel.set_width_chars(10)
- t.attach(sLabel, 0, 1, 6, 7)
+ sLabel.set_width_chars(8)
+ self.parent.entries.attach(sLabel, 0, 1, 6, 7)
self.sEntry = gtk.Entry()
- self.sEntry.set_width_chars(10)
- t.attach(self.sEntry, 1, 2, 6, 7)
+ self.sEntry.set_width_chars(8)
+ self.sEntry.connect('activate', self.auto_preview)
+ self.sEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.sEntry, 1, 2, 6, 7)
aLabel = gtk.Label('Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 7, 8)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 7, 8)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
+ self.aEntry.set_width_chars(8)
self.aEntry.set_text('0')
- t.attach(self.aEntry, 1, 2, 7, 8)
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 7, 8)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 9, 10)
+ preview.connect('pressed', self.sector_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 9, 10)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 9, 10)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/sector.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.rEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_settings.py b/configs/by_machine/plasmac/wizards/w_settings.py
index 3a79584e4d..aa46aa3f2b 100644
--- a/configs/by_machine/plasmac/wizards/w_settings.py
+++ b/configs/by_machine/plasmac/wizards/w_settings.py
@@ -25,21 +25,38 @@
import sys
import linuxcnc
-class settings:
+class settings_wiz:
def __init__(self):
self.W = gtk.Window()
self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
def save_settings(self, widget):
+ if self.parent.scale == 1:
+ unitCode = ['21', '0.25', '32']
+ else:
+ unitCode = ['20', '0.004', '1.26']
+ if not self.preEntry.get_text():
+ self.preEntry.set_text('G{} G64P{} G40 G49 G80 G90 G92.1 G94 G97'.format(unitCode[0], unitCode[1]))
+ if not self.postEntry.get_text():
+ self.postEntry.set_text('G{} G64P{} G40 G49 G80 G90 G92.1 G94 G97'.format(unitCode[0], unitCode[1]))
+ if not self.liEntry.get_text():
+ self.liEntry.set_text('0')
+ if not self.loEntry.get_text():
+ self.loEntry.set_text('0')
+ if not self.dEntry.get_text():
+ self.dEntry.set_text('{}'.format(unitCode[2]))
+ if not self.sEntry.get_text():
+ self.sEntry.set_text('60')
+ if not self.wWEntry.get_text():
+ self.wWEntry.set_text('890')
+ if not self.wHEntry.get_text():
+ self.wHEntry.set_text('582')
+ if not self.gSEntry.get_text():
+ self.gSEntry.set_text('0')
+ if not self.fEntry.get_text():
+ self.fEntry.set_text('9')
f_out = open(self.configFile, 'w')
f_out.write('#plasmac wizards configuration file, format is:\n#name = value\n\n')
f_out.write('preamble={}\n'.format(self.preEntry.get_text()))
@@ -49,104 +66,173 @@ def save_settings(self, widget):
f_out.write('lead-out={}\n'.format(self.loEntry.get_text()))
f_out.write('hole-diameter={}\n'.format(self.dEntry.get_text()))
f_out.write('hole-speed={}\n'.format(self.sEntry.get_text()))
- self.W.destroy()
- return None
+ f_out.write('window-width={}\n'.format(self.wWEntry.get_text()))
+ f_out.write('window-height={}\n'.format(self.wHEntry.get_text()))
+ f_out.write('grid-size={}\n'.format(self.gSEntry.get_text()))
+ f_out.write('font-size={}\n'.format(self.fEntry.get_text()))
+ self.parent.preamble = self.preEntry.get_text()
+ self.parent.postamble = self.postEntry.get_text()
+ self.parent.origin = self.centre.get_active()
+ self.parent.leadIn = self.liEntry.get_text()
+ self.parent.leadOut = self.loEntry.get_text()
+ self.parent.holeRadius = float(self.dEntry.get_text()) / 2
+ self.parent.holeSpeed = float(self.sEntry.get_text())
+ if int(self.wHEntry.get_text()) > 800:
+ self.parent.entries.set_row_spacings(8)
+ elif int(self.wHEntry.get_text()) > 700:
+ self.parent.entries.set_row_spacings(4)
+ else:
+ self.parent.entries.set_row_spacings(2)
+ gtk.settings_get_default().set_property('gtk-font-name', 'sans {}'.format(self.fEntry.get_text()))
+ self.parent.resize_window(int(self.wWEntry.get_text()), int(self.wHEntry.get_text()))
+ if self.gSEntry.get_text():
+ # glcanon has a reversed scale to just about everything else... :(
+ self.parent.preview.grid_size = float(self.gSEntry.get_text()) * (0.03937000787402 / self.parent.scale)
+ self.parent.preview.load(self.parent.fNgc)
+
+ def load_config(self, widget):
+ if os.path.exists(self.configFile):
+ f_in = open(self.configFile, 'r')
+ for line in f_in:
+ if line.startswith('preamble'):
+ self.preEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('postamble'):
+ self.postEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('origin'):
+ if line.strip().split('=')[1] == 'True':
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ elif line.startswith('lead-in'):
+ self.liEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('lead-out'):
+ self.loEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('hole-diameter'):
+ self.dEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('hole-speed'):
+ self.sEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('window-width'):
+ self.wWEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('window-height'):
+ self.wHEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('grid-size'):
+ self.gSEntry.set_text(line.strip().split('=')[1])
+ elif line.startswith('font-size'):
+ self.fEntry.set_text(line.strip().split('=')[1])
- def cancel(self, event):
- self.W.destroy()
- return None
+ def entry_changed(self, widget):
+ if widget.get_text():
+ if widget.get_text()[len(widget.get_text()) - 1] not in '.0123456789':
+ widget.set_text(widget.get_text()[:len(widget.get_text()) - 1])
- def do_settings(self):
- self.W = gtk.Dialog('Settings',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- self.W.vbox.add(t)
+ def settings_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ self.parent = parent
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
preLabel = gtk.Label('Preamble')
preLabel.set_alignment(0.95, 0.5)
- preLabel.set_width_chars(10)
- t.attach(preLabel, 0, 1, 0, 1)
+ preLabel.set_width_chars(8)
+ self.parent.entries.attach(preLabel, 0, 1, 0, 1)
self.preEntry = gtk.Entry()
- t.attach(self.preEntry, 1, 5, 0, 1)
+ self.parent.entries.attach(self.preEntry, 1, 5, 0, 1)
postLabel = gtk.Label('Postamble')
postLabel.set_alignment(0.95, 0.5)
- postLabel.set_width_chars(10)
- t.attach(postLabel, 0, 1, 1, 2)
+ postLabel.set_width_chars(8)
+ self.parent.entries.attach(postLabel, 0, 1, 1, 2)
self.postEntry = gtk.Entry()
- t.attach(self.postEntry, 1, 5, 1, 2)
+ self.parent.entries.attach(self.postEntry, 1, 5, 1, 2)
oLabel = gtk.Label('Origin')
oLabel.set_alignment(0.5, 1.0)
- oLabel.set_width_chars(10)
- t.attach(oLabel, 0, 5, 2, 3)
+ oLabel.set_width_chars(8)
+ self.parent.entries.attach(oLabel, 0, 5, 2, 3)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 3, 4)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 3, 4, 3, 4)
+ self.parent.entries.attach(self.centre, 1, 2, 3, 4)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 3, 4, 3, 4)
shLabel = gtk.Label('Lead Lengths')
shLabel.set_alignment(0.5, 1.0)
- shLabel.set_width_chars(10)
- t.attach(shLabel, 0, 5, 4, 5)
+ shLabel.set_width_chars(8)
+ self.parent.entries.attach(shLabel, 0, 5, 4, 5)
liLabel = gtk.Label('Lead In')
liLabel.set_alignment(0.95, 0.5)
- liLabel.set_width_chars(10)
- t.attach(liLabel, 0, 1, 5, 6)
+ liLabel.set_width_chars(8)
+ self.parent.entries.attach(liLabel, 0, 1, 5, 6)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 5, 6)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 5, 6)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.05, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 4, 5, 5, 6)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 4, 5, 5, 6)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 3, 4, 5, 6)
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.loEntry, 3, 4, 5, 6)
shLabel = gtk.Label('Small Holes')
shLabel.set_alignment(0.5, 1.0)
- shLabel.set_width_chars(10)
- t.attach(shLabel, 0, 5, 6, 7)
+ shLabel.set_width_chars(8)
+ self.parent.entries.attach(shLabel, 0, 5, 6, 7)
dLabel = gtk.Label('Diameter')
dLabel.set_alignment(0.95, 0.5)
- dLabel.set_width_chars(10)
- t.attach(dLabel, 0, 1, 7, 8)
+ dLabel.set_width_chars(8)
+ self.parent.entries.attach(dLabel, 0, 1, 7, 8)
self.dEntry = gtk.Entry()
- self.dEntry.set_width_chars(10)
- t.attach(self.dEntry, 1, 2, 7, 8)
+ self.dEntry.set_width_chars(8)
+ self.dEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.dEntry, 1, 2, 7, 8)
sLabel = gtk.Label('Speed %')
sLabel.set_alignment(0.05, 0.5)
- sLabel.set_width_chars(10)
- t.attach(sLabel, 4, 5, 7, 8)
+ sLabel.set_width_chars(8)
+ self.parent.entries.attach(sLabel, 4, 5, 7, 8)
self.sEntry = gtk.Entry()
- self.sEntry.set_width_chars(10)
- t.attach(self.sEntry, 3, 4, 7, 8)
+ self.sEntry.set_width_chars(8)
+ self.sEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.sEntry, 3, 4, 7, 8)
+ wSLabel = gtk.Label('Window')
+ wSLabel.set_alignment(0.5, 1.0)
+ wSLabel.set_width_chars(8)
+ self.parent.entries.attach(wSLabel, 0, 5, 8, 9)
+ wWLabel = gtk.Label('Width')
+ wWLabel.set_alignment(0.95, 0.5)
+ wWLabel.set_width_chars(8)
+ self.parent.entries.attach(wWLabel, 0, 1, 9, 10)
+ self.wWEntry = gtk.Entry()
+ self.wWEntry.set_width_chars(8)
+ self.wWEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.wWEntry, 1, 2, 9, 10)
+ wHLabel = gtk.Label('Height')
+ wHLabel.set_alignment(0.05, 0.5)
+ wHLabel.set_width_chars(8)
+ self.parent.entries.attach(wHLabel, 4, 5, 9, 10)
+ self.wHEntry = gtk.Entry()
+ self.wHEntry.set_width_chars(8)
+ self.wHEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.wHEntry, 3, 4, 9, 10)
+ gSLabel = gtk.Label('Grid Size')
+ gSLabel.set_alignment(0.95, 0.5)
+ gSLabel.set_width_chars(8)
+ self.parent.entries.attach(gSLabel, 0, 1, 10, 11)
+ self.gSEntry = gtk.Entry()
+ self.gSEntry.set_width_chars(8)
+ self.gSEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.gSEntry, 1, 2, 10, 11)
+ fLabel = gtk.Label('Font Size')
+ fLabel.set_alignment(0.05, 0.5)
+ fLabel.set_width_chars(8)
+ self.parent.entries.attach(fLabel, 4, 5, 10, 11)
+ self.fEntry = gtk.Entry()
+ self.fEntry.set_width_chars(8)
+ self.fEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.fEntry, 3, 4, 10, 11)
save = gtk.Button('Save')
save.connect('pressed', self.save_settings)
- t.attach(save, 1, 2, 9, 10)
- cancel = gtk.Button('Cancel')
- cancel.connect('pressed', self.cancel)
- t.attach(cancel, 3, 4, 9, 10)
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('postamble'):
- self.postEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('hole-diameter'):
- self.dEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('hole-speed'):
- self.sEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(save, 1, 2, 12, 13)
+ cancel = gtk.Button('Reload')
+ cancel.connect('pressed', self.load_config)
+ self.parent.entries.attach(cancel, 3, 4, 12, 13)
+ self.load_config(None)
+ self.parent.W.show_all()
+ self.liEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_slot.py b/configs/by_machine/plasmac/wizards/w_slot.py
index a0e6a47535..0a8342c10b 100644
--- a/configs/by_machine/plasmac/wizards/w_slot.py
+++ b/configs/by_machine/plasmac/wizards/w_slot.py
@@ -29,90 +29,22 @@
import hal
from subprocess import Popen,PIPE
-class slot:
+class slot_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def slot_preview(self, event):
length = width = 0
- if self.lEntry.get_text() and self.wEntry.get_text():
- if self.wEntry.get_text():
- width = float(self.wEntry.get_text())
- radius = width / 2
- if self.lEntry.get_text():
- length = float(self.lEntry.get_text()) - width
- if length > 0 and width > 0:
+ if self.lEntry.get_text():
+ length = float(self.lEntry.get_text())
+ if self.wEntry.get_text():
+ width = float(self.wEntry.get_text())
+ radius = width / 2
+ if length > 0 and width > 0 and length >= width:
+ blLength = math.sqrt((length / 2) ** 2 + width ** 2)
+ blAngle = math.atan(width / (length / 2))
+ length = length - width
if self.angEntry.get_text():
angle = math.radians(float(self.angEntry.get_text()))
else:
@@ -129,45 +61,43 @@ def send_preview(self, event):
up = math.radians(90)
left = math.radians(180)
down = math.radians(270)
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xS = float(self.xSEntry.get_text()) + (width / 2) * math.cos(angle + down)
- else:
- xS = float(self.xSEntry.get_text()) + (length / 2 + radius) * math.cos(angle + right)
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ xS = float(self.xSEntry.get_text()) + (width / 2) * math.cos(angle + up)
else:
- if self.centre.get_active():
- xS = xPos + (width / 2) * math.cos(angle + down)
- else:
- xS = xPos + (length / 2 + radius) * math.cos(angle + right)
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yS = float(self.ySEntry.get_text()) + (width / 2) * math.sin(angle + down)
+ if self.outside.get_active():
+ xS = (float(self.xSEntry.get_text()) + kOffset) + blLength * math.cos(angle + right + blAngle)
else:
- yS = float(self.ySEntry.get_text()) + (length / 2 + radius) * math.sin(angle + right)
+ xS = (float(self.xSEntry.get_text()) - kOffset) + blLength * math.cos(angle + right + blAngle)
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ yS = float(self.ySEntry.get_text()) + (width / 2) * math.sin(angle + up)
else:
- if self.centre.get_active():
- yS = yPos + (width / 2) * math.sin(angle + down)
+ if self.outside.get_active():
+ yS = (float(self.ySEntry.get_text()) + kOffset) + blLength * math.sin(angle + right + blAngle)
else:
- yS = yPos + (length / 2 + radius) * math.sin(angle + right)
+ yS = (float(self.xSEntry.get_text()) - kOffset) + blLength * math.sin(angle + right + blAngle)
if self.outside.get_active():
- dir = [down, right, left]
- else:
dir = [up, left, right]
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- outTmp.write('\n(wizard rectangle)\n')
+ dir = [down, right, left]
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
+ outTmp.write('\n(wizard slot)\n')
if leadInOffset > 0:
xlCentre = xS + (leadInOffset * math.cos(angle + dir[0]))
ylCentre = yS + (leadInOffset * math.sin(angle + dir[0]))
@@ -185,180 +115,199 @@ def send_preview(self, event):
y1 = yS + (length / 2) * math.sin(angle + dir[2])
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x1, y1))
if self.outside.get_active():
- xrCentre = x1 + (radius * math.cos(angle + up))
- yrCentre = y1 + (radius * math.sin(angle + up))
- xrEnd = xrCentre + (radius * math.cos(angle + up))
- yrEnd = yrCentre + (radius * math.sin(angle + up))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
- x2 = xrEnd + length * math.cos(angle + right)
- y2 = yrEnd + length * math.sin(angle + right)
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
- xrCentre = x2 + (radius * math.cos(angle + down))
- yrCentre = y2 + (radius * math.sin(angle + down))
+ xrCentre = x1 + (radius * math.cos(angle + down))
+ yrCentre = y1 + (radius * math.sin(angle + down))
xrEnd = xrCentre + (radius * math.cos(angle + down))
yrEnd = yrCentre + (radius * math.sin(angle + down))
- outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
- else:
- xrCentre = x1 + (radius * math.cos(angle + up))
- yrCentre = y1 + (radius * math.sin(angle + up))
- xrEnd = xrCentre + (radius * math.cos(angle + up))
- yrEnd = yrCentre + (radius * math.sin(angle + up))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
x2 = xrEnd + length * math.cos(angle + left)
y2 = yrEnd + length * math.sin(angle + left)
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
- xrCentre = x2 + (radius * math.cos(angle + down))
- yrCentre = y2 + (radius * math.sin(angle + down))
+ xrCentre = x2 + (radius * math.cos(angle + up))
+ yrCentre = y2 + (radius * math.sin(angle + up))
+ xrEnd = xrCentre + (radius * math.cos(angle + up))
+ yrEnd = yrCentre + (radius * math.sin(angle + up))
+ outTmp.write('g2 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
+ else:
+ xrCentre = x1 + (radius * math.cos(angle + down))
+ yrCentre = y1 + (radius * math.sin(angle + down))
xrEnd = xrCentre + (radius * math.cos(angle + down))
yrEnd = yrCentre + (radius * math.sin(angle + down))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x1, yrCentre - y1))
+ x2 = xrEnd + length * math.cos(angle + right)
+ y2 = yrEnd + length * math.sin(angle + right)
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(x2, y2))
+ xrCentre = x2 + (radius * math.cos(angle + up))
+ yrCentre = y2 + (radius * math.sin(angle + up))
+ xrEnd = xrCentre + (radius * math.cos(angle + up))
+ yrEnd = yrCentre + (radius * math.sin(angle + up))
outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xrEnd, yrEnd, xrCentre - x2, yrCentre - y2))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
if leadOutOffset > 0:
if self.outside.get_active():
- dir = [down, left]
- else:
dir = [up, right]
+ else:
+ dir = [down, left]
xlCentre = xS + (leadOutOffset * math.cos(angle + dir[0]))
ylCentre = yS + (leadOutOffset * math.sin(angle + dir[0]))
xlEnd = xlCentre + (leadOutOffset * math.cos(angle + dir[1]))
ylEnd = ylCentre + (leadOutOffset * math.sin(angle + dir[1]))
outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xS, ylCentre - yS))
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if length <= 0:
- msg += 'A positive Length is required\nor\nLength must be > Width x 2\n\n'
+ msg += 'A positive Length is required\n\n'
if width <= 0:
- msg += 'A positive Width is required'
- self.dialog_error(msg)
+ msg += 'A positive Width is required\n\n'
+ if length < width:
+ msg += 'Length must be greater than or equal to Width'
+ self.parent.dialog_error('SLOT', msg)
- def do_slot(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Slot',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def auto_preview(self, widget):
+ if self.lEntry.get_text() and self.wEntry.get_text():
+ self.slot_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
+
+ def slot_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
lLabel = gtk.Label('Length')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 6, 7)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 6, 7)
self.lEntry = gtk.Entry()
- self.lEntry.set_width_chars(10)
- t.attach(self.lEntry, 1, 2, 6, 7)
+ self.lEntry.set_width_chars(8)
+ self.lEntry.connect('activate', self.auto_preview)
+ self.lEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.lEntry, 1, 2, 6, 7)
wLabel = gtk.Label('Width')
wLabel.set_alignment(0.95, 0.5)
- wLabel.set_width_chars(10)
- t.attach(wLabel, 0, 1, 7, 8)
+ wLabel.set_width_chars(8)
+ self.parent.entries.attach(wLabel, 0, 1, 7, 8)
self.wEntry = gtk.Entry()
- self.wEntry.set_width_chars(10)
- t.attach(self.wEntry, 1, 2, 7, 8)
+ self.wEntry.set_width_chars(8)
+ self.wEntry.connect('activate', self.auto_preview)
+ self.wEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.wEntry, 1, 2, 7, 8)
angLabel = gtk.Label('Angle')
angLabel.set_alignment(0.95, 0.5)
- angLabel.set_width_chars(10)
- t.attach(angLabel, 0, 1, 8, 9)
+ angLabel.set_width_chars(8)
+ self.parent.entries.attach(angLabel, 0, 1, 8, 9)
self.angEntry = gtk.Entry()
- self.angEntry.set_width_chars(10)
+ self.angEntry.set_width_chars(8)
self.angEntry.set_text('0')
- t.attach(self.angEntry, 1, 2, 8, 9)
+ self.angEntry.connect('activate', self.auto_preview)
+ self.angEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.angEntry, 1, 2, 8, 9)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 10, 11)
+ preview.connect('pressed', self.slot_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 10, 11)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 10, 11)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/slot.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.lEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_star.py b/configs/by_machine/plasmac/wizards/w_star.py
index 2581171ff9..92bfaa0e93 100644
--- a/configs/by_machine/plasmac/wizards/w_star.py
+++ b/configs/by_machine/plasmac/wizards/w_star.py
@@ -29,82 +29,12 @@
import hal
from subprocess import Popen,PIPE
-class star:
+class star_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
- else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
+ def star_preview(self, event):
if self.pEntry.get_text():
points = int(self.pEntry.get_text())
else:
@@ -118,34 +48,26 @@ def send_preview(self, event):
else:
iRadius = 0
if points >= 3 and iRadius > 0 and oRadius > 0 and oRadius > iRadius:
- if self.xSEntry.get_text():
- if self.centre.get_active():
- xC = float(self.xSEntry.get_text())
- else:
- xC = float(self.xSEntry.get_text()) + oRadius * math.cos(math.radians(0))
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if self.centre.get_active():
+ xC = float(self.xSEntry.get_text())
else:
- if self.centre.get_active():
- xC = xPos
- else:
- xC = xPos + oRadius * math.cos(math.radians(0))
- if self.ySEntry.get_text():
- if self.centre.get_active():
- yC = float(self.ySEntry.get_text())
- else:
- yC = float(self.ySEntry.get_text()) + oRadius * math.sin(math.radians(90))
+ xC = float(self.xSEntry.get_text()) + oRadius * math.cos(math.radians(0))
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.centre.get_active():
+ yC = float(self.ySEntry.get_text())
else:
- if self.centre.get_active():
- yC = yPos
- else:
- yC = yPos + oRadius * math.sin(math.radians(90))
+ yC = float(self.ySEntry.get_text()) + oRadius * math.sin(math.radians(90))
if self.liEntry.get_text():
leadInOffset = float(self.liEntry.get_text())
else:
leadInOffset = 0
- if self.loEntry.get_text():
- leadOutOffset = float(self.loEntry.get_text())
- else:
- leadOutOffset = 0
+ # if self.loEntry.get_text():
+ # leadOutOffset = float(self.loEntry.get_text())
+ # else:
+ # leadOutOffset = 0
if self.aEntry.get_text():
angle = math.radians(float(self.aEntry.get_text()))
else:
@@ -160,20 +82,19 @@ def send_preview(self, event):
x = xC + iRadius * math.cos(pAngle)
y = yC + iRadius * math.sin(pAngle)
pList.append(['{:.6f}'.format(x), '{:.6f}'.format(y)])
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
- else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard star {})\n'.format(points))
if self.outside.get_active():
if leadInOffset > 0:
@@ -210,19 +131,17 @@ def send_preview(self, event):
outTmp.write('g1 x{} y{}\n'.format(pList[i][0], pList[i][1]))
if self.offset.get_active():
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
msg = ''
if points < 3:
@@ -233,7 +152,7 @@ def send_preview(self, event):
msg += 'Outside Diameter must be > Inside Diameter\n\n'
if iRadius <= 0:
msg += 'Inside Diameter is required'
- self.dialog_error(msg)
+ self.parent.dialog_error('STAR', msg)
def mode_changed(self, widget):
if self.mCombo.get_active() == 2:
@@ -241,127 +160,148 @@ def mode_changed(self, widget):
else:
self.dLabel.set_text('Diameter')
- def do_star(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Star',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def auto_preview(self, widget):
+ if self.pEntry.get_text() and self.odEntry.get_text() and self.idEntry.get_text():
+ self.star_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), self.centre.get_active())
+
+ def star_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cLabel = gtk.Label('Cut Type')
cLabel.set_alignment(0.95, 0.5)
- cLabel.set_width_chars(10)
- t.attach(cLabel, 0, 1, 0, 1)
+ cLabel.set_width_chars(8)
+ self.parent.entries.attach(cLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
oLabel = gtk.Label('Offset')
oLabel.set_alignment(0.95, 0.5)
- oLabel.set_width_chars(10)
- t.attach(oLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ oLabel.set_width_chars(8)
+ self.parent.entries.attach(oLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
- loLabel = gtk.Label('Lead Out')
- loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
- self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
+ # loLabel = gtk.Label('Lead Out')
+ # loLabel.set_alignment(0.95, 0.5)
+ # loLabel.set_width_chars(8)
+ # self.parent.entries.attach(loLabel, 0, 1, 2, 3)
+ # self.loEntry = gtk.Entry()
+ # self.loEntry.set_width_chars(8)
+ # self.loEntry.connect('activate', self.auto_preview)
+ # self.loEntry.connect('changed', self.parent.entry_changed)
+ # self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
self.centre = gtk.RadioButton(None, 'Centre')
- t.attach(self.centre, 1, 2, 5, 6)
- self.bLeft = gtk.RadioButton(self.centre, 'Bottom Left')
- t.attach(self.bLeft, 0, 1, 5, 6)
+ self.centre.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.centre, 1, 2, 5, 6)
+ self.bLeft = gtk.RadioButton(self.centre, 'Btm Lft')
+ self.parent.entries.attach(self.bLeft, 0, 1, 5, 6)
pLabel = gtk.Label('# of Points')
pLabel.set_alignment(0.95, 0.5)
- pLabel.set_width_chars(10)
- t.attach(pLabel, 0, 1, 6, 7)
+ pLabel.set_width_chars(8)
+ self.parent.entries.attach(pLabel, 0, 1, 6, 7)
self.pEntry = gtk.Entry()
- self.pEntry.set_width_chars(10)
- t.attach(self.pEntry, 1, 2, 6, 7)
- self.odLabel = gtk.Label('Outside Dia')
+ self.pEntry.set_width_chars(8)
+ self.pEntry.connect('activate', self.auto_preview)
+ self.pEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.pEntry, 1, 2, 6, 7)
+ self.odLabel = gtk.Label('Outer Dia')
self.odLabel.set_alignment(0.95, 0.5)
- self.odLabel.set_width_chars(10)
- t.attach(self.odLabel, 0, 1, 7, 8)
+ self.odLabel.set_width_chars(8)
+ self.parent.entries.attach(self.odLabel, 0, 1, 7, 8)
self.odEntry = gtk.Entry()
- self.odEntry.set_width_chars(10)
- t.attach(self.odEntry, 1, 2, 7, 8)
- self.idLabel = gtk.Label('Inside Dia')
+ self.odEntry.set_width_chars(8)
+ self.odEntry.connect('activate', self.auto_preview)
+ self.odEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.odEntry, 1, 2, 7, 8)
+ self.idLabel = gtk.Label('Inner Dia')
self.idLabel.set_alignment(0.95, 0.5)
- self.idLabel.set_width_chars(10)
- t.attach(self.idLabel, 0, 1, 8, 9)
+ self.idLabel.set_width_chars(8)
+ self.parent.entries.attach(self.idLabel, 0, 1, 8, 9)
self.idEntry = gtk.Entry()
- self.idEntry.set_width_chars(10)
- t.attach(self.idEntry, 1, 2, 8, 9)
+ self.idEntry.set_width_chars(8)
+ self.idEntry.connect('activate', self.auto_preview)
+ self.idEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.idEntry, 1, 2, 8, 9)
aLabel = gtk.Label('Angle')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 9, 10)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 9, 10)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
+ self.aEntry.set_width_chars(8)
self.aEntry.set_text('0')
- t.attach(self.aEntry, 1, 2, 9, 10)
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 9, 10)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 11, 12)
+ preview.connect('pressed', self.star_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 11, 12)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 11, 12)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/star.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('origin'):
- if line.strip().split('=')[1] == 'True':
- self.centre.set_active(1)
- else:
- self.bLeft.set_active(1)
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ if self.parent.oSaved:
+ self.centre.set_active(1)
+ else:
+ self.bLeft.set_active(1)
+ self.liEntry.set_text(self.parent.leadIn)
+ # self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.pEntry.grab_focus()
diff --git a/configs/by_machine/plasmac/wizards/w_triangle.py b/configs/by_machine/plasmac/wizards/w_triangle.py
index 1146411a41..6f4a4559b4 100644
--- a/configs/by_machine/plasmac/wizards/w_triangle.py
+++ b/configs/by_machine/plasmac/wizards/w_triangle.py
@@ -29,90 +29,23 @@
import hal
from subprocess import Popen,PIPE
-class triangle:
+class triangle_wiz:
def __init__(self):
- self.i = linuxcnc.ini(os.environ['INI_FILE_NAME'])
- self.c = linuxcnc.command()
- self.s = linuxcnc.stat()
- self.gui = self.i.find('DISPLAY', 'DISPLAY').lower()
- self.configFile = '{}_wizards.cfg'.format(self.i.find('EMC', 'MACHINE').lower())
+ pass
- def dialog_error(self, error):
- md = gtk.MessageDialog(self.W,
- gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
- gtk.BUTTONS_CLOSE, error)
- md.run()
- md.destroy()
-
- def load_file(self, fName):
- if self.gui == 'axis':
- Popen('axis-remote {}'.format(fName), stdout = PIPE, shell = True)
- elif self.gui == 'gmoccapy':
- self.c = linuxcnc.command()
- self.c.program_open('./wizards/blank.ngc')
- self.c.program_open(fName)
- else:
- print('Unknown GUI in .ini file')
-
- def end_this_shape(self, event):
- if os.path.exists(self.fWizard):
- outWiz = open(self.fWizard, 'a+')
- post = False
- for line in outWiz:
- if '(postamble)' in line:
- post = True
- if not post:
- outWiz.write('\n(postamble)\n')
- outWiz.write('{}\n'.format(self.postamble))
- outWiz.write('m30\n')
- outWiz.close()
- self.load_file(self.fWizard)
- self.W.destroy()
- return None
-
- def add_shape_to_file(self, event):
- if os.path.exists(self.fWizard):
- path = os.path.dirname(os.path.abspath(self.fWizard))
- tmp = ('{}/tmp'.format(path))
- shutil.copyfile(self.fWizard, tmp)
- inWiz = open(tmp, 'r')
- outWiz = open(self.fWizard, 'w')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outWiz.write(line)
- inWiz.close()
- outWiz.close()
- os.remove(tmp)
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'a')
- for line in inTmp:
- outWiz.write(line)
+ def triangle_preview(self, event):
+ kOffset = hal.get_value('plasmac_run.kerf-width-f') * self.offset.get_active() / 2
+ if not self.xSEntry.get_text():
+ self.xSEntry.set_text('{:0.3f}'.format(self.parent.xOrigin))
+ if not self.ySEntry.get_text():
+ self.ySEntry.set_text('{:0.3f}'.format(self.parent.yOrigin))
+ if self.outside.get_active():
+ xBPoint = float(self.xSEntry.get_text()) + kOffset
+ yBPoint = float(self.ySEntry.get_text()) + kOffset
else:
- inTmp = open(self.fTmp, 'r')
- outWiz = open(self.fWizard, 'w')
- outWiz.write('(preamble)\n')
- outWiz.write('{}\n'.format(self.preamble))
- outWiz.write('f#<_hal[plasmac.cut-feed-rate]>\n')
- for line in inTmp:
- outWiz.write(line)
- inTmp.close()
- outWiz.close()
- self.add.set_sensitive(False)
-
- def send_preview(self, event):
- self.s.poll()
- xPos = self.s.actual_position[0] - self.s.g5x_offset[0] - self.s.g92_offset[0]
- yPos = self.s.actual_position[1] - self.s.g5x_offset[1] - self.s.g92_offset[1]
- if self.xSEntry.get_text():
- xBPoint = float(self.xSEntry.get_text())
- else:
- xBPoint = xPos
- if self.ySEntry.get_text():
- yBPoint = float(self.ySEntry.get_text())
- else:
- yBPoint = yPos
+ xBPoint = float(self.xSEntry.get_text()) - kOffset
+ yBPoint = float(self.ySEntry.get_text()) - kOffset
if self.angEntry.get_text():
angle = math.radians(float(self.angEntry.get_text()))
else:
@@ -165,229 +98,275 @@ def send_preview(self, event):
a = c / math.sin(C) * math.sin(A)
done = True
if done:
- xCPoint = xBPoint + a * math.cos(angle)
- yCPoint = yBPoint + a * math.sin(angle)
- xAPoint = xBPoint + c * math.cos(angle + B)
- yAPoint = yBPoint + c * math.sin(angle + B)
- xCentre = xBPoint + (a / 2) * math.cos(angle)
- yCentre = yBPoint + (a / 2) * math.sin(angle)
right = math.radians(0)
up = math.radians(90)
left = math.radians(180)
down = math.radians(270)
- if self.outside.get_active():
- dir = [down, right]
+ xCPoint = xBPoint + a * math.cos(angle)
+ yCPoint = yBPoint + a * math.sin(angle)
+ xAPoint = xBPoint + c * math.cos(angle + B)
+ yAPoint = yBPoint + c * math.sin(angle + B)
+ hypotLength = math.sqrt((xAPoint - xCPoint) ** 2 + (yAPoint - yCPoint) ** 2)
+ if xAPoint <= xCPoint:
+ hypotAngle = left - math.atan((yAPoint - yCPoint) / (xCPoint - xAPoint))
else:
- dir = [up, left]
- self.fTmp = '{}/shape.tmp'.format(self.tmpDir)
- self.fNgc = '{}/shape.ngc'.format(self.tmpDir)
- outTmp = open(self.fTmp, 'w')
- outNgc = open(self.fNgc, 'w')
- if os.path.exists(self.fWizard):
- inWiz = open(self.fWizard, 'r')
- for line in inWiz:
- if '(postamble)' in line:
- break
- outNgc.write(line)
+ hypotAngle = right - math.atan((yAPoint - yCPoint) / (xCPoint - xAPoint))
+ xS = xCPoint + (hypotLength / 2) * math.cos(hypotAngle)
+ yS = yCPoint + (hypotLength / 2) * math.sin(hypotAngle)
+ if self.outside.get_active():
+ if yAPoint >= yBPoint:
+ dir = [up, right]
+ else:
+ dir = [down, left]
else:
- outNgc.write('(preamble)\n')
- outNgc.write('{}\n'.format(self.preamble))
- outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ if yAPoint >= yBPoint:
+ dir = [down, left]
+ else:
+ dir = [up, right]
+ outTmp = open(self.parent.fTmp, 'w')
+ outNgc = open(self.parent.fNgc, 'w')
+ inWiz = open(self.parent.fNgcBkp, 'r')
+ for line in inWiz:
+ if '(new wizard)' in line:
+ outNgc.write('\n{} (preamble)\n'.format(self.parent.preamble))
+ outNgc.write('f#<_hal[plasmac.cut-feed-rate]>\n')
+ break
+ elif '(postamble)' in line:
+ break
+ elif 'm2' in line.lower() or 'm30' in line.lower():
+ break
+ outNgc.write(line)
outTmp.write('\n(wizard triangle)\n')
if leadInOffset > 0:
- xlCentre = xCentre + (leadInOffset * math.cos(angle + dir[0]))
- ylCentre = yCentre + (leadInOffset * math.sin(angle + dir[0]))
- xlStart = xlCentre + (leadInOffset * math.cos(angle + dir[1]))
- ylStart = ylCentre + (leadInOffset * math.sin(angle + dir[1]))
+ xlCentre = xS + (leadInOffset * math.cos(hypotAngle - dir[0]))
+ ylCentre = yS + (leadInOffset * math.sin(hypotAngle - dir[0]))
+ xlStart = xlCentre + (leadInOffset * math.cos(hypotAngle - dir[1]))
+ ylStart = ylCentre + (leadInOffset * math.sin(hypotAngle - dir[1]))
outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xlStart, ylStart))
if self.offset.get_active():
outTmp.write('g41.1 d#<_hal[plasmac_run.kerf-width-f]>\n')
outTmp.write('m3 $0 s1\n')
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xCentre, yCentre , xlCentre - xlStart, ylCentre - ylStart))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xS, yS , xlCentre - xlStart, ylCentre - ylStart))
else:
- outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xCentre, yCentre))
+ outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(xS, yS))
outTmp.write('m3 $0 s1\n')
if self.outside.get_active():
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xCPoint , yCPoint))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xBPoint , yBPoint))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xAPoint , yAPoint))
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xCPoint , yCPoint))
else:
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xCPoint , yCPoint))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xAPoint , yAPoint))
outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xBPoint , yBPoint))
- outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xCentre, yCentre))
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xCPoint , yCPoint))
+ outTmp.write('g1 x{:.6f} y{:.6f}\n'.format(xS, yS))
if leadOutOffset > 0:
if self.outside.get_active():
- dir = [down, left]
+ if yAPoint >= yBPoint:
+ dir = [up, left]
+ else:
+ dir = [down, right]
else:
- dir = [up, right]
- xlCentre = xCentre + (leadOutOffset * math.cos(angle + dir[0]))
- ylCentre = yCentre + (leadOutOffset * math.sin(angle + dir[0]))
- xlEnd = xlCentre + (leadOutOffset * math.cos(angle + dir[1]))
- ylEnd = ylCentre + (leadOutOffset * math.sin(angle + dir[1]))
- outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xCentre, ylCentre - yCentre))
+ if yAPoint >= yBPoint:
+ dir = [down, right]
+ else:
+ dir = [up, left]
+ xlCentre = xS + (leadOutOffset * math.cos(hypotAngle - dir[0]))
+ ylCentre = yS + (leadOutOffset * math.sin(hypotAngle - dir[0]))
+ xlEnd = xlCentre + (leadOutOffset * math.cos(hypotAngle - dir[1]))
+ ylEnd = ylCentre + (leadOutOffset * math.sin(hypotAngle - dir[1]))
+ outTmp.write('g3 x{:.6f} y{:.6f} i{:.6f} j{:.6f}\n'.format(xlEnd, ylEnd , xlCentre - xS, ylCentre - yS))
outTmp.write('g40\n')
- outTmp.write('m5\n')
+ outTmp.write('m5 $0\n')
outTmp.close()
- outTmp = open(self.fTmp, 'r')
+ outTmp = open(self.parent.fTmp, 'r')
for line in outTmp:
outNgc.write(line)
outTmp.close()
- outNgc.write('\n(postamble)\n')
- outNgc.write('{}\n'.format(self.postamble))
- outNgc.write('m30\n')
+ outNgc.write('\n{} (postamble)\n'.format(self.parent.postamble))
+ outNgc.write('m2\n')
outNgc.close()
- self.load_file(self.fNgc)
+ self.parent.preview.load(self.parent.fNgc)
self.add.set_sensitive(True)
- hal.set_p('plasmac_run.preview-tab', '1')
else:
if A <> 0 and B <> 0 and C <> 0 and A + B + C <> math.radians(180):
- self.dialog_error('A + B + C must equal 180')
+ self.parent.dialog_error('TRIANGLE', 'A + B + C must equal 180')
else:
- self.dialog_error('Minimum requirements are:\n\n'\
- 'a + b + c\n\n'\
- 'or\n\n'\
- 'a + b + C\n\n'\
- 'or\n\n'\
- 'a + B + c\n\n'\
- 'or\n\n'\
- 'A + b + c\n\n'\
- 'or\n\n'\
- 'A + B + C + (a or b or c)')
+ self.parent.dialog_error('TRIANGLE', 'Minimum requirements are:\n\n'\
+ 'a + b + c\n\n'\
+ 'or\n\n'\
+ 'a + b + C\n\n'\
+ 'or\n\n'\
+ 'a + B + c\n\n'\
+ 'or\n\n'\
+ 'A + b + c\n\n'\
+ 'or\n\n'\
+ 'A + B + C + (a or b or c)')
+
+ def auto_preview(self, widget):
+ if (self.AEntry.get_text() and self.BEntry.get_text() and self.CEntry.get_text() and \
+ (self.aEntry.get_text() or self.bEntry.get_text() or self.cEntry.get_text())) or \
+ (self.AEntry.get_text() and self.bEntry.get_text() and self.cEntry.get_text()) or \
+ (self.aEntry.get_text() and self.BEntry.get_text() and self.cEntry.get_text()) or \
+ (self.aEntry.get_text() and self.bEntry.get_text() and self.CEntry.get_text()) or \
+ (self.aEntry.get_text() and self.bEntry.get_text() and self.cEntry.get_text()):
+ self.triangle_preview('auto')
+
+ def entry_changed(self, widget):
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ else:
+ self.offset.set_sensitive(True)
+ self.parent.entry_changed(widget)
+
+ def add_shape_to_file(self, button):
+ self.parent.add_shape_to_file(self.add, self.xSEntry.get_text(), self.ySEntry.get_text(), None)
- def do_triangle(self, fWizard, tmpDir):
- self.tmpDir = tmpDir
- self.fWizard = fWizard
- self.W = gtk.Dialog('Triangle',
- None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- buttons = None)
- self.W.set_keep_above(True)
- self.W.set_position(gtk.WIN_POS_CENTER_ALWAYS)
- self.W.set_default_size(250, 200)
- t = gtk.Table(1, 1, True)
- t.set_row_spacings(6)
- self.W.vbox.add(t)
+ def triangle_show(self, parent):
+ self.parent = parent
+ self.parent.entries.set_row_spacings(self.parent.rowSpace)
+ for child in self.parent.entries.get_children():
+ self.parent.entries.remove(child)
cutLabel = gtk.Label('Cut Type')
cutLabel.set_alignment(0.95, 0.5)
- cutLabel.set_width_chars(10)
- t.attach(cutLabel, 0, 1, 0, 1)
+ cutLabel.set_width_chars(8)
+ self.parent.entries.attach(cutLabel, 0, 1, 0, 1)
self.outside = gtk.RadioButton(None, 'Outside')
- t.attach(self.outside, 1, 2, 0, 1)
+ self.outside.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.outside, 1, 2, 0, 1)
inside = gtk.RadioButton(self.outside, 'Inside')
- t.attach(inside, 2, 3, 0, 1)
+ self.parent.entries.attach(inside, 2, 3, 0, 1)
offsetLabel = gtk.Label('Offset')
offsetLabel.set_alignment(0.95, 0.5)
- offsetLabel.set_width_chars(10)
- t.attach(offsetLabel, 3, 4, 0, 1)
- self.offset = gtk.CheckButton('Kerf Width')
- t.attach(self.offset, 4, 5, 0, 1)
+ offsetLabel.set_width_chars(8)
+ self.parent.entries.attach(offsetLabel, 3, 4, 0, 1)
+ self.offset = gtk.CheckButton('Kerf')
+ self.offset.connect('toggled', self.auto_preview)
+ self.parent.entries.attach(self.offset, 4, 5, 0, 1)
lLabel = gtk.Label('Lead In')
lLabel.set_alignment(0.95, 0.5)
- lLabel.set_width_chars(10)
- t.attach(lLabel, 0, 1, 1, 2)
+ lLabel.set_width_chars(8)
+ self.parent.entries.attach(lLabel, 0, 1, 1, 2)
self.liEntry = gtk.Entry()
- self.liEntry.set_width_chars(10)
- t.attach(self.liEntry, 1, 2, 1, 2)
+ self.liEntry.set_width_chars(8)
+ self.liEntry.connect('activate', self.auto_preview)
+ self.liEntry.connect('changed', self.entry_changed)
+ self.parent.entries.attach(self.liEntry, 1, 2, 1, 2)
loLabel = gtk.Label('Lead Out')
loLabel.set_alignment(0.95, 0.5)
- loLabel.set_width_chars(10)
- t.attach(loLabel, 0, 1, 2, 3)
+ loLabel.set_width_chars(8)
+ self.parent.entries.attach(loLabel, 0, 1, 2, 3)
self.loEntry = gtk.Entry()
- self.loEntry.set_width_chars(10)
- t.attach(self.loEntry, 1, 2, 2, 3)
- xSLabel = gtk.Label('X start')
+ self.loEntry.set_width_chars(8)
+ self.loEntry.connect('activate', self.auto_preview)
+ self.loEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.loEntry, 1, 2, 2, 3)
+ xSLabel = gtk.Label()
+ xSLabel.set_markup('X origin')
xSLabel.set_alignment(0.95, 0.5)
- xSLabel.set_width_chars(10)
- t.attach(xSLabel, 0, 1, 3, 4)
+ xSLabel.set_width_chars(8)
+ self.parent.entries.attach(xSLabel, 0, 1, 3, 4)
self.xSEntry = gtk.Entry()
- self.xSEntry.set_width_chars(10)
- t.attach(self.xSEntry, 1, 2, 3, 4)
- ySLabel = gtk.Label('Y start')
+ self.xSEntry.set_width_chars(8)
+ self.xSEntry.connect('activate', self.auto_preview)
+ self.xSEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.xSEntry, 1, 2, 3, 4)
+ ySLabel = gtk.Label()
+ ySLabel.set_markup('Y origin')
ySLabel.set_alignment(0.95, 0.5)
- ySLabel.set_width_chars(10)
- t.attach(ySLabel, 0, 1, 4, 5)
+ ySLabel.set_width_chars(8)
+ self.parent.entries.attach(ySLabel, 0, 1, 4, 5)
self.ySEntry = gtk.Entry()
- self.ySEntry.set_width_chars(10)
- t.attach(self.ySEntry, 1, 2, 4, 5)
+ self.ySEntry.set_width_chars(8)
+ self.ySEntry.connect('activate', self.auto_preview)
+ self.ySEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.ySEntry, 1, 2, 4, 5)
ALabel = gtk.Label('A angle')
ALabel.set_alignment(0.95, 0.5)
- ALabel.set_width_chars(10)
- t.attach(ALabel, 0, 1, 5, 6)
+ ALabel.set_width_chars(8)
+ self.parent.entries.attach(ALabel, 0, 1, 5, 6)
self.AEntry = gtk.Entry()
- self.AEntry.set_width_chars(10)
- t.attach(self.AEntry, 1, 2, 5, 6)
+ self.AEntry.set_width_chars(8)
+ self.AEntry.connect('activate', self.auto_preview)
+ self.AEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.AEntry, 1, 2, 5, 6)
BLabel = gtk.Label('B angle')
BLabel.set_alignment(0.95, 0.5)
- BLabel.set_width_chars(10)
- t.attach(BLabel, 0, 1, 6, 7)
+ BLabel.set_width_chars(8)
+ self.parent.entries.attach(BLabel, 0, 1, 6, 7)
self.BEntry = gtk.Entry()
- self.BEntry.set_width_chars(10)
- t.attach(self.BEntry, 1, 2, 6, 7)
+ self.BEntry.set_width_chars(8)
+ self.BEntry.connect('activate', self.auto_preview)
+ self.BEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.BEntry, 1, 2, 6, 7)
CLabel = gtk.Label('C angle')
CLabel.set_alignment(0.95, 0.5)
- CLabel.set_width_chars(10)
- t.attach(CLabel, 0, 1, 7, 8)
+ CLabel.set_width_chars(8)
+ self.parent.entries.attach(CLabel, 0, 1, 7, 8)
self.CEntry = gtk.Entry()
- self.CEntry.set_width_chars(10)
- t.attach(self.CEntry, 1, 2, 7, 8)
+ self.CEntry.set_width_chars(8)
+ self.CEntry.connect('activate', self.auto_preview)
+ self.CEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.CEntry, 1, 2, 7, 8)
aLabel = gtk.Label('a length')
aLabel.set_alignment(0.95, 0.5)
- aLabel.set_width_chars(10)
- t.attach(aLabel, 0, 1, 8, 9)
+ aLabel.set_width_chars(8)
+ self.parent.entries.attach(aLabel, 0, 1, 8, 9)
self.aEntry = gtk.Entry()
- self.aEntry.set_width_chars(10)
- t.attach(self.aEntry, 1, 2, 8, 9)
+ self.aEntry.set_width_chars(8)
+ self.aEntry.connect('activate', self.auto_preview)
+ self.aEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.aEntry, 1, 2, 8, 9)
bLabel = gtk.Label('b length')
bLabel.set_alignment(0.95, 0.5)
- bLabel.set_width_chars(10)
- t.attach(bLabel, 0, 1, 9, 10)
+ bLabel.set_width_chars(8)
+ self.parent.entries.attach(bLabel, 0, 1, 9, 10)
self.bEntry = gtk.Entry()
- self.bEntry.set_width_chars(10)
- t.attach(self.bEntry, 1, 2, 9, 10)
+ self.bEntry.set_width_chars(8)
+ self.bEntry.connect('activate', self.auto_preview)
+ self.bEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.bEntry, 1, 2, 9, 10)
cLabel = gtk.Label('c length')
cLabel.set_alignment(0.95, 0.5)
- cLabel.set_width_chars(10)
- t.attach(cLabel, 0, 1, 10, 11)
+ cLabel.set_width_chars(8)
+ self.parent.entries.attach(cLabel, 0, 1, 10, 11)
self.cEntry = gtk.Entry()
- self.cEntry.set_width_chars(10)
- t.attach(self.cEntry, 1, 2, 10, 11)
+ self.cEntry.set_width_chars(8)
+ self.cEntry.connect('activate', self.auto_preview)
+ self.cEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.cEntry, 1, 2, 10, 11)
angLabel = gtk.Label('Angle')
angLabel.set_alignment(0.95, 0.5)
- angLabel.set_width_chars(10)
- t.attach(angLabel, 0, 1, 11, 12)
+ angLabel.set_width_chars(8)
+ self.parent.entries.attach(angLabel, 0, 1, 11, 12)
self.angEntry = gtk.Entry()
- self.angEntry.set_width_chars(10)
+ self.angEntry.set_width_chars(8)
self.angEntry.set_text('0')
- t.attach(self.angEntry, 1, 2, 11, 12)
+ self.angEntry.connect('activate', self.auto_preview)
+ self.angEntry.connect('changed', self.parent.entry_changed)
+ self.parent.entries.attach(self.angEntry, 1, 2, 11, 12)
preview = gtk.Button('Preview')
- preview.connect('pressed', self.send_preview)
- t.attach(preview, 0, 1, 13, 14)
+ preview.connect('pressed', self.triangle_preview)
+ self.parent.entries.attach(preview, 0, 1, 12, 13)
self.add = gtk.Button('Add')
self.add.set_sensitive(False)
self.add.connect('pressed', self.add_shape_to_file)
- t.attach(self.add, 2, 3, 13, 14)
- end = gtk.Button('Return')
- end.connect('pressed', self.end_this_shape)
- t.attach(end, 4, 5, 13, 14)
+ self.parent.entries.attach(self.add, 2, 3, 12, 13)
+ undo = gtk.Button('Undo')
+ undo.connect('pressed', self.parent.undo_shape, self.add)
+ self.parent.entries.attach(undo, 4, 5, 12, 13)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
filename='./wizards/images/triangle.png',
width=240,
height=240)
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
- t.attach(image, 2, 5, 1, 9)
- self.xSEntry.grab_focus()
- self.W.show_all()
- if os.path.exists(self.configFile):
- f_in = open(self.configFile, 'r')
- for line in f_in:
- if line.startswith('preamble'):
- self.preamble = line.strip().split('=')[1]
- elif line.startswith('postamble'):
- self.postamble = line.strip().split('=')[1]
- elif line.startswith('lead-in'):
- self.liEntry.set_text(line.strip().split('=')[1])
- elif line.startswith('lead-out'):
- self.loEntry.set_text(line.strip().split('=')[1])
- response = self.W.run()
+ self.parent.entries.attach(image, 2, 5, 1, 9)
+ self.liEntry.set_text(self.parent.leadIn)
+ self.loEntry.set_text(self.parent.leadOut)
+ self.xSEntry.set_text('{}'.format(self.parent.xSaved))
+ self.ySEntry.set_text('{}'.format(self.parent.ySaved))
+ if not self.liEntry.get_text() or float(self.liEntry.get_text()) == 0:
+ self.offset.set_sensitive(False)
+ self.parent.undo_shape(None, self.add)
+ self.parent.W.show_all()
+ self.AEntry.grab_focus()
diff --git a/configs/by_machine/sherline/README_es b/configs/by_machine/sherline/README_es
new file mode 100644
index 0000000000..eafe1f60b9
--- /dev/null
+++ b/configs/by_machine/sherline/README_es
@@ -0,0 +1,3 @@
+Sherline Proucts
+
+www.sherline.com
diff --git a/configs/by_machine/sherline/Sherline3Axis/README_es b/configs/by_machine/sherline/Sherline3Axis/README_es
new file mode 100644
index 0000000000..3a9ba54b49
--- /dev/null
+++ b/configs/by_machine/sherline/Sherline3Axis/README_es
@@ -0,0 +1,7 @@
+This configuration step is intended for Sherline 3-axis stepper machines.
+
+Sherline3Axis_inch.ini
+ inch units
+
+Sherline3Axis_mm.ini
+ metric units
diff --git a/configs/by_machine/sherline/Sherline4Axis/README_es b/configs/by_machine/sherline/Sherline4Axis/README_es
new file mode 100644
index 0000000000..3ed7592e4f
--- /dev/null
+++ b/configs/by_machine/sherline/Sherline4Axis/README_es
@@ -0,0 +1,7 @@
+This configuration step is intended for Sherline 4-axis stepper machines.
+
+Sherline4Axis_inch.ini
+ inch units
+
+Sherline4Axis_mm.ini
+ metric units
diff --git a/configs/by_machine/sherline/SherlineLathe/README_es b/configs/by_machine/sherline/SherlineLathe/README_es
new file mode 100644
index 0000000000..4f82950bfd
--- /dev/null
+++ b/configs/by_machine/sherline/SherlineLathe/README_es
@@ -0,0 +1,7 @@
+This configuration step is intended for Sherline stepper lathes.
+
+SherlineLathe_inch.in
+ inch units
+
+SherlineLathe_mm.in
+ metric units
diff --git a/configs/by_machine/smithy/README_es b/configs/by_machine/smithy/README_es
new file mode 100644
index 0000000000..586ad5e692
--- /dev/null
+++ b/configs/by_machine/smithy/README_es
@@ -0,0 +1,49 @@
+Smithy
+
+www.smithy.com
+
+
+Estas configuraciones son para las siguientes máquinas Smithy:
+
+1240 - Fresadora equipada con driver de ejes Leadshine, VFD y husillo de motor de inducción de C.A. de 1.5kW, y controlada por señales de una tarjeta Mesa 5i20 FPGA.
+
+1240_4axis - Fresadora equipada con drivers de eje Leadshine, VFD y husillo de motor de inducción de C.A. de 1.5kW, 4.º eje giratorio, y controlados por señales de
+una tarjeta Mesa 5i20 FPGA.
+
+1240combined - Fresadora equipada con drivers trifásicos Leadshine, driver Mesa 8i20 BLDC de motor de husillo de 6000RPM, y controlada por señales de una tarjeta
+FPGA Mesa 5i20.
+
+1240combined_4axis - Fresadora equipada con drivers trifásicos Leadshine, driver Mesa 8i20 BLDC de motor de husillo de 6000RPM, 4º eje rotativo (dos fases) y
+controlado por señales de una tarjeta FPGA Mesa 5i20.
+
+1240combined_mm - Versión métrica de 1240combined.
+
+1034gecko/1240gecko - Fresadora equipada con drivers Gecko G201, VFD y husillo de motor de inducción de C.A. de 1.5kW, y controlada por señales desde un puerto paralelo de PC.
+
+1240rutex - Fresadora equipada con servomotores de escobillas Rutex DC, husillo de motor de inducción de C.A. de 1.5kW con avance y retroceso, y controlado por señales
+desde un puerto paralelo de PC.
+
+1240rutex_4axis - Fresadora equipada con servomotores de escobillas Rutex DC, husillo de motor de inducción de C.A. de 1.5kW con avance y retroceso, 4º eje rotativo, y
+controlado por señales desde un puerto paralelo de PC.
+
+516gecko: Fresadora equipada con drivers Gecko G201, husillo de C.C. sin escobillas de velocidad variable Sieg y controlada por señales desde un puerto paralelo de PC.
+
+622 - Fresadora equipada con drivers YAKO Automation, husillo de C.C. sin escobillas de velocidad variable Sieg y controlada por señales de una tarjeta FPGA Mesa 5i20.
+
+622_4axis - Fresadora equipada con drivers YAKO Automation, husillo de C.C. sin escobillas de velocidad variable Sieg, cuarto eje giratorio y controlado por señales de
+una tarjeta Mesa 5i20 FPGA.
+
+622gecko - Fresadora equipada con drivers Gecko G201, husillo de C.C. sin escobillas de velocidad variable Sieg y controlada por señales desde un puerto paralelo de PC.
+
+622keyence - Fresadora equipada con drivers Leadshine MD2278, husillo de C.C. sin escobillas de velocidad variable Sieg, sensor de contacto digital Keyence, aspirador de
+viruta y controlado por señales de una tarjeta Mesa 5i20 FPGA.
+
+622leadshine - Fresadora equipada con drivers Leadshine MD2278, husillo de C.C. sin escobillas de velocidad variable Sieg y controladas por señales de una tarjeta
+Mesa 5i20 FPGA.
+
+924 - Torno equipado con drivers YAKO Automation, husillo de C.C. sin escobillas de velocidad variable Sieg, puesto de herramienta programable y controlado por
+señales de una tarjeta Mesa 5i20 FPGA.
+
+6130 - Torno equipado con drivers de eje trifásico Leadshine, motor de husillo de inducción VFD y AC, puesto de herramientas programable y controlado por señales
+de una tarjeta Mesa 5i20 FPGA.
+
diff --git a/configs/by_machine/tormach/README_es b/configs/by_machine/tormach/README_es
new file mode 100644
index 0000000000..23ae9c35da
--- /dev/null
+++ b/configs/by_machine/tormach/README_es
@@ -0,0 +1,5 @@
+Tormach
+
+www.tormach.com
+
+Configuraciones para Tormach PCNC-1100 Series II y PCNC-770.
diff --git a/configs/maintainer_es.txt b/configs/maintainer_es.txt
new file mode 100644
index 0000000000..e9d07648ff
--- /dev/null
+++ b/configs/maintainer_es.txt
@@ -0,0 +1,132 @@
+maintainer.txt:
+
+Notas generales para el directorio de configuraciones, root/configs.
+'root' se refiere al nivel superior del árbol git de linuxcnc.
+
+-------------------------------------------------------
+
+El directorio config contiene una jerarquía de configuraciones,
+cada una con uno o más archivos ini, que están destinadas a:
+
+
+ 1) ejecutarse tal cual en una compilación RIP (ejecución en el lugar)
+ 2) ejecutarse cuando se copia al directorio de usuario ~/linuxcnc
+ por el selector de configuración (pickconfig.tcl)
+
+Nota: Casos especiales.
+ Cualquier archivo llamado _panelui.ini es ignorado
+
+Adicionalmente, los scripts de demostración identificados por un archivo
+con extensión .demo, puede ejecutarse de forma independiente para mostrar funcionalidades
+relacionadas con linuxcnc sin necesidad de arrancar linuxcnc.
+Un directorio configs no debe contener archivos .ini y .demo a la vez.
+
+Se ofrecen directorios para aplicaciones .demo por defecto
+para copiar a un directorio de usuario. Algunas aplicaciones no son útiles
+al copiarlas por lo que un directorio que contiene archivos .demo (y
+no archivos .ini) no se copiarán si el directorio incluye un
+archivo llamado 'nodemocopy'.
+
+Cuando se crea un acceso directo de escritorio para una aplicación .demo copiada,
+el acceso directo ejecutará el archivo .demo. El entorno
+para archivos ejecutados por archivos .desktop está limitado, por lo que se debe
+tener un cuidado especial para garantizar que un acceso directo de escritorio
+creado para un archivo .demo sea utilizable.
+
+-------------------------------------------------------
+
+El selector de configuración (pickconfig.tcl) recorre las
+configuraciones _de usuario_ existentes en ~/linuxcnc/configs y /configs del
+directorio raíz de la distribución. Presenta ambas
+configuraciones existentes; configuraciones de usuario y de muestra.
+Cuando se selecciona una configuración de muestra, el selector de configuración:
+
+ 1) crea un directorio en ~/linuxcnc/configs para el
+ elemento seleccionado y copia todos los archivos y directorios
+ relevantes al directorio recién creado. Cuando
+ se produce una duplicacion de nombres, el selector agrega un número
+ al nombre del directorio para que sea distinto.
+
+ 2) crea un directorio ~/linuxcnc/nc_files (si
+ no existe). Crea enlaces en este directorio
+ a las ubicaciones de sistema de los ejemplos y bibliotecas
+ (examples, ngcgui_lib, gladevcp_lib)
+
+ 3) edita todos los archivos ini que se copian haciendo que
+ [DISPLAY]PROGRAM_PREFIX = ~/linuxcnc/nc_files.
+
+Un proceso similar ocurre para los archivos de demostración (.demo) cuando
+se copian los directorios de los archivos .demo (solo cuando no hay ningún archivo
+con el nombre 'nodemocopy').
+
+La mayoría de los scripts de demostración de propósito general pueden ser localizados
+en el directorio root/configs/apps y su subdirectorios.
+
+-------------------------------------------------------
+
+Un directorio de configuración puede contener subdirectorios.
+
+Si un subdirectorio contiene un archivo con un sufijo .ini o
+.demo, se considera un directorio de configuracion seleccionable
+y se incluirá en el árbol de selección proporcionado por
+el selector de configuraciones.
+
+Los subdirectorios requeridos para otros fines no deben
+contener archivos con sufijo .ini o .demo.
+
+Cuando un subdirectorio requiere recursos de otro archivo o directorio
+que son compartidos por otras configuraciones, debería usar un
+enlace simbólico al archivo o directorio padres. El selector de
+configuraciones copia el archivo o directorio al que hace referencia
+el enlace simbólico. De esta manera, el uso de enlaces simbólicos reduce
+el número de archivos reales en el árbol git.
+
+-------------------------------------------------------
+
+Se anticipa la reubicación ocasional de directorios de configuración dentro
+del árbol root/configs. Para minimizar la edición de archivos requeridos
+para tales movimientos, se aplican las siguientes pautas:
+
+Es posible que los archivos .ini deban hacer referencia a los recursos de
+root/nc_files. El caso más común, [DISPLAY]PROGRAM_PREFIX, se maneja como
+se describió anteriormente. Otros ejemplos incluyen elementos de ruta como:
+
+ [RS274NGC]SUBROUTINE_PATH =
+ [RS274NGC]USER_M_PATH =
+
+Los elementos como estos deben referirse a ../../nc_files y usar
+enlaces simbólicos apropiados dentro del directorio de configuración.
+
+Ejemplo:
+ Una configuración llamada: root/configs/sim/axis/ngcgui podría, por
+ ejemplo, referirse a:
+ [RS274NGC]SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+
+ El directorio root/configs/sim debe contener un enlace simbólico:
+ root/configs/sim/nc_files -> ../../nc_files
+ para que la referencia del archivo ini funcione en compilaciones RIP.
+
+Estas convenciones funcionan porque:
+
+ 1) Las configuraciones de usuario copiadas
+ tienen configuraciones ubicadas en --------- ~/linuxcnc/configs/
+ y nc_files ubicados como ------------------- ~/linuxcnc/nc_files/
+
+ Así que si los archivos ini siempre se refieren a root/nc_files como
+ ../../nc_files
+ no requerirán modificaciones cuando se copien a
+ directorios de usuarios ni cuando se muevan dentro del
+ árbol de distribución
+
+ 2) Los enlaces simbólicos generalmente requieren hacer que ../../nc_files
+ resuelva a root/nc_files (para uso RIP).
+
+ Debido a esto, los enlaces simbólicos para nc_files nunca se copian
+ a los directorios de usuario.
+
+
+-------------------------------------------------- -----
+Cualquier directorio de configuración puede incluir un archivo llamado
+mantainer.txt para incluir comentarios o detalles sobre el mantenimiento de la
+configuración. Estos archivos no serán copiados al directorio de
+configuración del usuario.
diff --git a/configs/sim/README_es b/configs/sim/README_es
new file mode 100644
index 0000000000..da4d5fe609
--- /dev/null
+++ b/configs/sim/README_es
@@ -0,0 +1,5 @@
+Las configuraciones Sim permiten ejecutar LinuxCNC sin hardware especial de forma simulada.
+
+LinuxCNC admite múltiples guis y existen múltiples ejemplos de las guis más populares.
+
+Las configuraciones sim están diseñadas para ejecutarse sin requisitos de hardware especiales
diff --git a/configs/sim/axis/README_es b/configs/sim/axis/README_es
new file mode 100644
index 0000000000..7e818f8d11
--- /dev/null
+++ b/configs/sim/axis/README_es
@@ -0,0 +1,33 @@
+Axis es una moderna interfaz basada en GL y codificada en Python
+
+Archivos ini principales de Axis gui sim:
+
+axis.ini demo básica (in).
+axis_9axis.ini 9 ejes.
+axis_mm.ini demo básica (mm).
+canterp.ini demo de intérprete
+ no-gcode.
+gantry.ini demo pórtico.
+gantry_mm.ini demo pórtico (mm).
+histogram_demo.ini ejemplos
+ hal-histogram.
+historical_lathe.ini torno, 3 articula-
+ -ciones (XYZ, con Y
+ sin usar).
+ini_hal_demo.ini demo ini pines hal.
+lathe.ini demo torno.
+ldelta.ini robot delta lineal.
+ldelta_demo.ini robot delta lineal
+ con gui para jog.
+minimal_xyz.ini conjunto mínimo de
+ configuración.
+profile_axis.ini perfil.
+random_tc.ini cambiador aleatorio.
+ de herramientas.
+rdelta.ini robot delta rotativo.
+
+Seleccione uno de estos si no tiene una máquina funcional pero desea editar algunas cosas de configuración básica o jugar con una de las pantallas de LinuxCNC.
+
+Se proporcionan configuraciones adicionales en los subdirectorios.
+
+Estas configuraciones demuestran la funcionalidad de LinuxCNC utilizando la interfaz Axis. (La funcionalidad demostrada puede estar disponible tambien en otras guis)
diff --git a/configs/sim/axis/classicladder/README_es b/configs/sim/axis/classicladder/README_es
new file mode 100644
index 0000000000..e1a77c8b07
--- /dev/null
+++ b/configs/sim/axis/classicladder/README_es
@@ -0,0 +1,5 @@
+Esta configuración es una máquina de pasos simulada con la adición de conexiones ClassicLadder a algunas de las IO de LinuxCNC.
+
+El programa inicial de escalera incluye varias configuraciones posibles de e-stop y una bobina para lubricación temporizada. La escalera de lubricación incluye una carrera de detección que observa el nivel de lubricación o la presión de lubricación y advierte sobre un fallo en la condición de engrase.
+
+Esta integración de escalera con HAL le permitirá expandir la interfaz IO a una fresadora con controles de husillo y cambiador de herramientas.
diff --git a/configs/sim/axis/corexy/README_es b/configs/sim/axis/corexy/README_es
new file mode 100644
index 0000000000..089387c85b
--- /dev/null
+++ b/configs/sim/axis/corexy/README_es
@@ -0,0 +1,50 @@
+corexy examples:
+
+corexy_by_kins.ini
+ Demonstrates corexykins kinematics
+ (Note: using corexykins kinematics
+ on real hardware requires home
+ switches triggered by motor
+ positions)
+
+corexy_by_hal.ini
+ Demonstrates use of trivkins with
+ corexy kinematics implemented by a
+ hal component
+ (Notes: this method supports
+ home switches aligned with x,y
+ coordinates)
+
+Notes:
+ 1) The configurations share common ini
+ file settings from corey_base.inc
+ 2) Home switches are simulated
+ 3) stepgens are configured but no
+ connections to hardware are
+ included.
+
+
+Ejemplos corexy:
+
+corexy_by_kins.ini
+ Demuestra la cinemática corexykins
+ (Nota: el uso de la cinemática
+ corexykins en hardware real
+ requiere interruptores home
+ activados por las posiciones
+ del motor)
+
+corexy_by_hal.ini
+ Demuestra el uso de trivkins con
+ cinemática corexy implementada
+ por un componente hal (Notas:
+ este método admite interruptores
+ home alineados con x,y)
+
+Notas:
+ 1) Las configuraciones comparten
+ archivos ini comunes de corey_base.inc
+ 2) Los interruptores home son simulados
+ 3) los stepgens están configurados
+ pero no se incluyen conexiones
+ al hardware.
diff --git a/configs/sim/axis/external_offsets/README_es b/configs/sim/axis/external_offsets/README_es
new file mode 100644
index 0000000000..e1d04b7588
--- /dev/null
+++ b/configs/sim/axis/external_offsets/README_es
@@ -0,0 +1,4 @@
+eoffset_demo.ini ----- Demo basica (XYZ)
+jwp_z.ini ------------ Jog con (Z) en pausa
+dynamic_offsets.ini -- formas de onda Z offset
+opa.ini -------------- Offset por Angulo (XZC)
diff --git a/configs/sim/axis/external_offsets/dynamic_offsets_es.txt b/configs/sim/axis/external_offsets/dynamic_offsets_es.txt
new file mode 100644
index 0000000000..c0db213707
--- /dev/null
+++ b/configs/sim/axis/external_offsets/dynamic_offsets_es.txt
@@ -0,0 +1,37 @@
+dynamic_offsets
+
+Se aplica una onda sinusoidal al desplazamiento externo de la coordenada Z
+
+El amplitud y frecuencia de la forma de onda se establecen mediante spinboxes de panel pyvcp.
+
+La configuración de aceleración máxima y velocidad máxima de coordenadas Z (del archivo ini) se puede modificar con los spinboxes del panel pyvcp.
+
+Uso:
+ 1) Estop OFF (F1)
+ 2) Máquina ON (F2)
+ 3) HOME Todo (Ctrl-Inicio)
+ 4) Se inicia una aplicación de halscope
+ para mostrar los offsets de formas
+ de onda y la respuesta de
+ la coordenada z
+ 5) Habilita offset dinamico de la forma
+ de onda con la casilla 'Habilitar Z'
+ del panel
+ 6) Use el panel para ajustar:
+ Forma de onda: amplitud, frecuencia
+ Coordenada Z: max accel, max vel
+
+Notas:
+ La forma de onda dinámica se aplica
+ con y sin ejecutar un programa.
+
+ MDI no puede iniciarse con offsets
+ externas que no sean cero: deshabilite
+ los offsets Z y active/desactive la
+ máquina para offsets cero.
+
+ Los cambios en la aceleración máxima
+ máxima vel de Z no se realizan mientras
+ un programa o movimiento mdi esté
+ en progreso.
+
diff --git a/configs/sim/axis/external_offsets/eoffsets_es.txt b/configs/sim/axis/external_offsets/eoffsets_es.txt
new file mode 100644
index 0000000000..0559ac2a28
--- /dev/null
+++ b/configs/sim/axis/external_offsets/eoffsets_es.txt
@@ -0,0 +1,26 @@
+eoffsets.ini
+
+Uso:
+ 1) Estop OFF (F1)
+ 2) Máquina ON (F2)
+ 3) HOME Todo (Ctrl-Home)
+ 4) Explorar funcionalidad de offset
+ externos usando gui sim_pin para
+ alterar los pines hal por eje:
+
+ e:xcounts (señal a => axis.x.eoffset-counts)
+ e:ycounts (señal a=> axis.y.eoffset-counts)
+ e:zcounts (señal a=> axis.z.eoffset-counts)
+ e:clearall (señal a=> axis.*.eoffset-clear)
+
+-------------------------------------------
+Note: El interface de offsets externos es
+similar al de jog por volante:
+
+Pines Input hal:
+ axis.L.eoffset-enable (bit)
+ axis.L.eoffset-clear (bit)
+ axis.L.eoffset-scale (float)
+ axis.L.eoffset-counts (s32)
+
+Offset solicitado == counts*scale
diff --git a/configs/sim/axis/external_offsets/jwp_z_es.txt b/configs/sim/axis/external_offsets/jwp_z_es.txt
new file mode 100644
index 0000000000..f25c0135f8
--- /dev/null
+++ b/configs/sim/axis/external_offsets/jwp_z_es.txt
@@ -0,0 +1,16 @@
+jwp_z.ini
+
+Usage:
+ 1) Estop OFF (F1)
+ 2) Máquina ON (F2)
+ 3) HOME Todo (Ctrl-Home)
+ 4) Correr programa (R)
+ 5) pausa inicial:
+ ajuste z offset (+Incr/-Decr)
+ 6) Reanudar (S)
+ 7) Pausa (P)
+ ajuste z offset (+Incr/-Decr)
+ 8) Reanudar (R)
+ 9) Pausa final
+ volver offset a zero (+Incr/-Decr)
+ o borrar
diff --git a/configs/sim/axis/external_offsets/opa_es.txt b/configs/sim/axis/external_offsets/opa_es.txt
new file mode 100644
index 0000000000..5849f03227
--- /dev/null
+++ b/configs/sim/axis/external_offsets/opa_es.txt
@@ -0,0 +1,46 @@
+opa.ini Offset per Angle
+
+Demuestra offsets externos utilizando
+el componente hal: eoffset_per_angle.
+
+Una simulación para una máquina XZC
+desplaza la coordenada transversal
+(X) basada en el ángulo de la
+coordenada giratoria (C).
+
+($ man eoffset_per_angle)
+
+Uso:
+ 1) Estop OFF (F1)
+ 2) Máquina ON (F2)
+ 3) HOME Todo (Ctrl-Inicio)
+ 4) Ejecutar (R)
+ 5) Activar/Desactivar offsets usando
+ los botones de encendido/apagado
+ del panel pyvcp
+ 6) Seleccionar parámetros:
+ Inicio ---- ángulo de inicio
+ fmult ----- multiplicador de frecuencia
+ rfracción - amplitud (fracción de radio)
+ func ------ función
+ 0 polígono (dentro)
+ 1 polígono (exterior)
+ 2 ondas sinusoidales
+ Onda cuadrada 3
+
+Notas:
+
+1) El radio efectivo utilizado para
+ calcular los offsets externos se
+ establece utilizando el pin de
+ movimiento motion.analog-out-00
+ y controlado por el programa de
+ muestra o por MDI
+ (M68 E0 Q some_radius_value)
+
+2) La fidelidad de offset depende de
+ la configuración de archivos para
+ los elementos [AXIS_X]:
+ MAX_VELOCITY
+ MAX_ACCELERATION
+ OFFSET_AV_RATIO
diff --git a/configs/sim/axis/gantry/README_es b/configs/sim/axis/gantry/README_es
new file mode 100644
index 0000000000..0a3e3b7665
--- /dev/null
+++ b/configs/sim/axis/gantry/README_es
@@ -0,0 +1,13 @@
+Configuración Sim gui Axis para porticos
+usando 2 articulaciones en Y
+
+Usar trivkins coordinates=XYZY kinstype=BOTH
+X: articulacion0
+Y: articulacion1 y articulacion3
+Z: articulacion2
+
+gantry.ini Portico básico (in)
+gantry_mm.ini Portico basico (mm)
+
+gantry_jjog.ini demo para jog articulacion1 y
+articulacion3 (in)
diff --git a/configs/sim/axis/gantry/gantry_jjog_es.txt b/configs/sim/axis/gantry/gantry_jjog_es.txt
new file mode 100644
index 0000000000..a0fff6d48b
--- /dev/null
+++ b/configs/sim/axis/gantry/gantry_jjog_es.txt
@@ -0,0 +1,57 @@
+Configuracion sim gantry_jjog
+
+o Configuraciones predeterminadas que sincronizan el
+ movimiento final de homing para múltiples articulaciones
+ no permitiendo jog individual de tales articulaciones ya
+ que tales movimientos invitan al operador al error y a
+ desviaciones del pórtico. Esta configuración más
+ compleja demuestra:
+
+Jogging individual en modo articulación para articulación1
+y articulación3
+
+Jogging sincronizado en modo articulación para articulación1
+y articulación3
+
+
+Procedimiento de ejemplo:
+
+ 1) Estop-Off (F1)
+ 2) Máquina-On (F2)
+ 3) Establecer halscope en "Roll" y cambiar tamaño
+ 4) Panel "J1,3 JOGGING": establecer ENABLE en ON
+ para permitir jogging de la articulación1 y la
+ articulación3
+ 5) usar COUNTS para jog tanto de articulación1 y la
+ articulación3 SINCRÓNICAMENTE en tiempo real
+ 6) usar los botones radio del número de jog de
+ axisgui y los botones más (+) y menos (-) para
+ jog INDIVIDUAL de cualquier articulación.
+ NOTA: esto DESVIARA un pórtico de motores tandem.
+ 7) Panel "J1,3 JOGGING": establezca ENABLE en OFF
+ para permitir homing
+ 8) HOME Todos (Ctrl-Inicio) para dar home a todas
+ las articulaciones (puede ser necesario mover
+ primero todas las articulaciones cerca de cero para
+ simular correctamente los interruptores home)
+ 9) Usar los botones radio axisgui X, Y, Z
+ y los botones más (+) y menos (-)
+ para jog a cualquier coordenada
+10) Regrese al modo articulacion usando la tecla $
+
+Notas:
+a) Utilice trivkins coordinates=XYZY kinstype=BOTH
+b) El panel "J1,3 JOGGING" hace conexiones hal y
+ altera la configuracion de ini.[13].home_sequence y
+ motion.homing-inhibit para permitir el jogging de
+ articulaciones que usan homing sincronizado.
+c) El widget "J1,3 JOGGING" COUNTS simula
+ los recuentos que normalmente se proporcionarían
+ por un generador de pulso manual (MPG o volante de jog).
+d) El widget SCALE "J1,3 JOGGING" establece la distancia
+ en unidades de máquina para cada recuento
+e) En el modo articulacion, la interfaz gráfica de usuario
+ Axis muestra los números y las posiciones de articulaciones
+ correctamente, pero la interpretación gráfica puede
+ ser engañosa.
+
diff --git a/configs/sim/axis/gladevcp/README_es b/configs/sim/axis/gladevcp/README_es
new file mode 100644
index 0000000000..b351438848
--- /dev/null
+++ b/configs/sim/axis/gladevcp/README_es
@@ -0,0 +1 @@
+gladevcp -- demos basadas en gui glade
diff --git a/configs/sim/axis/gladevcp/probe_es.txt b/configs/sim/axis/gladevcp/probe_es.txt
new file mode 100644
index 0000000000..ca2744bf30
--- /dev/null
+++ b/configs/sim/axis/gladevcp/probe_es.txt
@@ -0,0 +1,27 @@
+Probe: un ejemplo de interacción con linuxcnc
+
+Ficheros:
+probe.ini fichero de configuracion
+probe.ui fichero gladevcp
+probe.hal fichero gladevcp
+probe.py fichero gladevcp
+probe.ngc subrutina gcode
+probe.tcl arranca gladevcp and simulate_probe
+probe.txt (esto)
+
+probe.save generado por probe
+
+Uso:
+ F1 (cancelar Estop)
+ F2 (Máquina On)
+ Ctrl-Inicio (Home todos)
+
+ Establecer parámetros en gui probe separada
+ Poner probe en motion (X+ por ejemplo)
+ Activar probe con gui simulate_probe
+
+-----------------------
+Nota: para obtener una gran cantidad de resultados de depuración sobre
+lo que están haciendo gladevcp y probe.py:
+
+ gladevcp -d -d -u probe.py -U debug=3 -H probe.hal probe.ui
diff --git a/configs/sim/axis/gladevcp/set-param-from-ini_es.txt b/configs/sim/axis/gladevcp/set-param-from-ini_es.txt
new file mode 100644
index 0000000000..4edc0c076f
--- /dev/null
+++ b/configs/sim/axis/gladevcp/set-param-from-ini_es.txt
@@ -0,0 +1,8 @@
+set-param-from-ini: establecer widgets HAL por programacion
+
+Ficheros:
+set-param-from-ini.ini fichero ini con [METER]MAX
+set-param-from-ini.txt (esto)
+set-param-from-ini.tcl arrancar gladevcp y sim_pin
+meter_scale.py fichero gladevcp
+meter_scale.ui fichero gladevcp
diff --git a/configs/sim/axis/halui_pyvcp/README_es b/configs/sim/axis/halui_pyvcp/README_es
new file mode 100644
index 0000000000..a9449d187d
--- /dev/null
+++ b/configs/sim/axis/halui_pyvcp/README_es
@@ -0,0 +1,7 @@
+Configuración de muestra para halui y pyvcp.
+
+pyvcp = El panel de control virtual HAL es una forma de definir botones virtuales y controles deslizantes; se crearán como botones en una GUI, pero se comportarán
+como hardware real. Consulte el Manual de Integradores para más detalles.
+
+halui = HAL User Interface es una herramienta para permitir que LinuxCNC sea controlado por paneles de hardware (mandos, interruptores, leds, etc.).
+
diff --git a/configs/sim/axis/histogram_demo_es.txt b/configs/sim/axis/histogram_demo_es.txt
new file mode 100644
index 0000000000..02a4558a94
--- /dev/null
+++ b/configs/sim/axis/histogram_demo_es.txt
@@ -0,0 +1,10 @@
+demo hal-histogram demo
+
+Gui Axis gui que lanza dos aplicaciones hal-histogram para los pines:
+ motion-command-handler.time
+ halui.axis.x.pos-commanded
+
+Generalmente, el programa hal-histogram debe correr desde la linea de comandos.
+
+Para uso, vea:
+$ hal-histogram --help
diff --git a/configs/sim/axis/ini_hal_demo_es.txt b/configs/sim/axis/ini_hal_demo_es.txt
new file mode 100644
index 0000000000..cf1410b925
--- /dev/null
+++ b/configs/sim/axis/ini_hal_demo_es.txt
@@ -0,0 +1,3 @@
+ini_hal_demo
+
+Gui Axis que arranca una aplicacion sim_pin para demostrar como alterar valores ini soportados usando pines hal.
diff --git a/configs/sim/axis/ini_with_includes/README_es b/configs/sim/axis/ini_with_includes/README_es
new file mode 100644
index 0000000000..292c98c059
--- /dev/null
+++ b/configs/sim/axis/ini_with_includes/README_es
@@ -0,0 +1,23 @@
+ini_with_includes
+
+Demostración para usar directiva(s) #INCLUDE en un archivo ini
+
+Ejemplos:
+1) especificación de archivo relativa (relativa al directorio del ini):
+#INCLUDE nombre_archivo.inc
+#INCLUDE ./nombre_de_archivo.inc
+#INCLUDE ../nombre_de_archivo.inc
+
+2) especificación absoluta del archivo:
+#INCLUDE /tmp/nombre_de_archivo.inc
+#INCLUDE /home/myname/inc/nombre_de_archivo.inc
+
+3) especificación tilde del archivo :
+#INCLUDE ~/linuxcnc/myincludes/nombre_de_archivo.inc
+
+Nota:
+
+Se recomienda el sufijo .inc para los archivos incluidos.
+
+El uso de un sufijo .ini permitiría erróneamente que el archivo parcial aparezca como una opción de configuración.
+
diff --git a/configs/sim/axis/iocontrolv2/README_es b/configs/sim/axis/iocontrolv2/README_es
new file mode 100644
index 0000000000..570030a4d7
--- /dev/null
+++ b/configs/sim/axis/iocontrolv2/README_es
@@ -0,0 +1,20 @@
+Configuración para demostrar iocontrolv2
+
+Demostración principal:
+axis-iocontrolv2-demo.ini
+
+
+Otras demostraciones:
+g8812.ini
+m66track.ini - bucles M6 y M61
+owordm6-ui.ini
+owordm6-ui-ns.ini
+
+
+Notas:
+ Algunos archivos ini usan:
+ EMCIO = iov2
+ Consulte el archivo ini para comenzar con -support-start-change
+
+ Es posible que haya mensajes de cancelación en el inicio al leer OPEN_FILE; borrar en gui Axis con Ctrl-espacio
+
diff --git a/configs/sim/axis/ja_tests/xyzb_locking_indexer/README_es b/configs/sim/axis/ja_tests/xyzb_locking_indexer/README_es
new file mode 100644
index 0000000000..d2f8ceb6ad
--- /dev/null
+++ b/configs/sim/axis/ja_tests/xyzb_locking_indexer/README_es
@@ -0,0 +1,31 @@
+El directorio TEMPORAL xyzb contiene ejemplos ini de xyzb simplificados
+e independientes para testear:
+
+ a) jogging con volante para las configuraciones de cinematica
+ IDENTITY donde los pines hal para jogging de articulaciones
+ y ejes están conectados entre sí.
+ b) letras de eje omitidas
+ c) letras de eje duplicadas (ref: algunas configuraciones de
+ pórtico)
+ d) indexador con bloqueo en AXIS_B (el número de articulacion
+ depende de la configuración)
+ e) establecer automáticamente el modo teleop después de homing
+
+Las configuraciones inician aplicaciones adicionales:
+ 1) Gui sim_pin para demostrar jogging de volante para
+ articulaciones y ejes
+ Señal j:x es jog-count para el eje X y articulación 0
+ Señal j:y es jog-count para eje Y y articulación 1
+ Señal j:z es jog-count para el eje Z y articulación 2
+ Señal j:b es jog-count para el eje b y la articulación 3
+ 2) aplicación halshow para mostrar los pines hal relevantes
+
+xyzb.ini Trivkins con letra de eje omitido (a)
+xyyzb.ini Trivkins con letra de eje omitido (a)
+ y letra de eje duplicado (y)
+ y teleop auto después de homing
+
+xyyzb.ini usa la opción kinstype de trivkins
+para establecer el tipo de cinemática en KINEMATICS_BOTH
+para demostrar jogging y teleop jogging.
+
diff --git a/configs/sim/axis/ja_tests/xyzx_mpg/README_es b/configs/sim/axis/ja_tests/xyzx_mpg/README_es
new file mode 100644
index 0000000000..bd6be35b06
--- /dev/null
+++ b/configs/sim/axis/ja_tests/xyzx_mpg/README_es
@@ -0,0 +1,70 @@
+Configuraciones xyzx_gantry usando:
+ trivkins coordinates=xyzx kintype=BOTH
+
+xyzx.ini -- incluye simulación sim_pin
+ para jogging de volante
+xyzx-xhc-hb04.ini -- utiliza un colgante xhc-hb04
+ (modelo de 18 botones)
+
+Uso:
+
+ 1) F1 (estop off)
+ F2 (máquina on)
+ Ctrl-Inicio (home, cambia automáticamente al modo teleop)
+
+ 2) Jogging modo teleop :
+
+ jog por teclado: Flechas izquierda/derecha --- x
+ Flechas arriba/abajo -------- y
+ PgUp/Dn --------------------- z
+ Corchete izquierdo/derecho -- x
+
+ jog mpg: rotativo x/rueda ------------ x
+ rotativo y/rueda ------------ y
+ rotativo z/rueda ------------ z
+ rotativo a/rueda ------------ nada
+
+ jog sim_pin jog:x-0 +/- ----------------- x
+ jog:y-1 +/- ----------------- y
+ jog:z-2 +/- ----------------- z
+ jog:3 +/- ----------------- nada
+
+ 3) Para cambiar al modo articulacion en la gui Axis, use la tecla '$'
+
+ 4) modo de jogging articulacion:
+
+ jog por teclado: flechas izquierda/derecha --- joint_0
+ flechas arriba/abajo -------- joint_1
+ PgUp/Dn --------------------- joint_2
+ corchete izquierdo/derecho -- joint_3
+
+ jog mpg: rotativo x/wheel ------------ joint_0
+ rotativo y/wheel ------------ joint_1
+ rotativo z/wheel ------------ joint_2
+ rotativo a/wheel ------------ joint_3
+
+ jog sim_pin jog: x-0 +/- ---------------- joint_0
+ jog: y-1 +/- ---------------- joint_1
+ jog: z-2 +/- ---------------- joint_2
+ jog: 3 +/- ---------------- joint_3
+
+Notas:
+a) Por simplicidad, las configuraciones conectan:
+ joint.N.motor=pos-cmd => joint.0.motor-pos-fb
+ y usa homming inmediato (no hay lógica de switch home).
+
+b) Las configuraciones usan [KINS]AUTOTELEOP= para cambiar
+ automáticamente al modo de teleop después de homing.
+
+c) El script LIB:xhc-hb04.tcl maneja las configuraciones
+ con cinemática conocida - trivkins para las configuraciones
+ proporcionadas aquí.
+
+d) Para una máquina configurada como xyzx, las conexiones
+ 0,1,2 --> x,y,z son manejadas automáticamente por LIB:xhc-hb04.tcl.
+ Conexiones hal adicionales para permitir jogging joint_3
+ se realizan en un archivo hal postgui (xhc-hb04-postgui.hal).
+
+ En la práctica, el jogging de articulaciones independientes
+ joint_0 y joint_3 puede atascar un pórtico o causar otros problemas
+ si no se usa con extremo cuidado.
\ No newline at end of file
diff --git a/configs/sim/axis/ja_tests/xz/README_es b/configs/sim/axis/ja_tests/xz/README_es
new file mode 100644
index 0000000000..5fe9ab50b4
--- /dev/null
+++ b/configs/sim/axis/ja_tests/xz/README_es
@@ -0,0 +1,21 @@
+Ejemplos trivkins
+
+xz.ini KINEMATICS_IDENTITY
+
+xz_both.ini KINEMATICS_BOTH
+
+xz_both_auto.ini KINEMATICS_BOTH
+ (cambio automático a teleop después homing)
+
+NOTA:
+!!! [TRAJ]COORDINATES DEBEN ESTAR DE ACUERDO CON KINS:
+!!! [TRAJ]COORDINATES = xz
+
+xz.ini
+ [KINS]KINEMATICS=trivkins coordinates=xz
+
+xz_both.ini
+ [KINS]KINEMATICS=trivkins coordinates=xz kinstype=BOTH
+
+xz_both_auto.ini
+ [KINS]KINEMATICS=trivkins coordinates=xz kinstype=BOTH
\ No newline at end of file
diff --git a/configs/sim/axis/lathe-fanucy/README_es b/configs/sim/axis/lathe-fanucy/README_es
new file mode 100644
index 0000000000..df3b6e4c06
--- /dev/null
+++ b/configs/sim/axis/lathe-fanucy/README_es
@@ -0,0 +1,10 @@
+Un ejemplo de combinación de la idea de offset compuesto G43.2 con la reasignación para crear
+un intercambiador de herramientas de tipo Fanuc.
+
+T1 = selecciona y carga la herramienta 1, y aplica el offset base para la herramienta 1
+T0101 = selecciona y carga la herramienta 1 y aplica offset 1 y 10001
+T0201 = selecciona y carga la herramienta 1 y apliaca offset 1 y 10002
+
+Esto podría no coincidir exactamente con Fanuc, pero el comportamiento es fácil de cambiar
+editando toolchange.ngc
+
diff --git a/configs/sim/axis/lathe_multispindle/README_es b/configs/sim/axis/lathe_multispindle/README_es
new file mode 100644
index 0000000000..33f584ef84
--- /dev/null
+++ b/configs/sim/axis/lathe_multispindle/README_es
@@ -0,0 +1,17 @@
+Esta es una simulación de un torno de 2 husillos para demostrar el parche de husillo múltiple.
+
+Se admiten hasta 8 cabezales, establecidos por [TRAJ]SPINDLES en el INI y un
+modparam num_spindles en motmod. Estos _deben_ estár de acuerdo entre sí.
+
+La mayoría de los comandos relacionados con el husillo tienen ahora una palabra "$" adicional para decir
+a qué husillo aplicarlos.
+
+Ejemplos
+
+S1000 $1: ajuste la velocidad del husillo 1 a 1000
+M3 S100 $0: ajuste la velocidad del husillo 0 a 100
+
+G33 X10 K1.5 $1 - realizar un movimiento sincronizado con el husillo 1.
+G33.2 Z-1 K1 $0 - roscado rígido sincronizado con el husillo 0.
+
+M51 P0 $6 - deshabilitar la anulación de velocidad en el husillo 6. M48 y M49 funcionan en todos los husillos.
\ No newline at end of file
diff --git a/configs/sim/axis/ldelta_demo_es.txt b/configs/sim/axis/ldelta_demo_es.txt
new file mode 100644
index 0000000000..acc7244e83
--- /dev/null
+++ b/configs/sim/axis/ldelta_demo_es.txt
@@ -0,0 +1,10 @@
+ldelta_demo
+
+Cinematica delta lineal (Rostock)
+
+La demo incluye popups simples para simular
+jogging usando pines HAL:
+
+Jogging articular (FREE) (volante 012 y halui)
+
+Jogging de Ejes (TELEOP) (volante xyz y halui)
diff --git a/configs/sim/axis/moveoff/1_onpause_local_es.txt b/configs/sim/axis/moveoff/1_onpause_local_es.txt
new file mode 100644
index 0000000000..da36e1bf3c
--- /dev/null
+++ b/configs/sim/axis/moveoff/1_onpause_local_es.txt
@@ -0,0 +1,33 @@
+Demo moveoff
+
+Opciones Moveoff_gui:
+
+ onpause - offsets cuando el programa está en pausa
+ local - controles locales
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Para información adicional:
+
+ man moveoff ------- componente moveoff
+ man moveoff_gui --- GUI de muestra de moveoff
+
+-------------------------------------------------- -
+Uso de demostración:
+ 1) Inicie linuxcnc usando la configuración 1_onpause_local.
+ 2) Establezca halscope en modo ROLL.
+ 3) (ESTOP off)
+ 4) (máquina on)
+ 5) (home todos los ejes)
+ 6) (Ejecuta el programa)
+ 7)
(Pausa el programa)
+ 8) Habilite los offsets con el botón de verificación Activar Offsets.
+ 9) Cambie los controles deslizantes de offsets x, y, z y observe
+ en halscope
+10) Desmarque el botón Activar Offsets para eliminar
+ offsets y permitir la reanudación del programa.
+11) Repita los pasos 6) a 9) pero modifique el retroceso del punto de referencia
+ con el botón Habilitar Retroceso.
+
diff --git a/configs/sim/axis/moveoff/2_onpause_external_es.txt b/configs/sim/axis/moveoff/2_onpause_external_es.txt
new file mode 100644
index 0000000000..307a5624a3
--- /dev/null
+++ b/configs/sim/axis/moveoff/2_onpause_external_es.txt
@@ -0,0 +1,46 @@
+Demo Moveoff
+
+Opciones de Moveoff_gui:
+
+ onpause - offsets cuando el programa está en pausa
+ externo - controles externos (simulados)
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Controles externos habilitados con conexiones en:
+
+ [HAL]HALFILE = LIB:moveoff_external.hal
+
+Controles externos simulados con sim_pin:
+
+ external_enable
+ external_backtrack_en
+ external_offset_0
+ external_offset_1
+ external_offset_2
+
+Para obtener información adicional, consulte las páginas de manual:
+
+ man sim_pin ------- utilidad para configurar pines
+ man moveoff ------- componente de movimiento
+ man moveoff_gui --- GUI de muestra de moveoff
+
+-------------------------------------------------- -
+Uso de demostración:
+ 1) Inicie linuxcnc usando la configuración 2_onpause_external.
+ (configure todos los botones sim_pin en el modo Alternar):
+ 2) Establezca halscope en modo ROLL
+ 3) (ESTOP off)
+ 4) (máquina on)
+ 5) (home todos los ejes)
+ 6) (Ejecuta el programa)
+ 7)
(Pausar el programa)
+ 8) Habilite offsets con el botón external_enable
+ 9) Cambia los offsets x, y, z (exernal_offset_0,1,2)
+ y observar en halscope
+10) Elimine offset con el botón external_enable
+ y permita la reanudación del programa.
+11) Repita los pasos 6) a 9) pero modifique el punto de referencia
+ retroceder con el botón external_backtrack_en.
diff --git a/configs/sim/axis/moveoff/3_always_local_es.txt b/configs/sim/axis/moveoff/3_always_local_es.txt
new file mode 100644
index 0000000000..0a1159dffb
--- /dev/null
+++ b/configs/sim/axis/moveoff/3_always_local_es.txt
@@ -0,0 +1,27 @@
+Demo Moveoff
+
+Opciones de Moveoff_gui:
+
+ always - offsets siempre disponibles
+ local - controles locales
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Para información adicional:
+
+ man moveoff ------- componente moveoff
+ man moveoff_gui --- GUI de muestra de moveoff
+
+-------------------------------------------------- -
+Uso de demostración:
+ 1) Inicie linuxcnc usando la configuración 3_always_local.
+ 2) Establezca halscope en modo ROLL.
+ 2) (ESTOP off)
+ 3) (máquina on)
+ Los offsets están disponibles continuamente.
+ 4) Aplicar offsets usando los botones +/-
+ 5) Desactiva los offsets desmarcando el botón de control
+ Activar Offsets
+
\ No newline at end of file
diff --git a/configs/sim/axis/moveoff/4_always_external_es.tx b/configs/sim/axis/moveoff/4_always_external_es.tx
new file mode 100644
index 0000000000..aece2d0f68
--- /dev/null
+++ b/configs/sim/axis/moveoff/4_always_external_es.tx
@@ -0,0 +1,29 @@
+Demo Moveoff
+
+Opciones de Moveoff_gui:
+
+ always -- offsets siempre disponibles
+ external - controles externos (simulados)
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Controles externos habilitados con conexiones en:
+
+ [HAL]HALFILE = LIB:moveoff_external.hal
+
+Controles externos simulados con sim_pin:
+
+ external_enable
+ external_backtrack_en
+ external_offset_0
+ external_offset_1
+ external_offset_2
+
+Para obtener información adicional, consulte las páginas de manual:
+
+ man sim_pin ------- utilidad para configurar pines
+ man moveoff ------- componente moveoff
+ man moveoff_gui --- GUI de muestra de moveoff
+
diff --git a/configs/sim/axis/moveoff/5_no_gui_es.txt b/configs/sim/axis/moveoff/5_no_gui_es.txt
new file mode 100644
index 0000000000..4c4d49d835
--- /dev/null
+++ b/configs/sim/axis/moveoff/5_no_gui_es.txt
@@ -0,0 +1,17 @@
+moveoff no_gui
+
+Esta demostración no proporciona soporte gui, pero muestra varias utilidades de uso general para mostrar el comportamiento de un solo eje (2 => z).
+
+La utilidad sim_pin se usa para establecer valores de pin que normalmente se conectarían a una gui o se establecerían en valores fijos de acuerdo con la configuración de archivos:
+
+La utilidad sim_pin se usa para establecer pines para controlar el componente.
+
+Un widget de la aplicación halshow muestra un panel de observación para los pines asociados con el desplazamiento del eje z. Vea el archivo moveoff.hal para las conexiones.
+
+Se inicia una sesión halscope (seleccione 'Roll' para comenzar) para mostrar el comportamiento de las entradas y salidas importantes de moveoff
+
+Estas utilidades pueden mostrarse o deshabilitarse usando la configuración inifile:
+ [APPLICATIONS]APP = nombre_programa
+
+Nota: Esta es una implementación solo de Hal y las posiciones de offset NO se muestran en la vista previa de la gui Axis.
+
diff --git a/configs/sim/axis/moveoff/6_zretract_es.txt b/configs/sim/axis/moveoff/6_zretract_es.txt
new file mode 100644
index 0000000000..0b8b495314
--- /dev/null
+++ b/configs/sim/axis/moveoff/6_zretract_es.txt
@@ -0,0 +1,47 @@
+Demo Moveoff - retracción fija en un solo eje (Z)
+
+Demo:
+ 1) Inicie linuxcnc usando la configuración 6_zretract
+ 2) Un panel pyvpcp incluye un botón de verificación
+ para habilitar offsets fijos en pausa del programa.
+ 3) Iniciar programa
+ 4) Pausa de programa
+ 5) Una pantalla moveoff_gui (sin controles)
+ aparece mostrando el offset Z actual. Si el
+ botón de verificación se configuró para habilitar offsets,
+ se aplicarán de inmediato. Si el
+ el botón de verificación no se configuró, habilite el botón de verificación
+ para aplicar el offset.
+ 6) Cambie el botón de verificación a APAGADO para
+ eliminar el offset fijo y reanude el programa.
+ 7) El offset fijo se eliminará después de
+ un retraso para permitir la reactivación del husillo.
+ Normalmente, el husillo estaría
+ apagado durante la duración del pin aplicado mv.offset.
+ El retraso permite que el husillo se reanude
+ a su velocidad.
+ 8) Cambie el interruptor sim_pin external_enable a
+ 1 (ON) para permitir offsets en la siguiente pausa
+ de programa - o déjelo apagado para requerir su
+ activación en la próxima pausa del programa.
+
+El archivo ini establece:
+ 1) cantidad compensada y su velocidad y aceleración
+ 2) estado de la señal de habilitación externa en la parada
+ 3) intervalo de demora de autoresume
+ 4) ubicación y tamaño de la pantalla moveoff_gui
+
+-------------------------------------------------- -
+Opciones de Moveoff_gui:
+
+ onpause - compensa cuando el programa está en pausa
+ local - controles locales
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Para información adicional:
+
+ man moveoff ------ componente de movimiento
+ man moveoff_gui --- GUI de muestra de moveoff
diff --git a/configs/sim/axis/moveoff/7_pyvcp_es.txt b/configs/sim/axis/moveoff/7_pyvcp_es.txt
new file mode 100644
index 0000000000..f3c66d2f11
--- /dev/null
+++ b/configs/sim/axis/moveoff/7_pyvcp_es.txt
@@ -0,0 +1,35 @@
+Demo Moveoff - controles externos con panel pvyvcp
+ La pantalla moveoff_gui está deshabilitada
+-------------------------------------------------- -
+Opciones de Moveoff_gui:
+(Nota: moveoff_gui se usa en el modo -no_display)
+
+ onpause - compensa cuando el programa está en pausa
+ external - controles externos en panel de pyvcp
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Para información adicional:
+
+ man moveoff ------ componente de movimiento
+ man moveoff_gui --- GUI de muestra de moveoff
+
+-------------------------------------------------- -
+Uso de demostración:
+ 1) Inicie linuxcnc usando la configuración 7_pyvcp.
+ 2) (eliminar ESTOP)
+ 3) (enciende la máquina)
+ 4) (inicio todos los ejes)
+ 5) (Ejecuta el programa)
+ 6)
(Pausa el programa)
+ 7) Configure halscope en modo ROLL y luego habilite las compensaciones
+ con el botón Habilitar compensaciones.
+ 8) Cambie los controles deslizantes de desplazamiento x, y, z y observe
+ en halscope
+ 9) Desmarque el botón Habilitar compensaciones para eliminar
+ compensa y permite la reanudación del programa.
+10) Repita los pasos 6) a 9) pero modifique el punto de referencia
+ retroceder con el botón Habilitar retroceso.
+
diff --git a/configs/sim/axis/moveoff/8_gladevcp_es.txt b/configs/sim/axis/moveoff/8_gladevcp_es.txt
new file mode 100644
index 0000000000..10d2ebd8ad
--- /dev/null
+++ b/configs/sim/axis/moveoff/8_gladevcp_es.txt
@@ -0,0 +1,38 @@
+Demo Moveoff - controles externos con panel gladevcp
+ La pantalla moveoff_gui está deshabilitada
+-------------------------------------------------- -
+Opciones de Moveoff_gui:
+(Nota: moveoff_gui se usa en el modo -no_display)
+
+ onpause - compensa cuando el programa está en pausa
+ external - controles externos en panel de pyvcp
+
+Componente Moveoff instalado y conectado usando:
+
+ [HAL]HALFILE = LIB:hookup_moveoff.tcl
+
+Para información adicional:
+
+ man moveoff ------ componente de movimiento
+ man moveoff_gui --- GUI de muestra de moveoff
+
+-------------------------------------------------- -
+Uso de demostración:
+ 1) Inicie linuxcnc usando la configuración 8_gladevcp.
+ 2) (eliminar ESTOP)
+ 3) (enciende la máquina)
+ 4) (home todos los ejes)
+ 5) (Ejecuta el programa)
+ 6)
(Pausa el programa)
+ 7) Configure halscope en modo ROLL y luego habilite las compensaciones
+ con el botón Habilitar compensaciones.
+ 8) Cambie los controles deslizantes de desplazamiento x, y, z y observe
+ en halscope
+ 9) Desmarque el botón Habilitar compensaciones para eliminar
+ compensa y permite la reanudación del programa.
+10) Repita los pasos 6) a 9) pero modifique el punto de referencia
+ retroceder con el botón Habilitar retroceso.
+
+-------------------------------------------------- -
+Las instrucciones se proporcionan en el archivo moveoff_display_8.inc
+para probar con la gui gscreen.
diff --git a/configs/sim/axis/moveoff/README_es b/configs/sim/axis/moveoff/README_es
new file mode 100644
index 0000000000..4736570eb8
--- /dev/null
+++ b/configs/sim/axis/moveoff/README_es
@@ -0,0 +1,32 @@
+moveoff.comp es un método 'solo de Hal' para proporcionar offsets hasta en nueve ejes (x, y, z, a, b, c, u, v, w).
+
+El componente moveoff.comp proporciona límites mínimos, máximos, de velocidad y de aceleración para cada eje (similar al componente limit3).
+
+Vea la página del manual para más información:
+
+ $ man moveoff
+
+Las configuraciones de demostración muestran:
+
+ o moveoff_gui
+ una gui simple
+
+ o hookup_moveoff.tcl
+ un script para conectar un componente moveoff
+
+ o moveoff.halscope
+ configuraciones de halscope para ilustrar el movimiento
+ (GUIs para no mostrar offsets de movimientos solo de Hal)
+
+Configuraciones de demostración:
+
+ demostración modo control
+ ---------------- -------- ------------------
+1 onpause_local en pausa local
+2 onpause_external en pausa externo (simulado)
+3 always_local siempre local
+4 siempre_externo siempre externo (simulado)
+5 no_gui NA NA
+6 zretract en pausa panel pyvcp
+7 pyvcp en pausa panel pyvcp
+8 gladevcp en pausa panel gladevcp
diff --git a/configs/sim/axis/ngcgui/README_es b/configs/sim/axis/ngcgui/README_es
new file mode 100644
index 0000000000..94c7bcb349
--- /dev/null
+++ b/configs/sim/axis/ngcgui/README_es
@@ -0,0 +1,21 @@
+ngcgui -- Crea pestañas en el gui Axis para las subrutinas.
+
+pyngcgui -- implementación de ngcgui python, gladevcp que se puede incrustar en guis como gmoccapy, touchy, gscreen
+
+En la versión empaquetada de linuxCNC, ngcgui_lib se crea como un enlace simbólico a un directorio del sistema propiedad root:
+
+/usr/share/linuxcnc/ncfiles/ngcgui_lib
+
+Esta biblioteca normalmente no es cambiada por el usuario. Para modificar un archivo .ngc de la biblioteca,
+copie el archivo .ngc en el directorio [DISPLAY]PROGRAM_PREFIX o en un directorio que esté incluido en la
+ruta especificada por [RS274NGC]SUBROUTINE_PATH y (opcionalmente) cambie el nombre del archivo.
+
+La ruta de búsqueda para linuxCNC y ngcgui es:
+ [DISPLAY]PROGRAM_PREFIX
+
+Seguido en orden por todos los directorios listados separados por dos puntos (:) en:
+ [RS274NGC]SUBROUTINE_PATH
+
+La búsqueda de archivos de subrutinas utiliza el primer archivo encontrado con un nombre coincidente.
+
+Consulte los ejemplos y la documentación para configurar ngcgui en el archivo ini de arranque.
diff --git a/configs/sim/axis/ngcgui/ngcgui_es.txt b/configs/sim/axis/ngcgui/ngcgui_es.txt
new file mode 100644
index 0000000000..44edfc4a5a
--- /dev/null
+++ b/configs/sim/axis/ngcgui/ngcgui_es.txt
@@ -0,0 +1 @@
+ngcgui -- ejemplo completo
diff --git a/configs/sim/axis/ngcgui/ngcgui_gcmc_es.txt b/configs/sim/axis/ngcgui/ngcgui_gcmc_es.txt
new file mode 100644
index 0000000000..fe56233e29
--- /dev/null
+++ b/configs/sim/axis/ngcgui/ngcgui_gcmc_es.txt
@@ -0,0 +1,15 @@
+ngcgui incrustado como pestaña de Axis
+
+con soporte para archivos .gcmc (G-Code Meta Compiler)
+
+Los archivos .ngc y .gcmc se pueden mezclar con
+líneas de archivo ini como:
+
+NGCGUI_SUBFILE = drill.gcmc
+NGCGUI_SUBFILE = wheels.gcmc
+NGCGUI_SUBFILE = star.gcmc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = ""
+
+Ver el archivo ini para detalles de ejemplo
+
diff --git a/configs/sim/axis/ngcgui/ngcgui_lathe_es.txt b/configs/sim/axis/ngcgui/ngcgui_lathe_es.txt
new file mode 100644
index 0000000000..9952c00bd5
--- /dev/null
+++ b/configs/sim/axis/ngcgui/ngcgui_lathe_es.txt
@@ -0,0 +1 @@
+Ejemplo ngcgui con subrutinas para torno
diff --git a/configs/sim/axis/ngcgui/ngcgui_simple_es.txt b/configs/sim/axis/ngcgui/ngcgui_simple_es.txt
new file mode 100644
index 0000000000..186d185cb9
--- /dev/null
+++ b/configs/sim/axis/ngcgui/ngcgui_simple_es.txt
@@ -0,0 +1 @@
+ngcgui -- ejemplo simple de subrutinas
diff --git a/configs/sim/axis/ngcgui/pyngcgui_axis_es.txt b/configs/sim/axis/ngcgui/pyngcgui_axis_es.txt
new file mode 100644
index 0000000000..e0fc141c3c
--- /dev/null
+++ b/configs/sim/axis/ngcgui/pyngcgui_axis_es.txt
@@ -0,0 +1,5 @@
+pyngcgui_axis
+
+Demuestra pyngcgui como aplicación gladevcp en gui Axis
+
+El ngcgui original puede integrarse mejor en la interfaz Axis
diff --git a/configs/sim/axis/ngcgui/pyngcgui_gcmc_es.txt b/configs/sim/axis/ngcgui/pyngcgui_gcmc_es.txt
new file mode 100644
index 0000000000..34d2392f27
--- /dev/null
+++ b/configs/sim/axis/ngcgui/pyngcgui_gcmc_es.txt
@@ -0,0 +1,15 @@
+Pyngcgui incrustado como pestaña de Axis
+
+con soporte para archivos .gcmc (G-Code Meta Compiler)
+
+Los archivos .ngc y .gcmc se pueden mezclar con
+líneas de archivo ini como:
+
+NGCGUI_SUBFILE = drill.gcmc
+NGCGUI_SUBFILE = wheels.gcmc
+NGCGUI_SUBFILE = star.gcmc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = ""
+
+Ver el archivo ini para detalles de ejemplo
+
diff --git a/configs/sim/axis/orphans/README_es b/configs/sim/axis/orphans/README_es
new file mode 100644
index 0000000000..775644ba98
--- /dev/null
+++ b/configs/sim/axis/orphans/README_es
@@ -0,0 +1,48 @@
+Huérfanos
+
+Configuraciones obsoletas o rotas
+
+axis_noio.ini io noespecificado:
+ [EMCIO] EMCIO =
+
+py.ini.notworking - necesita trabajo
+pyiocontrol.ini.notworking - necesita trabajo
+
+
+directorio: configs/sim/axis/orphans/pysubs
+
+originalmente era: configs/sim/axis/ pysubs
+
+Los ejemplos aquí parecen ser similares o redundantes a
+archivos en configs /sim/axis/remap/
+
+-------------------------------------------------------
+
+configs/sim/axis/orphans/pysubs/customtask.py
+configs/sim/axis/remap/iocontrol-removed/python/customtask.py
+
+configs/sim/axis/orphans/pysubs/nulluserfuncs.py
+configs/sim/axis/remap/iocontrol-removed/python/nulluserfuncs.py
+
+configs/sim/axis/orphans/pysubs/oword.py
+configs/sim/axis/remap/getting-started/python/oword.py
+configs/sim/axis/remap/iocontrol-removed/python/oword.py
+
+configs/sim/axis/orphans/pysubs/plugins.py
+
+
+configs/sim/axis/orphans/pysubs/sqltoolaccess.py
+configs/sim/axis/remap/iocontrol-removed/python/sqltoolaccess.py
+
+configs/sim/axis/orphans/pysubs/task.py
+configs/sim/axis/remap/iocontrol-removed/python/task.py
+
+configs/sim/axis/orphans/pysubs/tooltable.py
+configs/sim/axis/remap/iocontrol-removed/python/tooltable.py
+
+configs/sim/axis/orphans/pysubs/userfuncs.py
+configs/sim/axis/remap/iocontrol-removed/python/userfuncs.py
+
+configs/sim/axis/orphans/pysubs/remap.py
+
+muchos mas
diff --git a/configs/sim/axis/panelui-demo/README_es b/configs/sim/axis/panelui-demo/README_es
new file mode 100644
index 0000000000..061a694212
--- /dev/null
+++ b/configs/sim/axis/panelui-demo/README_es
@@ -0,0 +1,30 @@
+Esta es una configuración simulada para demostrar el componente panelui.
+
+Este ejemplo muestra:
+jogging rápido, selección de eje en MPG, selección de velocidad de jog en MPG y botones de control del husillo.
+Los botones del husillo lo encenderán en la dirección deseada (si está apagado) o si ya está encendido,
+aumentarán o disminuirán la velocidad.
+cambiando el archivo panelui.ini se pueden cambiar los efectos de los botones.
+
+Panelui permite al integrador conectar un panel de operador, ya sea en software o hardware, a un
+sistema solo-HAL o linuxcnc completo.
+
+Permite diferentes estilos de botones que incluyen:
+
+momentáneo
+ -La salida verdadera o el comando 'true' solo se da cuando se presiona y se mantiene
+ -La salida falsa o el comando 'false' solo se dan cuando se liberan
+palanca
+ -La salida verdadera o el comando 'true' solo se da en la primera posicion
+ -La salida falsa o el comando 'false' solo se dan en la segunda posicion
+radio
+ -cada botón puede tener su propio conjunto de pines/comandos similares a los botones de palanca
+ -tiene una asociación de grupo con sus propios pines/comandos que cambian dependiendo de qué
+ botón del grupo está activo.
+
+Hay varios comandos incorporados disponibles, que permiten presionar un botón para controlar linuxcnc,
+tales como control de husillo, máquina encendida, comandos MDI arbitrarios, etc.
+
+Al agregar un archivo de controlador escrito en python, se podrían agregar comandos arbitrarios o modificar los existentes.
+
+Panelui se configura utilizando un archivo de texto de estilo INI que se colocaría en la carpeta de configuración.
diff --git a/configs/sim/axis/pentapod/README_es b/configs/sim/axis/pentapod/README_es
new file mode 100644
index 0000000000..54581d80c6
--- /dev/null
+++ b/configs/sim/axis/pentapod/README_es
@@ -0,0 +1,25 @@
+La configuración de la máquina de pentápodos es un conjunto de archivos que conforman un pentápodo LinuxCNC básico.
+
+Encienda la máquina, active la parada de emergencia y la alimentación de la máquina, presione el botón Home Todo, cambie al modo mundial ($) y podrá mover el efector en coordenadas mundiales.
+
+
+pentapod.ini
+---------------
+Archivo de configuración para un pentápodo general.
+Si cambia la ubicación de HOME en TRAJ, asegúrese de cambiar también las ubicaciones HOME apropiadas de los EJES, y asegúrese de que la posición coincida (cuando se ejecuta a través de la cinemática).
+
+kinematics.hal
+--------------
+Define las coordenadas de las articulaciones base y efectoras.
+
+basic_sim.tcl
+--------------
+Define articulaciones simuladas, no hay hardware real conectado en esta configuración.
+
+panel.xml
+---------
+Agrega un panel PyVCP.
+
+pentapod_postgui.hal
+------------------
+Agrega valores de articulaciones y número de iteraciones al panel PyVCP.
diff --git a/configs/sim/axis/remap/README_es b/configs/sim/axis/remap/README_es
new file mode 100644
index 0000000000..d39e9489ca
--- /dev/null
+++ b/configs/sim/axis/remap/README_es
@@ -0,0 +1,28 @@
+Configuraciones de muestra para códigos reasignados
+
+Esto es lo que hacen las configuraciones de ejemplo:
+
+Primeros pasos: introduce la definición de nuevos códigos en procedimientos NGC y Python
+
+extend-builtins: demuestra la reasignación de los builtins T, M6, M61, S, F. Este podría ser un punto de partida para su propia configuración. También muestra cómo referirse al comportamiento integrado de los códigos.
+
+manual-toolchange-with-tool-length-switch: extender M6 para que haga una sonda de longitud de herramienta después del cambio.
+
+rack-toolchange: intenta imitar el parche del cambiador rack de herramientas, sin parche, sino con códigos de reasignación
+
+cycles: una demostración de cómo se pueden crear nuevos códigos de ciclo con subrutinas O-word o en Python
+
+iocontrol-remove: una 'parte de investigación' de la rama de reasignación (ahora fusionada): demuestra cómo eliminar iocontrol por completo y reemplazarlo por un complemento de Python en la tarea. Aparte de eso, se utiliza el ejemplo de cambiador de herramientas de rack. Además, usa experimentalmente sqlite3 para el almacenamiento de la tabla de herramientas.
+
+>>>>>>>>>>> No recomendado para uso en producción. <<<<<<<<<<<<<<<<<<<<<<<<
+
+python-stdglue contiene código Python incrustado que admite los ejemplos anteriores. Esto eventualmente debería evolucionar hacia un código enlatado que los usuarios no necesitan tocar, excepto en circunstancias más exóticas. Tenga en cuenta que todos los ejemplos anteriores usan el mismo código glue de remap.py.
+
+common_nc_subs: contiene reset_state.ngc, que debe llamarse desde el procedimiento ON_ABORT. Tenga en cuenta que es particularmente importante restablecer el estado modal después de un procedimiento de reasignación fallido porque esto puede conducir a fallas posteriores (por ejemplo, ID de error 3437928). Las demostraciones usan su propio sub on_abort y llaman a reset_state.
+
+Reasignación de documentación:
+ http://www.linuxcnc.org/docs/devel/html/remap/structure.html
+
+ver también:
+ http://wiki.linuxcnc.org/cgi-bin/emcinfo.pl?RemappingStatus
+
diff --git a/configs/sim/axis/remap/cycle/README_es b/configs/sim/axis/remap/cycle/README_es
new file mode 100644
index 0000000000..95e377c852
--- /dev/null
+++ b/configs/sim/axis/remap/cycle/README_es
@@ -0,0 +1,43 @@
+Muestra de cómo se pueden hacer ciclos a partir de subrutinas O-word o directamente codificadas en Python.
+
+# Suponga que G84.2 se reasigna a Python g842; así en la sección ini [RS274NGC]:
+# REMAP=G84.2 argspec=xyzqp python=g842 modalgroup=1
+# #
+# entonces, ejecutando
+# #
+# G84.2 x1 y1 (línea1)
+# x3 y3 (línea2)
+# y5 (línea3)
+# ...
+# #
+# se ejecutará como:
+# * G84.2 x1 y1
+# G84.2 x3 y3
+# G84.2 x3 y5
+# #
+# hasta que se borre el movimiento con G80 o se ejecute algún otro movimiento.
+# #
+# Esto permite escribir ciclos en Python, o como procedimientos de Oword; en el
+# último caso, self.motion_mode debe establecerse en el epílogo Python.
+# #
+
+Y lo mismo para un procedimiento de Oword:
+
+# un ciclo con un sub de Oword
+#REMAP=G84.3 modalgroup=1 argspec=xyzqp prolog=g843_prolog ngc=g843 epilog=g843_epilog
+
+Los ejemplos solo muestran los parámetros de los que se alimentan, y no hacen nada útil; "capte la idea".
+Los parámetros sticky se manejan correctamente.
+
+Uso:
+
+linuxcnc cycle.ini
+
+pulsa ejecutar y ver qué ocurre.
+
+Para entender cómo encajan las cosas:
+
+- vea las instrucciones REMAP en cycle.ini
+- python/remap.py contiene el pegamento Python
+- nc_subroutines/g843.ngc es un ejemplo 'cuerpo de ciclo'
+
diff --git a/configs/sim/axis/remap/extend-builtins/README_es b/configs/sim/axis/remap/extend-builtins/README_es
new file mode 100644
index 0000000000..83a1d9fd89
--- /dev/null
+++ b/configs/sim/axis/remap/extend-builtins/README_es
@@ -0,0 +1,27 @@
+Muestra como pueden redefinirse los códigos T, M6, M61, S, F y opcionalmente su comportamiento en el procedimiento de remapeo.
+
+La colección de prólogos y epílogos en python-stdglue pretende ser un conjunto repetitivo de pegamento Python que cubre la mayoría de los casos de uso. Normalmente no debería necesitar tocar ninguno de estos.
+
+Las rutinas de reasignación ngc en nc_subroutines se han configurado para:
+
+mostrar los 'parámetros expuestos' con una declaración de depuración
+
+consultar los códigos incorporados dentro del procedimiento de reasignación, de modo que el efecto de ejecución sea el mismo que no reasignar ese código (es decir, el resultado de la reasignación es idempotente)
+
+trabajar con los prólogos y epílogos de stdglue
+
+Los 'parámetros expuestos' son variables locales en el procedimiento de reasignación que pueden leerse y modificarse; el epílogo recogerá cualquier cambio y lo utilizará para confirmar el resultado
+
+
+Tenga en cuenta que el uso de M61 requiere iocontrol-v2 ya que el soporte de número de herramienta establecido en iocontrol está roto.
+
+actualizacion:
+
+Añadidas reasignaciones y extensión de M0, M1, M60 .
+Ver también hilo:
+ http://linuxcnc.org/index.php/english/component/kunena/?func=view&catid=38&id=17637&limit=6#17637
+
+-mah
+
+
+
diff --git a/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README_es b/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README_es
new file mode 100644
index 0000000000..dddc25ed66
--- /dev/null
+++ b/configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/README_es
@@ -0,0 +1,3 @@
+Ejemplo para un cambiador de herramientas manual con sonda de longitud de herramienta automática después del cambio
+
+
diff --git a/configs/sim/axis/remap/rack-toolchange/README_es b/configs/sim/axis/remap/rack-toolchange/README_es
new file mode 100644
index 0000000000..12f9b10fd8
--- /dev/null
+++ b/configs/sim/axis/remap/rack-toolchange/README_es
@@ -0,0 +1,11 @@
+Este ejemplo de un cambiador de herramientas rack intenta una transliteración del parche de cambiador de herramientas de micges.
+
+Esto supone un número de herramienta == número de ranura; el número de bolsillo en tool.tbl se ignora actualmente.
+
+Ver http://wiki.linuxcnc.org/cgi-bin/emcinfo.pl?RackToolChanger.
+
+NB:
+
+No entiendo completamente el significado de los pines involucrados, dwell y los movimientos.
+Esto NO ha sido probado en una máquina real. Úselo como punto de partida para su propia experimentación.
+
diff --git a/configs/sim/axis/remap/stop-lookahead/README_es b/configs/sim/axis/remap/stop-lookahead/README_es
new file mode 100644
index 0000000000..358335092f
--- /dev/null
+++ b/configs/sim/axis/remap/stop-lookahead/README_es
@@ -0,0 +1,15 @@
+Este es un código de ejemplo reasignado para demostrar cómo se puede controlar el anticipador del intérprete.
+
+Vea también este hilo del foro:
+ http://www.linuxcnc.org/index.php/english/forum/10-advanced-configuration/25994-abort-msg-in-o-sub?start=12#28355
+
+
+Relacionado:
+
+consulte 'Modo de búsqueda anticipada G103', página 152,
+
+Referencia de software PMAC-NC2 Pro2, Delta Tau Systems Inc
+
+http://www.deltatau.com/manuals/pdfs/PMAC-NC%20PRO2.pdf?id=634701792253582640
+
+
diff --git a/configs/sim/axis/rose_engine/README_es b/configs/sim/axis/rose_engine/README_es
new file mode 100644
index 0000000000..dd8f8f3ac8
--- /dev/null
+++ b/configs/sim/axis/rose_engine/README_es
@@ -0,0 +1,10 @@
+rose_engine.ini: demo de motor Rose
+
+Demuestra la cinematica de un motor Rose
+
+(man 9 rosekins)
+
+joint_0 lineal, transversal
+joint_1 lineal, longitudinal
+joint_2 rotativa, husillo (angulo acumalativo)
+
diff --git a/configs/sim/axis/simtcl/README_es b/configs/sim/axis/simtcl/README_es
new file mode 100644
index 0000000000..af9f07a433
--- /dev/null
+++ b/configs/sim/axis/simtcl/README_es
@@ -0,0 +1,16 @@
+Los archivos de configuración simtcl utilizan el lenguaje tcl para la configuración en lugar de los archivos ".hal" más comunes.
+
+Las configuraciones en este directorio también demuestran el uso de un método de dos pasos para procesar archivos ".hal" y ".tcl". Este método está habilitado por la configuración del archivo ini de [HAL] TWOPASS= . Con el procesamiento de dos pasos, los especificadores loadrt para un módulo se pueden especificar en varios lugares.
+
+o twopass_compat
+ verificar compatibilidad con halfiles .hal
+
+o twopass_basic
+ usar LIB de ejemplo basic_sim
+
+Notas:
+
+Convencionalmente, hal se configura con archivos ".hal" que contienen instrucciones en el lenguaje halcmd. Con los archivos ".tcl", también hay disponibles recursos de programación comunes como bucles y pruebas.
+
+Los archivos de configuración Hal se especifican mediante elementos ini file [HAL]HALFILE que pueden nombrar archivos ".hal" o ".tcl".
+
diff --git a/configs/sim/axis/simtcl/twopass_basic_es.txt b/configs/sim/axis/simtcl/twopass_basic_es.txt
new file mode 100644
index 0000000000..f6114f98a8
--- /dev/null
+++ b/configs/sim/axis/simtcl/twopass_basic_es.txt
@@ -0,0 +1 @@
+twopass_basic -- demuestra procesamiento twopass usando LIB:basic_sim.tcl
diff --git a/configs/sim/axis/simtcl/twopass_compat_es.txt b/configs/sim/axis/simtcl/twopass_compat_es.txt
new file mode 100644
index 0000000000..86f2b74499
--- /dev/null
+++ b/configs/sim/axis/simtcl/twopass_compat_es.txt
@@ -0,0 +1 @@
+twopass_compat -- verifica compatibilidad con archivos ".hal" existentes usados por sim/axis.ini
diff --git a/configs/sim/axis/spindle_orient/README_es b/configs/sim/axis/spindle_orient/README_es
new file mode 100644
index 0000000000..ca5870238a
--- /dev/null
+++ b/configs/sim/axis/spindle_orient/README_es
@@ -0,0 +1,20 @@
+La configuración de orient.ini ayuda a explorar el comando M19 y su efecto en varios pines HAL.
+
+Tenga en cuenta el valor ORIENT_OFFSET en orient.ini que se agrega a la palabra R.
+
+
+Correrlo y ejecutar en MDI:
+
+M19
+
+M5
+
+M19 R45 P1
+
+S500 M3
+
+Confirme una solicitud de orientación del husillo presionando el botón husillo-orientado.
+
+-mah
+
+
diff --git a/configs/sim/axis/twopass/README_es b/configs/sim/axis/twopass/README_es
new file mode 100644
index 0000000000..346e2578e1
--- /dev/null
+++ b/configs/sim/axis/twopass/README_es
@@ -0,0 +1,15 @@
+TWOPASS demo
+
+El procesamiento TWOPASS de los archivos hal permite múltiples especificaciones para las líneas loadrt de componentes.
+
+Para habilitar el procesamiento de dos pasos:
+
+[HAL]
+TWOPASS = on, verbose
+
+
+Para la depuración, use:
+TWOPASS = on,verbose,nodelete
+
+La opción detallada aumenta la salida a stdout.
+La opción nodelete evita la eliminación de archivos temporales.
diff --git a/configs/sim/axis/vismach/3axis-tutorial/README_es b/configs/sim/axis/vismach/3axis-tutorial/README_es
new file mode 100644
index 0000000000..5193b11f49
--- /dev/null
+++ b/configs/sim/axis/vismach/3axis-tutorial/README_es
@@ -0,0 +1,2 @@
+Un ejemplo simple de fresadora vismach de 3 ejes construido usando primitivas.
+Los comentarios se encuentran en el archivo vismach 3axis-tutorial, y algunos en 3axis-tutorial.hal explican paso a paso el proceso de creación.
diff --git a/configs/sim/axis/vismach/5axis/bridgemill/README_es b/configs/sim/axis/vismach/5axis/bridgemill/README_es
new file mode 100644
index 0000000000..078eaef7e3
--- /dev/null
+++ b/configs/sim/axis/vismach/5axis/bridgemill/README_es
@@ -0,0 +1 @@
+Esta es una simulación de una fresadora de puente de 5 ejes XYZBC.
diff --git a/configs/sim/axis/vismach/5axis/max5/README_es b/configs/sim/axis/vismach/5axis/max5/README_es
new file mode 100644
index 0000000000..7aca9a6052
--- /dev/null
+++ b/configs/sim/axis/vismach/5axis/max5/README_es
@@ -0,0 +1,10 @@
+Configuracion Max5 5 ejes XYZBC
+
+
+max5triv.ini - implementado con trivkins
+
+max5kins.ini - implementado con cinemática max5
+ cinemática sin identidad
+ teleop automático después de homing
+
+max5_base.inc - configuraciónes compartidas
diff --git a/configs/sim/axis/vismach/5axis/table-rotary-tilting/README_es b/configs/sim/axis/vismach/5axis/table-rotary-tilting/README_es
new file mode 100644
index 0000000000..edd779c9d9
--- /dev/null
+++ b/configs/sim/axis/vismach/5axis/table-rotary-tilting/README_es
@@ -0,0 +1,12 @@
+Mesa rotatoria/inclinable (trt) configuraciones Sim
+
+xyzac-trt
+xyzbc-trt
+
+Ejemplo de archivos ngc:
+ examples/boat-xyzac.ngc (!!! TOUCHOFF table Z to -13.25 !!!)
+ examples/boat-xyzbc.ngc (!!! TOUCHOFF table Z to - 8.30 !!!)
+
+Ejemplos de archivos ngc (subrutinas compatibles con ngcgui):
+ ejemplos/test-xyzac.ngc
+ ejemplos/test-xyzbc.ngc
\ No newline at end of file
diff --git a/configs/sim/axis/vismach/README_es b/configs/sim/axis/vismach/README_es
new file mode 100644
index 0000000000..86185f0e88
--- /dev/null
+++ b/configs/sim/axis/vismach/README_es
@@ -0,0 +1,24 @@
+El directorio 'vismach' contiene una serie de configuraciones que muestran modelos 3D de máquinas simuladas.
+
+El mejor lugar para comenzar es con roflmill, que es una fresadora de 3 ejes construida
+usando primitivas. El archivo rolfmill.hal está fuertemente comentado con instrucciones paso a paso
+sobre cómo construir la simulación de vismach.
+
+Estas simulaciones están destinadas principalmente a probar código cinemático complejo por personas que no tienen esas máquinas exóticas.
+
+Todas estas configuraciones funcionan sin tiempo real y sin hardware ni controladores.
+
+Todas las simulaciones usan la GUI Axis. Es posible que estas configuraciones deban modificarse a medida que avance el trabajo en articulaciones vs. ejes.
+
+Las opciones son:
+
+- max5triv.ini: MaxNC de Chris Radek que se ha modificado para tener ejes angulares B y C. Esta versión utiliza trivkins, por lo que no proporciona un comportamiento multieje adecuado.
+
+- max5kins.ini: MaxNC de Chris Radek que se ha modificado para tener ejes angulares B y C. Esta versión usa maxkins y permite código g completo de 9 ejes.
+
+- hbm.ini: una gran mandrinadora horizontal. La pluma está configurada como el eje W.
+
+-- 5axis
+-- hexapod-sim
+-- puma
+-- scar
diff --git a/configs/sim/axis/vismach/VMC_toolchange/README_es b/configs/sim/axis/vismach/VMC_toolchange/README_es
new file mode 100644
index 0000000000..cb67471ca8
--- /dev/null
+++ b/configs/sim/axis/vismach/VMC_toolchange/README_es
@@ -0,0 +1,52 @@
+Esta es una configuración del simulador Vismach diseñada para probar configuraciones de cambiador de herramientas
+El modelo Vismach combinado con el archivo sim_vmc.hal presenta tres ejes
+con interruptores home y límite, un carrusel con salidas tanto de código gray como de pulso/índice (encoder de cuadratura),
+una barra de bloqueo y un tirante.
+Hay dos configuraciones alternativas, una para codificación del carrusel en código gray y otra en pulso/índice.
+Tenga en cuenta que el componente de carrusel también admite sensores binarios e individuales.
+
+El VMC "virtual" es creado por el archivo sim_vmc.hal y define las siguientes señales
+,usadas en otros archivos HAL
+
+Posiciones de ejes
+x-pos
+y-pos
+z-pos
+
+Límites de ejes
+x-pos-lim
+x-neg-lim
+y-pos-lim
+y-neg-llm
+z-pos-lim
+z-neg-lim
+
+Husillo Simulado
+spindle-cmd - ajusta la velocidad del husillo en rpm; negativo para retroceso
+spindle-pos - posición simulada del husillo (revs)
+spindle-vel - velocidad del husillo simulada
+
+Brazo cambiador de herramientas
+arm-act - acciona el brazo
+arm-in - brazo en switch límite
+arm-out - brazo fuera del switch límite
+
+Bloqueo del carrusel
+car-lock - activar el bloqueo
+car-locked - carrusel bloqueado
+car-unlocked - carrusel desbloqueado
+
+Barra de tiro
+tool-release - liberar herramienta
+tool-released - herramienta liberada
+tool-locked - herramienta bloqueada
+
+Carrusel
+car-fwd girar hacia la derecha
+car-rev girar en sentido antihorario
+bit0
+bit1
+bit2
+bit3
+bit4 - Posición de carrusel codificada en gray
+
diff --git a/configs/sim/axis/vismach/hexapod-sim/README_es b/configs/sim/axis/vismach/hexapod-sim/README_es
new file mode 100644
index 0000000000..4ffb975fbd
--- /dev/null
+++ b/configs/sim/axis/vismach/hexapod-sim/README_es
@@ -0,0 +1,31 @@
+La configuración del hexápodo (plataforma Stewart) es un conjunto de archivos que constituye un hexápodo LinuxCNC muy básico. Es muy similar a la plantilla de configuración sim, pero con 6 ejes definidos.
+
+Encienda la máquina, apague E-Stop y de potencia de la máquina, presione el botón Home All, cambie al modo mundial ($) y podrá mover la plataforma en coordenadas mundiales. Tenga en cuenta que el inicio de Z es 20, para ejecutar axis.ngc debe hacer touch off Z a 0.
+
+
+hexapod.ini
+---------------
+Archivo de configuración para un hexápodo general.
+Para que funcione con su máquina, debe ajustar las coordenadas de las articulaciones de la base y la plataforma en kinematics.hal y especificar que se deben usar genhexkins en lugar de los trivkins normales (loadrt genhexkins en su archivo hal).
+Si cambia la ubicación de HOME en TRAJ, asegúrese de cambiar también las ubicaciones de HOME adecuadas de los AXES y asegúrese de que la posición coincida (cuando se ejecuta a través de la cinemática).
+
+kinematics.hal
+--------------
+Define coordenadas de articulaciones base y plataforma.
+
+hexagui.hal
+--------------
+Agrega la visualización simple de Vismach para hexapod.
+Tenga en cuenta que cambiar las posiciones de las articulaciones definitivamente rompe la visualización
+
+core_sim_6.hal
+--------------
+Define uniones simuladas, sin hardware real conectado en esta configuración.
+
+panel.xml
+---------
+Agrega el panel PyVCP.
+
+hexapod_postgui.hal
+------------------
+Agrega valores de articulaciones y números de iteraciones al panel PyVCP.
diff --git a/configs/sim/axis/vismach/puma/README_es b/configs/sim/axis/vismach/puma/README_es
new file mode 100644
index 0000000000..dc215aeafe
--- /dev/null
+++ b/configs/sim/axis/vismach/puma/README_es
@@ -0,0 +1,6 @@
+puma_cube.ini: archivo de configuración para un robot tipo PUMA que utiliza los módulos de cinemática pumakins específicos de puma. Esta configuración proporciona un archivo gcode de inicio ([DISPLAY]OPEN)FILE) que establece las compensaciones de coordenadas utilizables para trazar un contorno de un cubo. La velocidad, la aceleración y los límites de posición se configuran con valores grande para su comodidad y no son representativos de una máquina real.
+
+puma.ini: archivo de configuración para un robot tipo PUMA que utiliza el módulo de cinemática pumakins específico de puma ($ man pumakins). No se fuerzan los límites posicionales. El usuario debe configurar las compensaciones de coordenadas del sistema.
+
+puma560.ini: archivo de configuración para un robot tipo PUMA 560 que utiliza la cinemática en serie generalizada del módulo de genserkins ($ man genserkins). Genserkins usa una solución interactiva para la cinemática inversa y puede requerir que las ubicaciones de
+[JOINT_n]HOME sean consistentes con la configuración de [TRAJ]HOME.
diff --git a/configs/sim/axis/vismach/rolfmill/README_es b/configs/sim/axis/vismach/rolfmill/README_es
new file mode 100644
index 0000000000..c272d454c8
--- /dev/null
+++ b/configs/sim/axis/vismach/rolfmill/README_es
@@ -0,0 +1,2 @@
+Un ejemplo simple de fresadora de 3 ejes vismach construido con primitivas.
+Los comentarios en rolfmill.hal explican paso a paso el proceso de construcción.
diff --git a/configs/sim/axis/vismach/scara/README_es b/configs/sim/axis/vismach/scara/README_es
new file mode 100644
index 0000000000..317487458d
--- /dev/null
+++ b/configs/sim/axis/vismach/scara/README_es
@@ -0,0 +1,9 @@
+La configuración puma es un conjunto de archivos que constituye una simulación scara LinuxCNC muy básica que usa ini, tbl, var. Es muy similar a la plantilla de configuración de sim, pero con 4 uniones definidas.
+
+scara.ini
+-------------
+Archivo de configuración para un robot tipo SCARA.
+
+Debe especificar qué cinemática se debe usar (loadrt scarakins en su archivo hal)
+
+Si cambia la ubicación de HOME en TRAJ, asegúrese de cambiar también las ubicaciones de HOME adecuadas de AXES, y asegúrese de que la posición coincida (cuando se ejecuta a través de la cinemática).
diff --git a/configs/sim/axis/wrapped_rotary/README_es b/configs/sim/axis/wrapped_rotary/README_es
new file mode 100644
index 0000000000..e54d2b8762
--- /dev/null
+++ b/configs/sim/axis/wrapped_rotary/README_es
@@ -0,0 +1,10 @@
+Axis gui sim configs for wrapped_rotary applications
+
+Use trivkins coordinates=XYZA kinstype=BOTH
+X: joint0
+Y: joint1
+Z: joint3
+A: joint4
+
+wrapped_rotary.ini basic wrapped_rotary demo (in)
+
diff --git a/configs/sim/axis/xhc-hb04/README_es b/configs/sim/axis/xhc-hb04/README_es
new file mode 100644
index 0000000000..76a461198f
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/README_es
@@ -0,0 +1,262 @@
+Estas configuraciones de simulación demuestran el uso de un colgante MPG inalámbrico XHC-HB04 en LinuxCNC usando un módulo HAL creado por Frederic Rible (frible@teaser.fr) (Copyright (C) 2013). Ref:
+
+http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Using_A_XHC-HB04_Wireless_MPG_Pendant
+
+El módulo HAL está diseñado para el XHC-HB04 V3.0 identificado como dispositivo USB 10CE:EB70.
+Se manejan la mayoría de las características del colgante:
+- botones convertidos a pines hal
+- jog de volante con escala variable (use el pin stepsize-up o stepsize-down para cambiar la secuencia)
+- Las secuencias proporcionadas incluyen:
+ (0.001,0.010,0.100,1.000) tipico para máquinas en mm
+ (0.001,0.005,0.010,0.020) tipico para máquina en pulgadas
+- Pantalla LCD que muestra las posiciones relativas y máquina.
+
+Se proporcionan configuraciones Sim para dos configuraciones de botón conocidas:
+
+layout1 -- 16 buttons
+layout2 -- 18 buttons (más comunes)
+
+Los nombres de los botones se definen en los archivos LIB:xhc-hb04-layout*.cfg en una estrofa etiquetada XHC-HB04 con definiciones como BUTTON=XX:nombre donde XX es un código hexadecimal utilizado por el dispositivo.
+
+Ejemplo:
+ [XHC-HB04]
+ BUTTON=01:button-stop
+ BUTTON=03:button-rewind
+ ...
+
+Se crea un pin hal (Type = bit, Dir = OUT) para cada botón, por ejemplo:
+ xhc-hb04.button-stop
+ xhc-hb04.button-rewind
+ ...
+
+Si el archivo de configuración incluye botones nombrados:
+ button-zero
+ button-goto-zero
+ button-half
+entonces el driver crea botones adicionales para los que están activos solo si la articulacion se selecciona con el interruptor giratorio. Estos botones sintetizados son:
+ button-zero-x
+ button-zero-y
+ button-zero-z
+ button-zero-a
+ button-goto-zero-x
+ button-goto-zero-y
+ button-goto-zero-z
+ button-goto-zero-a
+ button-half-x
+ button-half-y
+ button-half-z
+ button-half-a
+Al igual que con los botones reales, los botones sintetizados tienen pines hal llamados:
+ xhc-hb04.button-zero-x
+ xhc-hb04.button-zero-y
+ etc.
+
+
+Los pines hal adicionales son creados por el controlador xhc-hb04 y conectados según lo requerido por el halfile incluido para las configuraciones de demostración.
+
+Se requiere un dispositivo xhc-hb04 en funcionamiento y conectado para las configuraciones de demostración. Si no está conectado, las configuraciones de sim se iniciarán sin la funcionalidad del colgante.
+
+----------------------------------
+
+Se necesita un archivo de reglas udev para otorgar los permisos correctos para el acceso USB. Con una instalación deb, el archivo de reglas se instala como /lib/udev/rules.d/99-xhc.rules
+
+Si usa una compilación Run-In-Place (RIP), cree un archivo en la ubicación para las reglas instaladas por el usuario: /etc/udev/rules.d/99-xhc.rules e incluya una regla para especificar Códigos del producto y el proveedor correspondiente y permitir tanto el acceso de lectura como de escritura al usuario.
+
+Ejemplo de regla udev:
+ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="0666", OWNER="root", GROUP="plugdev"
+
+Esta regla usa el modo 0666 para proporcionar acceso de lectura y escritura al propietario, grupo, mundo, --- todos.
+
+----------------------------------
+Las configuraciones sim utilizan un solo halfile: LIB:xhc-hb04.tcl. Este halfile utiliza un archivo comp personalizado (xhc_hb04_util.comp) y se puede agregar a las configuraciones existentes agregando una entrada de archivo ini para:
+ [HAL]HALFILE = LIB:xhc-hb04.tcl
+
+Esta entrada HALFILE debe seguir a otras entradas HALFILE.
+
+Los elementos del archivo ini de configuración opcional y los valores predeterminados son:
+
+[XHC_HB04_CONFIG]
+threadname = servo-thread (opcional, por defecto: servo-thread)
+layout = 2 (opcional, 1: 16 botones o 2: 18 botones, por defecto: 2)
+coords = x y z a (opcional, 4 max, por defecto: x y z a)
+coefs = 1 1 1 1 (opcional, filtro coefs 0 halui.program.stop
+ pendant:goto-zero <== xhc-hb04.button-goto-zero ==> halui.mdi-command-00
+ pendant:step <== xhc-hb04.button-step ==> xhc-hb04.stepsize-up
+ etc ...
+
+
+Nota: los comandos MDI de halui se definen en un parrafo [HALUI]:
+[HALUI]
+MDI_COMMAND = G0 X0 Y0 Z0
+MDI_COMMAND = M101
+
+
+Los comandos se asignan a los pines (Tipo=bit, Dir=IN) llamados halui.mdi-command-nn donde
+nn corresponde a su apariencia ordenada que comienza con nn=00. (man halui para más información)
+----------------------------------
+Se incluye una aplicación llamada monitor-xhc-hb04 para monitorear desconexiones y reconexiones del colgante. Esta secuencia de comandos se ejecuta en segundo plano y mostrará un mensaje cuando el colgante se desconecte o vuelva a conectarse. El uso es opcional; si se usa se especifica con la entrada del archivo ini:
+ [APPLICATIONS]APP = monitor-xhc-hb04
+
+(Nota: cuando se utiliza require_pendant=1, se detectan desconexiones pero no se admiten las reconexiones)
+----------------------------------
+Consulte la página de manual de xhc-hb04 para obtener detalles sobre el componente xhc-hb04
+----------------------------------
+
+Los archivos demo ini son ejemplos que utilizan la gui Axis en una configuración de simulador.
+Estos archivos utilizan directivas #INCLUDE para incluir archivos para la máquina básica
+y para el diseño del colgante.
+
+Por ejemplo, la organización para el archivo xhc-hb04-layout2.ini es:
+
+ #INCLUDE inch_base.inc | Items convencionales para un simulador basado en pulgadas.
+ #INCLUDE layout2.inc | Todos los items de botón ([XHC_HB04_BUTTONS],[HALUI])
+
+ [EMC] | Identificador de la máquina
+ MACHINE = |
+
+ [HAL] | Items HAL
+ HALFILE = |
+ ... |
+ HALFILE = |
+ HALFILE = LIB:xhc-hb04.tcl | script de configuración xhc-hb04
+ HALUI = halui | Especificador halui
+
+ [XHC_HB04_CONFIG] | Todos los items de configuración utilizados por LIB:xhc-hb04.tcl
+ layout = |
+ coords = |
+ coefs = |
+ scales = |
+ jogmode = |
+ sequence = |
+ require_pendant = |
+ inch_or_mm = |
+ mpg_accels = |
+
+ [APPLICATIONS] | Scripts auxiliares opcionales
+ APP = monitor-xhc-hb04 | Script de monitor de conexión
+
+----------------------------------
+
+Añadiendo un xhc-hb04 a una configuración existente.
+
+El procedimiento recomendado es crear una nueva configuración basada en una configuración existente.
+
+ Copie todos los archivos de un directorio de configuración existente (en funcionamiento)
+ a un nuevo directorio y edite la configuración del archivo ini para:
+ a) agregue [HAL]HALFILE=LIB:xhc-hb04.tcl
+ (esta entrada debe seguir a otras entradas de HALFILE)
+ b) (opcional) agregue [APPLICATIONS]APP=monitor-xhc-hb04
+ para monitorizar desconexiones/conexiones de colgante
+ c) agregue la estrofa [XHC_HB04_CONFIG] para configurar el colgante
+ d) incluir las estrofas [XHC_HB04_BUTTONS] y [HALUI] para
+ definir acciones de botón (estas pueden estar en un
+ archivo #INCLUDE - vea los ejemplos de demostración)
+
+ Las entradas en las estrofas nuevas o actualizadas deben personalizarse para su máquina.
+
+----------------------------------
+Nota: Para cinemática de identidad (trivkins), el script LIB:xhc-hb04.tcl se conecta
+ejes y pines de articulacion que tienen una correspondencia uno a uno para soportar jog
+en ambos modos de movimiento, articulacion y teleop.
+
+Para cinemáticas desconocidas (por ejemplo, cinemáticas sin identidad), el script LIB:xhc-hb04
+conecta la coordenada del eje especificada por:
+ [XHC_HB04_CONFIG]coords=
+para el jogging modo mundial (teleop). No se hacen conexiones para articulaciones individuales
+en modo jogging de articulaciones .
+Si se desea jogging wheel para articulaciones en modo de movimiento de articulación para configuraciones con
+cinemática sin identidad, utilice conexiones Hal adicionales para conectar los
+pines jog articulacion apropiados.
+
+Ejemplo: cinemática sin identidad que tiene un eje rotativo (c) con una
+correspondencia uno a uno a una sola articulación (3). El script LIB:xhc-hb04.tcl
+hace conexiones Hal para el eje c como:
+
+ pendant:jog-c <= xhc-hb04.jog.enable-a
+ => axis.c.jog-enable
+ pendant:jog-scale <= pendant_util.divide-by-k-out
+ => axis.c.jog-scale
+pendant:wheel-counts-c-filtered <= pendant_util.out3
+ => axis.c.jog-counts
+
+Para agregar jogging de articulaciones para la articulación 3 (con una escala idéntica a la escala mundial),
+agregar comandos hal suplementarios:
+
+net pendant:jog-c => joint.3.jog-enable
+net pendant:jog-scale => joint.3.jog-scale
+net pendant:wheel-counts-c-filtered => joint.3.jog-counts
+
+Estas conexiones podrían agregarse en un [HAL]HALFILE= adicional
+o utilizando [HAL]HALCMD= en el archivo ini
+
+Se podrían hacer conexiones similares para otras articulaciones que tienen
+correspondencia uno a uno a una coordenada de eje.
+
+Para articulaciones que no tienen una correspondencia directa con una coordenada de eje,
+se pueden hacer conexiones articulacion pin jog como en el ejemplo anterior, pero las
+conexiones alteradas pueden requerir una escala adecuada. Haga las conexiones articulaciones jog pin
+utilizando una letra de coordenadas de eje para una posición del interruptor giratorio selector de eje del colgante.
+Se producirá jogging de articulacion para esa posición de conmutador cuando LinuxCNC esté en
+modo de movimiento de articulacion.
+
+----------------------------------
+Notas:
+
+ 1) En versiones anteriores de xhc-hb04.tcl, mpg_accels usaba un
+ script de ayuda (xhc-hb04-accels) para multiplexar valores de aceleración reducidos durante
+ modo mundial de jogging.
+ La implementación actual utiliza ahora pines proporcionados por el
+ módulo motion:
+ axis.L.jog-accel-fraction
+ joint.N.jog-accel-fraction
+
+ 2) El soporte para la regulacion del husillo se admite utilizando los
+ pines halui: halui.spindle.0.override. * según corresponde a
+ uso por defecto de un solo husillo.
+
+
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout1_es.txt b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1_es.txt
new file mode 100644
index 0000000000..8337ba89b5
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout1_es.txt
@@ -0,0 +1,40 @@
+xhc-hb04-layout1
+
+16 botones:
+
+---------------------------------------
+|RESET | |
+---------------------------------------
+|Stop |Start/Pause|Rewind |Probe-Z |
+---------------------------------------
+|GotoZero| X2 | Y2 |Safe-Z |
+---------------------------------------
+| X=0 | Y=0 | Z=0 | Home |
+---------------------------------------
+|STEP | Mode |Spindle| |
+---------------------------------------
+| Off |
+| X |
+| Y |
+| Rotary -------> Z |
+| Switch A |
+| Spindle |
+| Feed |
+---------------------------------------
+
+Button codes defined in LIB:xhc-hb04-layout1.cfg
+
+El botón Start/Pause se puede conectar para un comportamiento estándar con:
+ [XHC_HB04_BUTTON]start-pause = std_start_pause
+
+El botón STEP normalmente está conectado con:
+ [XHC_HB04_BUTTON]step = xhc-hb04.stepsize-up
+
+Los otros botones se pueden conectar a los pines hal, típicamente pines provistos de halui.
+
+Los comandos MDI se pueden ejecutar usando los pines halui.mdi-command-nn definidos en el archivo ini con entradas como: [HALUI]MDI_COMMAND = mdi_command
+
+
+El interruptor giratorio selecciona el eje, el spindle.0 o el ajuste de velocidad para el control mediante la rueda.
+
+Las posiciones del interruptor (xyza) se pueden definir para cualquier eje disponible (xyzc, por ejemplo).
diff --git a/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_es.txt b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_es.txt
new file mode 100644
index 0000000000..d24421535d
--- /dev/null
+++ b/configs/sim/axis/xhc-hb04/xhc-hb04-layout2_es.txt
@@ -0,0 +1,40 @@
+xhc-hb04-layout2
+
+18 botones:
+
+---------------------------------------
+|RESET |Stop | |
+---------------------------------------
+|GotoZero|Start/Pause|Rewind |Probe-Z |
+---------------------------------------
+|Spindle | =1/2 | =0 |Safe-Z |
+---------------------------------------
+|GotoHome|Macro-1 |Macro-2|Macro-3 |
+---------------------------------------
+|STEP |Mode |Macro-6|Macro-7 |
+---------------------------------------
+| Off |
+| X |
+| Y |
+| Rotary -------> Z |
+| Switch A |
+| Spindle |
+| Feed |
+---------------------------------------
+
+Códigos de botón definidos en LIB:xhc-hb04-layout2.cfg
+
+El botón Start/Pause se puede conectar para un comportamiento estándar con:
+ [XHC_HB04_BUTTON]start-pause = std_start_pause
+
+El botón STEP normalmente está conectado con:
+ [XHC_HB04_BUTTON]step = xhc-hb04.stepsize-up
+
+Los otros botones se pueden conectar a los pines hal, típicamente pines provistos de halui.
+
+Los comandos MDI se pueden ejecutar usando los pines halui.mdi-command-nn definidos en el archivo ini con entradas como: [HALUI]MDI_COMMAND = mdi_command
+
+El interruptor giratorio selecciona el eje, spindle.0 o ajuste de velocidad para el control mediante la rueda.
+
+Las posiciones del interruptor (xyza) se pueden definir para cualquier eje disponible (xyzc, por ejemplo).
+
diff --git a/configs/sim/gmoccapy/README_es b/configs/sim/gmoccapy/README_es
new file mode 100644
index 0000000000..a6700af640
--- /dev/null
+++ b/configs/sim/gmoccapy/README_es
@@ -0,0 +1,13 @@
+Esta es una simulación de una fresadora con ejes XYZ y también un torno.
+
+Esta pantalla se basa en el diseño de moccagui, una GUI codificada en FreePascal.
+
+gmoccapy utiliza Python en su lugar.
+
+gmoccapy está diseñado para brindar la sensación de los controles industriales a los usuarios de LinuxCNC.
+La mayoría de los controles se pueden usar con una pantalla táctil y son accesibles a través de
+pines hal, por lo que se puede utilizar hardware real.
+
+Siéntase libre de enviar cualquier comentario a
+
+gmoccapy@web.de
diff --git a/configs/sim/gmoccapy/XYZAB.ini b/configs/sim/gmoccapy/XYZAB.ini
index e783ebac8a..c61ae2252c 100644
--- a/configs/sim/gmoccapy/XYZAB.ini
+++ b/configs/sim/gmoccapy/XYZAB.ini
@@ -41,7 +41,9 @@ MIN_SPINDLE_OVERRIDE = .5
# Max and default jog speeds in units per second
MAX_LINEAR_VELOCITY = 166
DEFAULT_LINEAR_VELOCITY = 5
-MAX_ANGULAR_VELOCITY = 234
+MIN_ANGULAR_VELOCITY = 10
+DEFAULT_ANGULAR_VELOCITY = 180
+MAX_ANGULAR_VELOCITY = 720
# Prefix to be used
PROGRAM_PREFIX = ../../nc_files/
diff --git a/configs/sim/gmoccapy/gmoccapy_XYZAB.ini b/configs/sim/gmoccapy/gmoccapy_XYZAB.ini
index e783ebac8a..35be5826f0 100644
--- a/configs/sim/gmoccapy/gmoccapy_XYZAB.ini
+++ b/configs/sim/gmoccapy/gmoccapy_XYZAB.ini
@@ -41,7 +41,9 @@ MIN_SPINDLE_OVERRIDE = .5
# Max and default jog speeds in units per second
MAX_LINEAR_VELOCITY = 166
DEFAULT_LINEAR_VELOCITY = 5
-MAX_ANGULAR_VELOCITY = 234
+DEFAULT_ANGULAR_VELOCITY = 180
+MIN_ANGULAR_VELOCITY = 10
+MAX_ANGULAR_VELOCITY = 720
# Prefix to be used
PROGRAM_PREFIX = ../../nc_files/
diff --git a/configs/sim/gmoccapy/gmoccapy_plasma/README_es b/configs/sim/gmoccapy/gmoccapy_plasma/README_es
new file mode 100644
index 0000000000..9d40e077d4
--- /dev/null
+++ b/configs/sim/gmoccapy/gmoccapy_plasma/README_es
@@ -0,0 +1,13 @@
+Esta es una simulación de un cortador de plasma XYZ (con unidades métricas).
+
+El propósito principal de esto es mostrar las posibilidades que ofrece gscreen/gmoccapy para diseñar pantallas personalizadas.
+
+Este diseño especial se ha hecho para controlar cortadores de plasma, Marius ha realizado muchos trabajos.
+
+El refrigerante original y los marcos del eje están ocultos, también el marco de información de la herramienta y la etiqueta de velocidad del eje en el marco activo de gcode están ocultos.
+
+Siéntase libre de enviar cualquier comentario a:
+
+gmoccapy@web.de
+
+
diff --git a/configs/sim/gmoccapy/lathe_configs/README b/configs/sim/gmoccapy/lathe_configs/README
new file mode 100644
index 0000000000..6b3d7802e5
--- /dev/null
+++ b/configs/sim/gmoccapy/lathe_configs/README
@@ -0,0 +1,8 @@
+This folder contains a number of simulated lathe configs.
+
+the "lathemacro" config offers a number of simple macros to perform
+the most common lathe operations.
+
+The GUI that controls the macros can be viewed by clicking the "Cycles"
+tab top left of the graphical preview window.
+
diff --git a/configs/sim/gmoccapy/lathe_configs/boring.ngc b/configs/sim/gmoccapy/lathe_configs/boring.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/lathe_configs/chamfer.ngc b/configs/sim/gmoccapy/lathe_configs/chamfer.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/lathe_configs/facing.ngc b/configs/sim/gmoccapy/lathe_configs/facing.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/lathe_configs/radius.ngc b/configs/sim/gmoccapy/lathe_configs/radius.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/lathe_configs/threading.ngc b/configs/sim/gmoccapy/lathe_configs/threading.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/lathe_configs/turning.ngc b/configs/sim/gmoccapy/lathe_configs/turning.ngc
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/macros/images/macro_8.png b/configs/sim/gmoccapy/macros/images/macro_8.png
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es b/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es
new file mode 100644
index 0000000000..317487458d
--- /dev/null
+++ b/configs/sim/gmoccapy/non_trivial_kinematics/scara/README_es
@@ -0,0 +1,9 @@
+La configuración puma es un conjunto de archivos que constituye una simulación scara LinuxCNC muy básica que usa ini, tbl, var. Es muy similar a la plantilla de configuración de sim, pero con 4 uniones definidas.
+
+scara.ini
+-------------
+Archivo de configuración para un robot tipo SCARA.
+
+Debe especificar qué cinemática se debe usar (loadrt scarakins en su archivo hal)
+
+Si cambia la ubicación de HOME en TRAJ, asegúrese de cambiar también las ubicaciones de HOME adecuadas de AXES, y asegúrese de que la posición coincida (cuando se ejecuta a través de la cinemática).
diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal b/configs/sim/gmoccapy/non_trivial_kinematics/scara/scara_postgui.hal
old mode 100755
new mode 100644
diff --git a/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es b/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es
new file mode 100644
index 0000000000..eb3bed15fd
--- /dev/null
+++ b/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/README_es
@@ -0,0 +1,12 @@
+Mesa Rotatoria/Inclinable (trt) Configuraciones Sim
+
+xyzac-trt
+xyzbc-trt
+
+Fichero ejemplo ngc:
+ examples/boat-xyzac.ngc (!!! TOUCHOFF table Z to -13.25 !!!)
+ examples/boat-xyzbc.ngc (!!! TOUCHOFF table Z to - 8.30 !!!)
+
+Fichero ejemplo ngc (compatibles con subrutinas ngcgui):
+ examples/test-xyzac.ngc
+ examples/test-xyzbc.ngc
diff --git a/configs/sim/gmoccapy/plasma_config/README_es b/configs/sim/gmoccapy/plasma_config/README_es
new file mode 100644
index 0000000000..0f86d487c2
--- /dev/null
+++ b/configs/sim/gmoccapy/plasma_config/README_es
@@ -0,0 +1,14 @@
+Esta es una simulación de un cortador de plasma XYZ (con unidades métricas).
+
+El propósito principal de esto es mostrar las posibilidades que ofrece gscreen/gmoccapy para diseñar pantallas personalizadas.
+
+Este diseño especial se ha hecho para controlar cortadores de plasma, Marius ha realizado muchos trabajos.
+
+El refrigerante original y los marcos del eje están ocultos, también el marco de información de la herramienta y la etiqueta de velocidad del eje en el marco activo de gcode están ocultos.
+
+Siéntase libre de enviar cualquier comentario a:
+
+gmoccapy@web.de
+
+
+
diff --git a/configs/sim/gscreen/README_es b/configs/sim/gscreen/README_es
new file mode 100644
index 0000000000..2215668426
--- /dev/null
+++ b/configs/sim/gscreen/README_es
@@ -0,0 +1,15 @@
+Gscreen es una pantalla de operador personalizable para LinuxCNC.
+Construido con python, GLADE, y GTK
+
+Utilizable con pantallas táctiles o un mouse.
+Estos .ini muestran el aspecto nativo de Gscreen.
+
+gscreen.ini
+ -Pantalla de fresado imperial,
+ -incluye paneles opcionales de gladevcp
+
+gscreen_lathe.ini
+ -Torno básico imperial.
+
+gscreen_mm.ini
+ - Pantalla de fresado métrico.
diff --git a/configs/sim/gscreen/gscreen_custom/README_es b/configs/sim/gscreen/gscreen_custom/README_es
new file mode 100644
index 0000000000..777eac2bac
--- /dev/null
+++ b/configs/sim/gscreen/gscreen_custom/README_es
@@ -0,0 +1,33 @@
+Gscreen es una pantalla de operador personalizable para LinuxCNC.
+
+Construido con python, GLADE, y GTK
+
+Utilizable con pantallas táctiles o un mouse.
+Estos ejemplos muestran algunos aspectos personalizados de Gscreen.
+
+9axis.ini
+ Pantalla de 9 ejes
+
+gaxis_no_plot.ini
+gscreen_gaxis.ini
+ -Una demostración similar a AXIS
+
+industrial.ini
+ -Diseño influenciado por Controles CNC industriales.
+ (El código de desbloqueo de la página del sistema es '123')
+
+tester.ini
+ -Tester se usa para cargar un archivo GLADE sin inicializar nada más que la ventana.
+ El archivo glade se debe llamar tester.glade
+ La ventana de nivel superior debe llamarse window1
+ tester_handler.py también es una plantilla de un
+ archivo de controlador para agregar código de Python para
+ personalizaciones más sofisticadas.
+ Si ejecuta esto sin añadir un archivo GLADE
+ a la carpeta, se cargará un archivo predeterminado
+ con un mensaje.
+ Esto es para máquinas con base imperial.
+
+tester_metric.ini
+ Esto es para máquinas métricas.
+ Funciona/requiere todo lo mismo que test.ini de arriba.
diff --git a/configs/sim/gscreen/industrial_lathe_wear/README_es b/configs/sim/gscreen/industrial_lathe_wear/README_es
new file mode 100644
index 0000000000..8c0b662600
--- /dev/null
+++ b/configs/sim/gscreen/industrial_lathe_wear/README_es
@@ -0,0 +1,3 @@
+Esta es la pantalla industrial de Gscreen combinada con una reasignación para agregar compensaciones de desgaste del torno y cambiar herramientas sin m6
+t101 proporciona la herramienta 1 con desplazamiento 1. El desplazamiento 1 está en el archivo de herramientas como herramienta 10001.
+t201 proporciona la herramienta 2 con desplazamiento 1. El desplazamiento 1 está en el archivo de herramientas como herramienta 10001.
diff --git a/configs/sim/gscreen/ngcgui/README_es b/configs/sim/gscreen/ngcgui/README_es
new file mode 100644
index 0000000000..068f8ff96b
--- /dev/null
+++ b/configs/sim/gscreen/ngcgui/README_es
@@ -0,0 +1,6 @@
+Ejemplos que muestran aplicaciones gladevcp:
+
+ pyngcgui pestaña en gui gscreen
+ gremlin_view pestaña en gui gscreen
+
+
diff --git a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_es.txt b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_es.txt
new file mode 100644
index 0000000000..e20baaad47
--- /dev/null
+++ b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_es.txt
@@ -0,0 +1,5 @@
+Demuestra aplicaciones gladevcp en pestañas de gscreen:
+
+ pyngcgui ------ utilidad de subrutina
+ gremlin_view -- gremlin con algunos botones
+
diff --git a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_gcmc_es.txt b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_gcmc_es.txt
new file mode 100644
index 0000000000..33c184d150
--- /dev/null
+++ b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_gcmc_es.txt
@@ -0,0 +1,17 @@
+Demuestra aplicaciones gladevcp en pestañas de gscreen:
+
+ pyngcgui ------ utilidad de subrutina
+ gremlin_view - gremlin con algunos botones
+
+con soporte para archivos .gcmc (G-Code Meta Compiler)
+
+Los archivos .ngc y .gcmc se pueden mezclar con
+líneas de archivo ini como:
+
+NGCGUI_SUBFILE = drill.gcmc
+NGCGUI_SUBFILE = wheels.gcmc
+NGCGUI_SUBFILE = star.gcmc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = ""
+
+Ver el archivo ini para detalles de ejemplo
\ No newline at end of file
diff --git a/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard_es.txt b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard_es.txt
new file mode 100644
index 0000000000..69ee164e34
--- /dev/null
+++ b/configs/sim/gscreen/ngcgui/pyngcgui_gscreen_popupkeyboard_es.txt
@@ -0,0 +1,6 @@
+Demuestra aplicaciones gladevcp en pestañas de gscreen:
+
+ pyngcgui ------ utilidad de subrutina
+ gremlin_view -- gremlin con algunos botones
+
+con un teclado emergente para usar con pantalla táctil
diff --git a/configs/sim/gscreen/silverdragon/README_es b/configs/sim/gscreen/silverdragon/README_es
new file mode 100644
index 0000000000..2f2b938879
--- /dev/null
+++ b/configs/sim/gscreen/silverdragon/README_es
@@ -0,0 +1,6 @@
+Esta es una pantalla de operador basada en gscreen para enrutadores/fresadoras.
+Fue diseñado por un usuario, Jim (persei8 en el foro) para su enrutador personal y cedido al
+proyecto linuxcnc.
+
+Este es un ejemplo de máquina simulada: será necesaria alguna adaptación de los archivos.
+
diff --git a/configs/sim/gscreen/spartan/README_es b/configs/sim/gscreen/spartan/README_es
new file mode 100644
index 0000000000..70ffa3fd70
--- /dev/null
+++ b/configs/sim/gscreen/spartan/README_es
@@ -0,0 +1,8 @@
+Esta es una pantalla de operador basada en gscreen para fresadoras.
+Fue diseñado por un usuario, Chris Brady para su proyecto y cedido al
+proyecto linuxcnc.
+
+Requiere algunos botones de hardware para funcionar, como un botón de inicio de ciclo.
+
+Este es un ejemplo de máquina simulada: será necesaria alguna adaptación de los archivos.
+
diff --git a/configs/sim/pyvcp_demo/README_es b/configs/sim/pyvcp_demo/README_es
new file mode 100644
index 0000000000..6c0f0c7ac6
--- /dev/null
+++ b/configs/sim/pyvcp_demo/README_es
@@ -0,0 +1,6 @@
+La configuración sim es un conjunto de archivos
+que dan una demostración de algunos de los widgets de pyvcp
+Nota:
+El widget de barra cambia de color en ciertos rangos de valores.
+El valor de los spinboxs y los diales se puede cambiar usando señales HAL.
+El multilabel cambiará el texto según la señal HAL.
diff --git a/configs/sim/qtvcp_screens/README_es b/configs/sim/qtvcp_screens/README_es
new file mode 100644
index 0000000000..7241ce0cf0
--- /dev/null
+++ b/configs/sim/qtvcp_screens/README_es
@@ -0,0 +1,12 @@
+Qtvcp es una infraestructura para construir pantallas/paneles de operador personalizados
+para LinuxCNC.
+
+Construido con python 2, QTDesigner y PyQt5
+
+Estas son pantallas de demostración/prueba para el kit de herramientas QTvcp.
+No han sido muy probados para operar hardware real.
+Por favor, pruebe cuidadosamente su idoneidad.
+
+Qtdefault - es la pantalla de prueba predeterminada
+Blender está inspirado en un diseño del foro linuxcnc.
+QtAxis es una versión QT de la pantalla AXIS de linuxcnc.
diff --git a/configs/sim/qtvcp_screens/blender.ini b/configs/sim/qtvcp_screens/blender.ini
index 839bc6e046..88f2462908 100644
--- a/configs/sim/qtvcp_screens/blender.ini
+++ b/configs/sim/qtvcp_screens/blender.ini
@@ -42,7 +42,7 @@ DEBUG = 0x00002000
# Name of display program, e.g., xemc
DISPLAY = qtvcp -m blender
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/blender.pref
# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME = 0.100
diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/README_es b/configs/sim/qtvcp_screens/industrial_lathe_wear/README_es
new file mode 100644
index 0000000000..8c0b662600
--- /dev/null
+++ b/configs/sim/qtvcp_screens/industrial_lathe_wear/README_es
@@ -0,0 +1,3 @@
+Esta es la pantalla industrial de Gscreen combinada con una reasignación para agregar compensaciones de desgaste del torno y cambiar herramientas sin m6
+t101 proporciona la herramienta 1 con desplazamiento 1. El desplazamiento 1 está en el archivo de herramientas como herramienta 10001.
+t201 proporciona la herramienta 2 con desplazamiento 1. El desplazamiento 1 está en el archivo de herramientas como herramienta 10001.
diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini b/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini
index 6d6bf6f3c4..877fdcb04c 100644
--- a/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini
+++ b/configs/sim/qtvcp_screens/industrial_lathe_wear/industrial_lathe_wear.ini
@@ -5,6 +5,7 @@ DEBUG = 0
[DISPLAY]
DISPLAY = qtvcp -d qtlathe
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qtlathe.pref
LATHE = true
OPEN_FILE = ""
CYCLE_TIME = 0.100
@@ -34,10 +35,24 @@ PROGRAM_EXTENSION = .py Python Script
py = python
[RS274NGC]
-SUBROUTINE_PATH = ./:../:~/linuxcnc/nc_files/macros/lathe
-REMAP = T prolog=get_T_number ngc=toolchange
+SUBROUTINE_PATH = ./:../:~/linuxcnc/nc_files/macros/lathe:~/linuxcnc/nc_files/examples/macros/lathe
+REMAP=T python=index_lathe_tool_with_wear
+REMAP=M6 python=ignore_m6
PARAMETER_FILE = sim.var
+[PYTHON]
+# where to find Python code
+# code specific for this configuration
+PATH_PREPEND=./
+# generic support code
+PATH_APPEND=../../nc_files/remap_lib/python-stdglue/
+
+# import the following Python module
+TOPLEVEL=toplevel.py
+
+# the higher the more verbose tracing of the Python plugin
+LOG_LEVEL = 0
+
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
@@ -64,22 +79,9 @@ POSITION_FILE = position.txt
[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
-TOOL_TABLE = lathe-fanucy.tbl
+TOOL_TABLE = lathe-wear.tbl
TOOL_CHANGE_WITH_SPINDLE_ON = 1
-[PYTHON]
-# where to find Python code
-# code specific for this configuration
-PATH_PREPEND= ./
-# generic support code
-PATH_APPEND= ../../nc_files/remap_lib/python-stdglue/
-
-# import the following Python module
-TOPLEVEL= toplevel.py
-
-# the higher the more verbose tracing of the Python plugin
-LOG_LEVEL = 0
-
[KINS]
KINEMATICS = trivkins coordinates=xz
JOINTS = 2
diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-fanucy.tbl b/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-fanucy.tbl
deleted file mode 100644
index eadb6f028d..0000000000
--- a/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-fanucy.tbl
+++ /dev/null
@@ -1,12 +0,0 @@
-T1 P1 X0.1 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I95.0 J155.0 Q1.0 ;face
-T2 P2 X0.2 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I85.0 J25.0 Q2.0 ;turn
-T3 P3 X0.1 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I95.0 J155.0 Q1.0 ;face
-T4 P4 X0.2 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I85.0 J25.0 Q2.0 ;turn
-T5 P5 X0.0 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I210.0 J150.0 Q5.0 ;No Tool
-T6 P6 X0.5 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I120.0 J60.0 Q6.0 ;No Tool
-T7 P7 X0.0 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I0.0 J30.0 Q7.0 ;No Tool
-T8 P8 X0.0 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I240.0 J300.0 Q8.0 ;No Tool
-T9 P9 X0.0 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I0.0 J0.0 Q9.0 ;No Tool
-T10 P10 X0.0 Y0 Z0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q0.0 ;No Tool
-T10001 P0 X0.001 Y0 Z0.001 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset Tool 1
-T10002 P0 X0.002 Y0 Z0.002 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset Tool 2
diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-wear.tbl b/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-wear.tbl
new file mode 100644
index 0000000000..2bc57dc7c5
--- /dev/null
+++ b/configs/sim/qtvcp_screens/industrial_lathe_wear/lathe-wear.tbl
@@ -0,0 +1,20 @@
+T1 P1 X0.10000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I95.0 J155.0 Q1 ;face
+T2 P2 X0.20000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I85.0 J25.0 Q2 ;turn
+T3 P3 X0.10000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I95.0 J155.0 Q1 ;face
+T4 P4 X0.20000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I85.0 J25.0 Q2 ;turn
+T5 P5 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I210.0 J150.0 Q5 ;No Tool
+T6 P6 X0.50000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I120.0 J60.0 Q6 ;No Tool
+T7 P7 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I0 J30.0 Q7 ;No Tool
+T8 P8 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I240.0 J300.0 Q8 ;No Tool
+T9 P9 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0.10000 I0 J0 Q9 ;No Tool
+T10 P10 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;No Tool
+T10001 P0 X0.00100 Y0 Z0.00100 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 1
+T10002 P0 X0.00200 Y0 Z0.00200 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 2
+T10003 P0 X0.01000 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 3
+T10004 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 4
+T10005 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 5
+T10006 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 6
+T10007 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 7
+T10008 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 8
+T10009 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 9
+T10010 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D0 I0 J0 Q0 ;Wear Offset 10
diff --git a/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py b/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py
index 693385b384..4eb1f4a32d 100644
--- a/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py
+++ b/configs/sim/qtvcp_screens/industrial_lathe_wear/remap.py
@@ -1,6 +1,5 @@
# This is a component of LinuxCNC
-# Copyright 2014 Andy Pugh , Chris Radek
-#
+# Copyright 2020 Chris Morley
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,18 +15,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
-from stdglue import *
+# see nc_files/remap_lib/stdglue.py
+#
+# use standard python remap functions:
+# index_lathe_tool_with_wear()
+# ignore_m6()
-# Extract the T number into a parameter, but don't try anything else clever
+from stdglue import *
-def get_T_number(self,**words):
- try:
- cblock = self.blocks[self.remap_level]
- if not cblock.t_flag:
- self.set_errormsg("T requires a tool number")
- return INTERP_ERROR
- self.params["tool"] = cblock.t_number
- return INTERP_OK
- except Exception, e:
- self.set_errormsg("T%d/prepare_prolog: %s" % (int(words['t']), e))
- return INTERP_ERROR
diff --git a/configs/sim/qtvcp_screens/qt_800x600.ini b/configs/sim/qtvcp_screens/qt_800x600.ini
index 4d4ddeb3c1..f122618394 100644
--- a/configs/sim/qtvcp_screens/qt_800x600.ini
+++ b/configs/sim/qtvcp_screens/qt_800x600.ini
@@ -25,7 +25,7 @@ DEBUG = 0
# Name of display program, e.g., xemc
DISPLAY = qtvcp -d qt_cnc_800x600.ui
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qt_cnc_800x600.pref
# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME = 0.100
diff --git a/configs/sim/qtvcp_screens/qt_gantry.ini b/configs/sim/qtvcp_screens/qt_gantry.ini
index f8f82285f3..eb8a56fee4 100644
--- a/configs/sim/qtvcp_screens/qt_gantry.ini
+++ b/configs/sim/qtvcp_screens/qt_gantry.ini
@@ -25,7 +25,7 @@ DEBUG = 0
[DISPLAY]
DISPLAY = qtvcp -d qtaxis
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qtaxis_gantry.pref
CYCLE_TIME = 0.100
MAX_FEED_OVERRIDE = 1.2
PROGRAM_PREFIX = ../../nc_files/
diff --git a/configs/sim/qtvcp_screens/qtaxis.ini b/configs/sim/qtvcp_screens/qtaxis.ini
index d594ee8f89..e5e03e8c93 100644
--- a/configs/sim/qtvcp_screens/qtaxis.ini
+++ b/configs/sim/qtvcp_screens/qtaxis.ini
@@ -42,7 +42,7 @@ DEBUG = 0x00002000
# Name of display program, e.g., xemc
DISPLAY = qtvcp -d qtaxis
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qtaxis.pref
# embedded programs
#EMBED_TAB_NAME=Onboard demo
#EMBED_TAB_COMMAND=onboard --xid
diff --git a/configs/sim/qtvcp_screens/qtdefault.ini b/configs/sim/qtvcp_screens/qtdefault.ini
index da46d7d499..a7f9ed63f2 100644
--- a/configs/sim/qtvcp_screens/qtdefault.ini
+++ b/configs/sim/qtvcp_screens/qtdefault.ini
@@ -42,7 +42,7 @@ DEBUG = 0x00002000
# Name of display program, e.g., xemc
DISPLAY = qtvcp -d
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qt_cnc.pref
# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME = 0.100
@@ -118,7 +118,7 @@ py = python
# File containing interpreter variables
PARAMETER_FILE = sim.var
-SUBROUTINE_PATH = ~/linuxcnc/nc_files/macros/lathe:~/linuxcnc/nc_files/macros/probe
+SUBROUTINE_PATH = ~/linuxcnc/nc_files/macros/lathe:~/linuxcnc/nc_files/macros/probe::~/linuxcnc/nc_files/examples/macros/mill
# Motion control section ------------------------------------------------------
[EMCMOT]
diff --git a/configs/sim/qtvcp_screens/qtdefault_9axis.ini b/configs/sim/qtvcp_screens/qtdefault_9axis.ini
index e5e3499474..f5911bf06b 100644
--- a/configs/sim/qtvcp_screens/qtdefault_9axis.ini
+++ b/configs/sim/qtvcp_screens/qtdefault_9axis.ini
@@ -5,6 +5,7 @@ MACHINE = LinuxCNC-sim-9axis
[DISPLAY]
DISPLAY = qtvcp qt_cnc_9_axis
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qt_cnc_9axis.pref
CYCLE_TIME = 0.100
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
diff --git a/configs/sim/qtvcp_screens/qtdefault_gantry.ini b/configs/sim/qtvcp_screens/qtdefault_gantry.ini
index e637bb6c42..adcf338f87 100644
--- a/configs/sim/qtvcp_screens/qtdefault_gantry.ini
+++ b/configs/sim/qtvcp_screens/qtdefault_gantry.ini
@@ -24,7 +24,8 @@ MACHINE = LinuxCNC-GANTRY-SIM-AXIS
DEBUG = 0
[DISPLAY]
-DISPLAY = qtvcp -d
+DISPLAY = qtvcp -d
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qt_cnc_gantry.pref
CYCLE_TIME = 0.100
HELP_FILE = tklinuxcnc.txt
POSITION_OFFSET = RELATIVE
diff --git a/configs/sim/qtvcp_screens/qtdefault_mm.ini b/configs/sim/qtvcp_screens/qtdefault_mm.ini
index 4e99e56541..37141f368b 100644
--- a/configs/sim/qtvcp_screens/qtdefault_mm.ini
+++ b/configs/sim/qtvcp_screens/qtdefault_mm.ini
@@ -20,7 +20,7 @@ DEBUG = 0
# Name of display program, e.g., axis
DISPLAY = qtvcp
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qt_cnc_mm.pref
# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME = 0.100
diff --git a/configs/sim/qtvcp_screens/qtdragon/gantrysim.hal b/configs/sim/qtvcp_screens/qtdragon/gantrysim.hal
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui.hal b/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui.hal
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui_ya.hal b/configs/sim/qtvcp_screens/qtdragon/qtdragon_postgui_ya.hal
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini b/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyz.ini
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini b/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyza.ini
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini b/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzy.ini
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini b/configs/sim/qtvcp_screens/qtdragon/qtdragon_xyzya.ini
old mode 100755
new mode 100644
diff --git a/configs/sim/qtvcp_screens/qttouchy/qttouchy.ini b/configs/sim/qtvcp_screens/qttouchy/qttouchy.ini
index cddc71e7ed..02fb33a40f 100644
--- a/configs/sim/qtvcp_screens/qttouchy/qttouchy.ini
+++ b/configs/sim/qtvcp_screens/qttouchy/qttouchy.ini
@@ -42,7 +42,7 @@ DEBUG = 0x00002000
# Name of display program, e.g., xemc
DISPLAY = qtvcp -d qttouchy
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qttouchy.pref
# Cycle time, in seconds, that display will sleep between polls
CYCLE_TIME = 0.100
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/LatheMacro.svg b/configs/sim/qtvcp_screens/qtvcp_experimental/LatheMacro.svg
new file mode 100644
index 0000000000..e632e2543b
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/LatheMacro.svg
@@ -0,0 +1,2135 @@
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/check_constraints.hal b/configs/sim/qtvcp_screens/qtvcp_experimental/check_constraints.hal
new file mode 100644
index 0000000000..c2a432078e
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/check_constraints.hal
@@ -0,0 +1,63 @@
+# HAL config file to check vel/acc constraints
+#
+loadrt wcomp names=wcomp_xacc,wcomp_xvel,wcomp_yacc,wcomp_yvel,wcomp_zacc,wcomp_zvel
+
+addf wcomp_xacc servo-thread
+addf wcomp_xvel servo-thread
+addf wcomp_yacc servo-thread
+addf wcomp_yvel servo-thread
+addf wcomp_zacc servo-thread
+addf wcomp_zvel servo-thread
+
+net Xacc => wcomp_xacc.in
+net Xvel => wcomp_xvel.in
+net Yacc => wcomp_yacc.in
+net Yvel => wcomp_yvel.in
+net Zacc => wcomp_zacc.in
+net Zvel => wcomp_zvel.in
+
+net acc-ok-x <= wcomp_xacc.out
+net vel-ok-x <= wcomp_xvel.out
+net acc-ok-y <= wcomp_yacc.out
+net vel-ok-y <= wcomp_yvel.out
+net acc-ok-z <= wcomp_zacc.out
+net vel-ok-z <= wcomp_zvel.out
+
+setp wcomp_xacc.max 50.001
+setp wcomp_xacc.min -50.001
+setp wcomp_xvel.max 5.001
+setp wcomp_xvel.min -5.001
+setp wcomp_yacc.max 50.001
+setp wcomp_yacc.min -50.001
+setp wcomp_yvel.max 5.001
+setp wcomp_yvel.min -5.001
+setp wcomp_zacc.max 50.001
+setp wcomp_zacc.min -50.001
+setp wcomp_zvel.max 5.001
+setp wcomp_zvel.min -5.001
+
+loadrt match8 names=match_all
+
+addf match_all servo-thread
+
+net acc-ok-x => match_all.a0
+setp match_all.b0 1
+net vel-ok-x => match_all.a1
+setp match_all.b1 1
+net acc-ok-y => match_all.a2
+setp match_all.b2 1
+net vel-ok-y => match_all.a3
+setp match_all.b3 1
+net acc-ok-z => match_all.a4
+setp match_all.b4 1
+net vel-ok-z => match_all.a5
+setp match_all.b5 1
+
+setp match_all.a6 0
+setp match_all.a7 0
+setp match_all.b6 0
+setp match_all.b7 0
+
+setp match_all.in 1
+
+net constraints-ok <= match_all.out
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc.ui b/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc.ui
new file mode 100644
index 0000000000..e13b272c21
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc.ui
@@ -0,0 +1,3086 @@
+
+
+ MainWindow
+
+
+ true
+
+
+
+ 0
+ 0
+ 1791
+ 790
+
+
+
+
+ 1027
+ 790
+
+
+
+
+ 10270
+ 790
+
+
+
+ MainWindow
+
+
+
+
+
+
+
+
+ 450
+ 520
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 75 18pt "Courier 10 Pitch";
+
+
+ 1
+
+
+ 0
+
+
+
+
+
+ 450
+ 550
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 18pt "Courier 10 Pitch";
+
+
+ 0.5217
+
+
+ Qt::PlainText
+
+
+ true
+
+
+ 2
+
+
+ 0
+
+
+
+
+
+ 450
+ 490
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 75 18pt "Courier 10 Pitch";
+
+
+ -1.6994
+
+
+ 0
+
+
+
+
+ true
+
+
+
+ 210
+ 10
+ 811
+ 231
+
+
+
+ #frame{
+border-image: url(/home/chris/emc-dev/configs/sim/qtscreen/backgound_blue.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 80
+ 10
+ 291
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ QFrame::NoFrame
+
+
+ Qt::AutoText
+
+
+ 1
+
+
+
+
+
+ 80
+ 70
+ 291
+ 61
+
+
+
+ font: 75 48pt "Noto Sans";
+color: rgb(255, 255, 255);
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 80
+ 130
+ 291
+ 61
+
+
+
+ font: 75 48pt "Noto Sans";
+color: rgb(255, 255, 255);
+
+
+ 2
+
+
+ 1
+
+
+
+
+
+ 10
+ 11
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ X
+
+
+
+
+
+ 10
+ 70
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ Y
+
+
+
+
+
+ 10
+ 130
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ Z
+
+
+
+
+
+ 280
+ 190
+ 131
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">%3.1f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 370
+ 40
+ 41
+ 22
+
+
+
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">MM</span></p></body></html>
+
+
+
+
+
+
+
+
+ 420
+ 0
+ 400
+ 231
+
+
+
+
+
+
+ 370
+ 10
+ 51
+ 22
+
+
+
+
+
+
+ false
+
+
+ true
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">DIAM</span></p></body></html>
+
+
+
+
+
+
+
+
+ 100
+ 190
+ 91
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">100.000</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">%3.3f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 370
+ 70
+ 51
+ 21
+
+
+
+ 0
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">G100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">G%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 200
+ 190
+ 101
+ 31
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 18pt "Noto Sans";
+
+
+ Velocity:
+
+
+ Qt::AutoText
+
+
+
+
+ true
+
+
+
+ 10
+ 191
+ 81
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">IPR:</span></p></body></html>
+
+
+ Qt::AutoText
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">mmPR:</span></p></body></html>
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">IPR:</span></p></body></html>
+
+
+
+
+
+
+ 210
+ 250
+ 811
+ 201
+
+
+
+
+
+ 489
+ 323
+ 700
+ 400
+
+
+
+
+
+
+ 130
+ 30
+ 800
+ 247
+
+
+
+ false
+
+
+
+
+
+
+ 610
+ 490
+ 61
+ 91
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+ 0
+ 60
+ 61
+ 27
+
+
+
+ Zero Z
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+
+
+
+ 0
+ 30
+ 61
+ 27
+
+
+
+ Zero Y
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+
+
+
+ 0
+ 0
+ 61
+ 27
+
+
+
+ Zero X
+
+
+ false
+
+
+ true
+
+
+ 0
+
+
+
+
+
+
+ 20
+ 650
+ 72
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;;">Jog Rate</span></p></body></html>
+
+
+
+
+
+ 150
+ 650
+ 61
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Jog Inc</span></p></body></html>
+
+
+
+
+
+ 700
+ 500
+ 71
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Number</span></p></body></html>
+
+
+
+
+
+ 700
+ 530
+ 72
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Diameter</span></p></body></html>
+
+
+
+
+
+ 360
+ 580
+ 301
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 130
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">RO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">RO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 20
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">FO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">FO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+
+
+
+ 240
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">SO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">SO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 760
+ 490
+ 71
+ 41
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">100</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">%d</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 90
+ 640
+ 61
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">100</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%2.f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 410
+ 610
+ 251
+ 61
+
+
+
+ <html><head/><body><p><span style=" font-size:36pt; color:#ffff00;">100</span><span style=" font-size:36pt; color:#d1d1d1;"> RPM</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p><span style=" font-size:36pt; color:#ffff00;">%d</span><span style=" font-size:36pt; color:#d1d1d1;"> RPM</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 480
+ 760
+ 316
+ 121
+
+
+
+ false
+
+
+
+
+
+ 0
+ 0
+ 1027
+ 847
+
+
+
+ false
+
+
+ true
+
+
+ STD_IMAGE_DIR/lcnc_swoop.png
+
+
+
+
+
+ 340
+ 770
+ 336
+ 104
+
+
+
+ false
+
+
+
+
+
+ 390
+ 240
+ 635
+ 448
+
+
+
+ false
+
+
+
+ 0
+ 0
+ 255
+
+
+
+
+
+
+ 590
+ 490
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 590
+ 520
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+ 1
+
+
+
+
+
+ 590
+ 550
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+ 2
+
+
+
+
+
+ 360
+ 685
+ 56
+ 31
+
+
+
+ MAN
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 490
+ 685
+ 56
+ 31
+
+
+
+ MDI
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 610
+ 685
+ 56
+ 31
+
+
+
+ AUTO
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 240
+ 820
+ 16
+ 16
+
+
+
+
+
+
+ 210
+ 640
+ 131
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%s</span></p></body></html>
+
+
+ true
+
+
+
+
+
+ 390
+ 230
+ 600
+ 400
+
+
+
+ false
+
+
+
+
+
+ 40
+ 40
+ 800
+ 500
+
+
+
+ false
+
+
+
+
+
+ 10
+ 10
+ 191
+ 441
+
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ false
+
+
+
+ 0
+ 260
+ 191
+ 181
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+ 0
+ 9
+ 191
+ 171
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+
+ 130
+ 70
+ 56
+ 32
+
+
+
+ X+
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 10
+ 70
+ 56
+ 32
+
+
+
+ X-
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 0
+ 56
+ 32
+
+
+
+ Z+
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+ 2
+
+
+
+
+
+ 10
+ 140
+ 56
+ 32
+
+
+
+ Z-
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+ 2
+
+
+
+
+
+ 70
+ 110
+ 56
+ 32
+
+
+
+ Y-
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 70
+ 30
+ 56
+ 32
+
+
+
+ Y+
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 80
+ 150
+ 101
+ 21
+
+
+
+
+
+
+
+
+ 30
+ 10
+ 131
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Home
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ -1
+
+
+
+
+
+ 130
+ 150
+ 55
+ 32
+
+
+
+ Fwd
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+ 10
+ 150
+ 55
+ 32
+
+
+
+ Rev
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 130
+ 190
+ 55
+ 32
+
+
+
+ +
+
+
+ true
+
+
+
+
+
+ 10
+ 190
+ 55
+ 32
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+ 70
+ 161
+ 55
+ 51
+
+
+
+ Stop
+
+
+ true
+
+
+
+
+
+ 10
+ 70
+ 81
+ 41
+
+
+
+ offsets
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 100
+ 70
+ 81
+ 41
+
+
+
+ Cam View
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 140
+ 10
+ 20
+ 20
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 50
+ 80
+ 91
+ 41
+
+
+
+ Macro
+
+
+ true
+
+
+
+
+
+ 50
+ 180
+ 91
+ 41
+
+
+
+ Go to
+Origion Zero
+
+
+ true
+
+
+ MDI_COMMAND_LIST = 0
+
+
+
+
+
+ 50
+ 230
+ 91
+ 41
+
+
+
+ Go to
+ Machine Zero
+
+
+ true
+
+
+ G53 G0 X0Y0Z0
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 20
+ 60
+ 61
+ 61
+
+
+
+ load
+file
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 100
+ 60
+ 61
+ 61
+
+
+
+ Run
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 30
+ 190
+ 61
+ 32
+
+
+
+ View P
+
+
+ true
+
+
+
+
+
+ 100
+ 190
+ 61
+ 32
+
+
+
+ View Z
+
+
+ true
+
+
+ z
+
+
+
+
+
+ 30
+ 240
+ 61
+ 32
+
+
+
+ View Y
+
+
+ true
+
+
+ y
+
+
+
+
+
+ 100
+ 240
+ 61
+ 32
+
+
+
+ View X
+
+
+ true
+
+
+ x
+
+
+
+
+
+ 20
+ 290
+ 71
+ 32
+
+
+
+ View Y2
+
+
+ true
+
+
+ y2
+
+
+
+
+
+ 100
+ 290
+ 71
+ 32
+
+
+
+ View Z2
+
+
+ true
+
+
+ z2
+
+
+
+
+
+
+
+
+ 860
+ 550
+ 91
+ 21
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+
+
+
+ 860
+ 580
+ 91
+ 21
+
+
+
+ 200
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 860
+ 610
+ 91
+ 21
+
+
+
+ 50
+
+
+ 150
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 860
+ 640
+ 91
+ 21
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 20
+ 725
+ 311
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Mcodes: </span><span style=" color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Mcodes: </span><span style=" color:#ffff00;">%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 955
+ 580
+ 51
+ 24
+
+
+
+ FO
+
+
+ true
+
+
+ true
+
+
+ 75.000000000000000
+
+
+
+
+
+ 955
+ 550
+ 51
+ 24
+
+
+
+ RO
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+ 25.000000000000000
+
+
+
+
+
+ 955
+ 610
+ 51
+ 24
+
+
+
+ SO
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+ 90.000000000000000
+
+
+
+
+
+ 955
+ 640
+ 51
+ 24
+
+
+
+ Jog
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 60.000000000000000
+
+
+ 15.000000000000000
+
+
+
+
+
+ 10
+ 460
+ 341
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 130
+ 10
+ 121
+ 27
+
+
+
+ Override Limits
+
+
+ true
+
+
+
+
+
+ 230
+ 0
+ 31
+ 41
+
+
+
+ 10
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 10
+ 10
+ 101
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Estop
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 10
+ 60
+ 101
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Power
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 100
+ 121
+ 27
+
+
+
+ Flood
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 130
+ 121
+ 27
+
+
+
+ Mist
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 40
+ 121
+ 27
+
+
+
+ Block Delete
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 70
+ 121
+ 27
+
+
+
+ Optional Stop
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 30
+ 31
+ 41
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 60
+ 31
+ 41
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 100
+ 31
+ 21
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 130
+ 31
+ 21
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 90
+ 60
+ 31
+ 21
+
+
+
+ 15
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 90
+ 10
+ 21
+ 21
+
+
+
+ 20
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 10
+ 110
+ 101
+ 51
+
+
+
+ Abort
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 260
+ 10
+ 61
+ 61
+
+
+
+ Pause
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 300
+ 10
+ 31
+ 16
+
+
+
+ 10
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+ 350
+ 460
+ 331
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 850
+ 460
+ 171
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 10
+ 10
+ 45
+ 27
+
+
+
+ Fine
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ 0.001000000000000
+
+
+ 0.010000000000000
+
+
+
+
+
+ 60
+ 10
+ 45
+ 27
+
+
+
+ Med
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ 0.010000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+ 110
+ 10
+ 45
+ 27
+
+
+
+ Large
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+
+
+
+ 20
+ 40
+ 121
+ 27
+
+
+
+ Continous
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ 0.000000000000000
+
+
+ 0.000000000000000
+
+
+
+
+
+
+ 10
+ 680
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 350
+ 680
+ 331
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 10
+ 720
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 350
+ 720
+ 671
+ 41
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 680
+ 680
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 60
+ -4
+ 271
+ 41
+
+
+
+
+ 15
+ 75
+ true
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 0
+ 0
+ 61
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">MDI:</span></p></body></html>
+
+
+
+
+
+
+ 370
+ 725
+ 651
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Gcodes: </span><span style=" color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Gcodes: </span><span style=" color:#ffff00;">%s</span></p></body></html>
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 680
+ 460
+ 171
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 10
+ 110
+ 151
+ 21
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+ 760
+ 530
+ 91
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">100.000</span></p></body></html>
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">%3.3f</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 410
+ 590
+ 251
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">200.00</span><span style=" font-size:18pt; color:#d1d1d1;"> SFPM</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%.2f</span><span style=" font-size:18pt; color:#d1d1d1;"> SFPM</span></p></body></html>
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%.2f</span><span style=" font-size:18pt; color:#d1d1d1;"> SMPM</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 1029
+ -1
+ 751
+ 761
+
+
+
+
+
+
+ halcmd loadusr gladevcp --xid pyngcgui.ui
+
+
+
+
+
+ lcncdialog
+ frame_auto_5
+ state_label_4
+ StatusLabel
+ frame_auto_10
+ frame_auto_9
+ frame_auto_6
+ frame_auto_7
+ frame_auto_4
+ frame_auto_3
+ frame_auto_2
+ drolabel_y
+ drolabel_z
+ drolabel_x
+ frame
+ gcodeeditor
+ state_enable_gridLayout
+ label_13
+ label_14
+ label_15
+ label_16
+ line
+ state_label
+ state_label_2
+ state_label_3
+ state_label_5
+ state_label_6
+ tooldialog
+ filedialog
+ led_home_x
+ led_home_y
+ led_home_z
+ actionbutton_9
+ actionbutton_10
+ actionbutton_11
+ ScreenOptions
+ StatusLabel_2
+ macrotabdialog
+ originoffsetdialog
+ StatusStacked
+ StatusSlider
+ StatusSlider_2
+ StatusSlider_6
+ StatusSlider_5
+ mcodes_label
+ actionbutton_15
+ actionbutton_16
+ actionbutton_17
+ actionbutton_18
+ frame_auto_8
+ gcodes_label
+ state_label_10
+ focusoverlay
+ horizontalLayoutWidget
+
+
+
+ true
+
+
+
+
+
+ GCodeGraphics
+ QWidget
+ qtvcp.widgets.gcode_graphics
+ 1
+
+
+ CamViewDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ LcncDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StatusSlider
+ QSlider
+ qtvcp.widgets.status_slider
+
+
+ MDILine
+ QLineEdit
+ qtvcp.widgets.mdi_line
+ 1
+
+
+ XEmbed
+ QWidget
+ qtvcp.widgets.xembed
+ 1
+
+
+ StateLabel
+ QLabel
+ qtvcp.widgets.state_label
+
+
+ LED
+ QWidget
+ qtvcp.widgets.led_widget
+
+
+ MacroTabDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StateLED
+ LED
+ qtvcp.widgets.state_led
+
+
+ OriginOffsetDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StateEnableGridLayout
+ QWidget
+ qtvcp.widgets.container_widgets
+ 1
+
+
+ StatusStacked
+ QStackedWidget
+ qtvcp.widgets.status_stacked
+ 1
+
+
+ ToolOffsetDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ JogIncrements
+ QComboBox
+ qtvcp.widgets.jog_increments
+
+
+ FileDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ FocusOverlay
+ QWidget
+ qtvcp.widgets.overlay_widget
+ 1
+
+
+ ScreenOptions
+ QWidget
+ qtvcp.widgets.screen_options
+ 1
+
+
+ StatusLabel
+ QLabel
+ qtvcp.widgets.status_label
+
+
+ DROLabel
+ QLabel
+ qtvcp.widgets.dro_widget
+ 1
+
+
+ GcodeEditor
+ QFrame
+ qtvcp.widgets.gcode_editor
+ 1
+
+
+ ActionButton
+ QPushButton
+ qtvcp.widgets.action_button
+
+
+ ToolDialog
+ LcncDialog
+ qtvcp.widgets.dialog_widget
+
+
+
+
+
+ halbuttonclicked()
+ estop_toggled()
+ machineon_toggled()
+ home_clicked()
+ jog_pressed()
+ jog_released()
+ change_jograte()
+ loadfile_clicked()
+ runfile_clicked()
+ launch_status()
+ zero_axis()
+ launch_halmeter()
+ stopfile_clicked()
+ change_feedrate()
+ change_rapidrate()
+ pausefile_clicked()
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc_handler.py b/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc_handler.py
new file mode 100644
index 0000000000..f750d7acbc
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/custom_screencode/qtdefault_ngc/qtdefault_ngc_handler.py
@@ -0,0 +1,478 @@
+############################
+# **** IMPORT SECTION **** #
+############################
+
+from PyQt5 import QtCore
+from PyQt5 import QtWidgets
+from qtvcp.widgets.origin_offsetview import OriginOffsetView as OFFVIEW_WIDGET
+from qtvcp.widgets.tool_offsetview import ToolOffsetView as TOOLVIEW_WIDGET
+from qtvcp.widgets.dialog_widget import CamViewDialog as CAMVIEW
+from qtvcp.widgets.dialog_widget import MacroTabDialog as LATHEMACRO
+from qtvcp.widgets.mdi_line import MDILine as MDI_WIDGET
+from qtvcp.widgets.gcode_editor import GcodeEditor as GCODE
+from qtvcp.lib.keybindings import Keylookup
+from qtvcp.lib.notify import Notify
+
+from qtvcp.core import Status, Action
+
+# Set up logging
+from qtvcp import logger
+
+import linuxcnc
+import sys
+import os
+
+###########################################
+# **** instantiate libraries section **** #
+###########################################
+
+KEYBIND = Keylookup()
+STATUS = Status()
+ACTION = Action()
+LOG = logger.getLogger(__name__)
+# Set the log level for this module
+#LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
+
+###################################
+# **** HANDLER CLASS SECTION **** #
+###################################
+
+class HandlerClass:
+
+ ########################
+ # **** INITIALIZE **** #
+ ########################
+ # widgets allows access to widgets from the qtvcp files
+ # at this point the widgets and hal pins are not instantiated
+ def __init__(self, halcomp,widgets,paths):
+ self.hal = halcomp
+ self.w = widgets
+ self.stat = linuxcnc.stat()
+ self.cmnd = linuxcnc.command()
+ self.error = linuxcnc.error_channel()
+ self.PATH = paths.CONFIGPATH
+ self.IMAGE_PATH = paths.IMAGEDIR
+ self.STYLE = Styles(widgets, paths)
+ ##########################################
+ # Special Functions called from QTVCP
+ ##########################################
+
+ # at this point:
+ # the widgets are instantiated.
+ # the HAL pins are built but HAL is not set ready
+ def initialized__(self):
+ if self.w.PREFS_:
+ print 'Using preference file:',self.w.PREFS_.fn
+ STATUS.emit('play-sound','SPEAK This is a test screen for Qt V C P')
+ # set custom theme
+ self.STYLE.dark_style()
+ KEYBIND.add_call('Key_F3','on_keycall_F3')
+ KEYBIND.add_call('Key_F4','on_keycall_F4')
+ KEYBIND.add_call('Key_F5','on_keycall_F5')
+ KEYBIND.add_call('Key_F6','on_keycall_F6')
+
+ def processed_key_event__(self,receiver,event,is_pressed,key,code,shift,cntrl):
+ # when typing in MDI, we don't want keybinding to call functions
+ # so we catch and process the events directly.
+ # We do want ESC, F1 and F2 to call keybinding functions though
+ if code not in(QtCore.Qt.Key_Escape,QtCore.Qt.Key_F1 ,QtCore.Qt.Key_F2,
+ QtCore.Qt.Key_F3,QtCore.Qt.Key_F5,QtCore.Qt.Key_F5):
+ if isinstance(receiver, OFFVIEW_WIDGET) or \
+ isinstance(receiver, MDI_WIDGET) or isinstance(receiver, TOOLVIEW_WIDGET):
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ elif isinstance(receiver, GCODE) and STATUS.is_man_mode() == False:
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ elif isinstance(receiver,QtWidgets.QDialog):
+ print 'dialog'
+ return True
+ if event.isAutoRepeat():return True
+
+ try:
+ KEYBIND.call(self,event,is_pressed,shift,cntrl)
+ return True
+ except Exception as e:
+ LOG.info('Exception loading Macros:', exc_info=e)
+ print 'Error in, or no function for: %s in handler file for-%s'%(KEYBIND.convert(event),key)
+ print 'from %s'% receiver
+ return False
+
+ ########################
+ # callbacks from STATUS #
+ ########################
+
+ #######################
+ # callbacks from form #
+ #######################
+
+ #####################
+ # general functions #
+ #####################
+
+ #####################
+ # KEY BINDING CALLS #
+ #####################
+ def on_keycall_ABORT(self,event,state,shift,cntrl):
+ if state:
+ print 'abort'
+ if STATUS.stat.interp_state == linuxcnc.INTERP_IDLE:
+ self.w.close()
+ else:
+ print 'abort'
+ self.cmnd.abort()
+ self.w.button_home.click()
+
+ def on_keycall_ESTOP(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_ESTOP_STATE(STATUS.estop_is_clear())
+ def on_keycall_POWER(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_MACHINE_STATE(not STATUS.machine_is_on())
+ def on_keycall_HOME(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.is_all_homed():
+ ACTION.SET_MACHINE_UNHOMED(-1)
+ else:
+ ACTION.SET_MACHINE_HOMING(-1)
+
+ def on_keycall_F3(self,event,state,shift,cntrl):
+ if state:
+ self.w.originoffsetdialog.load_dialog()
+ def on_keycall_F4(self,event,state,shift,cntrl):
+ if state:
+ self.w.camviewdialog.load_dialog()
+ def on_keycall_F5(self,event,state,shift,cntrl):
+ if state:
+ self.w.macrotabdialog.load_dialog()
+ def on_keycall_F6(self,event,state,shift,cntrl):
+ if state:
+ self.w.tooloffsetdialog.load_dialog()
+
+ def on_keycall_XPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(0, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(0, 0, STATUS.current_jog_distance)
+ def on_keycall_XNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(0, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(0, 0, STATUS.current_jog_distance)
+
+ def on_keycall_YPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(1, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(1, 0, STATUS.current_jog_distance)
+
+ def on_keycall_YNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(1, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(1, 0, STATUS.current_jog_distance)
+
+ def on_keycall_ZPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(2, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(2, 0, STATUS.current_jog_distance)
+
+ def on_keycall_ZNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(2, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(2, 0, STATUS.current_jog_distance)
+
+ ###########################
+ # **** closing event **** #
+ ###########################
+ def closing_cleanup__(self):
+ print'CLOSING'
+
+ ##############################
+ # required class boiler code #
+ ##############################
+
+ def __getitem__(self, item):
+ return getattr(self, item)
+ def __setitem__(self, item, value):
+ return setattr(self, item, value)
+
+################################
+# required handler boiler code #
+################################
+
+def get_handlers(halcomp,widgets,paths):
+ return [HandlerClass(halcomp,widgets,paths)]
+
+#####################################################################
+# Styles - put them here to keep things tidy
+#####################################################################
+class Styles:
+ def __init__(self, widgets, paths):
+ self.w = widgets
+ self.PATH = paths.CONFIGPATH
+ self.IMAGE_PATH = paths.IMAGEDIR
+
+ def bright_style(self):
+ self.w.setStyleSheet('''#MainWindow {background: black; }
+QLineEdit {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QPushButton {
+color: #333;
+border: 2px solid #555;
+border-radius: 11px;
+padding: 5px;
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+min-width: 40px;
+}
+
+ QPushButton:hover {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #bbb);
+}
+
+QPushButton:pressed {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+QPushButton:checked {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+
+QSlider::groove:horizontal {
+border: 1px solid #bbb;
+background: white;
+height: 5px;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #66e, stop: 1 #bbf);
+background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
+ stop: 0 #bbf, stop: 1 #55f);
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::add-page:horizontal {
+background: #fff;
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #eee, stop:1 #ccc);
+border: 1px solid #777;
+width: 20px;
+margin-top: -7px;
+margin-bottom: -75px;
+border-radius: 4px;
+
+}
+
+QSlider::handle:horizontal:hover {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #fff, stop:1 #ddd);
+border: 1px solid #444;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal:disabled {
+background: #bbb;
+border-color: #999;
+}
+
+QSlider::add-page:horizontal:disabled {
+background: #eee;
+border-color: #999;
+}
+
+QSlider::handle:horizontal:disabled {
+background: #eee;
+border: 1px solid #aaa;
+border-radius: 4px;
+min-height: 30px;
+}
+#frame_man { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ }
+
+''')
+
+ style ='''#frame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ } '''
+ self.w.frame.setStyleSheet(style)
+
+ style ='''QFrame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ } '''
+ self.w.frame_mdi.setStyleSheet(style)
+ self.w.frame_auto.setStyleSheet(style)
+ self.w.frame_auto_2.setStyleSheet(style)
+ self.w.frame_auto_3.setStyleSheet(style)
+ self.w.frame_auto_4.setStyleSheet(style)
+ self.w.frame_auto_5.setStyleSheet(style)
+ self.w.frame_auto_6.setStyleSheet(style)
+ self.w.frame_auto_7.setStyleSheet(style)
+ self.w.frame_auto_8.setStyleSheet(style)
+ self.w.frame_auto_9.setStyleSheet(style)
+ self.w.frame_auto_10.setStyleSheet(style)
+
+
+ def dark_style(self):
+ bgpath = self.IMAGE_PATH+'/hazzy_bg_black.png'
+ self.w.setStyleSheet('''#MainWindow {background: black; }
+QStatusBar {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QLineEdit {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QPushButton {
+color: #333;
+border: 2px solid #555;
+border-radius: 11px;
+padding: 5px;
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+min-width: 40px;
+}
+
+ QPushButton:hover {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #bbb);
+}
+
+QPushButton:pressed {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+QPushButton:checked {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+
+QSlider::groove:horizontal {
+border: 1px solid #bbb;
+background: white;
+height: 5px;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #66e, stop: 1 #bbf);
+background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
+ stop: 0 #bbf, stop: 1 #55f);
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::add-page:horizontal {
+background: #fff;
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #eee, stop:1 #ccc);
+border: 1px solid #777;
+width: 20px;
+margin-top: -7px;
+margin-bottom: -75px;
+border-radius: 4px;
+
+}
+
+QSlider::handle:horizontal:hover {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #fff, stop:1 #ddd);
+border: 1px solid #444;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal:disabled {
+background: #bbb;
+border-color: #999;
+}
+
+QSlider::add-page:horizontal:disabled {
+background: #eee;
+border-color: #999;
+}
+
+QSlider::handle:horizontal:disabled {
+background: #eee;
+border: 1px solid #aaa;
+border-radius: 4px;
+min-height: 30px;
+}
+#frame_man { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #38395a, stop: 1 #141529);
+ }
+
+''')
+ bgpath = self.IMAGE_PATH+'/frame_bg_blue.png'
+ self.w.frame.setStyleSheet("#frame { border-image: url(%s) 0 0 0 0 stretch stretch; }"%bgpath)
+ #bgpath = self.IMAGE_PATH+'/Grey.jpg'
+
+ style ='''QFrame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #38395a, stop: 1 #141529);
+ } '''
+ self.w.frame_mdi.setStyleSheet(style)
+ self.w.frame_auto.setStyleSheet(style)
+ self.w.frame_auto_2.setStyleSheet(style)
+ self.w.frame_auto_3.setStyleSheet(style)
+ self.w.frame_auto_4.setStyleSheet(style)
+ self.w.frame_auto_5.setStyleSheet(style)
+ self.w.frame_auto_6.setStyleSheet(style)
+ self.w.frame_auto_7.setStyleSheet(style)
+ self.w.frame_auto_8.setStyleSheet(style)
+ self.w.frame_auto_9.setStyleSheet(style)
+ self.w.frame_auto_10.setStyleSheet(style)
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.glade b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.glade
new file mode 100644
index 0000000000..62bd5d2c38
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.glade
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ False
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+ True
+ False
+
+
+ Reload
+ False
+ vcp_action_reload2
+ True
+ True
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ False
+ P
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini
new file mode 100644
index 0000000000..435d1e213e
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/gremlin.ini
@@ -0,0 +1,326 @@
+# This config file was created 2017-02-05 00:32:40.919119 by the update_ini script
+# The original config files may be found in the /home/chris/linuxcnc-mk/configs/sim/qtscreen/qtdefault.old directory
+
+# EMC controller parameters for a simulated machine.
+
+# General note: Comments can either be preceded with a # or ; - either is
+# acceptable, although # is in keeping with most linux config files.
+
+# General section -------------------------------------------------------------
+[EMC]
+
+
+# Version of this INI file
+VERSION = 1.1
+
+# Name of machine, for use with display, etc.
+MACHINE = LinuxCNC-HAL-SIM-AXIS
+
+# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
+#define EMC_DEBUG_CONFIG 0x00000002
+#define EMC_DEBUG_VERSIONS 0x00000008
+#define EMC_DEBUG_TASK_ISSUE 0x00000010
+#define EMC_DEBUG_NML 0x00000040
+#define EMC_DEBUG_MOTION_TIME 0x00000080
+#define EMC_DEBUG_INTERP 0x00000100
+#define EMC_DEBUG_RCS 0x00000200
+#define EMC_DEBUG_INTERP_LIST 0x00000800
+#define EMC_DEBUG_IOCONTROL 0x00001000
+#define EMC_DEBUG_OWORD 0x00002000
+#define EMC_DEBUG_REMAP 0x00004000
+#define EMC_DEBUG_PYTHON 0x00008000
+#define EMC_DEBUG_NAMEDPARAM 0x00010000
+#define EMC_DEBUG_GDBONSIGNAL 0x00020000
+#define EMC_DEBUG_PYTHON_TASK 0x00040000
+#define EMC_DEBUG_ALL 0x7FFFFFFF /* it's an int for %i to work
+
+DEBUG = 0x00002000
+#DEBUG = 0
+
+# Sections for display options ------------------------------------------------
+[DISPLAY]
+
+# Name of display program, e.g., xemc
+DISPLAY = qtvcp -d qtaxis
+EMBED_TAB_NAME= GladeVCP demo
+EMBED_TAB_LOCATION = rightTab
+EMBED_TAB_COMMAND= halcmd loadusr gladevcp --xid gremlin.glade
+
+# Cycle time, in seconds, that display will sleep between polls
+CYCLE_TIME = 0.100
+
+# Path to help file
+HELP_FILE = doc/help.txt
+
+# Initial display setting for position, RELATIVE or MACHINE
+POSITION_OFFSET = RELATIVE
+
+# Initial display setting for position, COMMANDED or ACTUAL
+POSITION_FEEDBACK = ACTUAL
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 2.0
+
+DEFAULT_SPINDLE_SPEED = 200
+MIN_SPINDLE_OVERRIDE = 0.5
+MAX_SPINDLE_OVERRIDE = 1.5
+
+MAX_LINEAR_VELOCITY = 1
+DEFAULT_LINEAR_VELOCITY = .25
+
+# Prefix to be used
+PROGRAM_PREFIX = ../../nc_files/
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+EDITOR = gedit
+TOOL_EDITOR = tooledit
+
+INCREMENTS = 0.1 in, 0.01 in, 0.001 in, 0.0001 in, 1 mm, 0.1 mm, 0.01 mm
+
+# set up 3 user popup message dialogs
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a statusbar test
+MESSAGE_DETAILS = STATUS DETAILS
+MESSAGE_TYPE = status
+MESSAGE_PINNAME = statustest
+
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a yes no dialog test
+MESSAGE_DETAILS = Y/N DETAILS
+MESSAGE_TYPE = yesnodialog
+MESSAGE_PINNAME = yndialogtest
+
+MESSAGE_BOLDTEXT = This is the short text
+MESSAGE_TEXT = This is the longer text of the both type test. It can be longer then the status bar text
+MESSAGE_DETAILS = BOTH DETAILS
+MESSAGE_TYPE = okdialog status
+MESSAGE_PINNAME = bothtest
+
+#NGCGUI_OPTIONS = opt1 opt2 ...
+# opt items:
+# nonew -- disallow making new tab page
+# noremove -- disallow removing any tab page
+# noauto -- no autosend (makeFile, then manually send)
+# noiframe -- no internal image, image on separate toplevel
+# nom2 -- no m2 terminator (use %)
+NGCGUI_PREAMBLE = in_std.ngc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = db25.ngc
+NGCGUI_SUBFILE = gosper.ngc
+NGCGUI_SUBFILE = xyz.ngc
+NGCGUI_SUBFILE = ihex.ngc
+NGCGUI_SUBFILE = slot.ngc
+NGCGUI_SUBFILE = arc2.ngc
+NGCGUI_SUBFILE = iquad.ngc
+NGCGUI_SUBFILE = qpocket.ngc
+NGCGUI_SUBFILE = ""
+
+[MDI_COMMAND_LIST]
+MDI_COMMAND = G0 X0Y0Z0
+MDI_COMMAND = G0 X1Y1Z1
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python
+
+# Task controller section -----------------------------------------------------
+
+[RS274NGC]
+
+# File containing interpreter variables
+PARAMETER_FILE = sim.var
+#SUBROUTINE_PATH = ~/linuxcnc/nc_files/macros/lathe
+
+SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+USER_M_PATH = ../../nc_files/ngcgui_lib/mfiles
+# Motion control section ------------------------------------------------------
+
+[EMCMOT]
+
+EMCMOT = motmod
+
+# Timeout for comm to emcmot, in seconds
+COMM_TIMEOUT = 1.0
+
+# Interval between tries to emcmot, in seconds
+COMM_WAIT = 0.010
+
+# BASE_PERIOD is unused in this configuration but specified in core_sim.hal
+BASE_PERIOD = 0
+# Servo task period, in nano-seconds
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+
+[TASK]
+
+# Name of task controller program, e.g., milltask
+TASK = milltask
+
+# Cycle time, in seconds, that task controller will sleep between polls
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+
+[HAL]
+
+# The run script first uses halcmd to execute any HALFILE
+# files, and then to execute any individual HALCMD commands.
+#
+
+# list of hal config files to run through halcmd
+# files are executed in the order in which they appear
+HALFILE = core_sim.hal
+HALFILE = sim_spindle_encoder.hal
+#HALFILE = axis_manualtoolchange.hal
+HALFILE = simulated_home.hal
+HALFILE = check_constraints.hal
+
+# list of halcmd commands to execute
+# commands are executed in the order in which they appear
+#HALCMD = save neta
+
+# Single file that is executed after the GUI has started. Only supported by
+# AXIS at this time (only AXIS creates a HAL component of its own)
+POSTGUI_HALFILE = qtvcp_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+
+[HALUI]
+#No Content
+[TRAJ]
+
+
+AXES = 3
+COORDINATES = X Y Z
+HOME = 0 0 0
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+CYCLE_TIME = 0.010
+DEFAULT_LINEAR_VELOCITY = 5
+POSITION_FILE = position.txt
+MAX_LINEAR_VELOCITY = 5
+
+# Axes sections ---------------------------------------------------------------
+
+# First axis
+[EMCIO]
+
+# Name of IO controller program, e.g., io
+EMCIO = io
+
+# cycle time, in seconds
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = ../../sim.tbl
+TOOL_CHANGE_POSITION = 0 0 0
+TOOL_CHANGE_QUILL_UP = 1
+
+
+[KINS]
+KINEMATICS = trivkins
+#This is a best-guess at the number of joints, it should be checked
+JOINTS = 3
+
+[AXIS_X]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_0]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Second axis
+[AXIS_Y]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_1]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -8.0
+MAX_LIMIT = 0.12
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_2]
+
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -8.0
+
+# Normally the Z max should be 0.000!
+# The only reason it's greater than 0 here is so that the splash screen
+# gcode will run.
+MAX_LIMIT = 0.12
+
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+# section for main IO controller parameters
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp.glade b/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp.glade
new file mode 100644
index 0000000000..79e8b6bbbf
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp.glade
@@ -0,0 +1,6445 @@
+
+
+
+
+
+
+ -90
+ 90
+ 10
+
+
+ 3
+ 0.14999999999999999
+ 10
+
+
+ 2
+ 0.03
+
+
+ 100
+ 10
+
+
+ 20
+ 200
+ 45
+ 10
+
+
+ 100
+ 10
+
+
+ -20
+ 250
+ 15
+ 10
+
+
+ -2000
+ 2000
+ 1
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ -89
+ 89
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 20
+ 0.1
+ 10
+
+
+ 20
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 200
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 20
+ 200
+ 45
+ 10
+
+
+ 100
+ 10
+ 10
+
+
+ -89
+ 89
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ gtk-media-play
+ O<boring>call [${bore.x-f}] [${bore.sf-f}] [${bore.cut-f}] [${bore.feed-f}] [${bore.z-f}] [${bore.rad-f}] [${bore.angle-f}] [${bore.tool-s}]
+
+
+ Set Tool
+ M61 Q${bore.tool-s} G43 H${bore.tool-s}
+
+
+ O<chamfer>call [${chamfer.x-f}] [${chamfer.sf-f}] [0.5] [0] [${chamfer.z-f}] [${chamfer.tool-s}] [0] [${chamfer.size-f}] [${chamfer.fo}] [${chamfer.fi}] [${chamfer.bo}]
+
+
+ M61 Q${chamfer.tool-s} G43 H${chamfer.tool-s}
+
+
+ O<facing>call [${face.x-f}] [${face.sf-f}] [${face.cut-f}] [${face.feed-f}] [${face.z-f}] [${face.angle-s}] [${face.tool-s}]
+
+
+ Set Tool
+ M61 Q${face.tool-s} G43 H${face.tool-s}
+
+
+ O<radius> call [${radius.x-f}] [${radius.sf-f}] [0.5] [0][${radius.z-f}] [${radius.tool-s}] [0] [${radius.rad-f}] [${radius.fo}] [${radius.fi}] [${radius.bo}]
+
+
+ Set Tool
+ M61 Q${radius.tool-s} G43 H${radius.tool-s}
+
+
+ O<threading>call [${thread.x-f}] [${thread.sf-f}] [${thread.tool-s}] [${thread.pitch-f}] [${thread.z-f}] [${thread.internal}] [${thread.external}]
+
+
+ M61 Q${thread.tool-s} G43 H${thread.tool-s}
+
+
+ O<turning> call [${turn.x-f}] [${turn.sf-f}] [${turn.cut-f}] [${turn.feed-f}] [${turn.z-f}] [${turn.rad-f}] [${turn.angle-f}] [${turn.tool-s}]
+
+
+ Set Tool
+ M61 Q${turn.tool-s} G43 H${turn.tool-s}
+
+
+ False
+ 5
+ dialog
+
+
+ True
+ False
+ 2
+
+
+ True
+ False
+ end
+
+
+ OK
+ 100
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ Cancel
+ 100
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ True
+ end
+ 0
+
+
+
+
+ 60
+ True
+ True
+ ●
+ False
+ False
+ True
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ False
+ 5
+ 4
+
+
+ 1
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+
+
+ 2
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+
+
+
+
+ 3
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+
+
+
+
+ DEL
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+
+
+
+
+ 4
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+
+
+
+
+ 5
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+ 6
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 1
+ 2
+
+
+
+
+ CLR
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 1
+ 2
+
+
+
+
+ 7
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+
+
+
+
+ 8
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+ 9
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 2
+ 3
+
+
+
+
+ PREV
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 2
+ 3
+
+
+
+
+ +/-
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+
+
+
+
+ 0
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ .
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 3
+ 4
+
+
+
+
+ /
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 3
+ 4
+
+
+
+
+ in->mm
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ mm->in
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ pitch->tpi
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ tpi->pitch
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ True
+ True
+ 2
+
+
+
+
+
+ button23
+ button24
+
+
+
+ False
+ GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK
+ 300
+ 180
+
+
+ True
+ False
+
+
+
+ True
+ True
+ GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnXAdj
+ 3
+
+
+
+ 9
+ 10
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 52
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnFeedAdj
+ 3
+
+
+
+ 5
+ 6
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnRadAdj
+ 3
+
+
+
+ 7
+ 8
+ 4
+ 5
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnCutAdj
+ 3
+
+
+
+ 7
+ 8
+ 18
+ 19
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 49
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnZAdj
+ 3
+
+
+
+ 1
+ 2
+ 13
+ 14
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnAngAdj
+ 4
+
+
+
+ 4
+ 5
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnSFAdj
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ turn.toolchange
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ True
+ True
+ 0.89999997615814209
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ True
+ turn.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnToolAdj
+
+
+
+ 11
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+ Turning
+
+
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment5
+ 3
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment4
+ 4
+
+
+
+ 4
+ 5
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment3
+ 3
+
+
+
+ 6
+ 7
+ 9
+ 10
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment8
+ 3
+
+
+
+ 9
+ 10
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment7
+ 3
+
+
+
+ 7
+ 8
+ 19
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 52
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnFeedAdj
+ 3
+
+
+ 5
+ 6
+ 17
+ 18
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment2
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ bore.toolchange
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ _Play
+ 50
+ 20
+ True
+ True
+ True
+ bore.go
+ False
+ True
+
+
+ 10
+ 12
+ 18
+ 20
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment1
+
+
+
+ 11
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+ True
+ False
+ Boring
+
+
+ 1
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ face.go
+ True
+
+
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment9
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment10
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment11
+ 3
+
+
+
+ 1
+ 2
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment13
+ 3
+
+
+
+ 9
+ 10
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment14
+ 4
+
+
+
+ 7
+ 8
+ 17
+ 18
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment15
+ 3
+
+
+
+ 6
+ 7
+ 18
+ 19
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment12
+ 4
+
+
+
+ 7
+ 8
+ 13
+ 14
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ face.toolchange
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+ True
+ False
+ Facing
+
+
+ 2
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ radius.go
+ True
+
+
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment20
+ 3
+
+
+
+ 8
+ 9
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 48
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment24
+ 3
+
+
+
+ 1
+ 2
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment19
+ 3
+
+
+
+ 7
+ 8
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 7
+ 8
+ 14
+ 15
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ radius.fi
+
+
+
+
+ 5
+ 6
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ radius.fi
+
+
+
+
+ 2
+ 3
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment16
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment17
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ radius.toolchange
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+ True
+ False
+ Radius
+
+
+ 3
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ chamfer.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 48
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment24
+ 3
+
+
+
+ 1
+ 2
+ 7
+ 8
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment23
+ 4
+
+
+
+ 7
+ 8
+ 9
+ 10
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment25
+ 3
+
+
+
+ 9
+ 10
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 2
+ 3
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ chamfer.bo
+
+
+
+
+ 6
+ 7
+ 17
+ 18
+
+
+
+
+ True
+ False
+
+
+ 50
+ 16
+ True
+ True
+ False
+ False
+ 1
+ True
+ True
+ chamfer.bo
+
+
+
+
+ 7
+ 8
+ 14
+ 15
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment21
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment22
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 12
+ True
+ True
+ True
+ chamfer.toolchange
+ False
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+ True
+ False
+ Chamfer
+
+
+ 4
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ thread.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment30
+ 3
+
+
+
+ 1
+ 2
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment28
+ 3
+
+
+
+ 8
+ 9
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment29
+ 4
+
+
+
+ 3
+ 4
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment32
+
+
+
+
+
+ 11
+ 12
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+
+
+
+
+ True
+ False
+
+
+ external
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 5
+ 6
+ 14
+ 15
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment31
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ thread.toolchange
+ False
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ internal
+ True
+ True
+ False
+ False
+ True
+ True
+ thread.external
+
+
+
+
+ 7
+ 8
+ 9
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+ True
+ False
+ Threads
+
+
+ 5
+ False
+
+
+
+
+
+
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp_handler.py b/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp_handler.py
new file mode 100644
index 0000000000..9dfa9a1dfd
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/gvcp_handler.py
@@ -0,0 +1,32 @@
+import gtk
+
+class HandlerClass:
+
+ def __init__(self, halcomp,builder,useropts):
+ self.halcomp = halcomp
+ self.builder = builder
+ #print 'GLADEVCP HANDLER INIT'
+
+ # This catches the signal from Touchy to say that the tab is exposed
+ t = self.builder.get_object('eventbox1')
+ t.connect('map-event',self.on_map_event)
+ t.add_events(gtk.gdk.STRUCTURE_MASK)
+
+ # This catches our messages from another program
+ def event(self,w,event):
+ print event.message_type,event.data
+ if event.message_type == 'Gladevcp':
+ if event.data[:7] == 'Visible':
+ print 'VISIBLE'
+ else:
+ print 'HIDDEN'
+
+ # We connect to client-events from the new toplevel widget
+ def on_map_event(self, widget, data=None):
+ top = widget.get_toplevel()
+ print "map event"
+ top.connect('client-event', self.event)
+
+def get_handlers(halcomp,builder,useropts):
+ return [HandlerClass(halcomp,builder,useropts)]
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/lathehandler.py b/configs/sim/qtvcp_screens/qtvcp_experimental/lathehandler.py
new file mode 100644
index 0000000000..bd91251b6f
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/lathehandler.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+# vim: sts=4 sw=4 et
+# This is a component of EMC
+# savestate.py copyright 2013 Andy Pugh
+# based on code from
+# probe.py Copyright 2010 Michael Haberler
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA''''''
+
+import os,sys
+from gladevcp.persistence import IniFile,widget_defaults,set_debug,select_widgets
+import hal
+import hal_glib
+import gtk
+import glib
+import linuxcnc
+import rsvg
+import cairo
+import signal
+import pango
+
+debug = 0
+
+class HandlerClass:
+ active = False
+ tab_num = 0
+
+ def on_expose(self,nb,data=None):
+ tab_num = nb.get_current_page()
+ tab = nb.get_nth_page(tab_num)
+ cr = tab.window.cairo_create()
+ cr.set_operator(cairo.OPERATOR_OVER)
+ x, y, w, h = tab.allocation
+ sx, sy, sw, sh = self.svg.get_dimension_data()
+ cr.translate(0, y)
+ cr.scale(1.0 *w / sw, 1.0*h/sh)
+ self.svg.render_cairo(cr = cr, id = '#layer%i' % tab_num)
+
+ # This catches our messages from another program
+ def event(self,w,event):
+ print event.message_type,event.data
+ if event.message_type == 'Gladevcp':
+ if event.data[:7] == 'Visible':
+ self.active = True
+ self.visible.set(True)
+ else:
+ self.active = False
+ self.visible.set(False)
+
+ # We connect to client-events from the new toplevel widget
+ def on_map_event(self, widget, data=None):
+ top = widget.get_toplevel()
+ print "map event"
+ top.connect('client-event', self.event)
+
+ def on_destroy(self,obj,data=None):
+ self.ini.save_state(self)
+
+ def on_restore_defaults(self,button,data=None):
+ '''
+ example callback for 'Reset to defaults' button
+ currently unused
+ '''
+ self.ini.create_default_ini()
+ self.ini.restore_state(self)
+
+ def __init__(self, halcomp,builder,useropts):
+ self.halcomp = halcomp
+ self.builder = builder
+ self.ini_filename = 'savestate.sav'
+ self.defaults = { IniFile.vars: dict(),
+ IniFile.widgets : widget_defaults(select_widgets(self.builder.get_objects(), hal_only=False,output_only = True))
+ }
+ self.ini = IniFile(self.ini_filename,self.defaults,self.builder)
+ self.ini.restore_state(self)
+
+ # A pin to use a physical switch to start the cycle
+ self.cycle_start = hal_glib.GPin(halcomp.newpin('cycle-start', hal.HAL_BIT, hal.HAL_IN))
+ self.cycle_start.connect('value-changed', self.cycle_pin)
+
+ # A pin to mask cycle-start so that Touchy doesn't run auto.
+ self.visible = hal_glib.GPin(halcomp.newpin('visible', hal.HAL_BIT, hal.HAL_OUT))
+
+ # This catches the signal from Touchy to say that the tab is exposed
+ t = self.builder.get_object('eventbox1')
+ t.connect('map-event',self.on_map_event)
+ t.add_events(gtk.gdk.STRUCTURE_MASK)
+ self.cmd = linuxcnc.command()
+
+ # This conects the expose event to re-draw and scale the SVG frames
+ t = self.builder.get_object('tabs1')
+ t.connect_after("expose_event", self.on_expose)
+ t.connect("destroy", gtk.main_quit)
+ t.add_events(gtk.gdk.STRUCTURE_MASK)
+ self.svg = rsvg.Handle(file='LatheMacro.svg', )
+
+ def show_keyb(self, obj, data=None):
+ self.active_ctrl = obj
+ self.keyb = self.builder.get_object('keyboard')
+ self.entry = self.builder.get_object('entry1')
+ self.entry.modify_font(pango.FontDescription("courier 42"))
+ self.entry.set_text("")
+ resp = self.keyb.run()
+
+ def keyb_prev_click(self, obj, data=None):
+ self.entry.set_text(self.active_ctrl.get_text())
+
+ def keyb_number_click(self, obj, data=None):
+ data = self.entry.get_text()
+ data = data + obj.get_label()
+ if data[-2:] in [ '/2', '/4', '/8']:
+ v = data[:-2].split('.')
+ if len(v) == 2:
+ data = '%6.3f'%(float(v[0]) + float(v[1]) / float(data[-1:]))
+ elif len(v) == 1:
+ data = '%6.3f'%(float(v[0]) / float(data[-1:]))
+ elif data[-3:] in [ '/16', '/32', '/64']:
+ v = data[:-3].split('.')
+ if len(v) == 2:
+ data = '%6.3f'%(float(v[0]) + float(v[1]) / float(data[-2:]))
+ elif len(v) == 1:
+ data = '%6.3f'%(float(v[0]) / float(data[-2:]))
+ self.entry.set_text(data)
+
+ def keyb_pm_click(self, obj, data=None):
+ data = self.entry.get_text()
+ if data[0] == '-':
+ data = data[1:]
+ else:
+ data = '-' + data
+ self.entry.set_text(data)
+
+ def keyb_convert_click(self, obj, data=None):
+ v = float(self.entry.get_text())
+ op = obj.get_label()
+ if op == 'in->mm':
+ v = v * 25.4
+ elif op == 'mm->in':
+ v = v / 25.4
+ elif op == 'tpi->pitch':
+ v = 25.4 / v
+ elif op == 'pitch->tpi':
+ v = 25.4 / v
+ self.entry.set_text('%6.4f'%v)
+
+ def keyb_del_click(self, obj, data=None):
+ data = self.entry.get_text()
+ data = data[:-1]
+ self.entry.set_text(data)
+
+ def keyb_clear_click(self, obj, data=None):
+ self.entry.set_text('')
+
+ def keyb_cancel_click(self, obj, data=None):
+ self.keyb.hide()
+
+ def keyb_ok_click(self, obj, data=None):
+ if self.entry.get_text() != '':
+ self.active_ctrl.set_value(float(self.entry.get_text()))
+ self.keyb.hide()
+
+ def set_alpha(self, obj, data = None):
+ cr = obj.window.cairo_create()
+ cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)
+
+ def cycle_pin(self, pin, data = None):
+ if pin.get() == 0:
+ return
+ print 'cycle pin'
+ if self.active:
+ nb = self.builder.get_object('tabs1')
+ print 'current tab', nb.get_current_page()
+ tab = nb.get_nth_page(nb.get_current_page())
+ for c in tab.get_children():
+ if c.name.partition('.')[2] == 'action':
+ self.cmd.abort()
+ self.cmd.mode(linuxcnc.MODE_MANUAL)
+ self.cmd.wait_complete()
+ c.emit('clicked')
+
+ def gash(self, obj, data = None):
+ print 'event', data
+
+def get_handlers(halcomp,builder,useropts):
+
+ global debug
+ for cmd in useropts:
+ exec cmd in globals()
+
+ set_debug(debug)
+ return [HandlerClass(halcomp,builder,useropts)]
+
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/lathemacro.ui b/configs/sim/qtvcp_screens/qtvcp_experimental/lathemacro.ui
new file mode 100644
index 0000000000..79e8b6bbbf
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/lathemacro.ui
@@ -0,0 +1,6445 @@
+
+
+
+
+
+
+ -90
+ 90
+ 10
+
+
+ 3
+ 0.14999999999999999
+ 10
+
+
+ 2
+ 0.03
+
+
+ 100
+ 10
+
+
+ 20
+ 200
+ 45
+ 10
+
+
+ 100
+ 10
+
+
+ -20
+ 250
+ 15
+ 10
+
+
+ -2000
+ 2000
+ 1
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ -89
+ 89
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 20
+ 0.1
+ 10
+
+
+ 20
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 200
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 250
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 20
+ 200
+ 45
+ 10
+
+
+ 100
+ 10
+ 10
+
+
+ -89
+ 89
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ 100
+ 10
+
+
+ -1000
+ 1000
+ 10
+
+
+ 100
+ 10
+
+
+ gtk-media-play
+ O<boring>call [${bore.x-f}] [${bore.sf-f}] [${bore.cut-f}] [${bore.feed-f}] [${bore.z-f}] [${bore.rad-f}] [${bore.angle-f}] [${bore.tool-s}]
+
+
+ Set Tool
+ M61 Q${bore.tool-s} G43 H${bore.tool-s}
+
+
+ O<chamfer>call [${chamfer.x-f}] [${chamfer.sf-f}] [0.5] [0] [${chamfer.z-f}] [${chamfer.tool-s}] [0] [${chamfer.size-f}] [${chamfer.fo}] [${chamfer.fi}] [${chamfer.bo}]
+
+
+ M61 Q${chamfer.tool-s} G43 H${chamfer.tool-s}
+
+
+ O<facing>call [${face.x-f}] [${face.sf-f}] [${face.cut-f}] [${face.feed-f}] [${face.z-f}] [${face.angle-s}] [${face.tool-s}]
+
+
+ Set Tool
+ M61 Q${face.tool-s} G43 H${face.tool-s}
+
+
+ O<radius> call [${radius.x-f}] [${radius.sf-f}] [0.5] [0][${radius.z-f}] [${radius.tool-s}] [0] [${radius.rad-f}] [${radius.fo}] [${radius.fi}] [${radius.bo}]
+
+
+ Set Tool
+ M61 Q${radius.tool-s} G43 H${radius.tool-s}
+
+
+ O<threading>call [${thread.x-f}] [${thread.sf-f}] [${thread.tool-s}] [${thread.pitch-f}] [${thread.z-f}] [${thread.internal}] [${thread.external}]
+
+
+ M61 Q${thread.tool-s} G43 H${thread.tool-s}
+
+
+ O<turning> call [${turn.x-f}] [${turn.sf-f}] [${turn.cut-f}] [${turn.feed-f}] [${turn.z-f}] [${turn.rad-f}] [${turn.angle-f}] [${turn.tool-s}]
+
+
+ Set Tool
+ M61 Q${turn.tool-s} G43 H${turn.tool-s}
+
+
+ False
+ 5
+ dialog
+
+
+ True
+ False
+ 2
+
+
+ True
+ False
+ end
+
+
+ OK
+ 100
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ Cancel
+ 100
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ True
+ end
+ 0
+
+
+
+
+ 60
+ True
+ True
+ ●
+ False
+ False
+ True
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ False
+ 5
+ 4
+
+
+ 1
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+
+
+ 2
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+
+
+
+
+ 3
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+
+
+
+
+ DEL
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+
+
+
+
+ 4
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+
+
+
+
+ 5
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 1
+ 2
+
+
+
+
+ 6
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 1
+ 2
+
+
+
+
+ CLR
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 1
+ 2
+
+
+
+
+ 7
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+
+
+
+
+ 8
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 2
+ 3
+
+
+
+
+ 9
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 2
+ 3
+
+
+
+
+ PREV
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 2
+ 3
+
+
+
+
+ +/-
+ 50
+ 50
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+
+
+
+
+ 0
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+ .
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 3
+ 4
+
+
+
+
+ /
+ 50
+ 20
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 3
+ 4
+
+
+
+
+ in->mm
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ mm->in
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 1
+ 2
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ pitch->tpi
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 2
+ 3
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ tpi->pitch
+ 80
+ 40
+ True
+ True
+ True
+ False
+
+
+
+ 3
+ 4
+ 4
+ 5
+ 4
+ 4
+
+
+
+
+ True
+ True
+ 2
+
+
+
+
+
+ button23
+ button24
+
+
+
+ False
+ GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK
+ 300
+ 180
+
+
+ True
+ False
+
+
+
+ True
+ True
+ GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnXAdj
+ 3
+
+
+
+ 9
+ 10
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 52
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnFeedAdj
+ 3
+
+
+
+ 5
+ 6
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnRadAdj
+ 3
+
+
+
+ 7
+ 8
+ 4
+ 5
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnCutAdj
+ 3
+
+
+
+ 7
+ 8
+ 18
+ 19
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 49
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnZAdj
+ 3
+
+
+
+ 1
+ 2
+ 13
+ 14
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnAngAdj
+ 4
+
+
+
+ 4
+ 5
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnSFAdj
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ turn.toolchange
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ True
+ True
+ 0.89999997615814209
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ True
+ turn.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnToolAdj
+
+
+
+ 11
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+ Turning
+
+
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment5
+ 3
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment4
+ 4
+
+
+
+ 4
+ 5
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment3
+ 3
+
+
+
+ 6
+ 7
+ 9
+ 10
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment8
+ 3
+
+
+
+ 9
+ 10
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment7
+ 3
+
+
+
+ 7
+ 8
+ 19
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 52
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ TurnFeedAdj
+ 3
+
+
+ 5
+ 6
+ 17
+ 18
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment2
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ bore.toolchange
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ _Play
+ 50
+ 20
+ True
+ True
+ True
+ bore.go
+ False
+ True
+
+
+ 10
+ 12
+ 18
+ 20
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment1
+
+
+
+ 11
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+ True
+ False
+ Boring
+
+
+ 1
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ face.go
+ True
+
+
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment9
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment10
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment11
+ 3
+
+
+
+ 1
+ 2
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment13
+ 3
+
+
+
+ 9
+ 10
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment14
+ 4
+
+
+
+ 7
+ 8
+ 17
+ 18
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment15
+ 3
+
+
+
+ 6
+ 7
+ 18
+ 19
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment12
+ 4
+
+
+
+ 7
+ 8
+ 13
+ 14
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ face.toolchange
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+ True
+ False
+ Facing
+
+
+ 2
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ radius.go
+ True
+
+
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment20
+ 3
+
+
+
+ 8
+ 9
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 48
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment24
+ 3
+
+
+
+ 1
+ 2
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment19
+ 3
+
+
+
+ 7
+ 8
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 7
+ 8
+ 14
+ 15
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ radius.fi
+
+
+
+
+ 5
+ 6
+ 16
+ 17
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ radius.fi
+
+
+
+
+ 2
+ 3
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment16
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment17
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ radius.toolchange
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+ True
+ False
+ Radius
+
+
+ 3
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ chamfer.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 48
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment24
+ 3
+
+
+
+ 1
+ 2
+ 7
+ 8
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment23
+ 4
+
+
+
+ 7
+ 8
+ 9
+ 10
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment25
+ 3
+
+
+
+ 9
+ 10
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 2
+ 3
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ False
+ False
+ True
+ True
+ chamfer.bo
+
+
+
+
+ 6
+ 7
+ 17
+ 18
+
+
+
+
+ True
+ False
+
+
+ 50
+ 16
+ True
+ True
+ False
+ False
+ 1
+ True
+ True
+ chamfer.bo
+
+
+
+
+ 7
+ 8
+ 14
+ 15
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment21
+
+
+
+ 11
+ 12
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment22
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 12
+ True
+ True
+ True
+ chamfer.toolchange
+ False
+ True
+
+
+
+
+ 10
+ 11
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+ True
+ False
+ Chamfer
+
+
+ 4
+ False
+
+
+
+
+ True
+ False
+ 20
+ 12
+ True
+
+
+ 50
+ 20
+ True
+ True
+ True
+ thread.go
+ False
+ True
+
+
+ True
+ False
+ media-playback-start
+
+
+
+
+ 10
+ 12
+ 18
+ 20
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 51
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment30
+ 3
+
+
+
+ 1
+ 2
+ 8
+ 9
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment28
+ 3
+
+
+
+ 8
+ 9
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment29
+ 4
+
+
+
+ 3
+ 4
+ 15
+ 16
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment32
+
+
+
+
+
+ 11
+ 12
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ 1
+ Speed
+
+
+
+
+ 10
+ 11
+ 1
+ 2
+
+
+
+
+ True
+ False
+
+
+ external
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+
+
+ 5
+ 6
+ 14
+ 15
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ True
+ False
+ False
+ True
+ True
+ adjustment31
+
+
+
+ 11
+ 12
+ 1
+ 2
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+ GTK_EXPAND | GTK_SHRINK | GTK_FILL
+
+
+
+
+ True
+ False
+
+
+ Set Tool
+ 50
+ 20
+ True
+ True
+ True
+ thread.toolchange
+ False
+ True
+
+
+
+
+ 10
+ 11
+
+
+
+
+ True
+ False
+
+
+ internal
+ True
+ True
+ False
+ False
+ True
+ True
+ thread.external
+
+
+
+
+ 7
+ 8
+ 9
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+ True
+ False
+ Threads
+
+
+ 5
+ False
+
+
+
+
+
+
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/pyngcgui.ui b/configs/sim/qtvcp_screens/qtvcp_experimental/pyngcgui.ui
new file mode 100644
index 0000000000..d56fcddd30
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/pyngcgui.ui
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ False
+ False
+ 712
+ 200
+
+
+ True
+ False
+ 0
+ none
+ False
+ False
+ False
+ default_send
+
+
+
+
+
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini
new file mode 100644
index 0000000000..5714960665
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp.ini
@@ -0,0 +1,326 @@
+# This config file was created 2017-02-05 00:32:40.919119 by the update_ini script
+# The original config files may be found in the /home/chris/linuxcnc-mk/configs/sim/qtscreen/qtdefault.old directory
+
+# EMC controller parameters for a simulated machine.
+
+# General note: Comments can either be preceded with a # or ; - either is
+# acceptable, although # is in keeping with most linux config files.
+
+# General section -------------------------------------------------------------
+[EMC]
+
+
+# Version of this INI file
+VERSION = 1.1
+
+# Name of machine, for use with display, etc.
+MACHINE = LinuxCNC-HAL-SIM-AXIS
+
+# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
+#define EMC_DEBUG_CONFIG 0x00000002
+#define EMC_DEBUG_VERSIONS 0x00000008
+#define EMC_DEBUG_TASK_ISSUE 0x00000010
+#define EMC_DEBUG_NML 0x00000040
+#define EMC_DEBUG_MOTION_TIME 0x00000080
+#define EMC_DEBUG_INTERP 0x00000100
+#define EMC_DEBUG_RCS 0x00000200
+#define EMC_DEBUG_INTERP_LIST 0x00000800
+#define EMC_DEBUG_IOCONTROL 0x00001000
+#define EMC_DEBUG_OWORD 0x00002000
+#define EMC_DEBUG_REMAP 0x00004000
+#define EMC_DEBUG_PYTHON 0x00008000
+#define EMC_DEBUG_NAMEDPARAM 0x00010000
+#define EMC_DEBUG_GDBONSIGNAL 0x00020000
+#define EMC_DEBUG_PYTHON_TASK 0x00040000
+#define EMC_DEBUG_ALL 0x7FFFFFFF /* it's an int for %i to work
+
+DEBUG = 0x00002000
+#DEBUG = 0
+
+# Sections for display options ------------------------------------------------
+[DISPLAY]
+
+# Name of display program, e.g., xemc
+DISPLAY = qtvcp -d qtaxis
+EMBED_TAB_NAME= GladeVCP demo
+EMBED_TAB_LOCATION = rightPanel
+EMBED_TAB_COMMAND= halcmd loadusr gladevcp -u lathehandler.py --xid lathemacro.ui
+
+# Cycle time, in seconds, that display will sleep between polls
+CYCLE_TIME = 0.100
+
+# Path to help file
+HELP_FILE = doc/help.txt
+
+# Initial display setting for position, RELATIVE or MACHINE
+POSITION_OFFSET = RELATIVE
+
+# Initial display setting for position, COMMANDED or ACTUAL
+POSITION_FEEDBACK = ACTUAL
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 2.0
+
+DEFAULT_SPINDLE_SPEED = 200
+MIN_SPINDLE_OVERRIDE = 0.5
+MAX_SPINDLE_OVERRIDE = 1.5
+
+MAX_LINEAR_VELOCITY = 1
+DEFAULT_LINEAR_VELOCITY = .25
+
+# Prefix to be used
+PROGRAM_PREFIX = ../../nc_files/
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+EDITOR = gedit
+TOOL_EDITOR = tooledit
+
+INCREMENTS = 0.1 in, 0.01 in, 0.001 in, 0.0001 in, 1 mm, 0.1 mm, 0.01 mm
+
+# set up 3 user popup message dialogs
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a statusbar test
+MESSAGE_DETAILS = STATUS DETAILS
+MESSAGE_TYPE = status
+MESSAGE_PINNAME = statustest
+
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a yes no dialog test
+MESSAGE_DETAILS = Y/N DETAILS
+MESSAGE_TYPE = yesnodialog
+MESSAGE_PINNAME = yndialogtest
+
+MESSAGE_BOLDTEXT = This is the short text
+MESSAGE_TEXT = This is the longer text of the both type test. It can be longer then the status bar text
+MESSAGE_DETAILS = BOTH DETAILS
+MESSAGE_TYPE = okdialog status
+MESSAGE_PINNAME = bothtest
+
+#NGCGUI_OPTIONS = opt1 opt2 ...
+# opt items:
+# nonew -- disallow making new tab page
+# noremove -- disallow removing any tab page
+# noauto -- no autosend (makeFile, then manually send)
+# noiframe -- no internal image, image on separate toplevel
+# nom2 -- no m2 terminator (use %)
+NGCGUI_PREAMBLE = in_std.ngc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = db25.ngc
+NGCGUI_SUBFILE = gosper.ngc
+NGCGUI_SUBFILE = xyz.ngc
+NGCGUI_SUBFILE = ihex.ngc
+NGCGUI_SUBFILE = slot.ngc
+NGCGUI_SUBFILE = arc2.ngc
+NGCGUI_SUBFILE = iquad.ngc
+NGCGUI_SUBFILE = qpocket.ngc
+NGCGUI_SUBFILE = ""
+
+[MDI_COMMAND_LIST]
+MDI_COMMAND = G0 X0Y0Z0
+MDI_COMMAND = G0 X1Y1Z1
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python
+
+# Task controller section -----------------------------------------------------
+
+[RS274NGC]
+
+# File containing interpreter variables
+PARAMETER_FILE = sim.var
+#SUBROUTINE_PATH = ~/linuxcnc/nc_files/macros/lathe
+
+SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+USER_M_PATH = ../../nc_files/ngcgui_lib/mfiles
+# Motion control section ------------------------------------------------------
+
+[EMCMOT]
+
+EMCMOT = motmod
+
+# Timeout for comm to emcmot, in seconds
+COMM_TIMEOUT = 1.0
+
+# Interval between tries to emcmot, in seconds
+COMM_WAIT = 0.010
+
+# BASE_PERIOD is unused in this configuration but specified in core_sim.hal
+BASE_PERIOD = 0
+# Servo task period, in nano-seconds
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+
+[TASK]
+
+# Name of task controller program, e.g., milltask
+TASK = milltask
+
+# Cycle time, in seconds, that task controller will sleep between polls
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+
+[HAL]
+
+# The run script first uses halcmd to execute any HALFILE
+# files, and then to execute any individual HALCMD commands.
+#
+
+# list of hal config files to run through halcmd
+# files are executed in the order in which they appear
+HALFILE = core_sim.hal
+HALFILE = sim_spindle_encoder.hal
+#HALFILE = axis_manualtoolchange.hal
+HALFILE = simulated_home.hal
+HALFILE = check_constraints.hal
+
+# list of halcmd commands to execute
+# commands are executed in the order in which they appear
+#HALCMD = save neta
+
+# Single file that is executed after the GUI has started. Only supported by
+# AXIS at this time (only AXIS creates a HAL component of its own)
+POSTGUI_HALFILE = qtvcp_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+
+[HALUI]
+#No Content
+[TRAJ]
+
+
+AXES = 3
+COORDINATES = X Y Z
+HOME = 0 0 0
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+CYCLE_TIME = 0.010
+DEFAULT_LINEAR_VELOCITY = 5
+POSITION_FILE = position.txt
+MAX_LINEAR_VELOCITY = 5
+
+# Axes sections ---------------------------------------------------------------
+
+# First axis
+[EMCIO]
+
+# Name of IO controller program, e.g., io
+EMCIO = io
+
+# cycle time, in seconds
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = ../../sim.tbl
+TOOL_CHANGE_POSITION = 0 0 0
+TOOL_CHANGE_QUILL_UP = 1
+
+
+[KINS]
+KINEMATICS = trivkins
+#This is a best-guess at the number of joints, it should be checked
+JOINTS = 3
+
+[AXIS_X]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_0]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Second axis
+[AXIS_Y]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_1]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -8.0
+MAX_LIMIT = 0.12
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_2]
+
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -8.0
+
+# Normally the Z max should be 0.000!
+# The only reason it's greater than 0 here is so that the splash screen
+# gcode will run.
+MAX_LIMIT = 0.12
+
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+# section for main IO controller parameters
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp.ui b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp.ui
new file mode 100644
index 0000000000..ece4e0e4b5
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp.ui
@@ -0,0 +1,3094 @@
+
+
+ MainWindow
+
+
+ true
+
+
+
+ 0
+ 0
+ 1587
+ 790
+
+
+
+
+ 1027
+ 790
+
+
+
+
+ 10270
+ 790
+
+
+
+ MainWindow
+
+
+
+
+
+
+
+
+ 450
+ 520
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 75 18pt "Courier 10 Pitch";
+
+
+ 1
+
+
+ 0
+
+
+
+
+
+ 450
+ 550
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 18pt "Courier 10 Pitch";
+
+
+ 0.5217
+
+
+ Qt::PlainText
+
+
+ true
+
+
+ 2
+
+
+ 0
+
+
+
+
+
+ 450
+ 490
+ 131
+ 21
+
+
+
+ color: rgb(0, 255, 255);
+font: 75 18pt "Courier 10 Pitch";
+
+
+ -1.6994
+
+
+ 0
+
+
+
+
+ true
+
+
+
+ 210
+ 10
+ 811
+ 231
+
+
+
+ #frame{
+border-image: url(/home/chris/emc-dev/configs/sim/qtscreen/backgound_blue.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 80
+ 10
+ 291
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ QFrame::NoFrame
+
+
+ Qt::AutoText
+
+
+ 1
+
+
+
+
+
+ 80
+ 70
+ 291
+ 61
+
+
+
+ font: 75 48pt "Noto Sans";
+color: rgb(255, 255, 255);
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 80
+ 130
+ 291
+ 61
+
+
+
+ font: 75 48pt "Noto Sans";
+color: rgb(255, 255, 255);
+
+
+ 2
+
+
+ 1
+
+
+
+
+
+ 10
+ 11
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ X
+
+
+
+
+
+ 10
+ 70
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ Y
+
+
+
+
+
+ 10
+ 130
+ 72
+ 61
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 48pt "Noto Sans";
+
+
+ Z
+
+
+
+
+
+ 280
+ 190
+ 131
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">%3.1f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 370
+ 40
+ 41
+ 22
+
+
+
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">MM</span></p></body></html>
+
+
+
+
+
+
+
+
+ 420
+ 0
+ 400
+ 231
+
+
+
+
+
+
+ 370
+ 10
+ 51
+ 22
+
+
+
+
+
+
+ false
+
+
+ true
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">DIAM</span></p></body></html>
+
+
+
+
+
+
+
+
+ 100
+ 190
+ 91
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">100.000</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p> <span style=" font-weight:600; font-size:18pt; color:#ffff00;">%3.3f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 370
+ 70
+ 51
+ 21
+
+
+
+ 0
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">G100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ffff00;">G%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 200
+ 190
+ 101
+ 31
+
+
+
+ color: rgb(255, 255, 255);
+font: 75 18pt "Noto Sans";
+
+
+ Velocity:
+
+
+ Qt::AutoText
+
+
+
+
+ true
+
+
+
+ 10
+ 191
+ 81
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">IPR:</span></p></body></html>
+
+
+ Qt::AutoText
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">mmPR:</span></p></body></html>
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#fffffd;">IPR:</span></p></body></html>
+
+
+
+
+
+
+ 210
+ 250
+ 811
+ 201
+
+
+
+
+
+ 467
+ 337
+ 700
+ 400
+
+
+
+
+
+
+ 130
+ 30
+ 800
+ 247
+
+
+
+ false
+
+
+
+
+
+
+ 610
+ 490
+ 61
+ 91
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+ 0
+ 60
+ 61
+ 27
+
+
+
+ Zero Z
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+
+
+
+ 0
+ 30
+ 61
+ 27
+
+
+
+ Zero Y
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+
+
+
+ 0
+ 0
+ 61
+ 27
+
+
+
+ Zero X
+
+
+ false
+
+
+ true
+
+
+ 0
+
+
+
+
+
+
+ 20
+ 650
+ 72
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;;">Jog Rate</span></p></body></html>
+
+
+
+
+
+ 150
+ 650
+ 61
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Jog Inc</span></p></body></html>
+
+
+
+
+
+ 700
+ 500
+ 71
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Number</span></p></body></html>
+
+
+
+
+
+ 700
+ 530
+ 72
+ 22
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">Diameter</span></p></body></html>
+
+
+
+
+
+ 360
+ 580
+ 301
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 130
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">RO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">RO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 20
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">FO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">FO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+
+
+
+ 240
+ 685
+ 101
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">SO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">100%</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#d0d0d0;">SO:</span><span style=" font-size:18pt; font-weight:600; color:#ffff00;">%3.f%%</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 760
+ 490
+ 71
+ 41
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">100</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">%d</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 90
+ 640
+ 61
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">100</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%2.f</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 410
+ 610
+ 251
+ 61
+
+
+
+ <html><head/><body><p><span style=" font-size:36pt; color:#ffff00;">100</span><span style=" font-size:36pt; color:#d1d1d1;"> RPM</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p><span style=" font-size:36pt; color:#ffff00;">%d</span><span style=" font-size:36pt; color:#d1d1d1;"> RPM</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 480
+ 760
+ 316
+ 121
+
+
+
+ false
+
+
+
+
+
+ 0
+ 0
+ 1027
+ 847
+
+
+
+ false
+
+
+ true
+
+
+ STD_IMAGE_DIR/lcnc_swoop.png
+
+
+
+
+
+ 340
+ 770
+ 336
+ 104
+
+
+
+ false
+
+
+
+
+
+ 390
+ 240
+ 635
+ 448
+
+
+
+ false
+
+
+
+ 0
+ 0
+ 255
+
+
+
+
+
+
+ 590
+ 490
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 590
+ 520
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+ 1
+
+
+
+
+
+ 590
+ 550
+ 21
+ 21
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ 600
+
+
+ true
+
+
+ true
+
+
+ 2
+
+
+
+
+
+ 360
+ 685
+ 56
+ 31
+
+
+
+ MAN
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 490
+ 685
+ 56
+ 31
+
+
+
+ MDI
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ 610
+ 685
+ 56
+ 31
+
+
+
+ AUTO
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ 240
+ 820
+ 16
+ 16
+
+
+
+
+
+
+ 210
+ 640
+ 131
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%s</span></p></body></html>
+
+
+ true
+
+
+
+
+
+ 390
+ 230
+ 600
+ 400
+
+
+
+ false
+
+
+
+
+
+ 40
+ 40
+ 800
+ 500
+
+
+
+ false
+
+
+
+
+
+ 10
+ 10
+ 191
+ 441
+
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ false
+
+
+
+ 0
+ 260
+ 191
+ 181
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+ 0
+ 9
+ 191
+ 171
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+
+ 130
+ 70
+ 56
+ 32
+
+
+
+ X+
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 10
+ 70
+ 56
+ 32
+
+
+
+ X-
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 0
+ 56
+ 32
+
+
+
+ Z+
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+ 2
+
+
+
+
+
+ 10
+ 140
+ 56
+ 32
+
+
+
+ Z-
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 2
+
+
+ 2
+
+
+
+
+
+ 70
+ 110
+ 56
+ 32
+
+
+
+ Y-
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 70
+ 30
+ 56
+ 32
+
+
+
+ Y+
+
+
+ false
+
+
+ true
+
+
+ 1
+
+
+ 1
+
+
+
+
+
+ 80
+ 150
+ 101
+ 21
+
+
+
+
+
+
+
+
+ 30
+ 10
+ 131
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Home
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ -1
+
+
+
+
+
+ 130
+ 150
+ 55
+ 32
+
+
+
+ Fwd
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+ 10
+ 150
+ 55
+ 32
+
+
+
+ Rev
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 130
+ 190
+ 55
+ 32
+
+
+
+ +
+
+
+ true
+
+
+
+
+
+ 10
+ 190
+ 55
+ 32
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+ 70
+ 161
+ 55
+ 51
+
+
+
+ Stop
+
+
+ true
+
+
+
+
+
+ 10
+ 70
+ 81
+ 41
+
+
+
+ offsets
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 100
+ 70
+ 81
+ 41
+
+
+
+ Cam View
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 140
+ 10
+ 20
+ 20
+
+
+
+ 10
+
+
+
+ 255
+ 255
+ 0
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 50
+ 80
+ 91
+ 41
+
+
+
+ Macro
+
+
+ true
+
+
+
+
+
+ 50
+ 180
+ 91
+ 41
+
+
+
+ Go to
+Origion Zero
+
+
+ true
+
+
+ MDI_COMMAND_LIST = 0
+
+
+
+
+
+ 50
+ 230
+ 91
+ 41
+
+
+
+ Go to
+ Machine Zero
+
+
+ true
+
+
+ G53 G0 X0Y0Z0
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 191
+ 441
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 20
+ 60
+ 61
+ 61
+
+
+
+ load
+file
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 100
+ 60
+ 61
+ 61
+
+
+
+ Run
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 30
+ 190
+ 61
+ 32
+
+
+
+ View P
+
+
+ true
+
+
+
+
+
+ 100
+ 190
+ 61
+ 32
+
+
+
+ View Z
+
+
+ true
+
+
+ z
+
+
+
+
+
+ 30
+ 240
+ 61
+ 32
+
+
+
+ View Y
+
+
+ true
+
+
+ y
+
+
+
+
+
+ 100
+ 240
+ 61
+ 32
+
+
+
+ View X
+
+
+ true
+
+
+ x
+
+
+
+
+
+ 20
+ 290
+ 71
+ 32
+
+
+
+ View Y2
+
+
+ true
+
+
+ y2
+
+
+
+
+
+ 100
+ 290
+ 71
+ 32
+
+
+
+ View Z2
+
+
+ true
+
+
+ z2
+
+
+
+
+
+
+
+
+ 860
+ 550
+ 91
+ 21
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+
+
+
+ 860
+ 580
+ 91
+ 21
+
+
+
+ 200
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 860
+ 610
+ 91
+ 21
+
+
+
+ 50
+
+
+ 150
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 860
+ 640
+ 91
+ 21
+
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+ QSlider::NoTicks
+
+
+ 10
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 20
+ 725
+ 311
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Mcodes: </span><span style=" color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Mcodes: </span><span style=" color:#ffff00;">%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 955
+ 580
+ 51
+ 24
+
+
+
+ FO
+
+
+ true
+
+
+ true
+
+
+ 75.000000000000000
+
+
+
+
+
+ 955
+ 550
+ 51
+ 24
+
+
+
+ RO
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+ 25.000000000000000
+
+
+
+
+
+ 955
+ 610
+ 51
+ 24
+
+
+
+ SO
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+ 90.000000000000000
+
+
+
+
+
+ 955
+ 640
+ 51
+ 24
+
+
+
+ Jog
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ 60.000000000000000
+
+
+ 15.000000000000000
+
+
+
+
+
+ 10
+ 460
+ 341
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 130
+ 10
+ 121
+ 27
+
+
+
+ Override Limits
+
+
+ true
+
+
+
+
+
+ 230
+ 0
+ 31
+ 41
+
+
+
+ 10
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 10
+ 10
+ 101
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Estop
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 10
+ 60
+ 101
+ 41
+
+
+
+ font: 75 italic 20pt "Noto Sans";
+
+
+ Power
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 100
+ 121
+ 27
+
+
+
+ Flood
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 130
+ 121
+ 27
+
+
+
+ Mist
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 40
+ 121
+ 27
+
+
+
+ Block Delete
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 130
+ 70
+ 121
+ 27
+
+
+
+ Optional Stop
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 30
+ 31
+ 41
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 60
+ 31
+ 41
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 100
+ 31
+ 21
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 230
+ 130
+ 31
+ 21
+
+
+
+ 10
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 90
+ 60
+ 31
+ 21
+
+
+
+ 15
+
+
+
+ 85
+ 255
+ 0
+
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 90
+ 10
+ 21
+ 21
+
+
+
+ 20
+
+
+ true
+
+
+ true
+
+
+
+
+
+ 10
+ 110
+ 101
+ 51
+
+
+
+ Abort
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 260
+ 10
+ 61
+ 61
+
+
+
+ Pause
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 300
+ 10
+ 31
+ 16
+
+
+
+ 10
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+ 350
+ 460
+ 331
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 850
+ 460
+ 171
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 10
+ 10
+ 45
+ 27
+
+
+
+ Fine
+
+
+ true
+
+
+ true
+
+
+ 0.001000000000000
+
+
+ 0.010000000000000
+
+
+ false
+
+
+
+
+
+ 60
+ 10
+ 45
+ 27
+
+
+
+ Med
+
+
+ true
+
+
+ true
+
+
+ 0.010000000000000
+
+
+ 0.100000000000000
+
+
+ false
+
+
+
+
+
+ 110
+ 10
+ 45
+ 27
+
+
+
+ Large
+
+
+ true
+
+
+ true
+
+
+ 0.100000000000000
+
+
+ 1.000000000000000
+
+
+ false
+
+
+
+
+
+ 20
+ 40
+ 121
+ 27
+
+
+
+ Continous
+
+
+ true
+
+
+ true
+
+
+ 0.000000000000000
+
+
+ 0.000000000000000
+
+
+ false
+
+
+
+
+
+
+ 10
+ 680
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 350
+ 680
+ 331
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 10
+ 720
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 350
+ 720
+ 671
+ 41
+
+
+
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+
+ 680
+ 680
+ 341
+ 41
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 60
+ -4
+ 271
+ 41
+
+
+
+
+ 15
+ 75
+ true
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 0
+ 0
+ 61
+ 41
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">MDI:</span></p></body></html>
+
+
+
+
+
+
+ 370
+ 725
+ 651
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Gcodes: </span><span style=" color:#ffff00;">100.0</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ <html><head/><body><p><span style=" font-size:16pt; color:#ffff00;">Gcodes: </span><span style=" color:#ffff00;">%s</span></p></body></html>
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 680
+ 460
+ 171
+ 221
+
+
+
+ QFrame{
+border-image: url(/home/chris/emc-dev/share/qtscreen/images/frame_bg_grey.png) 0 0 0 0 stretch stretch;}
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 10
+ 110
+ 151
+ 21
+
+
+
+ <html><head/><body><p><span style=" color:#d1d1d1;">%s</span></p></body></html>
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 70
+ 160
+ 85
+ 27
+
+
+
+ PushButton
+
+
+
+
+
+
+ 760
+ 530
+ 91
+ 31
+
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">100.000</span></p></body></html>
+
+
+ <html><head/><body><p> <span style=" font-weight:600;font-size:18pt; color:#ffff00;">%3.3f</span></p></body></html>
+
+
+ true
+
+
+ false
+
+
+
+
+
+ 410
+ 590
+ 251
+ 31
+
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">200.00</span><span style=" font-size:18pt; color:#d1d1d1;"> SFPM</span></p></body></html>
+
+
+ Qt::RichText
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%.2f</span><span style=" font-size:18pt; color:#d1d1d1;"> SFPM</span></p></body></html>
+
+
+ <html><head/><body><p><span style=" font-size:18pt; color:#ffff00;">%.2f</span><span style=" font-size:18pt; color:#d1d1d1;"> SMPM</span></p></body></html>
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ 1021
+ -1
+ 571
+ 771
+
+
+
+
+
+
+ -1
+
+
+
+
+
+ lcncdialog
+ frame_auto_5
+ state_label_4
+ StatusLabel
+ frame_auto_10
+ frame_auto_9
+ frame_auto_6
+ frame_auto_7
+ frame_auto_4
+ frame_auto_3
+ frame_auto_2
+ drolabel_y
+ drolabel_z
+ drolabel_x
+ frame
+ gcodeeditor
+ state_enable_gridLayout
+ label_13
+ label_14
+ label_15
+ label_16
+ line
+ state_label
+ state_label_2
+ state_label_3
+ state_label_5
+ state_label_6
+ tooldialog
+ filedialog
+ led_home_x
+ led_home_y
+ led_home_z
+ actionbutton_9
+ actionbutton_10
+ actionbutton_11
+ ScreenOptions
+ StatusLabel_2
+ macrotabdialog
+ originoffsetdialog
+ StatusStacked
+ StatusSlider
+ StatusSlider_2
+ StatusSlider_6
+ StatusSlider_5
+ mcodes_label
+ actionbutton_15
+ actionbutton_16
+ actionbutton_17
+ actionbutton_18
+ frame_auto_8
+ gcodes_label
+ state_label_10
+ focusoverlay
+ horizontalLayoutWidget
+
+
+
+ true
+
+
+
+
+
+ GCodeGraphics
+ QWidget
+ qtvcp.widgets.gcode_graphics
+ 1
+
+
+ CamViewDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ LcncDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StatusSlider
+ QSlider
+ qtvcp.widgets.status_slider
+
+
+ MDILine
+ QLineEdit
+ qtvcp.widgets.mdi_line
+ 1
+
+
+ StateLabel
+ QLabel
+ qtvcp.widgets.state_label
+
+
+ LED
+ QWidget
+ qtvcp.widgets.led_widget
+
+
+ FileDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ MacroTabDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StateLED
+ LED
+ qtvcp.widgets.state_led
+
+
+ OriginOffsetDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ StateEnableGridLayout
+ QWidget
+ qtvcp.widgets.container_widgets
+ 1
+
+
+ StatusStacked
+ QStackedWidget
+ qtvcp.widgets.status_stacked
+ 1
+
+
+ ToolOffsetDialog
+ QDialog
+ qtvcp.widgets.dialog_widget
+
+
+ JogIncrements
+ QComboBox
+ qtvcp.widgets.jog_increments
+
+
+ ScreenOptions
+ QWidget
+ qtvcp.widgets.screen_options
+ 1
+
+
+ StatusLabel
+ QLabel
+ qtvcp.widgets.status_label
+
+
+ DROLabel
+ QLabel
+ qtvcp.widgets.dro_widget
+ 1
+
+
+ GcodeEditor
+ QWidget
+ qtvcp.widgets.gcode_editor
+ 1
+
+
+ ToolDialog
+ LcncDialog
+ qtvcp.widgets.dialog_widget
+
+
+ ActionButton
+ QPushButton
+ qtvcp.widgets.action_button
+
+
+ FocusOverlay
+ QWidget
+ qtvcp.widgets.overlay_widget
+ 1
+
+
+
+
+
+ halbuttonclicked()
+ estop_toggled()
+ machineon_toggled()
+ home_clicked()
+ jog_pressed()
+ jog_released()
+ change_jograte()
+ loadfile_clicked()
+ runfile_clicked()
+ launch_status()
+ zero_axis()
+ launch_halmeter()
+ stopfile_clicked()
+ change_feedrate()
+ change_rapidrate()
+ pausefile_clicked()
+ client_message()
+
+
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp_handler.py b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp_handler.py
new file mode 100644
index 0000000000..e7d0a88e84
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp/qtdefault_gladevcp_handler.py
@@ -0,0 +1,181 @@
+############################
+# **** IMPORT SECTION **** #
+############################
+
+from PyQt5 import QtCore, QtWidgets
+from qtvcp.widgets.origin_offsetview import OriginOffsetView as OFFVIEW_WIDGET
+from qtvcp.widgets.dialog_widget import CamViewDialog as CAMVIEW
+from qtvcp.widgets.dialog_widget import MacroTabDialog as LATHEMACRO
+from qtvcp.widgets.mdi_line import MDILine as MDI_WIDGET
+from qtvcp.lib.keybindings import Keylookup
+from qtvcp.core import Status, Action
+
+# Set up logging
+from qtvcp import logger
+log = logger.getLogger(__name__)
+
+import linuxcnc
+import sys
+import os
+
+###########################################
+# **** instantiate libraries section **** #
+###########################################
+
+KEYBIND = Keylookup()
+STATUS = Status()
+ACTION = Action()
+###################################
+# **** HANDLER CLASS SECTION **** #
+###################################
+
+class HandlerClass:
+
+ ########################
+ # **** INITIALIZE **** #
+ ########################
+ # widgets allows access to widgets from the qtvcp files
+ # at this point the widgets and hal pins are not instantiated
+ def __init__(self, halcomp,widgets,paths):
+ self.hal = halcomp
+ self.w = widgets
+ self.stat = linuxcnc.stat()
+ self.cmnd = linuxcnc.command()
+ self.error = linuxcnc.error_channel()
+ self.PATHS = paths
+ self.IMAGE_PATH = paths.IMAGEDIR
+
+ ##########################################
+ # Special Functions called from QTSCREEN
+ ##########################################
+
+ # at this point:
+ # the widgets are instantiated.
+ # the HAL pins are built but HAL is not set ready
+ def initialized__(self):
+ pass
+
+ def processed_key_event__(self,receiver,event,is_pressed,key,code,shift,cntrl):
+ # when typing in MDI, we don't want keybinding to call functions
+ # so we catch and process the events directly.
+ # We do want ESC, F1 and F2 to call keybinding functions though
+ if code not in(QtCore.Qt.Key_Escape,QtCore.Qt.Key_F1 ,QtCore.Qt.Key_F2,
+ QtCore.Qt.Key_F3,QtCore.Qt.Key_F5,QtCore.Qt.Key_F5):
+ if isinstance(receiver, OFFVIEW_WIDGET) or isinstance(receiver, MDI_WIDGET):
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ if isinstance(receiver,QtWidgets.QDialog):
+ print 'dialog'
+ return True
+ if event.isAutoRepeat():return True
+ try:
+ KEYBIND.call(self,event,is_pressed,shift,cntrl)
+ return True
+ except Exception as e:
+ #log.debug('Exception loading Macros:', exc_info=e)
+ print 'Error in, or no function for: %s in handler file for-%s'%(KEYBIND.convert(event),key)
+ if e:
+ print e
+ #print 'from %s'% receiver
+ return False
+
+ ########################
+ # callbacks from STATUS #
+ ########################
+
+ #######################
+ # callbacks from form #
+ #######################
+
+ #####################
+ # general functions #
+ #####################
+
+ # keyboard jogging from key binding calls
+ # double the rate if fast is true
+ def kb_jog(self, state, joint, direction, fast = False, linear = True):
+ if linear:
+ distance = STATUS.get_jog_increment()
+ rate = STATUS.get_jograte()/60
+ else:
+ distance = STATUS.get_jog_increment_angular()
+ rate = STATUS.get_jograte_angular()/60
+ if state:
+ if fast:
+ rate = rate * 2
+ ACTION.JOG(joint, direction, rate, distance)
+ else:
+ ACTION.JOG(joint, 0, 0, 0)
+
+ #####################
+ # KEY BINDING CALLS #
+ #####################
+
+ # Machine control
+ def on_keycall_ESTOP(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_ESTOP_STATE(STATUS.estop_is_clear())
+ def on_keycall_POWER(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_MACHINE_STATE(not STATUS.machine_is_on())
+ def on_keycall_HOME(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.is_all_homed():
+ ACTION.SET_MACHINE_UNHOMED(-1)
+ else:
+ ACTION.SET_MACHINE_HOMING(-1)
+ def on_keycall_ABORT(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.stat.interp_state == linuxcnc.INTERP_IDLE:
+ self.w.close()
+ else:
+ self.cmnd.abort()
+
+ # Linear Jogging
+ def on_keycall_XPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 0, 1, shift)
+
+ def on_keycall_XNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 0, -1, shift)
+
+ def on_keycall_YPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 1, 1, shift)
+
+ def on_keycall_YNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 1, -1, shift)
+
+ def on_keycall_ZPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 2, 1, shift)
+
+ def on_keycall_ZNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 2, -1, shift)
+
+ def on_keycall_APOS(self,event,state,shift,cntrl):
+ pass
+ #self.kb_jog(state, 3, 1, shift, False)
+
+ def on_keycall_ANEG(self,event,state,shift,cntrl):
+ pass
+ #self.kb_jog(state, 3, -1, shift, linear=False)
+
+ ###########################
+ # **** closing event **** #
+ ###########################
+
+ ##############################
+ # required class boiler code #
+ ##############################
+
+ def __getitem__(self, item):
+ return getattr(self, item)
+ def __setitem__(self, item, value):
+ return setattr(self, item, value)
+
+################################
+# required handler boiler code #
+################################
+
+def get_handlers(halcomp,widgets,paths):
+ return [HandlerClass(halcomp,widgets,paths)]
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler.py b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler.py
new file mode 100644
index 0000000000..ef5c0aa1d8
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler.py
@@ -0,0 +1,206 @@
+############################
+# **** IMPORT SECTION **** #
+############################
+import sys
+import os
+import linuxcnc
+
+from PyQt5 import QtCore, QtWidgets
+
+from qtvcp.widgets.mdi_line import MDILine as MDI_WIDGET
+from qtvcp.widgets.gcode_editor import GcodeEditor as GCODE
+from qtvcp.lib.keybindings import Keylookup
+from qtvcp.core import Status, Action
+
+# Set up logging
+from qtvcp import logger
+LOG = logger.getLogger(__name__)
+
+# Set the log level for this module
+#LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
+
+###########################################
+# **** instantiate libraries section **** #
+###########################################
+
+KEYBIND = Keylookup()
+STATUS = Status()
+ACTION = Action()
+###################################
+# **** HANDLER CLASS SECTION **** #
+###################################
+
+class HandlerClass:
+
+ ########################
+ # **** INITIALIZE **** #
+ ########################
+ # widgets allows access to widgets from the qtvcp files
+ # at this point the widgets and hal pins are not instantiated
+ def __init__(self, halcomp,widgets,paths):
+ self.hal = halcomp
+ self.w = widgets
+ self.PATHS = paths
+
+ ##########################################
+ # Special Functions called from QTSCREEN
+ ##########################################
+
+ # at this point:
+ # the widgets are instantiated.
+ # the HAL pins are built but HAL is not set ready
+ def initialized__(self):
+ pass
+
+ def processed_key_event__(self,receiver,event,is_pressed,key,code,shift,cntrl):
+ # when typing in MDI, we don't want keybinding to call functions
+ # so we catch and process the events directly.
+ # We do want ESC, F1 and F2 to call keybinding functions though
+ if code not in(QtCore.Qt.Key_Escape,QtCore.Qt.Key_F1 ,QtCore.Qt.Key_F2,
+ QtCore.Qt.Key_F3,QtCore.Qt.Key_F5,QtCore.Qt.Key_F5):
+
+ # search for the top widget of whatever widget received the event
+ # then check if it's one we want the keypress events to go to
+ flag = False
+ receiver2 = receiver
+ while receiver2 is not None and not flag:
+ if isinstance(receiver2, QtWidgets.QDialog):
+ flag = True
+ break
+ if isinstance(receiver2, MDI_WIDGET):
+ flag = True
+ break
+ if isinstance(receiver2, GCODE):
+ flag = True
+ break
+ receiver2 = receiver2.parent()
+
+ if flag:
+ if isinstance(receiver2, GCODE):
+ # if in manual do our keybindings - otherwise
+ # send events to gcode widget
+ if STATUS.is_man_mode() == False:
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ elif is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ else:
+ event.accept()
+ return True
+
+ if event.isAutoRepeat():return True
+
+ # ok if we got here then try keybindings
+ try:
+ return KEYBIND.call(self,event,is_pressed,shift,cntrl)
+ except NameError as e:
+ LOG.debug('Exception in KEYBINDING: {}'.format (e))
+ except Exception as e:
+ LOG.debug('Exception in KEYBINDING:', exc_info=e)
+ print 'Error in, or no function for: %s in handler file for-%s'%(KEYBIND.convert(event),key)
+ return False
+
+ ########################
+ # callbacks from STATUS #
+ ########################
+
+ #######################
+ # callbacks from form #
+ #######################
+
+ #####################
+ # general functions #
+ #####################
+
+ # keyboard jogging from key binding calls
+ # double the rate if fast is true
+ def kb_jog(self, state, joint, direction, fast = False, linear = True):
+ if not STATUS.is_man_mode() or not STATUS.machine_is_on():
+ return
+ if linear:
+ distance = STATUS.get_jog_increment()
+ rate = STATUS.get_jograte()/60
+ else:
+ distance = STATUS.get_jog_increment_angular()
+ rate = STATUS.get_jograte_angular()/60
+ if state:
+ if fast:
+ rate = rate * 2
+ ACTION.JOG(joint, direction, rate, distance)
+ else:
+ ACTION.JOG(joint, 0, 0, 0)
+
+ #####################
+ # KEY BINDING CALLS #
+ #####################
+
+ # Machine control
+ def on_keycall_ESTOP(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_ESTOP_STATE(STATUS.estop_is_clear())
+ def on_keycall_POWER(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_MACHINE_STATE(not STATUS.machine_is_on())
+ def on_keycall_HOME(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.is_all_homed():
+ ACTION.SET_MACHINE_UNHOMED(-1)
+ else:
+ ACTION.SET_MACHINE_HOMING(-1)
+ def on_keycall_ABORT(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.stat.interp_state == linuxcnc.INTERP_IDLE:
+ self.w.close()
+ else:
+ self.cmnd.abort()
+
+ # Linear Jogging
+ def on_keycall_XPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 0, 1, shift)
+
+ def on_keycall_XNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 0, -1, shift)
+
+ def on_keycall_YPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 1, 1, shift)
+
+ def on_keycall_YNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 1, -1, shift)
+
+ def on_keycall_ZPOS(self,event,state,shift,cntrl):
+ self.kb_jog(state, 2, 1, shift)
+
+ def on_keycall_ZNEG(self,event,state,shift,cntrl):
+ self.kb_jog(state, 2, -1, shift)
+
+ def on_keycall_APOS(self,event,state,shift,cntrl):
+ pass
+ #self.kb_jog(state, 3, 1, shift, False)
+
+ def on_keycall_ANEG(self,event,state,shift,cntrl):
+ pass
+ #self.kb_jog(state, 3, -1, shift, linear=False)
+
+ ###########################
+ # **** closing event **** #
+ ###########################
+
+ ##############################
+ # required class boiler code #
+ ##############################
+
+ def __getitem__(self, item):
+ return getattr(self, item)
+ def __setitem__(self, item, value):
+ return setattr(self, item, value)
+
+################################
+# required handler boiler code #
+################################
+
+def get_handlers(halcomp,widgets,paths):
+ return [HandlerClass(halcomp,widgets,paths)]
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler_1.py b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler_1.py
new file mode 100644
index 0000000000..e9aa5a309d
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_gladevcp_handler_1.py
@@ -0,0 +1,479 @@
+############################
+# **** IMPORT SECTION **** #
+############################
+
+from PyQt5 import QtCore
+from PyQt5 import QtWidgets
+from qtvcp.widgets.origin_offsetview import OriginOffsetView as OFFVIEW_WIDGET
+from qtvcp.widgets.tool_offsetview import ToolOffsetView as TOOLVIEW_WIDGET
+from qtvcp.widgets.dialog_widget import CamViewDialog as CAMVIEW
+from qtvcp.widgets.dialog_widget import MacroTabDialog as LATHEMACRO
+from qtvcp.widgets.mdi_line import MDILine as MDI_WIDGET
+from qtvcp.widgets.gcode_editor import GcodeEditor as GCODE
+from qtvcp.lib.keybindings import Keylookup
+from qtvcp.lib.notify import Notify
+
+from qtvcp.core import Status, Action
+
+# Set up logging
+from qtvcp import logger
+
+import linuxcnc
+import sys
+import os
+
+###########################################
+# **** instantiate libraries section **** #
+###########################################
+
+KEYBIND = Keylookup()
+STATUS = Status()
+ACTION = Action()
+LOG = logger.getLogger(__name__)
+# Set the log level for this module
+#LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
+
+###################################
+# **** HANDLER CLASS SECTION **** #
+###################################
+
+class HandlerClass:
+
+ ########################
+ # **** INITIALIZE **** #
+ ########################
+ # widgets allows access to widgets from the qtvcp files
+ # at this point the widgets and hal pins are not instantiated
+ def __init__(self, halcomp,widgets,paths):
+ self.hal = halcomp
+ self.w = widgets
+ self.stat = linuxcnc.stat()
+ self.cmnd = linuxcnc.command()
+ self.error = linuxcnc.error_channel()
+ self.PATH = paths.CONFIGPATH
+ self.IMAGE_PATH = paths.IMAGEDIR
+ self.STYLE = Styles(widgets, paths)
+ ##########################################
+ # Special Functions called from QTVCP
+ ##########################################
+
+ # at this point:
+ # the widgets are instantiated.
+ # the HAL pins are built but HAL is not set ready
+ def initialized__(self):
+ if self.w.PREFS_:
+ print 'Using preference file:',self.w.PREFS_.fn
+ STATUS.emit('play-alert','SPEAK This is a test screen for Qt V C P')
+ # set custom theme
+ self.STYLE.dark_style()
+ KEYBIND.add_call('Key_F3','on_keycall_F3')
+ KEYBIND.add_call('Key_F4','on_keycall_F4')
+ KEYBIND.add_call('Key_F5','on_keycall_F5')
+ KEYBIND.add_call('Key_F6','on_keycall_F6')
+
+ def processed_key_event__(self,receiver,event,is_pressed,key,code,shift,cntrl):
+ # when typing in MDI, we don't want keybinding to call functions
+ # so we catch and process the events directly.
+ # We do want ESC, F1 and F2 to call keybinding functions though
+ if code not in(QtCore.Qt.Key_Escape,QtCore.Qt.Key_F1 ,QtCore.Qt.Key_F2,
+ QtCore.Qt.Key_F3,QtCore.Qt.Key_F5,QtCore.Qt.Key_F5):
+ if isinstance(receiver, OFFVIEW_WIDGET) or \
+ isinstance(receiver, MDI_WIDGET) or isinstance(receiver, TOOLVIEW_WIDGET):
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ elif isinstance(receiver, GCODE) and STATUS.is_man_mode() == False:
+ if is_pressed:
+ receiver.keyPressEvent(event)
+ event.accept()
+ return True
+ elif isinstance(receiver,QtWidgets.QDialog):
+ print 'dialog'
+ return True
+ try:
+ KEYBIND.call(self,event,is_pressed,shift,cntrl)
+ return True
+ except Exception as e:
+ LOG.info('Exception loading Macros:', exc_info=e)
+ print 'Error in, or no function for: %s in handler file for-%s'%(KEYBIND.convert(event),key)
+ print 'from %s'% receiver
+ return False
+
+ ########################
+ # callbacks from STATUS #
+ ########################
+
+ #######################
+ # callbacks from form #
+ #######################
+ def client_message(self):
+ print 'push'
+ self.w.xembed.send_x11_message()
+
+ #####################
+ # general functions #
+ #####################
+
+ #####################
+ # KEY BINDING CALLS #
+ #####################
+ def on_keycall_ABORT(self,event,state,shift,cntrl):
+ if state:
+ print 'abort'
+ if STATUS.stat.interp_state == linuxcnc.INTERP_IDLE:
+ self.w.close()
+ else:
+ print 'abort'
+ self.cmnd.abort()
+ self.w.button_home.click()
+
+ def on_keycall_ESTOP(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_ESTOP_STATE(STATUS.estop_is_clear())
+ def on_keycall_POWER(self,event,state,shift,cntrl):
+ if state:
+ ACTION.SET_MACHINE_STATE(not STATUS.machine_is_on())
+ def on_keycall_HOME(self,event,state,shift,cntrl):
+ if state:
+ if STATUS.is_all_homed():
+ ACTION.SET_MACHINE_UNHOMED(-1)
+ else:
+ ACTION.SET_MACHINE_HOMING(-1)
+
+ def on_keycall_F3(self,event,state,shift,cntrl):
+ if state:
+ self.w.originoffsetdialog.load_dialog()
+ def on_keycall_F4(self,event,state,shift,cntrl):
+ if state:
+ self.w.camviewdialog.load_dialog()
+ def on_keycall_F5(self,event,state,shift,cntrl):
+ if state:
+ self.w.macrotabdialog.load_dialog()
+ def on_keycall_F6(self,event,state,shift,cntrl):
+ if state:
+ self.w.tooloffsetdialog.load_dialog()
+
+ def on_keycall_XPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(0, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(0, 0, STATUS.current_jog_distance)
+ def on_keycall_XNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(0, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(0, 0, STATUS.current_jog_distance)
+
+ def on_keycall_YPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(1, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(1, 0, STATUS.current_jog_distance)
+
+ def on_keycall_YNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(1, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(1, 0, STATUS.current_jog_distance)
+
+ def on_keycall_ZPOS(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(2, 1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(2, 0, STATUS.current_jog_distance)
+
+ def on_keycall_ZNEG(self,event,state,shift,cntrl):
+ if state:
+ STATUS.do_jog(2, -1, STATUS.current_jog_distance)
+ else:
+ STATUS.do_jog(2, 0, STATUS.current_jog_distance)
+
+ ###########################
+ # **** closing event **** #
+ ###########################
+ def closing_cleanup__(self):
+ print'CLOSING'
+
+ ##############################
+ # required class boiler code #
+ ##############################
+
+ def __getitem__(self, item):
+ return getattr(self, item)
+ def __setitem__(self, item, value):
+ return setattr(self, item, value)
+
+################################
+# required handler boiler code #
+################################
+
+def get_handlers(halcomp,widgets,paths):
+ return [HandlerClass(halcomp,widgets,paths)]
+
+#####################################################################
+# Styles - put them here to keep things tidy
+#####################################################################
+class Styles:
+ def __init__(self, widgets, paths):
+ self.w = widgets
+ self.PATH = paths.CONFIGPATH
+ self.IMAGE_PATH = paths.IMAGEDIR
+
+ def bright_style(self):
+ self.w.setStyleSheet('''#MainWindow {background: black; }
+QLineEdit {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QPushButton {
+color: #333;
+border: 2px solid #555;
+border-radius: 11px;
+padding: 5px;
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+min-width: 40px;
+}
+
+ QPushButton:hover {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #bbb);
+}
+
+QPushButton:pressed {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+QPushButton:checked {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+
+QSlider::groove:horizontal {
+border: 1px solid #bbb;
+background: white;
+height: 5px;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #66e, stop: 1 #bbf);
+background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
+ stop: 0 #bbf, stop: 1 #55f);
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::add-page:horizontal {
+background: #fff;
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #eee, stop:1 #ccc);
+border: 1px solid #777;
+width: 20px;
+margin-top: -7px;
+margin-bottom: -75px;
+border-radius: 4px;
+
+}
+
+QSlider::handle:horizontal:hover {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #fff, stop:1 #ddd);
+border: 1px solid #444;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal:disabled {
+background: #bbb;
+border-color: #999;
+}
+
+QSlider::add-page:horizontal:disabled {
+background: #eee;
+border-color: #999;
+}
+
+QSlider::handle:horizontal:disabled {
+background: #eee;
+border: 1px solid #aaa;
+border-radius: 4px;
+min-height: 30px;
+}
+#frame_man { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ }
+
+''')
+
+ style ='''#frame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ } '''
+ self.w.frame.setStyleSheet(style)
+
+ style ='''QFrame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #0000ff, stop: 1 #141529);
+ } '''
+ self.w.frame_mdi.setStyleSheet(style)
+ self.w.frame_auto.setStyleSheet(style)
+ self.w.frame_auto_2.setStyleSheet(style)
+ self.w.frame_auto_3.setStyleSheet(style)
+ self.w.frame_auto_4.setStyleSheet(style)
+ self.w.frame_auto_5.setStyleSheet(style)
+ self.w.frame_auto_6.setStyleSheet(style)
+ self.w.frame_auto_7.setStyleSheet(style)
+ self.w.frame_auto_8.setStyleSheet(style)
+ self.w.frame_auto_9.setStyleSheet(style)
+ self.w.frame_auto_10.setStyleSheet(style)
+
+
+ def dark_style(self):
+ bgpath = self.IMAGE_PATH+'/hazzy_bg_black.png'
+ self.w.setStyleSheet('''#MainWindow {background: black; }
+QStatusBar {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QLineEdit {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+padding: 1px;
+border-style: solid;
+border: 2px solid gray;
+border-radius: 8px;
+}
+
+QPushButton {
+color: #333;
+border: 2px solid #555;
+border-radius: 11px;
+padding: 5px;
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #888);
+min-width: 40px;
+}
+
+ QPushButton:hover {
+background: qradialgradient(cx: 0.3, cy: -0.4,
+fx: 0.3, fy: -0.4,
+radius: 1.35, stop: 0 #fff, stop: 1 #bbb);
+}
+
+QPushButton:pressed {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+QPushButton:checked {
+background: qradialgradient(cx: 0.4, cy: -0.1,
+fx: 0.4, fy: -0.1,
+radius: 1.35, stop: 0 #fff, stop: 1 #ddd);
+}
+
+QSlider::groove:horizontal {
+border: 1px solid #bbb;
+background: white;
+height: 5px;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #66e, stop: 1 #bbf);
+background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
+ stop: 0 #bbf, stop: 1 #55f);
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::add-page:horizontal {
+background: #fff;
+border: 1px solid #777;
+height: 10px;
+border-radius: 4px;
+}
+
+QSlider::handle:horizontal {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #eee, stop:1 #ccc);
+border: 1px solid #777;
+width: 20px;
+margin-top: -7px;
+margin-bottom: -75px;
+border-radius: 4px;
+
+}
+
+QSlider::handle:horizontal:hover {
+background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #fff, stop:1 #ddd);
+border: 1px solid #444;
+border-radius: 4px;
+}
+
+QSlider::sub-page:horizontal:disabled {
+background: #bbb;
+border-color: #999;
+}
+
+QSlider::add-page:horizontal:disabled {
+background: #eee;
+border-color: #999;
+}
+
+QSlider::handle:horizontal:disabled {
+background: #eee;
+border: 1px solid #aaa;
+border-radius: 4px;
+min-height: 30px;
+}
+#frame_man { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #38395a, stop: 1 #141529);
+ }
+
+''')
+ bgpath = self.IMAGE_PATH+'/frame_bg_blue.png'
+ self.w.frame.setStyleSheet("#frame { border-image: url(%s) 0 0 0 0 stretch stretch; }"%bgpath)
+ #bgpath = self.IMAGE_PATH+'/Grey.jpg'
+
+ style ='''QFrame { border: 3px solid gray;border-radius: 15px;
+background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #38395a, stop: 1 #141529);
+ } '''
+ self.w.frame_mdi.setStyleSheet(style)
+ self.w.frame_auto.setStyleSheet(style)
+ self.w.frame_auto_2.setStyleSheet(style)
+ self.w.frame_auto_3.setStyleSheet(style)
+ self.w.frame_auto_4.setStyleSheet(style)
+ self.w.frame_auto_5.setStyleSheet(style)
+ self.w.frame_auto_6.setStyleSheet(style)
+ self.w.frame_auto_7.setStyleSheet(style)
+ self.w.frame_auto_8.setStyleSheet(style)
+ self.w.frame_auto_9.setStyleSheet(style)
+ self.w.frame_auto_10.setStyleSheet(style)
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini
new file mode 100644
index 0000000000..3531350772
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtdefault_ngc.ini
@@ -0,0 +1,323 @@
+# This config file was created 2017-02-05 00:32:40.919119 by the update_ini script
+# The original config files may be found in the /home/chris/linuxcnc-mk/configs/sim/qtscreen/qtdefault.old directory
+
+# EMC controller parameters for a simulated machine.
+
+# General note: Comments can either be preceded with a # or ; - either is
+# acceptable, although # is in keeping with most linux config files.
+
+# General section -------------------------------------------------------------
+[EMC]
+
+
+# Version of this INI file
+VERSION = 1.1
+
+# Name of machine, for use with display, etc.
+MACHINE = LinuxCNC-HAL-SIM-AXIS
+
+# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
+#define EMC_DEBUG_CONFIG 0x00000002
+#define EMC_DEBUG_VERSIONS 0x00000008
+#define EMC_DEBUG_TASK_ISSUE 0x00000010
+#define EMC_DEBUG_NML 0x00000040
+#define EMC_DEBUG_MOTION_TIME 0x00000080
+#define EMC_DEBUG_INTERP 0x00000100
+#define EMC_DEBUG_RCS 0x00000200
+#define EMC_DEBUG_INTERP_LIST 0x00000800
+#define EMC_DEBUG_IOCONTROL 0x00001000
+#define EMC_DEBUG_OWORD 0x00002000
+#define EMC_DEBUG_REMAP 0x00004000
+#define EMC_DEBUG_PYTHON 0x00008000
+#define EMC_DEBUG_NAMEDPARAM 0x00010000
+#define EMC_DEBUG_GDBONSIGNAL 0x00020000
+#define EMC_DEBUG_PYTHON_TASK 0x00040000
+#define EMC_DEBUG_ALL 0x7FFFFFFF /* it's an int for %i to work
+
+DEBUG = 0x00002000
+#DEBUG = 0
+
+# Sections for display options ------------------------------------------------
+[DISPLAY]
+
+# Name of display program, e.g., xemc
+DISPLAY = qtvcp -m qtdefault_ngc
+
+# Cycle time, in seconds, that display will sleep between polls
+CYCLE_TIME = 0.100
+
+# Path to help file
+HELP_FILE = doc/help.txt
+
+# Initial display setting for position, RELATIVE or MACHINE
+POSITION_OFFSET = RELATIVE
+
+# Initial display setting for position, COMMANDED or ACTUAL
+POSITION_FEEDBACK = ACTUAL
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 2.0
+
+DEFAULT_SPINDLE_SPEED = 200
+MIN_SPINDLE_OVERRIDE = 0.5
+MAX_SPINDLE_OVERRIDE = 1.5
+
+MAX_LINEAR_VELOCITY = 1
+DEFAULT_LINEAR_VELOCITY = .25
+
+# Prefix to be used
+PROGRAM_PREFIX = ../../nc_files/
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+#EDITOR = gedit
+TOOL_EDITOR = tooledit
+
+INCREMENTS = 0.1 in, 0.01 in, 0.001 in, 0.0001 in, 1 mm, 0.1 mm, 0.01 mm
+
+# set up 3 user popup message dialogs
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a statusbar test
+MESSAGE_DETAILS = STATUS DETAILS
+MESSAGE_TYPE = status
+MESSAGE_PINNAME = statustest
+
+MESSAGE_BOLDTEXT = NONE
+MESSAGE_TEXT = This is a yes no dialog test
+MESSAGE_DETAILS = Y/N DETAILS
+MESSAGE_TYPE = yesnodialog
+MESSAGE_PINNAME = yndialogtest
+
+MESSAGE_BOLDTEXT = This is the short text
+MESSAGE_TEXT = This is the longer text of the both type test. It can be longer then the status bar text
+MESSAGE_DETAILS = BOTH DETAILS
+MESSAGE_TYPE = okdialog status
+MESSAGE_PINNAME = bothtest
+
+#NGCGUI_OPTIONS = opt1 opt2 ...
+# opt items:
+# nonew -- disallow making new tab page
+# noremove -- disallow removing any tab page
+# noauto -- no autosend (makeFile, then manually send)
+# noiframe -- no internal image, image on separate toplevel
+# nom2 -- no m2 terminator (use %)
+NGCGUI_PREAMBLE = in_std.ngc
+NGCGUI_SUBFILE = simp.ngc
+NGCGUI_SUBFILE = db25.ngc
+NGCGUI_SUBFILE = gosper.ngc
+NGCGUI_SUBFILE = xyz.ngc
+NGCGUI_SUBFILE = ihex.ngc
+NGCGUI_SUBFILE = slot.ngc
+NGCGUI_SUBFILE = arc2.ngc
+NGCGUI_SUBFILE = iquad.ngc
+NGCGUI_SUBFILE = qpocket.ngc
+NGCGUI_SUBFILE = ""
+
+[MDI_COMMAND_LIST]
+MDI_COMMAND = G0 X0Y0Z0
+MDI_COMMAND = G0 X1Y1Z1
+
+[FILTER]
+PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
+PROGRAM_EXTENSION = .py Python Script
+
+png = image-to-gcode
+gif = image-to-gcode
+jpg = image-to-gcode
+py = python
+
+# Task controller section -----------------------------------------------------
+
+[RS274NGC]
+
+# File containing interpreter variables
+PARAMETER_FILE = sim.var
+#SUBROUTINE_PATH = ~/linuxcnc/nc_files/macros/lathe
+
+SUBROUTINE_PATH = ../../nc_files/ngcgui_lib:../../nc_files/ngcgui_lib/utilitysubs
+USER_M_PATH = ../../nc_files/ngcgui_lib/mfiles
+# Motion control section ------------------------------------------------------
+
+[EMCMOT]
+
+EMCMOT = motmod
+
+# Timeout for comm to emcmot, in seconds
+COMM_TIMEOUT = 1.0
+
+# Interval between tries to emcmot, in seconds
+COMM_WAIT = 0.010
+
+# BASE_PERIOD is unused in this configuration but specified in core_sim.hal
+BASE_PERIOD = 0
+# Servo task period, in nano-seconds
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+
+[TASK]
+
+# Name of task controller program, e.g., milltask
+TASK = milltask
+
+# Cycle time, in seconds, that task controller will sleep between polls
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+
+[HAL]
+
+# The run script first uses halcmd to execute any HALFILE
+# files, and then to execute any individual HALCMD commands.
+#
+
+# list of hal config files to run through halcmd
+# files are executed in the order in which they appear
+HALFILE = core_sim.hal
+HALFILE = sim_spindle_encoder.hal
+#HALFILE = axis_manualtoolchange.hal
+HALFILE = simulated_home.hal
+HALFILE = check_constraints.hal
+
+# list of halcmd commands to execute
+# commands are executed in the order in which they appear
+#HALCMD = save neta
+
+# Single file that is executed after the GUI has started. Only supported by
+# AXIS at this time (only AXIS creates a HAL component of its own)
+POSTGUI_HALFILE = qtvcp_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+
+[HALUI]
+#No Content
+[TRAJ]
+
+
+AXES = 3
+COORDINATES = X Y Z
+HOME = 0 0 0
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+CYCLE_TIME = 0.010
+DEFAULT_LINEAR_VELOCITY = 5
+POSITION_FILE = position.txt
+MAX_LINEAR_VELOCITY = 5
+
+# Axes sections ---------------------------------------------------------------
+
+# First axis
+[EMCIO]
+
+# Name of IO controller program, e.g., io
+EMCIO = io
+
+# cycle time, in seconds
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = ../../sim.tbl
+TOOL_CHANGE_POSITION = 0 0 0
+TOOL_CHANGE_QUILL_UP = 1
+
+
+[KINS]
+KINEMATICS = trivkins
+#This is a best-guess at the number of joints, it should be checked
+JOINTS = 3
+
+[AXIS_X]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_0]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Second axis
+[AXIS_Y]
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_1]
+
+
+TYPE = LINEAR
+HOME = 0.000
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -40.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -8.0
+MAX_LIMIT = 0.12
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+
+[JOINT_2]
+
+
+TYPE = LINEAR
+HOME = 0.0
+MAX_VELOCITY = 5
+MAX_ACCELERATION = 50.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -8.0
+
+# Normally the Z max should be 0.000!
+# The only reason it's greater than 0 here is so that the splash screen
+# gcode will run.
+MAX_LIMIT = 0.12
+
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME_SEARCH_VEL = 20.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+# section for main IO controller parameters
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/qtvcp_postgui.hal b/configs/sim/qtvcp_screens/qtvcp_experimental/qtvcp_postgui.hal
new file mode 100644
index 0000000000..7358d1a96d
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/qtvcp_postgui.hal
@@ -0,0 +1,11 @@
+# in case they were linked already
+unlinkp iocontrol.0.tool-change
+unlinkp iocontrol.0.tool-changed
+
+# Need a qt tool change dialog added to screen for this to work
+# though it uses the same pin names as the AXIS version
+# the Qt version intergrates better.
+
+net tool-change hal_manualtoolchange.change iocontrol.0.tool-change
+net tool-changed hal_manualtoolchange.changed iocontrol.0.tool-changed
+net tool-prep-number hal_manualtoolchange.number iocontrol.0.tool-prep-number
diff --git a/configs/sim/qtvcp_screens/qtvcp_experimental/savestate.sav b/configs/sim/qtvcp_screens/qtvcp_experimental/savestate.sav
new file mode 100644
index 0000000000..962b682688
--- /dev/null
+++ b/configs/sim/qtvcp_screens/qtvcp_experimental/savestate.sav
@@ -0,0 +1,53 @@
+# generated by gladevcp.persistence.create_default_ini() on Mon Jul 16 19:06:21 2018
+[ini]
+ version = 1
+ signature = 10614b72d8945308102d29d38e799e8fa8b30189
+[vars]
+[widgets]
+ turn.sf = 88.0
+ thread.pitch = 0.0
+ turn.tool = 0.0
+ turn.angle = 10.0
+ chamfer.bo = True
+ face.tool = 0.0
+ chamfer.sf = 0.0
+ turn.cut = 0.15
+ bore.angle = 0.0
+ radius.bo = False
+ chamfer.fi = False
+ chamfer.size = 0.0
+ thread.x = 0.0
+ radius.sf = 0.0
+ chamfer.fo = False
+ bore.z = 0.0
+ bore.feed = 2.0
+ thread.internal = True
+ bore.tool = 0.0
+ thread.sf = 45.0
+ turn.rad = 0.0
+ bore.sf = 0.0
+ turn.x = 0.0
+ turn.z = 1.0
+ face.z = 0.0
+ face.x = 0.0
+ face.feed = 0.0
+ thread.tool = 0.0
+ radius.x = 0.0
+ radius.z = 0.0
+ face.cut = 0.0
+ radius.rad = 0.0
+ turn.feed = 2.0
+ bore.x = 0.0
+ thread.z = 0.0
+ face.angle = 0.0
+ face.sf = 0.0
+ radius.tool = 0.0
+ bore.cut = 0.0
+ chamfer.x = 0.0
+ chamfer.tool = 0.0
+ chamfer.z = 0.0
+ radius.fo = False
+ bore.rad = 0.0
+ thread.external = False
+ radius.fi = True
+# last update by gladevcp.persistence.save_state() on Sun Aug 2 23:26:51 2020
diff --git a/configs/sim/qtvcp_screens/qtx1mill.ini b/configs/sim/qtvcp_screens/qtx1mill.ini
index 107ca803f4..701e274fdc 100644
--- a/configs/sim/qtvcp_screens/qtx1mill.ini
+++ b/configs/sim/qtvcp_screens/qtx1mill.ini
@@ -42,7 +42,7 @@ DEBUG = 0x00002000
# Name of display program, e.g., xemc
DISPLAY = qtvcp -d x1mill
-
+PREFERENCE_FILE_PATH = WORKINGFOLDER/qtx11mill.pref
# embedded programs
#EMBED_TAB_NAME=Onboard demo
#EMBED_TAB_COMMAND=onboard --xid
diff --git a/configs/sim/tklinuxcnc/README_es b/configs/sim/tklinuxcnc/README_es
new file mode 100644
index 0000000000..968770c057
--- /dev/null
+++ b/configs/sim/tklinuxcnc/README_es
@@ -0,0 +1,13 @@
+Archivos Sim usando gui tklinuxcnc:
+
+ldelta.ini
+ -robot delta con articulaciones lineales
+
+servo_sim.ini
+ -simulación para una máquina servos
+
+tklinuxcnc.ini
+ -interfaz tcl/tk
+
+tripod.ini
+ - maquina de cinemática no trivial
diff --git a/configs/sim/tklinuxcnc/trivkins/README_es b/configs/sim/tklinuxcnc/trivkins/README_es
new file mode 100644
index 0000000000..186ed9e6d6
--- /dev/null
+++ b/configs/sim/tklinuxcnc/trivkins/README_es
@@ -0,0 +1,15 @@
+Ejemplos trivkins
+
+xz.ini KINEMATICS_IDENTITY
+
+xz_both.ini KINEMATICS_BOTH
+
+NOTA:
+!!! [TRAJ]COORDINATES DEBEN COINCIDIR CON KINS:
+!!! [TRAJ]COORDINATES = xz
+
+xz.ini
+ [KINS]KINEMATICS=trivkins coordinates=xz
+
+xz_both.ini
+ KINEMATICS = trivkins coordinates=xz kinstype=BOTH
diff --git a/configs/sim/touchy/README_es b/configs/sim/touchy/README_es
new file mode 100644
index 0000000000..c1b9f16454
--- /dev/null
+++ b/configs/sim/touchy/README_es
@@ -0,0 +1,3 @@
+touchy
+
+Una interfaz gráfica de usuario basada en GTK para configuraciones de panel táctil
diff --git a/configs/sim/touchy/gladevcp/README_es b/configs/sim/touchy/gladevcp/README_es
new file mode 100644
index 0000000000..7e00616e03
--- /dev/null
+++ b/configs/sim/touchy/gladevcp/README_es
@@ -0,0 +1 @@
+gladevcp -- demos de guis basadas en glade
diff --git a/configs/sim/touchy/gladevcp/gladevcp-touchy.hal b/configs/sim/touchy/gladevcp/gladevcp-touchy.hal
index 70ff262c0b..c2fbb5bda5 100644
--- a/configs/sim/touchy/gladevcp/gladevcp-touchy.hal
+++ b/configs/sim/touchy/gladevcp/gladevcp-touchy.hal
@@ -5,7 +5,7 @@ setp gladevcp.settings 1
setp gladevcp.commands 1
# show the current spindle speed in the top hoizontal bar
-net spindle-speed motion.spindle-speed-out => gladevcp.spindle-rpm-hbar
+net spindle-speed spindle.0.speed-out => gladevcp.spindle-rpm-hbar
# the first and second labels show prepared and current tool
# unlinkp iocontrol.0.tool-prep-number
diff --git a/configs/sim/touchy/ngcgui/README_es b/configs/sim/touchy/ngcgui/README_es
new file mode 100644
index 0000000000..227fb3e3bc
--- /dev/null
+++ b/configs/sim/touchy/ngcgui/README_es
@@ -0,0 +1,9 @@
+configuraciones de pyngcgui para touchy
+
+Demostrar aplicaciones gladevcp:
+ pyngcgui -- aplicación de subrutina
+ gremlin_view -- gremlin con algunos botones
+
+Las configuraciones de pyngcgui incluyen un script de shell
+(hwsim.sh) para simular los botones de hardware
+y mpg que se pueden usar con touchy.
diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_es.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_es.txt
new file mode 100644
index 0000000000..3337a0f4f9
--- /dev/null
+++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_es.txt
@@ -0,0 +1,7 @@
+pyngcgui_touchy
+
+Demostrar aplicaciones gladevcp:
+ pyngcgui -- aplicación de subrutina
+ gremlin_view -- gremlin con algunos botones
+
+
diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_gcmc_es.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_gcmc_es.txt
new file mode 100644
index 0000000000..9b3d9f95b9
--- /dev/null
+++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_gcmc_es.txt
@@ -0,0 +1,8 @@
+configuración de pyngcgui para touchy
+
+Demostrar aplicaciones gladevcp:
+ pyngcgui -- aplicación de subrutina
+ gremlin_view -- gremlin con algunos botones
+
+Con soporte para archivos .gcmc
+ gcmc -> Meta compilador G-Code
diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe_es.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe_es.txt
new file mode 100644
index 0000000000..ce5fd0fb07
--- /dev/null
+++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_lathe_es.txt
@@ -0,0 +1,5 @@
+configuración de pyngcgui touchy para torno
+
+Demostrar aplicaciones gladevcp:
+ pyngcgui -- aplicación de subrutina
+ gremlin_view -- gremlin con algunos botones
diff --git a/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt
new file mode 100644
index 0000000000..4c920b3708
--- /dev/null
+++ b/configs/sim/touchy/ngcgui/pyngcgui_touchy_moveoff_es.txt
@@ -0,0 +1,23 @@
+demo moveoff para touchy
+
+modifica pyngcgui_touchy.ini para usar:
+
+[HAL]
+...
+HALFILE = hookup_move.tcl
+HALUI = halui
+
+APP = moveoff_gui \
+ -size 20 -loc center \
+ -axes xyz \
+ -autoresume -delay 4 \
+ -inc 0.001 -inc 0.01 -inc 0.1 -inc 1.0
+
+
+Las configuraciones de simulación generalmente conectan los pines motor-pos-cmd y motor-pos-fb (cortocircuitados). Esta configuración también es aplicable en bucle abierto (sistemas paso a paso) y hace posible que las simulaciones se ejecuten sin hardware externo. Los servosistemas utilizan rutas separadas para el comando y la retroalimentación y el lazo servo se completa con componentes hal (a menudo utilizando un componente pid).
+
+Esta conexión separada es necesaria para verificar que la secuencia de comandos hookup_moveoff funcione correctamente con configuraciones de servos y sistemas paso a paso.
+
+Para más información de uso:
+ $ man moveoff
+ $ moveoff_gui --help | more
\ No newline at end of file
diff --git a/configs/sim/touchy/touchy_es.txt b/configs/sim/touchy/touchy_es.txt
new file mode 100644
index 0000000000..3a54e70a05
--- /dev/null
+++ b/configs/sim/touchy/touchy_es.txt
@@ -0,0 +1,7 @@
+touchy.ini: una interfaz gráfica de usuario con pantalla táctil
+
+Botones externos requeridos:
+ touchy.cycle-start
+ touchy.abort
+
+Jogwheel externo recomendado
diff --git a/debian/changelog b/debian/changelog
index 845921a1bc..567316a542 100755
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,7 +4,7 @@ linuxcnc (1:2.9.0~pre0) stretch; urgency=medium
-- Sebastian Kuzminsky Sun, 02 Jun 2019 16:52:46 -0600
-linuxcnc (1:2.8.0~pre1.5970.gc1cbb001a) buster; urgency=low
+linuxcnc (1:2.8.0) buster; urgency=low
* Finally merge "Joints Axes". Joints and cartesian axes are no longer
treated as the same thing, making control of robots and non-trivial
@@ -36,17 +36,19 @@ linuxcnc (1:2.8.0~pre1.5970.gc1cbb001a) buster; urgency=low
* QTvcp: New QT-based VCP framework
* QTdragon, QTlathe, QTtouchy, QTscreen - new GUIs based on QTVP
* Silverdragon: New gscreen based GUI
- * plasmac: New full-featured Plasma cutter cotroller
+ * plasmac: New full-featured Plasma cutter controller
* Back tool lathe support in axis and gmoccapy
* Many Axis improvements
* Many Gmoccapy improvements
* stepconf - various improvements
* pncconf - many improvements
+ * Much enlarged new Spanish language translations
* it.po: New Italian translation file.
* Improve German translation
* Add international support for classicladder
- * added Chinese translations for some docs
+ * Added Chinese translations for some docs
+ * Some new French translations
* Mesa 7i96 support added
* RPi4 fixes and Mesa 7C80/7C81 board additions
@@ -118,7 +120,6 @@ linuxcnc (1:2.8.0~pre1.5970.gc1cbb001a) buster; urgency=low
* uspace: add uspace+rtai realtime
* add a sample config for the scorbot-er-3 robot arm
* docs: document AXIS's foam mode
- * configs: foam: this has no locking indexer
-- andypugh Sun, 12 Jul 2020 20:29:54 +0100
@@ -748,7 +749,7 @@ linuxcnc (1:2.7.5) unstable; urgency=medium
* build: make failure copying images an error
* packaging: interface with udev better
- -- Sebastian Kuzminsky Tue, 12 July 2016 21:47:18 -0600
+ -- Sebastian Kuzminsky Tue, 12 Jul 2016 21:47:18 -0600
linuxcnc (1:2.7.4) unstable; urgency=medium
diff --git a/debian/configure b/debian/configure
index 1bced30c5b..212d17167e 100755
--- a/debian/configure
+++ b/debian/configure
@@ -159,10 +159,16 @@ else
fi
if [ -n "$ENABLE_BUILD_DOCUMENTATION" ]; then
- DOC_DEPENDS='asciidoc (>= 8.5), dblatex (>= 0.2.12), docbook-xsl, dvipng, ghostscript, graphviz, groff, imagemagick, inkscape, python-lxml, source-highlight, texlive-extra-utils, texlive-font-utils, texlive-fonts-recommended, texlive-lang-cyrillic, texlive-lang-french, texlive-lang-german, texlive-lang-polish, texlive-lang-spanish, texlive-latex-recommended, w3c-linkchecker, xsltproc'
+ DOC_DEPENDS='asciidoc (>= 8.5), dblatex (>= 0.2.12), docbook-xsl, \
+ dvipng, ghostscript, graphviz, groff, imagemagick, inkscape, \
+ python-lxml, source-highlight, w3c-linkchecker, xsltproc, \
+ texlive-extra-utils, texlive-font-utils, texlive-fonts-recommended, \
+ texlive-lang-cyrillic, texlive-lang-french, texlive-lang-german, \
+ texlive-lang-polish, texlive-lang-spanish, texlive-latex-recommended'
else
DOC_DEPENDS=''
fi
+
MODUTILS_DEPENDS=kmod
PYTHON_PACKAGING_DEPENDS=dh-python
PYTHON_PACKAGING=dh_python2
@@ -171,6 +177,7 @@ TCLTK_VERSION=8.6
PYTHON_IMAGING="python${PYTHON_VERSION}-imaging | python-imaging | python-pil"
PYTHON_IMAGING_TK="python${PYTHON_VERSION}-imaging-tk | python-imaging-tk | python-pil.imagetk"
YAPPS_RUNTIME="yapps2-runtime"
+STANDARDS_VERSION="3.9.3"
case $DISTRIB_NAME in
Debian-10|Debian-10.*|Raspbian-10|Raspbian-10.*)
@@ -178,36 +185,37 @@ case $DISTRIB_NAME in
PYTHON_GST=python-gst-1.0,gstreamer1.0-plugins-base
EXTRA_BUILD=python-yapps
YAPPS_RUNTIME="python-yapps"
+ STANDARDS_VERSION="3.9.8"
;;
-Debian-9.*|Debian-10|Debian-10.*|Raspbian-9.*|Debian-testing|LinuxMint-19.*|Ubuntu-18.*)
+ Debian-9.*|Raspbian-9.*|LinuxMint-19.*|Ubuntu-18.*)
DOC_DEPENDS="$DOC_DEPENDS, asciidoc-dblatex"
PYTHON_GST=python-gst-1.0,gstreamer1.0-plugins-base
+ STANDARDS_VERSION="3.9.8"
;;
-Debian-8.*|Raspbian-8.*) # Jessie
+ Debian-8.*|Raspbian-8.*) # Jessie
+ STANDARDS_VERSION="3.9.6"
;;
-Debian-7.*|Raspbian-7) # Wheezy
+ Debian-7.*|Raspbian-7) # Wheezy
EXTRA_BUILD=libgnomeprintui2.2-dev
PYTHON_PACKAGING_DEPENDS=python-support
PYTHON_PACKAGING=dh_pysupport
TCLTK_VERSION=8.5
+ STANDARDS_VERSION="3.9.4"
;;
-Ubuntu-18.*) # Bionic Beaver
- PYTHON_GST=python-gst-1.0,gstreamer1.0-plugins-base
+ Ubuntu-1[456].*|LinuxMint-1[78]*) # Trusty through Xenial, LinuxMint 17 and 18
;;
-Ubuntu-1[456].*|LinuxMint-1[78]*) # Trusty through Xenial, LinuxMint 17 and 18
- ;;
-Ubuntu-1[12].*) # Natty Narwhal, Precise Pangolin (LTS), Quantal Quetzal
+ Ubuntu-1[12].*) # Natty Narwhal, Precise Pangolin (LTS), Quantal Quetzal
EXTRA_BUILD=libgnomeprintui2.2-dev
MODUTILS_DEPENDS=module-init-tools
PYTHON_PACKAGING_DEPENDS=python-support
PYTHON_PACKAGING=dh_pysupport
- TCLTK_VERSION=8.5
- ;;
-*)
+ TCLTK_VERSION=8.5
+ ;;
+ *)
echo "unknown distribution: $DISTRIB_NAME"
echo "detected dependencies may be incomplete or wrong"
echo "please consider fixing it and submitting a pull request"
- ;;
+ ;;
esac
TARGET_EXTRA=
@@ -351,6 +359,7 @@ sed \
-e "s#@XENOMAI_ARCHITECTURE@#$XENOMAI_ARCHITECTURE#g" \
-e "s|@YAPPS_RUNTIME@|$YAPPS_RUNTIME|g" \
-e "s#@ENABLE_BUILD_DOCUMENTATION@#$ENABLE_BUILD_DOCUMENTATION#g" \
+ -e "s#@STANDARDS_VERSION@#$STANDARDS_VERSION#g" \
-e "s#@OTHER_CONFLICTING_PACKAGES@#$OTHER_CONFLICTING_PACKAGES#g" \
-e "s#@MAIN_PACKAGE_DESCRIPTION_TEXT@#$MAIN_PACKAGE_DESCRIPTION_TEXT#g" \
-e "s#@DEV_PACKAGE_DESCRIPTION_TEXT@#$DEV_PACKAGE_DESCRIPTION_TEXT#g" \
@@ -437,7 +446,7 @@ else
fi
if [ -n "$ENABLE_BUILD_DOCUMENTATION" ]; then
- DOCS_PACKAGES=$(echo linuxcnc-doc-{en,fr,es})
+ DOCS_PACKAGES=$(echo linuxcnc-doc-{en,fr,es,cn})
for P in $DOCS_PACKAGES; do
if [ -f $EXTRAS/$P.files ]; then
cat $P.files.in $EXTRAS/$P.files > $P.files
@@ -448,5 +457,6 @@ if [ -n "$ENABLE_BUILD_DOCUMENTATION" ]; then
subst control.docs.in >> control
fi
+
rm -f ../build-stamp
echo "successfully configured for '$DISTRIB_NAME'-'$TARGET$TARGET_EXTRA'.."
diff --git a/debian/control.docs.in b/debian/control.docs.in
index 2b9cdf1b18..aeb21f8d5c 100644
--- a/debian/control.docs.in
+++ b/debian/control.docs.in
@@ -1,4 +1,3 @@
-
Package: linuxcnc-doc-en
Provides: linuxcnc-doc
Architecture: all
@@ -28,21 +27,23 @@ Provides: linuxcnc-doc
Architecture: all
Depends: ${misc:Depends}
Suggests: pdf-viewer
-Description: motion controller for CNC machines and robots (Spanish documentation)
- LinuxCNC is the next-generation Enhanced Machine Controller which
- provides motion control for CNC machine tools and robotic
- applications (milling, cutting, routing, etc.).
+Description: controlador de movimiento para máquinas CNC y robots (Español).
+ LinuxCNC es EMC (controlador de máquina mejorado) que proporciona
+ control de movimiento para máquinas herramientas CNC (fresado,
+ torneado, ruteado, etc.) y aplicaciones de robótica.
.
- This package contains the documentation in Spanish.
+ Este paquete contiene la documentación en español.
Package: linuxcnc-doc-cn
Provides: linuxcnc-doc
Architecture: all
Depends: ${misc:Depends}
Suggests: pdf-viewer
-Description: motion controller for CNC machines and robots (Chinese documentation)
+Description: motion controller for CNC machines and robots (Chinese
+ documentation)
LinuxCNC is the next-generation Enhanced Machine Controller which
provides motion control for CNC machine tools and robotic
applications (milling, cutting, routing, etc.).
.
This package contains the documentation in Chinese.
+
diff --git a/debian/control.top.in b/debian/control.top.in
index 8bd7874559..a58dd63b69 100644
--- a/debian/control.top.in
+++ b/debian/control.top.in
@@ -1,6 +1,6 @@
Source: linuxcnc
Section: misc
-Priority: extra
+Priority: optional
Maintainer: @MAINTAINER@
Build-Depends: debhelper (>= 6),
@PYTHON_PACKAGING_DEPENDS@,
@@ -33,8 +33,8 @@ Build-Depends: debhelper (>= 6),
psmisc,
desktop-file-utils,
yapps2,
- libtirpc-dev,
-Standards-Version: 3.9.2
+ libtirpc-dev
+Standards-Version: @STANDARDS_VERSION@
Vcs-Browser: https://github.com/LinuxCNC/linuxcnc
Vcs-Git: git://github.com/linuxcnc/linuxcnc.git
diff --git a/debian/extras/etc/xdg/menus/applications-merged/CNC.menu b/debian/extras/etc/xdg/menus/applications-merged/CNC.menu
index b717033cd7..43c280d017 100644
--- a/debian/extras/etc/xdg/menus/applications-merged/CNC.menu
+++ b/debian/extras/etc/xdg/menus/applications-merged/CNC.menu
@@ -22,5 +22,5 @@
X-CNC-DOC
- t>
+
diff --git a/debian/extras/lib/udev/rules.d/99-xhc-whb04b-6.rules b/debian/extras/lib/udev/rules.d/99-xhc-whb04b-6.rules
index e024d24b22..e742d8e721 100644
--- a/debian/extras/lib/udev/rules.d/99-xhc-whb04b-6.rules
+++ b/debian/extras/lib/udev/rules.d/99-xhc-whb04b-6.rules
@@ -1,3 +1,3 @@
# xhc-whb04b-6 mpg pendant
-ATTR{idProduct}=="eb93", ATTR{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="plugdev"
+SUBSYSTEM=="usb", ATTR{idProduct}=="eb93", ATTR{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="plugdev"
diff --git a/debian/extras/lib/udev/rules.d/99-xhc.rules b/debian/extras/lib/udev/rules.d/99-xhc.rules
index e8e4cada1d..9d48db338e 100644
--- a/debian/extras/lib/udev/rules.d/99-xhc.rules
+++ b/debian/extras/lib/udev/rules.d/99-xhc.rules
@@ -1,2 +1,2 @@
# xhc-hb04 mpg pendant
-ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="0666", OWNER="root", GROUP="plugdev"
+SUBSYSTEM=="usb", ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="0666", OWNER="root", GROUP="plugdev"
diff --git a/debian/extras/linuxcnc-doc-cn.files b/debian/extras/linuxcnc-doc-cn.files
new file mode 100644
index 0000000000..e5156febed
--- /dev/null
+++ b/debian/extras/linuxcnc-doc-cn.files
@@ -0,0 +1,2 @@
+usr/share/applications/linuxcnc-gettingstarted-cn.desktop
+
diff --git a/debian/extras/linuxcnc-doc-es.files b/debian/extras/linuxcnc-doc-es.files
index cc89f62af7..a0d0e5093f 100644
--- a/debian/extras/linuxcnc-doc-es.files
+++ b/debian/extras/linuxcnc-doc-es.files
@@ -1,2 +1,4 @@
usr/share/applications/linuxcnc-gettingstarted-es.desktop
+usr/share/applications/linuxcnc-documentation-es.desktop
+usr/share/applications/linuxcnc-gcoderef-es.desktop
diff --git a/debian/extras/usr/share/applications/linuxcnc-documentation-es.desktop b/debian/extras/usr/share/applications/linuxcnc-documentation-es.desktop
new file mode 100644
index 0000000000..e276115af6
--- /dev/null
+++ b/debian/extras/usr/share/applications/linuxcnc-documentation-es.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=/usr/bin/see /usr/share/doc/linuxcnc/LinuxCNC_Documentation_es.pdf
+Icon=/usr/share/icons/hicolor/scalable/apps/linuxcnc-es.svg
+X-GNOME-DocPath=
+Terminal=false
+Name=User Manual - ES
+Comment=LinuxCNC Documentation
+StartupNotify=false
+Categories=Science;X-CNC-DOC;
+Keywords=cnc;linuxcnc;
diff --git a/debian/extras/usr/share/applications/linuxcnc-gcoderef-es.desktop b/debian/extras/usr/share/applications/linuxcnc-gcoderef-es.desktop
new file mode 100644
index 0000000000..cb278fd14a
--- /dev/null
+++ b/debian/extras/usr/share/applications/linuxcnc-gcoderef-es.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=/usr/bin/x-www-browser /usr/share/doc/linuxcnc/gcode_es.html
+Icon=/usr/share/icons/hicolor/scalable/apps/linuxcnc-es.svg
+X-GNOME-DocPath=
+Terminal=false
+Name=G-Code Quick Reference - ES
+Comment=Quick reference for G, M and O codes in LinuxCNC
+StartupNotify=false
+Categories=Science;X-CNC-REF;
+Keywords=cnc;linuxcnc;
diff --git a/debian/extras/usr/share/applications/linuxcnc-gcoderef-fr.desktop b/debian/extras/usr/share/applications/linuxcnc-gcoderef-fr.desktop
index 495e7b6a67..c6c04d7310 100644
--- a/debian/extras/usr/share/applications/linuxcnc-gcoderef-fr.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-gcoderef-fr.desktop
@@ -10,3 +10,4 @@ Comment=Quick reference for G, M and O codes in LinuxCNC
StartupNotify=false
Categories=Utility;Engineering;X-CNC-DOC;
Keywords=cnc;linuxcnc;cncdoc;
+
diff --git a/debian/extras/usr/share/applications/linuxcnc-gettingstarted-cn.desktop b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-cn.desktop
new file mode 100644
index 0000000000..3aa4ef4d23
--- /dev/null
+++ b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-cn.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Name=Getting Started Guide - CN
+Type=Application
+Exec=/usr/bin/see /usr/share/doc/linuxcnc/LinuxCNC_Getting_Started_cn.pdf
+Icon=/usr/share/icons/hicolor/scalable/apps/linuxcnc-cn.svg
+X-GNOME-DocPath=
+Terminal=false
+Comment=Information on how to download and install LinuxCNC
+StartupNotify=false
+Categories=Science;X-CNC-DOC;
+Keywords=cnc;linuxcnc;
diff --git a/debian/extras/usr/share/applications/linuxcnc-gettingstarted-es.desktop b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-es.desktop
index 65ad40dca6..3337c7c130 100644
--- a/debian/extras/usr/share/applications/linuxcnc-gettingstarted-es.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-es.desktop
@@ -8,5 +8,5 @@ X-GNOME-DocPath=
Terminal=false
Comment=Information on how to download and install LinuxCNC
StartupNotify=false
-Categories=X-CNC-DOC;
+Categories=Science;X-CNC-DOC;
Keywords=cnc;linuxcnc;
diff --git a/debian/extras/usr/share/applications/linuxcnc-gettingstarted-fr.desktop b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-fr.desktop
index 4493a86cf7..59e8cd4346 100644
--- a/debian/extras/usr/share/applications/linuxcnc-gettingstarted-fr.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-gettingstarted-fr.desktop
@@ -10,3 +10,4 @@ Comment=Information on how to download and install LinuxCNC
StartupNotify=false
Categories=Utility;Engineering;X-CNC=DOC;
Keywords=cnc;linuxcnc;cncdoc;
+
diff --git a/debian/extras/usr/share/applications/linuxcnc-gettingstarted.desktop b/debian/extras/usr/share/applications/linuxcnc-gettingstarted.desktop
index ba372fa18b..0e8decc8b3 100644
--- a/debian/extras/usr/share/applications/linuxcnc-gettingstarted.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-gettingstarted.desktop
@@ -10,3 +10,4 @@ Comment=Information on how to download and install LinuxCNC
StartupNotify=false
Categories=Utility;Engineering;X-CNC-DOC;
Keywords=cnc;linuxcnc;cncdoc;
+
diff --git a/debian/extras/usr/share/applications/linuxcnc-integratorinfo.desktop b/debian/extras/usr/share/applications/linuxcnc-integratorinfo.desktop
index ab20a78565..fbaa36fbb5 100644
--- a/debian/extras/usr/share/applications/linuxcnc-integratorinfo.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-integratorinfo.desktop
@@ -9,4 +9,3 @@ Terminal=false
StartupNotify=false
Categories=Utility;Engineering;X-CNC-DOC;
Keywords=cnc;linuxcnc;cncdoc;
-Name[en_US]=Integrator Info
diff --git a/debian/extras/usr/share/applications/linuxcnc-latency.desktop b/debian/extras/usr/share/applications/linuxcnc-latency.desktop
index a4d839f364..33df68ecc6 100644
--- a/debian/extras/usr/share/applications/linuxcnc-latency.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc-latency.desktop
@@ -1,5 +1,4 @@
[Desktop Entry]
-Encoding=UTF-8
Version=1.0
Type=Application
Exec=/usr/bin/latency-test
@@ -11,3 +10,4 @@ Comment=Determine your machine's latency
StartupNotify=false
Categories=Utility;Engineering;X-CNC-DOC;
Keywords=cnc;linuxcnc;cncprog;benchmark;
+
diff --git a/debian/extras/usr/share/applications/linuxcnc.desktop b/debian/extras/usr/share/applications/linuxcnc.desktop
index 7903454e8a..e9c8ebb41b 100644
--- a/debian/extras/usr/share/applications/linuxcnc.desktop
+++ b/debian/extras/usr/share/applications/linuxcnc.desktop
@@ -1,5 +1,4 @@
[Desktop Entry]
-Encoding=UTF-8
Version=1.0
Type=Application
Exec=/usr/bin/linuxcnc
diff --git a/debian/extras/usr/share/icons/hicolor/scalable/apps/linuxcnc-logo.svg b/debian/extras/usr/share/icons/hicolor/scalable/apps/linuxcnc-logo.svg
old mode 100755
new mode 100644
diff --git a/debian/linuxcnc-doc-cn.files.in b/debian/linuxcnc-doc-cn.files.in
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/debian/linuxcnc-doc-cn.files.in
@@ -0,0 +1 @@
+
diff --git a/debian/linuxcnc.files.in b/debian/linuxcnc.files.in
index 17bcfb53fd..1ce6e6650f 100644
--- a/debian/linuxcnc.files.in
+++ b/debian/linuxcnc.files.in
@@ -21,6 +21,7 @@ usr/share/glade3
usr/share/doc/linuxcnc/asciidoc-markup.txt
usr/share/doc/linuxcnc/gcode.html
usr/share/doc/linuxcnc/gcode_fr.html
+usr/share/doc/linuxcnc/gcode_es.html
usr/share/doc/linuxcnc/gcode_vi.html
usr/share/doc/linuxcnc/rtfaults.txt
usr/share/doc/linuxcnc/AUTHORS
@@ -31,6 +32,7 @@ usr/share/doc/linuxcnc/README.axis
usr/share/doc/linuxcnc/examples/nc_files
usr/share/doc/linuxcnc/examples/sample-configs/*/*
usr/share/doc/linuxcnc/examples/sample-configs/maintainer.txt
+usr/share/doc/linuxcnc/examples/sample-configs/maintainer_es.txt
usr/share/linuxcnc/*
usr/share/linuxcnc/stepconf/*.glade
usr/share/linuxcnc/pncconf/*.glade
diff --git a/debian/rules.in b/debian/rules.in
index 5251fe4442..2f1a6e12a6 100644
--- a/debian/rules.in
+++ b/debian/rules.in
@@ -87,6 +87,8 @@ ifneq "$(enable_build_documentation)" ""
mkdir -p debian/tmp/usr/share/doc/linuxcnc-dev
mv debian/tmp/usr/share/doc/linuxcnc/LinuxCNC_Developer_Manual.pdf \
debian/tmp/usr/share/doc/linuxcnc-dev/
+ mv debian/tmp/usr/share/doc/linuxcnc/LinuxCNC_Developer_Manual_es.pdf \
+ debian/tmp/usr/share/doc/linuxcnc-dev/
endif
cp docs/html/gcode*.html debian/tmp/usr/share/doc/linuxcnc/
rm -rf debian/tmp/usr/share/doc/linuxcnc/html
@@ -144,7 +146,7 @@ binary-arch: build install
dh_makeshlibs
dh_installdeb
cat debian/@MAIN_PACKAGE_NAME@/DEBIAN/shlibs debian/shlibs.pre > debian/shlibs.local
- dh_shlibdeps -l debian/@MAIN_PACKAGE_NAME@/usr/lib
+ dh_shlibdeps -u--warnings=0 -l debian/@MAIN_PACKAGE_NAME@/usr/lib
dh_gencontrol
dh_md5sums
dh_builddeb
diff --git a/docs/INSTALL b/docs/INSTALL
index 349681892f..e102215f2d 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -45,8 +45,8 @@ in the future to recreate the current configuration, a file
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
- The file `configure.ac' is used to create `configure' by a program
-called `autoconf'. You only need `configure.ac' if you want to change
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
@@ -114,3 +114,4 @@ operates.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
+
diff --git a/docs/INSTALL_es b/docs/INSTALL_es
new file mode 100644
index 0000000000..6eb14032e7
--- /dev/null
+++ b/docs/INSTALL_es
@@ -0,0 +1,115 @@
+Descripción básica
+------------------
+Desde el directorio de nivel superior, cambie al directorio de fuentes:
+
+cd src
+
+En el directorio de fuentes, compile LinuxCNC:
+
+./autogen.sh (esto construye el script de configuración)
+./configure [--with-realtime = uspace | /usr/rtai ...]
+make clean
+make
+sudo make setuid
+
+para ejecutar el software, regrese al directorio de nivel superior y ordene:
+
+source scripts/rip-environment
+linuxcnc
+
+
+Descripción detallada
+=====================
+
+Script de tiempo de ejecución
+=============================
+
+El script de tiempo de ejecución se llama linuxcnc, lo que le permite escribir simplemente
+'linuxcnc' en una instalacion para hacerlo funcionar. En un sistema de ejecución in situ (RIP)
+(por ejemplo, el que acaba de obtener de git), el script de ejecución es scripts/linuxcnc.
+Cuando compruebe una copia nueva de LinuxCNC, verá que no hay
+'scripts/linuxcnc', solo 'scripts/linuxcnc.in'. Al ejecutar configure
+este ultimo será cambiado a 'scripts/linuxcnc'. configure también
+reemplaza algunos valores predeterminados para su sistema (carpetas, rutas, etc.).
+
+
+Script configure
+=================
+
+ El script de shell `configure 'intenta adivinar los valores correctos de
+varias variables dependientes del sistema utilizadas durante la compilación. Usa
+esos valores para crear un archivo `Makefile.inc '.
+Finalmente, crea un script de shell `config.status' que puede ejecutar
+en el futuro para recrear la configuración actual, un archivo
+`config.cache' que guarda los resultados de sus pruebas para acelerar la
+reconfiguración, y un archivo `config.log' que contiene la salida del compilador
+(útil principalmente para depurar `configure').
+
+ El archivo `configure.ac' se usa para crear `configure' mediante un programa
+llamado `autoconf'. Solo necesita `configure.ac' si desea cambiar
+o regenerar `configure' usando una versión más reciente de `autoconf'.
+
+La forma más sencilla de compilar este paquete es:
+
+ 1. `cd' al directorio que contiene el código fuente del paquete y teclee
+ `./configure' para configurar el paquete para su sistema. Si esta
+ usando `csh' en una versión anterior de System V, es posible que necesite escribir
+ `sh ./configure' en su lugar para evitar que `csh' intente ejecutar
+ `configure' en sí mismo.
+
+ Ejecutar `configure' toma un tiempo. Mientras se ejecuta, imprime algunos
+ mensajes que dicen qué características está buscando.
+
+ 2. Escriba `make' para compilar el paquete.
+
+ 3. Escriba `scripts/linuxcnc` para probar el software.
+
+
+Características opcionales
+==========================
+ LinuxCNC puede operar hardware solo si ha sido instalado un sistema de
+tiempo real. Ya sea RT-PREEMPT o RTAI. Si no tiene ninguno instalado,
+no puede ejecutar LinuxCNC para controlar ninguna máquina. Por favor instale uno
+de los parches RT (consulte la documentación del proyecto sobre cómo
+lograr eso).
+
+ Sin embargo, es posible probar LinuxCNC sin un sistema en tiempo real. Esto es
+posible utilizando un modo simulador, que no permite el control del hardware. Este es
+un modo alternativo de `uspace` en tiempo real.
+
+ Para especificar RT-PREEMPT o no-tiempo-real, use --with-realtime=uspace.
+De lo contrario, use --with-realtime=[ubicación donde rtai está instalado].
+
+Si no desea generar la documentación desde las fuentes:
+ --disable-build-documentation No compila documentación automáticamente
+
+configure también acepta otros argumentos. Use --help para ver la lista.
+
+
+Controles de operación
+======================
+
+ `configure' reconoce las siguientes opciones para controlar cómo
+opera.
+
+`--cache-file=FILE'
+ Utilizar y guardar los resultados de las pruebas en FILE en lugar de en
+ `./config.cache'. Para depuración de `configure', haga FILE como `/dev/null 'para
+ deshabilitar el almacenamiento en caché,
+
+`--help '
+ Imprime un resumen de las opciones de 'configure' y sale.
+
+`--quiet '
+`--silent '
+`-q '
+ No imprime mensajes que indiquen qué chequeos se están realizando. Para
+ suprimir toda la salida normal, redirigirla a `/dev/null' (cualquier mensaje
+ de error se mostrara todavia).
+
+`--srcdir=DIR '
+ Buscar el código fuente del paquete en el directorio DIR. Generalmente
+ `configure' puede determinar ese directorio automáticamente.
+
+`--version '
+ Imprimir la versión de Autoconf utilizada para generar el script`configure' y sale.
diff --git a/docs/README_es b/docs/README_es
new file mode 100644
index 0000000000..c65aed2a5d
--- /dev/null
+++ b/docs/README_es
@@ -0,0 +1,150 @@
+LÉAME para autores de documentos
+
+Agregar archivos:
+-----------------
+Para agregar un archivo a los documentos, se deben actualizar Submakefile, docs.xml e index.tmpl.
+
+docs.xml se usa para crear los botones "anterior" y "siguiente" en la parte superior de cada documento html individual.
+En general, los documentos debe coincidir con el orden de index.tmpl
+
+Notas sobre la documentación de LinuxCNC:
+-----------------------------------------
+El archivo makefile principal de LinuxCNC puede construir opcionalmente la documentación y
+otros archivos en este árbol de directorios. Utilice --enable-build-documentation cuando
+invoque src/configure, y ejecute make desde ../src
+
+Notas sobre los dibujos:
+------------------------
+
+-N.T. Muchos de los inconvenientes que aqui se comentan estan superados en las versiones
+actuales de los correspondientes programas.N.T.-
+
+Muchos de los documentos incluyen dibujos. La mayoría de ellos fueron creados
+originalmente con EasyCad, una aplicación de Windows no gratuita, y luego exportados a archivos .eps
+e incluido en los documentos. Los archivos originales 'fuente' (formato EasyCad .FC7)
+no se podían usar en un sistema gratuito. Para solucionar este problema, todos
+los archivos fuente se han convertido a archivos .dxf y se han agregado a git.
+Los archivos .dxf pueden editarse con diferentes paquetes CAD y servir como
+archivos 'fuente' para futuros cambios en los dibujos. Se pueden convertir
+de .dxf a postscript (no .eps) usando Qcad, que está disponible como
+paquete ubuntu (y creo que también está disponible para debian).
+
+Desafortunadamente, EasyCad (y AutoCad) admiten varias entidades
+que Qcad no importa correctamente, incluyendo algunos que fueron utilizados
+en los dibujos de LinuxCNC; círculos rellenos, puntas de flecha rellenas,
+líneas de ancho no nulos y líneas discontinuas. Qcad representa círculos rellenos como
+huecos, hace que todas las líneas tengan el mismo ancho, y se hace lineas de puntos
+como sólidas, a menos que le diga que haga lo contrario. Todos estas
+cosas hacen que los dibujos sean menos atractivos, pero son aceptables.
+Sin embargo, Qcad no importa puntas de flecha rellenas en absoluto,
+lo que daña seriamente los dibujos. Así que se usó EasyCad para convertir
+las puntas de flecha a huecas antes de exportarlas. Las puntas de flecha huecas
+no se ven tan bonitas como las sólidas, pero al menos son visibles.
+
+Una vez exportadas, las puntas de flecha pierden su relación con la línea correspondiente
+y deben moverse y/o girarse manualmente si la línea se ha
+movido. Creo que incluso si fueran importados de nuevo a EasyCad,
+la conexión línea/flecha permanecería rota. Nuevas líneas con
+las puntas de flecha se pueden crear en Qcad con la herramienta de dimensión 'líder'.
+
+Debido a que los archivos EPS originales con líneas llenas y círculos, líneas anchas,
+y las líneas punteadas se ven mucho mejor, permanecerán en git y probablemente deberían
+usarse para los documentos. Sin embargo, si se vuelven inexactos
+debido a cambios en el software, tendremos que editar los archivos DXF,
+generar postscript, y usar imágenes menos bonitas pero correctas.
+
+Dado que Qcad en sí es una aplicación GUI, la conversión dxf a postscript
+implica hacer clicks en ventanas, y no se puede automatizar y formar parte de
+makefile. Además, no todos tendrán Qcad instalado en su sistema.
+Por lo tanto, almacenaremos los archivos DXF y los archivos postscript resultante
+en git, y el proceso normal de creación de documentación usará
+archivos postscript solamente. La edicion de archivos dxf necesitará
+la conversion manual a PostScript. El procedimiento de conversión es como
+sigue:
+
+comenzar qcad
+Archivo-> Abrir-> elegir archivo dxf
+el dibujo aparece en la ventana
+Editar-> CurrentDrawingPreferences-> Paper
+establecer el tamaño del papel a "carta", establecer la orientación a "paisaje" o "retrato"
+ dependiendo de la relación de aspecto del dibujo
+Archivo-> Vista Previa Impresion
+haga clic en el botón "ajustar a la página" en la barra de herramientas (último botón a la derecha en
+ menos en la versión 2.0.4.0 de qcad)
+Archivo-> Imprimir
+ seleccionar "imprimir en archivo"
+ establecer la ruta para que apunte al mismo directorio que el archivo .dxf fuente
+ establecer el nombre como el mismo que el archivo de origen, pero .ps en lugar de .dxf
+ haga clic en Aceptar
+
+Los fabricantes de Qcad también tienen un convertidor de formato GPL llamado vec2web,
+que puede hacer la conversión dxf a postscript desde la línea de comando. Esto
+no está disponible como un paquete precompilado, pero está disponible en http://www.ribbonsoft.com/vec2web.html
+
+vec2web depende de los paquetes de desarrollo qt3 para la compilación, por lo que no debería
+ser una dependencia para construir los documentos de LinuxCNC. Pero si configure puede
+detectarlo, sería bueno automatizar la conversión de dxf a ps para aquellos
+sistemas donde está instalado vec2web.
+
+Para construir vec2web, ejecutar apt-get install qt3-dev-tools
+El archivo tar de vec2web contiene un script de compilación, pero antes de ejecutarlo
+debe configurar $QTDIR para que apunte a la instalación de QT3; en mi caso fue
+ export QTDIR=/usr/share/qt3
+A continuación, ejecutar el script de compilación:
+ ./build_vec2web.sh
+No hay un paso de instalación, el ejecutable se descarga en el directorio de compilación.
+Tampoco hay una página man, pero al ejecutarla sin argumentos imprime las siguiente
+instrucciones de uso:
+
+
+Uso: vec2web [opciones]
+Donde las opciones son:
+ -x # tamaño x máximo para el mapa de bits de salida en píxeles
+ -y # tamaño máximo y para el mapa de bits de salida en píxeles
+ -b negro/blanco en lugar de usar colores
+ -o [l|p]orientación para salida PS (horizontal o vertical)
+ -s .. tamaño de página para salida PS (A4, A5)
+
+p.ej. vec2web drawing.dxf drawing.png
+ convierte drawing.dxf en un gráfico .png
+
+
+Mis intentos iniciales de usar vec2web dieron como resultado la conversion de
+las partes gráficas del dibujo, pero todo el texto se perdió. No sé si
+vale la pena pasar mucho más tiempo con vec2web, sin embargo, es GPL e incluye una
+biblioteca para leer archivos DXF que podría ser una cosa que vale la pena a la
+comunidad LinuxCNC.
+
+Dibujos de QCad
+-------------------
+Guardar como .dxf en el mismo directorio que la imagen
+Establecer grosor de línea a 0.50 mm
+Exportar imagen con resolución 480 x 480 Auto .png
+
+
+Cómo agregar un nuevo idioma de traducción
+-------------------------------------
+
+Agregue los archivos de origen asciidoc que contendrán su nueva traducción.
+Por lo general, eso significa copiar los archivos de idioma de uno de los idiomas
+existentes, probablemente inglés ya que suele ser el más actualizado.
+
+Agregue los archivos nuevos al lugar correcto en docs/src/Submakefile, para asegurar
+que se construirán.
+
+Edite debian/control.in para agregar el nuevo paquete linuxcnc-doc-$NEWLANG.
+Agregue el nuevo paquete de documentos a la lista "or" de la línea Recommends del
+paquete linuxcnc/linuxcnc-sim.
+N.T. Actualmente, control.in esta dividido en control.top.in y control.bottom.in, siendo
+este ultimo el que contiene los parrafos Package:
+
+Agregue el nuevo idioma a la lista en la variable DOCS_PACKAGES en debian/configure.
+Si hay un paquete texlive-lang-$NEWLANGUAGE para su nuevo idioma,
+agréguelo a todas las líneas EXTRA_BUILD apropiadas en debian/configure.
+N.T La variable que contiene los texlive-lang-$NEWLANGUAGE es DOC_DEPENDS
+
+Agregue el archivo 'linuxcnc-doc-$NEWLANG.files.in' al nuevo paquete, probablemente
+copiando y editando "debian/linuxcnc-doc-en.files.in".
+
+¡Pruebe a construir los paquetes y verifiquelos!
+
diff --git a/docs/archive/UPDATING b/docs/archive/UPDATING
index b172c052a5..d980ad2142 100644
--- a/docs/archive/UPDATING
+++ b/docs/archive/UPDATING
@@ -1,3 +1,8 @@
+NOTA DE TRADUCCION:
+ESTE DOCUMENTO SE REFIERE A VERSIONES ANTIGUAS
+NO PROCEDE TRADUCCION
+
+
This file describes needed steps to update configurations from 2.2.x to 2.3
1. Classicladder changes
diff --git a/docs/help/asciidoc-markup.txt b/docs/help/asciidoc-markup.txt
index 816fbe435c..26c8907501 100644
--- a/docs/help/asciidoc-markup.txt
+++ b/docs/help/asciidoc-markup.txt
@@ -1,121 +1,121 @@
-This document is a guide for using asciidoc markup
+Este documento es una guía para usar el marcado de asciidoc
-Master Document file Headers, first line replace en with two letter language code
----------------------------------------------------------------------------------
+Encabezados de archivo de documento maestro, primera línea reemplazar "en" con su código de idioma de dos letras
+----------------------------------------------------------------------------------------------------------------
:lversion: {sys: cat ../VERSION}
-Getting Started V{lversion}, {localdate}
-=================================
-:lang: en
+Comenzar V{lversion}, {localdate}
+===============================
+:lang:en
:masterdir: {indir}
:leveloffset: 1
-The EMC Team
+El equipo de EMC
-The parameters are interpreted well before the load files lang-xx.conf and the other files .conf
-It is particularly important for the parameters as :lang:
+Los parámetros se interpretan antes de que se cargen los archivos lang-xx.conf y los demás archivos .conf
+Es particularmente importante para los parámetros como :lang:
-The typical authorized attributes : doctype, lang, encoding, icons, data-uri, toc, numbered
+Los atributos típicos autorizados son: doctype, lang, encoding, icons, data-uri, toc, numbered
-More information here
+Más información aquí
http://www.methods.co.nz/asciidoc/userguide.html#_introduction
8.2 Header
-Titles
-======
-= Document Title (level 0) = Note: level 0 can only be once per file!
-== Section title (level 1) == Note: trailing delimiter is optional.
-=== Section title (level 2) ===
-.Third level Title
+Títulos
+=======
+= Título del documento (nivel 0) = Nota: ¡el nivel 0 solo puede estar una vez por archivo!
+== Título de la sección (nivel 1) == Nota: el delimitador final es opcional.
+=== Título de la sección (nivel 2) ===
+.Tercer nivel de título
-Links
-=====
+Enlaces
+=======
[[anchor]]
-<>
+<>
-Example document link
+Ejemplo de enlace de documento
[[sub:torpodeos]]
-<>
+<>
-only bombs will show in the text with an underline so always provide a caption
-for a link.
+solo se mostrará "bombas" en el texto con un subrayado, así que siempre proporcione una leyenda
+para un enlace.
-External link
-http://linuxnc.org/someplace[description of link]
+Enlace externo
+http://linuxnc.org/someplace[descripcion del link]
-Comment Block
-=============
+Bloque de comentarios
+=====================
////
-Use: hide comments
+Uso: ocultar comentarios
////
-Listing Block for G Code and terminal output
-============================================
----- < 4 dashes start of block
-lines of code
+Bloque de listado para código G y salida por terminal
+=====================================================
+---- <4 guiones comienzan un bloque
+líneas de código
...
-more code
----- < 4 dashes end of block
- < 1 blank line after
-
-Literal blocks
-==============
-.... < 4 periods start the block
-literal block
-will show up
-just as you type it.
-.... < 4 periods end the block
- < 1 blank line after
-
-Lists
-=====
+mas codigo
+---- <4 guiones finalizan el bloque
+ <1 después, línea en blanco
+
+Bloques literales
+=================
+.... <4 puntos comienzan el bloque
+Un bloque literal
+aparecerá
+tal como lo escribe.
+.... <4 puntos terminan el bloque
+ <1 después, línea en blanco
+
+Listas
+======
* bullet
** bullet
. numbered
.. numbered
-List Item Continuation
-* List item paragaph one
- continued with a single plus hard left.
+Continuacion de Lista de elementos
+* Parrafo uno de la lista de elementos
+ continuado con un signo + ajustado a la izquierda.
+
-List item one continued
- with a second paragraph
- and first line of second paragraph must be hard left.
+El elemento de lista uno continua
+ con un segundo párrafo
+ y la primera línea del segundo párrafo estar ajustada a la izquierda.
-HAL pins and parameters use the following format for consistency
-* 'parport.
.pin--out' (bit) Drives a physical output pin.
-bulleted list with the pin name emphasized by surrounding it with
-single quotes.
+Para ser consistentes, los pines y parámetros HAL usaran el siguiente formato
+* 'parport.
.pin--out' (bit) Maneja un pin de salida física.
+lista con bullets con el nombre del pin enfatizado rodeándolo con
+comillas simples.
-Images
-======
-put all images in the images subdirectory
+Imágenes
+========
+poner todas las imágenes en el subdirectorio de imágenes
-image::[]
+image::[]
-example
+ejemplo
image::images/axis.png[]
-image::images/tiger.png["Tiger image",align="center"]
+image::images/tiger.png["Imagen de tigre",align="center"]
-If the image is small and displays too big in the pdf you can
-use the scaledwidth="60%" attribute
+Si la imagen es pequeña y se muestra demasiado grande en un pdf, puede
+usar el atributo scaledwidth="60%"
-Inline Images
-=============
-Same as images except only one : is used and no attributes are used between
-the []
+Imágenes en línea
+=================
+Igual que imágenes excepto que solo se usa un : y no se usan atributos entre
+los []
-My text has an image in it image:images/axisbutton.png[]
+Mi texto tiene una imagen en el image:images/axisbutton.png[]
-Figures
+Figuras
=======
-Use the following format for figures so any links to the anchor will move to
-correct place. Only create a link to a figure if it is somewhere else and not
-the next thing you see when scrolling down. Just say something like "in the
-following figure..."
+Utilice el siguiente formato para las figuras de modo que los enlaces al ancla se moverán a
+lugar correcto. Solo cree un enlace a una figura si está en otro lugar y no en
+lo siguiente que se vea en un scroll hacia abajo. Diga algo como "en la
+siguiente figura... "
[[fig:Parport-block-diag]]
@@ -123,20 +123,21 @@ following figure..."
image::images/parport-block-diag.png[align="center"]
-Notes and Warnings
-==================
-Inline example
-NOTE: This is an example note.
+Notas y Advertencias
+====================
+Ejemplo en línea
+NOTA: Esta es un ejemplo de nota.
-Paragraph example
+Ejemplo de párrafo
[NOTE]
-This is an example note of the
-paragraph style.
+Esta es una nota de ejemplo de
+estilo de párrafo.
-Styles include
+Los estilos incluyen
NOTE TIP IMPORTANT WARNING CAUTION
-Tables
+
+Tablas
======
[options="header, width="80%"]
|=======
@@ -145,17 +146,17 @@ Tables
|5 |6 |C
|=======
-Escaping a character
-====================
-Normally characters like ' and * would not print unless you use \' or \* then
-they will print as normal characters.
+Escapar un caracter
+======================
+Normalmente los caracteres como ' y * no se imprimirían a menos que use \' o \* y entonces
+se imprimirán como caracteres normales.
-Making a horizontal labeled list.
+Hacer una lista etiquetada horizontal.
[horizontal]
-Label:: The text about the label
+Label:: El texto acerca de la etiqueta
-Latexmath is broken at the moment and trashes the HTML. A work around is to use open office math
-to create the math image and gimp to screen capture and save to a png.
+Latexmath no funciona en este momento y destruye el HTML. Una solución alternativa es utilizar Open Office Math (o LibreOffice)
+para crear la imagen matemática y gimp para la captura de pantalla y guardarla en un png.
-check asciidoc cheatsheet http://powerman.name/doc/asciidoc or user manual
-http://www.methods.co.nz/asciidoc/userguide.html for details about format.
+compruebe la hoja de referencia de asciidoc http://powerman.name/doc/asciidoc o el manual del usuario
+http://www.methods.co.nz/asciidoc/userguide.html para detalles sobre el formato.
diff --git a/docs/help/rtfaults.txt b/docs/help/rtfaults.txt
index e58bde4d03..21e660e0ed 100644
--- a/docs/help/rtfaults.txt
+++ b/docs/help/rtfaults.txt
@@ -1,43 +1,43 @@
-Finding line number information for faults in realtime components
+Encontrar información del número de línea para fallos en componentes de tiempo real
-1. Get a version of LinuxCNC which prints the faulting instruction address
- (that includes this version of LinuxCNC)
+1. Obtenga una versión de LinuxCNC que imprima la dirección de instrucción que falla
+ (se incluye en esta versión de LinuxCNC)
-2. Include debugging info in your modules. For built-in modules,
- below the definition of EXTRA_CFLAGS in Makefile, add
+2. Incluya información de depuración en sus módulos. Para módulos incorporados,
+ debajo de la definición de EXTRA_CFLAGS en Makefile, agregue
EXTRA_CFLAGS += -g
- For standalone modules, add the same line just above the line
+ Para módulos independientes, agregue la misma línea justo encima de la línea
ifeq ($(BUILDSYS),kbuild)
- and (re)build the component
+ y (re)compile el componente
-3. Run hal until the fault occurs. DO NOT EXIT THE HAL SESSION YET. You
- must find the start of the module (step 5) first.
+3. Ejecute hal hasta que ocurra el fallo. NO SALGA DE LA SESIÓN HAL TODAVÍA.
+ Primero se debe encontrar el inicio del módulo (paso 5).
-4. Note the ip (instruction pointer) address in dmesg. e.g.:
+4. Anote la dirección IP (puntero de instrucción) en dmesg. p.ej.:
RTAPI: Task 1[c2800000]: Fault with vec=14, signo=11 ip=c93dc01a.
^^^^^^^^
-5. Find the module which contains the offending IP.
- $cat /proc/modules
+5. Encuentra el módulo que contiene la IP que provoca el fallo.
+ $ cat /proc/modules
motmod 142230 0 - Live 0xc93df000
- fault 1626 1 motmod, Live 0xc93dc000
+ falla 1626 1 motmod, Live 0xc93dc000
hal_lib 30517 2 motmod,fault, Live 0xc93d5000
- Now you can exit hal/emc2.
+ Ahora puedes salir de hal/emc2.
-6. Subtract the start of the module from the faulting ip (in this case, 0x1a)
- Among other ways to do this, you can use the shell:
+6. Reste el inicio del módulo de la IP con fallo (en este caso, 0x1a)
+ Entre otras formas de hacer esto, puedes usar el shell:
$ printf "0x%x\n" $((0xc93dc01a-0xc93dc000))
0x1a
-7. Use addr2line to find out the source code line:
+7. Use addr2line para descubrir la línea del código fuente:
$ addr2line -e emc2-dev/src/fault.ko 0x1a
/usr/src/linux-headers-2.6.32-122-rtai/hal/components/fault.comp:9
- Ignore how the directory name is wrong and see whether this has helped you
- localize the problem:
+ Ignora cómo el nombre del directorio es incorrecto y mira si esto te ayudó
+ localizar el problema:
fault.comp:9 *(int*)0 = 0;
- Yup! Looks like it has.
+ ¡Si! Parece que era eso.
- Note that even if you do not prefix the address argument to addr2line
- with 0x, it is taken to be a hex number, and you'll get the wrong
- line-number information. Take care to always use hex addresses with
- addr2line.
+ Tenga en cuenta que incluso si no agrega el argumento de dirección a addr2line
+ con 0x, se espera un número hexadecimal, y obtendrá un error
+ en la información del número de línea. Tenga cuidado de usar siempre direcciones
+ hexadecimales con addr2line.
\ No newline at end of file
diff --git a/docs/html/gcode_es.html b/docs/html/gcode_es.html
new file mode 100644
index 0000000000..3524cf857f
--- /dev/null
+++ b/docs/html/gcode_es.html
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+Referencia Rápida "G-Code" LinuxCNC
+
+
+
+
+
+
diff --git a/docs/man/.gitignore b/docs/man/.gitignore
index a992618dba..e5190abb14 100644
--- a/docs/man/.gitignore
+++ b/docs/man/.gitignore
@@ -11,19 +11,20 @@ man1/svd-ps_vfd.1
man1/linuxcnc.1
man1/halstreamer.1
man1/thermistor.1
+man1/wj200_vfd.1
man1/xhc-whb04b-6.1
-man9/abs.9
man9/abs_s32.9
+man9/abs.9
man9/and2.9
+man9/axistest.9
man9/bin2gray.9
man9/biquad.9
man9/bitslice.9
man9/bitwise.9
man9/bldc.9
-man9/bldc_hall3.9
-man9/bldc_sine.9
man9/blend.9
+man9/carousel.9
man9/charge_pump.9
man9/clarke2.9
man9/clarke3.9
@@ -60,14 +61,22 @@ man9/conv_u8_float.9
man9/conv_u8_s32.9
man9/conv_u8_s8.9
man9/conv_u8_u32.9
+man9/corexy_by_hal.9
+man9/dbounce.9
man9/ddt.9
man9/deadzone.9
+man9/demux.9
+man9/differential.9
man9/edge.9
+man9/eoffset_per_angle.9
man9/estop_latch.9
man9/feedcomp.9
+man9/filter_kalman.9
man9/flipflop.9
+man9/gantry.9
man9/gearchange.9
man9/gray2bin.9
+man9/histobins.9
man9/hypot.9
man9/ilowpass.9
man9/integ.9
@@ -84,10 +93,13 @@ man9/lowpass.9
man9/lut5.9
man9/maj3.9
man9/match8.9
+man9/max31855.9
man9/mesa_7i65.9
+man9/mesa_pktgyro_test.9
man9/mesa_uart.9
man9/message.9
man9/minmax.9
+man9/moveoff.9
man9/mult2.9
man9/multiclick.9
man9/multiswitch.9
@@ -98,18 +110,27 @@ man9/mux8.9
man9/near.9
man9/not.9
man9/offset.9
+man9/ohmic.9
man9/oneshot.9
man9/or2.9
man9/orient.9
man9/pcl720.9
+man9/plasmac.9
man9/pluto_servo.9
man9/pluto_step.9
man9/sample_hold.9
man9/scale.9
man9/select8.9
man9/serport.9
+man9/sim_axis_hardware.9
+man9/sim_home_switch.9
+man9/sim_matrix_kb.9
+man9/sim_parport.9
man9/sim_spindle.9
+man9/simple_tp.9
man9/sphereprobe.9
+man9/spindle_monitor.9
+man9/spindle.9
man9/steptest.9
man9/streamer.9
man9/sum2.9
@@ -119,12 +140,11 @@ man9/threadtest.9
man9/time.9
man9/timedelay.9
man9/timedelta.9
-man9/toggle2nist.9
man9/toggle.9
+man9/toggle2nist.9
man9/tristate_bit.9
man9/tristate_float.9
man9/updown.9
man9/wcomp.9
-man9/wj200_vfd.9
man9/xhc_hb04_util.9
man9/xor2.9
diff --git a/docs/man/es/man1/axis-remote.1 b/docs/man/es/man1/axis-remote.1
new file mode 100644
index 0000000000..77cf42d2b4
--- /dev/null
+++ b/docs/man/es/man1/axis-remote.1
@@ -0,0 +1,79 @@
+.\" Copyright (c) 2007 Alex Joni
+.\" (alex_joni AT users DOT sourceforge DOT net)
+.\" Spanish translation by: J.M. Garcia (2018)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH axis-remote "1" "2007-04-01" "Documentacion de LinuxCNC" "The Enhanced Machine Controller"
+.SH NOMBRE
+axis\-remote \- Interface remota AXIS
+.SH SINOPSIS
+.B axis\-remote \fIOPCIONES\fR|\fINOMBREFICHERO\fR
+.SH DESCRIPCION
+\fBaxis\-remote\fR es un peque\[~n]o script que activa comandos en una GUI AXIS en ejecucion.
+.TP
+Use \fBaxis\-remote \-\-help\fR para mas informacion.
+.SH OPCIONES
+.TP
+\fB\-\-ping\fR, \fB\-p\fR
+Chequea si se esta ejecutando AXIS.
+.TP
+\fB\-\-reload\fR, \fB\-r\fR
+Hace que AXIS recargue el archivo actual.
+.TP
+\fB\-\-clear\fR, \fB\-c\fR
+Hace que AXIS limpie el area grafica.
+.TP
+\fB\-\-quit\fR, \fB\-q\fR
+Salida de AXIS.
+.TP
+\fB\-\-help\fR, \fB\-h\fR, \fB\-?\fR
+Muestra la lista de parametros validos para \fBaxis\-remote\fR.
+.TP
+\fB\-\-mdi COMANDO\fR, \fB\-m COMANDO\fR
+Ejecuta el \fBCOMANDO\fR en MDI.
+.TP
+\fBNOMBREFICHERO\fR
+Carga el fichero de codigo G \fBNOMBREFICHERO\fR.
+.SH "VEA TAMBIEN"
+\fBaxis(1)\fR
+
+Los manuales de LinuxCNC y HAL tienen mucha mas informacion disponible.
+.TP
+Puede encontrarlos en /usr/share/doc/linuxcnc/.
+
+.SH HISTORIA
+
+.SH BUGS
+En este momento, ninguno conocido.
+.PP
+.SH AUTOR
+Esta pagina man fue escrita por Alex Joni, como parte del proyecto LinuxCNC.
+.SH COMUNICACION DE BUGS
+Comunicar errores a alex_joni AT users DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2007 Alex Joni.
+.br
+Este software es libre; vea las fuentes para las condiciones de copia. NO hay garantia;
+ni para COMERCIABILIDAD, ni para APTITUD PARA UN USO PARTICULAR
+
diff --git a/docs/man/es/man1/axis.1 b/docs/man/es/man1/axis.1
new file mode 100644
index 0000000000..3ee86aa668
--- /dev/null
+++ b/docs/man/es/man1/axis.1
@@ -0,0 +1,66 @@
+.\" Copyright (c) 2007 Alex Joni
+.\" (alex_joni AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH AXIS "1" "2007-04-01" "Documentacion de LinuxCNC" "The Enhanced Machine Controller"
+.SH NOMBRE
+axis \- Interface grafica de usuario para LinuxCNC
+.SH SINOPSIS
+.B axis
+\fI\-ini\fR \fIFICHEROINI\fR
+.SH DESCRIPCION
+\fBaxis\fR es una de las interfaces graficas de usuario (GUI) para LinuxCNC
+Se ejecuta usualmente desde un script.
+.SH OPCIONES
+.TP
+\fBFICHEROINI\fR
+el archivo ini es la pieza principal de una configuracion de LinuxCNC.
+No es toda la configuracion; hay otros archivos que lo acompa\[~n]an
+(archivos NML, HAL, TBL, VAR, etc). Sin embargo, es el mas importante,
+porque es el archivo que mantiene la configuracion unida.
+Puede ajustar muchos parametros por si mismo, pero tambien le dice
+a \fBLinuxCNC\fR que otros archivos cargar y usar.
+
+.SH "VEA TAMBIEN"
+\fBLinuxCNC(1)\fR
+
+Los manuales de LinuxCNC y HAL tienen mucha mas informacion disponible.
+.TP
+Puede encontrarlos en /usr/share/doc/linuxcnc/.
+
+.SH HISTORIA
+
+.SH BUGS
+En este momento, ninguno conocido.
+.PP
+.SH AUTOR
+Esta pagina man fue escrita por Alex Joni, como parte del proyecto LinuxCNC.
+.SH COMUNICACION DE BUGS
+Comunicar errores a alex_joni AT users DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2007 Alex Joni.
+.br
+Este software es libre; vea las fuentes para las condiciones de copia. NO hay garantia;
+ni para COMERCIABILIDAD, ni para APTITUD PARA UN USO PARTICULAR
+
diff --git a/docs/man/es/man1/elbpcom.1 b/docs/man/es/man1/elbpcom.1
new file mode 100644
index 0000000000..446e52c176
--- /dev/null
+++ b/docs/man/es/man1/elbpcom.1
@@ -0,0 +1,90 @@
+.\" Copyright (C) 2015 Jeff Epler
+.TH LinuxCNC "1" "2015-04-18" "Documentacion de LinuxCNC" ""
+.SH NOMBRE
+elbpcom \- Comunicacion con tarjetas Mesa ethernet
+.SH SINOPSIS
+Opciones comunes:
+.RS
+.SY elbpcom
+.BI [\-\-ip= IP ]
+.BI [\-\-port= PORT ]
+.BI [\-\-timeout= TIMEOUT ]
+.RE
+
+Lectura de datos:
+.RS
+.SY elbpcom
+.BI [ opciones\ comunes ]
+.BI \-\-space= SPACE
+.B [\-\-info]
+.BI \-\-address= ADDRESS
+.BI \-\-read= LENGTH
+.RE
+
+Escritura de datos:
+.RS
+.SY elbpcom
+.BI [ opciones\ comunes ]
+.BI \-\-space= SPACE
+.BI \-\-address= ADDRESS
+.BI \-\-write= HEXDATA
+.RE
+
+Envio de paquetes arbitrarios:
+.RS
+.SY elbpcom
+.BI [ opciones\ comunes ]
+.I HEXDATA
+.RE
+
+.SH DESCRIPCION
+Lee o escribe datos de una tarjeta Ethernet de Mesa que use el protocolo LBP16,
+como la 7i80. Esto puede ser util para realizar ciertas tareas de bajo nivel.
+
+Para obtener mas informacion sobre el significado de cada espacio de direcciones,
+consulte la documentacion de la tarjeta. El uso incorrecto de esta utilidad puede
+tener efectos negativos, como cambiar la direccion IP de la placa o incluso da\[~n]ar
+el archivo de bits FPGA en la eeprom. Para algunas tareas, como actualizar archivos
+de bits FPGA y configurar direcciones IP,
+.BR mesaflash (1)
+es una herramienta mas apropiada.
+
+Si no se especifican, los valores por defecto son:
+.RS
+.BI \-\-ip= 192.168.1.121
+.BI \-\-port= 27181
+.BI \-\-timeout= .2
+.RE
+
+Este ejemplo demuestra la lectura de HOSTMOT2 identificando cadenas desde
+la IDROM en espacio 0:
+.RS
+.nf
+$ elbpcom \-\-space 0 \-\-address 0x104 \-\-read 8
+> 82420401
+< 484f53544d4f5432
+ HOSTMOT2
+.fi
+.RE
+Primero se muestra la solicitud en hexadecimal. Despues, la respuesta (si la hay)
+se muestra en hexadecimal. Finalmente, la respuesta se muestra en ASCII, con "."
+reemplazando cualquier caracter no ASCII. Esto es similar a las siguientes
+invocaciones de mesaflash:
+.RS
+.nf
+$ ./mesaflash \-\-device 7i80 \-\-rpo 0x104
+54534F48
+$ ./mesaflash \-\-device 7i80 \-\-rpo 0x108
+32544F4D
+.fi
+.RE
+Pero notese el diferente tratamiento de orden de bytes.
+
+.SH SEE ALSO
+.BR mesaflash (1),
+.BR hostmot2 (9),
+.BR hm2_eth (9),
+.UR http://www.mesanet.com
+Documentacion de Mesa para tarjetas Anything I/O
+.UE .
+
diff --git a/docs/man/es/man1/gladevcp.1 b/docs/man/es/man1/gladevcp.1
new file mode 100644
index 0000000000..00cefcdae0
--- /dev/null
+++ b/docs/man/es/man1/gladevcp.1
@@ -0,0 +1,79 @@
+.\" Copyright (c) 2007 Michael Haberler
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.TH GLADEVCP "1" "2010-12-20" "Documentacion de LinuxCNC" "The Enhanced Machine Controller"
+.SH NOMBRE
+gladevcp \- Panel de Control Virtual para LinuxCNC basado en widgets Glade, Gtk y HAL
+.SH SINOPSIS
+\fBgladevcp\fR [\-g \fIWxH+X+Y\fR] [\-c \fInombre-componente\fR] [\-u \fIhandler\fR] [\-U \fIopcionusuario\fR] [\-H \fIficheroHAL\fR] [\-d] \fImifichero.ui\fR
+.SH OPCIONES
+.TP
+\fB\-g\fR \fIWxH+X+Y\fR
+Establecer la geometria inicial de la ventana raiz.
+Use 'WxH' para el tama\[~n]o, '+ X + Y' para la posicion, o 'WxH+X+Y' para ambos.
+Tama\[~n]o / posicion utilizan unidades de pixeles. La posicion esta referenciada desde la parte superior izquierda.
+.TP
+\fB\-c\fR \fInombre-componente\fR
+Use \fInombre-componente\fR como el nombre del componente HAL. Si el nombre del componente no se especifica, se usa
+el nombre base del fichero .ui. \fR
+.TP
+\fB\-u\fR \fIhandler\fR
+Instruye a gladevcp para inspeccionar el script Python \fIhandler\fR para manejadores de eventos
+y los conecta a se\[~n]ales en el fichero .ui.\fR
+.TP
+\fB\-U\fR \fIopcionusuario\fR
+gladevcp colecciona todas las cadenas \fIopcionusuario\fR y las pasa al metodo del manejador init()
+como una lista de cadenas, sin mas inspeccion.\fR
+.TP
+\fB\-x\fR \fIXID\fR
+Hace de una ventana \fIXID\fR existente la ventana padre de gladevcp, en lugar de crear una ventana
+nueva de nivel superior.\fR
+.TP
+\fB\-H\fR \fIficheroHAL\fR
+gladevcp ejecuta \fIficheroHAL\fR - una lista de comandos HAL - mediante \fIhalcmd \-c ficheroHAL\fR
+despues de la finalizacion del componente HAL.\fR
+
+.TP
+\fB\-d\fR
+activa la salida debug.
+
+.TP
+\fB\-R\fR \fIgtkrcfile\fR
+carga explicitamente un fichero gtkrc.\fR
+
+.TP
+\fB\-t\fR \fITHEME\fR
+Establece un tema gtk. El tema por defecto es \fIsystem\fR. Diferentes paneles pueden tener diferentes temas.
+
+.TP
+\fB\-m\fR \fIMAXIMUM\fR
+fuerza el maximizado de la ventana de panel. Junto con la opcion \fI\-g geometry\fR
+puede mover el panel a un segundo monitor y forzarlo a usar toda la pantalla.
+
+.TP
+\fB\-R\fR
+desactivar explicitamente la solucion para el error gtk que hace coincidir widgets y widget_class en el tema
+gtk y fallos de los archivos gtkrc. Normalmente no es necesario.
+
+.SH "VER TAMBIEN"
+\fIGladeVCP\fR en la documentacion de LinuxCNC para una descripcion de las capacidades de gladevcp
+y el conjunto de widgets HAL asociados, junto con ejemplos.
+
diff --git a/docs/man/es/man1/gs2.1 b/docs/man/es/man1/gs2.1
new file mode 100644
index 0000000000..e46090d83d
--- /dev/null
+++ b/docs/man/es/man1/gs2.1
@@ -0,0 +1,183 @@
+.\" Copyright (c) 2009 John Thornton
+.\" (jet1024 AT semo DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH gs2_vfd "1" "January 1, 2009" "GS2 VFD" "LinuxCNC Documentation"
+
+.SH NAME
+\fBgs2_vfd\fR \- HAL userspace component for Automation Direct GS2 VFD's
+
+.SH SYNOPSIS
+.B gs2_vfd
+.RI [OPTIONS]
+.br
+
+.SH DESCRIPTION
+This manual page explains the
+.B gs2_vfd
+component. This component reads and writes to the GS2 via a modbus connection.
+.PP
+\fBgs2_vfd\fP is for use with LinuxCNC
+
+.SH OPTIONS
+.B
+.IP \-b,\ \-\-bits\
+(default 8) Set number of data bits to , where n must be from 5 to 8 inclusive
+.B
+.IP \-d,\ \-\-device\
+(default /dev/ttyS0) Set the name of the serial device node to use.
+.B
+.IP \-v,\ \-\-verbose
+Turn on verbose mode.
+.B
+.IP \-g,\ \-\-debug
+Turn on debug messages. Note that if there are serial errors, this may
+become annoying. Debug mode will cause all modbus messages to be printed
+in hex on the terminal.
+.B
+.IP \-n,\ \-\-name\
+(default gs2_vfd) Set the name of the HAL module. The HAL comp name will be set to , and all pin and parameter names will begin with .
+.B
+.IP \-p,\ \-\-parity\ [even,odd,none]
+(default odd) Set serial parity to even, odd, or none.
+.B
+.IP \-r,\ \-\-rate\
+(default 38400) Set baud rate to . It is an error if the rate is not one of the following: 110, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
+.B
+.IP \-s,\ \-\-stopbits\ [1,2]
+(default 1) Set serial stop bits to 1 or 2
+.B
+.IP \-t,\ \-\-target\
+(default 1) Set MODBUS target (slave) number. This must match the device number you set on the GS2.
+.B
+.IP \-A,\ \-\-accel\-seconds\
+(default 10.0) Seconds to accelerate the spindle from 0 to Max RPM.
+.B
+.IP \-D,\ \-\-decel\-seconds\
+(default 0.0) Seconds to decelerate the spindle from Max RPM to 0.
+If set to 0.0 the spindle will be allowed to coast to a stop without
+controlled deceleration.
+.B
+.IP \-R,\ \-\-braking\-resistor
+This argument should be used when a braking resistor is installed on the
+GS2 VFD (see Appendix A of the GS2 manual). It disables deceleration
+over-voltage stall prevention (see GS2 modbus Parameter 6.05), allowing
+the VFD to keep braking even in situations where the motor is regenerating
+high voltage. The regenerated voltage gets safely dumped into the
+braking resistor.
+.B
+
+.SH PINS
+.B
+.IP .DC\-bus\-volts\ (float,\ out)
+from the VFD
+.B
+.IP .at\-speed\ (bit,\ out)
+when drive is at commanded speed
+.B
+.IP .err\-reset\ (bit,\ in)
+reset errors sent to VFD
+.B
+.IP .firmware\-revision\ (s32,\ out)
+from the VFD
+.B
+.IP .frequency\-command\ (float,\ out)
+from the VFD
+.B
+.IP .frequency\-out\ (float,\ out)
+from the VFD
+.B
+.IP .is\-stopped\ (bit,\ out)
+when the VFD reports 0 Hz output
+.B
+.IP .load\-percentage\ (float,\ out)
+from the VFD
+.B
+.IP .motor\-RPM\ (float,\ out)
+from the VFD
+.B
+.IP .output\-current\ (float,\ out)
+from the VFD
+.B
+.IP .output\-voltage\ (float,\ out)
+from the VFD
+.B
+.IP .power\-factor\ (float,\ out)
+from the VFD
+.B
+.IP .scale\-frequency\ (float,\ out)
+from the VFD
+.B
+.IP .speed\-command\ (float,\ in)
+speed sent to VFD in RPM It is an error to send a speed faster than the Motor Max RPM as set in the VFD
+.B
+.IP .spindle\-fwd\ (bit,\ in)
+1 for FWD and 0 for REV sent to VFD
+.B
+.IP .spindle\-on\ (bit,\ in)
+1 for ON and 0 for OFF sent to VFD, only on when running
+.B
+.IP .spindle\-rev\ (bit,\ in)
+1 for ON and 0 for OFF, only on when running
+.B
+.IP .status\-1\ (s32,\ out)
+Drive Status of the VFD (see the GS2 manual)
+.B
+.IP .status\-2\ (s32,\ out)
+Drive Status of the VFD (see the GS2 manual) Note that the value is a sum of all the bits that are on. So a 163 which means the drive is in the run mode is the sum of 3 (run) + 32 (freq set by serial) + 128 (operation set by serial).
+
+.SH PARAMETERS
+.B
+.IP .error\-count\ (s32,\ RW)
+.B
+.IP .loop\-time\ (float,\ RW)
+how often the modbus is polled (default 0.1)
+.B
+.IP .nameplate\-HZ\ (float,\ RW)
+Nameplate Hz of motor (default 60)
+.B
+.IP .nameplate\-RPM\ (float,\ RW)
+Nameplate RPM of motor (default 1730)
+.B
+.IP .retval\ (s32,\ RW)
+the return value of an error in HAL
+.B
+.IP .tolerance\ (float,\ RW)
+ speed tolerance (default 0.01)
+.B
+.IP .ack\-delay\ (s32,\ RW)
+ number of read/write cycles before checking at\-speed (default 2)
+
+.SH SEE ALSO
+\fIGS2 Driver\fR in the LinuxCNC documentation for a full description of the \fBGS2\fR syntax
+
+\fIGS2 Examples\fR in the LinuxCNC documentation for examples using the \fBGS2\fR component
+
+.SH BUGS
+
+.SH AUTHOR
+John Thornton
+
+.SH LICENSE
+GPL
diff --git a/docs/man/es/man1/hal_input.1 b/docs/man/es/man1/hal_input.1
new file mode 100644
index 0000000000..a9d5a131bc
--- /dev/null
+++ b/docs/man/es/man1/hal_input.1
@@ -0,0 +1,165 @@
+.TH HAL_INPUT "1" "2007-02-25" "Documentacion de LinuxCNC" "Manual HAL de usuario"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+.SH NOMBRE
+hal_input \- controla los pines HAL con cualquier dispositivo de entrada de Linux, incluidos los dispositivos USB HID
+.SH SINOPSIS
+\fIloadusr\fR \fBhal_input\fR \fI[\-KRAL] inputspec ...\fR
+.SH DESCRIPCION
+hal_input es una interfaz entre HAL y cualquier dispositivo de entrada de Linux, incluido
+dispositivos USB HID. Para cada dispositivo nombrado, \fBhal_input\fR crea los pines correspondientes
+a sus teclas, ejes absolutos, y leds. Sincroniza el dispositivo y los pines HAL a una tasa fija de
+aproximadamente 10 ms,
+.SH ESPECIFICACIONES DE ENTRADA
+\fIinputspec\fR puede estar en una de varias formas:
+.TP
+Una cadena \fIS\fR
+Se comparara una subcadena o un patron de estilo de shell con el "nombre"
+del dispositivo, el "phys" (que proporciona informacion sobre como está conectado),
+y el "id", que es una cadena con el formato "Bus = ... Vendor = ... Product = ...
+Version = ... ". Puede ver el nombre, el estado fisico y la identificacion de los dispositivos
+conectados ejecutando \fBless /proc/bus/input/devices\fR. Ejemplos:
+.RS 12
+.PD 0
+SpaceBall
+.PP
+"Vendor=001f Product=0001"
+.PP
+serio*/input0
+.RE
+.PD
+.TP
+Un numero \fIN\fR
+Esto abre \fB /dev/input/event\fIN\fR. A excepcion de los dispositivos que estan siempre
+conectados al sistema, este numero puede cambiar durante los reinicios o cuando el dispositivo
+es removido. Por esta razon, no se recomienda usar un numero entero.
+.PP
+Cuando varios dispositivos están identificados por la misma cadena, agregue "\fB:\fIN\fR" donde
+\fIN\fR es el indice del dispositivo deseado. Por ejemplo, si \fBMouse\fR
+coincide con \fBinput3\fR y con \fBinput10\fR, entonces \fBMouse\fR y \fBMouse:0\fR
+selecciona \fBinput3\fR. Especificando \fBmouse:1\fR selecciona\fRinput10\fR.
+.PP
+Para dispositivos que aparecen como entradas multiples en /dev/input, es probable que estos indices
+permanezcan igual cada vez. Para multiples dispositivos idénticos,
+es probable que los indices dependan del orden de insercion, pero permanezcan iguales en
+el reinicio, siempre que los dispositivos no se muevan a puertos diferentes o se desenchufen
+mientras se arranca la maquina.
+.PP
+Si el primer caracter de \fIinputspec\fR es un "+", entonces \fBhal_input\fR
+solicita acceso exclusivo al dispositivo. Se utiliza l primer dispositivo que
+coincida con \fIinputspec\fR. Se puede usar cualquier numero de \fIinputspec\fRs.
+.PP
+La opcion \fIsubset\fI puede preceder a cada \fIinputspec\fR. La opcion sunset
+comienza con un guion. Cada letra en la opcion subset especifica una carecteristica
+del dispositivo a \fBincluir\fR. Se excluyen las caracteristicas que no esten especificadas.
+Por ejemplo, para exportar los LED del teclado a HAL sin exportar teclas, use
+.RS 12
+hal_input \-L \fIkeyboard\fR ...
+.RE
+
+.SH CARACTERISTICAS DEL DISPOSITIVO SOPORTADAS
+.IP \(bu 4
+EV_KEY (botones y teclas). Subset \-K
+.IP \(bu 4
+EV_ABS (entradas analogicas absolutas). Subset \-A
+.IP \(bu 4
+EV_REL (entradas analogicas relativas). Subset \-R
+.IP \(bu 4
+EV_LED (salidas LED). Subset \-L
+.SH PINES Y PARAMETROS HAL
+.SS Para botones
+.TP
+.B input.\fIN\fB.btn\-\fIname\fR bit out
+.TQ
+.B input.\fIN\fB.btn\-\fIname\fB\-not\fR bit out
+Creado para cada boton en el dispositivo.
+.SS Para teclas
+.TP
+.B input.\fIN\fB.key\-\fIname\fB
+.TQ
+.B input.\fIN\fB.key\-\fIname\fB\-not
+Creado para cada tecla en el dispositivo.
+.SS para ejes absolutos
+.TP
+.B input.\fIN\fB.abs\-\fIname\fB\-counts\fR s32 out
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-position\fR float out
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-scale\fR parameter float rw
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-offset\fR parameter float rw
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-fuzz\fR parameter s32 rw
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-flat\fR parameter s32 rw
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-min\fR parameter s32 r
+.TQ
+.B input.\fIN\fB.abs\-\fIname\fB\-max\fR parameter s32 r
+Creado para cada eje absoluto en el dispositivo. Posiciones del dispositivo mas cercanas que
+\fBflat\fR a \fBoffset\fR se reportan como \fBoffset\fR en \fBcounts\fR, y
+\fBcounts\fR no cambia hasta que la posicion del dispositivo cambie al menos
+\fBfuzz\fR. La posicion se calcula como
+
+\fBposition\fR = (\fBcounts\fR \-\fBoffset\fR) / \fBscale\fR
+
+El valor predeterminado de \fBscale\fR y \fBoffset\fR
+asigna el rango del eje reportado por el sistema operativo a [\-1,1].
+Los valores predeterminados de \fBfuzz\fR y \fBflat\fR son los informados por el operador del
+sistema. Los valores de \fBmin\fR y \fBmax\fR son los reportados por el
+sistema operativo.
+.SS para ejes relativos
+.TP
+.B input.\fIN\fB.rel\-\fIname\fB\-counts\fR s32 out
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-position\fR float out
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-reset\fR bit in
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-scale\fR parameter float rw
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-absolute\fR parameter s32 rw
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-precision\fR parameter s32 rw
+.TQ
+.B input.\fIN\fB.rel\-\fIname\fB\-last\fR parameter s32 rw
+Creado para cada eje relativo en el dispositivo. Siempre que \fBreset\fR sea TRUE,
+\fBcounts\fR se restablece a cero independientemente de cualquier movimiento anterior o actual del eje.
+De lo contrario, \fBcounts\fR aumenta o disminuye de acuerdo con el movimiento del
+eje. \fBcounts\fR se divide por\fRposition \-scale\fR para dar \fBposition\fR.
+El valor predeterminado de \fBposition\fR es 1. Hay algunos dispositivos, en particular
+ruedas de desplazamiento, que devuelven valores con signo con resolucion menor de 32 bits.
+El valor predeterminado de \fBprecision\fR es 32. \fBprecision\fR se puede establecer en 8
+para un dispositivo que devuelve valores de 8 bits con signo, o cualquier otro valor de 1 a 32.
+\fBabsolute\fR, cuando se establece TRUE, ignora los eventos duplicados con el mismo valor.
+Esto permite que los dispositivos que repiten eventos sin ninguna accion del usuario funcionen.
+correctamente. \fBlast\fR muestra el valor de conteo mas reciente devuelto por el
+dispositivo, y se utiliza en la implementacion de \fBabsolute\fR.
+.SS para LEDs
+.TP
+.B input.\fIN\fB.led\-\fIname\fR bit out
+.TQ
+.B input.\fIN\fB.led\-\fIname\fB\-invert\fR parameter bit rw
+Creado para cada LED en el dispositivo.
+.SH PERMISOS Y UDEV
+Por defecto, los dispositivos de entrada pueden no ser accesibles para
+usuarios - \fBhal_input\fR requiere acceso de lectura y escritura, incluso si el dispositivo no tiene
+salidas.
+
+Las diferentes versiones de udev tienen sintaxis ligeramente diferentes e incompatibles.
+Por esta razon, no es posible que esta pagina de manual brinde informacion y ejemplo preciso.
+.B udev(7)
+La pagina de manual documenta la sintaxis utilizada en su distribucion de Linux.
+Para verlo en un terminal, el comando es
+
+.BR "man 7 udev".
+
+.SH ERRORES
+El estado inicial de las teclas, botones y ejes absolutos se informa erroneamente
+como FALSE o 0 hasta que se reciba un evento para esa tecla, boton o eje.
+.SH VER TAMBIEN
+\fBudev(8)\fR, \fBudev(7)\fR
+
diff --git a/docs/man/es/man1/hal_manualtoolchange.1 b/docs/man/es/man1/hal_manualtoolchange.1
new file mode 100644
index 0000000000..1276b141bd
--- /dev/null
+++ b/docs/man/es/man1/hal_manualtoolchange.1
@@ -0,0 +1,77 @@
+.\" Man page for hal_manualtoolchange userspace component.
+.\" Written 05 APR 2017 by Joe Hildreth (joeh@threerivershospital.com)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.TH hal_manualtoolchange 1 "04 ABR 2017" "Documentación LinuxCNC" "Componente de espacio de usuario HAL"
+.SH NOMBRE
+hal_manualtoolchange \- Componente de espacio de usuario HAL para habilitar cambios manuales de herramienta.
+.SH SINOPSIS
+loadusr hal_manualtoolchange
+.SH DESCRIPCIÓN
+hal_manualtoolchange es un componente de espacio de usuario de LinuxCNC que permite a los usuarios con máquinas que no tienen cambiadores automáticos de herramientas realizar cambios manuales de herramienta. Cuando se usa y se encuentra un cambio de herramienta M6, el componente de movimiento detendrá el husillo y pausará el programa. El componente hal_manualtoolchange recibirá una señal del componente de movimiento, lo que hará que muestre una ventana de cambio de herramienta que le indica al usuario qué número de herramienta cargar en función del último número T\- programado. El diálogo permanecerá activo hasta que se presione el botón "continuar". Cuando se presiona el botón "continuar", hal_manualtoolchange le indicará al componente de movimiento que el cambio de herramienta está completo, permitiendo así que el movimiento vuelva a encender el husillo y reanude la ejecución del programa.
+.P
+Además, el componente hal_manualtoolchange incluye un pin de hal para un botón que se puede conectar a un botón físico para completar el cambio de herramienta y eliminar el indicador de la ventana (hal_manualtoolchange.change_button).
+.P
+hal_manualtoolchange se puede usar incluso cuando AXIS no se usa como GUI. Este componente es más útil si tiene herramientas preestablecidas y usa la tabla de herramientas.
+.SH PINS
+.TP
+.B hal_manualtoolchange.number \fRs32 in\fR
+Recibe el último número T\- programado.
+.TP
+.B hal_manualtoolchange.change \fRbit in\fR
+Recibe la señal para hacer cambio de herramienta.
+.TP
+.B hal_manualtoolchange.changed \fRbit out\fR
+Indica que el cambio de herramienta está completo.
+.TP
+.B hal_manualtoolchange.change_button \fRbit in\fR
+Pin para permitir que un interruptor externo indique que el cambio de herramienta se ha completado.
+.SH USO
+El uso normal es cargar el componente en su archivo HAL y conectar los pines apropiados de los componentes \fImotion\fR y \fIio\fR. Las siguientes líneas son típicas en un archivo HAL cuando se utiliza el componente userspace hal_manualtoolchange.
+.TP
+.B loadusr \-W hal_manualtoolchange
+Cargar el componente hal_manualtoolchange userspace esperando que el componente esté listo antes de continuar.
+.TP
+.B net tool\-change iocontrol.0.tool\-change => hal_manualtoolchange.change
+Cuando se ejecuta un código M6, el movimiento establece \fIiocontrol.0.tool\-change\fR en alto, lo que indica un cambio de herramienta. Este pin debe estar conectado a \fIhal_manualtoolchange.change\fR. Esto hace que el cuadro de diálogo Cambio de Herramienta se muestre en la pantalla y espere a que el usuario haga clic en el botón Continuar en el cuadro de diálogo o presione un botón conectado externamente.
+.TP
+.B net tool\-changed iocontrol.0.tool\-changed <= hal_manualtoolchange.changed
+Cuando se presiona el botón Continuar del cuadro de diálogo Cambio de Herramienta, establecerá el pin
+.I hal_manualtoolchange.changed
+a alto, esto debe ser conectado al pin
+.I iocontrol.0.tool\-changed
+, indicando al controlador de movimiento que el cambio de herramienta se ha completado y puede continuar con la ejecución del programa de código G.
+.TP
+.B net tool\-number iocontrol.0.tool\-prep\-number => hal_manualtoolchange.number
+Cuando se ejecuta un comando T\- en un programa de código G, el número de herramienta se mantendrá en
+.I iocontrol.0.tool\-prep\-number\fR. \fR
+Este pin debe estar conectado a
+.I hal_manualtoolchange.number\fR. \fR
+El valor de este pin, el número de herramienta, se muestra en el cuadro de diálogo Cambio de herramienta para que el usuario sepa qué herramienta debe cargarse.
+.TP
+.B net tool\-prepare\-loopback iocontrol.0.tool\-prepare => iocontrol.0.tool\-prepared
+El pin \fIiocontrol.0.tool\-prepare\fR se activará cuando se solicite una preparacion de herramienta Tn. Como no hay un cambiador de herramientas automatizado, este pin debe conectarse a \fIiocontrol.0.tool\-prepared\fR para indicar que la herramienta ha sido preparada.
+.P
+Si desea utilizar un botón externo para indicar al componente hal_manualtoolchange que el cambio de herramienta se ha completado, simplemente coloque el botón en HAL (a través de un pin de entrada parport o una entrada hostmot2 gpio o similar) y conéctelo directamente al pin \fIhal_manualtoolchange. change_button\fR. Por ejemplo:
+.P
+.B net tool\-changed\-btn hal_manualtoolchange.change_button <= parport.0.pin\-15\-in
+.SH VER TAMBIÉN
+motion(1) iocontrol(1) halcmd(1)
diff --git a/docs/man/es/man1/hal_parport.1 b/docs/man/es/man1/hal_parport.1
new file mode 100755
index 0000000000..b0fe4f00ab
--- /dev/null
+++ b/docs/man/es/man1/hal_parport.1
@@ -0,0 +1,179 @@
+.\" Man page for hal_manualtoolchange userspace component.
+.\" Written 12 APR 2017 by Joe Hildreth (joeh@threerivershospital.com)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.TH hal_parport 1 "12 ABR 2017" "Documentacion de LinuxCNC" "Componente HAL Realtime"
+.SH NOMBRE
+hal_parport \- Componente HAL en tiempo real para comunicarse con uno o mas puertos paralelos de PC.
+.SH SINOPSIS
+.B loadrt hal_parport cfg="\fIport_addr\fR[\fItype\fR] [[\fIport_addr \fR[\fItype \fR] ...]\fB"
+.SH DESCRIPCION
+El componente hal_parport es un componente en tiempo real que proporciona conexiones HAL a traves de halpins a los pines fisicos de uno o mas puertos paralelos. Proporciona una funcion de lectura y escritura para enviar y recibir datos a los puertos paralelos conectados.
+.PP
+El componente hal_parport admite hasta \fB8 \fRpuertos paralelos fisicos.
+.SH OPCIONES
+.TP
+.B cfg="port_addr [tipo] [[port_addr [tipo] ...]"
+
+La cadena cfg le dice a hal_parport la(s) direccion(es) del(de los) puerto(s) paralelo(s) y si el(los) puerto(s) se usa(n) como puerto(s) de entrada o salida. El componente admite hasta ocho puertos paralelos.
+
+El parametro \fBport_addr\fR de la cadena de configuracion puede ser la direccion base fisica de un puerto paralelo o se puede especificar como el puerto paralelo detectado a traves del controlador parport_pc de Linux. En ese caso, la \fBport_addr\fRde \fI0 \fRes el primer puerto paralelo detectado en el sistema, \fI1\fRes el siguiente, y asi sucesivamente.
+
+El parametro \fBtype\fR de la cadena de configuracion determina como se utilizan los bits de E/S del puerto. Hay cuatro opciones posibles y si no se especifica ninguna, por defecto sera de salida.
+
+\fIin\fR\- Establece los 8 bits del puerto de datos para entrada. En este modo, el puerto paralelo tiene un total de 13 pines de entrada y 4 pines de salida.
+
+\fIout\fR\- Establece los 8 bits del puerto de datos para salida. En este modo, el puerto paralelo tiene un total de 5 pines de entrada y 12 pines de salida.
+
+\fIepp\fR\: esta opcion es la misma que la configuracion para salida, pero puede hacer que la computadora cambie las caracteristicas electricas del puerto. (\fIVea USO mas abajo\fR.)
+
+\fIx\fR\- La opcion permite que los puertos con colectores abiertos en los pines del grupo de control se configuren como entradas, lo que da como resultado 8 pines de salida y 9 pines de entrada. (\fIVea USO mas abajo\fR.)
+.SH PINES
+.TP
+Los pines creados por el componente hal_parport dependen de como se configure la cadena \fBcfg = ""\fR pasada a el. (\fIVer OPCIONES\fR.)
+\fBparport.
.pin\-\-out (bit) \fRConduce un pin de salida fisico.
+
+\fBparport.
.pin\-\-in (bit) \fRRastrea un pin de entrada fisico.
+
+\fBparport.
.pin\-\-in\-not (bit) \fRRastrea un pin de entrada fisico, pero invertido.
+
+Para cada pin creado, \fB
\fRes el numero de puerto, y \fB\fRes el numero de pin fisico en el conector D\-shell de 25 pines.
+
+Para cada pin de salida fisica, el controlador crea un solo pin HAL, por ejemplo: \fBparport.0.pin\-14\-out\fR.
+
+Para cada pin de entrada fisica, el controlador crea dos pines HAL, por ejemplo: \fBparport.0.pin\-12\-in\fRy \fBparport.0.pin\-12\-in\-not\fR.
+
+El pin HAL \fB\-in \fRes VERDADERO si el pin fisico esta alto, y FALSO si el pin fisico esta bajo. El pin HAL \fB\-in\-not \fResta invertido y es FALSO si el pin fisico esta alto.
+
+A continuacion se enumeran los pines de entrada y salida segun la configuracion de tipo utilizada en la cadena cfg="".
+
+\fBin\fR: Los pines 2,3,4,5,6,7,8,9,10,11,12,13,15 son pins de entrada y los pines 1,14,16 y 17 son pines de salida.
+
+\fBout/epp\fR: Los pines 10,11,12,13 y 15 son pines de entrada y los pines 1,2,3,4,5,6,7,8,9,14,16 y 17 son pines de salida.
+
+\fBx\fR: Los pines 1,10,11,12,13,14,15,16 y 17 son pines de entrada y los pines 2,3,4,5,6,7,8,9 son pines de salida. (\fIVer USO\fR.)
+.SH PARAMETROS
+.TP
+\fBparport.
.pin\-\-out\-invert (bit)
+\fRInvierte un pin de salida.
+.TP
+\fBparport.
.pin\-\-out\-reset (bit)
+\fR (solo para los pines de salida) VERDADERO si este pin debe restablecerse cuando se ejecuta la funcion .reset.
+.TP
+\fBparport.
.reset\-time' (U32)
+\fREl tiempo (en nanosegundos) entre que un pin se establece mediante escritura y reinicio mediante la funcion reset, si esta habilitada.
+.SH FUNCIONES
+.TP
+\fBparport.
.read (funct)
+\fRLee los pines de entrada fisicos del puerto y actualiza pines HAL \-in y \-in\-not.
+.TP
+\fBparport.read\-all (funct)
+Lee los pines de entrada fisica de todos los puertos y actualiza los pines HAL \-in y \-in\-not.
+.TP
+\fBparport.
.write (funct)
+Lee los pines HAL \-out del puerto
y actualiza los pines de salida fisicos de ese puerto.
+.TP
+\fBparport.write\-all (funct)
+Lee los pines HAL \-out de todos los puertos y actualiza todos los pines de salida fisicos.
+.TP
+\fBparport.
.reset (funct)
+Espera hasta que \fIreset\-time \fRha transcurrido desde la escritura asociada. Luego restablece los pines a los valores indicados por \fI\-out\-reset \fRy \fI\-out\-invert\fR. reset debe estar despues de write en el mismo hilo. Si \fI\-out\-reset\fRes VERDADERO, la funcion de reset establecera el pin en el valor de \fI\-out\-invert\fR. Esto se puede utilizar junto con doublefreq de stepgen para producir un paso por periodo. El espacio de paso stepgen para ese pin debe establecerse en 0 para habilitar doublefreq.
+.SH USO
+El componente hal_parport es un controlador para el puerto paralelo de PC tradicional. El puerto tiene un total de 25 pines fisicos de los cuales 17 se utilizan para se\[~n]ales. El puerto paralelo original dividio esos pines en tres grupos: datos, control y estado. El grupo de datos consta de 8 pines de salida, el grupo de control consta de 4 pines de salida y el grupo de estado consta de 5 pines de entrada.
+
+A principios de la decada de 1990, se introdujo el puerto paralelo bidireccional, que permite que el grupo de datos se use para salida o entrada. El controlador HAL es compatible con el puerto bidireccional y permite al usuario configurar el grupo de datos como entrada o salida. Si se configura como \fIout\fR, un puerto proporciona un total de 12 salidas y 5 entradas. Si se configura como \fIin\fR, proporciona 4 salidas y 13 entradas.
+
+En algunos puertos paralelos, los pines del grupo de control son colectores abiertos, que tambien pueden ser accionados por una puerta externa. En una placa con pines de control de colector abierto, si esta configurado como \fIx\fR, proporciona 8 salidas y 9 entradas.
+
+En algunos puertos paralelos, el grupo de control tiene controladores push-pull y no se puede utilizar como entrada.
+.TP
+\fBNote: HAL y colectores abiertos
+HAL no puede determinar automaticamente si los pines bidireccionales del modo x son en realidad de colectores abiertos (OC). Si no lo estan, no se pueden usar como entradas, e intentar llevarlos a BAJO desde una fuente externa puede da\[~n]ar el hardware.
+
+Para determinar si su puerto tiene pines de colector abiertos, cargue hal_parport en modo x. Sin dispositivo conectado, HAL deberia leer el pin como VERDADERO. A continuacion, inserte una resistencia de 470 ohmios desde uno de los pines de control a GND. Si el voltaje resultante en el pin de control esta cerca de 0 V, y HAL ahora lee el pin como FALSO, entonces tiene un puerto OC. Si el voltaje resultante esta lejos de 0 V, o HAL no lee el pin como FALSO, entonces su puerto no se puede usar en el modo \fIx\fR.
+
+El hardware externo que controla los pines de control tambien debe usar puertas de colector abierto (por ejemplo, 74LS05).
+
+En algunas computadoras, la configuracion del BIOS puede afectar si se puede usar el modo x. El modo SPP es mas probable que funcione.
+.PP
+No se admiten otras combinaciones, y no se puede cambiar un puerto de entrada a salida una vez que se instala el controlador.
+
+El controlador puede controlar hasta 8 puertos (definidos por MAX_PORTS en hal_parport.c). Los puertos estan numerados a partir de cero.
+.TP
+\fBCargando el componente hal_parport
+
+El controlador hal_parport es un componente en tiempo real, por lo que debe cargarse en un hilo en tiempo real con loadrt. La cadena de configuracion describe los puertos paralelos que se utilizaran y (opcionalmente) sus tipos. Es un error si la cadena de configuracion no describe al menos un puerto.
+
+\fBloadrt hal_parport cfg="puerto [tipo] [puerto [tipo] ...]"
+.TP
+\fBEspecificando el puerto
+
+Los numeros inferiores a 16 se refieren a puertos paralelos detectados por el sistema. Esta es la forma mas sencilla de configurar el controlador hal_parport y cooperar con el controlador parport_pc de Linux si esta cargado. Un puerto 0 es el primer puerto paralelo detectado en el sistema, 1 es el siguiente, y asi sucesivamente.
+.TP
+\fBConfiguracion basica
+
+Esto usara el primer puerto paralelo que detecta Linux:
+
+ \fBloadrt hal_parport cfg="0"
+.TP
+\fBUsando la direccion del puerto
+
+En su lugar, la direccion del puerto se puede especificar utilizando la notacion hexadecimal 0x mas la direccion.
+
+ \fBloadrt hal_parport cfg="0x378"
+.TP
+\fBEspecificar un tipo de puerto
+
+Para cada puerto paralelo manejado por el controlador hal_parport, se puede especificar un tipo opcionalmente. El tipo es uno de in, out, epp o x.
+
+Si el tipo no esta especificado, el valor predeterminado es out.
+
+Un tipo epp es el mismo que out, pero el controlador hal_parport solicita que el puerto entre en modo EPP. El controlador hal_parport no utiliza el protocolo de bus EPP, pero en algunos sistemas, el modo EPP cambia las caracteristicas electricas del puerto de una manera que puede hacer que algunos hardware funcionen mejor. Se sabe que la bomba de carga de la Gecko G540 requiere esto en algunos puertos paralelos.
+
+Consulte la nota anterior sobre el modo x.
+.TP
+\fBEjemplo con dos puertos paralelos
+
+Esto permitira dos puertos paralelos detectados por el sistema, el primero en modo salida y el segundo en modo entrada:
+
+ \fBloadrt hal_parport cfg = "0 out 1 in"
+.TP
+\fBFunciones unicas de puerto
+
+Tambien debe indicar a LinuxCNC que ejecute las funciones de lectura y escritura.
+
+ \fBaddf parport.read\-all base\-thread
+ \fBaddf parport.write\-all base\-thread
+.TP
+\fBFunciones multiples de puertos
+
+Puede indicar a LinuxCNC que pierda las funciones de lectura y escritura para todos los puertos conectados.
+
+ \fBaddf parport.0.read base\-thread
+ \fBaddf parport.0.write base\-thread
+
+\fRLas funciones individuales se proporcionan para situaciones en las que un puerto debe actualizarse en un hilo muy rapido, pero otros puertos pueden actualizarse en un hilo mas lento para ahorrar tiempo de CPU. Probablemente no sea una buena idea utilizar una funcion \-all y una funcion individual al mismo tiempo.
+.SH VER TAMBIEN
+Controlador de puerto paralelo (Seccion de controladores de hardware de LinuxCNC Docs) Ejemplo de puerto paralelo PCI (Seccion de ejemplos de hardware de LinuxCNC Docs)
+.SH AUTOR
+Esta pagina de manual escrita por Joe Hildreth como parte del proyecto LinuxCNC. La mayor parte de esta informacion se tomo de los documentos de puertos paralelos ubicados en la seccion Controladores de hardware de la documentacion. Que yo sepa, esa documentacion fue escrita por Sebastian Kuzminsky y Chris Radek.
+
+
diff --git a/docs/man/es/man1/halcmd.1 b/docs/man/es/man1/halcmd.1
new file mode 100644
index 0000000000..79bce8dab7
--- /dev/null
+++ b/docs/man/es/man1/halcmd.1
@@ -0,0 +1,413 @@
+.\" Copyright (c) 2003 John Kasunich
+.\" (jmkasunich AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.de URL
+\\$2 \(laURL: \\$1 \(ra\\$3
+..
+.if \n[.g] .mso www.tmac
+.TH HALCMD "1" "2003-12-18" "Documentacion LinuxCNC" "Manual HAL de usuario"
+.SH NOMBRE
+halcmd \-manipula HAL de LinuxCNC desde la linea de comandos
+.SH SINOPSIS
+.B halcmd
+[\fIOPTIONS\fR] [\fICOMMAND\fR[\fIARG\fR]]
+.PP
+.SH DESCRIPCION
+\fBhalcmd\fR se utiliza para manipular HAL (Capa de abstraccion de hardware) desde la linea de comando.
+\fBhalcmd\fR puede leer, opcionalmente, comandos de un archivo, permitiendo que configuraciones complejas de HAL sean
+establecidas con un solo comando.
+
+Si la biblioteca \fBreadline\fR esta disponible cuando se compila LinuxCNC, entonces
+\fBhalcmd\fR ofrece edicion y finalizacion de la linea de comandos cuando se ejecuta
+interactivamente. Use la flecha hacia arriba para recuperar los comandos anteriores y presione la tecla tab para
+completar los nombres de elementos, como pines y se\[~n]ales.
+.SH OPCIONES
+.TP
+\fB\-I\fR
+Antes de destruir el entorno en tiempo real, ejecute un halcmd interactivo.
+\fBhalrun\fR solamente. Si se usa \fB\-I\fR, debe preceder a todos los demas
+argumentos de linea de comandos.
+.TP
+\fB \\-f\fR [\fIfichero\fR]
+Ignorar los comandos en la linea de comandos; toma la entrada \fIfile\fR
+en su lugar. Si no se especifica \fIfile\fR, toma la entrada de \fIstdin\fR.
+.TP
+\fB\-i \fIfichero.ini\fR
+Usar variables de \fIinifile\fR para las sustituciones. Ver \fBSUSTITUCIONES\fR mas abajo.
+.TP
+\fB\\-k\fR
+Continuar despues de comandos fallidos. El valor predeterminado es detener
+y devolver el fallo si falla cualquier comando.
+.TP
+\fB\\-q\fR
+Visualizar solo errores (predeterminado)
+.TP
+\fB\\-Q\fR
+No mostrar nada; ejecutar comandos silenciosamente
+.TP
+\fB\\-s\fR
+Modo amigable con el script. En este modo, \fIshow\fR no generara titulos para los elementos
+mostrados. Ademas, se imprimiran los nombres de los modulos en lugar de los codigos de identificacion en listados de
+pines, parametros y funciones. Los hilos se imprimen en una sola linea, con el periodo de hilo, el uso de FP y
+el nombre primero, seguido de todas las funciones en el hilo, en orden de ejecucion. Las se\[~n]ales
+se imprimen en una sola linea, con el tipo, el valor y el nombre de la se\[~n]al primero, seguidos de
+una lista de pines conectados a la se\[~n]al, que muestra la direccion y el nombre del pin.
+.TP
+\fB\-R\fR
+Librar el mutex HAL. Esto es util para recuperacion cuando un componente HAL falla
+mientras retenia el mutex HAL.
+.TP
+\fB \\-v\fR
+mostrar los resultados de cada comando
+.TP
+\fB\\-V\fR
+Mostrar informacion de depuracion
+.TP
+\fB\\-h\fR[\fIcomando\fR]
+Muestra una pantalla de ayuda y sale; muestra ayuda extendida de \fIcomando\fR si se especifica
+.SH COMANDOS
+Los comandos le dicen a \fBhalcmd\fR que hacer. Normalmente \fBhalcmd\fR
+lee un solo comando desde la linea de comandos y lo ejecuta.
+Si se usa la opcion '\fB\-f\fR' para leer comandos de un archivo,
+\fBhalcmd\fR lee cada linea del archivo como un nuevo comando.
+Todo lo que siga a '\fB#\fR' en una linea es un comentario.
+.TP
+\fBloadrt\fR \fImodname\fR
+(\fIload\fR \fIr\fReal\fIt\fRime module) Carga un modulo HAL en tiempo real
+llamado \fImodname\fR. \fBhalcmd\fR busca el modulo
+en el directorio especificado en tiempo de compilacion.
+
+En sistemas con tiempo real, \fBhalcmd\fR llama a
+\fBlinuxcnc_module_helper\fR para cargar modulos en tiempo real.
+\fBlinuxcnc_module_helper\fR es un programa setuid y se compila con
+una lista blanca de modulos que se permiten cargar. Esto es actualmente
+solo una lista de los modulos relacionados con \fBLinuxCNC\fR.
+\fBlinuxcnc_module_helper\fR ejecuta insmod, asi que devuelve los mensajes de codigos y error
+de insmod. Los administradores que deseen
+restringir que usuarios pueden cargar estos modulos de kernel relacionados con \fBLinuxCNC\fR
+pueden hacer esto configurando los permisos y el grupo en
+\fBlinuxcnc_module_helper\fR apropiadamente.
+
+En sistemas sin tiempo real, \fBhalcmd\fR llama a
+\fBrtapi_app\fR que crea el entorno en tiempo real simulado,
+si aun no existia, y luego carga el componente solicitado
+con una llamada a \fBdlopen(3)\fR.
+.TP
+\fBunloadrt\fR \fImodname\fR
+(\fIunload\fR \fIr\fReal\fIt\fRime module) Descarga un modulo HAL en tiempo real
+llamado \fImodname\fR. Si \fImodname\fR es "all",
+descargara todos los modulos HAL en tiempo real cargados actualmente. \fBunloadrt\fR
+Tambien funciona ejecutando \fBlinuxcnc_module_helper\fR o \fBrtapi_app\fR, al igual que
+\fBloadrt\fR.
+.TP
+\fBloadusr\fR \fI[flags]\fR \fIunix-command\fR
+(\fIload\fR \fIUs\fRe\fIr\fRspace component) Ejecuta
+\fIunix-command\fR, generalmente para cargar un componente de espacio de usuario.
+\fI[flags]\fR puede ser uno o mas de:
+.RS
+.IP \(bu 4
+\fB\-W\fR para esperar a que el componente este listo. El componente
+se asume que tiene el mismo nombre que el primer argumento del comando.
+.IP \(bu 4
+\fB\-Wn name\fR para esperar al componente, que tendra el nombre dado.
+.IP \(bu 4
+\fB\-w\fR para esperar a que el programa salga
+.IP \(bu 4
+\fB\-i\fR para ignorar el valor de retorno del programa (con \-w)
+.RE
+.TP
+\fBwaitusr\fR \fIname\fR
+(\fIwait\fR for \fIUs\fRe\fIr\fRspace component) Espera al componente de espacio de usuario
+\fIname\fR hasta que desconecte de HAL (generalmente en la salida).
+El componente ya debe estar cargado. Util cerca del final de un
+archivo HAL para esperar hasta que el usuario cierre algun componente de la interfaz de usuario
+antes de limpiar y salir.
+.TP
+\fBunloadusr\fR \fIcompname\fR
+(\fIunload\fR \fIUs\fRe\fIr\fRspace component) Descarga un componente de espacio de usuario
+llamado \fIcompname\fR. Si \fIcompname\fR es "all",
+descargara todos los componentes del espacio de usuario. \fBunloadusr\fR
+funciona mediante el envio de SIGTERM a todos los componentes del espacio de usuario.
+.TP
+\fBunload\fR \fIcompname\fR
+Descarga un componente de espacio de usuario o modulo en tiempo real. Si \fIcompname\fR es "all",
+descargara todos los componentes del espacio de usuario y modulos en tiempo real.
+.TP
+\fBnewsig\fR \fIsigname\fR \fItype\fR
+(OBSOLETO: use \fBnet\fR en su lugar) (\fInew\fR\fIsig\fRnal)
+Crea una nueva se\[~n]al HAL llamada \fIsigname\fR que puede ser posteriormente
+utilizada para conectar dos o mas pines de componentes HAL. \fItype\fR
+es el tipo de datos de la nueva se\[~n]al y debe ser uno de "\fBbit\fR",
+"\fBs32\fR", "\fBu32\fR", o "\fBfloat\fR".
+Falla si ya existe una se\[~n]al del mismo nombre.
+.TP
+\fBdelsig\fR \fIsigname\fR
+(\fIdel\fRete \fIsig\fRnal) Borra la se\[~n]al HAL \fIsigname\fR.
+Cualquier pin actualmente vinculado a la se\[~n]al sera desvinculado.
+Falla si \fIsigname\fR no existe.
+.TP
+\fBsets\fR \fIsigname\fR \fIvalue\fR
+(\fIset\fR \fIs\fRignal) Establece el valor de la se\[~n]al \fIsigname\fR
+a \fIvalue\fR. Falla si \fIsigname\fR no existe, si
+ya tiene un escritor, o si \fIvalue\fR no es un valor legal.
+Los valores legales dependen del tipo de se\[~n]al.
+.TP
+\fBstype\fR \fIname\fR
+(\fIs\fRignal type\fR) Obtiene el tipo de la se\[~n]al
+\fIname\fR. Falla si \fIname\fR no existe como una se\[~n]al.
+.TP
+\fBgets\fR \fIsigname\fR
+(\fIget\fR\fIs\fRignal) Obtiene el valor de la se\[~n]al \fIsigname\fR. Falla
+si \fIsigname\fR no existe.
+.TP
+\fBlinkps\fR \fIpinname\fR [\fIarrow\fR] \fIsigname\fR
+(OBSOLETO: use \fBnet\fR en su lugar) (\fIlink\fR\fIp\fRin a \fIs\fRignal)
+Establece un enlace entre un pin de componente HAL \fIpinname\fR y
+una se\[~n]al HAL \fIsigname\fR. Cualquier enlace anterior a \fIpinname\fR sera
+roto. \fIarrow\fR puede ser "\fB =>\fR", "\fB <=\fR", "\fB <=>\fR",
+u omitido. \fBhalcmd\fR ignora las flechas, pero pueden ser utiles
+en los archivos de comando para documentar la direccion del flujo de datos. Las flechas
+no debe utilizarse en la linea de comandos ya que el shell podria intentar
+interpretarlas. Falla si \fIpinname\fR o \fIsigname\fR
+no existe, o si no son del mismo tipo.
+.TP
+\fBlinksp\fR \fIsigname\fR [\fIarrow\fR] \fIpinname\fR
+(OBSOLETO: use \fBnet\fR en su lugar) (\fIlink\fR\fIs\fRignal a \fIp\fRin)
+Funciona como \fBlinkps\fR pero invierte el orden de los argumentos.
+\fBhalcmd\fR trata a ambos comandos de enlace exactamente igual. Usar el que se
+prefiera.
+.TP
+\fBlinkpp\fR \fIpinname1\fR [\fIarrow\fR] \fIpinname2\fR
+(OBSOLETO: use \fBnet\fR en su lugar) (\fIlink\fR\fIp\fRin a \fIp\fRin)
+Atajo para \fBlinkps\fR que crea la se\[~n]al (nombrada como el
+primer pin), y luego vincula a ambos a esa se\[~n]al. \fBhalcmd\fR trata
+esto como:
+ \fBhalcmd\fR \fBnewsig\fR pinname1
+ \fBhalcmd\fR \fBlinksp\fR pinname1 pinname1
+ \fBhalcmd\fR \fBlinksp\fR pinname1 pinname2
+.TP
+\fBnet\fR \fIsigname\fR \fIpinname\fR\fI ...\fR
+Crea \fIsignname\fR para que coincida con el tipo de \fIpinname\fR si aun no
+existe. Luego, enlaza \fIsigname\fR a cada \fIpinname\fR a su vez. Las flechas pueden
+ser utilizadas como en \fBlinkps\fR. Al vincular un pin a una se\[~n]al por primera
+vez, el valor de la se\[~n]al heredara el valor predeterminado del pin.
+
+.TP
+\fBunlinkp\fR \fIpinname\fR
+(\fIunlink\fR\fIp\fRin) Rompe cualquier enlace anterior a \fIpinname\fR.
+Falla si \fIpinname\fR no existe. Un pin no enlazado retendra el ultimo
+valor de la se\[~n]al a la que estaba vinculado.
+
+.TP
+\fBsetp\fR \fIname\fR \fIvalue\fR
+(\fIset\fR\fIp\fRarameter o \fIp\fRin) Establece el valor del parametro o pin
+\fIname\fR a \fIvalue\fR. Falla si \fIname\fR no existe como pin o
+parametro, si es un parametro que no se puede escribir, si es un pin que es un pin
+salida, si es un pin que ya esta conectado a una se\[~n]al, o si \fIvalue\fR
+no es un valor legal. Los valores legales dependen del tipo de pin o parametro.
+Si un pin y un parametro existen con el nombre dado, se actua en el parametro.
+.TP
+\fIparamname\fR\fB =\fR\fIvalue\fR
+.TP
+\fIpinname\fR\fB =\fR\fIvalue\fR
+Identico a \fBsetp\fR. Esta forma alternativa del comando puede
+ser mas conveniente y legible cuando se utiliza en un archivo.
+.TP
+\fBptype\fR \fIname\fR
+(\fIp\fRarameter o \fIp\fRin \fItype\fR) Obtiene el tipo de parametro o
+pin \fIname\fR. Falla si \fIname\fR no existe como pin o
+parametro. Si un pin y un parametro existen con el nombre dado,
+se actua sobre el parametro.
+.TP
+\fBgetp\fR \fIname\fR
+(\fIget\fR\fIp\fRarameter o \fIp\fRin) Obtiene el valor del parametro o
+pin \fIname\fR. Falla si \fIname\fR no existe como pin o
+parametro. Si un pin y un parametro existen con el nombre dado,
+se actua sobre el parametro.
+.TP
+\fBaddf\fR \fIfunctname\fR \fIthreadname\fR
+(\fIadd\fR\fIf\fRunction) Agrega la funcion \fIfunctname\fR al hilo de tiempo real
+\fIthreadname\fR. \fIfunctname\fR se ejecutara despues de cualquier funcion
+que fuera agregada previamente al hilo. Falla si cualquiera
+\fIfunctname\fR o \fIthreadname\fR no existe, o si
+son incompatibles
+.TP
+\fBdelf\fR \fIfunctname\fR \fIthreadname\fR
+(\fIdel\fRete \fIf\fRunction) Elimina la funcion \fIfunctname\fR del
+hilo en tiempo real \fIthreadname\fR. Falla si \fIfunctname\fR o bien
+\fIthreadname\fR no existe, o si \fIfunctname\fR no es actualmente
+parte de \fIthreadname\fR.
+.TP
+\fBstart\fR
+Inicia la ejecucion de hilos en tiempo real. Cada hilo llama periodicamente a
+todas las funciones que se le agregaron con el comando \fBaddf\fR,
+en el orden en que fueron a\[~n]adidas.
+.TP
+\fBstop\fR
+Detiene la ejecucion de hilos en tiempo real. Los hilos ya no llamaran a
+sus funciones.
+.TP
+\fBshow\fR [\fIitem\fR]
+Imprime los elementos HAL en \fIstdout\fR en formato legible por humanos.
+\fIitem\fR puede ser uno de "\fBcomp\fR" (componentes), "\fBpin\fR",
+"\fBsig\fR" (se\[~n]ales), "\fBparam\fR" (parametros), "\fBfunct\fR"
+(funciones), "\fBthread\fR", o "\fBalias\fR". El tipo "\fBall\fR"
+se puede utilizar para mostrar elementos coincidentes de todos los tipos anteriores.
+Si se omite \fIitem\fR, \fBshow\fR imprimira todo.
+.TP
+\fBitem\fR
+Esto es equivalente a \fBshow all [item]\fR.
+
+.TP
+\fBsave\fR [\fIitem\fR]
+Imprime los elementos HAL en \fIstdout\fR en forma de comandos HAL.
+Estos comandos se pueden redirigir a un archivo y luego ejecutarse
+utilizando \fBhalcmd \-f\fR para restaurar la configuracion guardada.
+\fIitem\fR puede ser uno de los siguientes:
+
+"\fBcomp\fR" genera
+un comando \fBloadrt\fR para el componente en tiempo real.
+
+"\fBalias\fR" genera
+un comando \fBalias\fR para cada emparejamiento de pin o parametro alias
+
+"\fBsig\fR" (o "\fBsignal\fR")
+genera un comando \fBnewsig\fR para cada se\[~n]al, y "\fBsigu\fR" genera un comando
+\fBnewsig\fR para cada se\[~n]al no vinculada (para usar con \fBnetl\fR y
+\fBnetla\fR).
+
+"\fBlink\fR" y "\fBlinka\fR" generan comandos \fBlinkps\fR
+para cada enlace. (\fBlinka\fR incluye flechas, mientras que \fBlink\fR
+no.)
+
+ "\fBnet\fR" y "\fBneta\fR" generan un comando \fBnewsig\fR para
+cada se\[~n]al, seguida de los comandos \fBlinksp\fR para cada pin vinculado a esa
+se\[~n]al. (\fBneta\fR incluye flechas.)
+
+"\fBnetl\fR" genera un comando \fBnet\fR
+para cada se\[~n]al enlazada, y "\fBnetla\fR" (o "\fBnetal\fR")
+genera un comando similar utilizando flechas.
+
+"\fBparam\fR" (o "\fBparameter\fR)" genera un comando \fBsetp\fR para cada
+parametro.
+
+"\fBthread\fR" genera un comando \fBaddf\fR para cada funcion
+en cada hilo en tiempo real.
+
+"\fBunconnectedinpins\fR" genera un comando setp para cada
+pin de entrada hal desconectado.
+
+Si \fIitem\fR es \fB all\fR, \fBsave\fR hace lo
+equivalente a \fBcomp\fR, \fBalias\fR, \fBsigu\fR, \fBnetla\fR, \fBparam\fR,
+\fBthread\fR, y \fBunconnectedinpins\fR en conjunto.
+
+Si se omite \fIitem\fR (o \fBall\fR), \fBsave\fR hace el
+equivalente a \fBcomp\fR, \fBalias\fR, \fBsigu\fR, \fBnetla\fR, \fBparam\fR,
+y \fBthread\fR en conjunto.
+
+.TP
+\fBsource\fR \fInombre_de_archivo.hal\fR
+Ejecuta los comandos desde \fInombre_de_archivo.hal\fR.
+.TP
+\fBalias\fR \fItype\fR \fIname\fR \fIalias\fR
+Asigna "\fBalias\fR" como segundo nombre para el pin o parametro
+"name". Para la mayoria de las operaciones, un alias proporciona un segundo
+nombre que se puede usar para referirse a un pin o parametro; tanto el
+nombre original como el alias funcionaran.
+ "tipo" debe ser \fBpin\fR o \fBparam\fR.
+ "nombre" debe ser un nombre existente o \fBalias\fR del tipo especificado.
+.TP
+\fBunalias\fR \fItype\fR \fIalias\fR
+Elimina cualquier alias del pin o parametro.
+ "tipo" debe ser \fBpin\fR o \fBparam\fR
+ "alias" debe ser un nombre existente o \fBalias\fR del tipo especificado.
+.TP
+\fBlist\fR \fItype\fR [\fIpattern\fR]
+ Imprime los nombres de los elementos HAL del tipo especificado.
+ 'type' es '\fBcomp\fR', '\fBpin\fR', '\fBsig\fR', '\fBparam\fR', '\fBfunct\fR', o
+ '\fBthread\fR'. Si se especifica 'pattern' solo se imprime
+ los nombres que coinciden con el patron, que puede ser un
+ 'shell glob'.
+ Para '\fBsig\fR', '\fBpin\fR' y '\fBparam\fR', el primer patron puede ser
+ \-t \fBdatatype\fR donde datatype es el tipo de datos (por ejemplo, 'float')
+ En este caso, los pines, se\[~n]ales o parametros listados
+ estan restringidos al tipo de datos dado.
+ Los nombres se imprimen en una sola linea, separados por espacios.
+.TP
+\fBlock\fR [\fIall\fR| \fItune\fR | \fInone\fR]
+ Bloquea HAL hasta cierto punto.
+ none - no hay bloqueo
+ tune: es posible realizar algunos ajustes (\fBsetp\fR y similares).
+ all - HAL queda completamente bloqueado.
+.TP
+\fBunlock\fR [\fIall\fR | \fItune\fR]
+ Desbloquea HAL hasta cierto punto.
+ tune: es posible realizar algunos ajustes (\fBsetp\fR y similares).
+ all - HAL queda completamente desbloqueado.
+.TP
+\fBstatus\fR [\fItype\fR]
+ Imprime informacion de estado sobre HAL.
+ 'type' es '\fBlock\fR', '\fBmem\fR' o '\fBall\fR'.
+ Si se omite "type", se asume "\fBall\fR".
+.TP
+\fBhelp\fR [\fIcomando\fR]
+ Dar informacion de ayuda para el comando.
+ Si se omite 'comando', lista todos los comandos y una breve descripcion
+.SH SUSTITUCION
+Despues de que se lee un comando pero antes de que se ejecute, tiene lugar varios tipos de sustitucion de variables.
+.SS Variables de entorno
+Las variables de entorno tienen los siguientes formatos:
+.IP
+\fB $ ENVVAR\fR seguido de final de linea o espacio en blanco
+.IP
+\fB $ (ENVVAR)\fR
+.SS Variables Inifile
+Las variables inifile estan disponibles solo cuando se especifico un inifile con
+la bandera de halcmd \fB \-i\fR. Tienen los siguientes formatos:
+.IP
+\fB [SECCION]VAR\fR seguido de final de linea o espacio en blanco
+.IP
+\fB [SECCION] (VAR)\fR
+.SH EJEMPLOS
+.SH HISTORIA
+.SH ERRORES
+Ninguno conocido en este momento.
+.SH AUTOR
+Version original de John Kasunich, como parte del proyecto LinuxCNC. Ahora
+incluye importantes aportaciones de varios miembros del proyecto.
+.SH REPORTE DE ERRORES
+Informar de errores en
+.URL http://sf.net/p/emc/bugs/ "LinuxCNC bug tracker".
+.SH COPYRIGHT
+Copyright \(co 2003 John Kasunich.
+.br
+Este es un software libre; ver las fuentes para las condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPOSITO PARTICULAR.
+.SH "VER TAMBIEN"
+\fBhalrun (1)\fR: un script conveniente para iniciar un entorno en tiempo real,
+procesar un archivo .hal o .tcl y, opcionalmente, iniciar una sesion de comandos interactivos
+usando \fBhalcmd\fR (descrito aqui) o \fBhaltcl\fR(1).
+
+
diff --git a/docs/man/es/man1/halcompile.1 b/docs/man/es/man1/halcompile.1
new file mode 100644
index 0000000000..eb6bac20a0
--- /dev/null
+++ b/docs/man/es/man1/halcompile.1
@@ -0,0 +1,84 @@
+.\" Copyright (c) 2007 Jeff Epler
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH halcompile "1" "2007-10-17" "Documentación de LinuxCNC" "The Enhanced Machine Controller"
+.SH NOMBRE
+halcompile \- Construye, compila e instala componentes HAL de LinuxCNC
+.SH SINOPSIS
+.PD 0
+.RS 5
+.PP
+\fBhalcompile\fR [\fB\-\-compile\fR | \fB\-\-preprocess\fR | \fB\-\-document\fR | \fB\-\-view\-doc\fR] archivo.comp...
+.RE
+.PP
+\fIsudo\fR \fBhalcompile\fR [\fB\-\-install\fR|\fB\-\-install\-doc\fR] archivo.comp...
+.RS 5
+.PP
+\fBhalcompile\fR \fB\-\-compile\fR \fB\-\-userspace\fR archivo.c...
+.RE
+.PP
+\fIsudo\fR \fBhalcompile\fR \fB\-\-install\fR \fB\-\-userspace\fR archivo.c...
+.PP
+\fIsudo\fR \fBhalcompile\fR \fB\-\-install\fR \fB\-\-userspace\fR archivo.py...
+
+.PP
+
+Cuando se utilizan personalidades en un archivo de compilación, las instancias de hal se exportan
+secuencialmente (por lo general, por los parámetros count= o names= mutuamente excluyentes).
+Si el número de exportaciones excede el número máximo de personalidades, a las personalidades posteriores se
+les asigna módulo al número máximo de personalidades permitido.
+
+De forma predeterminada, el número máximo de personalidades es 64. Para modificar este límite,
+use la opción \fB--personalities=\fR con halcompile. Por ejemplo, para establecer el máximo de elementos
+de personalidad en 4:
+ [sudo] \fBhalcompile --personalities=4\fR --install ...
+
+.SH DESCRIPCION
+\fBhalcompile\fR realiza muchas funciones diferentes:
+.IP \(bu 4
+Compila los archivos \fB.comp\fR y \fB.c\fR en \fB.so\fR o \fB.ko\fR como componentes HAL en tiempo real (la bandera \fB\-\-compile\fR)
+.IP \(bu 4
+Compila los archivos \fB.comp\fR y \fB.c\fR en componentes de espacio de usuario HAL (bandera \fB\-\-compile \-\-userspace\fR)
+.IP \(bu 4
+Preprocesa archivos \fB.comp\fR en archivos \fB.c\fR (bandera \fB \-\-preprocess\fR)
+.IP \(bu 4
+Extrae la documentacion de los archivos \fB.comp\fR en archivos de paginas de manual de \fB.9\fR (bandera \fB \-\-document\fR)
+.IP \(bu 4
+Muestra la documentacion de los archivos \fB.comp\fR en pantalla (bandera \fB\-\-view\-doc\fR)
+.IP \(bu 4
+Compila e instala los archivos \fB.comp\fR y \fB.c\fR en el directorio adecuado para los componentes HAL en tiempo real
+(bandera \fB\-\-install\fR), lo que puede requerir que \fIsudo\fR escriba en el sistema de directorios.
+.IP \(bu 4
+Instala los archivos \fB.c\fR y \fB.py\fR en el directorio adecuado para los componentes HAL de espacio de usuario
+(bandera \fB\-\-install \-\-userspace\fR),lo que puede requerir que \fIsudo\fR escriba en el sistema de directorios.
+.IP \(bu 4
+Extrae documentacion de los archivos \fB.comp\fR en los archivos de paginas de manual de \fB.9\fR en el directorio del sistema adecuado
+(bandera \fB\-\-install \fR), lo que puede requerir que \fIsudo\fR escriba en el sistema de directorios.
+.SH "VER TAMBIEN"
+\fIHalcompile Generador de Componentes HAL\fR en la documentacion de LinuxCNC para obtener una descripcion completa de la sintaxis de
+archivos \fB.comp\fR, junto con ejemplos.
+\fBpydoc hal\fR y \fICreando Componentes Python de Espacio de Usuario\fR en la documentacion de LinuxCNC para obtener documentacion
+sobre la interfaz de Python para los componentes HAL
+
+
diff --git a/docs/man/es/man1/halmeter.1 b/docs/man/es/man1/halmeter.1
new file mode 100644
index 0000000000..c9133119e3
--- /dev/null
+++ b/docs/man/es/man1/halmeter.1
@@ -0,0 +1,120 @@
+.\" Copyright (c) 2006 John Kasunich
+.\" (jmkasunich AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH HALMETER "1" "2006-03-13" "Documentacion de LinuxCNC" "Manual HAL del usuario"
+.SH NOMBRE
+halmeter \- observa los pines, se\[~n]ales y parametros de HAL
+.SH SINOPSIS
+.B halmeter
+[\fB\-s\fR] [\fBpin\fR|\fBsig\fR|\fBparam\fR \fIname\fR] [\fB\-g\fR \fIX-positon Y-position [Width] \fR]
+.SH DESCRIPCION
+\fBhalmeter\fR se utiliza para observar pines, se\[~n]ales, o parametros HAL (Capa de abstraccion de hardware).
+Sirve para el mismo proposito que un multimetro cuando se trabaja en sistemas fisicos.
+.SH OPCIONES
+.TP
+\fBpin\fR \fIname\fR
+mostrar el pin HAL \fIname\fR.
+.TP
+\fBsig\fR \fIname \fR
+mostrar la se\[~n]al HAL \fIname\fR.
+.TP
+\fBparam\fR \fIname\fR
+mostrar el parametro HAL \fIname\fR.
+Si no se especifica \fBpin\fR, \fBsig\fR o \fBparam \fR, la ventana comienza en blanco y el usuario debe seleccionar un elemento para observar.
+.TP
+\fB\-s\fR
+ventana peque\[~n]a, no interactiva, que debe utilizarse con \fBpin\fR, \fBsig\fR,
+o \fBparam\fR para seleccionar el elemento a mostrar. Se muestra el nombre del elemento
+en la barra de titulo en lugar de la ventana, y no hay botones "Seleccionar" o "Salir".
+Practico cuando se requieren muchas medidas en un espacio reducido.
+.TP
+\fB\-g\fR
+Posicion de la geometria. Permite especificar la posicion inicial
+y, opcionalmente, el ancho del multimetro. Referenciado desde la parte superior izquierda de la pantalla
+en unidades de pixel.
+Util cuando se requieren muchos multimetros en un script, sin solapar
+uno encima del otro.
+.SH USO
+A menos que se especifique \fB\-s\fR, hay dos botones, "Seleccionar" y "Salir".
+"Seleccionar" abre un cuadro de dialogo para seleccionar el elemento (pin, se\[~n]al o parametro)
+a ser observado. "Exit" termina el multimetro.
+
+El dialogo de seleccion tiene botones "Aceptar", "Aplicar" y "Cancelar". "Aceptar" muestra
+el elemento seleccionado y cierra el dialogo. "Aplicar" muestra el elemento seleccionado
+pero mantiene abierto el dialogo de seleccion. "Cancelar" cierra el dialogo
+sin cambiar el elemento mostrado.
+
+.SH EJEMPLOS
+
+.TP
+\fBhalmeter\fR
+Abre una ventana de medidor, sin mostrar nada inicialmente. Use el boton "Seleccionar"
+para elegir un elemento a observar. No termina hasta que se cierre la ventana.
+.TP
+\fBhalmeter &\fR
+Abre una ventana de medidor, sin mostrar nada inicialmente. Use el boton "Seleccionar"
+boton para elegir un elemento. Se ejecuta en segundo plano dejando el shell libre para otros comandos.
+.TP
+\fBhalmeter pin\fR \fIparport.0.pin\-03\-out\fR \fB&\fR
+Abre una ventana de multimetro, mostrando inicialmente el pin HAL \fIparport.0.pin\-03\-out\fR.
+El boton "Seleccionar" se puede utilizar para mostrar otros elementos. Se ejecuta en segundo plano.
+
+.TP
+\fBhalmeter \-s pin\fR \fIparport.0.pin\-03\-out\fR \fB&\fR
+Abre una peque\[~n]a ventana de multimetro, que muestra el pin HAL \fIparport.0.pin\-03\-out\fR.
+El elemento mostrado no se puede cambiar. Se ejecuta en segundo plano.
+
+.TP
+\fBhalmeter \-s pin\fR \fIparport.0.pin\-03\-out\fR \fB\-g\fR \fI100 500\fR \fB&\fR
+Abre una peque\[~n]a ventana que muestra el pin HAL \fIparport.0.pin\-03\-out\fR y
+la coloca 100 pixeles a la izquierda y 500 pixeles hacia abajo desde la parte superior de la pantalla.
+El elemento mostrado no se puede cambiar. Se ejecuta en segundo plano.
+
+.TP
+\fBhalmeter \-s pin\fR \fIparport.0.pin\-03\-out\fR \fB\-g\fR \fI100 500 400\fR \fB&\fR
+Abre una peque\[~n]a ventana que muestra el pin HAL \fIparport.0.pin\-03\-out\fR y
+la coloca 100 pixeles a la izquierda y 500 pixeles hacia abajo desde la parte superior de la pantalla.
+El ancho sera de 400 pixeles (270 es el valor predeterminado).
+El elemento mostrado no se puede cambiar. Se ejecuta en segundo plano.
+
+.SH "VER TAMBIEN"
+
+.SH HISTORIA
+
+.SH ERRORES
+
+.SH AUTOR
+Version original de John Kasunich, como parte del proyecto LinuxCNC.
+Mejoras de varios otros miembros de
+El equipo de desarrollo de LinuxCNC.
+.SH REPORTAR ERRORES
+Informar errores a jmkasunich AT usuarios DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2003 John Kasunich.
+.br
+Este es un software libre; ver las fuentes para condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPoSITO PARTICULAR.
+
+
diff --git a/docs/man/es/man1/halrun.1 b/docs/man/es/man1/halrun.1
new file mode 100644
index 0000000000..202b9f4d73
--- /dev/null
+++ b/docs/man/es/man1/halrun.1
@@ -0,0 +1,106 @@
+.\" Copyright (c) 2003 John Kasunich
+.\" (jmkasunich AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.de URL
+\\$2 \(laURL: \\$1 \(ra\\$3
+..
+.if \n[.g] .mso www.tmac
+.TH HALRUN "1" "2012-01-31" "Documentacion de LinuxCNC" "Manual HAL del usuario"
+.SH NOMBRE
+halrun \- manipula HAL de LinuxCNC desde la linea de comandos
+.SH SINOPSIS
+.B halrun \fI\-h\fR
+.PP
+.B halrun [\fI\-I\fR] [\fIhalcmd_opts\fR] [\fInombre_de_archivo[.hal|.tcl]\fR]
+.PP
+.B halrun \fI\-T\fR [\fIhalcmd_opts\fR] [\fInombre_de_archivo[.hal|.tcl]\fR]
+.PP
+.B halrun \fI\-U\fR
+.SH DESCRIPCION
+\fBhalrun\fR es un script de conveniencia que se utiliza para manipular la HAL (
+Capa de abstraccion Hardware) desde la linea de comando. Cuando se invoca, \fBhalrun\fR:
+
+ Configura el entorno en tiempo real.
+ Ejecuta un interprete de comandos (\fBhalcmd\fR o \fBhaltcl\fR).
+ Ejecuta una sesion interactiva (opcionalmente).
+ Destruye el entorno en tiempo real.
+
+ Si no se especifica ningun nombre de archivo, se inicia una sesion interactiva.
+ La sesion utilizara \fBhalcmd\fR(1) a menos que se especifique \-T en
+ en que caso se utilizara \fBhaltcl\fR(1).
+
+ Si se especifica un nombre de archivo y ni la opcion \-I ni la opcion \-T
+ estan incluidas, el nombre del archivo sera procesado por el interprete de comandos
+ correspondiente a la extension de nombre de archivo (\fBhalcmd\fR
+ o \fBhaltcl\fR). Despues del procesamiento, el entorno en tiempo real.
+ sera destruido.
+
+ Si se especifica un nombre de archivo y se incluye la opcion \-I o \-T,
+ el archivo es procesado por el interprete de comandos apropiado y
+ luego se inicia una sesion interactiva para \fBhalcmd\fR o
+ \fBhaltcl\fR de acuerdo con la opcion \-I o \-T.
+
+.SH OPCIONES
+.TP
+\fBhalcmd_opts\fR
+Cuando se especifica un archivo .hal, los \fBhalcmd_opts\fR son
+pasados a \fBhalcmd\fR. Consulte la pagina de manual de \fBhalcmd\fR(1).
+Cuando se especifica un archivo .tcl, las unicas opciones validas son:
+ \-i inifile
+ \-f nombre de archivo[.tcl|.hal] (alterna con la especificacion del archivo)
+.TP
+\fB\-I\fR
+Ejecutar una sesion interactiva de \fBhalcmd\fR
+.TP
+\fB\-T\fR
+Ejecutar una sesion interactiva de \fBhaltcl\fR.
+.TP
+\fB\-U\fR
+Forzar la salida del entorno en tiempo real. Libera el mutex HAL,
+solicita que se descarguen todos los componentes de HAL y detiene el sistema en tiempo real.
+\fB\-U\fR debe ser el unico argumento de la linea de comandos.
+.TP
+\fB\\-h\fR
+Mostrar una breve pantalla de ayuda y salir
+.SH EJEMPLOS
+.SH HISTORIA
+.SH ERRORES
+Ninguno conocido en este momento.
+.SH AUTOR
+Version original de John Kasunich, como parte del Proyecto de controlador de maquina mejorada LinuxCNC.
+Ahora incluye importantes aportaciones de varios miembros del proyecto.
+.SH COMUNICACION DE ERRORES
+Informar de errores a
+.URL http://sf.net/p/emc/bugs/ "LinuxCNC bug tracker".
+.SH COPYRIGHT
+Copyright \(co 2003 John Kasunich.
+.br
+Este es un software libre; ver las fuentes para condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPoSITO PARTICULAR.
+
+.SH "VER TAMBIEN"
+\fBhalcmd\fR(1), \fBhaltcl\fR(1)
+
+
diff --git a/docs/man/es/man1/halsampler.1 b/docs/man/es/man1/halsampler.1
new file mode 100644
index 0000000000..497010d41c
--- /dev/null
+++ b/docs/man/es/man1/halsampler.1
@@ -0,0 +1,163 @@
+.\" Copyright (c) 2006 John Kasunich
+.\" (jmkasunich AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH HALSAMPLER "1" "2006-11-18" "Documentacion de LinuxCNC" "Manual HAL del usuario"
+.SH NOMBRE
+halsampler \- muestrea datos de HAL en tiempo real
+.SH SINOPSIS
+.B halsampler
+.RI [opciones]
+
+.SH DESCRIPCION
+.BR sampler(9)
+y
+.B halsampler
+se utilizan juntos para muestrear datos HAL en tiempo real y almacenarlos en un archivo.
+.B sampler
+es un componente HAL en tiempo real que exporta pines HAL y crea una FIFO en la memoria compartida. Luego comienza a muestrear los datos de HAL y los almacena en la FIFO.
+.B halsampler
+es un programa de espacio de usuario que copia los datos de la FIFO a la salida estandar, donde pueden
+ser redirigidos a un archivo o canalizados a algun otro programa.
+
+.SH OPCIONES
+.TP
+.BI "\-c " CHAN
+Instruye a
+.B halsampler
+para leer de la FIFO
+.IR CHAN.
+Las FIFO se numeran desde cero y el valor predeterminado es cero, por lo que
+esta opcion no es necesaria a menos que se hayan creado multiples FIFOs.
+.TP
+.BI "\-n " COUNT
+Instruye a
+.B halsampler
+para leer
+.I COUNT
+muestras de la FIFO y luego salir. Si
+.B \-n
+no se especifica,
+.B halsampler
+Leera continuamente hasta que se mate.
+.TP
+.B \-t
+Instruye a
+.B halsampler
+para etiquetar cada linea imprimiendo el numero de muestra en la primera columna.
+.TP
+.B FILENAME
+Instruye a
+.B halsampler
+para escribir en \fBFILENAME\fR en lugar de en stdout.
+.SH USO
+Debe crearse primero una FIFO, cargando
+.BR sampler (9)
+con
+.B halcmd loadrt
+o con un comando
+.B loadrt
+en un archivo .hal. Despues
+.B halsampler
+se puede invocar para comenzar a imprimir datos desde la FIFO a la salida estandar.
+.P
+Los datos se imprimen una linea por muestra. Si se especifico
+.B \-t
+, el numero de muestra se imprime primero. Siguen los datos, en el
+orden que los pines fueron definidos en la cadena de configuracion. Por ejemplo, si la cadena de configuracion de
+.B sampler
+era "ffbs", entonces una linea tipica de salida (sin
+.BR \-t)
+se veria como
+.P
+123.55 33.4 0 \-12
+.P
+.B halsampler
+imprime los datos lo mas rapido posible hasta que la FIFO queda vacia, luego reintenta a intervalos regulares, hasta que se elimina o se imprime
+.I COUNT
+muestras solicitadas por
+.BR \-n.
+Por lo general, pero no siempre, los datos impresos por
+.B halsampler
+seran redirigido a un archivo o canalizados a algun otro programa.
+.P
+El tama\[~n]o de la FIFO debe elegirse para absorber las muestras capturadas durante cualquier interrupcion momentanea en el flujo de datos, como busquedas en disco, desplazamiento del terminal o limitaciones de procesamiento del programa posterior en una tuberia. Si la FIFO se
+llena, y
+.B sampler
+queda obligado a sobrescribir los datos antiguos,
+.B halsampler
+imprimira 'sobrepasado' en una linea para marcar cada gap en el muestreo de
+datos. Si se especifico
+.B \-t
+, los gaps en los numeros de muestra secuenciales en la primera columna
+se pueden usar para determinar exactamente cuantas muestras se perdieron.
+.P
+El formato de datos de salida de
+.B halsampler
+es el mismo que el de entrada de
+.BR halstreamer(1)
+, por lo que 'formas de onda' capturadas con
+.B halsampler
+se puede reproducir utilizando
+.BR halstreamer.
+La opcion
+.B \-t
+no debe ser utilizada en este caso.
+
+.SH "ESTADO DE SALIDA"
+Si se encuentra un problema durante la inicializacion,
+.B halsampler
+imprime un mensaje a stderr y devuelve el error.
+.P
+Al imprimir
+.I COUNT
+muestras (si
+.B \-n
+fue especificado) se cerrara y devolvera exito. Si es terminado
+antes de imprimir el numero especificado de muestras, devuelve error. Esto
+significa que cuando
+.B \-n
+no se especifica, siempre devolvera un error cuando termine.
+
+.SH "VER TAMBIEN"
+.BR sampler(9)
+.BR streamer(9)
+.BR halstreamer(1)
+
+.SH HISTORIA
+
+.SH ERRORES
+
+.SH AUTOR
+Version original de John Kasunich, como parte del proyecto LinuxCNC.
+Mejoras de varios otros miembros del equipo de desarrollo de LinuxCNC.
+.SH REPORTAR ERRORES
+Informar errores a jmkasunich AT usuarios DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2006 John Kasunich.
+.br
+Este es un software libre; ver las fuentes para condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPoSITO PARTICULAR.
+
+
diff --git a/docs/man/es/man1/halstreamer.1 b/docs/man/es/man1/halstreamer.1
new file mode 100644
index 0000000000..fe7b949249
--- /dev/null
+++ b/docs/man/es/man1/halstreamer.1
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: halstreamer
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1
+.\" Date: 08/11/2020
+.\" Manual: LinuxCNC Documentation
+.\" Source: LinuxCNC
+.\" Language: English
+.\"
+.TH "HALSTREAMER" "1" "08/11/2020" "LinuxCNC" "LinuxCNC Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+halstreamer \- stream file data into HAL in real time
+.SH "SYNOPSIS"
+.sp
+\fBhalstreamer\fR [\fIoptions\fR]
+.SH "DESCRIPTION"
+.sp
+\fBstreamer\fR(9) and \fBhalstreamer\fR are used together to stream data from a file into the HAL in real time\&. \fBstreamer\fR is a realtime HAL component that exports HAL pins and creates a FIFO in shared memory\&. \fBhal_streamer\fR is a user space program that copies data from stdin into the FIFO, so that \fBstreamer\fR can write it to the HAL pins\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR \fICHAN\fR
+.RS 4
+Instructs
+\fBhalstreamer\fR
+to write to FIFO
+\fICHAN\fR\&. FIFOs are numbered from zero, and the default value is zero, so this option is not needed unless multiple FIFOs have been created\&.
+.RE
+.PP
+\fIFILENAME\fR
+.RS 4
+Instructs
+\fBhalsampler\fR
+to read from
+\fIFILENAME\fR
+instead of from stdin\&.
+.RE
+.SH "USAGE"
+.sp
+A FIFO must first be created by loading \fBstreamer\fR(9) with \fBhalcmd loadrt\fR or a \fBloadrt\fR command in a \&.hal file\&. Then \fBhalstreamer\fR can be invoked to begin writing data into the FIFO\&.
+.sp
+Data is read from stdin, and is almost always either redirected from a file or piped from some other program, since keyboard input would be unable to keep up with even slow streaming rates\&.
+.sp
+Each line of input must match the pins that are attached to the FIFO, for example, if the \fBstreamer\fR config string was "ffbs" then each line of input must consist of two floats, a bit, and a signed integer, in that order and separated by whitespace\&. Floats must be formatted as required by \fBstrtod\fR(3), signed and unsigned integers must be formated as required by \fBstrtol\fR(3) and \fBstrtoul\fR(3), and bits must be either \fI0\fR or \fI1\fR\&.
+.sp
+Input lines that begin with \fI#\fR will be treated as comments and silently skipped\&.
+.sp
+\fBhalstreamer\fR transfers data to the FIFO as fast as possible until the FIFO is full, then it retries at regular intervals, until it is either killed or reads EOF from stdin\&. Data can be redirected from a file or piped from some other program\&.
+.sp
+The FIFO size should be chosen to ride through any momentary disruptions in the flow of data, such as disk seeks\&. If the FIFO is big enough, \fBhalstreamer\fR can be restarted with the same or a new file before the FIFO empties, resulting in a continuous stream of data\&.
+.sp
+The data format for \fBhalstreamer\fR input is the same as for \fBhalsampler\fR(1) output, so \fIwaveforms\fR captured with \fBhalsampler\fR can be replayed using \fBhalstreamer\fR\&.
+.SH "EXIT STATUS"
+.sp
+If a problem is encountered during initialization, \fBhalstreamer\fR prints a message to stderr and returns failure\&.
+.sp
+If a badly formatted line is encountered while writing to the FIFO, it prints a message to stderr, skips the line, and continues (this behavior may be revised in the future)\&.
+.sp
+Upon reading EOF from the input, it returns success\&. If it is terminated before the input ends, it returns failure\&.
+.SH "SEE ALSO"
+.sp
+\fBstreamer\fR(9) \fBsampler\fR(9) \fBhalsampler\fR(1)
+.SH "AUTHOR"
+.sp
+Original version by John Kasunich, as part of the LinuxCNC project\&. Improvements by several other members of the LinuxCNC development team\&.
+.SH "REPORTING BUGS"
+.sp
+Report bugs to jmkasunich AT users DOT sourceforge DOT net
+.SH "COPYRIGHT"
+.sp
+Copyright \(co 2006 John Kasunich\&. This is free software; see the source for copying conditions\&. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\&.
diff --git a/docs/man/es/man1/haltcl.1 b/docs/man/es/man1/haltcl.1
new file mode 100644
index 0000000000..e17dfcb225
--- /dev/null
+++ b/docs/man/es/man1/haltcl.1
@@ -0,0 +1,94 @@
+.\" Copyright (c) 2003 John Kasunich
+.\" (jmkasunich AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.de URL
+\\$2 \(laURL: \\$1 \(ra\\$3
+..
+.if \n[.g] .mso www.tmac
+.TH HALTCL "1" "2012-01-31" "Documentacion de LinuxCNC" "Manual HAL del usuario"
+.SH NOMBRE
+haltcl \- manipula HAL de LinuxCNC desde la linea de comandos usando un interprete tcl.
+
+.SH SINOPSIS
+.B haltcl [\fI\-i inifile\fR] [\fIfilename\fR\]
+.PP
+
+.SH DESCRIPCION
+\fBhaltcl\fR se utiliza para manipular la HAL (Capa de abstraccion de hardware)
+desde la linea de comando usando un interprete tcl. \fBhaltcl\fR
+puede, opcionalmente, leer comandos desde un archivo (filename), permitiendo que
+configuraciones complejas de HAL establezcan con un solo comando.
+
+.SH OPCIONES
+.TP
+\fB\-i\fR \fIinifile\fR
+Si se especifica, el archivo inifile se lee y se usa para crear una matriz de variables globales tcl.
+Se crea una matriz para cada SECCION del archivo inifile con
+elementos para cada ITEM en la seccion.
+.P
+ Por ejemplo, si el archivo inifile contiene:
+ [SECTION_A]ITEM_1 = 1
+ [SECTION_A]ITEM_2 = 2
+ [SECTION_B]ITEM_1 = 10
+
+ Las variables tcl correspondientes son:
+ SECTION_A(ITEM_1) = 1
+ SECTION_A(ITEM_2) = 2
+ SECTION_B(ITEM_1) = 10
+.TP
+\fB\-ini\fR \fIinifile\fR - uso desaconsejado. En su lugar use \fB\-i\fR \fIinifile\fR
+.TP
+\fBfilename\fR
+Si se especifica, se ejecutan los comandos tcl de \fBfilename\fR. Si no se especifica ningun nombre de archivo,
+haltcl abre una sesion interactiva.
+
+.SH COMANDOS
+\fBhaltcl\fR incluye los comandos de un interprete tcl ampliado con
+comandos para el lenguaje hal como los descritos para \fBhalcmd\fR(1).
+Los comandos se pueden enumerar con:
+
+ haltcl: hal \-\-commands
+
+ addf alias delf delsig getp gets ptype stype help linkpp linkps linksp list loadrt loadusr lock net newsig save setexact_for_test_suite_only setp sets show source start status stop unalias unlinkp unload unloadrt unloadusr unlock waitusr
+
+Dos de los comandos ampliados, 'list' y 'gets', requieren un tratamiento especial para
+evitar conflictos con los comandos incorporados de tcl que tienen los mismos nombres. Usar estos
+comandos precedidos con la palabra clave 'hal':
+
+ hal list
+ hal gets
+
+.SH REPORTE DE ERRORES
+Informar de errores a la
+.URL http://sf.net/p/emc/bugs/ "LinuxCNC bug tracker".
+.SH COPYRIGHT
+.br
+Este es un software libre; ver las fuentes para condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPoSITO PARTICULAR.
+
+.SH VER TAMBIEN
+\fBhalcmd\fR(1), \fBhalrun\fR(1)
+
+
diff --git a/docs/man/es/man1/halui.1 b/docs/man/es/man1/halui.1
new file mode 100644
index 0000000000..1fa20b262c
--- /dev/null
+++ b/docs/man/es/man1/halui.1
@@ -0,0 +1,575 @@
+.\" Copyright (c) 2006 Alex Joni
+.\" (alex_joni AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH HALUI "1" "2006-07-22" "Documentacion de LinuxCNC" "Interfaz HAL de usuario"
+.SH NOMBRE
+halui \- observacion de los pines HAL y ordenes LinuxCNC a traves de NML
+.SH SINOPSIS
+.B halui
+[\fB\-ini \fR]
+.SH DESCRIPCION
+\fBhalui\fR se usa para construir una interfaz de usuario usando mandos
+e interruptores hardware. Exporta un gran numero de pines, y actua en consecuencia
+cuando estos cambian
+.SH OPCIONES
+.TP
+\fB\-ini name\fR
+Use \fIname\fR como el archivo de configuracion. Nota: halui debe encontrar el
+archivo nml especificado en el ini; normalmente ese archivo esta en la misma
+carpeta que el ini, por lo que tiene sentido ejecutar halui desde esa carpeta.
+.SH USO
+Cuando se ejecuta, \fBhalui\fR exportara una gran cantidad de pines. Un usuario puede conectarlos
+a sus mandos fisicos, interruptores y leds, y cuando se produzca un cambio,
+Halui disparara el evento apropiado.
+
+\fBhalui\fR espera que las se\[~n]ales sean limpias, por lo que si es necesario (contacto con ruido en el boton), conecte primero el boton fisico a un filtro debounce HAL.
+
+.SH PINS
+
+.SS Abortar
+.TP
+.B halui.abort\fR bit in \fR
+pin para borrar la mayoria de los errores
+
+.SS Herramientas
+.TP
+.B halui.tool.length\-offset.a\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje A
+.TP
+.B halui.tool.length\-offset.b\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje B
+.TP
+.B halui.tool.length\-offset.c\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje C
+.TP
+.B halui.tool.length\-offset.u\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje U
+.TP
+.B halui.tool.length\-offset.v\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje V
+.TP
+.B halui.tool.length\-offset.w\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje W
+.TP
+.B halui.tool.length\-offset.x\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje X
+.TP
+.B halui.tool.length\-offset.y\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje Y
+.TP
+.B halui.tool.length\-offset.z\fR float out \fR
+Offset aplicado de la longitud de la herramienta actual para el eje Z
+.TP
+.B halui.tool.diameter\fR float out \fR
+Diametro actual de la herramienta, o 0 si no hay ninguna herramienta cargada.
+.TP
+.B halui.tool.number\fR u32 out \fR
+herramienta seleccionada actual
+
+.SS Husillo
+.TP
+.B halui.spindle.brake\-is\-on\fR bit out \fR
+Pin de estado que dice si el freno esta activado
+.TP
+.B halui.spindle.brake\-off\fR bit in \fR
+Pin para desactivar el freno del husillo.
+.TP
+.B halui.spindle.brake\-on\fR bit in \fR
+Pin para activar el freno de husillo
+.TP
+.B halui.spindle.decrease\fR bit in \fR
+Un flanco ascendente en este pin disminuye la velocidad actual del husillo en 100
+.TP
+.B halui.spindle.forward\fR bit in \fR
+Un flanco ascendente en este pin hace que el husillo gire en sentido normal
+.TP
+.B halui.spindle.increase\fR bit in \fR
+Un flanco ascendente en este pin aumenta la velocidad actual del husillo en 100
+.TP
+.B halui.spindle.is\-on\fR bit out \fR
+Pin de estado que indica si el husillo esta encendido
+.TP
+.B halui.spindle.reverse\fR bit in \fR
+Un flanco ascendente en este pin hace que el husillo gire en sentido inverso
+.TP
+.B halui.spindle.runs\-backward\fR bit out \fR
+Pin de estado que indica si el eje esta en sentido inverso
+.TP
+.B halui.spindle.runs\-forward\fR bit out \fR
+Pin de estado que indica si el eje esta en sentido normal
+.TP
+.B halui.spindle.start\fR bit in \fR
+Un flanco ascendente en este pin inicia el husillo
+.TP
+.B halui.spindle.stop\fR bit in \fR
+Un flanco ascendente en este pin detiene el husillo
+
+.SS Ajuste del husillo (override)
+.TP
+(SO = Spindle Override. FO = Feed Override)
+.TP
+.B halui.spindle\-override.count\-enable\fR bit in \fR (por defecto: \fBTRUE\fR)
+Cuando sea VERDADERO, modifica el ajuste del husillo cuando los recuentos cambien.
+.TP
+.B halui.spindle\-override.counts\fR s32 in \fR
+cuenta X escala = porcentaje de ajuste del husillo
+.TP
+.B halui.spindle\-override.decrease\fR bit in \fR
+pin para disminuir el SO (\-=escala)
+.TP
+.B halui.spindle\-override.direct \-value\fR bit in \fR
+pin para habilitar la entrada del valor directo de ajuste del husillo
+.TP
+.B halui.spindle\-override.increase\fR bit in \fR
+pin para aumentar el SO (+= escala)
+.TP
+.B halui.spindle\-override.scale\fR float in \fR
+pin para establecer la escala de cuentas para SO
+.TP
+.B halui.spindle\-override.value\fR float out \fR
+valor actual de FO
+
+.SS Programa
+.TP
+.B halui.program.block\-delete.is\-on\fR bit out \fR
+Pin de estado que indica que la eliminacion de bloque esta activada
+.TP
+.B halui.program.block\-delete.off\fR bit in \fR
+pin para solicitar que la eliminacion de bloque este desactivada
+.TP
+.B halui.program.block\-delete.on\fR bit in \fR
+pin para solicitar que la eliminacion de bloque esta activada
+.TP
+.B halui.program.is\-idle\fR bit out \fR
+Pin de estado diciendo que no hay ningun programa en ejecucion
+.TP
+.B halui.program.is\-paused\fR bit out \fR
+Pin de estado que indica que un programa esta en pausa
+.TP
+.B halui.program.is\-running\fR bit out \fR
+pin de estado que dice que un programa se esta ejecutando
+.TP
+.B halui.program.optional\-stop.is\-on\fR bit out \fR
+Pin de estado que indica que la parada opcional esta activada
+.TP
+.B halui.program.optional\-stop.off\fR bit in \fR
+pin solicitando que la parada opcional este desactivada
+.TP
+.B halui.program.optional\-stop.on\fR bit in \fR
+pin solicitando que la parada opcional este activada
+.TP
+.B halui.program.pause\fR bit in \fR
+pin para pausar un programa
+.TP
+.B halui.program.resume\fR bit in \fR
+pin para reanudar un programa
+.TP
+.B halui.program.run\fR bit in \fR
+pin para ejecutar un programa
+.TP
+.B halui.program.step\fR bit in \fR
+pin para avanzar en un programa
+.TP
+.B halui.program.stop\fR bit in \fR
+pin para detener un programa
+(nota: este pin hace lo mismo que halui.abort)
+
+.SS Modo
+.TP
+.B halui.mode.auto\fR bit in \fR
+pin para solicitar el modo auto
+.TP
+.B halui.mode.is\-auto\fR bit out \fR
+pin para se\[~n]alar modo auto activado
+.TP
+.B halui.mode.is\-joint\fR bit out \fR
+pin para articulacion en modo de jog de articulacion activado
+.TP
+.B halui.mode.is \-manual\fR bit out \fR
+pin para se\[~n]alar modo manual activado
+.TP
+.B halui.mode.is\-mdi\fR bit out \fR
+pin para se\[~n]alar modo mdi activado
+.TP
+.B halui.mode.is\-teleop\fR bit out \fR
+pin para se\[~n]alar que el modo jog coordinado esta activado
+.TP
+.B halui.mode.joint\fR bit in \fR
+pin para solicitar articulacion en modo jog articulacion
+.TP
+.B halui.mode.manual\fR bit in \fR
+pin para solicitar modo manual
+.TP
+.B halui.mode.mdi\fR bit in \fR
+pin para solicitar modo mdi
+.TP
+.B halui.mode.teleop\fR bit in \fR
+pin para solicitar el modo jog coordinado
+
+.SS mdi \fR(opcional)
+.TP
+.B halui.mdi\-command\-XX\fR bit in \fR
+\fBhalui\fR busca las variables ini [HALUI]MDI_COMMAND, y
+exporta un pin para cada comando que encuentra. Cuando el pin se hace VERDADERO,
+\fBhalui\fR ejecuta el comando MDI especificado. XX es un numero de dos digitos
+a partir de 00. Si no se establecen variables [HALUI]MDI_COMMAND en el archivo ini,
+no seran exportados pines halui.mdi\-command\-XX.
+
+.SS niebla
+.TP
+.B halui.mist.is\-on\fR bit out \fR
+pin para se\[~n]alar niebla activada
+.TP
+.B halui.mist.off\fR bit in \fR
+pin para detener niebla
+.TP
+.B halui.mist.on\fR bit in \fR
+pin para activar niebla
+
+.SS max\-velocidad
+.TP
+.B halui.max\-velocity.count\-enable\fR bit in \fR (por defecto: \fBTRUE \fR)
+Cuando sea VERDADERO, modifica la velocidad maxima cuando cambie halui.max\-velocity.counts.
+.TP
+.B halui.max\-velocity.counts\fR s32 in \fR
+Cuando .count\-enable es VERDADERO, halui cambia la velocidad maxima en respuesta
+a cambios en este pin. Por lo general, esta conectado a un MPG en
+un panel de operador o jog colgante. Cuando .count\-enable es FALSO, halui
+ignora este pin.
+.TP
+.B halui.max\-velocity.direct\-value\fR bit in \fR
+Cuando este pin es VERDADERO, halui ordena la velocidad maxima directamente a
+(.counts * .scale). Cuando este pin es FALSO, halui ordena la maxima
+velocidad de forma relativa: cambie la velocidad maxima en una cantidad igual a
+(cambio en .counts * .scale).
+.TP
+.B halui.max\-velocity.increase\fR bit in \fR
+Un flanco positivo (una transicion de FALSO a VERDADERO) en este pin aumenta la
+velocidad maxima por el valor del pin de escala. (Tenga en cuenta que halui siempre
+responde a este pin, independientemente del pin .count\-enable.)
+.TP
+.B halui.max\-velocity.decrease\fR bit in \fR
+Un flanco positivo (una transicion de FALSO a VERDADERO) en este pin disminuye la
+velocidad maxima por el valor del pin de escala. (Tenga en cuenta que halui siempre
+responde a este pin, independientemente del pin .count\-enable.)
+.TP
+.B halui.max\-velocity.scale\fR float in \fR
+Este pin controla la escala de cambios a la velocidad maxima. Cada unidad
+cambia en .counts, y cada flanco positivo en .increase y .decrease,
+cambia la velocidad maxima por la escala. Las unidades del pin de escala son
+unidades\-maquina por segundo.
+.TP
+.B halui.max\-velocity.value\fR float out \fR
+Valor actual para la velocidad maxima, en unidades\-maquina por segundo.
+
+.SS maquina
+.TP
+.B halui.machine.units\-per\-mm\fR float out \fR
+pin para unidades\-maquina\-per\-mm (pulgada: 1 / 25.4, mm: 1)
+de acuerdo con la configuracion inifile: [TRAJ]LINEAR_UNITS
+.TP
+.B halui.machine.is\-on\fR bit out \fR
+pin que se\[~n]ala maquina encendida/apagada
+.TP
+.B halui.machine.off\fR bit in \fR
+pin para apagado de la maquina
+.TP
+.B halui.machine.on\fR bit in \fR
+pin para encendido de la maquina
+
+.SS lubricacion
+.TP
+.B halui.lube.is\-on\fR bit out \fR
+pin que se\[~n]ala lubricacion encendida
+.TP
+.B halui.lube.off\fR bit in \fR
+pin para detener la lubricacion
+.TP
+.B halui.lube.on\fR bit in \fR
+pin para activar la lubricacion
+
+.SS Articulaciones (joints) \fR(\fBN\fR = numero de articulacion (0 ... num_joints\-1))
+.TP
+.B halui.joint.N.select\fR bit in \fR
+pin para seleccionar la articulacion N
+.TP
+.B halui.joint.N.is\-selected\fR bit out \fR
+pin de estado; articulacion N seleccionada
+.TP
+.B halui.joint.N.has\-fault\fR bit out \fR
+pin de estado; la articulacion N tiene un fallo
+.TP
+.B halui.joint.N.home\fR bit in \fR
+pin para referenciado de la articulacion N
+.TP
+.B halui.joint.N.is\-homed\fR bit out \fR
+pin de estado; la articulacion N esta referenciada
+.TP
+.B halui.joint.N.on\-hard\-max\-limit\fR bit out \fR
+pin de estado; la articulacion N esta en el limite hardware positivo
+.TP
+.B halui.joint.N.on\-hard\-min\-limit\fR bit out \fR
+pin de estado; la articulacion N esta en el limite hardware negativo
+.TP
+.B halui.joint.N.on\-soft\-max\-limit\fR bit out \fR
+pin de estado; la articulacion N esta en el limite software positivo
+.TP
+.B halui.joint.N.on\-soft\-min\-limit\fR bit out \fR
+pin de estado; la articulacion N esta en el limite software negativo
+.TP
+.B halui.joint.N.override\-limits\fR bit out \fR
+pin de estado; los limites de articulacion N se anulan temporalmente
+.TP
+.B halui.joint.N.unhome\fR bit in \fR
+pin para desreferenciar articulacion N
+.TP
+.B halui.joint.selected\fR u32 out \fR
+pin de numero de articulacion seleccionado (0 ... num_joints\-1)
+.TP
+.B halui.joint.selected.has\-fault\fR bit out \fR
+pin pin de estado; seleccion de articulacion ha fallado
+.TP
+.B halui.joint.selected.home\fR bit in \fR
+pin para referenciar la articulacion seleccionada
+.TP
+.B halui.joint.selected.is\-homed\fR bit out \fR
+pin de estado; indica que la articulacion seleccionada esta referenciada.
+.TP
+.B halui.joint.selected.on\-hard\-max\-limit\fR bit out \fR
+pin de estado; indica que la articulacion seleccionada esta en el limite hardware positivo
+.TP
+.B halui.joint.selected.on\-hard\-min\-limit\fR bit out \fR
+pin de estado; indica que la articulacion seleccionada esta en el limite hardware negativo
+.TP
+.B halui.joint.selected.on\-soft\-max\-limit\fR bit out \fR
+pin de estado; indica que la articulacion seleccionada esta en el limite software positivo
+.TP
+.B halui.joint.selected.on\-soft\-min\-limit\fR bit out \fR
+pin de estado; indica que la articulacion seleccionada esta en el limite software negativo
+.TP
+.B halui.joint.selected.override \-limits\fR bit out \fR
+pin de estado; indica que los limites de la articulacion seleccionada se anulan temporalmente
+.TP
+.B halui.joint.selected.unhome\fR bit in \fR
+pin para desreferenciar la articulacion seleccionada
+
+.SS jogging de articulacion \fR(\fBN\fR = numero de articulacion (0 ... num_joints \-1))
+.B halui.joint.jog\-deadband\fR float in \fR
+Pin para configurar la banda muerta analogica de jog (entradas analogicas jog mas peque\[~n]as o lentas que
+este valor (en valor absoluto) se ignora)
+.TP
+.B halui.joint.jog\-speed\fR float in \fR
+pin para ajustar la velocidad de jog para jogging mas/menos
+.TP
+.B halui.joint.N.analog\fR float in \fR
+pin para mover la articulacion N usando un valor flotante (por ejemplo, un joystick). El valor, tipicamente
+establecido entre 0.0 y \ (+ - 1.0), se usa como un multiplicador jog\-speed.
+.TP
+.B halui.joint.N.increment\fR float in \fR
+pin para configurar el incremento de jog para la articulacion N cuando se utiliza el incremento \-plus/minus
+.TP
+.B halui.joint.N.increment\-minus\fR bit in \fR
+un flanco ascendente hara un movimiento de articulacion N en la direccion negativa por la cantidad de incremento
+.TP
+.B halui.joint.N.increment\-plus\fR bit in \fR
+un flanco ascendente hara un movimiento de articulacion N en la direccion positiva por la cantidad de incremento
+.TP
+.B halui.joint.N.minus\fR bit in \fR
+pin para jog de la articulacion N en direccion negativa en la velocidad halui.joint.jog\-speed
+.TP
+.B halui.joint.N.plus\fR bit in \fR
+pin para jog de la articulacion N en direccion positiva a la velocidad halui.joint.jog\-speed
+.TP
+.B halui.joint.selected.increment\fR float in \fR
+pin para configurar el incremento de jog para la articulacion seleccionada cuando se utiliza el incremento \-plus/minus
+.TP
+.B halui.joint.selected.increment\-minus\fR bit in \fR
+un flanco ascendente hara un jog de articulacion seleccionada, en la direccion negativa, la cantidad de incremento
+.TP
+.B halui.joint.selected.increment\-plus\fR bit in \fR
+un flanco ascendente hara un jog de articulacion seleccionada, en la direccion positiva, la cantidad de incremento
+.TP
+.B halui.joint.selected.minus\fR bit in \fR
+pin para mover la articulacion seleccionada en direccion negativa a la velocidad halui.joint.jog\-speed
+.TP
+.B halui.joint.selected.plus \fR bit in \fR
+pin para jog de la articulacion seleccionada en direccion positiva a la velocidad halui.joint.jog\-speed
+
+.SS Ejes (axis) \fB(\fBL\fR = indice del eje (0:x 1:y 2:z 3:a 4:b 5:c 6:u 7:v 8:w))
+.TP
+.B halui.axis.L.select\fR bit in \fR
+Pin para seleccionar eje por indice
+.TP
+.B halui.axis.L.is \-selected\fR bit out \fR
+pin de estado; el eje L esta seleccionado
+.TP
+.B halui.axis.L.pos\-commanded\fR float out \fR
+Posicion ordenada del eje, en coordenadas maquina.
+.TP
+.B halui.axis.L.pos\-feedback\fR float out\ fR
+Realimentacion de posicion del eje, en coordenadas maquina.
+.TP
+.B halui.axis.L.pos\-relative\fR float out \fR
+Posicion ordenada del eje, en coordenadas relativas.
+
+.SS axis jogging \fR(\fBL\fR = indice del eje (0:x 1:y 2:z 3:a 4:b 5:c 6:u 7:v 8:w)
+.TP
+.B halui.axis.jog\-deadband\fR float in \fR
+Pin para configurar la banda muerta analogica de jog (entradas analogicas jog mas peque\[~n]as o lentas que
+este valor (en valor absoluto) se ignora)
+.TP
+.B halui.axis.jog\-speed\fR float in \fR
+pin para ajustar la velocidad de jog para jogging mas/menos
+.TP
+.B halui.axis.L.analog\fR float in \fR
+pin para mover el eje L utilizando un valor flotante (por ejemplo, un joystick). El valor, tipicamente
+establecido entre 0.0 y \(+-1.0, se usa como un multiplicador jog\-speed.
+.TP
+.B halui.axis.L.increment\fR float in \fR
+pin para configurar el incremento de jog para el eje L cuando se utiliza el incremento \-plus/minus
+.TP
+.B halui.axis.L.increment\-minus\fR bit in \fR
+un flanco ascendente hara que el eje L avance, en la direccion negativa, la cantidad de incremento
+.TP
+.B halui.axis.L.increment\-plus\fR bit in \fR
+un flanco ascendente hara que el eje L avance, en la direccion positiva, la cantidad de incremento
+.TP
+.B halui.axis.L.minus\fR bit in \fR
+pin para mover el eje L, en direccion negativa, a la velocidad halui.axis.jog\-speed
+.TP
+.B halui.axis.L.plus\fR bit in \fR
+pin para mover el eje L, en direccion positiva, a la velocidad halui.axis.jog\-speed
+.TP
+.B halui.axis.selected\fR u32 out \fR
+eje seleccionado (por indice: (0:x 1:y 2:z 3:a 4:b 5:c 6:u 7:v 8:w)
+.TP
+.B halui.axis.selected.increment\fR float in \fR
+pin para configurar el incremento de jog para el eje seleccionado cuando se utiliza el incremento \-plus/minus
+.TP
+.B halui.axis.selected.increment \-minus\fR bit in \fR
+un flanco ascendente hara que el eje seleccionado avance, en la direccion negativa, la cantidad de incremento
+.TP
+.B halui.axis.selected.increment \-plus\fR bit in \fR
+un flanco ascendente hara que el eje seleccionado avance, en la direccion positiva, la cantidad de incremento
+.TP
+.B halui.axis.selected.minus\fR bit in \fR
+pin para mover el eje seleccionado, en direccion negativa, a la velocidad de velocidad halui.axis.jog\-speed
+.TP
+.B halui.axis.selected.plus \fR bit in \fR
+pin para mover el eje seleccionado, en direccion positiva, a la velocidad halui.axis.jog\-speed
+
+.SS inundacion
+.TP
+.B halui.flood.is\-on\fR bit out \fR
+pin para inundacion ON
+.TP
+.B halui.flood.off\fR bit in \fR
+pin para inundacion OFF
+.TP
+.B halui.flood.on\fR bit in \fR
+pin para activar inundacion
+
+.SS Ajuste manual de la alimentacion (Feed Override)(FO)
+.TP
+.B halui.feed\-override.count\-enable\fR bit in \fR (por defecto: \fBTRUE \fR)
+Cuando sea VERDADERO, modifica la alimentacion cuando cambien los conteos.
+.TP
+.B halui.feed\-override.counts\fR s32 in \fR
+cuenta X escala = porcentaje de ajuste de alimentacion
+.TP
+.B halui.feed\-override.decrease\fR bit in \fR
+pin para disminuir FO (\-=escala)
+.TP
+.B halui.feed\-override.direct \-value\fR bit in \fR
+pin para habilitar la entrada directa de valor FO
+.TP
+.B halui.feed\-override.increase\fR bit in \fR
+pin para aumentar FO (+=escala)
+.TP
+.B halui.feed\-override.scala \fR flota en \fR
+pin para ajustar la escala en el cambio de FO
+.TP
+.B halui.feed\-override.value\fR float out \fR
+valor de reemplazo de alimentacion actual
+
+.SS Ajuste manual de rapidos (Rapid override)
+.TP
+.B halui.rapid\-override.count\-enable\fR bit in \fR (por defecto: \fBTRUE \fR)
+Cuando sea TRUE, modifica Rapid Override cuando los recuentos cambien.
+.TP
+.B halui.rapid\-override.counts\fR s32 in \fR
+cuenta X escala = porcentaje de ajuste de rapidos
+.TP
+.B halui.rapid\-override.decrease\fR bit in \fR
+pin para disminuir el reemplazo rapido (\-= escala)
+.TP
+.B halui.rapid\-override.direct \-value\fR bit in \fR
+pin para habilitar la entrada de valor directo de rapidos
+.TP
+.B halui.rapid\-override.increase\fR bit in \fR
+pin para aumentar el ajuste de rapidos (+= escala)
+.TP
+.B halui.rapid\-override.scale\fR float in \fR
+pin para establecer la escala en el cambio de rapidos
+.TP
+.B halui.rapid\-override.value\fR float out \fR
+valor de ajuste de rapidos actual
+
+.SS estop
+.TP
+.B halui.estop.activate\fR bit in \fR
+pin para configurar Estop ON (interno de LinuxCNC)
+.TP
+.B halui.estop.is\-activated\fR bit out \fR
+pin para mostrar el estado Estop On/Off (interno de LinuxCNC)
+.TP
+.B halui.estop.reset\fR bit in \fR
+pin para reiniciar Estop OFF (interno de LinuxCNC)
+
+
+.SS Home (referencia)
+.TP
+.B halui.home\-all\fR bit in \fR
+pin para solicitar referenciar todo
+(solo disponible cuando se especifica una secuencia de referencia valida)
+
+.SH "VER TAMBIEN"
+
+.SH HISTORIA
+
+.SH ERRORES
+Ninguna conocida en este momento.
+.SH AUTOR
+Escrito por Alex Joni, como parte del proyecto LinuxCNC. Actualizado por John
+Thornton
+.SH REPORTE DE ERRORES
+Informar errores a alex_joni AT usuarios DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2006 Alex Joni.
+.br
+Este es un software libre; ver las fuentes para condiciones de copia. No hay
+garantia; ni siquiera para COMERCIABILIDAD o APTITUD PARA UN PROPoSITO PARTICULAR.
+
+
diff --git a/docs/man/es/man1/hy_gt_vfd.1 b/docs/man/es/man1/hy_gt_vfd.1
new file mode 100644
index 0000000000..ec1dcbf947
--- /dev/null
+++ b/docs/man/es/man1/hy_gt_vfd.1
@@ -0,0 +1,296 @@
+'\" t
+.\" Title: hy_gt_vfd
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1
+.\" Date: 08/11/2020
+.\" Manual: LinuxCNC Documentation
+.\" Source: LinuxCNC
+.\" Language: English
+.\"
+.TH "HY_GT_VFD" "1" "08/11/2020" "LinuxCNC" "LinuxCNC Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+hy_gt_vfd \- HAL userspace component for Huanyang GT\-series VFDs
+.SH "SYNOPSIS"
+.sp
+\fBhy_gt_vfd\fR [\fIOPTIONS\fR]
+.SH "DESCRIPTION"
+.sp
+The hy_gt_vfd component interfaces a Huanyang GT\-series VFD to the LinuxCNC HAL\&. The VFD is connected via RS\-485 serial to the LinuxCNC computer\&.
+.SH "HARDWARE SETUP"
+.sp
+At least some Huanyang GT VFDs must be physically modified to enable Modbus communication\&.
+.sp
+The circuit board location marked "SW1" is identified in the manual as "Switch of terminal resistor for RS485 communication"\&. On the only VFD I have experience with, the circuit board contained no switch at that location, instead holding a pair of crossed jumper wires (top\-left pad connected to bottom\-right pad, top\-right to bottom\-left)\&. In this configuration, no Modbus communication is possible\&. We had to desolder the two crossed jumper wires and re\-solder them parallel to each other (top\-left to bottom\-left, top\-right to bottom\-right)\&.
+.SH "FIRMWARE SETUP"
+.sp
+The Huanyang GT VFD must be configure via the faceplate to talk Modbus with LinuxCNC\&. Consult the Operation section of the Huanyang GT\-series Inverter Manual for details\&. Set the following parameters:
+.PP
+P0\&.01 = 2
+.RS 4
+Set Run Command Source to Modbus serial port\&.
+.RE
+.PP
+P0\&.03
+.RS 4
+Set Maximum Frequency to the maximum frequency you want the VFD to output, in Hz\&.
+.RE
+.PP
+P0\&.04
+.RS 4
+Set Upper Frequence Limit to the maximum frequency you want the VFD to output, in Hz\&. This should be the same as the value in P0\&.03\&.
+.RE
+.PP
+P0\&.05
+.RS 4
+Set Lower Frequency Limit to the minimum frequency you want the VFD to output, in Hz\&.
+.RE
+.PP
+P0\&.07 = 7
+.RS 4
+Set Frequency A Command Source to Modbus serial port\&.
+.RE
+.PP
+P2\&.01 = ???
+.RS 4
+Set Motor Rated Power to the motor\(cqs power rating in kW\&.
+.RE
+.PP
+P2\&.02 = ???
+.RS 4
+Set Motor Rated Frequency to the motor\(cqs max frequency in Hz\&.
+.RE
+.PP
+P2\&.03 = ???
+.RS 4
+Set Motor Rated Speed to the motor\(cqs speed in RPM at its rated maximum frequence\&.
+.RE
+.PP
+P2\&.04 = ???
+.RS 4
+Set Motor Rated Voltage to the motor\(cqs maximum voltage, in Volts\&.
+.RE
+.PP
+P2\&.05 = ???
+.RS 4
+Set Motor Rated Current to the motor\(cqs maximum current, in Amps\&.
+.RE
+.PP
+PC\&.00 = 1
+.RS 4
+Set Local Address to 1\&. This matches the default in the hy_gt_vfd driver, change this if your setup has special needs\&.
+.RE
+.PP
+PC\&.01 = 5
+.RS 4
+Set Baud Rate Selection to 5 (38400 bps)\&. This matches the default in the hy_gt_vfd driver, change this if your setup has special needs\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+0 = 1200
+1 = 2400
+2 = 4800
+3 = 9600
+4 = 19200
+5 = 38400
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+PC\&.02 = 0
+.RS 4
+Set Data Format (8n1 RTU)\&. This matches the default in the hy_gt_vfd driver, change this if your setup has special needs\&.
+.RE
+.PP
+PC\&.03 = 1
+.RS 4
+Set Communication Delay Time to 1 ms\&. This is expected by the hy_gt_vfd driver\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-b\fR, \fB\-\-bits\fR \fIN\fR
+.RS 4
+(default 8) For Modbus communication\&. Set number of data bits to
+\fIN\fR\&.
+\fIN\fR
+must be between 5 and 8 inclusive\&.
+.RE
+.sp
+\fB\-p\fR, \fB\-\-parity\fR [Even,Odd,None]
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+(default None) For Modbus communication\&. Set serial parity to Even,
+Odd, or None\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+\fB\-r\fR, \fB\-\-rate\fR \fIN\fR
+.RS 4
+(default 38400) For Modbus communication\&. Set baud rate to
+\fIN\fR\&. It is an error if the rate is not one of the following: 1200, 2400, 4800, 9600, 19200, 38400
+.RE
+.PP
+\fB\-s\fR, \fB\-\-stopbits\fR [1,2]
+.RS 4
+(default 1) For Modbus communication\&. Set serial stop bits to 1 or 2\&.
+.RE
+.PP
+\fB\-t\fR, \fB\-\-target\fR \fIN\fR
+.RS 4
+(default 1) For Modbus communication\&. Set Modbus target (slave) number\&. This must match the device number you set on the Huanyang GT VFD\&.
+.RE
+.PP
+\fB\-d\fR, \fB\-\-device\fR \fIPATH\fR
+.RS 4
+(default /dev/ttyS0) For Modbus communication\&. Set the name of the serial device node to use\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-verbose\fR
+.RS 4
+Turn on verbose mode\&.
+.RE
+.PP
+\fB\-S\fR, \fB\-\-motor\-max\-speed\fR \fIRPM\fR
+.RS 4
+The motor\(cqs max speed in RPM\&. This must match the motor speed value configured in VFD register P2\&.03\&.
+.RE
+.PP
+\fB\-F\fR, \fB\-\-max\-frequency\fR \fIHZ\fR
+.RS 4
+This is the maximum output frequency of the VFD in Hz\&. It should correspond to the motor\(cqs rated max frequency, and to the maximum and upper limit output frequency configured in VFD register P0\&.03 and P0\&.04\&.
+.RE
+.PP
+\fB\-f\fR, \fB\-\-min\-frequency\fR \fIHZ\fR
+.RS 4
+This is the minimum output frequency of the VFD in Hz\&. It should correspond to the minimum output frequency configured in VFD register P0\&.05\&.
+.RE
+.SH "PINS"
+.PP
+\fBhy_gt_vfd\&.period\fR (float, in)
+.RS 4
+The period for the driver\(cqs update cycle, in seconds\&. This is how frequently the driver will wake up, check its HAL pins, and communicate with the VFD\&. Must be between 0\&.001 and 2\&.000 seconds\&. Default: 0\&.1 seconds\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.speed\-cmd\fR (float, in)
+.RS 4
+The requested motor speed, in RPM\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.speed\-fb\fR (float, out)
+.RS 4
+The motor\(cqs current speed, in RPM, reported by the VFD\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.at\-speed\fR (bit, out)
+.RS 4
+True when the drive is on and at the commanded speed (within 2%), False otherwise\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.freq\-cmd\fR (float, out)
+.RS 4
+The requested output frequency, in Hz\&. This is set from the \&.speed\-cmd value, and is just shown for debugging purposes\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.freq\-fb\fR (float, out)
+.RS 4
+The current output frequency of the VFD, in Hz\&. This is reported from the VFD to the driver\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.spindle\-on\fR (bit, in)
+.RS 4
+Set this pin True to command the spindle on, at the speed requested on the \&.speed\-cmd pin\&. Set this pin False to command the spindle off\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.output\-voltage\fR (float, out)
+.RS 4
+The voltage that the VFD is current providing to the motor, in Volts\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.output\-current\fR (float, out)
+.RS 4
+The current that the motor is currently drawing from the VFD, in Amperes\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.output\-power\fR (float, out)
+.RS 4
+The power that the motor is currently drawing from the VFD, in Watts\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.dc\-bus\-volts\fR (float, out)
+.RS 4
+The current voltage of the VFD\(cqs internal DC power supply, in Volts\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.modbus\-errors\fR (u32, out)
+.RS 4
+A count of the number of modbus communication errors between the driver and the VFD\&. The driver is resilient against communication errors, but a large or growing number here indicates a problem that should be investigated\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.input\-terminal\fR (float, out)
+.RS 4
+The VFD\(cqs input terminal register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.output\-terminal\fR (float, out)
+.RS 4
+The VFD\(cqs output terminal register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.AI1\fR (float, out)
+.RS 4
+The VFD\(cqs AI1 register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.AI2\fR (float, out)
+.RS 4
+The VFD\(cqs AI2 register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.HDI\-frequency\fR (float, out)
+.RS 4
+The VFD\(cqs HDI\-frequency register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.external\-counter\fR (float, out)
+.RS 4
+The VFD\(cqs external counter register\&.
+.RE
+.PP
+\fBhy_gt_vfd\&.fault\-info\fR (float, out)
+.RS 4
+The VFD\(cqs fault info register\&.
+.RE
+.SH "ISSUES"
+.sp
+The VFD produces the output frequency that it sends to the motor by adding a manually specified offset to the frequency command it gets over modbus\&.
+.sp
+The manual offset is controlled by pressing the Up/Down arrows on the faceplate while the VFD is turning the motor\&.
+.sp
+If you command a speed on the \&.speed\-cmd pin and get a different speed reported on the \&.speed\-fb pin, first verify that the VFD registers listed in the FIRMWARE SETUP section above and the driver\(cqs command\-line arguments all agree with the info on the motor\(cqs name plate\&. If you still aren\(cqt getting the speed you expect, zero the VFD\(cqs frequency offset by starting the motor running, then pressing the Up/Down buttons to zero the offset\&.
diff --git a/docs/man/es/man1/hy_vfd.1 b/docs/man/es/man1/hy_vfd.1
new file mode 100644
index 0000000000..6da9ae4e73
--- /dev/null
+++ b/docs/man/es/man1/hy_vfd.1
@@ -0,0 +1,318 @@
+.\" Copyright (c) 2015 Sebastian Kuzminsky
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH hy_vfd "1" "April 25, 2015" "Huanyang VFD" "LinuxCNC Documentation"
+
+.SH NAME
+\fBhy_vfd\fR \- HAL userspace component for Huanyang VFDs
+
+.SH SYNOPSIS
+.B hy_vfd
+.RI [OPTIONS]
+.br
+
+.SH DESCRIPTION
+This component connects the Huanyang VFD to the LinuxCNC HAL via a serial
+(RS-485) connection.
+.PP
+The Huanyang VFD must be configured via the face plate user interface
+to accept serial communications:
+.B
+.IP PD001\ =\ 2
+Set register PD001 (source of run commands) to 2 (communication port).
+.B
+.IP PD002\ =\ 2
+Set register PD002 (source of operating frequency) to 2 (communication
+port).
+.B
+.IP PD004
+.br
+Set register PD004 (Base Frequency) according to motor specs. This is
+the rated frequency of the motor from the motor's name plate, in Hz.
+.B
+.IP PD005
+.br
+Set register PD005 (max frequency) according to motor specs. This is
+the maximum frequency of the motor's power supply, in Hz.
+.B
+.IP PD011
+.br
+Set register PD011 (min frequency) according to motor specs. This is
+the minimum frequency of the motor's power supply, in Hz.
+.B
+.IP PD141
+.br
+Set register PD141 (rated motor voltage) according to motor name plate.
+This is the motor's maximum voltage, in Volts.
+.B
+.IP PD142
+.br
+Set register PD142 (rated motor current) according to motor name plate.
+This is the motor's maximum current, in Amps.
+.B
+.IP PD143
+.br
+Set register PD143 (Number of Motor Poles) according to motor name plate.
+.B
+.IP PD144
+.br
+Set register PD144 (rated motor revolutions) according to motor name
+plate. This is the motor's speed in RPM at 50 Hz. Note: This is not the
+motor's max speed (unless the max motor frequency happens to be 50 Hz)!
+.B
+.IP PD163\ =\ 1
+Set register PD163 (communication address) to 1. This matches the
+default in the hy_vfd driver, change this if your setup has special needs.
+.B
+.IP PD164\ =\ 2
+Set register PD164 (baud rate) to 2 (19200 bps). This matches the
+default in the hy_vfd driver, change this if your setup has special needs.
+.B
+.IP PD165\ =\ 3
+Set register PD165 (communication data method) to 3 (8n1 RTU).
+This matches the default in the hy_vfd driver, change this if your
+setup has special needs. Note that the hy_vfd driver only supports RTU
+communication, not ASCII.
+.PP
+Consult the Huanyang instruction manual for details on using the face
+plate to program the VFDs registers, and alternative values for the
+above registers.
+.PP
+Access to devices such as /dev/ttyUSB0 is restricted to members of the
+"dialout" group. If you see error messages such as
+.br
+.B open: Permission denied
+.br
+.B ERROR Can't open the device /dev/ttyUSB0 (errno 13)
+.br
+Check your groups membership with the command
+.br
+.B groups
+.br
+Then add your user to the dialout group with
+.br
+.B sudo addgroup your-username dialout
+.br
+You will need to log out and back in again for this to take effect.
+
+.SH OPTIONS
+.B
+.IP \-d,\ \-\-device\
+(default /dev/ttyS0) Set the name of the serial device node to use.
+.B
+.IP \-g,\ \-\-debug
+Turn on debug messages. Note that if there are serial errors, this may
+become annoying. Debug mode will cause all serial communication messages
+to be printed in hex on the terminal.
+.B
+.IP \-n,\ \-\-name\
+(default hy_vfd) Set the name of the HAL module. The HAL comp name will be
+set to , and all pin and parameter names will begin with .
+.B
+.IP \-b,\ \-\-bits\
+(default 8) Set number of data bits to , where n must be from 5
+to 8 inclusive. This must match the setting in register PD165 of the
+Huanyang VFD.
+.B
+.IP \-p,\ \-\-parity\ [even,odd,none]
+(default odd) Set serial parity to even, odd, or none. This must match
+the setting in register PD165 of the Huanyang VFD.
+.B
+.IP \-r,\ \-\-rate\
+(default 38400) Set baud rate to . It is an error if the rate is
+not one of the following: 110, 300, 600, 1200, 2400, 4800, 9600, 19200,
+38400, 57600, 115200. This must match the setting in register PD164 of
+the Huanyang VFD.
+.B
+.IP \-s,\ \-\-stopbits\ [1,2]
+(default 1) Set serial stop bits to 1 or 2. This must match the setting
+in register PD165 of the HuanyangVFD.
+.B
+.IP \-t,\ \-\-target\
+(default 1) Set HYCOMM target (slave) number. This must match the device
+number you set on the Hyanyang VFD in register PD163.
+.B
+.IP \-F,\ \-\-max\-frequency\
+(default: read from VFD) If specified, program register PD005 of the VFD
+with the specified max frequency of Hz (and use the same max frequency
+in the hy_vfd driver). If not specified, read the max frequency to use
+from register PD005 of the VFD.
+.B
+.IP \-f,\ \-\-min\-frequency\
+(default: read from VFD) If specified, program register PD011 of the
+VFD with the specified minimum frequency of Hz (and use the same
+minimum frequency in the hy_vfd driver). If not specified, read the
+minimum frequency to use from register PD011 of the VFD.
+.B
+.IP \-V,\ \-\-motor\-voltage\
+(default: read from VFD) If specified, program register PD141 of the VFD
+with the specified max motor voltage of Volts. If not specified,
+read the max motor voltage from register PD141 of the VFD.
+.B
+.IP \-I,\ \-\-motor\-current\
+(default: read from VFD) If specified, program register PD142 of the
+VFD with the specified max motor current of Amps. If not specified,
+read the max motor current from register PD142 of the VFD.
+.B
+.IP \-S,\ \-\-motor\-speed\
+(default: compute from value read from VFD P144) This command-line
+argument is the motor's max speed. If specified, compute the motor's
+speed at 50 Hz from this argument and from the motor's max frequency
+(from the \-\-max\-frequency argument or from P011 if \-\-max\-frequency is
+not specified) and program register PD144 of the VFD. If not specified,
+read the motor's speed at 50 Hz from register P144 of the VFD, and use
+that and the max frequency to compute the motor's max speed.
+.B
+.IP \-P,\ \-\-motor\-poles\
+(default: read value from VFD P143) This command-line argument is the
+number of poles in the motor. If specified, this value is sent to the
+VFD's register PD143. If not specified, the value is read from PD143
+and reported on the corresponding HAL pin.
+.B
+.SH PINS
+.B
+.IP .enable
+(bit, in) Enable communication from the hy_vfd driver to the VFD.
+.B
+.IP .SetF
+(float, out)
+.B
+.IP .OutF
+(float, out)
+.B
+.IP .OutA
+(float, out)
+.B
+.IP .Rott
+(float, out)
+.B
+.IP .DCV
+(float, out)
+.B
+.IP .ACV
+(float, out)
+.B
+.IP .Cont
+(float, out)
+.B
+.IP .Tmp
+(float, out)
+.B
+.IP .spindle\-forward
+(bit, in)
+.B
+.IP .spindle\-reverse
+(bin, in)
+.B
+.IP .spindle\-on
+(bin, in)
+.B
+.IP .CNTR
+(float, out)
+.B
+.IP .CNST
+(float, out)
+.B
+.IP .CNST\-run
+(bit, out)
+.B
+.IP .CNST\-jog
+(bit, out)
+.B
+.IP .CNST\-command\-rf
+(bit, out)
+.B
+.IP .CNST\-running
+(bit, out)
+.B
+.IP .CNST\-jogging
+(bit, out)
+.B
+.IP .CNST\-running\-rf
+(bit, out)
+.B
+.IP .CNST\-bracking
+(bit, out)
+.B
+.IP .CNST\-track\-start
+(bit, out)
+.B
+.IP .speed\-command
+(float, in)
+.B
+.IP .spindle\-speed\-fb
+(float, out) Current spindle speed as reported by Huanyang VFD.
+.B
+.IP .spindle\-at\-speed\-tolerance
+(float, in) Spindle speed error tolerance. If the actual spindle
+speed is within .spindle\-at\-speed\-tolerance of the commanded speed,
+then the .spindle\-at\-speed pin will go True. The
+default .spindle\-at\-speed\-tolerance is 0.02, which means the actual
+speed must be within 2% of the commanded spindle speed.
+.B
+.IP .spindle\-at\-speed
+(bit, out) True when the current spindle speed is
+within .spindle\-at\-speed\-tolerance of the commanded speed.
+.B
+.IP .frequency\-command
+(float, out)
+.B
+.IP .max\-freq
+(float, out)
+.B
+.IP .base\-freq
+(float, out)
+.B
+.IP .freq\-lower\-limit
+(float, out)
+.B
+.IP .rated\-motor\-voltage
+(float, out)
+.B
+.IP .rated\-motor\-current
+(float, out)
+.B
+.IP .rated\-motor\-rev
+(float, out)
+.B
+.B
+.IP .motor\-poles
+(u32, out)
+.B
+.IP .hycomm\-ok
+(bit, out)
+
+.SH PARAMETERS
+.B
+.IP .error\-count
+(s32, RW)
+.B
+.IP .retval
+(float, RW)
+
+.SH AUTHOR
+Sebastian Kuzminsky
+
+.SH LICENSE
+GPL
diff --git a/docs/man/es/man1/io.1 b/docs/man/es/man1/io.1
new file mode 100644
index 0000000000..cc860da690
--- /dev/null
+++ b/docs/man/es/man1/io.1
@@ -0,0 +1 @@
+.so man1/iocontrol.1
diff --git a/docs/man/es/man1/iocontrol.1 b/docs/man/es/man1/iocontrol.1
new file mode 100644
index 0000000000..c726d8555d
--- /dev/null
+++ b/docs/man/es/man1/iocontrol.1
@@ -0,0 +1,98 @@
+.TH IOCONTROL "1" "2007-08-25" "Documentacion de LinuxCNC" "Componentes HAL"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+
+.SH NOMBRE
+iocontrol \- acepta comandos de E/S NML, interactua con HAL en el espacio de usuario
+
+.SH SINOPSIS
+\fBloadusr io [\-ini \fIinifile\fB]
+
+
+.SH DESCRIPCION
+Estos pines son creados por el controlador IO de espacio de usuario, que generalmente se encuentra en $LINUXCNC_HOME/bin/io
+.PP
+Las se\[~n]ales se activan y desactivan en el espacio de usuario: si tiene requisitos de tiempo estrictos o simplemente necesita mas I/O, considere usar la I/O sincronizada en tiempo real proporcionada por \fBmotion \fR(9).
+.PP
+El archivo inifile se busca en el directorio desde donde se ejecuto halcmd, a menos que se especifique una ruta absoluta.
+
+.SH PINES
+
+.TP
+\fBiocontrol.0.coolant\-flood
+(Bit, Out) TRUE cuando se solicita refrigerante de inundacion
+
+.TP
+\fBiocontrol.0.coolant\-mist
+(Bit, Out) TRUE cuando se solicita refrigerante de niebla
+
+.TP
+\fBiocontrol.0.emc\-enable\-in
+(Bit, In) Se debe activar FALSE cuando existe una condicion Estop externa.
+
+.TP
+\fBiocontrol.0.lube
+(Bit, Out) TRUE cuando se solicita lubricante. Este pin pasa a TRUE cuando
+el controlador sale de E-stop, y cuando el comando "Lube On"
+se envia al controlador. Es FALSE cuando el controlador
+recibe E-stop, y cuando se envia el comando "Lube Off".
+
+.TP
+\fBiocontrol.0.lube_level
+(Bit, in.) Se debe poner en FALSE cuando el tanque de lubricacion esta vacio.
+
+.TP
+\fBiocontrol.0.tool\-change
+(Bit, Out) Se debe poner en TRUE cuando se solicita un cambio de herramienta
+
+.TP
+\fBiocontrol.0.tool\-changed
+(Bit, In) Se debe poner en TRUE cuando se completa un cambio de herramienta.
+
+.TP
+\fBiocontrol.0.tool\-number
+(s32, Out) Numero de herramienta actual
+
+.TP
+\fBiocontrol.0.tool\-prep\-number
+(s32, Out) El numero de la siguiente herramienta de la palabra T
+
+.TP
+\fBiocontrol.0.tool\-prep\-pocket
+(s32, Out) Este es el numero de ranura (ubicacion en el almacenamiento del mecanismo de herramientas)
+de la herramienta solicitada por la palabra T mas reciente.
+
+.TP
+\fBiocontrol.0.tool\-prepare
+(Bit, Out) TRUE cuando se solicita la preparacion de la herramienta T\fIn\fR
+
+.TP
+\fBiocontrol.0.tool\-prepared
+(Bit, In) Debe ponerse en TRUE cuando se completa la preparacion de una herramienta.
+
+.TP
+\fBiocontrol.0.user\-enable\-out
+(Bit, Out) FALSE cuando existe una condicion de detencion interna
+
+.TP
+\fBiocontrol.0.user\-request\-enable
+(Bit, Out) TRUE cuando el usuario ha solicitado que se elimine la detencion
+
+.SH PARAMETROS
+
+.TP
+\fBiocontrol.0.tool\-prep\-index
+(s32, RO) indice de matriz interna de IO de la herramienta preparada solicitada
+por la palabra T mas reciente. 0 si no hay ninguna herramienta preparada.
+En maquinas con cambiador de herramientas random, este es el numero de ranura de la herramienta (es decir, el mismo que
+tool\-prep\-pocket pin). En maquinas de cambiador de herramientas no random, esto es
+un numero entero que corresponde a la ubicacion de la herramienta en la representacion interna
+de la tabla de herramientas. Este parametro vuelve a 0 despues de un
+cambio de herramienta con exito (M6).
+
+.SH VER TAMBIEN
+\fBmotion\ fR (9)
+
diff --git a/docs/man/es/man1/linuxcnc.1 b/docs/man/es/man1/linuxcnc.1
new file mode 100644
index 0000000000..5099dab314
--- /dev/null
+++ b/docs/man/es/man1/linuxcnc.1
@@ -0,0 +1,110 @@
+.\" Copyright (c) 2006 Alex Joni
+.\" (alex_joni AT users DOT sourceforge DOT net)
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH LinuxCNC "1" "2006-02-20" "LinuxCNC Documentation" "The Enhanced Machine Controller"
+.SH NAME
+linuxcnc \- LinuxCNC (The Enhanced Machine Controller)
+.SH SYNOPSIS
+.B linuxcnc
+[\fI-v\fR] [\fI-d\fR] [\fIINIFILE\fR]
+.SH DESCRIPTION
+\fBlinuxcnc\fR is used to start LinuxCNC (The Enhanced Machine Controller). It
+starts the realtime system and then initializes a number of LinuxCNC
+components (IO, Motion, GUI, HAL, etc). The most important parameter
+is \fIINIFILE\fR, which specifies the configuration name you would like
+to run. If \fIINIFILE\fR is not specified, the \fBlinuxcnc\fR script presents
+a graphical wizard to let you choose one.
+.SH OPTIONS
+.TP
+\fB\-v\fR
+Be a little bit verbose. This causes the script to print information
+as it works.
+.TP
+\fB\-d\fR
+Print lots of debug information. All executed commands
+are echoed to the screen. This mode is useful when something is
+not working as it should.
+.TP
+\fB\-l\fR
+Use the last-used INI file without prompting. This is often a good choice
+for a shortcut command or startup item.
+.TP
+\fBINIFILE\fR
+The ini file is the main piece of an LinuxCNC configuration. It is not the
+entire configuration; there are various other files that go with it
+(NML files, HAL files, TBL files, VAR files). It is, however, the most
+important one, because it is the file that holds the configuration
+together. It can adjust a lot of parameters itself, but it also tells
+\fBlinuxcnc\fR which other files to load and use.
+
+There are several ways to specify which config to use:
+
+Specify the absolute path to an ini, e.g.
+.br
+\fBlinuxcnc\fR \fI/usr/local/linuxcnc/configs/sim/sim.ini\fR
+
+Specify a relative path from the current directory, e.g.
+.br
+\fBlinuxcnc\fR \fIconfigs/sim/sim.ini\fR
+
+Otherwise, in the case where the \fBINIFILE\fR is not specified,
+the behavior will depend on whether you configured linuxcnc with
+\fB--enable-run-in-place\fR. If so, the linuxcnc config chooser will search
+only the configs directory in your source tree. If not (or if you are
+using a packaged version of linuxcnc), it may search several directories.
+The config chooser is currently set to search the path:
+
+.nf
+\fB~/linuxcnc/configs:/usr/local/etc/linuxcnc/configs:/usr/share/doc/linuxcnc/examples/sample-configs\fR
+
+.SH EXAMPLES
+
+\fBlinuxcnc\fR
+
+\fBlinuxcnc\fR \fIconfigs/sim/sim.ini\fR
+
+\fBlinuxcnc\fR \fI/etc/linuxcnc/sample-configs/stepper/stepper_mm.ini\fR
+
+.SH "SEE ALSO"
+\fBhalcmd(1)\fR
+
+Much more information about LinuxCNC and HAL is available in the LinuxCNC
+and HAL User Manuals, found at /usr/share/doc/linuxcnc/.
+
+.SH HISTORY
+
+.SH BUGS
+None known at this time.
+.PP
+.SH AUTHOR
+This man page written by Alex Joni, as part of the LinuxCNC Enhanced Machine
+Controller project.
+.SH REPORTING BUGS
+Report bugs to alex_joni AT users DOT sourceforge DOT net
+.SH COPYRIGHT
+Copyright \(co 2006 Alex Joni.
+.br
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/docs/man/es/man1/linuxcncrsh.1 b/docs/man/es/man1/linuxcncrsh.1
new file mode 100644
index 0000000000..5f0668e669
--- /dev/null
+++ b/docs/man/es/man1/linuxcncrsh.1
@@ -0,0 +1,754 @@
+.TH linuxcncrsh 1 "31 de mayo de 2011" "" "El Controlador de Máquina Mejorado"
+.SH NOMBRE
+linuxcncrsh \- interfaz en modo texto para comandar LinuxCNC a través de la red
+.SH SINOPSIS
+.SI
+linuxcncrsh [OPCIONES] [\-\- LINUXCNC_OPCIONES]
+.br
+.SH DESCRIPCIÓN
+\fBlinuxcncrsh\fP es una interfaz de usuario para LinuxCNC. En lugar de abrir una
+ventana GUI como axis(1) o touchy(1), procesa comandos en modo texto
+que recibe a través de la red. Un humano (o un programa) puede interactuar
+con \fBlinuxcncrsh\fP usando telnet(1) o nc(1) o programas similares.
+.P
+Todas las características de LinuxCNC están disponibles a través de la interfaz \fBlinuxcncrsh\fP.
+.SH OPCIONES
+.P
+.B
+\-p,\-\-port PORT_NUMBER
+.RS
+Especifique el puerto de escucha para linuxcncrsh. El valor predeterminado es 5007 si se omite.
+.RE
+.P
+.B
+\-n,\-\-name SERVER_NAME
+.RS
+Establece el nombre del servidor que linuxcncrsh usará para identificarse durante
+el reconocimiento con un nuevo cliente. El valor predeterminado es EMCNETSVR si se omite.
+.RE
+.P
+.B
+\-w,\-\-connectpw CONTRASEÑA
+.RS
+Especifique la contraseña de conexión para usar durante el protocolo de enlace con un nuevo
+cliente. Tenga en cuenta que la contraseña se envía sin cifrar, por lo que puede leerse
+por cualquiera que pueda leer paquetes en la red entre el servidor y
+el cliente. El valor predeterminado es EMC si se omite.
+.RE
+.P
+.B
+\-e,\-\-enablepw CONTRASEÑA
+.RS
+Especifique la contraseña requerida para habilitar LinuxCNC a través de linuxcncrsh. Tenga en cuenta que
+la contraseña se envía sin cifrar, por lo que cualquier persona que pueda leer
+paquetes en la red entre el servidor y el cliente puede leerla. Por defecto es
+EMCTOO si se omite.
+.RE
+.P
+.B
+\-s,\-\-sessions MAX_SESSIONS
+.RS
+Especifique el número máximo de conexiones simultáneas. El valor predeterminado es \-1
+(sin límite) si no se especifica.
+.RE
+.P
+Además de las opciones enumeradas anteriormente, linuxcncrsh acepta una opción
+LINUXCNC_OPTION especial al final:
+.P
+.B
+\-ini LINUXCNC_INI_FILE
+.RS
+Archivo LinuxCNC .ini a usar. La opción \-ini \fBdebe\fP estar precedida por dos
+guiones: "\-\-". El valor predeterminado es emc.ini si se omite.
+.RE
+.SH Inicio de linuxcncrsh
+.P
+Para usar linuxcncrsh en lugar de una GUI LinuxCNC normal como Axis o Touchy, especifique
+su archivo .ini así:
+.RS
+.P
+.B [DISPLAY]
+.P
+.B DISPLAY=linuxcncrsh
+.RE
+.P
+Para usar linuxcncrsh además de una GUI normal, puede iniciarlo
+al final de su archivo .hal, o ejecutarlo a mano en una ventana de terminal.
+.P
+Para iniciarlo desde hal, agregue una línea como esta al final de su archivo .hal:
+.RS
+.P
+.B loadusr linuxcncrsh [OPCIONES] [\-\- LINUXCNC_OPTIONS]
+.RE
+.P
+Para iniciarlo desde la terminal, ejecute linuxcncrsh manualmente de esta manera:
+.RS
+.P
+.B linuxcncrsh [OPCIONES] [\-\- LINUXCNC_OPTIONS]
+.RE
+.SH Conexión
+.P
+Una vez que LinuxCNC esté activo y se esté ejecutando linuxcncrsh, puede conectarse a él utilizando
+\fBtelnet\fP o \fBnc\fP o similar:
+.RS
+.P
+.B telnet HOST PORT
+.RS
+HOST es el nombre de host o la dirección IP de la computadora que ejecuta linuxcncrsh, y
+PORT es el puerto en el que está escuchando (5007 si no le dio a linuxcncrsh la opción \-\-port).
+
+.RE
+.SH Protocolo de red
+.P
+linuxcncrsh acepta conexiones TCP en el puerto especificado por la opción \-\-port,
+o 5007 si no se especifica.
+.P
+El cliente envía solicitudes y el servidor linuxcncrsh devuelve respuestas.
+Las solicitudes consisten en una palabra de comando seguida de parámetros específicos del comando.
+Las solicitudes y la mayoría de los parámetros de solicitud son insensibles a mayúsculas y minúsculas.
+Las excepciones son contraseñas, rutas de archivo y cadenas de texto.
+.P
+Las solicitudes de linuxcncrsh se finalizan con terminaciones de línea; cualquier combinación de
+uno o más caracteres '\\r' y '\\n'. Las respuestas de linuxcncrsh finalizan
+con la secuencia \'\\r\\n\'.
+.P
+Los comandos admitidos son los siguientes:
+.P
+\fBhello \fR
+.RS
+ debe coincidir con la contraseña de conexión de linuxcncrsh o "EMC" si no
+se suministró \-\-connectpw. Los tres argumentos pueden no contener espacios en blanco.
+Si se ingresó una contraseña válida, el servidor responderá con:
+.RS
+\fIHELLO ACK \fR
+.RE
+.P
+Si se produce una contraseña no válida o cualquier otro error de sintaxis, el servidor
+responde con:
+.RS
+\fIHELLO NAK\fR
+.RE
+.RE
+.P
+\fBget []\fR
+.RS
+El comando get toma uno de los subcomandos LinuxCNC (descrito en la
+sección \fBSubcomandos LinuxCNC\fR, a continuación) y cero o más parámetros
+adicionales específicos del subcomando.
+.RE
+.P
+\fBset \fR
+.RS
+El comando set toma uno de los subcomandos LinuxCNC (descrito en el
+sección \fBSubcomandos LinuxCNC\fR, a continuación) y uno o más parámetros adicionales.
+.RE
+.P
+\fBquit\fR
+.RS
+El comando quit desconecta la conexión de socket asociada.
+.RE
+.P
+\fBshutdown\fR
+.RS
+El comando shutdown le dice a LinuxCNC que apague y desconecte la
+sesión. Este comando solo se puede emitir si el reconocimiento ha sido
+negociado con éxito y la conexión tiene el control del CNC (ver subcomando
+\fBenable\fR en la sección \fBSubcomandos LinuxCNC\fR, a continuación).
+.RE
+.P
+\fBhelp\fR
+.RS
+El comando de ayuda devolverá información de ayuda en formato de texto sobre la
+conexión. Si no se especifican parámetros, detallará los comandos disponibles.
+Si se especifica un comando, proporcionará información de uso
+para el comando especificado. La ayuda responderá independientemente de si un
+"Hello" se ha negociado con éxito.
+.RE
+.SH "Subcomandos LinuxCNC"
+.P
+Los subcomandos para \fBget\fR y \fBset\fR son:
+.P
+\fBecho {on|off}\fR
+.RS
+Con get, se ignora cualquier parámetro on/off y es devuelto el estado de eco actual.
+Con set, se establece el estado del eco como se especifica. El eco por defecto es
+on cuando se establece la conexión por primera vez. Cuando el eco está activado, todos los comandos
+hará eco al recibirlo. Este estado es local para cada conexión.
+.RE
+.P
+\fBverbose {on|off}\fR
+.RS
+Con get, cualquier parámetro on/off se ignora y es devuelto el estado detallado actual.
+Con set, se establece el estado detallado como se especifica. Cuando el modo detallado
+está activado, todos los comandos set devuelven un reconocimiento positivo en la forma
+SET ACK, y se emitirán mensajes de error de texto (FIXME: no
+se lo que esto significa). El estado detallado es local para cada conexión,
+y comienza OFF en nuevas conexiones.
+.RE
+.P
+\fBenable {|off}\fR
+.RS
+El estado de habilitación de la sesión indica si la conexión actual está
+habilitada para realizar funciones de control. Con get, se ignora cualquier parámetro,
+y se devuelve el estado de habilitación actual. Con set y una contraseña válida coincidente
+con \-\-enablepw (EMCTOO si no se especifica), la conexión actual
+está habilitada para las funciones de control. "OFF" no puede usarse como
+una contraseña y deshabilita las funciones de control para esta conexión.
+.RE
+.P
+\fBconfig [TBD]\fR
+.RS
+Sin usar, ignorar por ahora.
+.RE
+.P
+\fBcomm_mode {ascii| binary}\fR
+.RS
+Con get, se ignora cualquier parámetro y se devuelve el modo de
+comunicacion actual. Con set, se establecerá el modo de comunicaciones en
+el modo especificado El modo ascii es el modo de solicitud/respuesta de texto, el
+protocolo binario no está actualmente diseñado o implementado.
+.RE
+.P
+\fBcomm_prot \fR
+.RS
+Con get, se ignora cualquier parámetro y se devuelve la versión actual del protocolo
+utilizado por el servidor. Con set, se configura el servidor para que use
+la versión de protocolo especificada, siempre que sea inferior o igual al
+mayor número de versión compatible con la implementación del servidor.
+.RE
+.P
+\fBinifile\fR
+.RS
+¡Actualmente no implementado! Con get, devuelve la cadena "emc.ini".
+Debería devolver la ruta completa y el nombre de archivo de la configuración actual
+inifile. Set no hace nada.
+.RE
+.P
+\fBplat\fR
+.RS
+Con get, devuelve la cadena "Linux".
+.RE
+.P
+\fBini \fR
+.RS
+Actualmente no implementado, ¡no lo use! Debería devolver el valor de la cadena
+ en la sección del archivo ini.
+.RE
+.P
+\fBdebug \fR
+.RS
+Con get, se ignora cualquier parámetro y se devuelve el valor entero actual de
+EMC_DEBUG. Tenga en cuenta que el valor de EMC_DEBUG devuelto es
+el del archivo ini de la UI, que puede ser diferente al archivo ini de emc.
+Con set, se envía un comando a EMC para establecer el nuevo nivel de depuración y
+establece el EMC_DEBUG global aquí con el mismo valor. Esto hará que los
+dos valores sean iguales, ya que realmente deberían ser iguales.
+.RE
+.P
+\fBset_wait {recived|done}\fR
+.RS
+La configuración set_wait controla la espera después de recibir un comando.
+Puede ser "recived" (después de que el comando fue enviado y recibido) o "done"
+(después de que se ejecuto el comando). Con get, se ignora cualquier parámetro y
+se devuelve la configuración actual de set_wait. Con set, se establece la configuración set_wait
+al valor especificado.
+.RE
+.P
+\fBwait {recived|done}\fR
+.RS
+Con set, fuerza una espera para que se reciba el comando anterior, o done.
+.RE
+.P
+\fBset_timeout \fR
+.RS
+Con set, establece el tiempo de espera para que los comandos vuelvan a los
+segundos. El tiempo de espera es un número real. Si es <= 0.0, significa esperar para siempre.
+El valor predeterminado es 0.0, espera para siempre.
+.RE
+.P
+\fBupdate {none|auto}\fR
+.RS
+El modo de actualización controla si se deben devolver valores nuevos u obsoletos para
+"obtener" solicitudes. Cuando el modo de actualización es "none", devuelve valores obsoletos;
+cuando es "auto" devuelve valores nuevos. El valor predeterminado es "auto" para nuevas
+conexiones. Ajústelo a "none" si quiere confundirse.
+.RE
+.P
+\fBerror\fR
+.RS
+Con get, devuelve la cadena de error actual o "ok" si no hay error.
+.RE
+.P
+\fBoperator_display\fR
+.RS
+Con get, devuelve la cadena de visualización del operador actual, o "ok" si no hay ninguno.
+.RE
+.P
+\fBoperator_text\fR
+.RS
+Con get, devuelve la cadena de texto del operador actual, o "ok" si no hay ninguno.
+.RE
+.P
+\fBtime\fR
+.RS
+Con get, devuelve el tiempo, en segundos, desde el comienzo del epoch.
+El tiempo de inicio depende de la plataforma.
+.RE
+.P
+\fBestop {on|off}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelve la configuración actual de estop
+como "on" o "off". Con set, establece estop como se especifica. Estop "on"
+significa que la máquina está en estado de parada y no actuará.
+.RE
+.P
+\fBmachine {on|off}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelve el encendido actual de la máquina
+configurando como "on" o "off". Con set, enciende o apaga la máquina como se
+especifique.
+.RE
+.P
+\fBmode {manual|auto|mdi}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelve el modo de máquina actual.
+Con set, establece el modo de máquina como se especifica.
+.RE
+.P
+\fBmist {on|off}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelve el ajuste de refrigerante de niebla actual.
+Con set, establece la configuración de niebla como se especifica.
+.RE
+.P
+\fBflood {on|off}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelve el ajuste de refrigerante de inundación actual.
+Con set, establece la configuración de inundación como se especifica.
+.RE
+.P
+\fBlube {on|off}\fR
+.RS
+Con get, ignora cualquier parámetro y devuelveel ajuste de la bomba de lubricación actual.
+Con set, establece la configuración de la bomba de lubricación como se especifica.
+.RE
+.P
+\fBlube_level\fR
+.RS
+Con get, devuelve la lectura del sensor de nivel de lubricante como "ok" o "low".
+Con set, no hay efecto real.
+.RE
+.P
+\fBspindle {forward|reverse|increase|decrease|constant|off}\fR
+.RS
+Con get, se ignora cualquier parámetro y el estado actual del cabezal es
+devuelto como "forward", "reverse", "increase", "decrease", "constant" o "off". Con
+set, establece el husillo como se especifica. Tenga en cuenta que "increase" y "decrease"
+provocará un cambio de velocidad en la dirección correspondiente hasta que
+se envía el comando "constant".
+.RE
+.P
+\fBbrake {on|off}\fR
+.RS
+Con get, se ignora cualquier parámetro y la configuración actual del freno es
+devuelta. Con set, el freno se establece como se especifica.
+.RE
+.P
+\fBtool\fR
+.RS
+Con get, devuelve la identificación de la herramienta cargada actualmente.
+.RE
+.P
+\fBtool_offset\fR
+.RS
+Con get, devuelve el desplazamiento de longitud de herramienta aplicado actualmente.
+.RE
+.P
+\fBload_tool_table \fR
+.RS
+Con set, carga la tabla de herramientas especificada por .
+.RE
+.P
+\fBhome {0|1|2|...}|-1\fR
+.RS
+Con set, pone home a la articulación indicada o, si -1, home Todas las articulaciones
+.RE
+.P
+\fBjog_stop joint_number|axis_letter\fR
+.RS
+Con set, detiene cualquier jog en curso en la articulación o eje especificado.
+Si TELEOP_ENABLE es NO, use joint_number;
+Si TELEOP_ENABLE es SÍ, use axis_letter.
+.RE
+.P
+\fBjog joint_number|axis_letter \fR
+.RS
+Con set, mueve la articulación o eje especificado a la ; el signo de velocidad es dirección.
+Si TELEOP_ENABLE es NO, use joint_number;
+Si TELEOP_ENABLE es SÍ, use axis_letter.
+.RE
+.P
+\fBjog_incr jog_number|axis_letter \fR
+.RS
+Con set, mueve la articulación o eje indicado por incremento en ; el signo de
+la velocidad es dirección.
+Si TELEOP_ENABLE es NO, use joint_number;
+Si TELEOP_ENABLE es SÍ, use axis_letter.
+.RE
+.P
+\fBfeed_override \fR
+.RS
+Con get, se ignora cualquier parámetro y retorna el ajuste de alimentación actual
+(como un porcentaje del feed ordenado). Con set, establece el ajuste de feed
+como se especifica.
+.RE
+.P
+\fBspindle_override \fR
+.RS
+Con get, se ignora cualquier parámetro y retorna el ajuste de husillo actual
+(como un porcentaje de husillo ordenado). Con set, establece el ajuste de husillo
+como se especifica.
+.RE
+.P
+\fBabs_cmd_pos [{0|1|...}]\fR
+.RS
+Con get, devuelve la posición ordenada del eje especificado en absoluto
+coordenadas Si no se especifica ningún eje, devuelve todos los ejes ordenados
+posición absoluta
+.RE
+.P
+\fBabs_act_pos [{0|1|...}]\fR
+.RS
+Con get, devuelve la posición real del eje especificado en absoluto
+coordenadas Si no se especifica ningún eje, devuelve el absoluto real de todos los ejes
+posición.
+.RE
+.P
+\fBrel_cmd_pos [{0|1|...}]\fR
+.RS
+Con get, devuelve la posición ordenada del eje especificado en relación
+coordenadas, incluido el desplazamiento de la longitud de la herramienta. Si no se especifica ningún eje,
+devuelve la posición relativa ordenada de todos los ejes.
+.RE
+.P
+\fBrel_act_pos [{0|1|...}]\fR
+.RS
+Con get, devuelve la posición real del eje especificado en relación
+coordenadas, incluido el desplazamiento de la longitud de la herramienta. Si no se especifica ningún eje,
+devuelve la posición relativa real de todos los ejes.
+.RE
+.P
+\fBjoint_pos [{0|1|...}]\fR
+.RS
+Con get, devuelve la posición real de la articulación especificada en absoluto
+coordenadas, excluyendo el desplazamiento de la longitud de la herramienta. Si no se especifica una junta,
+devuelve la posición absoluta real de todas las articulaciones.
+.RE
+.P
+\fBpos_offset [{X|Y|Z|R|P|W}]\fR
+.RS
+Con get, devuelve el desplazamiento de posición asociado con la coordenada mundial
+previsto.
+.RE
+.P
+\fBjoint_limit [{0|1|...}]\fR
+.RS
+Con get, devuelve el estado límite de la unión especificada como "ok", "minsoft",
+"minhard", "maxsoft" o "maxhard". Si no se especifica un número conjunto,
+devuelve el estado límite de todas las articulaciones.
+.RE
+.P
+\fBjoint_fault [{0|1|...}]\fR
+.RS
+Con get, devuelve el estado de falla de la unión especificada como "ok" o
+"culpa". Si no se especifica un número conjunto, devuelve el estado de falla de
+Todas las articulaciones.
+.RE
+.P
+\fBjoint_homed [{0|1|...}]\fR
+.RS
+Con get, devuelve el estado de referencia de la unión especificada como "referenciada"
+o no". Si no se especifica un número conjunto, devuelve el estado de inicio de
+Todas las articulaciones.
+.RE
+.P
+\fBmdi \fR
+.RS
+Con set, envía como un comando MDI.
+.RE
+.P
+\fBtask_plan_init\fR
+.RS
+Con set, inicializa el intérprete de programa.
+.RE
+.P
+\fBopen \fR
+.RS
+Con set, abre el archivo con nombre. El es abierto por linuxcnc,
+por lo que debería ser una ruta absoluta o una ruta relativa que comience en
+el directorio de trabajo de linuxcnc (el directorio del archivo .ini activo).
+.RE
+.P
+\fBrun []\fR
+.RS
+Con set, ejecuta el programa abierto. Si no se especifica StartLine, se ejecuta
+desde el principio. Si se especifica una línea de inicio, la línea de inicio se ejecuta desde
+esa linea. Una línea de inicio de \ -1 se ejecuta en modo de verificación.
+.RE
+.P
+\fBpause\fR
+.RS
+Con set, pausa la ejecución del programa.
+.RE
+.P
+\fBresume\fR
+.RS
+Con set, reanudar la ejecución del programa.
+.RE
+.P
+\fBabort\fR
+.RS
+Con set, abortar programa o ejecución MDI.
+.RE
+.P
+\fBstep\fR
+.RS
+Con set, pasa el programa una línea.
+.RE
+.P
+\fBprogram\fR
+.RS
+Con get, devuelve el nombre del programa abierto actualmente o "ninguno".
+.RE
+.P
+\fBprogram_line\fR
+.RS
+Con get, devuelve la línea actualmente en ejecución del programa.
+.RE
+.P
+\fBprogram_status\fR
+.RS
+Con get, devuelve "inactivo", "en ejecución" o "en pausa".
+.RE
+.P
+\fBprogram_codes\fR
+.RS
+Con get, devuelve la cadena para los códigos de programa actualmente activos.
+.RE
+.P
+\fBjoint_type []\fR
+.RS
+Con get, devuelve "lineal", "angular" o "personalizado" para el tipo de
+junta especificada (o para todas las juntas si no se especifica ninguna).
+.RE
+.P
+\fBjoint_units []\fR
+.RS
+Con get, devuelve "inch", "mm", "cm" o "deg", "rad", "grad" o
+"personalizado", para las unidades nativas correspondientes de la unión especificada (o
+para todas las juntas si no se especifica ninguna). El tipo del eje (lineal o
+angular) se utiliza para resolver qué tipo de unidades se devuelven. las unidades
+se obtienen heurísticamente, en base a las unidades numéricas EMC_AXIS_STAT ::
+valor de unidades de usuario por mm o deg. Para juntas lineales, algo cercano
+a 0.03937 se considera "pulgada", 1.000 es "mm", 0.1 es "cm", de lo contrario es
+"personalizado". Para juntas angulares, algo cercano a 1,000 se considera "deg",
+PI / 180 es "rad", 100/90 es "grad", de lo contrario es "personalizado".
+.RE
+.P
+\fBprogram_units\fR
+.RS
+Sinónimo de program_linear_units.
+.RE
+.P
+\fBprogram_linear_units\fR
+.RS
+Con get, devuelve "inch", "mm", "cm" o "none", para el correspondiente
+unidades lineales que están activas en el intérprete de programa.
+.RE
+.P
+\fBprogram_angular_units\fR
+.RS
+Con get, devuelve "deg", "rad", "grad" o "none" para el correspondiente
+unidades angulares que están activas en el intérprete de programa.
+.RE
+.P
+\fBuser_linear_units\fR
+.RS
+Con get, devuelve "inch", "mm", "cm" o "custom", para el correspondiente
+Unidades lineales de usuario nativo del nivel de trayectoria LinuxCNC. Esto se obtiene
+heurísticamente, basado en el valor numérico EMC_TRAJ_STAT :: linearUnits
+de unidades de usuario por mm. Algo cercano a 0.03937 se considera "pulgada",
+1.000 es "mm", 0.1 es "cm", de lo contrario es "personalizado".
+.RE
+.P
+\fBuser_angular_units\fR
+.RS
+Devuelve "deg", "rad", "grad" o "custom" para el nativo correspondiente
+Unidades angulares de usuario del nivel de trayectoria LinuxCNC. Al igual que con las unidades lineales,
+Esto se obtiene heurísticamente.
+.RE
+.P
+\fBdisplay_linear_units\fR
+.RS
+Con get, devuelve "inch", "mm", "cm" o "personalizado" para el lineal
+unidades que están activas en la pantalla. Este es efectivamente el valor
+de linearUnitConversion.
+.RE
+\fBdisplay_angular_units\fR
+.RS
+Con get, devuelve "deg", "rad", "grad" o "custom", para el angular
+unidades que están activas en la pantalla. Este es efectivamente el valor
+de angularUnitConversion.
+.RE
+.P
+\fBlinear_unit_conversion {inch|mm|cm|auto}\fR
+.RS
+Con get, se ignora cualquier parámetro y la conversión de unidad activa es
+devuelto Con set, establece la unidad que se mostrará. Si es "auto",
+las unidades que se mostrarán coinciden con las unidades del programa.
+.RE
+.P
+\fBangular_unit_conversion {deg|rad|grad|auto}\fR
+.RS
+Con get, se ignora cualquier parámetro y la conversión de unidad activa es
+devuelto Con set, establece las unidades que se mostrarán. Si es "auto",
+las unidades que se mostrarán coinciden con las unidades del programa.
+.RE
+.P
+\fBprobe_clear\fR
+.RS
+Con el set, borre la bandera de la sonda disparada.
+.RE
+.P
+\fBprobe_tripped\fR
+.RS
+Con get, devuelve el estado de la sonda: ¿se ha disparado la sonda desde el último borrado?
+.RE
+.P
+\fBprobe_value\fR
+.RS
+Con get, devuelve el valor actual de la señal de la sonda.
+.RE
+.P
+\fBprobe\fR
+.RS
+Con el set, muévete hacia una determinada ubicación. Si la sonda se dispara
+la forma de detener el movimiento, registrar la posición y levantar la bandera de la sonda disparada.
+.RE
+.P
+\fBteleop_enable [on|off]\fR
+.RS
+Con get, se ignora cualquier parámetro y el modo teleop actual es
+devuelto Con set, establece el modo teleop como se especifica.
+.RE
+.P
+\fBkinematics_type\fR
+.RS
+Con get, devuelve el tipo de funciones cinemáticas utilizadas (identidad = 1,
+serial = 2, paralelo = 3, personalizado = 4).
+.RE
+.P
+\fBoverride_limits {on|off}\fR
+.RS
+Con get, se ignora cualquier parámetro y la configuración override_limits es
+devuelto Con set, el parámetro override_limits se establece como se especifica.
+Si override_limits está activado, deshabilita los límites de hardware de fin de viaje para
+permitir correr fuera de un límite. Si los parámetros están desactivados, entonces los límites de hardware
+están habilitados
+.RE
+.P
+\fBoptional_stop {0|1}\fR
+.RS
+Con get, se ignora cualquier parámetro y la actual "parada opcional en M1"
+Se devuelve la configuración. Con set, la configuración se establece como se especifica.
+.RE
+.SH Sesión de ejemplo
+.P
+Esta sección muestra una sesión de ejemplo para la máquina local (\fBlocalhost\fR).
+Usted escribe los elementos en negrita, la salida de máquina no es negrita. Los valores predeterminados se muestran para
+--port PORT_NUMBER (\fB5007\fR), --conectpw PASSWORD (\fBEMC\fR) y
+--enablepw CONTRASEÑA (\fBEMCTOO\fR).
+.P
+El usuario se conecta a linuxcncrsh, reconocimiento con el servidor (hello), habilita
+comandos para la máquina de esta sesión (set enable), saca la máquina
+de parada (apaga estop) y la enciende (la máquina), hace todos los home de
+los ejes, cambia la máquina al modo mdi, envía un comando MDI de código g,
+luego se desconecta y apaga LinuxCNC.
+.P
+> \fBtelnet localhost 5007\fR
+.br
+Trying 127.0.0.1...
+.br
+Connected to 127.0.0.1
+.br
+Escape character is '^]'.
+.br
+\fBhello EMC user\-typing\-at\-telnet 1.0\fR
+.br
+HELLO ACK EMCNETSVR 1.1
+.br
+\fBset enable EMCTOO\fR
+.br
+set enable EMCTOO
+.br
+\fBset mode manual\fR
+.br
+set mode manual
+.br
+\fBset estop off\fR
+.br
+set estop off
+.br
+\fBset machine on\fR
+.br
+set machine on
+.br
+\fBset home 0\fR
+.br
+set home 0
+.br
+\fBset home 1\fR
+.br
+set home 1
+.br
+\fBset home 2\fR
+.br
+set home 2
+.br
+\fBset mode mdi\fR
+.br
+set mode mdi
+.br
+\fBset mdi g0x1\fR
+.br
+set mdi g0x1
+.br
+\fBhelp\fR
+.br
+help
+.br
+Available commands:
+ Hello
+ Get
+ Set
+ Shutdown
+ Help
+.br
+\fBhelp get\fR
+.br
+help get
+.br
+Usage:
+Get
+ Get commands require that a hello has been successfully negotiated.
+ Emc command may be one of:
+ Abs_act_pos
+ Abs_cmd_pos
+.br
+\fB ... \fR
+.br
+\fBshutdown\fR
+.br
+shutdown
+.br
+Connection closed by foreign host.
diff --git a/docs/man/es/man1/mb2hal.1 b/docs/man/es/man1/mb2hal.1
new file mode 100644
index 0000000000..5e86be0aad
--- /dev/null
+++ b/docs/man/es/man1/mb2hal.1
@@ -0,0 +1,40 @@
+.\" Copyright (c) 2016 John Thornton
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH mb2hal "1" "January 1, 2016" "Modbus to HAL" "LinuxCNC Documentation"
+.SH NAME
+\fBmb2hal\fR - HAL userspace component for Modbus
+.SH SYNOPSIS
+.B mb2hal
+.RI [OPTIONS]
+.br
+.SH DESCRIPTION
+MB2HAL is a generic userspace HAL component to communicate with one or more
+Modbus devices.
+.PP
+See the Documents for more information on mb2hal
+.SH AUTHOR
+John Thornton
+.SH LICENSE
+GPL
diff --git a/docs/man/es/man1/milltask.1 b/docs/man/es/man1/milltask.1
new file mode 100644
index 0000000000..a629b48c50
--- /dev/null
+++ b/docs/man/es/man1/milltask.1
@@ -0,0 +1,112 @@
+.TH milltask 1 "30 de septiembre de 2014" "" "EMC Controlador de maquina mejorado"
+.SH NOMBRE
+\fBmilltask\fR \- Controlador de tareas de espacio de usuario para LinuxCNC
+.SH DESCRIPCION
+
+\fBmilltask\fR es un proceso interno de LinuxCNC. Generalmente no
+se invoca directamente, sino mediante una configuracion de archivo: \fB[TASK]TASK=milltask\fR.
+El proceso \fBmilltask\fR crea los pines HAL \fBini.*\fR enumerados a continuacion, que son
+propiedad del componente de usuario \fBinihal\fR. Estos pines pueden ser modificados
+mientras LinuxCnC se esta ejecutando para alterar los valores que normalmente se especifican
+en un inifile
+
+Los pines \fBinihal\fR se \fBmuestrean\fR en cada ciclo de tareas, sin embargo, los comandos
+afectados por sus valores suelen utilizar el valor presente en el momento
+cuando se procesa el comando. Tales comandos incluyen todos los codigos manejados
+por el interprete (programas \fBGcode\fR y comandos \fBMDI\fR comandos) y comandos NML
+\fBjogging\fR emitidos por una GUI (incluida \fBhalui\fR).
+\fBEl volante de jogging\fR se implementa en el modulo de movimiento en tiempo real de forma que
+\fBinihal\fR los cambios en pines (por ejemplo, ini.*.max_velocity,
+ini.*.max_acceleration) puede ser tratados tan pronto como los valores alterados sean
+conocidos por el modulo de movimiento.
+
+.SH PINES
+.SS Pines por articulacion (N == numero de articulacion)
+.TP
+\fBini.\fIN\fB.backlash
+Permite el ajuste de \fB[JOINT_\fIN\fB]BACKLASH
+.TP
+\fBini.\fIN \fB.ferror
+Permite el ajuste de \fB[JOINT_\fIN\fB]FERROR
+.TP
+\fBini.\fIN \fB.min_ferror
+Permite el ajuste de \fB[JOINT_\fIN\fB]MIN_FERROR
+.TP
+\fBini.\fIN \fB.min_limit
+Permite el ajuste de \fB[JOINT_\fIN\fB]MIN_LIMIT
+.TP
+\fBini.\fIN \fB.max_limit
+Permite el ajuste de \fB[JOINT_\fIN\fB]MAX_LIMIT
+.TP
+\fBini.\fIN \fB.max_velocity
+Permite el ajuste de \fB[JOINT_\fIN\fB]MAX_VELOCITY
+.TP
+\fBini.\fIN \fB.max_acceleration
+Permite el ajuste de \fB[JOINT_\fIN\fB]MAX_ACCELERATION
+.TP
+\fBini.\fIN \fB.home
+Permite el ajuste de \fB[JOINT_\fIN\fB]HOME
+.TP
+\fBini.\fIN \fB.home_offset
+Permite el ajuste de \fB[JOINT_\fIN\fB]HOME_OFFSET
+.TP
+\fBini.\fIN \fB.home_offset
+Permite el ajuste de \fB[JOINT_\fIN\fB]HOME_SEQUENCE
+
+.SS pines por eje (L == eje de la letra)
+.TP
+\fBini.\fIL \fB.min_limit
+Permite el ajuste de \fB[AXIS_\fIL\fB]MIN_LIMIT
+.TP
+\fBini.\fIL \fB.max_limit
+Permite el ajuste de \fB[AXIS_\fIL\fB]MAX_LIMIT
+.TP
+\fBini.\fIL \fB.max_velocity
+Permite el ajuste de \fB[AXIS_\fIL\fB]MAX_VELOCITY
+.TP
+\fBini.\fIL \fB.max_acceleration
+Permite el ajuste de \fB[AXIS_\fIL\fB]MAX_ACCELERATION
+
+.SS Pines Globales
+.TP
+\fBini.traj_default_acceleration
+Permite el ajuste de \fB[TRAJ]DEFAULT_ACCELERATION
+.TP
+\fBini.traj_default_velocity
+Permite el ajuste de \fB[TRAJ]DEFAULT_VELOCITY
+.TP
+\fBini.traj_max_acceleration
+Permite el ajuste de \fB[TRAJ]MAX_ACCELERATION
+.TP
+\fBini.traj_max_velocity
+Permite el ajuste de \fB[TRAJ]MAX_VELOCITY
+
+.SS Pines Globales (planificador de trayectoria arc_blend)
+.TP
+\fBini.traj_arc_blend_enable
+Permite el ajuste de \fB[TRAJ]ARC_BLEND_ENABLE
+.TP
+\fBini.traj_arc_blend_fallback_enable
+Permite el ajuste de \fB[TRAJ]ARC_BLEND_FALLBACK_ENABLE
+.TP
+\fBini.traj_arc_blend_gap_cycles
+Permite el ajuste de \fB[TRAJ]ARC_OPTIMIZATION_DEPTH
+.TP
+\fBini.traj_arc_blend_optimization_depth
+Permite el ajuste de \fB[TRAJ]ARC_BLEND_GAP_CYCLES
+.TP
+\fBini.traj_arc_blend_ramp_freq
+Permite el ajuste de \fB[TRAJ]ARC_BLEND_RAMP_FREQ
+
+.SH NOTAS
+
+Los pines \fBinihal\fR no pueden vincularse o establecerse en un halfile que es
+especificado por un elemento inifile \fB[HAL]HALFILE\fR porque no se crean
+hasta que se inicie \fBmilltask\fR. Los valores de pines \fBinihal\fR pueden ser
+alterados por programas independientes de halcmd especificados por elementos
+\fB[APPLICATION]APP\fR o por GUIs que soportan un
+\fB[HAL]POSTGUI_HALFILE\fR.
+
+El archivo inifile no se actualiza automaticamente con los valores alterados por configuracionws de pines de
+\fBinihal\fR, pero se puede actualizar utilizando el programa de calibracion
+(emccalib.tcl) cuando se usa \fB[HAL]POSTGUI_HALFILE\fR.
\ No newline at end of file
diff --git a/docs/man/es/man1/mitsub_vfd.1 b/docs/man/es/man1/mitsub_vfd.1
new file mode 100644
index 0000000000..d6a0a41899
--- /dev/null
+++ b/docs/man/es/man1/mitsub_vfd.1
@@ -0,0 +1,238 @@
+.TH mitsub_vfd "1" "2018-10-25" "LinuxCNC Documentation" "HAL Component"
+
+
+.SH NAME
+
+mitsub_vfd - HAL userspace component for Mitsubishi A500 F500
+E500 A500 D700 E700 F700-series VFDs (others may work)
+
+
+.SH SYNOPSIS
+
+.B loadrt mitsub_vfd [--baud 4800] [--port /dev/ttyUSB0] name1=number1[,name2=numer2...]
+.br
+\fBname1\fR is user selectable (usually a description of the
+controlled device).
+.br
+\fBnumber1\fR is the slave number that was set on the VFD.
+must be two digits (Parameter 117)
+.br
+\fBname=number\fR can be repeated for multiple VFD's
+connected together
+.br
+\fB--baud\fR is optional as it defaults to 9600
+ all networked vfds must be set to the same baudrate
+.br
+\fB--port\fR is optional as it defaults to ttyS0
+
+.SH DESCRIPTION
+
+The mitsub_vfd component interfaces a Mitsubishi VFD to
+LinuxCNC. The VFD is connected via RS-485 serial to the
+computer's USB or serial port using a RS-232/RS-485 converter
+
+
+.SH HARDWARE SETUP
+reference manual 'communication option reference manual'
+and A500 technical manual for 500 series.
+Fr-A700 F700 E700 D700 technical manual for the 700 series
+.br
+The inverter must be set manually for communication
+.br
+( you may have to set PR 77 to 1 to unlock PR modifcation )
+.br
+You must power cycle the inverter for some of these. (eg 79)
+
+.TP
+\fBVFD INTERNAL PARAMETERS: \fR
+
+\fBPARAMETER 79\fR - 1 or 0
+
+\fBPARAMETER 117\fR station number - 1
+.br
+(can be optionally set 0 - 31) if component is also set
+
+\fBPARAMETER 118\fR communication speed 96
+.br
+(can be optionally set 48,96,192 if component is also set)
+
+\fBPARAMETER 119\fR stop bit/data length - 0
+.br
+(8 bits, two stop - don't change)
+
+\fBPARAMETER 120\fR parity - 0
+.br
+(no parity - don't change)
+
+\fBPARAMETER 121\fR COM tries - 10
+.br
+(if maximuim 10 COM errors then inverter faults- can change)
+
+\fBPARAMETER 122\fR COM check time interval 9999
+.br
+(never check - if communication is lost inverter will
+not know (can change)
+
+\fBPARAMETER 123\fR wait time - 9999
+.br
+no wait time is added to the serial data frame (don't change)
+
+\fBPARAMETER 124\fR CR selection - 0
+.br
+don't change
+
+.SH
+
+This driver assumes certain other VFD settings:
+-That the motor frequency status is set to show herts.
+.br
+-That the status bit 3 is up to speed
+.br
+-That the status bit 7 is alarm
+
+some models (eg E500) cannot monitor status.
+.br
+You must set set the monitor pin to false.
+.br
+In this case pins such as up-to-speed,
+amps, alarm and status bits are not useful.
+
+.SH PINS
+\fB[VFD NAME].fwd\fR (bit, in)::
+ forward/reverse pin
+.br
+\fB[VFD NAME].run\fR (bit, in)::
+ run/stop pin
+.br
+\fB[VFD NAME].debug\fR (bit, in)::
+ set debug mode pin
+.br
+ This will print many messages to the terminal
+.br
+\fB[VFD NAME].monitor\fR (bit, in)::
+ set monitor mode pin
+ If false request-status command will not be sent to vfd.
+ Status, amps, power, motor-feedback, and alarm would then not
+ be useful.
+.br
+\fB[VFD NAME].estop\fR (bit, in)::
+ set estop mode pin
+.br
+ This will stop the VFD.
+ Restarting requires the run pin to cycle.
+
+\fB[VFD NAME].fwd\fR (bit, out)::
+ up-to-speed status pin
+ Motor is at requested speed within VFD's settings tolerance.
+.br
+\fB[VFD NAME].alarm\fR (bit, out)::
+ alarm status pin
+.br
+
+\fB[VFD NAME].motor-cmd\fR (float, in)::
+ The requested motor speed, is Hertz
+.br
+
+\fB[VFD NAME].motor-fb\fR (float, out)::
+ The motor feedback speed (from vfd) in hertz
+.br
+\fB[VFD NAME].motor-amps\fR (float, out)::
+ The motor current, in amps
+.br
+\fB[VFD NAME].motor-power\fR (float, out)::
+ The motor power
+.br
+
+\fB[VFD NAME].scale-cmd\fR (float, in)::
+ Motor command's scale setting defaults to 1
+.br
+\fB[VFD NAME].scale-cmd\fR (float, in)::
+ Motor command's scale setting defaults to 1
+.br
+\fB[VFD NAME].scale-cmd\fR (float, in)::
+ Motor command's scale setting defaults to 1
+.br
+
+\fB[VFD NAME].stat-bit-0\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-1\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-2\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-3\fR (bit, out)::
+ raw status bit
+ set the VFD so this is motor-at-speed status
+.br
+\fB[VFD NAME].stat-bit-4\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-5\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-6\fR (bit, out)::
+ raw status bit
+.br
+\fB[VFD NAME].stat-bit-7\fR (bit, out)::
+ raw status bit
+ Set the VFD so this in the alarm bit
+
+.SH SAMPLE HAL
+loadusr -Wn coolant mitsub_vfd --port /dev/ttyUSB0 spindle=02 coolant=01
+.br
+# **************** Spindle VFD setup slave 2 ****************
+.br
+net spindle-vel-cmd spindle.motor-cmd
+.br
+net spindle-cw spindle.fwd
+.br
+net spindle-on spindle.run
+.br
+net spindle-at-speed spindle.up-to-speed
+.br
+net estop-out spindle.estop
+.br
+# cmd scaled to RPM (belt/gearbox driven)
+.br
+setp spindle.scale-cmd .135
+.br
+# feedback is in rpm (recipicale of command)
+.br
+setp spindle.scale-fb 7.411
+.br
+# turn on monitoring so feedback works
+.br
+setp spindle.monitor 1
+.br
+net spindle-speed-indicator spindle.motor-fb
+.br
+# *************** Coolant vfd setup slave 1 *****************
+.br
+net coolant-flood coolant.run
+.br
+net coolant-is-on coolant.up-to-speed
+.br
+# cmd and feedback scaled to hertz
+.br
+setp coolant.scale-cmd 1
+.br
+setp coolant.scale-fb 1
+.br
+# command full speed
+.br
+setp coolant.motor-cmd 60
+.br
+# allows us to see status
+.br
+setp coolant.monitor 1
+.br
+net estop-out coolant.estop
+
+.SH ISSUES
+
+some models (eg E500) cannot monitor status, so set the
+monitor pin to false In this case pins such as up-to-speed,
+amps, alarm and status bits are not useful.
+
diff --git a/docs/man/es/man1/moveoff_gui.1 b/docs/man/es/man1/moveoff_gui.1
new file mode 100644
index 0000000000..5bdfc18ab0
--- /dev/null
+++ b/docs/man/es/man1/moveoff_gui.1
@@ -0,0 +1,238 @@
+.\" Copyright (c) 2014 Dewey Garrett
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH moveoff_gui "1" "2014-12-18" "Documentacion de LinuxCNC" "LinuxCNC"
+.SH NOMBRE
+moveoff_gui \- GUI para el componente moveoff
+
+.SH SINOPSIS
+.B moveoff_gui \fB[\-\-help | \-\- \-h | \-?]\fR
+
+.PP
+.B moveoff_gui [\fBopciones\fR]
+.PP
+
+.SH DESCRIPCION
+Moveoff_gui es una interfaz grafica de usuario (GUI) para
+controlar un componente moveoff de Hal para implementar offsets.
+Ver la pagina de manual (man moveoff) para \fBIMPORTANTES Limitaciones y Advertencias\fR .
+
+Las configuraciones compatibles deben usar un modulo de cinematica conocido como
+\fBKINEMATICS_TYPE=KINEMATICS_IDENTITY\fR . Los modulos actualmente
+soportados son:
+ \fBtrivkins\fR
+
+.SH OPCIONES
+
+.TP
+\fB\-\-help | \-? |\-\- \-h\fR
+Mostrar opciones y salir
+
+.TP
+\fB\-mode\fR \fBonpause\fR | always
+.br
+Onpause: gui emergente para controlar los offsets cuando el programa esta en pausa
+.br
+always: mostrar siempre la gui para controlar los offsets.
+.br
+Predeterminado: \fBonpause\fR
+
+.TP
+\fB\-axes\fR axisnames
+.br
+Letras del conjunto {x y z a b c u v w}
+.br
+Ejemplos:\-axes x,\-axes xyz,\-axes xz (sin espacios)
+.br
+Predeterminado: \fBxyz\fR
+
+.TP
+\fB\-inc\fR incrementvalue
+.br
+Especifica un valor de incremento por \-inc (hasta 4)
+.br
+Valores predeterminados: \fB0.001 0.01 0.10 1.0\fR
+
+.TP
+\fB\-size\fR integer
+.br
+El tama\[~n]o total de la interfaz grafica de usuario se basa en el tama\[~n]o de la fuente, normalmente entre 8 y 20
+.br
+Predeterminado: \fB14\fR
+
+.TP
+\fB\-loc\fR center | +x+y
+.br
+Ubicacion inicial en pantalla
+.br
+Ejemplos:\-loc center, \-loc +20+100
+.br
+Predeterminado: \fBcenter\fR
+
+.TP
+\fB\-autoresume\fR
+.br
+Reanudar el programa cuando se desactiva move-enable
+.br
+Predeterminado: no utilizado
+
+.TP
+\fB\-delay\fR delay_secs
+.br
+Retraso para autoresume (dar tiempo para restaurar la velocidad del husillo, etc.)
+Predeterminado: \fB5\fR
+
+.SH OTRAS OPCIONES
+Estas opciones estan disponibles para casos especiales:
+
+.TP
+\fB\-noentry\fR
+.br
+Desactiva la creacion de widgets de entrada.
+.br
+Predeterminado: no utilizado
+
+.TP
+\fB\-no_resume_inhibit\fR
+.br
+Deshabilitar el uso de reanudar\-inhibir para controlar gui
+.br
+Predeterminado: no utilizado
+
+.TP
+\fB\-no_pause_requirement
+.br
+Desactivar la comprobacion de halui.program.is\-paused
+.br
+Predeterminado: no utilizado
+
+.TP
+\fB\-no_cancel_autoresume
+.br
+util para retraer compensaciones con controles externos simples
+.br
+Predeterminado: no utilizado
+
+.TP
+\fB\-no_display
+.br
+Se usa cuando los controles externos y las pantallas externas estan en uso
+.br
+Predeterminado: no utilizado
+
+.SH NOTAS
+LinuxCNC debe estar ejecutandose.
+.P
+Halui debe estar cargado; configuracion tipica de archivo ini
+ \fB [HAL]HALUI = halui\fR .
+.P
+El componente moveoff debe cargarse con el nombre 'mv':
+.br
+ \fBloadrt moveoff names=mv personality=number_of_axes\fR
+.P
+Si el pin mv.motion\-enable \fBno\fR esta conectado cuando se inicia moveoff_gui,
+\fBcontrols se proporcionara controles\fR para habilitar las compensaciones y establecer
+valores de desplazamiento. Si el pin \fBesta\fR conectado, se muestra \fBsolo una pantalla\fR
+de compensaciones y el control debe hacerse por conexiones HAL \fBexternas\fR.
+.P
+Si un pin llamado *.resume\-inhibit existe y no esta conectado, lo hara
+Se establece mientras se aplican las compensaciones. Este pin puede ser proporcionado por el
+controlando linuxcnc gui en uso. El uso del pin puede estar deshabilitado.
+con la opcion\-no_resume_inhibit.
+.P
+La opcion\-autoresume usa halui.program.resume para reanudar automaticamente
+la ejecucion del programa cuando el pin de move\-enable esta desactivado
+y todas las compensaciones se eliminan. El pin de reanudacion no esta activado
+hasta que transcurra un intervalo adicional (\-delay delay_secs).
+El intervalo de demora puede ser util para reiniciar equipos relacionados
+(un motor de husillo, por ejemplo). Mientras se sincroniza el retraso, se muestra una ventana emergente
+que ofrece cancelar la reanudacion automatica del programa.
+
+.SH USO
+El archivo ini en el directorio de configuracion debe proporcionar HALFILEs
+para cargar el componente de movimiento, conectar sus pines y agregar sus funciones
+de lectura y escritura en el orden correcto. Estos pasos pueden ser
+hecho en tiempo de ejecucion utilizando un archivo ini de configuracion existente y
+especificando una biblioteca del sistema HALFILE \fBhookup_moveoff.tcl\fR como se
+ilustra:
+.P
+\fB[HAL]\fR
+.br
+HALUI = halui
+.br
+HALFILE = user_halfile_1
+.br
+etc ...
+.br
+HALFILE = user_halfile_n
+.br
+\fBHALFILE = LIB:hookup_moveoff.tcl\fR
+.P
+El halfile \fBhookup_moveoff.tcl\fR usara la configuracion del archivo ini para
+los pines de control del componente moveoff:
+.P
+\fB[OFFSET]\fR
+.br
+EPSILON =
+.br
+WAYPOINT_SAMPLE_SECS =
+.br
+WAYPOINT_THRESHOLD =
+.br
+BACKTRACK_ENABLE =
+.P
+\fBhookup_moveoff.tcl\fR utilizara la configuracion del archivo ini para los
+limites por eje de moveoff:
+.P
+\fB[AXIS_m]\fR
+.br
+OFFSET_MAX_VELOCITY =
+.br
+OFFSET_MAX_ACCELERATION =
+.br
+OFFSET_MAX_LIMIT =
+.br
+OFFSET_MIN_LIMIT =
+.P
+El programa moveoff_gui debe especificarse en las APPLICATIONS
+del archivo ini, por ejemplo:
+.P
+\fB[APLICACIONES]\fR
+.br
+DELAY = delay_in_secs_to_allow_hal_connections
+.br
+\fBAPP = moveoff_gui\-option1\-option2 ...\fR
+.P
+
+.SH "VER TAMBIEN"
+Las configuraciones de simulacion que demuestran moveoff_gui y el
+componente moveoff se encuentran en:
+.P
+ configs/sim/axis/moveoff (axis-ui)
+.br
+ configs/sim/touchy/ngcgui (touchy-ui)
+
+Pagina del manual para el componente moveoff:\fBmoveoff\fR(9)
+
+
diff --git a/docs/man/es/man1/pmx485.1 b/docs/man/es/man1/pmx485.1
new file mode 100644
index 0000000000..6c66acda2c
--- /dev/null
+++ b/docs/man/es/man1/pmx485.1
@@ -0,0 +1,39 @@
+.\" Copyright (c) 2020 Phillip A Carter
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH pmx485 "1" "Feb 1 2020" "Powermax Modbus Communications" "LinuxCNC Documentation"
+.SH NAME
+\fBpmx485\fR - Modbus communications with a Powermax Plasma Cutter
+.SH SYNOPSIS
+.B loadusr -Wn pmx485 pmx485 /dev/ttyUSB0
+.br
+.SH DESCRIPTION
+pmx485 is a userspace HAL component to communicate with a Hypertherm Powermax
+plasma cutter using the Modbus ASCII protocol over RS485.
+.PP
+See the Drivers section of the LinuxCNC Documentation for more information on pmx485
+.SH AUTHOR
+Phillip Carter
+.SH LICENSE
+GPL
diff --git a/docs/man/es/man1/pyvcp.1 b/docs/man/es/man1/pyvcp.1
new file mode 100644
index 0000000000..83294377a8
--- /dev/null
+++ b/docs/man/es/man1/pyvcp.1
@@ -0,0 +1,39 @@
+.\" Copyright (c) 2007 Jeff Epler
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.TH PYVCP "1" "2007-04-01" "Documentación LinuxCNC" "El controlador de máquina mejorado"
+.SH NOMBRE
+pyvcp \- Panel de control virtual para LinuxCNC
+.SH SINOPSIS
+\fBpyvcp\fR [\-g \fIWxH+X+Y\fR] [\-c \fIcomponent\-name\fR] \fImyfile.xml\fR
+.SH OPCIONES
+.TP
+\fB\-g\fR \fIWxH + X + Y\fR
+Esto establece la geometría inicial de la ventana raíz.
+Use 'WxH' solo para el tamaño, '+ X + Y' para solo la posición, o 'WxH + X + Y' para ambos.
+El tamaño/posición utiliza unidades de píxeles. Se hace referencia a la posición desde la parte superior izquierda.
+.TP
+\fB\-c\fR\fIcomponent-name\fR
+Use \fIcomponent-name\fR como el nombre del componente HAL. Si el nombre del componente no es
+especificado, se utiliza el nombre base del archivo xml. \fR
+.SH "VER TAMBIÉN"
+\fIPython Virtual Control Panel\fR en la documentación de LinuxCNC para obtener una descripción de
+sintaxis xml, junto con ejemplos
diff --git a/docs/man/es/man1/shuttle.1 b/docs/man/es/man1/shuttle.1
new file mode 100644
index 0000000000..66ceb578de
--- /dev/null
+++ b/docs/man/es/man1/shuttle.1
@@ -0,0 +1,95 @@
+.TH SHUTTLE "1" "2011-01-13" "LinuxCNC Documentation" "HAL User's Manual"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+.SH NAME
+shuttle \- control HAL pins with the ShuttleXpress or ShuttlePRO device made by Contour Design
+.SH SYNOPSIS
+\fIloadusr\fR \fBshuttle\fR \fI[DEVICE ...]\fR
+.SH DESCRIPTION
+shuttle is a non-realtime HAL component that interfaces Contour
+Design's ShuttleXpress and ShuttlePRO devices with LinuxCNC's HAL.
+
+.PP
+If the driver is started without command-line arguments, it will probe all
+/dev/hidraw* device files for Shuttle devices, and use all devices found.
+If it is started with command-line arguments, it will only probe the
+devices specified.
+
+.PP
+The ShuttleXpress has five momentary buttons, a 10 counts/revolution
+jog wheel with detents, and a 15-position spring-loaded outer wheel that
+returns to center when released.
+
+.PP
+The ShuttlePRO has 13 momentary buttons, a 10 counts/revolution
+jog wheel with detents, and a 15-position spring-loaded outer wheel that
+returns to center when released.
+
+.SH UDEV
+The shuttle driver needs read permission to the Shuttle devices'
+/dev/hidraw* device files. This can be accomplished by adding a file
+\fB/etc/udev/rules.d/99-shuttle.rules\fR, with the following contents:
+
+SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0b33", ATTRS{idProduct}=="0020", MODE="0444"
+
+SUBSYSTEM=="hidraw", ATTRS{idVendor}=="05f3", ATTRS{idProduct}=="0240", MODE="0444"
+
+The LinuxCNC Debian package installs an appropriate udev file
+automatically, but if you are building LinuxCNC from source and are not
+using the Debian packaging, you'll need to install this file by hand.
+
+.SH A warning about the Jog Wheel
+The Shuttle devices have an internal 8-bit counter for the current
+jog-wheel position. The shuttle driver can not know this value
+until the Shuttle device sends its first event. When the first
+event comes into the driver, the driver uses the device's reported
+jog-wheel position to initialize counts to 0.
+
+This means that if the first event is generated by a jog-wheel move,
+that first move will be lost.
+
+Any user interaction with the Shuttle device will generate an event,
+informing the driver of the jog-wheel position. So if you (for example)
+push one of the buttons at startup, the jog-wheel will work fine and
+notice the first click.
+
+.SH Pins
+
+All HAL pin names are prefixed with the type of device followed by
+the index of the device (the order in which the driver found them),
+for example "shuttlexpress.0" or "shuttlepro.2".
+
+.TP
+(bit out) \fI(prefix).button-(number)\fR
+.TP
+(bit out) \fI(prefix).button-(number)-not\fR
+
+ The momentary buttons. "(number)" identifies which button corresponds
+ to the HAL pin. The "button-(number)" pins are True when the button
+ is pushed, the "button-(number)-not" pins are True when the button
+ is not pushed.
+
+.TP
+(s32 out) \fI(prefix).counts\fR
+
+ Accumulated counts from the jog wheel (the inner wheel).
+
+.TP
+(s32 out) \fI(prefix).spring-wheel-s32\fR
+
+ The current deflection of the spring-wheel (the outer wheel).
+ It's 0 at rest, and ranges from -7 at the counter-clockwise
+ extreme to +7 at the clockwise extreme.
+
+.TP
+(float out) \fI(prefix).spring-wheel-f\fR
+
+ The current deflection of the spring-wheel (the outer wheel).
+ It's 0.0 at rest, -1.0 at the counter-clockwise extreme, and +1.0 at
+ the clockwise extreme. (The Shuttle devices report the spring-wheel
+ position as an integer from -7 to +7, so this pin reports only 15
+ discrete values in its range.)
+
diff --git a/docs/man/es/man1/sim_pin.1 b/docs/man/es/man1/sim_pin.1
new file mode 100644
index 0000000000..4a85e4535c
--- /dev/null
+++ b/docs/man/es/man1/sim_pin.1
@@ -0,0 +1,96 @@
+.\" Copyright (c) 2014 Dewey Garrett
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\"
+.\"
+.TH sim_pin "1" "2014-12-18" "Documentación LinuxCNC" "LinuxCNC"
+.SH NOMBRE
+\fBsim_pin\fR \- GUI para mostrar y configurar una o más entradas Hal
+
+.SH SINOPSIS
+.B \fBsim_pin\fR \fI[Options]\fR \fIname1\fR [\fIname2\fR [\fIname3\fR ...]]
+
+\fIOptions\fR:
+ \fB\-\- help\fR (muestra el texto de ayuda)
+ \fB\-\- title title_string\fR
+
+Para elementos de bit, el nombre puede incluir un especificador /mode= :
+ \fInamei\fR\fB/mode=\fR[\fBpulse\fR | \fBtoggle\fR | \fBhold\fR]
+ (el valor predeterminado es alternar)
+.P
+
+.SH DESCRIPCIÓN
+Se admiten elementos Hal booleanos (bit) y elementos numéricos (u32, s32, float).
+
+Si la entrada con nombre es de tipo numérico, la interfaz gráfica de usuario muestra:
+.P
+ \fBEntry\fR Widget de entrada para valor o una expresión Tcl válida.
+.br
+ \fBSet\fR Pulsador para establecer un nuevo valor desde Entry (o usar )
+.br
+ \fBReset\fR Pulsador para restablecer el valor presente al inicio
+
+Si la entrada es de tipo \fBbit\fR , la interfaz gráfica de usuario muestra un solo botón
+que está controlado por selectores de botones radio:
+.P
+ mode = \fBpulse\fR Entrada de pulso 1 por cada pulsación de botón
+.br
+ mode = \fBtoggle\fR Alternar entrada para cada pulsación de botón
+.br
+ mode = \fBhold\fR Establece la entrada en 1 mientras se presiona el botón
+
+Si el modo de elemento de bit comienza con una letra mayúscula,
+los botones de radio para seleccionar otros modos no se muestran
+
+
+
+.SH NOTA
+LinuxCNC o una aplicación Hal independiente debe estar ejecutándose
+.P
+Un elemento con nombre puede especificar un \fBpin\fR , \fBparametro\fR o \fBseñal\fR .
+El elemento nombrado debe ser escribible:
+.P
+ \fBpin IN o I/O\fR (y no está conectado a una señal con un escritor)
+.br
+ \fBparam RW\fR
+.br
+ \fBsignal conectado a un pin escribible\fR
+
+.SH USO
+\fBsim_pin\fR se puede usar de forma interactiva desde una línea de comandos de shell o
+comenzar automáticamente desde un archivo ini de configuración.
+
+.SH EJEMPLO
+Ejemplo para el uso del archivo ini:
+
+ [APPLICATIONS]
+ DELAY = 5
+ APP = \fBsim_pin\fR \\\
+.br
+ halui.machine.off/mode=pulse \\
+.br
+ ini.traj_arc_blend_enable \\
+.br
+ motion\-command\-handler\-tmax
+
+
+
diff --git a/docs/man/es/man1/thermistor.1 b/docs/man/es/man1/thermistor.1
new file mode 100644
index 0000000000..eca52705b6
--- /dev/null
+++ b/docs/man/es/man1/thermistor.1
@@ -0,0 +1,64 @@
+.TH THERMISTOR "9" "2020-08-11" "LinuxCNC Documentation" "HAL Component"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+
+.SH NAME
+
+thermistor \- compute temperature indicated by a thermistor
+.SH SYNOPSIS
+.B thermistor
+.SH DESCRIPTION
+
+This component computes the temperature indicated by a
+thermistor in a voltage-divider ladder. It uses the Beta-parameter
+variant of the Steinhart-Hart equation, described here:
+
+ http://en.wikipedia.org/wiki/Thermistor
+.SH PINS
+.TP
+.B thermistor.\fIN\fB.t0-c\fR float in \fR
+Reference temperature of the thermistor, in degrees
+Celsius (typically 25 C). This must be set before the component can
+compute the thermistor temperature. The reference temperature information
+is supplied by the thermistor manufacturer.
+.TP
+.B thermistor.\fIN\fB.r0\fR float in \fR
+Resistance of the thermistor at the reference
+temperature. This must be set before the component can compute the
+thermistor temperature. The reference resistance information is supplied
+by the thermistor manufacturer.
+.TP
+.B thermistor.\fIN\fB.beta\fR float in \fR
+Beta parameter of the thermistor (sometimes
+just called B). This must be set before the component can compute the
+thermistor temperature. The Beta parameter is supplied by the thermistor
+manufacturer.
+.TP
+.B thermistor.\fIN\fB.r-other\fR float in \fR
+Resistance of the other resistor in the
+voltage-divider ladder. This must be set before the component can
+compute the thermistor temperature.
+.TP
+.B thermistor.\fIN\fB.v-total\fR float in \fR
+Supply voltage of the voltage-divider ladder.
+.TP
+.B thermistor.\fIN\fB.v-thermistor\fR float in \fR
+Voltage drop across the termistor.
+.TP
+.B thermistor.\fIN\fB.temperature-c\fR float out \fR
+Temperature sensed by the thermistor, in degrees Celsius.
+.TP
+.B thermistor.\fIN\fB.temperature-k\fR float out \fR
+Temperature sensed by the thermistor, in Kelvins.
+.TP
+.B thermistor.\fIN\fB.temperature-f\fR float out \fR
+Temperature sensed by the thermistor, in degrees Fahrenheit.
+.TP
+.B thermistor.\fIN\fB.resistance\fR float out \fR
+Computed resistance of the thermistor.
+.SH LICENSE
+
+GPL
diff --git a/docs/man/es/man1/vfdb_vfd.1 b/docs/man/es/man1/vfdb_vfd.1
new file mode 100644
index 0000000000..207dd905c3
--- /dev/null
+++ b/docs/man/es/man1/vfdb_vfd.1
@@ -0,0 +1,262 @@
+.\" Copyright (c) 2013 Sebastian Kuzminsky
+.\" derived from the vfs11_vfd manpage by Michael Haberler and John Thornton
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+.\" USA.
+.\"
+.\" $Id: vfdb_vfd.1,v 1.8 2009-09-19 13:49:34 mah Exp $
+.\"
+.TH vfdb_vfd "1" "September 19, 2009" "VFD-B VFD" "LinuxCNC Documentation"
+
+.SH NAME
+\fBvfdb_vfd\fR - HAL userspace component for Delta VFD-B Variable Frequency Drives
+
+.SH SYNOPSIS
+.B vfdb_vfd
+.RI [OPTIONS]
+.br
+
+.SH DESCRIPTION
+This manual page explains the
+.B vfdb_vfd
+component. This component reads and writes to the VFD-B device via a
+Modbus connection.
+.PP
+\fBvfdb_vfd\fP is for use with LinuxCNC.
+
+.SH QUICK START
+The VFD-B ships in a configuration that can not talk to this driver.
+The VFD-B must be reconfigured via the face plate by the integrator
+before it will work. This section gives a brief description of what
+changes need to be made, consult your Delta VFD-B manual for more details.
+.RS
+.TP
+Switch the VFD-B to Modbus RTU frame format:
+Switch parameter 09-04 from the factory default of 0 (Ascii framing)
+to 3, 4, or 5 (RTU framing). The setting you choose will determine
+several serial parameters in addition to the Modbus framing protocol.
+.TP
+Set the frequency control source to be Modbus, not the keypad:
+Switch parameter 02-00 from factory default of 00 (keypad control) to 5
+(control from RS-485).
+.TP
+Set the run/stop control source to be Modbus, not the keypad:
+Switch parameter 02-01 from the factory default of 0 (control from keypad)
+to 3 (control from Modbus, with Stop enabled on the keypad).
+.RE
+
+.SH OPTIONS
+.B
+.IP \-n\ \-\-name\
+set the HAL component name
+.B
+.IP \-d\ \-\-debug
+Turn on debugging messages. Also toggled by sending a USR1 signal to the
+vfdb_vfd process.
+.B
+.IP \-m\ \-\-modbus\-debug
+Turn on Modbus debugging messages. This will cause all Modbus messages to
+be printed in hex on the terminal. Also toggled by sending a USR2 signal
+to the vfdb_vfd process.
+.B
+.IP \-I\ \-\-ini\
+take configuration from this ini
+file. Defaults to environment variable INI_FILE_NAME. Most vfdb_vfd
+configuration comes from the ini file, not from command-line arguments.
+.B
+.IP \-S\ \-\-section\
+take configuration from this
+section in the ini file. Defaults to 'VFD-B'.
+.B
+.IP \-r\ \-\-report\-device
+report device propertiers on console at startup
+
+.SH INI CONFIG VARIABLES
+.B
+.IP DEBUG
+Set to a non-zero value to enable general debug output from the VFD-B
+driver. Optional.
+.B
+.IP MODBUS_DEBUG
+Set to a non-zero value to enable modbus debug output from the VFD-B
+driver. Optional.
+.B
+.IP DEVICE
+Serial port device file to use for Modbus communication with the VFD-B.
+Defaults to '/dev/ttyS0'.
+.B
+.IP BAUD
+Modbus baud rate. Defaults to 19200.
+.B
+.IP BITS
+Modbus data bits. Defaults to 8.
+.B
+.IP PARITY
+Modbus parity. Defaults to Even. Accepts 'Even', 'Odd', or 'None'.
+.B
+.IP STOPBITS
+Modbus stop bits. Defaults to 1.
+.B
+.IP TARGET
+Modbus target number of the VFD-B to speak to. Defaults to 1.
+.B
+.IP POLLCYCLES
+Only read the less important variables from the VFD-B once in this many
+poll cycles. Defaults to 10.
+.B
+.IP RECONNECT_DELAY
+If the connection to the VFD-B is broken, wait this many seconds before
+reconnecting. Defaults to 1.
+.B
+.IP MOTOR_HZ,\ MOTOR_RPM
+The frequency of the motor (in Hz) and the corresponding speed of the
+motor (in RPM). This information is provided by the motor manufacturer,
+and is generally printed on the motor's name plate.
+
+.SH PINS
+.B
+.IP .at\-speed\ (bit,\ out)
+True when drive is at commanded speed (see
+.I
+speed\-tolerance
+below)
+.B
+.IP .enable\ (bit,\ in)
+Enable the VFD. If False, all operating parameters are still read but
+control is released and panel control is enabled (subject to VFD setup).
+.B
+.IP .frequency\-command\ (float,\ out)
+Current target frequency in HZ as set through speed\-command (which is in
+RPM), from the VFD.
+.B
+.IP .frequency\-out\ (float,\ out)
+Current output frequency of the VFD.
+.B
+.IP .inverter\-load\-percentage\ (float,\ out)
+Current load report from VFD.
+.B
+.IP .is\-e\-stopped\ (bit,\ out)
+The VFD is in emergency stop status (blinking "E" on panel).
+.B
+.IP .is\-stopped\ (bit,\ out)
+True when the VFD reports 0 Hz output.
+.B
+.IP .jog\-mode\ (bit,\ in)
+1 for ON and 0 for OFF, enables the VFD-B 'jog mode'. Speed control
+is disabled. This might be useful for spindle orientation.
+.B
+.IP .max\-rpm\ (float,\ out)
+Actual RPM limit based on maximum frequency the VFD may generate, and
+the motors nameplate values. For instance, if
+.I nameplate\-HZ
+is 50, and
+.I nameplate\-RPM
+is 1410, but the VFD may generate up to 80Hz, then
+.I max\-rpm
+would read as 2256 (80*1410/50). The frequency limit is read from the VFD
+at startup. To increase the upper frequency limit, the UL and FH
+parameters must be changed on the panel. See the VFD-B manual for
+instructions how to set the maximum frequency.
+.B
+.IP .modbus\-ok\ (bit,\ out)
+True when the Modbus session is successfully established and the last 10
+transactions returned without error.
+.B
+.IP .motor\-RPM\ (float,\ out)
+Estimated current RPM value, from the VFD.
+.B
+.IP .motor\-RPS\ (float,\ out)
+Estimated current RPS value, from the VFD.
+.B
+.IP .output\-voltage\ (float,\ out)
+From the VFD.
+.B
+.IP .output\-current\ (float,\ out)
+From the VFD.
+.B
+.IP .speed\-command\ (float,\ in)
+Speed sent to VFD in RPM. It is an error to send a speed faster than the
+Motor Max RPM as set in the VFD.
+.B
+.IP .spindle\-on\ (bit,\ in)
+1 for ON and 0 for OFF sent to VFD, only on when running.
+.B
+.IP .max\-speed\ (bit,\ in)
+Ignore the loop-time parameter and run Modbus at maximum
+speed, at the expense of higher CPU usage. Suggested use
+during spindle positioning.
+.B
+.IP .status\ (s32,\ out)
+Drive Status of the VFD (see the VFD manual). A bitmap.
+.B
+.IP .error\-count\ (s32,\ out)
+Total number of transactions returning a Modbus error.
+.B
+.IP .error\-code\ (s32,\ out)
+Most recent Error Code from VFD.
+.B
+.IP