diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/.gitignore b/linuxcnc/sim.gmoccapy.lathe_configs/.gitignore
new file mode 100755
index 0000000..b25c15b
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/LatheMacro.svg b/linuxcnc/sim.gmoccapy.lathe_configs/LatheMacro.svg
new file mode 100755
index 0000000..dc974c4
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/LatheMacro.svg
@@ -0,0 +1,3057 @@
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/README b/linuxcnc/sim.gmoccapy.lathe_configs/README
new file mode 100755
index 0000000..da5d6cf
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/README
@@ -0,0 +1,72 @@
+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.
+
+There are two load-time options to control the tab behaviour:
+1) norun will hide the action button, use this if you want to use only
+a physical button (connected to gladevcp.cycle-start) to start the macros
+(Strongly recommended, especially with Touchy)
+2) notouch will allow keyboard editing of the spinboxes. Otherwise the
+custom numeric keyboard will be shown.
+
+An example loadrt line, as used here in the Gmoccapy demo is:
+
+[DISPLAY]
+EMBED_TAB_COMMAND = halcmd loadusr -Wn gladevcp gladevcp -c gladevcp -U notouch=1 -U norun=0 -u lathehandler.py -x {XID} lathemacro.ui
+
+The window will resize slowly if you grab the corner and move the mouse
+inside the window. It's not as bad as it was, but still needs work.
+You may need to click the unmaximise button in the toolbar to get a
+window border to be able to use the resize handles.
+
+Notes on the keyboard:
+As well as the obvious functions and unit conversions, it can be used to
+enter fractions. For example if you type 1.1/2 it will automatically
+update to display 1.5000 and 16.17/64 will show 16.2656.
+This can be used in a limited way to halve the onscreen value eg for
+entering radius instead of diameter.
+However it only works for whole numbers: 100/2 will become 50 but
+3.14149/2 is interpreted as 3 and 14 thousand halves so won't work.
+
+Notes on adding your own cycles:
+Create a new G-code subroutine in the same format as the existing ones.
+In Glade add a new tab to the 'tabs1' notebook and give it a name matching
+the new cycle.
+Edit the action button (inside an eventbox) to call the new G-code sub.
+Rename the action button to match the tab name and append '.action' eg
+MyCycle.action
+
+Create new artwork. I used Fusion360, the models are here:
+https://a360.co/3uFPZNv
+and the drawings are here:
+https://a360.co/3uFPZNv
+Esport the drawing page as PDF and import into the lathemacro.svg file in
+Inkscape. You will need to resize. Add your own arrows and annotations.
+
+Save the new layer in a layer named "layerN" (lower case) where N is the
+tab number, starting at zero. You will need to invoke the XML editor for
+this (Shift-Cmd-X on Mac)
+
+The entry boxes are positioned relative to a 1500 x 1000 image; the
+original size of the SVG. So you can hover your mouse over the image in
+Inkscape to determine the coordinates.
+In the in the case of on-drawing controls the coordinates are entered as
+an XML comment in the Tooltip for the control in x,y format (The surface speed,
+tool and coolant do not need this, they are in a fixed table)
+
+An example:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/ethercat_end.hal b/linuxcnc/sim.gmoccapy.lathe_configs/ethercat_end.hal
new file mode 100755
index 0000000..b61ece0
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/ethercat_end.hal
@@ -0,0 +1 @@
+addf lcec.write-all servo-thread
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/facing.ngc b/linuxcnc/sim.gmoccapy.lathe_configs/facing.ngc
new file mode 100755
index 0000000..341bc61
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/facing.ngc
@@ -0,0 +1,45 @@
+;Facing
+O sub
+
+G7 ; Lathe Diameter Mode
+G18 ; XZ Plane
+G21 ; Metric Units
+G90 ; Absolute Distance
+
+M6 T#7 G43
+
+O90 IF [#8 GT 0.5]
+ M8
+O90 ENDIF
+
+O10 IF [#6 NE 0]
+ (MSG, Angled facing isn't supported yet)
+O10 ENDIF
+
+#14 = [#<_x> * 2] (starting X)
+#13 = #<_z> (starting Z)
+
+G96 D2500 S#2 ; Constant Surface Speed Mode
+M3
+g95 F#4 ; Feed-Per-Rev Mode
+
+g4p1 ; Wait to reach speed
+
+ O200 WHILE [#13 GT #5 + #3]
+
+ #13=[#13-#3]
+ G1 Z#13
+ G1 X#1
+ G0 Z[#13+#3]
+ G0 X#14
+ G0 Z#13
+ O200 ENDWHILE
+
+ G1 Z#5
+ G1 X#1
+ G0 Z[#13+#3]
+ G0 X[#14+#3]
+ G0 Z#5 ; For touch-off
+ M5 M9
+O endsub
+M2
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe.pref b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe.pref
new file mode 100755
index 0000000..9b9f354
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe.pref
@@ -0,0 +1,81 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+view = y
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 140.4
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+grid_size = 1.0
+mouse_btn_mode = 4
+hide_cursor = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rot
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+jump_to_dir = /home/emcmesa
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = False
+show_keyboard_on_mdi = False
+show_keyboard_on_file_selection = False
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+reload_tool = True
+blockdel = False
+opstop = False
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+run_from_line = no_run
+unlock_way = no
+show_preview_on_offset = False
+use_keyboard_shortcuts = True
+dro_digits = 3
+toggle_readout = True
+tool_in_spindle = 3
+diameter offset_axis_x = 0
+offset_axis_x = 0.0
+offset_axis_z = 0.0
+offset_axis_r = 50.0
+radius offset_axis_x = 0
+use_toolmeasurement = False
+kbd_height = 250
+icon_theme = None
+hide_tooltips = False
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe_c.pref b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe_c.pref
new file mode 100755
index 0000000..483f557
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_lathe_c.pref
@@ -0,0 +1,72 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+view = y
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 140.4
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+grid_size = 1.0
+mouse_btn_mode = 4
+hide_cursor = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rot
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+jump_to_dir = /home/emcmesa
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = True
+show_keyboard_on_mdi = True
+show_keyboard_on_file_selection = False
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+reload_tool = True
+blockdel = False
+opstop = False
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+run_from_line = no_run
+unlock_way = use
+show_preview_on_offset = False
+use_keyboard_shortcuts = False
+dro_digits = 3
+toggle_readout = True
+tool_in_spindle = 0
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_postgui.hal b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_postgui.hal
new file mode 100755
index 0000000..aa8a9d7
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/gmoccapy_postgui.hal
@@ -0,0 +1,23 @@
+###################################################################
+# moccapy_postgui.hal file from Norbert Schechner #
+###################################################################
+
+loadrt abs names=abs_spindle_feedback
+addf abs_spindle_feedback servo-thread
+
+net spindle-speed-limited => abs_spindle_feedback.in
+net spindle-abs abs_spindle_feedback.out => gmoccapy.spindle_feedback_bar
+net spindle-at-speed gmoccapy.spindle_at_speed_led
+
+# the unlink pin commands are only used, because they are connected
+# in core_sim.hal and we use this file to simulate
+unlinkp iocontrol.0.tool-change
+unlinkp iocontrol.0.tool-changed
+unlinkp iocontrol.0.tool-prep-number
+
+net tool-change gmoccapy.toolchange-change <= iocontrol.0.tool-change
+net tool-changed gmoccapy.toolchange-changed <= iocontrol.0.tool-changed
+net tool-prep-number gmoccapy.toolchange-number <= iocontrol.0.tool-prep-number
+
+net tooloffset-x gmoccapy.tooloffset-x <= motion.tooloffset.x
+net tooloffset-z gmoccapy.tooloffset-z <= motion.tooloffset.z
\ No newline at end of file
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/grooving.ngc b/linuxcnc/sim.gmoccapy.lathe_configs/grooving.ngc
new file mode 100755
index 0000000..475da84
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/grooving.ngc
@@ -0,0 +1,32 @@
+;grooving
+
+O sub
+
+G8 ; Radius mode (easier maths)
+G18 ; XZ Plane
+G21 ; Metric Units
+G90 ; Absolute Distance
+G91.1 ; but not for arcs
+
+M6 T#4 G43
+
+#1 = [#1 / 2] ; because of radius mode
+
+#14 = [#<_x>] (starting X)
+
+G96 D1500 S#2 ; Constant Surface Speed Mode
+m3 ;Start Spindle
+g95 F#3 ; Feed-Per-Rev Mode
+
+O90 IF [#5 GT 0.5]
+ M8
+O90 ENDIF
+
+g4p1 ; Wait to reach speed
+G1 F#3 X#1
+G0 X#14
+M5 M9
+G7
+O endsub
+
+M2
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/README b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/README
new file mode 100755
index 0000000..596828d
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/README
@@ -0,0 +1,70 @@
+This directory contains halfiles (*.hal and *.tcl) that are available
+using the LinuxCNC halfile search path or by an explicit directive.
+
+The HALLIB_PATH is '.:HALLIB_DIR'
+ The '.' specifies the directory containing the INI file.
+ HALIB_DIR specifies this directory.
+
+The explicit directive uses a prefix (LIB:) to identify halfiles:
+ [HAL]
+ HALFILE = LIB:filename.[hal|tcl]
+
+The LinuxCNC startup script (linuxcnc) finds each halfile using the
+HALLIB_PATH unless the explicit directive is used.
+
+Also included in this directory are files associated with included
+system halfiles. For example, the button layout files
+(xhc-hb04-layout*.cfg) that are used with the halfile xhc-hb04.tcl.
+------------------------------------------------------------------------
+
+
+Hal files (*.hal) Notes
+----------------------- ---------------------------------------------
+axis_manualtoolchange.hal setup for using hal_manualtoolchange
+ (for axis or other guis)
+core_sim.hal xyz simulator config
+core_servo.hal xyz servo (pid) config
+core_sim9.hal 9 axis (xyzabcuvw) simulation config
+core_stepper.hal xyz stepper config
+gantrysim.hal gantrykins config, 4 joints: X Y Y Z
+lathe.hal simulate spindle with encoder,sim_encoder
+locking_indexer.hal simulate locking rotary using timedelay comp
+wheeljogpins.tcl enable wheel jog pins for joints & axes
+moveoff_external.hal Simulate external control connections for
+ a moveoff component
+servo_sim.hal simulate servo (pid) xyz using lowpass comp
+sim_spindle_encoder.hal simulate spindle with lowpass filter
+simulated-gantry-home.hal simulate gantry home switches (4 joints)
+simulated_home.hal simulate xyz home switches
+simulated_limits.hal simulate xyz limit switches
+tripodsim.hal simulated tripodkins system
+
+Haltcl Files (*.tcl) Notes
+----------------------- ---------------------------------------------
+basic_sim.tcl set up a sim config (arbitrary no. of axes)
+var_show.tcl show INI variables and context
+hookup_moveoff.tcl make connections for a moveoff component
+plasmac.tcl common connections for the plasmac component
+
+xhc-hb04.tcl Configuration builder for xhc-hb04 pendant
+xhc-hb04-layout1.cfg button layout 1 for xhc-hb04.tcl
+xhc-hb04-layout2.cfg button layout 2 for xhc-hb04.tcl
+
+halcheck.tcl Report: 1) functions without addf
+ 2) signals with no inputs
+ 3) signals with no output
+
+Haltcl libs (*_lib.tcl) Notes
+----------------------- ---------------------------------------------
+sim_lib.tcl simulator config procedures
+ procs:
+ core_sim (arbitrary axes)
+ make-ddts (arbitrary axes)
+ simulated_home (arbitrary axes)
+ use_hal_manualtoolchange
+ sim_spindle
+util_lib.tcl utility procedures
+ procs:
+ show_context (calling parms)
+ show_ini (INI file settings)
+ show_env (environmental vars)
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/axis_manualtoolchange.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/axis_manualtoolchange.hal
new file mode 100755
index 0000000..45dbe63
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/axis_manualtoolchange.hal
@@ -0,0 +1,10 @@
+loadusr -W hal_manualtoolchange
+
+# in case they were linked already
+unlinkp iocontrol.0.tool-change
+unlinkp iocontrol.0.tool-changed
+
+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/linuxcnc/sim.gmoccapy.lathe_configs/hallib/basic_sim.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/basic_sim.tcl
new file mode 100755
index 0000000..22bcebb
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/basic_sim.tcl
@@ -0,0 +1,71 @@
+# basic_sim.tcl
+#
+# Provide common hal components and connections for a simulated machine.
+# By default, the script makes and connects ddts, simulated_home,
+# spindle, and hal_manualtoolchange components.
+#
+# Options are available to
+# a) disable specific hal components and connections
+# b) save a halfile equivalent to the hal commands executed by
+# this script (and any prior executed hal commands)
+#
+# Coordinate letters and number_of_joints are determined from the usual
+# INI file settings.
+#
+# INI file usage:
+# [HAL]HALFILE = basic_sim.tcl [Options]
+# Options:
+# -no_make_ddts
+# -no_simulated_home
+# -no_use_hal_manualtoolchange
+# -no_sim_spindle
+
+#----------------------------------------------------------------------
+# Notes:
+# 1) ::env() is a global associative array of environmental variables
+# as exported by the main LinuxCNC script (linuxcnc)
+# 2) Settings from the INI file are available as global associative
+# arrays named: ::SECTION(varname)
+# example: ::EMCMOT(SERVO_PERIOD)
+# 3) procs are from sim_lib.tcl
+
+#begin-----------------------------------------------------------------
+source [file join $::env(HALLIB_DIR) sim_lib.tcl]
+set save_options {}
+
+if [catch {check_ini_items} msg] {
+ puts "\nbasic_sim.tcl ERROR: $msg\n"
+ exit 1
+}
+set axes [get_traj_coordinates]
+set number_of_joints $::KINS(JOINTS)
+
+set base_period 0 ;# 0 means no thread
+if [info exists ::EMCMOT(BASE_PERIOD)] {
+ set base_period $::EMCMOT(BASE_PERIOD)
+}
+
+core_sim $axes \
+ $number_of_joints \
+ $::EMCMOT(SERVO_PERIOD) \
+ $base_period \
+ $::EMCMOT(EMCMOT)
+
+if {[lsearch -nocase $::argv -no_make_ddts] < 0} {
+ make_ddts $number_of_joints
+}
+if {[lsearch -nocase $::argv -no_simulated_home] < 0} {
+ simulated_home $number_of_joints
+}
+if {[lsearch -nocase $::argv -no_use_hal_manualtoolchange] < 0} {
+ use_hal_manualtoolchange
+ lappend save_options use_hal_manualtoolchange
+}
+if {[lsearch -nocase $::argv -no_sim_spindle] < 0} {
+ sim_spindle
+}
+
+# make a halfile (inifilename_cmds.hal) with equivalent hal commands
+set savefilename \
+ ./[file rootname [file tail $::env(INI_FILE_NAME)]]_cmds.hal
+save_hal_cmds $savefilename $save_options
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_config.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_config.tcl
new file mode 100755
index 0000000..d18b833
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_config.tcl
@@ -0,0 +1,240 @@
+# check_config.tcl
+# Usage: tclsh path_to_this_file inifilename
+# if a check fails, print message and exit 1
+#
+# checks:
+# 1) mandatory items per ::mandatory_items list
+# 2) if trivkins, check consistency of [JOINT_] and [AXIS_]
+# MIN_LIMIT and MAX_LIMIT
+#----------------------------------------------------------------------
+set ::mandatory_items {KINS KINEMATICS
+ KINS JOINTS
+ }
+# Ref: src/emc/nml_intf/emccfg.h,src/emc/ini/inijoint.cc,src/emc/iniaxis.cc:
+set ::DEFAULT_AXIS_MAX_VELOCITY 1.0
+set ::DEFAULT_AXIS_MAX_ACCELERATION 1.0
+set ::DEFAULT_JOINT_MAX_VELOCITY 1.0
+set ::DEFAULT_JOINT_MAX_ACCELERATION 1.0
+
+# Ref: src/emc/ini/iniaxis.cc:
+set ::DEFAULT_AXIS_MIN_LIMIT -1e99
+set ::DEFAULT_AXIS_MAX_LIMIT +1e99
+#----------------------------------------------------------------------
+proc warnings msg {
+ puts -nonewline "\n$::progname:\n"
+ catch {puts ($::kins(module) kinematics) WARNING:"}
+ foreach m $msg {puts " $m"}
+ puts ""
+} ;# warnings
+
+proc err_exit msg {
+ puts -nonewline "\n$::progname:\n"
+ catch {puts ($::kins(module) kinematics) ERROR:"}
+ foreach m $msg {puts " $m"}
+ puts ""
+ exit 1
+} ;# err_exit
+
+proc check_mandatory_items {} {
+ foreach {section item} $::mandatory_items {
+ if  ] {
+ set section [string trim $section :]
+ lappend emsg "Missing \[$section\]$item="
+ }
+ }
+ if [info exists emsg] {
+ err_exit $emsg
+ }
+} ;# check_mandatory_items
+
+proc uniq {list_name} { ;# make list unique
+ foreach item $list_name { set tmp($item) "" }
+ return [array names tmp]
+} ;# uniq
+
+proc joints_for_trivkins {coords} {
+ # ref: src/emc/kinematics/trivkins.c
+ # order of coord letters determines assigned joint number
+ if {"$coords" == ""} {set coords {X Y Z A B C U V W}}
+ set i 0
+ foreach a [string toupper $coords] {
+ # assign to consecutive joints:
+ lappend ::kins(jointidx,$a) $i
+ incr i
+ }
+} ;# joints_for_trivkins
+
+proc consistent_coords_for_trivkins {trivcoords} {
+ set m {" " "" "\t" ""} ;# mapping to remove whitespace
+ set trivcoords [string map $m $trivcoords]
+ if {"$trivcoords" == "XYZABCUVW"} {
+ return ;# unspecified trivkins coordinates
+ # allows use of any coordinates
+ }
+ set trajcoords ""
+ if [info exists ::TRAJ(COORDINATES)] {
+ set trajcoords [string map $m [lindex $::TRAJ(COORDINATES) 0]]
+ }
+ if {[string toupper "$trivcoords"] != [string toupper "$trajcoords"]} {
+ lappend ::wmsg "INCONSISTENT coordinates specifications:
+ trivkins coordinates=$trivcoords
+ \[TRAJ\]COORDINATES=$trajcoords"
+ }
+} ;# consistent_coords_for_trivkins
+
+proc validate_identity_kins_limits {} {
+ set emsg ""
+ for {set j 0} {$j < $::KINS(JOINTS)} {incr j} {
+ if {] } {
+ lappend ::wmsg "Unspecified \[JOINT_$j\]MAX_VELOCITY, default used: $::DEFAULT_JOINT_MAX_VELOCITY"
+ }
+ if {] } {
+ lappend ::wmsg "Unspecified \[JOINT_$j\]MAX_ACCELERATION, default used: $::DEFAULT_JOINT_MAX_ACCELERATION"
+ }
+ }
+ foreach c [uniq $::kins(coordinates)] {
+ # array test avoids superfluous messages when coordinates= not specified
+ if [array exists ::AXIS_[set c]] {
+ if {] } {
+ lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_VELOCITY, default used: $::DEFAULT_AXIS_MAX_VELOCITY"
+ }
+ if {] } {
+ lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_ACCELERATION, default used: $::DEFAULT_AXIS_MAX_ACCELERATION"
+ }
+ }
+
+ set missing_axis_min_limit 0
+ set missing_axis_max_limit 0
+ if ] {
+ set ::AXIS_[set c](MIN_LIMIT) $::DEFAULT_AXIS_MIN_LIMIT
+ set missing_axis_min_limit 1
+ }
+ if ] {
+ set ::AXIS_[set c](MAX_LIMIT) $::DEFAULT_AXIS_MAX_LIMIT
+ set missing_axis_max_limit 1
+ }
+ foreach j $::kins(jointidx,$c) {
+ if [info exists ::JOINT_[set j](MIN_LIMIT)] {
+ set jlim [set ::JOINT_[set j](MIN_LIMIT)]
+ set clim [set ::AXIS_[set c](MIN_LIMIT)]
+ if {$jlim > $clim} {
+ if $missing_axis_min_limit {
+ lappend ::wmsg "Unspecified \[AXIS_$c\]MIN_LIMIT, default used: $::DEFAULT_AXIS_MIN_LIMIT"
+ }
+ lappend emsg "\[JOINT_$j\]MIN_LIMIT > \[AXIS_$c\]MIN_LIMIT ($jlim > $clim)"
+ }
+ }
+ if [info exists ::JOINT_[set j](MAX_LIMIT)] {
+ set jlim [set ::JOINT_[set j](MAX_LIMIT)]
+ set clim [set ::AXIS_[set c](MAX_LIMIT)]
+ if {$jlim < $clim} {
+ if $missing_axis_max_limit {
+ lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_LIMIT, default used: $::DEFAULT_AXIS_MAX_LIMIT"
+ }
+ lappend emsg "\[JOINT_$j\]MAX_LIMIT < \[AXIS_$c\]MAX_LIMIT ($jlim < $clim)"
+ }
+ }
+ }
+ }
+ return $emsg
+} ;# validate_identity_kins_limits
+
+proc check_extrajoints {} {
+ if ![info exists ::EMCMOT(EMCMOT)] return
+ if {[string first motmod $::EMCMOT(EMCMOT)] <= 0} return
+ set mot [split [lindex $::EMCMOT(EMCMOT) 0]]
+ foreach item $mot {
+ set pair [split $item =]
+ set parm [lindex $pair 0]
+ set val [lindex $pair 1]
+ if {"$parm" == "num_extrajoints"} {
+ set ::num_extrajoints $val
+ }
+ }
+ if [info exists ::num_extrajoints] {
+ lappend ::wmsg [format "Extra joints specified=%d\n \
+\[KINS\]JOINTS=%d must accommodate kinematic joints *plus* extra joints " \
+ $::num_extrajoints $::KINS(JOINTS)]
+ }
+} ;#check_extrajoints
+
+proc warn_for_multiple_ini_values {} {
+ set sections [info globals]
+ set sections_to_check {JOINT_ AXIS_}
+
+ foreach section $sections {
+ set enforce 0
+ foreach csection $sections_to_check {
+ if {[string first $csection $section"] >= 0} {
+ set enforce 1
+ break
+ }
+ }
+ if !$enforce continue
+ foreach name [array names ::$section] {
+ set gsection ::$section
+ set val [set [set gsection]($name)]
+ set len [llength $val]
+ if {$len > 1} {
+ lappend ::wmsg "Unexpected multiple values \[$section\]$name: $val"
+ }
+ }
+ }
+} ;# warn_for_multiple_ini_values
+
+#----------------------------------------------------------------------
+# begin
+package require Linuxcnc ;# parse_ini
+
+set ::progname [file rootname [file tail [info script]]]
+set inifile [lindex $::argv 0]
+if ![file exists $inifile] {
+ err_exit [list "No such file <$inifile>"]
+}
+if ![file readable $inifile] {
+ err_exit [list "File not readable <$inifile>"]
+}
+parse_ini $inifile
+
+check_mandatory_items
+
+set kins_kinematics [lindex $::KINS(KINEMATICS) end]
+set ::kins(module) [lindex $kins_kinematics 0]
+
+# parameters specified as parm=value --> ::kins(parm)=value
+foreach item $kins_kinematics {
+ if {[string first = $item] >= 0} {
+ set l [split $item =]
+ set ::kins([lindex $l 0]) [lindex $l 1]
+ } else {
+ if {"$item" != $::kins(module)} {
+ puts "Unknown \[KINS\]KINEMATICS item: <$item>"
+ }
+ }
+}
+# coordinates --> ::kins(coordinates) (all if not specified)
+if [info exists ::kins(coordinates)] {
+ set ::kins(coordinates) [split $::kins(coordinates) ""]
+ set ::kins(coordinates) [string toupper $::kins(coordinates)]
+} else {
+ set ::kins(coordinates) {X Y Z A B C U V W}
+}
+
+# list of joints for each coord --> ::kins(jointidx,coordinateletter)
+switch $::kins(module) {
+ trivkins {joints_for_trivkins $::kins(coordinates)}
+ default {
+ puts "$::progname: Unchecked: \[KINS\]KINEMATICS=$::KINS(KINEMATICS)"
+ exit 0
+ }
+}
+check_extrajoints
+
+warn_for_multiple_ini_values
+#parray ::kins
+set emsg [validate_identity_kins_limits]
+consistent_coords_for_trivkins $::kins(coordinates)
+if [info exists ::wmsg] {warnings $::wmsg}
+
+if {"$emsg" == ""} {exit 0}
+err_exit $emsg
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_xyz_constraints.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_xyz_constraints.hal
new file mode 100755
index 0000000..c2a4320
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/check_xyz_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/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_servo.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_servo.hal
new file mode 100755
index 0000000..166a46b
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_servo.hal
@@ -0,0 +1,74 @@
+# core HAL config file for servos
+
+# first load the core RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+# PID module, for three PID loops
+loadrt pid num_chan=3
+
+# hook functions to realtime thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+addf pid.0.do-pid-calcs servo-thread
+addf pid.1.do-pid-calcs servo-thread
+addf pid.2.do-pid-calcs servo-thread
+
+# connect position feedback
+net Xpos-fb joint.0.motor-pos-fb => pid.0.feedback
+net Ypos-fb joint.1.motor-pos-fb => pid.1.feedback
+net Zpos-fb joint.2.motor-pos-fb => pid.2.feedback
+
+# create PID to DAC output signals
+net Xoutput <= pid.0.output
+net Youtput <= pid.1.output
+net Zoutput <= pid.2.output
+
+# set PID loop output limits to +/-1.00
+setp pid.0.maxoutput [JOINT_0]MAX_VELOCITY
+setp pid.1.maxoutput [JOINT_1]MAX_VELOCITY
+setp pid.2.maxoutput [JOINT_2]MAX_VELOCITY
+
+# set PID loop gains from INI file
+
+# the values below come from the INI
+setp pid.0.Pgain [JOINT_0]P
+setp pid.0.Igain [JOINT_0]I
+setp pid.0.Dgain [JOINT_0]D
+setp pid.0.bias [JOINT_0]BIAS
+setp pid.0.FF0 [JOINT_0]FF0
+setp pid.0.FF1 [JOINT_0]FF1
+setp pid.0.FF2 [JOINT_0]FF2
+# deadband should be just over 1 count
+setp pid.0.deadband [JOINT_0]DEADBAND
+
+setp pid.1.Pgain [JOINT_1]P
+setp pid.1.Igain [JOINT_1]I
+setp pid.1.Dgain [JOINT_1]D
+setp pid.1.bias [JOINT_1]BIAS
+setp pid.1.FF0 [JOINT_1]FF0
+setp pid.1.FF1 [JOINT_1]FF1
+setp pid.1.FF2 [JOINT_1]FF2
+# deadband should be just over 1 count
+setp pid.1.deadband [JOINT_1]DEADBAND
+
+setp pid.2.Pgain [JOINT_2]P
+setp pid.2.Igain [JOINT_2]I
+setp pid.2.Dgain [JOINT_2]D
+setp pid.2.bias [JOINT_2]BIAS
+setp pid.2.FF0 [JOINT_2]FF0
+setp pid.2.FF1 [JOINT_2]FF1
+setp pid.2.FF2 [JOINT_2]FF2
+# deadband should be just over 1 count
+setp pid.2.deadband [JOINT_2]DEADBAND
+
+# position command signals
+net Xpos-cmd joint.0.motor-pos-cmd => pid.0.command
+net Ypos-cmd joint.1.motor-pos-cmd => pid.1.command
+net Zpos-cmd joint.2.motor-pos-cmd => pid.2.command
+
+# joint enable signals
+net Xenable joint.0.amp-enable-out => pid.0.enable
+net Yenable joint.1.amp-enable-out => pid.1.enable
+net Zenable joint.2.amp-enable-out => pid.2.enable
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim.hal
new file mode 100755
index 0000000..4bdf936
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim.hal
@@ -0,0 +1,51 @@
+# core HAL config file for simulation
+
+# first load all the RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+# load 6 differentiators (for velocity and accel signals
+loadrt ddt names=ddt_x,ddt_xv,ddt_y,ddt_yv,ddt_z,ddt_zv
+# load additional blocks
+loadrt hypot names=vel_xy,vel_xyz
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+# link the differentiator functions into the code
+addf ddt_x servo-thread
+addf ddt_xv servo-thread
+addf ddt_y servo-thread
+addf ddt_yv servo-thread
+addf ddt_z servo-thread
+addf ddt_zv servo-thread
+addf vel_xy servo-thread
+addf vel_xyz servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net Xpos joint.0.motor-pos-cmd => joint.0.motor-pos-fb ddt_x.in
+net Ypos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt_y.in
+net Zpos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt_z.in
+
+# send the position commands thru differentiators to
+# generate velocity and accel signals
+net Xvel ddt_x.out => ddt_xv.in vel_xy.in0
+net Xacc <= ddt_xv.out
+net Yvel ddt_y.out => ddt_yv.in vel_xy.in1
+net Yacc <= ddt_yv.out
+net Zvel ddt_z.out => ddt_zv.in vel_xyz.in0
+net Zacc <= ddt_zv.out
+
+# Cartesian 2- and 3-axis velocities
+net XYvel vel_xy.out => vel_xyz.in1
+net XYZvel <= vel_xyz.out
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim9.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim9.hal
new file mode 100755
index 0000000..3146afc
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_sim9.hal
@@ -0,0 +1,67 @@
+#!!! DECLINING USAGE use: HALFILE=LIB:basic_sim.tcl to automatically
+#!!! make the components and connections required for sim configs
+
+# core HAL config file for simulation
+
+# first load all the RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+# load 6 differentiators (for velocity and accel signals
+loadrt ddt names=ddt_x,ddt_xv,ddt_y,ddt_yv,ddt_z,ddt_zv
+# load additional blocks
+loadrt hypot names=vel_xy,vel_xyz
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+# link the differentiator functions into the code
+addf ddt_x servo-thread
+addf ddt_xv servo-thread
+addf ddt_y servo-thread
+addf ddt_yv servo-thread
+addf ddt_z servo-thread
+addf ddt_zv servo-thread
+addf vel_xy servo-thread
+addf vel_xyz servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net Xpos joint.0.motor-pos-cmd => joint.0.motor-pos-fb ddt_x.in
+net Ypos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt_y.in
+net Zpos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt_z.in
+net Apos joint.3.motor-pos-cmd => joint.3.motor-pos-fb
+net Bpos joint.4.motor-pos-cmd => joint.4.motor-pos-fb
+net Cpos joint.5.motor-pos-cmd => joint.5.motor-pos-fb
+net Upos joint.6.motor-pos-cmd => joint.6.motor-pos-fb
+net Vpos joint.7.motor-pos-cmd => joint.7.motor-pos-fb
+net Wpos joint.8.motor-pos-cmd => joint.8.motor-pos-fb
+
+# send the position commands thru differentiators to
+# generate velocity and accel signals
+net Xvel ddt_x.out => ddt_xv.in vel_xy.in0
+net Xacc <= ddt_xv.out
+net Yvel ddt_y.out => ddt_yv.in vel_xy.in1
+net Yacc <= ddt_yv.out
+net Zvel ddt_z.out => ddt_zv.in vel_xyz.in0
+net Zacc <= ddt_zv.out
+
+# Cartesian 2- and 3-axis velocities
+net XYvel vel_xy.out => vel_xyz.in1
+net XYZvel <= vel_xyz.out
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
+
+net spindle-fwd spindle.0.forward
+net spindle-rev spindle.0.reverse
+#net spindle-speed spindle.0.speed-out
+
+net lube iocontrol.0.lube
+net flood iocontrol.0.coolant-flood
+net mist iocontrol.0.coolant-mist
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_stepper.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_stepper.hal
new file mode 100755
index 0000000..b911393
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/core_stepper.hal
@@ -0,0 +1,53 @@
+# core HAL config file for steppers
+
+# first load the core RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+# stepper module, three step generators, all three using step/dir
+loadrt stepgen step_type=0,0,0
+
+# hook functions to base thread (high speed thread for step generation)
+addf stepgen.make-pulses base-thread
+
+# hook functions to servo thread
+addf stepgen.capture-position servo-thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+addf stepgen.update-freq servo-thread
+
+# connect position commands from motion module to step generator
+net Xpos-cmd joint.0.motor-pos-cmd => stepgen.0.position-cmd
+net Ypos-cmd joint.1.motor-pos-cmd => stepgen.1.position-cmd
+net Zpos-cmd joint.2.motor-pos-cmd => stepgen.2.position-cmd
+
+# connect position feedback from step generators
+# to motion module
+net Xpos-fb stepgen.0.position-fb => joint.0.motor-pos-fb
+net Ypos-fb stepgen.1.position-fb => joint.1.motor-pos-fb
+net Zpos-fb stepgen.2.position-fb => joint.2.motor-pos-fb
+
+# connect enable signals for step generators
+net Xen joint.0.amp-enable-out => stepgen.0.enable
+net Yen joint.1.amp-enable-out => stepgen.1.enable
+net Zen joint.2.amp-enable-out => stepgen.2.enable
+
+# connect signals to step pulse generator outputs
+net Xstep <= stepgen.0.step
+net Xdir <= stepgen.0.dir
+net Ystep <= stepgen.1.step
+net Ydir <= stepgen.1.dir
+net Zstep <= stepgen.2.step
+net Zdir <= stepgen.2.dir
+
+# set stepgen module scaling - get values from INI file
+setp stepgen.0.position-scale [JOINT_0]SCALE
+setp stepgen.1.position-scale [JOINT_1]SCALE
+setp stepgen.2.position-scale [JOINT_2]SCALE
+
+# set stepgen module accel limits - get values from INI file
+setp stepgen.0.maxaccel [JOINT_0]STEPGEN_MAXACCEL
+setp stepgen.1.maxaccel [JOINT_1]STEPGEN_MAXACCEL
+setp stepgen.2.maxaccel [JOINT_2]STEPGEN_MAXACCEL
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/gantrysim.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/gantrysim.hal
new file mode 100755
index 0000000..77e9d55
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/gantrysim.hal
@@ -0,0 +1,35 @@
+loadrt [KINS]KINEMATICS
+show comp
+
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net J0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb
+net J1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb
+net J2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb
+net J3pos joint.3.motor-pos-cmd => joint.3.motor-pos-fb
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out => iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed
+
+# amp control - these nets are not used, but are placeholders for
+# converting this sample config to actual machines
+net J0ena <= joint.0.amp-enable-out
+net J1ena <= joint.1.amp-enable-out
+net J2ena <= joint.2.amp-enable-out
+net J3ena <= joint.3.amp-enable-out
+
+net J0flt => joint.0.amp-fault-in
+net J1flt => joint.1.amp-fault-in
+net J2flt => joint.2.amp-fault-in
+net J3flt => joint.3.amp-fault-in
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hal_procs_lib.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hal_procs_lib.tcl
new file mode 100755
index 0000000..6347d5d
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hal_procs_lib.tcl
@@ -0,0 +1,190 @@
+# hal_procs_lib.tcl
+package require Hal ;# provides hal commands
+
+proc pin_exists {name} {
+ # return 1 if pin exists
+ if { [lindex [hal list pin "$name"] 0] == "$name"} {return 1}
+ return 0
+} ;# pin_exists
+
+proc connection_info {result_name pinname } {
+ # return 0 if pinname not found, else 1
+ # result_name is associative array with details
+ # owner type direction value separator signame
+ upvar $result_name ay
+ set ans [hal show pin $pinname]
+ set lines [split $ans \n]
+ set sig ""
+ set sep ""
+ set ct [scan [lindex $lines 2] "%s %s %s %s %s %s %s" \
+ owner type dir val name sep sig]
+ if {$ct <0} {
+ return 0
+ }
+ set ay(owner) $owner
+ set ay(type) $type
+ set ay(direction) $dir
+ set ay(value) $val
+ set ay(separator) $sep
+ set ay(signame) $sig
+ return 1
+} ;# connection_info
+
+proc is_connected {pinname {signame {} } } {
+ # return is_input or is_output or is_io or not_connected
+ # set signame to signal name if connected
+ upvar $signame thesig
+ set ans [hal show pin $pinname]
+ set lines [split $ans \n]
+ set thesig ""
+ set sep ""
+ set ct [scan [lindex $lines 2] "%s %s %s %s %s %s %s" \
+ owner type dir val name sep thesig]
+ if {$ct <0} {return not_connected}
+ if {"$sep" == "<=="} {return is_input}
+ if {"$sep" == "==>"} {return is_output}
+ if {"$sep" == "<=>"} {return is_io}
+ return "not_connected"
+} ;# is_connected
+
+proc thread_info {ay_name} {
+ # return details about threads in associative array ay_name
+ # items for each $threadname:
+ # ($threadname,$componentname) $threadname index for $componentname
+ # ($threadname,fp) $threadname uses floatingpoint
+ # ($threadname,period) $threadname period
+ # ($threadname,index,last) $threadname last index used
+ #
+ # motion specific items:
+ # (motion-command-handler,threadname) threadname
+ # (motion-command-handler,index) index
+ # (motion-controller,threadname) threadname
+ # (motion-controller,index) index
+ # other:
+ # (threadnames) list of all threanames
+ #
+ # return string is $ay(motion-controller,threadname)
+
+ upvar $ay_name ay
+ set ans [hal show thread]
+ set lines [split $ans \n]
+ set header_len 2
+ set lines [lreplace $lines 0 [expr $header_len -1]]
+ set lines [lreplace $lines end end]
+ set remainder ""
+ set ct 0
+ foreach line $lines {
+ catch {unset f1 f2 f3 f4}
+ scan [lindex $lines $ct] \
+ "%s %s %s %s" \
+ f1 f2 f3 f4
+ if ![info exists f3] {
+ set index $f1; set compname $f2
+ set ay($threadname,$compname) $index
+ set ay($threadname,index,last) $index
+ if {"$compname" == "motion-command-handler"} {
+ set ay(motion-command-handler,threadname) $threadname
+ set ay(motion-command-handler,index) $index
+ }
+ if {"$compname" == "motion-controller"} {
+ set ay(motion-controller,threadname) $threadname
+ set ay(motion-controller,index) $index
+ }
+ } else {
+ set period $f1; set fp $f2; set threadname $f3
+ lappend ay(threadnames) $threadname
+ set ay($threadname,fp) $fp
+ set ay($threadname,period) $period
+ }
+ incr ct
+ }
+ if [info exists ay(motion-controller,threadname)] {
+ if [info exists ay(motion-command-handler,threadname)] {
+ if { "$ay(motion-controller,threadname)" \
+ != "$ay(motion-command-handler,threadname)" \
+ } {
+ return -code error "thread_info: mot funcs on separate threads"
+ if { $ay(motion-command-handler,index) \
+ > $ay(motion-controller,index) \
+ } {
+ return -code error "thread_info: mot funcs OUT-OF-SEQUENCE"
+ }
+ }
+ return $ay(motion-controller,threadname)
+ } else {
+ return -code error "thread_info: motion-controller not found"
+ }
+ }
+} ;# thread_info
+
+proc get_netlist {inpins_name outpin_name iopins_name signame} {
+ # input: signame
+ # outputs:
+ # inpins_name list of input pins for signame or ""
+ # iopins_name list of io pins for signame or ""
+ # outpin_name output pin for signame or ""
+ upvar $inpins_name inpins
+ upvar $iopins_name iopins
+ upvar $outpin_name outpin
+
+ set inpins ""
+ set iopins ""
+ set outpin ""
+
+ set header_len 2
+ set lines [split [hal show signal $signame] \n]
+ set lines [lreplace $lines 0 [expr $header_len -1]]
+ set lines [lreplace $lines end end]
+ set ct 0
+ foreach line $lines {set l($ct) [string trim $line];incr ct}
+ set ct_max $ct
+ set ct 0
+ for {set ct 0} {$ct < $ct_max} {incr ct} {
+ set v0 [lindex $l($ct) 0]
+ set v1 [lindex $l($ct) 1]
+ set v2 [lindex $l($ct) 2]
+ switch $v0 {
+ float -
+ bit -
+ u32 -
+ s32 {set sname $v2} ;# set on 1st non-header line
+ "==>" {}
+ "<==" {}
+ "<=>" {}
+ * {return -code error "get_netlist: Unexpected <$line">}
+ }
+ if {"$signame"=="$sname"} {
+ switch $v0 {
+ "==>" {lappend inpins $v1}
+ "<==" {lappend outpin $v1}
+ "<=>" {lappend iopins $v1}
+ }
+ }
+ }
+} ;# get_netlist
+
+proc find_file_in_hallib_path {filename {inifile .}} {
+ # find halfile using path HALLIB_PATH=.:HALLIB_DIR (see scripts/linuxcnc.in)
+ set libtag LIB: ;# special prefix for explicit use of hallib file
+ set halname [lindex $filename end]
+ if {[string first "$libtag" $halname] == 0} {
+ # explicit $libtag used
+ set halname [string range $halname [string len $libtag] end]
+ set usehalname [file join $::env(HALLIB_DIR) $halname]
+ } else {
+ if {[file pathtype $filename] == "absolute"} {
+ set usehalname $filename
+ } else {
+ # relative file specifier (relative to INI file directory)
+ set usehalname [file join [file dirname $inifile] $halname]
+ if ![file readable $usehalname] {
+ # use ::env(HALLIB_DIR)
+ set usehalname [file join $::env(HALLIB_DIR) $halname]
+ }
+ }
+ }
+ if [file readable $usehalname] {
+ return $usehalname
+ }
+ return -code error "find_file_in_hallib_path: cannot find: <$filename>"
+} ;# find_file_in_hallib_path
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/halcheck.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/halcheck.tcl
new file mode 100755
index 0000000..af58589
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/halcheck.tcl
@@ -0,0 +1,171 @@
+# halcheck.tcl: a halfile to report:
+# 1) functions with no addf (usually an error)
+# 2) signals with no inputs (not an error)
+# 3) signals with no output (not an error)
+#
+# Usage in INI file (must be the last HALFILE):
+# [HAL]
+# ...
+# HALFILE = LIB:halcheck.tcl
+#
+# Note: connections in a POSTGUI_HALFILE are not checked
+#
+
+# config items:
+set ::popup 1 ;# default: enable popup (in addition to prints)
+set ::bigfont {Helvetica 12 bold} ;# {Family size weight}
+
+#----------------------------------------------------------------------
+set ::prog halcheck
+
+# test for ::argv items on halfile line (requires 2.7)
+if [info exists ::argv] {
+ if {[lsearch $::argv nopopup] >= 0} {
+ set ::popup 0 ;# disable popup
+ }
+}
+
+#----------------------------------------------------------------------
+proc gui_message { type items } {
+ if { "$items" == "" } return
+ # twopass processing uses built-ins only (no Tk)
+ if {$::popup && [catch {package require Tk} msg]} {
+ set ::popup 0
+ }
+ if { !$::popup } return
+ if { ![winfo exists .b] } {
+ wm title . "HAL checks"
+ pack [button .b \
+ -text Dismiss \
+ -command {destroy .} \
+ ] -side bottom
+ }
+ set items [string map {" " \n} $items]
+ switch $type {
+ no_addfs {
+ pack [label .noa1 \
+ -text "Functions with no addf: " \
+ -font $::bigfont \
+ -relief ridge -bd 3 \
+ ] -side top -fill x -expand 1
+ pack [label .noa2 \
+ -text "$items" \
+ -justify left \
+ -anchor w \
+ -relief sunken -bd 3 \
+ ] -side top -fill x -expand 1
+ }
+ no_inputs {
+ pack [label .noi1 \
+ -text "Signals with no inputs: " \
+ -font $::bigfont \
+ -relief ridge -bd 3 \
+ ] -side top -fill x -expand 1
+ pack [label .noi2 \
+ -text "$items" \
+ -justify left \
+ -anchor w \
+ -relief sunken -bd 3 \
+ ] -side top -fill x -expand 1
+ }
+ no_output {
+ pack [label .noo1 \
+ -text "Signals with no output: " \
+ -font $::bigfont \
+ -relief ridge -bd 3 \
+ ] -side top -fill x -expand 1
+ pack [label .noo2 \
+ -text "$items" \
+ -justify left \
+ -anchor w \
+ -relief sunken -bd 3 \
+ ] -side top -fill x -expand 1
+ }
+ }
+} ;# gui_message
+
+proc check_function_usage {} {
+ set ans [hal show function]
+ set lines [split $ans \n]
+ set header_len 2
+ set lines [lreplace $lines 0 [expr $header_len -1]]
+ set lines [lreplace $lines end end]
+ set ct 0
+ set no_addfs ""
+ foreach line $lines {
+ catch {unset f1 f2 f3 f4}
+ scan [lindex $lines $ct] \
+ "%s %s %s %s %s %s" \
+ owner codeaddr arg fp users name
+ if {"$users" == 0} {
+ puts "$::prog: Functions with no addf: $name"
+ lappend no_addfs $name
+ }
+ incr ct
+ }
+ gui_message no_addfs $no_addfs
+} ;# check_function_usage
+
+proc check_signal_usage {} {
+ set ans [hal show signal]
+ set lines [split $ans \n]
+ set header_len 2
+ set lines [lreplace $lines 0 [expr $header_len -1]]
+ set lines [lreplace $lines end end]
+ set ct 0
+ foreach line $lines {
+ set howmany [scan $line "%s%s%s" fld1 fld2 fld3]
+ if {$howmany == 3} {
+ set signame $fld3
+ set ::SIG($signame,type) $fld1
+ set ::SIG($signame,value) $fld2
+ set ::SIG($signame,inputs) ""
+ set ::SIG($signame,output) ""
+ set ::SIG($signame,ios) ""
+ continue
+ }
+ switch $fld1 {
+ "==>" {lappend ::SIG($signame,inputs) $fld2}
+ "<==" {lappend ::SIG($signame,output) $fld2}
+ "<=>" {lappend ::SIG($signame,ios) $fld2}
+ default {return -code error "check-signal_usage: unrecognized <$line>"}
+ }
+ incr ct
+ }
+ set no_inputs ""
+ foreach iname [array names ::SIG *,inputs] {
+ set signame [lindex [split $iname ,] 0]
+ if {$::SIG($iname) == ""} {
+ set msg "$::prog: Signal: $signame <$::SIG($signame,value)> NO inputs"
+ if {$::SIG($signame,ios) != ""} {
+ set msg "$msg (i/o:$::SIG($signame,ios))"
+ } else {
+ lappend no_inputs $signame
+ }
+ puts "$msg"
+ }
+ }
+ set no_output ""
+ foreach oname [array names ::SIG *,output] {
+ set signame [lindex [split $oname ,] 0]
+ if {$::SIG($oname) == ""} {
+ set msg "$::prog: Signal: $signame <$::SIG($signame,value)> NO output"
+ if {$::SIG($signame,ios) != ""} {
+ set msg "$msg (i/o:$::SIG($signame,ios))"
+ } else {
+ lappend no_output $signame
+ }
+ puts "$msg"
+ }
+ }
+ foreach iname [array names ::SIG *,ios] {
+ if { $::SIG($iname) == ""} {unset ::SIG($iname)}
+ }
+ gui_message no_inputs $no_inputs
+ gui_message no_output $no_output
+} ;# check_signal_usage
+
+#----------------------------------------------------------------------
+# begin
+check_function_usage
+check_signal_usage
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hookup_moveoff.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hookup_moveoff.tcl
new file mode 100755
index 0000000..38f4cfa
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/hookup_moveoff.tcl
@@ -0,0 +1,316 @@
+# hallib procs:
+source [file join $::env(HALLIB_DIR) hal_procs_lib.tcl]
+#
+# hookup_moveoff.tcl -- HALFILE to:
+# 1) disconnect initial pos-cmd and pos-fb pin connections
+# 2) loadrt the moveoff component with name=mv
+# 3) addf the moveoff component functions in required sequence
+# 4) reconnect the pos-cmd and pos-fb pins to use the component
+#
+# Support for demo type INI files where the pos-cmd and pos-fb pins are
+# 'shortcircuit' connected together is included.
+#
+# The moveoff component may be initialized with settings from the INI file
+#
+# Usage:
+# 1) Specify this file in the INI file as [HAL]HALFILE
+# Its position must follow halfiles that connect the pos-cmd and
+# pos-fb pins.
+# [HAL]
+# ...
+# HALFILE = hookup_moveoff.tcl
+# ...
+#
+# 2) Include INI file entries for moveoff component settings:
+# [MOVEOFF]
+# EPSILON =
+# WAYPOINT_SAMPLE_SECS =
+# WAYPOINT_THRESHOLD =
+# BACKTRACK_ENABLE =
+#
+# If these settings are not found in the INI file, the moveoff
+# component defaults will be used.
+#
+# 3) Include INI file entries for the per-joint settings
+# [MOVEOFF_n]
+# MAX_VELOCITY =
+# MAX_ACCELERATION =
+# MAX_LIMIT =
+# MIN_LIMIT =
+#
+# If settings are not found in the INI file, the items
+# [JOINT_n]
+# MAX_VELOCITY =
+# MAX_ACCELERATION =
+# MAX_LIMIT =
+# MIN_LIMIT =
+# are used. If these are not defined, the moveoff component
+# defaults are used.
+#
+# To use the (optional) demonstration gui named moveoff_gui,
+# include an INI entry:
+#
+# [APPLICATIONS]
+# APP = moveoff_gui option1 option2 ...
+#
+# For available options, Use:
+# $ moveoff_gui --help
+#
+# The moveoff_gui will provide a display and control for
+# enabling offsetting if the pin mv.move-enable is not connected
+# when moveoff_gui is started.
+#
+# If the mv.move-enable pin is connected when moveoff_gui
+# is started, then it will provide a display but no control.
+# This mode supports hal connections for a jog wheel or other
+# methods of controlling the offset input pins (mv.offset-M)
+
+#-----------------------------------------------------------------------
+# Copyright: 2014
+# Authors: Dewey Garrett
+#
+# 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.
+#-----------------------------------------------------------------------
+
+proc do_hal {args} {
+ if {[info exists ::noexecute] && $::noexecute} {
+ puts "((do_hal))$args"
+ } else {
+ if {$::HU(verbose)} {puts do_hal:$args}
+ eval hal $args
+ }
+} ;# do_hal
+
+proc setup_pinnames {} {
+ # Note: works for standard names but a custom proc is needed
+ # here if the Hal alias command is used on the names
+
+ # Identify JOINT_n stanzas
+ for {set a 0} {$a < 9} {incr a} {
+ if [info exists ::JOINT_[set a](TYPE)] {
+ lappend ::HU(axes) $a
+ set ::HU(highest_joint_num) $a
+ }
+ }
+ foreach a $::HU(axes) {
+ set ::HU($a,pos,pinname) joint.${a}.motor-pos-cmd
+ set ::HU($a,fb,pinname) joint.${a}.motor-pos-fb
+ }
+} ;# setup_pinnames
+
+proc install_moveoff {} {
+ # note expected name for moveoff_gui is $::m
+ set pnumber [expr 1 + $::HU(highest_joint_num)]
+ do_hal loadrt moveoff personality=$pnumber names=$::m
+
+ set mot_thread $::HU(motion-controller,threadname)
+
+ if [info exists ::HU($mot_thread,motion-controller)] {
+ set write_index [expr 1 + $::HU($mot_thread,motion-controller)]
+ } else {
+ set write_index [expr 1 + $::HU($mot_thread,index,last)]
+ }
+ do_hal addf $::m.write-outputs $mot_thread $write_index
+
+ if [info exists ::HU($mot_thread,motion-command-handler)] {
+ if {1 == $::HU($mot_thread,motion-command-handler) } {
+ set read_index 1
+ } else {
+ set read_index [expr -1 + $::HU($mot_thread,motion-command-handler)]
+ }
+ } else {
+ set read_index 1
+ }
+ do_hal addf $::m.read-inputs $mot_thread $read_index
+} ;# install_moveoff
+
+proc disconnect_pos_from_motion {a} {
+ set pinname $::HU($a,pos,pinname)
+ set inpins {}; set outpin {}
+ if [connection_info tmp $pinname] {
+ if {$tmp(signame) != ""} {
+ get_netlist inpins outpin iopins $tmp(signame)
+ set ::HU($a,pos,signame) $tmp(signame)
+ set ::HU($a,pos,inputs) $inpins
+ set ::HU($a,pos,output) $outpin
+ }
+ } else {
+ return -code error "<$pinname> not connected as expected"
+ }
+ do_hal unlinkp $pinname
+} ;# disconnect_pos_from_motion
+
+proc disconnect_fb_to_motion {a} {
+ set pinname $::HU($a,fb,pinname)
+ set inpins {}; set outpin {}
+ if [connection_info tmp $pinname] {
+ if {$tmp(signame) != ""} {
+ get_netlist inpins outpin iopins $tmp(signame)
+ set ::HU($a,fb,signame) $tmp(signame)
+ set ::HU($a,fb,inputs) $inpins
+ set ::HU($a,fb,output) $outpin
+ }
+ } else {
+ return -code error "<$pinname> not connected as expected"
+ }
+ do_hal unlinkp $pinname
+} ;# disconnect_fb_to_motion
+
+proc check_for_short_circuit {a} {
+ if {$::HU($a,fb,signame) == $::HU($a,pos,signame)} {
+ set ::HU($a,shortcircuit) 1
+ } else {
+ set ::HU($a,shortcircuit) 0
+ }
+} ;# check_for_short_circuit
+
+proc new_connect_pos_to_moveoff {a} {
+ do_hal delsig $::HU($a,pos,signame)
+ do_hal net hu:pos-$a <= $::HU($a,pos,pinname)
+ do_hal net hu:pos-$a => $::m.pos-$a
+} ;# new_connect_pos_to_moveoff
+
+proc new_connect_plus_offset {a} {
+ if $::HU($a,shortcircuit) return
+ do_hal net hu:plus-$a <= $::m.pos-plusoffset-$a
+ foreach in_pinname $::HU($a,pos,inputs) {
+ if {"$in_pinname" == "$::HU($a,fb,pinname)"} continue
+ do_hal unlinkp $in_pinname
+ do_hal net hu:plus-$a => $in_pinname
+ }
+} ;# new_connect_plus_offset
+
+proc new_connect_minus_offset {a} {
+ do_hal net hu:minus-$a <= $::m.fb-minusoffset-$a
+ do_hal net hu:minus-$a => $::HU($a,fb,pinname)
+} ;# new_connect_plus_offset
+
+proc new_connect_fb_to_moveoff {a} {
+ if $::HU($a,shortcircuit) return
+ do_hal delsig $::HU($a,fb,signame)
+ do_hal net hu:fb-$a => $::m.fb-$a
+ do_hal net hu:fb-$a <= $::HU($a,fb,output)
+ foreach in_pinname $::HU($a,fb,inputs) {
+ if {"$in_pinname" == "$::HU($a,fb,pinname)"} continue
+ do_hal unlinkp $in_pinname
+ do_hal net hu:fb-$a => $in_pinname
+ }
+} ;# new_connect_fb_to_moveoff
+
+proc reconnect_short_circuit {a} {
+ do_hal net hu:shortcircuit-$a <= $::m.pos-plusoffset-$a
+ do_hal net hu:shortcircuit-$a => $::m.fb-$a
+ foreach in_pinname $::HU($a,pos,inputs) {
+ if {"$in_pinname" == "$::HU($a,fb,pinname)"} {continue}
+ do_hal unlinkp $in_pinname
+ do_hal net hu:shortcircuit-$a => $in_pinname
+ }
+} ;# reconnect_short_circuit
+
+proc set_moveoff_inputs {a} {
+ foreach {pin ininame} { offset-vel MAX_VELOCITY \
+ offset-accel MAX_ACCELERATION \
+ offset-max MAX_LIMIT \
+ offset-min MIN_LIMIT \
+ } {
+ if [info exists ::MOVEOFF_[set a]($ininame)] {
+ set ::HU($a,$pin) [set ::MOVEOFF_[set a]($ininame)]
+ # lindex is used in case there are duplicate entries
+ set ::HU($a,$pin) [lindex $::HU($a,$pin) end]
+ } elseif { [info exists ::JOINT_[set a]($ininame)] } {
+ set ::HU($a,$pin) [set ::JOINT_[set a]($ininame)]
+ # lindex is used in case there are duplicate entries
+ set ::HU($a,$pin) [lindex $::HU($a,$pin) end]
+ puts "hookup_moveoff.tcl:use \[JOINT_$a\]$ininame=$::HU($a,$pin)"
+ }
+ if [info exists ::HU($a,$pin)] {
+ do_hal setp $::m.$pin-$a $::HU($a,$pin)
+ }
+ }
+} ;# set_moveoff_inputs
+
+proc set_moveoff_parms {} {
+ foreach {pin ininame} { epsilon EPSILON \
+ waypoint-sample-secs WAYPOINT_SAMPLE_SECS \
+ waypoint-threshold WAYPOINT_THRESHOLD \
+ backtrack-enable BACKTRACK_ENABLE \
+ } {
+ if {[info exists ::MOVEOFF($ininame)]} {
+ # lindex is used in case there are duplicate entries
+ set ::HU($pin) [lindex $::MOVEOFF($ininame) end]
+ do_hal setp $::m.$pin $::HU($pin)
+ }
+ }
+} ;# set_moveoff_parms
+
+proc set_moveoff_controls {} {
+ return
+ # provision for future offset control connections
+} ;# set_moveoff_controls
+
+# begin-----------------------------------------------------------------
+
+set ::m mv ;# moveoff component name
+ #(must agree with the (optionaL) gui moveoff_gui)
+
+# debugging items
+set ::HU(verbose) 0
+set ::noexecute 0
+
+# Provision for twopass compatibility
+# (::tp is the namespace for [HAL]TWOPASS processing)
+if [namespace exists ::tp] {
+ set passno [::tp::passnumber]
+ if {$passno == 0} {
+ # With twopass processing, the initial pass0 only collects
+ # loadrt and loadusr commands with no execution.
+ # So the checks etc herein cannot work until pass1
+ # Note that this file only uses loadrt once for the moveoff
+ # component so it manages its loadrt exclusively
+ puts "hookup_moveoff.tcl: twopass active, pass $passno skipped"
+ return
+ } else {
+ puts "hookup_moveoff.tcl: twopass active, pass $passno active"
+ }
+}
+
+if [catch {
+ set ::HU(cmd) "thread_info ::HU"; eval $::HU(cmd)
+ set ::HU(cmd) setup_pinnames; eval $::HU(cmd)
+ set ::HU(cmd) install_moveoff; eval $::HU(cmd)
+ foreach a $::HU(axes) {
+ set ::HU(cmd) "disconnect_pos_from_motion $a"; eval $::HU(cmd)
+ set ::HU(cmd) "disconnect_fb_to_motion $a"; eval $::HU(cmd)
+ set ::HU(cmd) "check_for_short_circuit $a"; eval $::HU(cmd)
+ set ::HU(cmd) "new_connect_pos_to_moveoff $a"; eval $::HU(cmd)
+ set ::HU(cmd) "new_connect_plus_offset $a"; eval $::HU(cmd)
+ set ::HU(cmd) "new_connect_minus_offset $a"; eval $::HU(cmd)
+ set ::HU(cmd) "new_connect_fb_to_moveoff $a"; eval $::HU(cmd)
+ if $::HU($a,shortcircuit) {
+ set ::HU(cmd) "reconnect_short_circuit $a "; eval $::HU(cmd)
+ }
+ set ::HU(cmd) "set_moveoff_inputs $a"; eval $::HU(cmd)
+ }
+ set ::HU(cmd) "set_moveoff_parms"; eval $::HU(cmd)
+ set ::HU(cmd) "set_moveoff_controls"; eval $::HU(cmd)
+ if $::HU(verbose) {parray ::HU}
+} msg ] {
+ puts "\n\n$::argv0 $::argv"
+ parray ::HU
+ catch {puts filename=$filename}
+ puts "\n failing cmd=$::HU(cmd)"
+ puts msg=<$msg>
+ return -code error
+}
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/lathe.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/lathe.hal
new file mode 100755
index 0000000..1e8b3ca
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/lathe.hal
@@ -0,0 +1,69 @@
+# counting the spindle encoder in software
+loadrt encoder names=encoder_0
+# simulate the encoder
+loadrt sim_encoder names=sim_encoder_0
+loadrt limit2 names=limit_speed
+
+addf limit_speed servo-thread
+
+#######################################################
+# Beginning of threading related stuff
+#######################################################
+
+# spindle speed control
+net spindle-speed-cmd spindle.0.speed-out => limit_speed.in
+net spindle-speed-limited limit_speed.out => sim_encoder_0.speed
+
+# simulate spindle mass
+setp limit_speed.maxv 500.0 # rpm/second
+
+# spindle encoder
+# connect encoder signals to encoder counter
+net spindle-phase-A sim_encoder_0.phase-A => encoder_0.phase-A
+net spindle-phase-B sim_encoder_0.phase-B => encoder_0.phase-B
+net spindle-phase-Z sim_encoder_0.phase-Z => encoder_0.phase-Z
+
+# assume 120 ppr = 480 counts/rev for the spindle
+setp sim_encoder_0.ppr 120
+# iocontrol output is in rpm, but sim-encoder speed is rps
+setp sim_encoder_0.scale 60
+# scale encoder output to read in revolutions
+# (that way thread pitches can be straightforward,
+# a 20 tpi thread would multiply the encoder output
+# by 1/20, etc)
+setp encoder_0.position-scale 480
+
+# encoder reset control
+# hook up motion controller's sync output
+net spindle-index-enable spindle.0.index-enable <=> encoder_0.index-enable
+
+# report our revolution count to the motion controller
+net spindle-pos encoder_0.position => spindle.0.revs
+
+# for spindle velocity estimate
+loadrt lowpass names=lowpass_velocity
+loadrt scale names=scale_to_rpm
+net spindle-rps-raw encoder_0.velocity lowpass_velocity.in
+net spindle-rps-filtered lowpass_velocity.out scale_to_rpm.in spindle.0.speed-in
+net spindle-rpm-filtered scale_to_rpm.out
+setp scale_to_rpm.gain 60
+setp lowpass_velocity.gain .07
+addf lowpass_velocity servo-thread
+addf scale_to_rpm servo-thread
+
+# for at-speed detection
+loadrt near names=near_speed
+addf near_speed servo-thread
+setp near_speed.scale 1.1
+setp near_speed.difference 10
+net spindle-speed-cmd => near_speed.in1
+net spindle-rpm-filtered => near_speed.in2
+net spindle-at-speed near_speed.out spindle.0.at-speed
+
+net spindle-fwd <= spindle.0.forward
+
+addf encoder.capture-position servo-thread
+addf sim-encoder.update-speed servo-thread
+
+addf sim-encoder.make-pulses base-thread
+addf encoder.update-counters base-thread
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/locking_indexer.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/locking_indexer.hal
new file mode 100755
index 0000000..5a147fa
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/locking_indexer.hal
@@ -0,0 +1,11 @@
+# simulate a locking rotary axis B
+
+loadrt timedelay names=timedelay_unlock
+addf timedelay_unlock servo-thread
+
+net B-unlock joint.4.unlock => timedelay_unlock.in
+net B-is-unlocked timedelay_unlock.out => joint.4.is-unlocked
+
+setp timedelay_unlock.on-delay 0.75
+setp timedelay_unlock.off-delay 0.5
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/moveoff_external.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/moveoff_external.hal
new file mode 100755
index 0000000..92c205a
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/moveoff_external.hal
@@ -0,0 +1,28 @@
+# moveoff_external.hal (for use with moveoff_gui)
+
+# This halfile demonstrates how a connection to
+# mv.move-enable
+# allows moveoff_gui to interface with other connections that control:
+# mv.move-enable
+# mv.offset-in-M
+
+# This halfile should follow halfiles which loadrt the moveoff component
+#-----------------------------------------------------------------------
+
+# Overall enable for the component:
+# 0 ==> external control of mv.move-enable required
+setp mv.move-enable 0
+
+# When the mv.move-enable pin is connected to a signal, moveoff_gui
+# will provide display but no controls.
+# An external app must connect the mv.move-enable pin to control:
+net external_enable mv.move-enable
+
+# An external app must connect to the mv.offset-in-M pins to control:
+net external_offset_0 mv.offset-in-0
+net external_offset_1 mv.offset-in-1
+net external_offset_2 mv.offset-in-2
+
+# An external app may optionally connect the mv.backtrack-enable pin
+# to manage backtracking:
+net external_backtrack_en mv.backtrack-enable
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/plasmac.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/plasmac.tcl
new file mode 100755
index 0000000..77db473
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/plasmac.tcl
@@ -0,0 +1,79 @@
+
+# ***** THIS FILE IS USED ONLY BY CONFIGS THAT HAVE BEEN MIGRATED FROM A PLASMAC CONFIGURATION *****
+
+# common connections for the plasmac component
+
+# PLASMAC COMPONENT ##########################################################
+loadrt plasmac
+addf plasmac servo-thread
+
+# COMPONENT INPUTS ###########################################################
+net plasmac:axis-x-position axis.x.pos-cmd => plasmac.axis-x-position
+net plasmac:axis-y-position axis.y.pos-cmd => plasmac.axis-y-position
+net plasmac:current-velocity motion.current-vel => plasmac.current-velocity
+net plasmac:cutting-start spindle.0.on => plasmac.cutting-start
+net plasmac:feed-override halui.feed-override.value => plasmac.feed-override
+net plasmac:feed-reduction motion.analog-out-03 => plasmac.feed-reduction
+net plasmac:feed-upm motion.feed-upm => plasmac.feed-upm
+net plasmac:homed motion.is-all-homed => plasmac.homed
+net plasmac:ignore-arc-ok-0 motion.digital-out-01 => plasmac.ignore-arc-ok-0
+net plasmac:motion-type motion.motion-type => plasmac.motion-type
+net plasmac:offsets-active motion.eoffset-active => plasmac.offsets-active
+net plasmac:program-is-idle halui.program.is-idle => plasmac.program-is-idle
+net plasmac:program-is-paused halui.program.is-paused => plasmac.program-is-paused
+net plasmac:program-is-running halui.program.is-running => plasmac.program-is-running
+net plasmac:thc-disable motion.digital-out-02 => plasmac.thc-disable
+net plasmac:torch-off motion.digital-out-03 => plasmac.torch-off
+net plasmac:units-per-mm halui.machine.units-per-mm => plasmac.units-per-mm
+net plasmac:x-offset-current axis.x.eoffset => plasmac.x-offset-current
+net plasmac:y-offset-current axis.y.eoffset => plasmac.y-offset-current
+net plasmac:z-offset-current axis.z.eoffset => plasmac.z-offset-current
+
+# use existing machine-is-on signal from pncconf if it exists
+if {[hal list sig machine-is-on] != {}} {
+ net machine-is-on => plasmac.machine-is-on
+} else {
+ net machine-is-on halui.machine.is-on => plasmac.machine-is-on
+}
+
+# if no new dbounce then use old debounce component for legacy plasmac conversions
+if {[hal list pin db_float.out] != {}} {
+ net plasmac:arc-ok db_arc-ok.out => plasmac.arc-ok-in
+ net plasmac:breakaway-switch-out db_breakaway.out => plasmac.breakaway
+ net plasmac:float-switch-out db_float.out => plasmac.float-switch
+ net plasmac:ohmic-probe-out db_ohmic.out => plasmac.ohmic-probe
+} else {
+ net plasmac:breakaway-switch-out debounce.0.1.out => plasmac.breakaway
+ net plasmac:float-switch-out debounce.0.0.out => plasmac.float-switch
+ net plasmac:ohmic-probe-out debounce.0.2.out => plasmac.ohmic-probe
+}
+
+# COMPONENT OUTPUTS ##########################################################
+net plasmac:adaptive-feed plasmac.adaptive-feed => motion.adaptive-feed
+net plasmac:cutting-stop halui.spindle.0.stop => plasmac.cutting-stop
+net plasmac:feed-hold plasmac.feed-hold => motion.feed-hold
+net plasmac:jog-inhibit plasmac.jog-inhibit => motion.jog-inhibit motion.jog-stop
+net plasmac:offset-scale plasmac.offset-scale => axis.x.eoffset-scale axis.y.eoffset-scale axis.z.eoffset-scale
+net plasmac:program-pause plasmac.program-pause => halui.program.pause
+net plasmac:program-resume plasmac.program-resume => halui.program.resume
+net plasmac:program-run plasmac.program-run => halui.program.run
+net plasmac:program-stop plasmac.program-stop => halui.program.stop
+net plasmac:torch-on plasmac.torch-on
+net plasmac:x-offset-counts plasmac.x-offset-counts => axis.x.eoffset-counts
+net plasmac:y-offset-counts plasmac.y-offset-counts => axis.y.eoffset-counts
+net plasmac:xy-offset-enable plasmac.xy-offset-enable => axis.x.eoffset-enable axis.y.eoffset-enable
+net plasmac:z-offset-counts plasmac.z-offset-counts => axis.z.eoffset-counts
+net plasmac:z-offset-enable plasmac.z-offset-enable => axis.z.eoffset-enable
+
+# multiple spindles
+if [info exists ::TRAJ(SPINDLES)] {
+ set num_spindles [lindex $::TRAJ(SPINDLES) 0]
+ if {$num_spindles > 1} {net plasmac:scribe-start spindle.1.on => plasmac.scribe-start}
+ if {$num_spindles > 2} {net plasmac:spotting-start spindle.2.on => plasmac.spotting-start}
+}
+
+# powermax serial communications
+# for qtplasmac
+if [info exists ::QTPLASMAC(PM_PORT)] {loadusr -Wn pmx485 pmx485 [lindex $::QTPLASMAC(PM_PORT) 0]}
+# for plasmac
+if [info exists ::PLASMAC(PM_PORT)] {loadusr -Wn pmx485 plasmac/pmx485.py [lindex $::PLASMAC(PM_PORT) 0]}
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/qtplasmac_comp.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/qtplasmac_comp.hal
new file mode 100755
index 0000000..f3fc216
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/qtplasmac_comp.hal
@@ -0,0 +1,51 @@
+
+# ***** plasmac component connections for a QtPlasmaC configuration *****
+
+# do not make any changes to this file, it may be overwritten by future updates
+# make all customizations in custom.hal or custom_postgui.hal
+
+# ---PLASMAC COMPONENT INPUTS---
+net plasmac:arc-ok db_arc-ok.out => plasmac.arc-ok-in
+net plasmac:axis-x-position axis.x.pos-cmd => plasmac.axis-x-position
+net plasmac:axis-y-position axis.y.pos-cmd => plasmac.axis-y-position
+net plasmac:breakaway-switch-out db_breakaway.out => plasmac.breakaway
+net plasmac:current-velocity motion.current-vel => plasmac.current-velocity
+net plasmac:cutting-start spindle.0.on => plasmac.cutting-start
+net plasmac:cutting-stop halui.spindle.0.stop => plasmac.cutting-stop
+net plasmac:feed-override halui.feed-override.value => plasmac.feed-override
+net plasmac:feed-reduction motion.analog-out-03 => plasmac.feed-reduction
+net plasmac:float-switch-out db_float.out => plasmac.float-switch
+net plasmac:feed-upm motion.feed-upm => plasmac.feed-upm
+net plasmac:homed motion.is-all-homed => plasmac.homed
+net plasmac:ignore-arc-ok-0 motion.digital-out-01 => plasmac.ignore-arc-ok-0
+net machine-is-on halui.machine.is-on => plasmac.machine-is-on
+net plasmac:motion-type motion.motion-type => plasmac.motion-type
+net plasmac:offsets-active motion.eoffset-active => plasmac.offsets-active
+net plasmac:ohmic-probe-out db_ohmic.out => plasmac.ohmic-probe
+net plasmac:program-is-idle halui.program.is-idle => plasmac.program-is-idle
+net plasmac:program-is-paused halui.program.is-paused => plasmac.program-is-paused
+net plasmac:program-is-running halui.program.is-running => plasmac.program-is-running
+net plasmac:scribe-start spindle.1.on => plasmac.scribe-start
+net plasmac:spotting-start spindle.2.on => plasmac.spotting-start
+net plasmac:thc-disable motion.digital-out-02 => plasmac.thc-disable
+net plasmac:torch-off motion.digital-out-03 => plasmac.torch-off
+net plasmac:units-per-mm halui.machine.units-per-mm => plasmac.units-per-mm
+net plasmac:x-offset-current axis.x.eoffset => plasmac.x-offset-current
+net plasmac:y-offset-current axis.y.eoffset => plasmac.y-offset-current
+net plasmac:z-offset-current axis.z.eoffset => plasmac.z-offset-current
+
+# ---PLASMAC COMPONENT OUTPUTS---
+net plasmac:adaptive-feed plasmac.adaptive-feed => motion.adaptive-feed
+net plasmac:feed-hold plasmac.feed-hold => motion.feed-hold
+net plasmac:jog-inhibit plasmac.jog-inhibit => motion.jog-inhibit motion.jog-stop
+net plasmac:offset-scale plasmac.offset-scale => axis.x.eoffset-scale axis.y.eoffset-scale axis.z.eoffset-scale
+net plasmac:program-pause plasmac.program-pause => halui.program.pause
+net plasmac:program-resume plasmac.program-resume => halui.program.resume
+net plasmac:program-run plasmac.program-run => halui.program.run
+net plasmac:program-stop plasmac.program-stop => halui.program.stop
+net plasmac:torch-on plasmac.torch-on
+net plasmac:x-offset-counts plasmac.x-offset-counts => axis.x.eoffset-counts
+net plasmac:y-offset-counts plasmac.y-offset-counts => axis.y.eoffset-counts
+net plasmac:xy-offset-enable plasmac.xy-offset-enable => axis.x.eoffset-enable axis.y.eoffset-enable
+net plasmac:z-offset-counts plasmac.z-offset-counts => axis.z.eoffset-counts
+net plasmac:z-offset-enable plasmac.z-offset-enable => axis.z.eoffset-enable
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/servo_sim.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/servo_sim.hal
new file mode 100755
index 0000000..7e3ac85
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/servo_sim.hal
@@ -0,0 +1,285 @@
+# HAL config file for simulated servo machine
+
+# first load all the RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+# PID module, for three PID loops
+loadrt pid names=pid_x,pid_y,pid_z
+# 6 differentiators (for velocity and accel sigs)
+loadrt ddt names=ddt_x,ddt_xv,ddt_y,ddt_yv,ddt_z,ddt_zv
+# three scale blocks (to simulate motor and leadscrew scaling)
+loadrt scale names=scale_x,scale_y,scale_z
+# three lowpass filters (to simulate motor inertia), and nine
+loadrt lowpass names=lowpass_x,lowpass_y,lowpass_z
+# window comparators (to simulate limit and home switches)
+loadrt wcomp names=wcomp_xneg,wcomp_xpos,wcomp_xhome,wcomp_yneg,wcomp_ypos,wcomp_yhome,wcomp_zneg,wcomp_zpos,wcomp_zhome
+
+# simulated encoders
+loadrt sim_encoder names=sim_encoder_px,sim_encoder_py,sim_encoder_pz
+# software encoder counters, 3 for feedback, 3 for actual axis pos
+loadrt encoder names=encoder_px,encoder_py,encoder_pz,encoder_x,encoder_y,encoder_z
+# add encoder counter and simulator functions to high speed thread
+addf sim-encoder.make-pulses base-thread
+addf encoder.update-counters base-thread
+
+# add all required functions to servo thread
+addf encoder.capture-position servo-thread
+addf wcomp_xneg servo-thread
+addf wcomp_xpos servo-thread
+addf wcomp_xhome servo-thread
+addf wcomp_yneg servo-thread
+addf wcomp_ypos servo-thread
+addf wcomp_yhome servo-thread
+addf wcomp_zneg servo-thread
+addf wcomp_zpos servo-thread
+addf wcomp_zhome servo-thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+addf pid_x.do-pid-calcs servo-thread
+addf pid_y.do-pid-calcs servo-thread
+addf pid_z.do-pid-calcs servo-thread
+addf scale_x servo-thread
+addf scale_y servo-thread
+addf scale_z servo-thread
+addf lowpass_x servo-thread
+addf lowpass_y servo-thread
+addf lowpass_z servo-thread
+addf sim-encoder.update-speed servo-thread
+
+# link the differentiator functions into the code
+addf ddt_x servo-thread
+addf ddt_xv servo-thread
+addf ddt_y servo-thread
+addf ddt_yv servo-thread
+addf ddt_z servo-thread
+addf ddt_zv servo-thread
+
+# get position feedback from encoder module
+# connect position feedback to PID loop and motion module
+net Xpos-fb encoder_px.position => pid_x.feedback joint.0.motor-pos-fb
+net Ypos-fb encoder_py.position => pid_y.feedback joint.1.motor-pos-fb
+net Zpos-fb encoder_pz.position => pid_z.feedback joint.2.motor-pos-fb
+
+# set position feedback scaling
+setp encoder_px.position-scale [JOINT_0]INPUT_SCALE
+setp encoder_py.position-scale [JOINT_1]INPUT_SCALE
+setp encoder_pz.position-scale [JOINT_2]INPUT_SCALE
+
+# connect encoder index-enables for homing on index
+net Xindex-enable encoder_px.index-enable <=> joint.0.index-enable pid_x.index-enable
+net Yindex-enable encoder_py.index-enable <=> joint.1.index-enable
+net Zindex-enable encoder_pz.index-enable <=> joint.2.index-enable
+
+# connect position commands from motion controller to PID input
+net Xpos-cmd <= joint.0.motor-pos-cmd => pid_x.command
+net Ypos-cmd <= joint.1.motor-pos-cmd => pid_y.command
+net Zpos-cmd <= joint.2.motor-pos-cmd => pid_z.command
+
+# connect motion controller enables to PID blocks
+net Xenable joint.0.amp-enable-out => pid_x.enable
+net Yenable joint.1.amp-enable-out => pid_y.enable
+net Zenable joint.2.amp-enable-out => pid_z.enable
+
+# connect PID loops to scale blocks that translate to motor revs per sec
+net Xoutput pid_x.output => scale_x.in
+net Youtput pid_y.output => scale_y.in
+net Zoutput pid_z.output => scale_z.in
+
+# set scaling, number of motor revs needed to
+# travel one inch
+setp scale_x.gain [JOINT_0]DRIVE_RATIO
+setp scale_y.gain [JOINT_1]DRIVE_RATIO
+setp scale_z.gain [JOINT_2]DRIVE_RATIO
+
+# motor speed command sigs come from scale blocks
+# motor speed commands go thru lowpass filters
+# to simulate motor inertia
+net Xmtr-cmd scale_x.out => lowpass_x.in
+net Ymtr-cmd scale_y.out => lowpass_y.in
+net Zmtr-cmd scale_z.out => lowpass_z.in
+
+# set "inertia" here, probably by trial and error
+setp lowpass_x.gain 0.1
+setp lowpass_y.gain 0.1
+setp lowpass_z.gain 0.1
+
+# "actual" motor speed signals
+# output of lowpass is simulated motor speed
+# speed goes to simulated encoders
+net Xmtr-spd lowpass_x.out => sim_encoder_px.speed
+net Ymtr-spd lowpass_y.out => sim_encoder_py.speed
+net Zmtr-spd lowpass_z.out => sim_encoder_pz.speed
+
+# set simulated encoder scaling
+setp sim_encoder_px.ppr [JOINT_0]MOTOR_PPR
+setp sim_encoder_py.ppr [JOINT_1]MOTOR_PPR
+setp sim_encoder_pz.ppr [JOINT_2]MOTOR_PPR
+
+# simulated encoder output signals
+# connect them up
+net XphA sim_encoder_px.phase-A => encoder_px.phase-A
+net XphB sim_encoder_px.phase-B => encoder_px.phase-B
+net XphZ sim_encoder_px.phase-Z => encoder_px.phase-Z
+net YphA sim_encoder_py.phase-A => encoder_py.phase-A
+net YphB sim_encoder_py.phase-B => encoder_py.phase-B
+net YphZ sim_encoder_py.phase-Z => encoder_py.phase-Z
+net ZphA sim_encoder_pz.phase-A => encoder_pz.phase-A
+net ZphB sim_encoder_pz.phase-B => encoder_pz.phase-B
+net ZphZ sim_encoder_pz.phase-Z => encoder_pz.phase-Z
+
+# set PID loop output limits to max velocity
+setp pid_x.maxoutput [JOINT_0]MAX_VELOCITY
+setp pid_y.maxoutput [JOINT_1]MAX_VELOCITY
+setp pid_z.maxoutput [JOINT_2]MAX_VELOCITY
+
+# set PID loop gains
+# NOTE: eventually these will be non-zero values as
+# needed to tune the performance of each axis. The
+# initial values shown here are extremely conservative
+# to prevent unexpected behavior. After this file
+# has been "executed" by halcmd, the gains can be
+# interactively adjusted using commands like
+# "halcmd setp pid..Pgain "
+# Once the axis has been tuned to your satisfaction,
+# do "halcmd show param | grep pid" to get a listing
+# of the tuning parameters, and enter those values here.
+
+# the values below come from the INI
+setp pid_x.Pgain [JOINT_0]PGAIN
+setp pid_x.Igain [JOINT_0]IGAIN
+setp pid_x.Dgain [JOINT_0]DGAIN
+setp pid_x.bias [JOINT_0]BIAS
+setp pid_x.FF0 [JOINT_0]FF0
+setp pid_x.FF1 [JOINT_0]FF1
+setp pid_x.FF2 [JOINT_0]FF2
+# deadband should be just over 1 count
+setp pid_x.deadband [JOINT_0]DEADBAND
+
+setp pid_y.Pgain [JOINT_1]PGAIN
+setp pid_y.Igain [JOINT_1]IGAIN
+setp pid_y.Dgain [JOINT_1]DGAIN
+setp pid_y.bias [JOINT_1]BIAS
+setp pid_y.FF0 [JOINT_1]FF0
+setp pid_y.FF1 [JOINT_1]FF1
+setp pid_y.FF2 [JOINT_1]FF2
+# deadband should be just over 1 count
+setp pid_y.deadband [JOINT_1]DEADBAND
+
+setp pid_z.Pgain [JOINT_2]PGAIN
+setp pid_z.Igain [JOINT_2]IGAIN
+setp pid_z.Dgain [JOINT_2]DGAIN
+setp pid_z.bias [JOINT_2]BIAS
+setp pid_z.FF0 [JOINT_2]FF0
+setp pid_z.FF1 [JOINT_2]FF1
+setp pid_z.FF2 [JOINT_2]FF2
+# deadband should be just over 1 count
+setp pid_z.deadband [JOINT_2]DEADBAND
+
+# send the position commands thru differentiators to
+# generate velocity and accel signals
+net Xvel ddt_x.out => ddt_xv.in
+net Xacc <= ddt_xv.out
+net Yvel ddt_y.out => ddt_yv.in
+net Yacc <= ddt_yv.out
+net Zvel ddt_z.out => ddt_zv.in
+net Zacc <= ddt_zv.out
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
+
+net xflt => joint.0.amp-fault-in
+net yflt => joint.1.amp-fault-in
+net zflt => joint.2.amp-fault-in
+
+# a second set of encoder counters keeps track of position
+net XphA => encoder_x.phase-A
+net XphB => encoder_x.phase-B
+net YphA => encoder_y.phase-A
+net YphB => encoder_y.phase-B
+net ZphA => encoder_z.phase-A
+net ZphB => encoder_z.phase-B
+
+setp encoder_x.position-scale [JOINT_0]INPUT_SCALE
+setp encoder_y.position-scale [JOINT_1]INPUT_SCALE
+setp encoder_z.position-scale [JOINT_2]INPUT_SCALE
+
+# connect "actual" position from encoders
+# to window comparators
+net Xaxis-pos encoder_x.position => wcomp_xneg.in wcomp_xpos.in wcomp_xhome.in
+net Yaxis-pos encoder_y.position => wcomp_yneg.in wcomp_ypos.in wcomp_yhome.in
+net Zaxis-pos encoder_z.position => wcomp_zneg.in wcomp_zpos.in wcomp_zhome.in
+
+# connect simulated switch outputs to motion controller
+net Xminlim wcomp_xneg.out => joint.0.neg-lim-sw-in
+net Xmaxlim wcomp_xpos.out => joint.0.pos-lim-sw-in
+net Xhome wcomp_xhome.out => joint.0.home-sw-in
+
+net Yminlim wcomp_yneg.out => joint.1.neg-lim-sw-in
+net Ymaxlim wcomp_ypos.out => joint.1.pos-lim-sw-in
+net Yhome wcomp_yhome.out => joint.1.home-sw-in
+
+net Zminlim wcomp_zneg.out => joint.2.neg-lim-sw-in
+net Zmaxlim wcomp_zpos.out => joint.2.pos-lim-sw-in
+net Zhome wcomp_zhome.out => joint.2.home-sw-in
+
+# configure the points at which the simulated switches trip
+# X axis first
+# min limit switch
+setp wcomp_xneg.max [JOINT_0]MIN_HARD_LIMIT
+setp wcomp_xneg.min [JOINT_0]MIN_HARD_LIMIT_RELEASE
+# max limit switch
+setp wcomp_xpos.min [JOINT_0]MAX_HARD_LIMIT
+setp wcomp_xpos.max [JOINT_0]MAX_HARD_LIMIT_RELEASE
+# home switch
+setp wcomp_xhome.min [JOINT_0]HOME_SW_MIN
+setp wcomp_xhome.max [JOINT_0]HOME_SW_MAX
+
+# Y axis
+# min limit switch
+setp wcomp_yneg.max [JOINT_1]MIN_HARD_LIMIT
+setp wcomp_yneg.min [JOINT_1]MIN_HARD_LIMIT_RELEASE
+# max limit switch
+setp wcomp_ypos.min [JOINT_1]MAX_HARD_LIMIT
+setp wcomp_ypos.max [JOINT_1]MAX_HARD_LIMIT_RELEASE
+# home switch
+setp wcomp_yhome.min [JOINT_1]HOME_SW_MIN
+setp wcomp_yhome.max [JOINT_1]HOME_SW_MAX
+
+# Z axis
+# min limit switch
+setp wcomp_zneg.max [JOINT_2]MIN_HARD_LIMIT
+setp wcomp_zneg.min [JOINT_2]MIN_HARD_LIMIT_RELEASE
+# max limit switch
+setp wcomp_zpos.min [JOINT_2]MAX_HARD_LIMIT
+setp wcomp_zpos.max [JOINT_2]MAX_HARD_LIMIT_RELEASE
+# home switch
+setp wcomp_zhome.min [JOINT_2]HOME_SW_MIN
+setp wcomp_zhome.max [JOINT_2]HOME_SW_MAX
+
+# Configure fake probing
+loadrt sphereprobe names=sphereprobe
+
+addf sphereprobe base-thread 2
+
+setp sphereprobe.cx -2811 # this is where it ends up after homing
+setp sphereprobe.cz -6000 # this is where it ends up after homing
+setp sphereprobe.r 5000 # 5/6 inch
+net px encoder_px.rawcounts => sphereprobe.px
+net py encoder_py.rawcounts => sphereprobe.py
+net pz encoder_pz.rawcounts => sphereprobe.pz
+net probe-out sphereprobe.probe-out => motion.probe-input
+net probe-out => encoder_px.latch-input encoder_py.latch-input
+net probe-out => encoder_pz.latch-input
+
+setp encoder_px.latch-rising 1
+setp encoder_px.latch-falling 1
+setp encoder_py.latch-rising 1
+setp encoder_py.latch-falling 1
+setp encoder_pz.latch-rising 1
+setp encoder_pz.latch-falling 1
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_ldelta.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_ldelta.hal
new file mode 100755
index 0000000..01a4248
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_ldelta.hal
@@ -0,0 +1,43 @@
+# core HAL config file for simulation
+
+# first load all the RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+#loadrt lineardeltakins
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+
+loadusr -W lineardelta MIN_JOINT=-420
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net J0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb lineardelta.joint0
+net J1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb lineardelta.joint1
+net J2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb lineardelta.joint2
+net Apos joint.3.motor-pos-cmd => joint.3.motor-pos-fb
+
+net L lineardeltakins.L => lineardelta.L
+net R lineardeltakins.R => lineardelta.R
+
+sets L 269
+sets R 130.25
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
+
+net spindle-fwd spindle.0.forward
+net spindle-rev spindle.0.reverse
+#net spindle-speed spindle.0.speed-out
+
+net lube iocontrol.0.lube
+net flood iocontrol.0.coolant-flood
+net mist iocontrol.0.coolant-mist
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_lib.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_lib.tcl
new file mode 100755
index 0000000..7d98add
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_lib.tcl
@@ -0,0 +1,498 @@
+# sim_lib.tcl: haltcl procs for sim configurations
+
+#----------------------------------------------------------------------
+# Notes (Joints-Axes):
+# 1) if ::KINS(KINEMATICS) exists:
+# loadrt the kins using any included parameters
+# example: for inifile item:
+# [KINS]KINEMATICS = trivkins coordinates=XZ kinstype=BOTH
+# use:
+# loadrt trivkins coordinates=xz kinstype=BOTH
+# else:
+# loadrt trivkins
+#
+# 2) NB: If $::KINS(KINEMATICS) specifies coordinates=, the
+# coordinates must agree with ::TRAJ(COORDINATES)
+#
+# 3) if known kins (trivkins) and xyz, make hypotenuse velocity
+# pins for xy,xyz
+#----------------------------------------------------------------------
+
+proc indices_for_trivkins {axes} {
+ # ref: src/emc/kinematics/trivkins.c
+ if {"$axes" == ""} {set axes {x y z a b c u v w}}
+ set i 0
+ foreach a [string tolower $axes] {
+ # assign to consecutive joints:
+ set ::SIM_LIB(jointidx,$a) $i
+ incr i
+ }
+} ;# indices_for_trivkins
+
+proc get_traj_coordinates {} {
+ # initraj.cc: coordinates may be with or without spaces X Z or XZ
+ # convert either form to list like {x z}
+ set coordinates [lindex $::TRAJ(COORDINATES) 0]
+ set coordinates [string map {" " "" "\t" ""} $coordinates]
+ set coordinates [split $coordinates ""]
+ return [string tolower $coordinates]
+} ;# get_traj_coordinates
+
+proc check_ini_items {} {
+ foreach {section item} {KINS KINEMATICS
+ KINS JOINTS
+ TRAJ COORDINATES
+ } {
+ if ![info exists ::${section}($item)] {
+ return -code error "Missing inifile item: \[$section\]$item"
+ }
+ }
+
+ if { [info exists ::DISPLAY(LATHE)]
+ && [lsearch $::KINS(KINEMATICS) trivkins] >= 0
+ } {
+ # reject historical lathe config using default trivkins coordinates (all)
+ if {[string first "=" $::KINS(KINEMATICS)] < 0} {
+ set msg "trivkins lathe config must specify coordinates= "
+ set msg "$msg\n(typically use \[KINS]KINEMATICS trivkins coordinates=XZ)"
+ return -code error "$msg"
+ }
+ }
+
+ set n_extrajoints 0
+ if [info exists ::EMCMOT(EMCMOT)] {
+ set mot [split [lindex $::EMCMOT(EMCMOT) 0]]
+ if {[string first motmod $mot] >= 0} {
+ foreach item $mot {
+ if {[string first num_extrajoints= $item] < 0} continue
+ set n_extrajoints [lindex [split $item =] end]
+ } ;# foreach
+ }
+ }
+
+ set kins [split [lindex $::KINS(KINEMATICS) 0]]
+ if {[string first trivkins $kins] >= 0} {
+ foreach item $kins {
+ if {[string first coordinates= $item] < 0} continue
+ set tcoords [lindex [split $item =] end]
+ set len_tcoords [string len $tcoords]
+ set expected_joints [expr $len_tcoords + $n_extrajoints]
+ if {$expected_joints != $::KINS(JOINTS)} {
+ set m "\ncheck_ini_items: WARNING:\n"
+ set m "$m trivkins coordinates=$tcoords specifies $len_tcoords joints\n"
+ set m "$m trivkins extrajoints=$n_extrajoints\n"
+ set m "$m trivkins totaljoints=$expected_joints\n"
+ set m "$m !!! but \[KINS\]JOINTS=$::KINS(JOINTS)\n"
+ puts stderr $m
+ }
+ } ;# foreach
+ }
+ return
+} ;# check_ini_items
+
+proc setup_kins {axes} {
+ if ![info exists ::KINS(KINEMATICS)] {
+ puts stderr "setup_kins: NO \[KINS\]KINEMATICS, trying default trivkins"
+ loadrt trivkins
+ return
+ }
+ set kins_kinematics [lindex $::KINS(KINEMATICS) end]
+ set cmd "loadrt $kins_kinematics" ;# may include parms
+ set kins_module [lindex $kins_kinematics 0]
+
+ puts stderr "setup_kins: cmd=$cmd"
+ if [catch {eval $cmd} msg] {
+ puts stderr "\nmsg=$msg\n"
+ }
+
+ # set up axis indices for known kins
+ switch $kins_module {
+ trivkins {indices_for_trivkins $axes}
+ default {
+ puts stderr "setup_kins: unknown \[KINS\]KINEMATICS=<$::KINS(KINEMATICS)>"
+ }
+ }
+} ;# setup_kins
+
+proc core_sim {axes
+ number_of_joints
+ servo_period
+ {base_period 0}
+ {emcmot motmod}
+ } {
+ # adapted as haltcl proc from core_sim.hal
+ # note: with default emcmot==motmot,
+ # thread will not be added for (default) base_pariod == 0
+
+ setup_kins $axes
+
+ if {"$emcmot" == "motmod"} {
+ if [catch {loadrt $emcmot \
+ base_period_nsec=$base_period \
+ servo_period_nsec=$servo_period \
+ num_joints=$number_of_joints} msg
+ ] {
+ # typ: too many joints attempted
+ puts stderr "\n"
+ puts stderr "core_sim: loadrt $emcmot FAIL"
+ puts stderr " msg=$msg\n"
+ exit 1
+ }
+ } else {
+ # known special case with additional parameter:
+ # unlock_joint_mask=0xNN
+ # num_extrajoints=n
+ set module [split [lindex $emcmot 0]]
+ set modname [lindex $module 0]
+ set modparm [lreplace $module 0 0]
+ if [catch {eval loadrt $modname $modparm \
+ base_period_nsec=$base_period \
+ servo_period_nsec=$servo_period \
+ num_joints=$number_of_joints} msg
+ ] {
+ puts stderr "\n"
+ puts stderr "core_sim:unhandled emcmot<$emcmot>"
+ puts stderr " modname=$modname"
+ puts stderr " modparm=$modparm"
+ puts stderr " msg=$msg\n"
+ exit 1
+ }
+ }
+
+ addf motion-command-handler servo-thread
+ addf motion-controller servo-thread
+
+ set pid_names ""
+ set mux_names ""
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ set pid_names "${pid_names},J${jno}_pid"
+ set mux_names "${mux_names},J${jno}_mux"
+ }
+ set pid_names [string trimleft $pid_names ,]
+ set mux_names [string trimleft $mux_names ,]
+ loadrt pid names=$pid_names
+ loadrt mux2 names=$mux_names
+
+ # pid components
+ # The pid comp is used as a pass-thru device (FF0=1,all other gains=0)
+ # to emulate the connectivity of a servo system
+ # (e.g., no short-circuit connection of motor-pos-cmd to motor-pos-fb)
+ foreach cname [split $pid_names ,] {
+ addf ${cname}.do-pid-calcs servo-thread
+ # FF0 == 1 for pass-thru, all others 0
+ do_setp ${cname}.FF0 1.0
+ foreach pin {Pgain Dgain Igain FF1 FF2} { do_setp ${cname}.$pin 0 }
+ }
+
+ # mux components
+ # The mux comp is used as a sample-hold to simulate a machine
+ # with encoders that measure output position when power
+ # is not applied to the motors or controllers
+ foreach cname [split $mux_names ,] {
+ addf $cname servo-thread
+ }
+
+ # signal connections:
+ net estop:loop <= iocontrol.0.user-enable-out
+ net estop:loop => iocontrol.0.emc-enable-in
+
+ net tool:prep-loop <= iocontrol.0.tool-prepare
+ net tool:prep-loop => iocontrol.0.tool-prepared
+
+ net tool:change-loop <= iocontrol.0.tool-change
+ net tool:change-loop => iocontrol.0.tool-changed
+
+ net sample:enable <= motion.motion-enabled
+
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ net sample:enable => J${jno}_mux.sel
+
+ net J${jno}:enable <= joint.$jno.amp-enable-out
+ net J${jno}:enable => J${jno}_pid.enable
+
+ net J${jno}:pos-cmd <= joint.$jno.motor-pos-cmd
+ net J${jno}:pos-cmd => J${jno}_pid.command
+
+ net J${jno}:on-pos <= J${jno}_pid.output
+ net J${jno}:on-pos => J${jno}_mux.in1 ;# pass thru when motion-enabled
+
+ net J${jno}:pos-fb <= J${jno}_mux.out
+ net J${jno}:pos-fb => J${jno}_mux.in0 ;# hold position when !motion-enabled
+ net J${jno}:pos-fb => joint.$jno.motor-pos-fb
+ }
+} ;# core_sim
+
+proc make_ddts {number_of_joints} {
+ # make vel,accel ddts and signals for all joints
+ # if xyz, make hypotenuse xy,xyz vels
+
+ set ddt_names ""
+ set ddt_ct 0
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ incr ddt_ct 2
+ set ddt_names "${ddt_names},J${jno}_vel,J${jno}_accel"
+ }
+ set ddt_names [string trimleft $ddt_names ,]
+ loadrt ddt names=$ddt_names
+ foreach cname [split $ddt_names ,] {
+ addf $cname servo-thread
+ }
+
+ # joint vel,accel signal connections:
+ set ddt_ct 0
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ incr ddt_ct 2
+ net J${jno}:pos-fb => J${jno}_vel.in ;# net presumed to exist
+ net J${jno}:vel <= J${jno}_vel.out
+ net J${jno}:vel => J${jno}_accel.in
+ net J${jno}:acc <= J${jno}_accel.out
+ }
+
+ set has_xyz 1
+ foreach letter {x y z} {
+ if ![info exists ::SIM_LIB(jointidx,$letter)] {
+ set has_xyz 0
+ break
+ }
+ }
+ if $has_xyz {
+ loadrt hypot names=hyp_xy,hyp_xyz ;# vector velocities
+ addf hyp_xy servo-thread
+ addf hyp_xyz servo-thread
+ net J$::SIM_LIB(jointidx,x):vel <= J$::SIM_LIB(jointidx,x)_vel.out
+ net J$::SIM_LIB(jointidx,x):vel => hyp_xy.in0
+ net J$::SIM_LIB(jointidx,x):vel => hyp_xyz.in0
+
+ net J$::SIM_LIB(jointidx,y):vel <= J$::SIM_LIB(jointidx,y)_vel.out
+ net J$::SIM_LIB(jointidx,y):vel => hyp_xy.in1
+ net J$::SIM_LIB(jointidx,y):vel => hyp_xyz.in1
+
+ net J$::SIM_LIB(jointidx,z):vel <= J$::SIM_LIB(jointidx,z)_vel.out
+ net J$::SIM_LIB(jointidx,z):vel => hyp_xyz.in2
+
+ net xy:vel => hyp_xy.out
+ net xyz:vel <= hyp_xyz.out
+ }
+} ;# make_ddts
+
+proc use_hal_manualtoolchange {} {
+ # adapted as haltcl proc from axis_manualtoolchange.hal
+ loadusr -W hal_manualtoolchange
+
+ # disconnect if previously connected:
+ unlinkp iocontrol.0.tool-change
+ unlinkp iocontrol.0.tool-changed
+ # remove signal with no connections:
+ delsig tool:change-loop
+
+ net tool:change <= iocontrol.0.tool-change
+ net tool:change => hal_manualtoolchange.change
+
+ net tool:changed <= hal_manualtoolchange.changed
+ net tool:changed => iocontrol.0.tool-changed
+
+ net tool:prep-number <= hal_manualtoolchange.number
+ net tool:prep-number => iocontrol.0.tool-prep-number
+} ;# use_hal_manualtoolchange
+
+proc simulated_home {number_of_joints} {
+ # uses sim_home_switch component
+ set switch_names ""
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ set switch_names "${switch_names},J${jno}_switch"
+ }
+ set switch_names [string trimleft $switch_names ,]
+ loadrt sim_home_switch names=$switch_names
+ foreach cname [split $switch_names ,] {
+ addf $cname servo-thread
+ }
+
+ for {set jno 0} {$jno < $number_of_joints} {incr jno} {
+ # add pin to pre-existing signal:
+ net J${jno}:pos-fb => J${jno}_switch.cur-pos
+
+ net J${jno}:homesw <= J${jno}_switch.home-sw
+ net J${jno}:homesw => joint.$jno.home-sw-in
+
+ # set sim_home_switch .hysteresis,.home-pos pins
+ # according to traj units and joint type
+ if ] {
+ # use component defaults
+ } else {
+ if {"[set ::JOINT_[set jno](TYPE)]" == "ANGULAR"} {
+ # use component defaults
+ } else {
+ if ![info exists ::TRAJ(LINEAR_UNITS)] {
+ # use component defaults
+ } else {
+ switch $::TRAJ(LINEAR_UNITS) {
+ in - inch - imperial {
+ do_setp J${jno}_switch.hysteresis 0.05
+ do_setp J${jno}_switch.home-pos 0.10
+ }
+ default { # use component default }
+ }
+ }
+ if { [info exists ::JOINT_[set jno](HOME_SEARCH_VEL)]
+ && [set ::JOINT_[set jno](HOME_SEARCH_VEL)] < 0} {
+ do_setp J${jno}_switch.home-pos -[getp J${jno}_switch.home-pos]
+ }
+ }
+ } ;# type
+ if [info exists ::JOINT_[set jno](HOME_USE_INDEX)] {
+ if [set ::JOINT_[set jno](HOME_USE_INDEX)] {
+ # Note: use default for joint.${jno}.index-delay-ms
+ net J${jno}:index-enable <= joint.${jno}.index-enable
+ net J${jno}:index-enable => J${jno}_switch.index-enable
+ }
+ }
+ } ;# for
+} ;# simulated_home
+
+proc sim_spindle {} {
+ # adapted as haltcl proc from sim_spindle_encoder.hal
+ # simulated spindle encoder (for spindle-synced moves)
+ loadrt sim_spindle names=sim_spindle
+ do_setp sim_spindle.scale 0.01666667
+
+ loadrt limit2 names=limit_speed
+ loadrt lowpass names=spindle_mass
+ loadrt near names=near_speed
+ loadrt scale names=rpm_rps
+
+ setp rpm_rps.gain .0167
+
+ # this limit doesn't make any sense to me:
+ do_setp limit_speed.maxv 5000.0 ;# rpm/second
+
+ # encoder reset control
+ # hook up motion controller's sync output
+ net spindle-index-enable <=> spindle.0.index-enable
+ net spindle-index-enable <=> sim_spindle.index-enable
+
+ # report our revolution count to the motion controller
+ net spindle-pos <= sim_spindle.position-fb
+ net spindle-pos => spindle.0.revs
+
+ # simulate spindle mass
+ do_setp spindle_mass.gain .07
+
+ # spindle speed control
+ net spindle-speed-cmd <= spindle.0.speed-out
+ net spindle-speed-cmd => limit_speed.in
+ net spindle-speed-cmd => near_speed.in1
+
+ net spindle-speed-limited <= limit_speed.out
+ net spindle-speed-limited => sim_spindle.velocity-cmd
+ net spindle-speed-limited => spindle_mass.in
+
+ # for spindle velocity estimate
+ net spindle-rpm-filtered <= spindle_mass.out
+ net spindle-rpm-filtered rpm_rps.in
+ net spindle-rps-filtered rpm_rps.out spindle.0.speed-in
+ net spindle-rpm-filtered => near_speed.in2
+
+ # at-speed detection
+ do_setp near_speed.scale 1.1
+ do_setp near_speed.difference 10
+
+ net spindle-at-speed <= near_speed.out
+ net spindle-at-speed => spindle.0.at-speed
+
+ net spindle-orient <= spindle.0.orient
+ net spindle-orient <= spindle.0.is-oriented
+
+ addf limit_speed servo-thread
+ addf spindle_mass servo-thread
+ addf rpm_rps servo-thread
+ addf near_speed servo-thread
+ addf sim_spindle servo-thread
+} ;# sim_spindle
+
+proc save_hal_cmds {savefilename {options ""} } {
+ set tmpfile /tmp/save_hal_cmds_tmp
+ set date [clock format [clock seconds]]
+ set script [info script]
+ set save_arg all ;# suffices if only basic_sim in use
+ if {[llength $::HAL(HALFILE)] > 1} {
+ set save_arg allu ;# do *all* unconnected pins including
+ ;# pins from other HALFILEs
+ }
+ set fd [open $savefilename w] ;# overwrite any existing file
+ puts $fd "# $date
+#
+# This file: $savefilename
+# Created by: $script
+# With options: $::argv
+# From inifile: $::env(INI_FILE_NAME)
+# Halfiles: $::HAL(HALFILE)
+#
+# This file contains the hal commands produced by [file tail $script]
+# (and any hal commands executed prior to its execution).
+# ------------------------------------------------------------------
+# To use $savefilename in the original inifile (or a copy of it),
+# edit to change:
+# \[HAL\]
+# HALFILE = LIB:basic_sim.tcl parameters
+# to:
+# \[HAL\]
+# HALFILE = $savefilename
+#
+# Notes:
+# 1) Inifile Variables substitutions specified in the inifile
+# and interpreted by halcmd are automatically substituted
+# in the created halfile ($savefilename).
+# 2) Input pins connected to a signal with no writer are
+# not included in the setp listings herein so must be added
+# manually
+#
+"
+ if {[lsearch $options use_hal_manualtoolchange] >= 0} {
+ puts $fd "# user space components"
+ puts $fd "loadusr -W hal_manualtoolchange"
+ puts $fd ""
+ }
+
+ hal save $save_arg $tmpfile
+
+ set ftmp [open $tmpfile r]
+ set gave_msg 0
+ set setp_fmt "%-3s %-30s %s"
+ while {![eof $ftmp]} {
+ gets $ftmp line
+ if {([string first "unconnected pin values" $line] >0) && !$gave_msg} {
+ set gave_msg 1
+ puts $fd "# Note: ALL unconnected pins follow"
+ puts $fd "# (includes pins using default with no explicit setp command)"
+ } else {
+ scan $line "%s %s %s" cmd arg1 remainder
+ switch $cmd {
+ setp {puts $fd [format $setp_fmt $cmd $arg1 $remainder]}
+ loadrt {
+ if { [string first tpmod [list $line]] >= 0
+ || [string first homemod [list $line]] >= 0
+ } {
+ puts $fd "#preloaded module: $line"
+ } else {
+ puts $fd $line
+ }
+ }
+ default {puts $fd $line}
+ }
+ }
+ } ;# while
+ close $ftmp
+ file delete $tmpfile
+ if {("$save_arg" != "allu") && [info exists ::SIM_LIB(setp_list)]} {
+ puts $fd "# setp commands for unconnected input pins"
+ foreach {pname value} $::SIM_LIB(setp_list) {
+ puts $fd [format $setp_fmt setp $pname $value]
+ }
+ }
+ close $fd
+} ;# save_hal_cmds
+
+proc do_setp {pname value} {
+ setp $pname $value
+ lappend ::SIM_LIB(setp_list) $pname $value
+} ;# do_setp
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_rdelta.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_rdelta.hal
new file mode 100755
index 0000000..efe3b6b
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_rdelta.hal
@@ -0,0 +1,42 @@
+loadrt [KINS]KINEMATICS
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
+
+loadusr -W rotarydelta
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net J0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb
+net J1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb
+net J2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb
+
+net J3pos joint.3.motor-pos-cmd => joint.3.motor-pos-fb
+net J4pos joint.4.motor-pos-cmd => joint.4.motor-pos-fb
+net J5pos joint.5.motor-pos-cmd => joint.5.motor-pos-fb
+net J6pos joint.6.motor-pos-cmd => joint.6.motor-pos-fb
+net J7pos joint.7.motor-pos-cmd => joint.7.motor-pos-fb
+net J8pos joint.8.motor-pos-cmd => joint.8.motor-pos-fb
+
+net J0cmd joint.0.pos-cmd => rotarydelta.joint0
+net J1cmd joint.1.pos-cmd => rotarydelta.joint1
+net J2cmd joint.2.pos-cmd => rotarydelta.joint2
+
+net pfr rotarydeltakins.platformradius => rotarydelta.pfr
+net tl rotarydeltakins.thighlength => rotarydelta.tl
+net sl rotarydeltakins.shinlength => rotarydelta.sl
+net fr rotarydeltakins.footradius => rotarydelta.fr
+
+sets pfr 10
+sets tl 10
+sets sl 18
+sets fr 5
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change iocontrol.0.tool-changed
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_spindle_encoder.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_spindle_encoder.hal
new file mode 100755
index 0000000..e0fcde6
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/sim_spindle_encoder.hal
@@ -0,0 +1,45 @@
+# simulated spindle encoder (for spindle-synced moves)
+loadrt sim_spindle names=sim_spindle
+setp sim_spindle.scale 0.01666667
+loadrt limit2 names=limit_speed
+loadrt lowpass names=spindle_mass
+loadrt near names=near_speed
+loadrt scale names=rpm_rps
+
+setp rpm_rps.gain .0167
+
+# this limit doesn't make any sense to me:
+setp limit_speed.maxv 5000.0 # rpm/second
+
+# encoder reset control
+# hook up motion controller's sync output
+net spindle-index-enable spindle.0.index-enable <=> sim_spindle.index-enable
+
+# report our revolution count to the motion controller
+net spindle-pos sim_spindle.position-fb => spindle.0.revs
+
+# simulate spindle mass
+setp spindle_mass.gain .07
+
+# spindle speed control
+net spindle-speed-cmd spindle.0.speed-out => limit_speed.in
+net spindle-speed-limited limit_speed.out => sim_spindle.velocity-cmd spindle_mass.in
+
+# for spindle velocity estimate
+net spindle-rpm-filtered spindle_mass.out near_speed.in2
+net spindle-rpm-filtered rpm_rps.in
+net spindle-rps-filtered rpm_rps.out spindle.0.speed-in
+
+# at-speed detection
+setp near_speed.scale 1.1
+setp near_speed.difference 10
+
+net spindle-speed-cmd => near_speed.in1
+net spindle-at-speed near_speed.out spindle.0.at-speed
+
+addf limit_speed servo-thread
+addf spindle_mass servo-thread
+addf rpm_rps servo-thread
+addf near_speed servo-thread
+addf sim_spindle servo-thread
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated-gantry-home.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated-gantry-home.hal
new file mode 100755
index 0000000..dd31c9e
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated-gantry-home.hal
@@ -0,0 +1,47 @@
+
+loadrt comp names=comp_j0,comp_j1,comp_j2,comp_j3
+loadrt or2 names=or_homesws
+
+# Joint 0 = X axis, home switch is on negative end
+# Joint 1 = Y1 axis, home switch is on negative end
+# Joint 2 = Z axis, home switch is on positive end
+# Joint 3 = Y2 axis, home switch is on negative end
+net J0homeswpos => comp_j0.in1
+net J1homeswpos => comp_j1.in1
+net J2homeswpos => comp_j2.in0
+net J3homeswpos => comp_j3.in1
+
+sets J0homeswpos -0.1
+sets J1homeswpos -0.1
+sets J2homeswpos 0.1
+sets J3homeswpos -0.1
+
+net J0pos => comp_j0.in0
+net J1pos => comp_j1.in0
+net J2pos => comp_j2.in1
+net J3pos => comp_j3.in0
+
+setp comp_j0.hyst .02
+setp comp_j1.hyst .02
+setp comp_j2.hyst .02
+setp comp_j3.hyst .02
+
+# the X and Z joints share a home switch
+# the Y joints each have their own home switches
+net J0homesw <= comp_j0.out
+net J1homesw <= comp_j1.out => joint.1.home-sw-in
+net J2homesw <= comp_j2.out
+net J3homesw <= comp_j3.out => joint.3.home-sw-in
+
+net J0homesw => or_homesws.in0
+net J2homesw => or_homesws.in1
+net J0.J1homesw or_homesws.out => joint.0.home-sw-in joint.2.home-sw-in
+
+
+addf comp_j0 servo-thread
+addf comp_j1 servo-thread
+addf comp_j2 servo-thread
+addf comp_j3 servo-thread
+
+addf or_homesws servo-thread
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_home.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_home.hal
new file mode 100755
index 0000000..3422569
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_home.hal
@@ -0,0 +1,32 @@
+loadrt or2 names=or2_0
+loadrt comp names=comp_x,comp_y,comp_z
+
+net Xhomeswpos => comp_x.in0
+net Yhomeswpos => comp_y.in0
+net Zhomeswpos => comp_z.in0
+
+sets Xhomeswpos 1
+sets Yhomeswpos .5
+sets Zhomeswpos 2
+
+net Xpos => comp_x.in1
+net Ypos => comp_y.in1
+net Zpos => comp_z.in1
+
+setp comp_x.hyst .02
+setp comp_y.hyst .02
+setp comp_z.hyst .02
+
+net Xhomesw <= comp_x.out
+net Yhomesw <= comp_y.out => joint.1.home-sw-in
+net Zhomesw <= comp_z.out
+
+net Xhomesw => or2_0.in0
+net Zhomesw => or2_0.in1
+net XZhomesw or2_0.out => joint.0.home-sw-in joint.2.home-sw-in
+
+addf comp_x servo-thread
+addf comp_y servo-thread
+addf comp_z servo-thread
+
+addf or2_0 servo-thread
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_limits.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_limits.hal
new file mode 100755
index 0000000..070051f
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/simulated_limits.hal
@@ -0,0 +1,76 @@
+# HAL config file to simulate limit switches using window comparators
+#
+# first install nine comparators
+loadrt wcomp names=wcomp_xmin,wcomp_xmax,wcomp_xhome,wcomp_ymin,wcomp_ymax,wcomp_yhome,wcomp_zmin,wcomp_zmax,wcomp_zhome
+
+# add comparators to servo thread so they will be evaluated
+# every servo period
+addf wcomp_xmin servo-thread
+addf wcomp_xmax servo-thread
+addf wcomp_xhome servo-thread
+addf wcomp_ymin servo-thread
+addf wcomp_ymax servo-thread
+addf wcomp_yhome servo-thread
+addf wcomp_zmin servo-thread
+addf wcomp_zmax servo-thread
+addf wcomp_zhome servo-thread
+
+# connect position feedback from step generators
+# to window comparators
+net Xpos-fb => wcomp_xmin.in
+net Xpos-fb => wcomp_xmax.in
+net Xpos-fb => wcomp_xhome.in
+net Ypos-fb => wcomp_ymin.in
+net Ypos-fb => wcomp_ymax.in
+net Ypos-fb => wcomp_yhome.in
+net Zpos-fb => wcomp_zmin.in
+net Zpos-fb => wcomp_zmax.in
+net Zpos-fb => wcomp_zhome.in
+
+# connect simulated switch outputs to motion controller
+net Xminlim wcomp_xmin.out => joint.0.neg-lim-sw-in
+net Xmaxlim wcomp_xmax.out => joint.0.pos-lim-sw-in
+net Xhome wcomp_xhome.out => joint.0.home-sw-in
+
+net Yminlim wcomp_ymin.out => joint.1.neg-lim-sw-in
+net Ymaxlim wcomp_ymax.out => joint.1.pos-lim-sw-in
+net Yhome wcomp_yhome.out => joint.1.home-sw-in
+
+net Zminlim wcomp_zmin.out => joint.2.neg-lim-sw-in
+net Zmaxlim wcomp_zmax.out => joint.2.pos-lim-sw-in
+net Zhome wcomp_zhome.out => joint.2.home-sw-in
+
+# configure the points at which the simulated switches trip
+# X axis first
+# set min limit switch to trip at -10.2, release at -1000
+setp wcomp_xmin.max -10.2
+setp wcomp_xmin.min -1000
+# set max limit switch to trip at +10.2, release at +10.21
+setp wcomp_xmax.min 10.20
+setp wcomp_xmax.max 10.21
+# set home switch to trip at 9.5 and release at 9.75
+setp wcomp_xhome.min 9.5
+setp wcomp_xhome.max 9.75
+
+# Y axis
+# set min limit switch to trip at -10.2, release at -1000
+setp wcomp_ymin.max -10.2
+setp wcomp_ymin.min -1000
+# set max limit switch to trip at +10.2, release at +10.21
+setp wcomp_ymax.min 10.20
+setp wcomp_ymax.max 10.21
+# set home switch to trip at 9.5 and release at 9.75
+setp wcomp_yhome.min 9.5
+setp wcomp_yhome.max 9.75
+
+# Z axis
+# set min limit switch to trip at -2.1, release at -1000
+setp wcomp_zmin.max -2.1
+setp wcomp_zmin.min -1000
+# set max limit switch to trip at +4.05,release at +5
+setp wcomp_zmax.min 4.05
+setp wcomp_zmax.max 5
+# set home switch to trip at 3.9 and release at 4.1
+setp wcomp_zhome.min 3.9
+setp wcomp_zhome.max 4.1
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/tripodsim.hal b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/tripodsim.hal
new file mode 100755
index 0000000..2b29487
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/tripodsim.hal
@@ -0,0 +1,55 @@
+# core HAL config file for simulation
+
+# first load all the RT modules that will be needed
+# kinematics
+loadrt [KINS]KINEMATICS
+setp tripodkins.Bx 10
+setp tripodkins.Cx 5
+setp tripodkins.Cy 7.071
+
+# motion controller, get name and thread periods from INI file
+loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD
+# 6 differentiators (for velocity and accel sigs)
+loadrt ddt names=ddt_j0,ddt_j1,ddt_j2,ddt_j0v,ddt_j1v,ddt_j2v
+
+# add motion controller functions to servo thread
+addf motion-command-handler servo-thread
+addf motion-controller servo-thread
+# link the differentiator functions into the code
+addf ddt_j0 servo-thread
+addf ddt_j0v servo-thread
+addf ddt_j1 servo-thread
+addf ddt_j1v servo-thread
+addf ddt_j2 servo-thread
+addf ddt_j2v servo-thread
+
+# create HAL signals for position commands from motion module
+# loop position commands back to motion module feedback
+net J0pos joint.0.motor-pos-cmd => joint.0.motor-pos-fb ddt_j0.in
+net J1pos joint.1.motor-pos-cmd => joint.1.motor-pos-fb ddt_j1.in
+net J2pos joint.2.motor-pos-cmd => joint.2.motor-pos-fb ddt_j2.in
+
+# send the position commands thru differentiators to
+# generate velocity and accel signals
+net J0vel ddt_j0.out => ddt_j0v.in
+net J0acc <= ddt_j0v.out
+net J1vel ddt_j1.out => ddt_j1v.in
+net J1acc <= ddt_j1v.out
+net J2vel ddt_j2.out => ddt_j2v.in
+net J2acc <= ddt_j2v.out
+
+# estop loopback
+net estop-loop iocontrol.0.user-enable-out => iocontrol.0.emc-enable-in
+
+# create signals for tool loading loopback
+net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
+net tool-change-loop iocontrol.0.tool-change => iocontrol.0.tool-changed
+
+# amp control
+net J0ena <= joint.0.amp-enable-out
+net J1ena <= joint.1.amp-enable-out
+net J2ena <= joint.2.amp-enable-out
+
+net J0flt => joint.0.amp-fault-in
+net J1flt => joint.1.amp-fault-in
+net J2flt => joint.2.amp-fault-in
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/util_lib.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/util_lib.tcl
new file mode 100755
index 0000000..6a0c731
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/util_lib.tcl
@@ -0,0 +1,62 @@
+# util_lib.tcl -- utilities
+
+set ::util_lib_quiet 0
+# ::tp is the namespace for [HAL]TWOPASS processing
+# quiet irrelevant messages in pass0
+if { [namespace exists ::tp] \
+ && ([::tp::passnumber] == 0) } { set ::util_lib_quiet 1 }
+
+proc show_context {} {
+ if { $::util_lib_quiet } { return }
+ set pname show_context
+ puts "$pname: argv0=$::argv0"
+ puts "$pname: argv=$::argv"
+ foreach arg $::argv {
+ puts "$pname: arg=$arg"
+ }
+ puts "$pname: INI_FILE_NAME=$::env(INI_FILE_NAME)"
+} ;# show_context
+
+proc show_ini {} {
+ if { $::util_lib_quiet } { return }
+ set vars [uplevel #0 {info vars}]
+ set exclude_list {TP auto_index tcl_platform env}
+ foreach v $vars {
+ if { [lsearch $exclude_list $v] >= 0 } {continue}
+ set vg ::$v
+ if [array exists $vg] {
+ parray $vg
+ }
+ }
+} ;# show_ini_info
+
+proc show_env {} {
+ parray ::env
+} ;# show_env
+
+proc joint_number_for_axis {axis_letter} {
+ # For JOINTS_AXES:
+ # Apply rule for known kins with KINEMATICS_IDENTITY
+ set kinematics [lindex $::env(KINS_KINEMATICS) 0]
+ set coordinates $::env(TRAJ_COORDINATES)
+ if {[ string first " " $coordinates] < 0} {
+ set coordinates [split $coordinates ""]
+ }
+ set coordinates [string toupper $coordinates]
+ set axis_letter [string toupper $axis_letter]
+
+ # rules for known kinematics types
+ switch $kinematics {
+ trivkins {set joint_number [lsearch $coordinates $axis_letter]}
+ default {return -code error \
+ "joint_number_for_axis: <$axis_letter> unavailable for kinematics:\
+<$::env(KINS_KINEMATICS)>"
+ }
+ }
+ #puts stderr "kins=$kinematics coords=$coordinates a=$axis_letter j=$joint_number"
+ if { $joint_number < 0} {
+ return -code error \
+ "joint_number_for_axis <$axis_letter> not in $::env(TRAJ_COORDINATES)"
+ }
+ return $joint_number
+} ;# joint_number_for_axis
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/var_show.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/var_show.tcl
new file mode 100755
index 0000000..8ee7561
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/var_show.tcl
@@ -0,0 +1,14 @@
+# var_show.tcl
+
+# this halfile can be used to show context and
+# INI variable arrays available to tcl halfiles
+# example: [HAL]LIB:var_show.tcl arg1 arg2
+
+#begin-----------------------------------------------------------------
+source [file join $::env(HALLIB_DIR) util_lib.tcl]
+
+show_ini
+show_context
+
+puts ::argv=$::argv
+puts ::arglen=[llength $::argv]
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/wheeljogpins.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/wheeljogpins.tcl
new file mode 100755
index 0000000..18ea580
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/wheeljogpins.tcl
@@ -0,0 +1,20 @@
+# tcl file to enable jog pins
+# for all axis letters
+# for up to 9 joints
+# errors are ignored
+# scale defaults to 1, use ::argv otherwise for all
+
+set scalevalue 1 ;# default
+if {[llength $::argv] == 1} {
+ set scalevalue $::argv
+}
+catch {
+ foreach l {x y z a b c u v w} {
+ setp axis.$l.jog-enable 1
+ setp axis.$l.jog-scale $::scalevalue
+ }
+ for {set i 0} {$i < 9} {incr i} {
+ setp joint.$i.jog-enable 1
+ setp joint.$i.jog-scale $::scalevalue
+ }
+}
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout1.cfg b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout1.cfg
new file mode 100755
index 0000000..6a77415
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout1.cfg
@@ -0,0 +1,17 @@
+[XHC-HB04]
+BUTTON=01:button-stop
+BUTTON=02:button-start-pause
+BUTTON=03:button-rewind
+BUTTON=04:button-safe-z
+BUTTON=05:button-home
+BUTTON=06:button-x2
+BUTTON=07:button-y2
+BUTTON=08:button-probe-z
+BUTTON=09:button-x0
+BUTTON=0A:button-y0
+BUTTON=0B:button-z0
+BUTTON=0C:button-goto-zero
+BUTTON=0D:button-step
+BUTTON=0E:button-mode
+BUTTON=0F:button-spindle
+BUTTON=17:button-reset
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout2.cfg b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout2.cfg
new file mode 100755
index 0000000..d844658
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04-layout2.cfg
@@ -0,0 +1,19 @@
+[XHC-HB04]
+BUTTON=01:button-goto-zero
+BUTTON=02:button-start-pause
+BUTTON=03:button-rewind
+BUTTON=04:button-probe-z
+BUTTON=05:button-macro-3
+BUTTON=06:button-half
+BUTTON=07:button-zero
+BUTTON=08:button-safe-z
+BUTTON=09:button-home
+BUTTON=0A:button-macro-1
+BUTTON=0B:button-macro-2
+BUTTON=0C:button-spindle
+BUTTON=0D:button-step
+BUTTON=0E:button-mode
+BUTTON=0F:button-macro-6
+BUTTON=10:button-macro-7
+BUTTON=16:button-stop
+BUTTON=17:button-reset
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04.tcl b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04.tcl
new file mode 100755
index 0000000..5232eb9
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/hallib/xhc-hb04.tcl
@@ -0,0 +1,594 @@
+# xhc-hb04.tcl: HALFILE for xhc-hb04 pendant
+
+# library procs:
+source [file join $::env(HALLIB_DIR) hal_procs_lib.tcl]
+source [file join $::env(HALLIB_DIR) util_lib.tcl]
+
+# Usage:
+# In INI file, include:
+# [HAL]
+# HALFILE = existing halfiles
+# ...
+# HALFILE = xhc-hb04.tcl
+#
+# [XHC_HB04_CONFIG]
+# layout = 2 (required: 1|2 are supported)
+# coords = x y z a (up to 4 unique letters from x y z a b c u v w)
+# coefs = 1 1 1 1 (optional, filter coefs, 0 < coef < 1, not usually reqd)
+# scales = 1 1 1 1 (optional)
+# mpg_accels = 50 75 30 75 (optional, less than axis max accel)
+# threadname = servo-thread (optional)
+# sequence = 1 (optional: 1|2)
+# jogmode = normal (optional: normal|vnormal)
+# require_pendant = yes (optional: yes|no)
+# inch_or_mm = in (optional: in|mm, default is mm)
+
+# [XHC_HB04_BUTTONS]
+# name = pin (connect button to hal pin)
+# name = "" (no connect button)
+# special cases:
+# start-pause = std_start_pause (for usual behavior)
+# step = xhc-hb04.stepsize-up (for usual behavior)
+# (see INI files for more exanples)
+
+# Notes:
+# 1) the 'start-pause' pin can be set to "std_start_pause" to
+# implement default behavior
+# 2) the 'step' pin is normally connected to xhc-hb04.stepsize-up
+# 3) non-root access to the usb device requires an additional
+# udev rule. Typically, create /etc/udev/rules.d/90-xhc.rules:
+# SYSFS{idProduct}=="eb70", SYSFS{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+# or (for ubuntu12 and up):
+# ATTR{idProduct}=="eb70", ATTR{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
+# 4) For jogmode==vnormal (man motion -- see joint.N.jog-vel-mode),
+# the max movement is limited by the machine velocity and acceleration limits
+# such that delta_x = 0.5 * vmax**2/accelmx
+# so for sim example:
+# inch: vmax= 1.2 accelmax= 20 delta_x=0.036
+# mm: vmax=30.48 acclemax=508 delta_x=0.9144
+# Typically:
+# (-s1) sequence 1 (1,10,100,1000) is ok for mm-based machines
+# (-s2) sequence 2 (1,5,10,20) is ok for inch-based machines
+#
+# 5) updated for joints_axes: support only configs with known kins
+# and they must be KINEMATICS_IDENTITY (trivkins)
+# a) connect axis.L.jog-counts to joint.N.jog-counts
+# axis.L.jog-scale to joint.L.jog-scale
+# c) use [AXIS_N]MAX_ACCELERATION for both axis.L, joint.N
+
+#-----------------------------------------------------------------------
+# Copyright: 2014-16
+# Author: Dewey Garrett
+#
+# 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.
+#-----------------------------------------------------------------------
+
+proc is_uniq {list_name} {
+ set tmp(xxxxxxxx) "" ;# make an array first
+ foreach item $list_name {
+ if {[array names tmp $item] == $item} {
+ return 0 ;# not unique
+ }
+ set tmp($item) $item
+ }
+ return 1 ;# unique
+} ;# is_uniq
+
+proc connect_pins {} {
+ foreach bname [lsort [array names ::XHC_HB04_BUTTONS]] {
+ set thepin $::XHC_HB04_BUTTONS($bname)
+ set thepin [lindex $thepin 0]
+
+ if {"$thepin" == "\"\""} {
+ #puts stderr "$::progname: no pin defined for <$bname>"
+ continue
+ }
+ # this pin is can specify std behavior
+ if { ([string tolower $bname] == "start-pause")
+ && ([string tolower $thepin] == "std_start_pause")
+ } {
+ std_start_pause_button
+ puts stderr "$::progname: using std_start_pause_button"
+ continue
+ }
+ # these are warnings in the INI file examples but aren't real pins
+ if {[string tolower "$thepin"] == "caution"} {
+ puts stderr "$::progname: skipping button $bname marked <$thepin>"
+ continue
+ }
+ set fullbname xhc-hb04.button-$bname
+ if !$::xhc_hb04_quiet {
+ if ![pin_exists $fullbname] {
+ puts stderr "$::progname: !!! <$fullbname> pin does not exist, continuing"
+ continue
+ }
+ if ![pin_exists $thepin] {
+ puts stderr "$::progname: !!! <$thepin> target pin does not exist, continuing"
+ continue
+ }
+ }
+
+ makenet pendant:$bname <= $fullbname => $thepin
+ }
+} ;# connect_pins
+
+proc wheel_setup {jogmode} {
+
+ if [info exists ::XHC_HB04_CONFIG(mpg_accels)] {
+ set idx 0
+ foreach g $::XHC_HB04_CONFIG(mpg_accels) {
+ set g1 $g
+ if {$g < 0} {
+ set g [expr -1 * $g]
+ puts stderr "$::progname: mpg_accel #$idx must be positive was:$g1, is:$g"
+ }
+ set ::XHC_HB04_CONFIG(accel,$idx) [format %f $g] ;# ensure floatingpt
+ incr idx
+ }
+ }
+
+ # defaults if not in INI file:
+ set ::XHC_HB04_CONFIG(coef,0) 1.0
+ set ::XHC_HB04_CONFIG(coef,1) 1.0
+ set ::XHC_HB04_CONFIG(coef,2) 1.0
+ set ::XHC_HB04_CONFIG(coef,3) 1.0
+ if [info exists ::XHC_HB04_CONFIG(coefs)] {
+ set idx 0
+ foreach g $::XHC_HB04_CONFIG(coefs) {
+ set g1 $g
+ if {$g < 0} {
+ set g [expr -1 * $g]
+ puts stderr "$::progname: coef #$idx must be positive was:$g1, is:$g"
+ }
+ if {$g > 1} {
+ set g .5
+ puts stderr "$::progname: coef #$idx must < 1 coef was:$g1, is:$g"
+ }
+ set ::XHC_HB04_CONFIG(coef,$idx) $g
+ incr idx
+ }
+ }
+ # defaults if not in INI file:
+ set ::XHC_HB04_CONFIG(scale,0) 1.0
+ set ::XHC_HB04_CONFIG(scale,1) 1.0
+ set ::XHC_HB04_CONFIG(scale,2) 1.0
+ set ::XHC_HB04_CONFIG(scale,3) 1.0
+ if [info exists ::XHC_HB04_CONFIG(scales)] {
+ set idx 0
+ foreach g $::XHC_HB04_CONFIG(scales) {
+ set ::XHC_HB04_CONFIG(scale,$idx) $g
+ incr idx
+ }
+ }
+
+ # to support fractional scales:
+ # divide the xhc-hb04.jog.scale by $kvalue
+ # and
+ # multiply the pendant_util.scale$idx by $kvalue
+ # to manipulate the integer (s32) joint.N.jog-counts
+
+ set kvalue 100.0; # allow fractional scales (.1, .01)
+ # Note: larger values not advised as the
+ # jog-counts are type s32 (~ +/-2e9)
+ setp pendant_util.k $kvalue
+
+ makenet pendant:jog-prescale <= xhc-hb04.jog.scale
+ makenet pendant:jog-prescale => pendant_util.divide-by-k-in
+
+ makenet pendant:jog-scale <= pendant_util.divide-by-k-out
+ # pendant:jog-scale connects to each:
+ # and axis.$coord.jog-scale
+ # joint.$jnum.jog-scale (if applicable)
+
+ makenet pendant:wheel-counts <= xhc-hb04.jog.counts
+ makenet pendant:wheel-counts-neg <= xhc-hb04.jog.counts-neg
+
+ set anames {x y z a}
+ set available_idx {0 1 2 3}
+ # The pendant has fixed labels and displays for letters: x y z a
+ # and xhc-hb04.cc hardcodes pin names for these letters: x y z a
+ # Herein: Use label corresponding to coord if possible.
+ # Otherwise, use next available label. When this occurs,
+ # pin names will be a little confusing but the signal names will
+ # align correctly.
+ #
+ # With this method, any coord (xyzabcuvw) can be controlled by
+ # the wheel (providing it exists)
+ #
+ set unassigned_coords {}
+
+ foreach coord $::XHC_HB04_CONFIG(coords) {
+ set i [lsearch $anames $coord]
+ if {$i >= 0} {
+ set i [lsearch $available_idx $i]
+ # use idx corresponding to coord
+ set use_idx($coord) [lindex $available_idx $i]
+ set available_idx [lreplace $available_idx $i $i]
+ } else {
+ lappend unassigned_coords $coord
+ }
+ }
+ foreach coord $unassigned_coords {
+ # use next available_idx
+ set use_idx($coord) [lindex $available_idx 0]
+ set available_idx [lreplace $available_idx 0 0]
+ }
+
+ set mapmsg ""
+ foreach coord $::XHC_HB04_CONFIG(coords) {
+ if [catch {set jnum [joint_number_for_axis $coord]} msg] {
+ puts stderr "$::progname: $msg"
+ set has_jnum 0
+ } else {
+ set has_jnum 1
+ }
+ set use_lbl($coord) [lindex $anames $use_idx($coord)]
+ set idx $use_idx($coord)
+ if {"$use_lbl($coord)" != "$coord"} {
+ set mapmsg "$mapmsg\
+ coord: $coord is mapped to pendant switch/display:\
+ $use_lbl($coord) index: $idx\n"
+ }
+ setp pendant_util.coef$idx $::XHC_HB04_CONFIG(coef,$idx)
+ setp pendant_util.scale$idx [expr $kvalue * $::XHC_HB04_CONFIG(scale,$idx)]
+
+ set acoord [lindex $anames $idx]
+ # accommodate existing signames for halui outpins:
+ makenet [existing_outpin_signame halui.axis.$coord.pos-feedback pendant:pos-$coord] \
+ <= halui.axis.$coord.pos-feedback \
+ => xhc-hb04.$acoord.pos-absolute
+
+ makenet [existing_outpin_signame halui.axis.$coord.pos-relative pendant:pos-rel-$coord] \
+ <= halui.axis.$coord.pos-relative \
+ => xhc-hb04.$acoord.pos-relative
+
+ makenet pendant:jog-scale => axis.$coord.jog-scale
+
+ makenet pendant:wheel-counts => pendant_util.in$idx
+ makenet pendant:wheel-counts-$coord-filtered <= pendant_util.out$idx \
+ => axis.$coord.jog-counts
+
+
+ set COORD [string toupper $coord]
+ makenet pendant:jog-$coord <= xhc-hb04.jog.enable-$acoord \
+ => axis.$coord.jog-enable
+ switch $jogmode {
+ vnormal {
+ setp axis.$coord.jog-vel-mode 1
+ }
+ }
+
+ set afraction 1.0 ;# default
+ # Only calculate an afraction IF we have specified mpg_accels in the INI file
+ if [info exists ::XHC_HB04_CONFIG(mpg_accels)] {
+ if [catch {
+ set afraction [expr $::XHC_HB04_CONFIG(accel,$idx)\
+ /[set ::AXIS_[set COORD](MAX_ACCELERATION)] ]
+ } msg] {
+ err_exit "<$msg>\n\nMissing INI setting: \[AXIS_$COORD\]MAX_ACCELERATION"
+ }
+ }
+ setp axis.$coord.jog-accel-fraction $afraction
+
+ # connect for joint pins if known (trivkins)
+ if $has_jnum {
+ if ![pin_exists joint.$jnum.jog-scale] {
+ err_exit "Not configured for coords = $::XHC_HB04_CONFIG(coords),\
+ missing joint.$jnum.* pins"
+ }
+ makenet pendant:jog-scale => joint.$jnum.jog-scale
+ makenet pendant:wheel-counts-$coord-filtered => joint.$jnum.jog-counts
+ if [catch {set std_accel [set ::JOINT_[set jnum](MAX_ACCELERATION)]} msg] {
+ err_exit "Error: missing \[JOINT_[set jnum]\]MAX_ACCELERATION"
+ }
+ if { [set ::JOINT_[set jnum](MAX_ACCELERATION)]
+ != [set ::AXIS_[set COORD](MAX_ACCELERATION)] } {
+ puts stderr "$::progname: Warning accel values differ:"
+ puts stderr " \[JOINT_[set jnum]\]MAX_ACCELERATION=[set ::JOINT_[set jnum](MAX_ACCELERATION)]"
+ puts stderr " \[AXIS_[set COORD]\]MAX_ACCELERATION=[set ::AXIS_[set COORD](MAX_ACCELERATION)]"
+ }
+ makenet pendant:jog-$coord => joint.$jnum.jog-enable
+
+ set jfraction 1.0 ;# default
+ if [info exists ::XHC_HB04_CONFIG(mpg_accels)] {
+ if [catch {
+ set jfraction [expr $::XHC_HB04_CONFIG(accel,$idx)\
+ /[set ::JOINT_[set jnum](MAX_ACCELERATION)] ]
+ } msg] {
+ err_exit "<$msg>\n\nMissing INI setting: \[JOINT_$jnum\]MAX_ACCELERATION"
+ }
+ }
+ setp joint.$jnum.jog-accel-fraction $jfraction
+
+ switch $jogmode {
+ vnormal {
+ setp joint.$jnum.jog-vel-mode 1
+ }
+ }
+
+ }
+ } ;# for coord
+ if {"$mapmsg" != ""} {
+ puts "\n$::progname:\n$mapmsg"
+ }
+
+ setp halui.feed-override.scale 0.01
+ makenet pendant:wheel-counts => halui.feed-override.counts
+
+ setp halui.spindle.0.override.scale 0.01
+ makenet pendant:wheel-counts => halui.spindle.0.override.counts
+
+ makenet pendant:feed-override-enable => halui.feed-override.count-enable \
+ <= xhc-hb04.jog.enable-feed-override
+
+ makenet pendant:spindle-override-enable => halui.spindle.0.override.count-enable \
+ <= xhc-hb04.jog.enable-spindle-override
+
+
+ # accommodate existing signames for motion outpins
+ makenet [existing_outpin_signame motion.current-vel pendant:feed-value] \
+ <= motion.current-vel \
+ => xhc-hb04.feed-value
+
+ makenet [existing_outpin_signame spindle.0.speed-out-rps-abs pendant:spindle-rps] \
+ <= spindle.0.speed-out-rps-abs \
+ => xhc-hb04.spindle-rps
+
+ # accommodate existing signames for halui outpins:
+ makenet [existing_outpin_signame halui.max-velocity.value pendant:jog-speed] \
+ <= halui.max-velocity.value
+
+ makenet [existing_outpin_signame halui.feed-overide.value pendant:feed-override] \
+ <= halui.feed-override.value \
+ => xhc-hb04.feed-override
+
+ makenet [existing_outpin_signame halui.spindle.0.override.value pendant:spindle-override] \
+ <= halui.spindle.0.override.value \
+ => xhc-hb04.spindle-override
+
+} ;# wheel_setup
+
+proc existing_outpin_signame {pinname newsigname} {
+ # return existing outpin signame if it exists, else newsigname
+ set answer [is_connected $pinname signame]
+ switch $answer {
+ not_connected {return $newsigname}
+ is_output {puts "$::progname: Using existing outpin signame: $signame"
+ return "$signame"
+ }
+ default {return -code error \
+ "existing_outpin_signame:UNEXPECTED $answer"
+ }
+ }
+} ;# existing_outpin_signame
+
+proc std_start_pause_button {} {
+ # hardcoded setup for button-start-pause
+ makenet pendant:start-or-pause <= xhc-hb04.button-start-pause \
+ => pendant_util.start-or-pause
+
+ makenet pendant:program-resume <= pendant_util.resume \
+ => halui.program.resume
+ makenet pendant:program-pause <= pendant_util.pause \
+ => halui.program.pause
+ makenet pendant:program-run <= pendant_util.run \
+ => halui.program.run \
+ => halui.mode.auto
+
+ # accommodate existing signames for halui outpins:
+ makenet [existing_outpin_signame halui.program.is-idle pendant:is-idle] \
+ <= halui.program.is-idle \
+ => pendant_util.is-idle
+
+ makenet [existing_outpin_signame halui.program.is-paused pendant:is-paused] \
+ <= halui.program.is-paused \
+ => pendant_util.is-paused
+
+ makenet [existing_outpin_signame halui.program.is-running pendant:is-running] \
+ <= halui.program.is-running \
+ => pendant_util.is-running
+} ;# std_start_pause_button
+
+proc popup_msg {msg} {
+ puts stderr "$msg"
+ if [catch {package require Tk
+ wm withdraw .
+ tk_messageBox \
+ -title "$::progname" \
+ -type ok \
+ -message "$msg"
+ destroy .
+ } msg] {
+ puts stderr "$msg"
+ }
+} ;# popup_msg
+
+proc err_exit {msg} {
+ popup_msg $msg
+ puts stderr "\n$::progname: $msg\n"
+ exit 1
+} ;# err_exit
+
+proc makenet {args} {
+ if [catch {eval net $args} msg] {
+ if ![info exists ::makenet_msg] {
+ set ::makenet_msg \
+ "Failed to make some required connections"
+ }
+ set sig "Signal: <[lindex $args 0]>:"
+ set ::makenet_msg "$::makenet_msg\n\n$sig\n$msg"
+ }
+} ;# makenet
+
+# begin------------------------------------------------------------------------
+set ::progname "xhc-hb04.tcl"
+
+set ::xhc_hb04_quiet 0
+# ::tp is the namespace for [HAL]TWOPASS processing
+if { [namespace exists ::tp] && ([::tp::passnumber] == 0) } {
+ set ::xhc_hb04_quiet 1
+ puts "$::progname: suppressing messages in twopass pass0"
+}
+
+set libtag "LIB:"
+set cfg ${libtag}xhc-hb04-layout2.cfg ;# default
+
+if ![info exists ::HAL(HALUI)] {
+ err_exit "\[HAL\]HALUI is not set"
+}
+if {[array names ::XHC_HB04_CONFIG] == ""} {
+ err_exit "Missing stanza: \[XHC_HB04_CONFIG\]"
+}
+if {[array names ::XHC_HB04_BUTTONS] == ""} {
+ err_exit "Missing stanza: \[XHC_HB04_BUTTONS\]"
+}
+
+foreach name [array names ::XHC_HB04_CONFIG] {
+ set ::XHC_HB04_CONFIG($name) [string trim $::XHC_HB04_CONFIG($name) "{}"]
+}
+
+if [info exists ::XHC_HB04_CONFIG(layout)] {
+ switch ${::XHC_HB04_CONFIG(layout)} {
+ 1 {set cfg ${libtag}xhc-hb04-layout1.cfg}
+ 2 {set cfg ${libtag}xhc-hb04-layout2.cfg}
+ default {
+ set msg "Nonstandard layout:<$::XHC_HB04_CONFIG(layout)>"
+ set cfg $::XHC_HB04_CONFIG(layout)
+ set msg "$msg\ntrying: $cfg"
+ popup_msg "$msg"
+ # keep going
+ }
+ }
+}
+
+# .cfg files use same search path as halfiles
+set cfg [find_file_in_hallib_path $cfg]
+
+if ![file exists $cfg] {
+ set msg "Cannot find file: <$cfg>\nCannot configure pendant\n"
+ set msg "$msg\nContinuing without xhc-hb04"
+ popup_msg "$msg"
+ return ;# not an exit
+}
+
+# handle keywords with either upper or lower case
+foreach name [array names ::XHC_HB04_CONFIG] {
+ set lname [string tolower $name]
+ set uname [string toupper $name]
+ if ![info exists ::XHC_HB04_CONFIG($uname)] {
+ continue
+ } else {
+ if { [info exists ::XHC_HB04_CONFIG($lname)]
+ && "$::XHC_HB04_CONFIG($lname)" != "$::XHC_HB04_CONFIG($uname)"} {
+ puts "duplicated item: \[XHC_HB04_CONFIG\]$uname = $::XHC_HB04_CONFIG($uname)"
+ puts "superseded with: \[XHC_HB04_CONFIG\]$lname = $::XHC_HB04_CONFIG($lname)"
+ unset ::XHC_HB04_CONFIG($uname)
+ }
+ }
+}
+foreach name [array names ::XHC_HB04_BUTTONS] {
+ set lname [string tolower $name]
+ set uname [string toupper $name]
+ if ![info exists ::XHC_HB04_BUTTONS($uname)] {
+ continue
+ } else {
+ if { [info exists ::XHC_HB04_BUTTONS($lname)]
+ && "$::XHC_HB04_BUTTONS($lname)" != "$::XHC_HB04_BUTTONS($uname)"} {
+ puts "duplicated item: \[XHC_HB04_BUTTONS\]$uname = $::XHC_HB04_BUTTONS($uname)"
+ puts "superseded with: \[XHC_HB04_BUTTONS\]$lname = $::XHC_HB04_BUTTONS($lname)"
+ unset ::XHC_HB04_BUTTONS($uname)
+ }
+ }
+}
+# require_pendant==yes: use -x, dont create pins unless connected
+# require_pendant==no: create pins if not connected
+if ![info exists ::XHC_HB04_CONFIG(require_pendant)] {
+ set ::XHC_HB04_CONFIG(require_pendant) yes ;# default
+}
+set dashx -x
+switch $::XHC_HB04_CONFIG(require_pendant) {
+ no {set dashx ""}
+}
+
+if [info exists ::XHC_HB04_CONFIG(sequence)] {
+ set dashs "-s $::XHC_HB04_CONFIG(sequence)"
+} else {
+ set dashs ""
+}
+
+set cmd "loadusr -W xhc-hb04 $dashx $dashs -I $cfg -H"
+if [catch {eval $cmd} msg] {
+ set msg "\n$::progname: loadusr xhc-hb04:\n<$msg>\n\n"
+ set msg "$msg Is it plugged in?\n\n"
+ set msg "$msg Are permissions correct?\n\n"
+ set msg "$msg Continuing without xhc-hb04\n"
+ set msg "$msg \nFailing cmd:\n$cmd"
+ popup_msg "$msg"
+ return ;# not an exit
+}
+
+if ![info exists ::XHC_HB04_CONFIG(inch_or_mm)] {
+ set ::XHC_HB04_CONFIG(inch_or_mm) mm
+}
+switch -glob $::XHC_HB04_CONFIG(inch_or_mm) {
+ in* {setp xhc-hb04.inch-icon 1}
+ default {}
+}
+
+if ![info exists ::XHC_HB04_CONFIG(jogmode)] {
+ set ::XHC_HB04_CONFIG(jogmode) normal ;# default
+}
+
+set jogmode $::XHC_HB04_CONFIG(jogmode)
+switch $jogmode {
+ normal {}
+ vnormal {}
+ default {
+ set ::XHC_HB04_CONFIG(jogmode) normal
+ set msg "Unkknown jogmode <$jogmode>"
+ set msg "$msg Using $::XHC_HB04_CONFIG(jogmode)"
+ popup_msg "$msg"
+ }
+}
+
+if [info exists ::XHC_HB04_CONFIG(coords)] {
+ if ![is_uniq $::XHC_HB04_CONFIG(coords)] {
+ err_exit "coords must be unique, not: <$::XHC_HB04_CONFIG(coords)>"
+ }
+ if {[llength $::XHC_HB04_CONFIG(coords)] > 4} {
+ err_exit "max no.of coords is 4 <$::XHC_HB04_CONFIG(coords)>"
+ }
+} else {
+ set ::XHC_HB04_CONFIG(coords) {x y z a} ;# default
+}
+
+if ![info exists ::XHC_HB04_CONFIG(threadname)] {
+ set ::XHC_HB04_CONFIG(threadname) "servo-thread" ;# default
+}
+loadrt xhc_hb04_util names=pendant_util
+addf pendant_util $::XHC_HB04_CONFIG(threadname)
+
+# If twopass, do not call procs in pass0 that test pin
+# connections since components not yet loaded
+if { ![namespace exists ::tp] || ([::tp::passnumber] != 0) } {
+ connect_pins ;# per INI file items: [XHC_HB04_BUTTONS]buttonname=pin
+ wheel_setup $::XHC_HB04_CONFIG(jogmode)
+ # jog wheel per INI file items:
+ # [XHC_HB04_CONFIG]coords,coefs,scales
+}
+if [info exists ::makenet_msg] {
+ popup_msg $::makenet_msg
+}
+#parray ::XHC_HB04_CONFIG
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/halshow.preferences b/linuxcnc/sim.gmoccapy.lathe_configs/halshow.preferences
new file mode 100755
index 0000000..310fce1
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/halshow.preferences
@@ -0,0 +1,24 @@
+# Halshow settings
+# This file is generated automatically.
+wm geometry . 953x382+810+114
+placeFrames 0.4680232558139535
+set ::ratio 0.4680232558139535
+set ::old_w_leftf 160
+set ::watchlist {
+ pin+lcec.0.0.actual-position
+ pin+lcec.0.0.commanded-position
+ pin+lcec.0.0.enc-frequency
+ pin+lcec.0.0.enc-pos-scale
+ pin+lcec.0.0.enc-position
+ pin+lcec.0.0.index-byte
+ pin+lcec.0.0.DiffT
+ pin+lcec.0.read.time
+ pin+lcec.0.write.time
+}
+set ::workmode watchhal
+set ::watchInterval 100
+set ::col1_width 100
+set ::ffmts
+set ::ifmts
+set ::alwaysOnTop 0
+set ::autoSaveWatchlist 1
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.ini
new file mode 100755
index 0000000..e6cffcb
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.ini
@@ -0,0 +1,160 @@
+# 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 = 1.1
+MACHINE = gmoccapy_lathe
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+LATHE = 1
+BACK_TOOL_LATHE = 0
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 1.000 mm, 0.100 mm, 0.010 mm, 0.001 mm
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G21 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.005
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+HALFILE = ethercat_end.hal
+
+# Single file that is executed after the GUI has started.
+POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 50
+MAX_LINEAR_VELOCITY = 234
+POSITION_FILE = position.txt
+#NO_FORCE_HOMING = 1
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZ
+JOINTS = 2
+
+[AXIS_X]
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 100
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = 250
+HOME_SEARCH_VEL = 200.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 -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe.pref b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.pref
new file mode 100755
index 0000000..d58a1da
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.pref
@@ -0,0 +1,74 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+gremlin_view = rbt_view_y2
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 140.4
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+use_screen2 = False
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+grid_size = 1.0
+view = p
+mouse_btn_mode = 4
+hide_cursor = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rot
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+jump_to_dir = /home/emcmesa
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = True
+show_keyboard_on_mdi = True
+show_keyboard_on_file_selection = False
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+reload_tool = True
+blockdel = False
+opstop = False
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+run_from_line = no_run
+unlock_way = use
+show_preview_on_offset = False
+use_keyboard_shortcuts = False
+dro_digits = 3
+toggle_readout = True
+tool_in_spindle = 0
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe.tbl b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.tbl
new file mode 100755
index 0000000..bd538b5
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe.tbl
@@ -0,0 +1,5 @@
+T1 P1 X-12.0 Y0.0 Z-25.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.4 I26.0 J86.0 Q2.0 ;60 Grad vorn
+T2 P2 X-10.356 Y0.0 Z12.123 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I50.0 J85.0 Q2.0 ;35 Grad vorn
+T3 P3 X1.123 Y0.0 Z25.456 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.4 I-80.0 J-25.0 Q3.0 ;55 Grad vorn
+T4 P4 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I94.0 J154.0 Q1.0 ;60 Grad Rück
+T5 P5 X5.737 Y0.0 Z12.2399 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I0.0 J0.0 Q6.0 ;Einstichstahl
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_C.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_C.ini
new file mode 100755
index 0000000..6adbccb
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_C.ini
@@ -0,0 +1,182 @@
+# 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 = 1.1
+MACHINE = lathe_c
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+LATHE = 1
+BACK_TOOL_LATHE = 0
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 1.000 mm, 0.100 mm, 0.010 mm, 0.001 mm
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G21 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.005
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe_C.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+
+# Single file that is executed after the GUI has started.
+POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z C
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 50
+MAX_LINEAR_VELOCITY = 234
+POSITION_FILE = position.txt
+#NO_FORCE_HOMING = 1
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZC
+JOINTS = 3
+
+[AXIS_X]
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = -10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+
+[AXIS_C]
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+
+[JOINT_2]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+# section for main IO controller parameters -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_CW.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_CW.ini
new file mode 100755
index 0000000..7b16666
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_CW.ini
@@ -0,0 +1,210 @@
+# 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 = 1.1
+MACHINE = lathe_cw
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+LATHE = 1
+BACK_TOOL_LATHE = 0
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 1.000 mm, 0.100 mm, 0.010 mm, 0.001 mm
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G21 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.005
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe_CW.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+
+# Single file that is executed after the GUI has started.
+POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z C W
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 50
+MAX_LINEAR_VELOCITY = 234
+POSITION_FILE = position.txt
+#NO_FORCE_HOMING = 1
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZCW
+JOINTS = 4
+
+[AXIS_X]
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = -10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+
+[AXIS_C]
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+
+[JOINT_2]
+TYPE = ANGULAR
+HOME = 0.0
+MAX_VELOCITY = 90.0
+MAX_ACCELERATION = 1200.0
+BACKLASH = 0.000
+INPUT_SCALE = 40
+OUTPUT_SCALE = 1.000
+FERROR = 5.0
+MIN_FERROR = 1.0
+HOME_OFFSET = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+
+[AXIS_W]
+MIN_LIMIT = -200.0
+MAX_LIMIT = 0.0
+MAX_VELOCITY = 66
+MAX_ACCELERATION = 150.0
+
+[JOINT_3]
+TYPE = LINEAR
+MAX_VELOCITY = 66
+MAX_ACCELERATION = 150.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -200.0
+MAX_LIMIT = 0.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 0.0
+HOME_SEARCH_VEL = 0.0
+HOME_LATCH_VEL = 0.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+
+
+
+# section for main IO controller parameters -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_backtool.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_backtool.ini
new file mode 100755
index 0000000..3ec2f6a
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_backtool.ini
@@ -0,0 +1,160 @@
+# 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 = 1.1
+MACHINE = gmoccapy_lathe
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+LATHE = 1
+BACK_TOOL_LATHE = 1
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 1.000 mm, 0.100 mm, 0.010 mm, 0.001 mm
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G21 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.005
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+
+# Single file that is executed after the GUI has started.
+POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 50
+MAX_LINEAR_VELOCITY = 234
+POSITION_FILE = position.txt
+#NO_FORCE_HOMING = 1
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZ
+JOINTS = 2
+
+[AXIS_X]
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = -10
+HOME_SEARCH_VEL = 200.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 -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_c.pref b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_c.pref
new file mode 100755
index 0000000..c4dadc1
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_c.pref
@@ -0,0 +1,73 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+reload_tool = True
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+mouse_btn_mode = 4
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = True
+show_keyboard_on_mdi = False
+show_keyboard_on_file_selection = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rotation of Z
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+unlock_way = no
+grid_size = 1.0
+view = y2
+gremlin_view = rbt_view_y
+tool_in_spindle = 0
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 140.4
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+hide_cursor = False
+jump_to_dir = /home/emcmesa
+blockdel = False
+opstop = False
+run_from_line = run
+show_preview_on_offset = True
+use_keyboard_shortcuts = True
+dro_digits = 3
+toggle_readout = True
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_cw.pref b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_cw.pref
new file mode 100755
index 0000000..6ca7186
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_cw.pref
@@ -0,0 +1,72 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+view = y2
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 140.4
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+grid_size = 1.0
+mouse_btn_mode = 4
+hide_cursor = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rot
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+jump_to_dir = /home/emcmesa
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = False
+show_keyboard_on_mdi = False
+show_keyboard_on_file_selection = False
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+reload_tool = True
+blockdel = False
+opstop = False
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+run_from_line = no_run
+unlock_way = no
+show_preview_on_offset = False
+use_keyboard_shortcuts = True
+dro_digits = 3
+toggle_readout = True
+tool_in_spindle = 2
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.ini
new file mode 100755
index 0000000..4629d00
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.ini
@@ -0,0 +1,160 @@
+# 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 = 1.1
+MACHINE = lathe_imperial
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+
+LATHE = 1
+BACK_TOOL_LATHE = 0
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 0.4 inch, 0.04 inch , 0.004 inch, 0.0004 inch
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G20 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.001
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+
+# Single file that is executed after the GUI has started.
+POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z
+LINEAR_UNITS = inch
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 1.6
+MAX_LINEAR_VELOCITY = 10
+POSITION_FILE = position.txt
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZ
+JOINTS = 2
+
+[AXIS_X]
+MIN_LIMIT = -2.0
+MAX_LIMIT = 40.0
+MAX_VELOCITY = 6.5
+MAX_ACCELERATION = 59.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 6.5
+MAX_ACCELERATION = 59.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -2.0
+MAX_LIMIT = 40.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 4
+HOME_SEARCH_VEL = 40.0
+HOME_LATCH_VEL = 2.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -3.0
+MAX_LIMIT = 400.0
+MAX_VELOCITY = 6.5
+MAX_ACCELERATION = 59.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 6.5
+MAX_ACCELERATION = 59.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -3.0
+MAX_LIMIT = 400.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = -4
+HOME_SEARCH_VEL = 40.0
+HOME_LATCH_VEL = 2.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 0
+HOME_IS_SHARED = 1
+
+# section for main IO controller parameters -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+# Sections for display options ------------------------------------------------
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.pref b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.pref
new file mode 100755
index 0000000..d261f5c
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_imperial.pref
@@ -0,0 +1,71 @@
+[DEFAULT]
+dro_size = 28
+abs_color = #0000FF
+rel_color = #000000
+dtg_color = #FFFF00
+homed_color = #00FF00
+unhomed_color = #FF0000
+spindle_bar_min = 0.0
+spindle_bar_max = 6000.0
+unlock_code = 123
+blockheight = 0.0
+spindle_start_rpm = 300.0
+scale_jog_vel = 6.0
+scale_spindle_override = 1
+scale_feed_override = 1
+scale_rapid_override = 1
+hide_turtle_jog_button = False
+turtle_jog_factor = 20
+open_file =
+screen1 = window
+x_pos = 40
+y_pos = 30
+width = 979
+height = 750
+gtk_theme = Follow System Theme
+audio_alert = /usr/share/sounds/freedesktop/stereo/dialog-warning.oga
+audio_error = /usr/share/sounds/freedesktop/stereo/dialog-error.oga
+grid_size = 1.0
+mouse_btn_mode = 4
+hide_cursor = False
+system_name_tool = Tool
+system_name_g5x = G5x
+system_name_rot = Rot
+system_name_g92 = G92
+system_name_g54 = G54
+system_name_g55 = G55
+system_name_g56 = G56
+system_name_g57 = G57
+system_name_g58 = G58
+system_name_g59 = G59
+system_name_g59.1 = G59.1
+system_name_g59.2 = G59.2
+system_name_g59.3 = G59.3
+jump_to_dir = /home/emcmesa
+show_keyboard_on_offset = False
+show_keyboard_on_tooledit = False
+show_keyboard_on_edit = True
+show_keyboard_on_mdi = True
+show_keyboard_on_file_selection = False
+x_pos_popup = 45.0
+y_pos_popup = 55
+width_popup = 250.0
+max_messages = 10
+message_font = sans 10
+use_frames = True
+reload_tool = True
+blockdel = False
+opstop = False
+enable_dro = False
+show_offsets = False
+show_dtg = False
+view_tool_path = True
+view_dimension = True
+run_from_line = no_run
+unlock_way = use
+show_preview_on_offset = False
+use_keyboard_shortcuts = False
+dro_digits = 4
+toggle_readout = True
+view = y
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathe_macros.ini b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_macros.ini
new file mode 100755
index 0000000..ca358f6
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathe_macros.ini
@@ -0,0 +1,165 @@
+# 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 = 1.1
+MACHINE = gmoccapy_lathe
+#DEBUG = 0x7FFFFFFF
+DEBUG = 0
+
+# for details see nc_files/subroutines/maco_instructions.txt
+[DISPLAY]
+DISPLAY = gmoccapy
+LATHE = 1
+BACK_TOOL_LATHE = 0
+
+# Cycle time, in milliseconds, that display will sleep between polls
+CYCLE_TIME = 100
+
+# Highest value that will be allowed for feed override, 1.0 = 100%
+MAX_FEED_OVERRIDE = 1.5
+MAX_SPINDLE_OVERRIDE = 1.2
+MIN_SPINDLE_OVERRIDE = .5
+
+
+# Prefix to be used
+PROGRAM_PREFIX = /home/debian/linuxcnc/nc_files
+
+# Introductory graphic
+INTRO_GRAPHIC = linuxcnc.gif
+INTRO_TIME = 5
+
+# list of selectable jog increments
+INCREMENTS = 1.000 mm, 0.100 mm, 0.010 mm, 0.001 mm
+
+EMBED_TAB_NAME = Cycles
+EMBED_TAB_LOCATION = ntb_preview
+#EMBED_TAB_LOCATION = ntb_user_tabs
+EMBED_TAB_COMMAND = halcmd loadusr -Wn gladevcp gladevcp -c gladevcp -U notouch=1 -U norun=0 -u lathehandler.py -x {XID} lathemacro.ui
+
+[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]
+RS274NGC_STARTUP_CODE = G18 G21 G40 G49 G54 G80 G90 G94 G8 M9 M5 G64 P0.005
+PARAMETER_FILE = sim.var
+SUBROUTINE_PATH = macros:./
+
+# Motion control section ------------------------------------------------------
+[EMCMOT]
+EMCMOT = motmod
+COMM_TIMEOUT = 1.0
+BASE_PERIOD = 100000
+SERVO_PERIOD = 1000000
+
+# Hardware Abstraction Layer section --------------------------------------------------
+[TASK]
+TASK = milltask
+CYCLE_TIME = 0.001
+
+# Part program interpreter section --------------------------------------------
+[HAL]
+HALFILE = core_sim_lathe.hal
+HALFILE = spindle_sim.hal
+HALFILE = simulated_home_lathe.hal
+
+# Single file that is executed after the GUI has started.
+#POSTGUI_HALFILE = gmoccapy_postgui.hal
+
+HALUI = halui
+
+# Trajectory planner section --------------------------------------------------
+[HALUI]
+#No Content
+
+[TRAJ]
+COORDINATES = X Z
+LINEAR_UNITS = mm
+ANGULAR_UNITS = degree
+DEFAULT_LINEAR_VELOCITY = 50
+MAX_LINEAR_VELOCITY = 234
+POSITION_FILE = position.txt
+#NO_FORCE_HOMING = 1
+
+# First axis
+[EMCIO]
+EMCIO = io
+CYCLE_TIME = 0.100
+
+# tool table file
+TOOL_TABLE = lathe.tbl
+
+[KINS]
+KINEMATICS = trivkins coordinates=XZ
+JOINTS = 2
+
+[AXIS_X]
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_0]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -50.0
+MAX_LIMIT = 200.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 0.0
+HOME = 10
+HOME_SEARCH_VEL = 200.0
+HOME_LATCH_VEL = 20.0
+HOME_USE_INDEX = NO
+HOME_IGNORE_LIMITS = NO
+HOME_SEQUENCE = 1
+HOME_IS_SHARED = 1
+
+# Third axis
+[AXIS_Z]
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+
+[JOINT_1]
+TYPE = LINEAR
+MAX_VELOCITY = 166
+MAX_ACCELERATION = 1500.0
+BACKLASH = 0.000
+INPUT_SCALE = 4000
+OUTPUT_SCALE = 1.000
+MIN_LIMIT = -75.0
+MAX_LIMIT = 1000.0
+FERROR = 0.050
+MIN_FERROR = 0.010
+HOME_OFFSET = 1.0
+HOME = -10
+HOME_SEARCH_VEL = 200.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 -----------------------------------
+[MACROS]
+MACRO = i_am_lost
+MACRO = halo_world
+MACRO = jog_around
+MACRO = increment xinc yinc
+MACRO = go_to_position X-pos Y-pos Z-pos
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathehandler.py b/linuxcnc/sim.gmoccapy.lathe_configs/lathehandler.py
new file mode 100755
index 0000000..86a2091
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathehandler.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+# 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 glib
+import linuxcnc
+import cairo
+import signal
+import re
+import gi
+gi.require_version('Rsvg', '2.0')
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
+from gi.repository import Pango
+from gi.repository import Rsvg
+from gi.repository import GdkPixbuf
+debug = 0
+notouch = 0
+norun = 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)
+ alloc = tab.get_allocation()
+ x, y, w, h = (alloc.x, alloc.y, alloc.width, alloc.height)
+ pixbuf = self.svg.get_pixbuf_sub(f'#layer{tab_num}').scale_simple(w-10, h-10, GdkPixbuf.InterpType.BILINEAR)
+ im = self.builder.get_object(f'Image{tab_num}')
+ im.set_from_pixbuf(pixbuf)
+ for c in im.get_parent().get_children():
+ if c.get_has_tooltip():
+ m = re.findall(r'', c.get_tooltip_markup())
+ if len(m) > 0:
+ x1 = int(m[0][0]); y1 = int(m[0][1])
+ c.set_margin_left(max(0, w * x1/1500))
+ c.set_margin_top(max(0, h * y1/1000))
+
+
+ # decide if our window is active to mask the cycle-start hardware button
+ # FIXME: This is probably not as reliable as one might wish.
+ def event(self,w,event):
+ if w.is_active():
+ if w.has_toplevel_focus() :
+ self.active = True
+ else:
+ self.active = False
+
+ # Capture notify events
+ def on_map_event(self, widget, data=None):
+ top = widget.get_toplevel()
+ top.connect('notify', 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)
+
+ # This catches the signal from Touchy to say that the tab is exposed
+ t = self.builder.get_object('macrobox')
+ t.connect('map-event',self.on_map_event)
+ t.add_events(Gdk.EventMask.STRUCTURE_MASK)
+
+ self.cmd = linuxcnc.command()
+
+ # This connects the expose event to re-draw and scale the SVG frames
+ t = self.builder.get_object('tabs1')
+ t.connect_after("draw", self.on_expose)
+ t.connect("destroy", Gtk.main_quit)
+ t.add_events(Gdk.EventMask.STRUCTURE_MASK)
+ self.svg = Rsvg.Handle().new_from_file('LatheMacro.svg')
+ self.active = True
+
+ # handle Useropts
+ if norun:
+ for c in range(0,6):
+ print(c)
+ print( f'tab{c}.action')
+ self.builder.get_object(f'tab{c}.action').set_visible(False)
+
+ def show_keyb(self, obj, data=None):
+ if notouch: return False
+ 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()
+ return True
+
+ 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 any( x in data for x in [ '/2', '/4', '/8', '/16', '/32', '/64', '/128']):
+ v = [0] + [float(x) for x in data.replace('/','.').split('.')]
+ data = f'{v[-3] + v[-2]/v[-1]:6.7}'
+ 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':
+ self.entry.set_text(f'{v * 25.4:6.4}')
+ elif op == 'mm->in':
+ self.entry.set_text(f'{v / 25.4:6.4}')
+ elif op == 'tpi->pitch':
+ self.entry.set_text(f'{25.4 / v:6.4}')
+ elif op == 'pitch->tpi':
+ self.entry.set_text(f'{25.4 / v:6.4}')
+
+ 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.get_property('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
+ if self.active:
+ nb = self.builder.get_object('tabs1')
+ print('current tab', nb.get_current_page())
+ c = self.builder.get_object(f"tab{nb.get_current_page()}.action")
+ if c is not None:
+ self.cmd.abort()
+ self.cmd.mode(linuxcnc.MODE_MDI)
+ self.cmd.wait_complete()
+ c.emit('clicked')
+ print(c.get_name(), "clicked")
+
+ def testing(self, obj, data = None):
+ print('event', data)
+
+def get_handlers(halcomp,builder,useropts):
+
+ global debug
+ for cmd in useropts:
+ print(cmd)
+ exec(cmd, globals())
+
+ set_debug(debug)
+ return [HandlerClass(halcomp,builder,useropts)]
+
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/lathemacro.ui b/linuxcnc/sim.gmoccapy.lathe_configs/lathemacro.ui
new file mode 100755
index 0000000..f9261e8
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/lathemacro.ui
@@ -0,0 +1,2937 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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}] [${radius.coolant}]
+
+
+ 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}] [${thread.coolant}]
+
+
+ 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}] [${turn.coolant}]
+
+
+ Set Tool
+ M61 Q${turn.tool-s} G43 H${turn.tool-s}
+
+
+ False
+ GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK
+ 200
+ 100
+ False
+
+
+
+
+
+ True
+ False
+
+ 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
+ left
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1000,654-->Finish Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ False
+ TurnXAdj
+ 4
+ True
+
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--635,687-->Feed per Rev
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ TurnFeedAdj
+ 3
+ True
+
+
+
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--800,230-->End Radius
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ TurnRadAdj
+ 4
+ True
+
+
+
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--821,863-->Cut per pass
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ TurnCutAdj
+ 3
+ True
+
+
+
+ 3
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--125,424-->Finish Z
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ TurnZAdj
+ 4
+ True
+
+
+
+ 4
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--520,474-->Taper angle
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ False
+ TurnAngAdj
+ 3
+ True
+
+
+
+ 5
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ gtk-media-play
+ False
+ turn.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+
+
+ 10
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 0
+ False
+ False
+ TurnToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ turn.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 20
+ False
+ False
+ TurnSFAdj
+ 20
+
+
+
+ 1
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+ 11
+
+
+
+
+ False
+
+
+
+
+ True
+ False
+ Turning
+
+
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--700,280-->Taper Angle
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ BoreAngleAdj
+ 3
+
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--421,520-->Run-out radius
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ BoreRadAdj
+ 4
+
+
+
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1080,616-->Finish Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ BoreXAdj
+ 4
+
+
+
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--900,825-->Diameter Increment
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ BoreCutAdj
+ 4
+
+
+
+ 3
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--530,820-->Feed per rev
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ BoreFeedAdj
+ 4
+
+
+
+ 4
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ gtk-media-play
+ False
+ bore.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+ True
+
+
+
+
+ 7
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--273,267-->Finish Z
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ BoreZAdj
+ 4
+
+
+
+ 9
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 0
+ False
+ False
+ BoreSFAdj
+
+
+
+ 1
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 0
+ False
+ False
+ BoreToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ bore.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+ 11
+
+
+
+
+ 1
+ False
+
+
+
+
+ True
+ False
+ Boring
+
+
+ 1
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--156,404-->Finish Z
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ FaceZAdj
+ 4
+
+
+
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1115,626-->Finish Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ FaceXAdj
+ 4
+
+
+
+ 3
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--876,886-->Feed per Rev
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ FaceFeedAdj
+ 3
+
+
+
+ 4
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--408,760-->Cut per pass
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ FaceCutAdj
+ 3
+
+
+
+ 5
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1044,364-->Face Angle
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ FaceAngleAdj
+ 3
+
+
+
+ 6
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+ False
+
+
+ gtk-media-play
+ False
+ face.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+ True
+
+
+
+
+ 9
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 0
+ False
+ False
+ FaceSFAdj
+
+
+
+ 1
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 0
+ False
+ False
+ FaceToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ face.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+ 10
+
+
+
+
+ Face
+ 2
+ False
+
+
+
+
+ True
+ False
+ Facing
+
+
+ 2
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1018,674-->Radius Inner or Outer Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ RadXAdj
+ 4
+
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--202,334-->Radius Z position
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ RadiusZAdj
+ 4
+
+
+
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--848,451-->Radius
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ RadRadAdj
+ 3
+
+
+
+ 2
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--863,629-->Front Inside Radius
+ start
+ start
+
+
+ 50
+ 20
+ True
+ True
+ False
+ True
+ True
+
+
+
+
+ 3
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--763,680-->Front Outside Radius
+ start
+ start
+
+
+ 50
+ 20
+ True
+ True
+ False
+ True
+ radius.fi
+
+
+
+
+ 4
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--335,448-->Back Outside Radius
+ start
+ start
+
+
+ 50
+ 20
+ True
+ True
+ False
+ True
+ radius.fi
+
+
+
+
+ 5
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ radius.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ True
+ False
+ gtk-media-play
+
+
+
+
+
+
+ 10
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 0
+ False
+ False
+ RadiusSFAdj
+
+
+
+ 1
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 5
+ 0
+ False
+ False
+ RadiusToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ radius.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+ 11
+
+
+
+
+ Radius
+ 3
+ False
+
+
+
+
+ True
+ False
+ Radius
+
+
+ 3
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--202,334-->Chamfer Z position
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ ChamferZAdj
+ 4
+
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1112,287-->Chamfer size
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ ChamChamAdj
+ 3
+
+
+
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1033,678-->Chamfer Diametric position
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ ChamXAdj
+ 4
+
+
+
+ 2
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--335,448-->Back outside chamfer
+ start
+ start
+
+
+ 50
+ 20
+ True
+ True
+ False
+ <!--335,448-->Chamfer Z position
+ True
+ True
+
+
+
+
+ 3
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--763,680-->Front Outside Chamfer
+ start
+ start
+
+
+ 50
+ 20
+ True
+ True
+ False
+ True
+ chamfer.bo
+
+
+
+
+ 4
+
+
+
+
+ 100
+ 40
+ True
+ False
+ <!--863,629-->Front Inside Chamfer
+ start
+ start
+
+
+ 50
+ 16
+ True
+ True
+ False
+ 0
+ True
+ chamfer.bo
+
+
+
+
+ 5
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ False
+ chamfer.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ True
+ False
+ gtk-media-play
+
+
+
+
+
+
+ 10
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ Set Tool
+ False
+ chamfer.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 20
+ True
+ True
+ start
+ start
+ ●
+ 5
+ 0
+ False
+ False
+ ChamferSFAdj
+
+
+
+ 1
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ start
+ start
+ ●
+ 0
+ False
+ False
+ ChamferToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+
+
+
+ 11
+
+
+
+
+ Chamfer
+ 4
+ False
+
+
+
+
+ True
+ False
+ Chamfer
+
+
+ 4
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--268,341-->Finish Z position
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ ThreadZAdj
+ 4
+
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1010,753-->Radius Z position
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ ThreadXAdj
+ 4
+
+
+
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ False
+ <!--652,737-->External Thread
+ start
+ start
+
+
+ True
+ True
+ False
+ True
+ True
+
+
+
+
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--192,616-->Radius Z position
+ start
+ start
+ ●
+ 7
+ 0.0000
+ False
+ False
+ ThreadPitchAdj
+ 4
+
+
+
+ 4
+
+
+
+
+ 50
+ 20
+ True
+ False
+ <!--754,603-->Internal Thread
+ start
+ start
+
+
+ True
+ True
+ False
+ True
+ thread.external
+
+
+
+
+ 6
+
+
+
+
+ 50
+ 20
+ True
+ False
+ end
+ end
+
+
+ False
+ thread.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ True
+ False
+ gtk-media-play
+
+
+
+
+
+
+ 7
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ start
+ start
+ ●
+ 5
+ 20
+ False
+ False
+ ThreadSFAdj
+ 20
+
+
+
+ 1
+ 1
+
+
+
+
+ Set Tool
+ False
+ thread.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 20
+ True
+ True
+ start
+ start
+ ●
+ 0
+ False
+ False
+ ThreadToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+
+
+
+ 9
+
+
+
+
+ 5
+ False
+
+
+
+
+ True
+ False
+ Thread
+
+
+ 5
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ False
+ groove.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ True
+ False
+ gtk-media-play
+
+
+
+
+
+
+ 4
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1084,672-->Finish Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ GrooveXAdj
+ 4
+
+
+
+ 5
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 0
+ False
+ False
+ GrooveToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ groove.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 20
+ False
+ False
+ GrooveSFAdj
+ 20
+
+
+
+ 1
+ 1
+
+
+
+
+
+
+
+ 8
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--648,864-->Feed per rev
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ GrooveFeedAdj
+ 3
+
+
+
+ 4
+
+
+
+
+ 6
+
+
+
+
+ True
+ False
+ Groove
+
+
+ 6
+ False
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ gtk-missing-image
+
+
+ -1
+
+
+
+
+ 100
+ 40
+ True
+ False
+ end
+ end
+
+
+ False
+ drill.go
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ True
+ False
+ gtk-media-play
+
+
+
+
+
+
+ 3
+
+
+
+
+ True
+ False
+ end
+ start
+
+
+ 50
+ 20
+ True
+ True
+ end
+ start
+ ●
+ 5
+ 0
+ False
+ False
+ DrillSFAdj
+
+
+
+ 1
+ 1
+
+
+
+
+ 50
+ 20
+ True
+ True
+ ●
+ 0
+ False
+ False
+ DrillToolAdj
+
+
+
+ 1
+ 0
+
+
+
+
+ Set Tool
+ drill.toolchange
+ 50
+ 20
+ True
+ True
+ True
+ True
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ center
+ Speed
+ 1
+
+
+ 0
+ 1
+
+
+
+
+ Coolant
+ True
+ True
+ False
+ True
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+ 3
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--770,900-->Feed per Rev
+ start
+ start
+ ●
+ 5
+ 0.0000
+ False
+ False
+ DrillFeedAdj
+ 3
+
+
+
+ 2
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--260,250-->Finish Z
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ DrillZAdj
+ 4
+
+
+
+ 3
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--1200,270-->Drill Diameter
+ start
+ start
+ ●
+ 7
+ 0.000
+ False
+ False
+ DrillDiaAdj
+ 4
+
+
+
+ 4
+
+
+
+
+ 50
+ 20
+ True
+ True
+ <!--300,711-->Peck distance
+ start
+ start
+ ●
+ 5
+ 0.000
+ False
+ False
+ DrillPeckAdj
+ 0.25
+ 3
+ 2
+
+
+
+ 5
+
+
+
+
+ 7
+
+
+
+
+ True
+ False
+ Drill
+
+
+ 7
+ False
+
+
+
+
+
+
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var b/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var
new file mode 100755
index 0000000..1776377
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var
@@ -0,0 +1,119 @@
+5161 0.000000
+5162 0.000000
+5163 0.000000
+5164 0.000000
+5165 0.000000
+5166 0.000000
+5167 0.000000
+5168 0.000000
+5169 0.000000
+5181 0.000000
+5182 0.000000
+5183 0.000000
+5184 0.000000
+5185 0.000000
+5186 0.000000
+5187 0.000000
+5188 0.000000
+5189 0.000000
+5210 0.000000
+5211 0.000000
+5212 0.000000
+5213 0.000000
+5214 0.000000
+5215 0.000000
+5216 0.000000
+5217 0.000000
+5218 0.000000
+5219 0.000000
+5220 1.000000
+5221 0.000000
+5222 0.000000
+5223 0.000000
+5224 0.000000
+5225 0.000000
+5226 0.000000
+5227 0.000000
+5228 0.000000
+5229 0.000000
+5230 0.000000
+5241 0.000000
+5242 0.000000
+5243 0.000000
+5244 0.000000
+5245 0.000000
+5246 0.000000
+5247 0.000000
+5248 0.000000
+5249 0.000000
+5250 0.000000
+5261 0.000000
+5262 0.000000
+5263 0.000000
+5264 0.000000
+5265 0.000000
+5266 0.000000
+5267 0.000000
+5268 0.000000
+5269 0.000000
+5270 0.000000
+5281 0.000000
+5282 0.000000
+5283 0.000000
+5284 0.000000
+5285 0.000000
+5286 0.000000
+5287 0.000000
+5288 0.000000
+5289 0.000000
+5290 0.000000
+5301 0.000000
+5302 0.000000
+5303 0.000000
+5304 0.000000
+5305 0.000000
+5306 0.000000
+5307 0.000000
+5308 0.000000
+5309 0.000000
+5310 0.000000
+5321 0.000000
+5322 0.000000
+5323 0.000000
+5324 0.000000
+5325 0.000000
+5326 0.000000
+5327 0.000000
+5328 0.000000
+5329 0.000000
+5330 0.000000
+5341 0.000000
+5342 0.000000
+5343 0.000000
+5344 0.000000
+5345 0.000000
+5346 0.000000
+5347 0.000000
+5348 0.000000
+5349 0.000000
+5350 0.000000
+5361 0.000000
+5362 0.000000
+5363 0.000000
+5364 0.000000
+5365 0.000000
+5366 0.000000
+5367 0.000000
+5368 0.000000
+5369 0.000000
+5370 0.000000
+5381 0.000000
+5382 0.000000
+5383 0.000000
+5384 0.000000
+5385 0.000000
+5386 0.000000
+5387 0.000000
+5388 0.000000
+5389 0.000000
+5390 0.000000
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var.bak b/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var.bak
new file mode 100755
index 0000000..1776377
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/linuxcnc.var.bak
@@ -0,0 +1,119 @@
+5161 0.000000
+5162 0.000000
+5163 0.000000
+5164 0.000000
+5165 0.000000
+5166 0.000000
+5167 0.000000
+5168 0.000000
+5169 0.000000
+5181 0.000000
+5182 0.000000
+5183 0.000000
+5184 0.000000
+5185 0.000000
+5186 0.000000
+5187 0.000000
+5188 0.000000
+5189 0.000000
+5210 0.000000
+5211 0.000000
+5212 0.000000
+5213 0.000000
+5214 0.000000
+5215 0.000000
+5216 0.000000
+5217 0.000000
+5218 0.000000
+5219 0.000000
+5220 1.000000
+5221 0.000000
+5222 0.000000
+5223 0.000000
+5224 0.000000
+5225 0.000000
+5226 0.000000
+5227 0.000000
+5228 0.000000
+5229 0.000000
+5230 0.000000
+5241 0.000000
+5242 0.000000
+5243 0.000000
+5244 0.000000
+5245 0.000000
+5246 0.000000
+5247 0.000000
+5248 0.000000
+5249 0.000000
+5250 0.000000
+5261 0.000000
+5262 0.000000
+5263 0.000000
+5264 0.000000
+5265 0.000000
+5266 0.000000
+5267 0.000000
+5268 0.000000
+5269 0.000000
+5270 0.000000
+5281 0.000000
+5282 0.000000
+5283 0.000000
+5284 0.000000
+5285 0.000000
+5286 0.000000
+5287 0.000000
+5288 0.000000
+5289 0.000000
+5290 0.000000
+5301 0.000000
+5302 0.000000
+5303 0.000000
+5304 0.000000
+5305 0.000000
+5306 0.000000
+5307 0.000000
+5308 0.000000
+5309 0.000000
+5310 0.000000
+5321 0.000000
+5322 0.000000
+5323 0.000000
+5324 0.000000
+5325 0.000000
+5326 0.000000
+5327 0.000000
+5328 0.000000
+5329 0.000000
+5330 0.000000
+5341 0.000000
+5342 0.000000
+5343 0.000000
+5344 0.000000
+5345 0.000000
+5346 0.000000
+5347 0.000000
+5348 0.000000
+5349 0.000000
+5350 0.000000
+5361 0.000000
+5362 0.000000
+5363 0.000000
+5364 0.000000
+5365 0.000000
+5366 0.000000
+5367 0.000000
+5368 0.000000
+5369 0.000000
+5370 0.000000
+5381 0.000000
+5382 0.000000
+5383 0.000000
+5384 0.000000
+5385 0.000000
+5386 0.000000
+5387 0.000000
+5388 0.000000
+5389 0.000000
+5390 0.000000
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M101 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M101
new file mode 100755
index 0000000..db40680
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M101
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=0.1923
+MAXRPM=380
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M102 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M102
new file mode 100755
index 0000000..a846012
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M102
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=0.3189
+MAXRPM=630
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M103 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M103
new file mode 100755
index 0000000..7789473
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M103
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=0.4638
+MAXRPM=920
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M104 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M104
new file mode 100755
index 0000000..ab7f331
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M104
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=0.8846
+MAXRPM=1770
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M105 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M105
new file mode 100755
index 0000000..d9c332f
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M105
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=1.4672
+MAXRPM=2930
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M106 b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M106
new file mode 100755
index 0000000..c53798f
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/nc_files/M106
@@ -0,0 +1,6 @@
+#!/bin/bash
+R=2.1334
+MAXRPM=4260
+halcmd setp scale.0.gain $R
+halcmd setp scale.1.gain $(echo "scale=5;1.0 / $R"| bc -q)
+exit 0
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/position.txt b/linuxcnc/sim.gmoccapy.lathe_configs/position.txt
new file mode 100755
index 0000000..bdc031f
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/position.txt
@@ -0,0 +1,16 @@
+92.85000059605819445
+249.99999999908729365
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
+0.00000000000000000
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/postgui_call_list.hal b/linuxcnc/sim.gmoccapy.lathe_configs/postgui_call_list.hal
new file mode 100755
index 0000000..c048069
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/postgui_call_list.hal
@@ -0,0 +1,3 @@
+# These files are loaded post GUI, in the order they appear
+
+source custom_postgui.hal
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/radius.ngc b/linuxcnc/sim.gmoccapy.lathe_configs/radius.ngc
new file mode 100755
index 0000000..4ba6e52
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/radius.ngc
@@ -0,0 +1,76 @@
+;radius
+
+O sub
+
+G8 ; Lathe radius Mode
+G18 ; XZ Plane
+G21 ; Metric Units
+G90 ; Absolute Distance
+
+
+M6 T#6 G43
+
+#1 = [#1 / 2] ; because of radius mode
+#14 = [#<_x>] (starting X)
+#13 = [#<_z>] (starting Z)
+
+G96 D2400 S#2 ; Constant Surface Speed Mode
+M3
+g95 F0.1 ; Feed-Per-Rev Mode
+
+O90 IF [#12 GT 0.5]
+ M8
+O90 ENDIF
+
+#20 = 0
+O101 if [#9 GT 0.5] ; Front outside
+ o100 while [[#20 + #3] lt #8]
+ #20 = [#20 + #3]
+ g0 x[#1 - #20] z#13
+ g1 z#5
+ g3 x#1 z[#5 - #20] K[-#20]
+ g1 x #14
+ g0 z#13
+ o100 endwhile
+ g0 x#14 z#13
+ g0 x[#1 - #8]
+ g1 z#5
+ g3 x#1 z[#5 - #8] K[-#8]
+ g1 x #14
+ g0 z#13
+O101 elseif [#10 GT 0.5] ; front inside
+ o102 while [[#20 + #3] lt #8]
+ #20 = [#20 + #3]
+ g0 x[#1 + #20] z#13
+ g1 z#5
+ g2 x#1 z[#5 - #20] K[-#20]
+ g1 x #14
+ g0 z#13
+ o102 endwhile
+ g0 x#14 z#13
+ g0 x[#1 + #8]
+ g1 z#5
+ g2 x#1 z[#5 - #8] K[-#8]
+ g1 x #14
+ g0 z#13
+O101 elseif [#11 GT 0.5] ; back outside
+ o103 while [[#20 + #3] lt #8]
+ #20 = [#20 + #3]
+ g0 x[#1 - #20] z#13
+ g1 z#5
+ g2 x#1 z[#5 + #20] K#20
+ g1 x #14
+ g0 z#13
+ o103 endwhile
+ g0 x#14 z#13
+ g0 x[#1 - #8]
+ g1 z#5
+ g2 x#1 z[#5 + #8] K#8
+ g1 x #14
+ g0 z#13
+O101 endif
+M5 M9
+G7
+O endsub
+m2
+%
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/savestate.sav b/linuxcnc/sim.gmoccapy.lathe_configs/savestate.sav
new file mode 100755
index 0000000..c1d61dd
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/savestate.sav
@@ -0,0 +1,71 @@
+# generated by gladevcp.persistence.create_default_ini() on Tue Jul 12 01:49:47 2022
+[ini]
+ signature = a9fe768b61bb9201e86d89ad226616650f20e7ac
+ version = 1
+[vars]
+[widgets]
+ chamfer.fi = False
+ chamfer.fo = False
+ turn.rad = 3.0
+ groove.coolant = True
+ turn.z = 120.0
+ turn.x = 15.0
+ drill.dia = 10.0
+ radius.x = 0.0
+ radius.z = 0.0
+ thread.pitch = 1.0
+ turn.feed = 0.15
+ thread.x = 6.0
+ bore.rad = 0.0
+ radius.coolant = False
+ radius.bo = False
+ thread.z = 0.0
+ face.coolant = False
+ drill.peck = 2.0
+ face.cut = 2.8999999999999977
+ radius.rad = 1.0
+ thread.internal = False
+ face.sf = 0.0
+ bore.sf = 100.0
+ turn.tool = 1.0
+ face.feed = 0.15
+ chamfer.tool = 1.0
+ chamfer.bo = True
+ groove.sf = 100.0
+ thread.tool = 5.0
+ groove.feed = 0.03
+ bore.feed = 0.15
+ radius.sf = 100.0
+ chamfer.x = 0.0
+ chamfer.z = 0.0
+ thread.external = True
+ turn.coolant = True
+ face.z = 0.0
+ bore.x = 0.0
+ bore.z = 0.0
+ groove.x = 0.0
+ face.tool = 1.0
+ face.x = 0.0
+ chamfer.size = 1.0
+ turn.cut = 1.0
+ drill.coolant = True
+ chamfer.sf = 100.0
+ bore.tool = 1.0
+ groove.tool = 4.0
+ face.angle = 0.0
+ bore.coolant = True
+ drill.feed = 0.020000000000000004
+ drill.z = 0.0
+ turn.sf = 60.0
+ thread.sf = 60.0
+ radius.fo = False
+ turn.angle = 0.0
+ thread.coolant = False
+ bore.cut = 1.0
+ radius.fi = True
+ drill.tool = 3.0
+ drill.sf = 100.0
+ radius.tool = 1.0
+ bore.angle = 0.0
+ chamfer.coolant = False
+# last update by gladevcp.persistence.save_state() on Thu Dec 28 23:36:07 2023
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/shutdown.hal b/linuxcnc/sim.gmoccapy.lathe_configs/shutdown.hal
new file mode 100755
index 0000000..8766c9e
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/shutdown.hal
@@ -0,0 +1,2 @@
+# Include your shutdown HAL commands here
+# This file will not be overwritten when you run PNCconf again
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/sim.var b/linuxcnc/sim.gmoccapy.lathe_configs/sim.var
new file mode 100755
index 0000000..1776377
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/sim.var
@@ -0,0 +1,119 @@
+5161 0.000000
+5162 0.000000
+5163 0.000000
+5164 0.000000
+5165 0.000000
+5166 0.000000
+5167 0.000000
+5168 0.000000
+5169 0.000000
+5181 0.000000
+5182 0.000000
+5183 0.000000
+5184 0.000000
+5185 0.000000
+5186 0.000000
+5187 0.000000
+5188 0.000000
+5189 0.000000
+5210 0.000000
+5211 0.000000
+5212 0.000000
+5213 0.000000
+5214 0.000000
+5215 0.000000
+5216 0.000000
+5217 0.000000
+5218 0.000000
+5219 0.000000
+5220 1.000000
+5221 0.000000
+5222 0.000000
+5223 0.000000
+5224 0.000000
+5225 0.000000
+5226 0.000000
+5227 0.000000
+5228 0.000000
+5229 0.000000
+5230 0.000000
+5241 0.000000
+5242 0.000000
+5243 0.000000
+5244 0.000000
+5245 0.000000
+5246 0.000000
+5247 0.000000
+5248 0.000000
+5249 0.000000
+5250 0.000000
+5261 0.000000
+5262 0.000000
+5263 0.000000
+5264 0.000000
+5265 0.000000
+5266 0.000000
+5267 0.000000
+5268 0.000000
+5269 0.000000
+5270 0.000000
+5281 0.000000
+5282 0.000000
+5283 0.000000
+5284 0.000000
+5285 0.000000
+5286 0.000000
+5287 0.000000
+5288 0.000000
+5289 0.000000
+5290 0.000000
+5301 0.000000
+5302 0.000000
+5303 0.000000
+5304 0.000000
+5305 0.000000
+5306 0.000000
+5307 0.000000
+5308 0.000000
+5309 0.000000
+5310 0.000000
+5321 0.000000
+5322 0.000000
+5323 0.000000
+5324 0.000000
+5325 0.000000
+5326 0.000000
+5327 0.000000
+5328 0.000000
+5329 0.000000
+5330 0.000000
+5341 0.000000
+5342 0.000000
+5343 0.000000
+5344 0.000000
+5345 0.000000
+5346 0.000000
+5347 0.000000
+5348 0.000000
+5349 0.000000
+5350 0.000000
+5361 0.000000
+5362 0.000000
+5363 0.000000
+5364 0.000000
+5365 0.000000
+5366 0.000000
+5367 0.000000
+5368 0.000000
+5369 0.000000
+5370 0.000000
+5381 0.000000
+5382 0.000000
+5383 0.000000
+5384 0.000000
+5385 0.000000
+5386 0.000000
+5387 0.000000
+5388 0.000000
+5389 0.000000
+5390 0.000000
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/sim.var.bak b/linuxcnc/sim.gmoccapy.lathe_configs/sim.var.bak
new file mode 100755
index 0000000..1776377
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/sim.var.bak
@@ -0,0 +1,119 @@
+5161 0.000000
+5162 0.000000
+5163 0.000000
+5164 0.000000
+5165 0.000000
+5166 0.000000
+5167 0.000000
+5168 0.000000
+5169 0.000000
+5181 0.000000
+5182 0.000000
+5183 0.000000
+5184 0.000000
+5185 0.000000
+5186 0.000000
+5187 0.000000
+5188 0.000000
+5189 0.000000
+5210 0.000000
+5211 0.000000
+5212 0.000000
+5213 0.000000
+5214 0.000000
+5215 0.000000
+5216 0.000000
+5217 0.000000
+5218 0.000000
+5219 0.000000
+5220 1.000000
+5221 0.000000
+5222 0.000000
+5223 0.000000
+5224 0.000000
+5225 0.000000
+5226 0.000000
+5227 0.000000
+5228 0.000000
+5229 0.000000
+5230 0.000000
+5241 0.000000
+5242 0.000000
+5243 0.000000
+5244 0.000000
+5245 0.000000
+5246 0.000000
+5247 0.000000
+5248 0.000000
+5249 0.000000
+5250 0.000000
+5261 0.000000
+5262 0.000000
+5263 0.000000
+5264 0.000000
+5265 0.000000
+5266 0.000000
+5267 0.000000
+5268 0.000000
+5269 0.000000
+5270 0.000000
+5281 0.000000
+5282 0.000000
+5283 0.000000
+5284 0.000000
+5285 0.000000
+5286 0.000000
+5287 0.000000
+5288 0.000000
+5289 0.000000
+5290 0.000000
+5301 0.000000
+5302 0.000000
+5303 0.000000
+5304 0.000000
+5305 0.000000
+5306 0.000000
+5307 0.000000
+5308 0.000000
+5309 0.000000
+5310 0.000000
+5321 0.000000
+5322 0.000000
+5323 0.000000
+5324 0.000000
+5325 0.000000
+5326 0.000000
+5327 0.000000
+5328 0.000000
+5329 0.000000
+5330 0.000000
+5341 0.000000
+5342 0.000000
+5343 0.000000
+5344 0.000000
+5345 0.000000
+5346 0.000000
+5347 0.000000
+5348 0.000000
+5349 0.000000
+5350 0.000000
+5361 0.000000
+5362 0.000000
+5363 0.000000
+5364 0.000000
+5365 0.000000
+5366 0.000000
+5367 0.000000
+5368 0.000000
+5369 0.000000
+5370 0.000000
+5381 0.000000
+5382 0.000000
+5383 0.000000
+5384 0.000000
+5385 0.000000
+5386 0.000000
+5387 0.000000
+5388 0.000000
+5389 0.000000
+5390 0.000000
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe.hal b/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe.hal
new file mode 100755
index 0000000..24410d8
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe.hal
@@ -0,0 +1,21 @@
+loadrt comp names=comp_x,comp_z
+
+addf comp_x servo-thread
+addf comp_z servo-thread
+
+net Xhomeswpos => comp_x.in0
+net Zhomeswpos => comp_z.in0
+
+sets Xhomeswpos 1
+sets Zhomeswpos 2
+
+net Xpos => comp_x.in1
+net Zpos => comp_z.in1
+
+setp comp_x.hyst .02
+setp comp_z.hyst .02
+
+net Xhomesw <= comp_x.out => joint.0.home-sw-in
+net Zhomesw <= comp_z.out => joint.1.home-sw-in
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe_CW.hal b/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe_CW.hal
new file mode 100755
index 0000000..24410d8
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/simulated_home_lathe_CW.hal
@@ -0,0 +1,21 @@
+loadrt comp names=comp_x,comp_z
+
+addf comp_x servo-thread
+addf comp_z servo-thread
+
+net Xhomeswpos => comp_x.in0
+net Zhomeswpos => comp_z.in0
+
+sets Xhomeswpos 1
+sets Zhomeswpos 2
+
+net Xpos => comp_x.in1
+net Zpos => comp_z.in1
+
+setp comp_x.hyst .02
+setp comp_z.hyst .02
+
+net Xhomesw <= comp_x.out => joint.0.home-sw-in
+net Zhomesw <= comp_z.out => joint.1.home-sw-in
+
+
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/spindle_sim.hal b/linuxcnc/sim.gmoccapy.lathe_configs/spindle_sim.hal
new file mode 100755
index 0000000..7b97c3d
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/spindle_sim.hal
@@ -0,0 +1,69 @@
+# counting the spindle encoder in software
+loadrt encoder names=encoder_0
+# simulate the encoder
+loadrt sim_encoder names=sim_encoder_0
+loadrt limit2 names=limit_speed
+
+addf limit_speed servo-thread
+
+#######################################################
+# Beginning of threading related stuff
+#######################################################
+
+# spindle speed control
+net spindle-speed-cmd spindle.0.speed-out => limit_speed.in
+net spindle-speed-limited limit_speed.out => sim_encoder_0.speed
+
+# simulate spindle mass
+setp limit_speed.maxv 3000.0 # rpm/second
+
+# spindle encoder
+# connect encoder signals to encoder counter
+net spindle-phase-A sim_encoder_0.phase-A => encoder_0.phase-A
+net spindle-phase-B sim_encoder_0.phase-B => encoder_0.phase-B
+net spindle-phase-Z sim_encoder_0.phase-Z => encoder_0.phase-Z
+
+# assume 120 ppr = 480 counts/rev for the spindle
+setp sim_encoder_0.ppr 12
+# iocontrol output is in rpm, but sim-encoder speed is rps
+setp sim_encoder_0.scale 60
+# scale encoder output to read in revolutions
+# (that way thread pitches can be straightforward,
+# a 20 tpi thread would multiply the encoder output
+# by 1/20, etc)
+setp encoder_0.position-scale 48
+
+# encoder reset control
+# hook up motion controller's sync output
+net spindle-index-enable spindle.0.index-enable <=> encoder_0.index-enable
+
+# report our revolution count to the motion controller
+net spindle-pos encoder_0.position => spindle.0.revs
+
+# for spindle velocity estimate
+loadrt lowpass names=lowpass_velocity
+loadrt scale names=scale_to_rpm
+net spindle-rps-raw encoder_0.velocity lowpass_velocity.in
+net spindle-rps-filtered lowpass_velocity.out scale_to_rpm.in spindle.0.speed-in
+net spindle-rpm-filtered scale_to_rpm.out
+setp scale_to_rpm.gain 60
+setp lowpass_velocity.gain .07
+addf lowpass_velocity servo-thread
+addf scale_to_rpm servo-thread
+
+# for at-speed detection
+loadrt near names=near_speed
+addf near_speed servo-thread
+setp near_speed.scale 1.1
+setp near_speed.difference 10
+net spindle-speed-cmd => near_speed.in1
+net spindle-rpm-filtered => near_speed.in2
+net spindle-at-speed near_speed.out spindle.0.at-speed
+
+net spindle-fwd <= spindle.0.forward
+
+addf encoder.capture-position servo-thread
+addf sim-encoder.update-speed servo-thread
+
+addf sim-encoder.make-pulses base-thread
+addf encoder.update-counters base-thread
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/threading.ngc b/linuxcnc/sim.gmoccapy.lathe_configs/threading.ngc
new file mode 100755
index 0000000..71c05ef
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/threading.ngc
@@ -0,0 +1,59 @@
+;threading
+
+O sub
+
+G7 ; Lathe Diameter Mode
+G18 ; XZ Plane
+G21 ; Metric Units
+G90 ; Absolute Distance
+
+
+M6 T#3 G43
+
+#14 = [#<_x> * 2] (starting X)
+#13 = #<_z> (starting Z)
+
+G96 D200 S#2 ; Constant Surface Speed Mode
+M3
+g95 F0.25 ; Feed-Per-Rev Mode
+
+O90 IF [#8 GT 0.5]
+ M8
+O90 ENDIF
+
+g4p1 ; Wait to reach speed
+
+;Threading
+ O51 IF [#6 GT 0.5]
+ # = [#1]
+ # = [#1 - 1.3 * #4]
+ ;g1X [# - 1] ;thread truncation
+ ;g0 Z #13
+ ;g1 X #
+ ;g1 Z #5
+ G0 X[# - 1]
+ g0 Z #13
+ #3 = [#4 * 1.3]
+ (debug, INTERNAL Threading thread dia-#1 start-#13 finish-#5 Pitch-#4 Depth-#3)
+ g1X [# - 1]
+ g76 p#4 z#5 i1 j1 k#3 h3 r1.5 q29.5 e0 l0
+
+ O51 ELSE
+ # = [#1 - 0.108 * #4]
+ # = [#1 - 1.0825 * #4]
+ (debug, EXTERNAL Threading OD = # ID = #)
+ #3 = [#4 * 1.0825]
+ g1X [# + 1] ;final thread truncation
+ g0 z#13
+ g1 X #
+ g1 Z #5
+ G0 X[# +1]
+ G0 Z #13
+ g76 p#4 z#5 i-1 j1 k#3 h3 r1.5 q29.5 e0 l0
+
+ O51 ENDIF
+ G0 Z #13
+ m5 M9
+O endsub
+
+M2
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/tool.tbl b/linuxcnc/sim.gmoccapy.lathe_configs/tool.tbl
new file mode 100755
index 0000000..32d8777
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/tool.tbl
@@ -0,0 +1,19 @@
+T1 P1 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;# rh turning
+T2 P2 X-25.3242 Y0.0 Z15.924 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I80.0 J20.0 Q3.0 ;
+T3 P3 X-15.4825 Y0.0 Z258.6854 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D3.0 I90.0 J90.0 Q6.0 ;
+T4 P4 X-0.5336 Y0.0 Z54.9583 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I87.0 J40.0 Q2.0 ;
+T5 P5 X-15.0582 Y0.0 Z117.9963 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I60.0 J200.0 Q5.0 ;
+T6 P6 X2.6969 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.5 I120.0 J70.0 Q6.0 ;# threading
+T7 P7 X-8.408 Y0.0 Z13.7459 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.8 I107.5 J77.5 Q6.0 ;# vcmt110304
+T8 P8 X-11.16 Y0.0 Z-31.05 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I200.0 J300.0 Q8.0 ;
+T9 P9 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.1 I0.0 J0.0 Q9.0 ;
+T10 P10 X-0.07 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;
+T11 P11 X-23.0718 Y0.0 Z-3.7292 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;
+T12 P12 X-1.8392 Y0.0 Z-3.8279 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;
+T13 P13 X-10.8533 Y0.0 Z-6.2652 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;
+T14 P14 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I300.0 J200.0 Q4.0 ;
+T15 P15 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I200.0 J200.0 Q5.0 ;
+T16 P16 X-15.13 Y0.0 Z14.91 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I100.0 J60.0 Q6.0 ;
+T17 P17 X-15.14 Y0.0 Z5.992 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I-30.0 J30.0 Q7.0 ;
+T18 P18 X0.0 Y0.0 Z0.0 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I200.0 J300.0 Q8.0 ;
+T19 P19 X29.7817 Y0.0 Z-21.8231 A0.0 B0.0 C0.0 U0.0 V0.0 W0.0 D0.0 I0.0 J0.0 Q9.0 ;
diff --git a/linuxcnc/sim.gmoccapy.lathe_configs/turning.ngc b/linuxcnc/sim.gmoccapy.lathe_configs/turning.ngc
new file mode 100755
index 0000000..8dc3ec0
--- /dev/null
+++ b/linuxcnc/sim.gmoccapy.lathe_configs/turning.ngc
@@ -0,0 +1,66 @@
+;Turning
+
+O sub
+
+G8 ; Radius mode (easier maths)
+G18 ; XZ Plane
+G21 ; Metric Units
+G90 ; Absolute Distance
+G91.1 ; but not for arcs
+
+M6 T#8 G43
+
+#1 = [#1 / 2] ; because of radius mode
+#14 = [#<_x>] (starting X)
+#13 = #<_z> (starting Z)
+
+#20 = [#6 * SIN[#7]]
+#21 = [#6 * COS[#7]]
+#22 = [#6 / COS[#7]]
+#23 = [#5 + #6 - #20]
+#24 = [[#13 - #23] * TAN[#7]]
+
+G96 D2500 S#2 ; Constant Surface Speed Mode
+m3 ;Start Spindle
+g95 F#4 ; Feed-Per-Rev Mode
+
+O90 IF [#9 GT 0.5]
+ M8
+O90 ENDIF
+g4p1 ; Wait to reach speed
+
+ O100 WHILE [#14 GT [#1 + #3 / 2]]
+ g0 X #14
+ #14=[#14-#3 / 2]
+ G1 X #14
+ G1 Z #23 X[#14 + #24]
+ O101 IF [#6 GT 0]
+ G2 Z#5 X[#14 + #24 + #21] I#21 K#20
+ G1 X[#14 + #24 + #21 + #3/2]
+ O101 ELSE
+ G1 X[#14 + #24 + [#3 * .6]]
+ O101 ENDIF
+ O104 IF [#7 LT 0]
+ G0 X#14
+ O104 ENDIF
+ G0 Z[#13]
+ O100 ENDWHILE
+
+ G0 x#1
+ G1 Z #23 X[#1 + #24]
+ O102 IF [#6 GT 0]
+ G2 Z#5 X[#1 + #24 + #21] I#21 K#20
+ G1 X[#1 + #24 + #21 + #3]
+ O102 ELSE
+ G1 X[#1 + #24 + #3]
+ O102 ENDIF
+ O106 IF [#7 LT 0]
+ G0 X#14
+ O106 ENDIF
+ M9
+ G0 Z #13
+ G0 X #1 ; For touch-off
+ M5
+ G7
+O endsub
+M2