PID tuning: one vs multiple loops, gain scheduling

More
25 Oct 2014 04:52 - 25 Oct 2014 05:11 #52372 by DaBit
OK. so the answer to my original question is 'both'. I implemented an inner velocity loop, outer position loop, and used gain scheduling on the position loop based on position error.

Inner velocity loop, response to a small velocity step. That one is the worst case situation as PCW explained earlier. Resonances are mechanical; this servo uses a fairly long belt to drive the ballscrew.
I used a biquad filter on the velocity signal to smooth out the worst jitter without introducing much delay so I could use a bit more Dgain. Dgain is important in torque mode.
Current Fcutoff is 800Hz, Q=0,707 to get a flat response.



Positioning error when doing a 10 meter/minute (~400ipm) move. Scale is 0,02mm/division (0.00078"/div).
The cheap 5um Chinese scale on the X axis attaches it's carriage with a thin spring. That is clearly visible in the plot :)
With this low resolution and compliancy I decided to reduce the correction speed of the scale a lot.

When doing a slower move the error is much less.

www.icecoldcomputing.com/misc/xservopiv_ferror_10metermin.png


The amount of tuning parameters for a single axis is growing rapidly :cheer:



I have no hard measurement data, but the positioning speed and stiffness have increased at least an order of magnitude over a single non-gain-scheduling PID loop.
I am happy :)

I did not yet implement notching of mechanical resonances. I changed the mechanics a bit and I need a new belt. Before that one is mounted it makes no sense. However, I did improve the sinesweep component to include a log sweep also. I will post it on the wiki.

3 more servos to go and one 7i77 to modify....
Last edit: 25 Oct 2014 05:11 by DaBit.

Please Log in or Create an account to join the conversation.

More
25 Oct 2014 07:23 #52374 by Todd Zuercher
Sounds promising. Would your dual loop set up work with only a single input form an encoder, or is the linear scale required?

Please Log in or Create an account to join the conversation.

More
25 Oct 2014 13:48 #52382 by DaBit
The linear scale is not required, that is an extra loop.

Also in my situation the normal servo loop does all the positioning, the scale only says 'on average you are a little bit off, let's move to target slowly'. That 'you are a little bit off' can have multiple causes. For example: by comparing the position of the scale and ballscrew I can calculate the temperature in my shed :laugh:

Please Log in or Create an account to join the conversation.

More
26 Oct 2014 02:33 #52393 by DaBit
Did the Y axes today. Took me a bit more than an hour to modify the HAL file and tune the servos. The nested loops are fairly easy to tune once you get a feel for it.



Look good. And once again the positioning is a lot stiffer and speedier than it used to be.

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 05:33 #52415 by DaBit
Made a small change to the HAL file, and got a much improved response. Servos are silent also.



Wat did I do? I put the addf()'s in the correct order so execution of the various loops is correct. First read from the 7i77, then scale PID, then servo position, then servo velocity, then write to 7i77.
Andy once noticed that things are executed strictly in order, but somehow I still had the addf()'s in a nicely human-readable sort order. That costed me 3 servo periods to have everything ripple through.

I think that by now I proved well that torque mode control loop execution rate is very important. For my servos I would consider 3kHz the absolute minimum.


Now, I do want to try an even higher rate than 5kHz. Limiting factor is the 7i77; choose a 150usec servo thread rate and the error boxes about the serial IO start popping up.
But if I look at this list (halcmd show all | grep '\.time')
    25  s32   RO            456  SnSMill-correction.time
    13  s32   RO             28  coolant_or2.time
    28  s32   RO             32  flipflop_pause.time
    28  s32   RO            120  flipflop_resume.time
    28  s32   RO             32  flipflop_run.time
    23  s32   RO             36  hm2_5i25.0.pet_watchdog.time
    23  s32   RO         145296  hm2_5i25.0.read.time
    23  s32   RO              0  hm2_5i25.0.read_gpio.time
    23  s32   RO           4544  hm2_5i25.0.write.time
    23  s32   RO              0  hm2_5i25.0.write_gpio.time
    24  s32   RO            172  millturn-helper.0.time
     9  s32   RO            232  motion-command-handler.time
     9  s32   RO           3648  motion-controller.time
    16  s32   RO             60  offset_yjoints.update-feedback.time
    16  s32   RO            120  offset_yjoints.update-output.time
    21  s32   RO            212  sampler.0.time
    20  s32   RO             92  sinesweep.0.time
    12  s32   RO             68  xhomed_not.time
    14  s32   RO             68  xmaxsw_and2.time
    14  s32   RO            120  xminsw_and2.time
    18  s32   RO            132  xposerr_abs.time
    19  s32   RO            160  xposgain_lincurve.time
    10  s32   RO            904  xposition_pid.do-pid-calcs.time
    10  s32   RO            248  xscale_pid.do-pid-calcs.time
    15  s32   RO            136  xscale_sum2.time
    17  s32   RO           1836  xvelocity_filter.time
    10  s32   RO           1656  xvelocity_pid.do-pid-calcs.time
    18  s32   RO             44  y1poserr_abs.time
    19  s32   RO             44  y1posgain_lincurve.time
    10  s32   RO            192  y1position_pid.do-pid-calcs.time
    10  s32   RO            156  y1scale_pid.do-pid-calcs.time
    15  s32   RO             80  y1scale_sum2.time
    17  s32   RO             48  y1velocity_filter.time
    10  s32   RO            232  y1velocity_pid.do-pid-calcs.time
    18  s32   RO             88  y2poserr_abs.time
    19  s32   RO            128  y2posgain_lincurve.time
    10  s32   RO            320  y2position_pid.do-pid-calcs.time
    10  s32   RO            220  y2scale_pid.do-pid-calcs.time
    15  s32   RO             64  y2scale_sum2.time
    17  s32   RO             72  y2velocity_filter.time
    10  s32   RO            204  y2velocity_pid.do-pid-calcs.time
    12  s32   RO             32  yhomed_not.time
    13  s32   RO            108  yjoint_faultgen_or2_1.time
    13  s32   RO             56  yjoint_faultgen_or2_2.time
    11  s32   RO             96  yjoints_comp.time
    12  s32   RO            100  yjointscomp_not.time
    14  s32   RO             28  ymaxsw_and2.time
    14  s32   RO             32  yminsw_and2.time
    10  s32   RO            144  zscale_pid.do-pid-calcs.time
    15  s32   RO             80  zscale_sum2.time
    10  s32   RO            132  zservo_pid.do-pid-calcs.time

then it shows that the hm2_5i25.0.read function seems to consume a lot of CPU cycles, which limits maximum servo thread rate anyway.

@PCW: Would that improve when the smart serial bitrate is increased to 5Mbit or 10Mbit? If so, is this something I can do myself? I do have a PicKIT3 myself, access to an ICD3, and making a serial port that talks RS422 so I can communicate at 115k2 with the board wouldn't be a problem either.

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 08:34 - 27 Oct 2014 08:43 #52417 by PCW
Before you get too excited about increasing the loop rate, you might halscope the read /write and
perhaps motion controller times (your readout of those times is a snapshot of some very noisy signals)
(resetting the corresponding tmax's and watching them is interesting also)
you will likely find that you have latencies in them that will prevent much higher rates
(unless you have a PC with very low _actual_ latencies)

(that is the latency test doesn't tell the whole story)


The remote sserial baud rate is changed by setting the remotes baud rate setting in its EEPROM (via a serial command)
and changing the host interface baud rate. I will have to look into how the host interface baud rate can be changed
for a test
Last edit: 27 Oct 2014 08:43 by PCW.

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 15:52 #52422 by DaBit
I do not strictly need to increase thread rate; I am definitely on the path of diminishing returns. It is unrealistic to expect a dynamic positioning error much below, say, +/- 8 encoder counts and that's where I am now. It is just that nagging voice between my ears....
I ran that command multiple times, and the .time signals are indeed very noisy (do-pid-calcs varies between 200 and 1800 cycles, for example), but hm2_5i25.0.read is quite consistent in being high.

BTW: basically all I want to run at a high thread rate is the I/O, the velocity-PID's with their accompanying logic and possibly the servo position PID.
Linear scale PID, motion controller, additional signal juggling, etc. can all run at a lower rate.

Except for a single issue the PC (Asus P8Z77 mainboard+Celeron G550) is very good in the latency department. Plotting motion.servo.last-period-ns reveals that 99.99% of the time the jitter on the thread scheduling is very low (<5us) but once in a while there is a +30usec spike in the timing. It happens only once in a few seconds, for a single cycle only and I cannot measure or notice any influence on LinuxCNC operation or servo performance.

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 20:29 #52428 by Todd Zuercher
Would you mind sharing your configuration files? ( For the curious to look at.)

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 21:48 #52435 by DaBit
No problem. Just keep in mind that it is still a work in progress although I am quite happy with the current state.

I'll post them here in code blocks for easy viewability. If you prefer a .tar.gz, just shout.
If you need information about the construction of the mill: here is a topic in Dutch: www.cnczone.nl/viewtopic.php?f=8&t=8410.

SnSMill.ini
# INI file for DaBit's Stone-'n-Steel mill

[HOSTMOT2]
DRIVER=hm2_pci
BOARD=5i25
CONFIG="num_encoders=8 num_stepgens=2 sserial_port_0=0000xxxx"

[EMC]

# Name of machine, for use with display, etc.
MACHINE =               SnS_Mill

# Debug level, 0 means no messages. See src/emc/nml_int/emcglb.h for others
#DEBUG =                0x00000003
#DEBUG =                0x00000007
DEBUG = 0x0

[DISPLAY]
DISPLAY = gmoccapy
PREFERENCE_FILE_PATH = gmoccapy_preferences
DEFAULT_LINEAR_VELOCITY = 100.0
DEFAULT_ANGULAR_VELOCITY = 360.0
MAX_LINEAR_VELOCITY = 300.0
MAX_ANGULAR_VELOCITY = 30000.0
MAX_FEED_OVERRIDE = 2.5
MAX_SPINDLE_OVERRIDE = 2.0
MIN_SPINDLE_OVERRIDE = 0.5
EDITOR = leafpad
POSITION_OFFSET = 		RELATIVE
POSITION_FEEDBACK = 	ACTUAL
#POSITION_FEEDBACK = 	COMMANDED
INTRO_GRAPHIC = 		linuxcnc.gif
INTRO_TIME = 			5
PROGRAM_PREFIX = /home/dabit/linuxcnc/nc_files
INCREMENTS = 10mm 1mm .5mm .1mm .05mm .01mm .005mm
GEOMETRY = 		XYYZ
CYCLE_TIME = 			0.0500
#EMBED_TAB_NAME = Subroutines
#EMBED_TAB_COMMAND = halcmd loadusr -Wn gladevcp gladevcp -c bvh_subs -x {XID} bvh_subs.ui
#EMBED_TAB_NAME = Camera
#EMBED_TAB_COMMAND = mplayer -cache 128 -vf bmovl=0:0:tfifo -tv driver=v4l2:width=640:height=480 -wid {XID} tv://0
#GLADEVCP = sidepanel.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]
TASK =                  milltask
CYCLE_TIME =            0.010

[RS274NGC]
PARAMETER_FILE = 		SnSMill.var
SUBROUTINE_PATH = 		/home/dabit/linuxcnc/ngc_lib:/home/dabit/linuxcnc/m_codes
USER_M_PATH = 			/home/dabit/linuxcnc/m_codes


[EMCMOT]
EMCMOT = 			motmod
COMM_TIMEOUT = 			1.0
COMM_WAIT = 			0.010
SERVO_PERIOD = 			200000
BASE_PERIOD = 			200000

[HAL]
HALUI = 			halui
HALFILE = 			SnSMill.hal
HALFILE = 			SnS-xhc-hb04.hal
HALFILE = 			spindle.hal
POSTGUI_HALFILE = 		postgui.hal

[TRAJ]
AXES = 				4
COORDINATES = 			X Y Z A
LINEAR_UNITS = 			mm
ANGULAR_UNITS = 		degree
CYCLE_TIME = 			0.010
DEFAULT_VELOCITY = 		100.00
MAX_VELOCITY = 			300.00
DEFAULT_ACCELERATION =  2500.0
MAX_ACCELERATION =      2500.0
NO_FORCE_HOMING =		1
POSITION_FILE = 		machine_position.txt
ARC_BLEND_ENABLE = 		1
ARC_BLEND_FALLBACK_ENABLE = 	0
ARC_BLEND_OPTIMIZATION_DEPTH = 50
ARC_BLEND_GAP_CYCLES = 		4
ARC_BLEND_RAMP_FREQ = 		200

[EMCIO]
EMCIO =                 io
CYCLE_TIME =            0.100
TOOL_TABLE = 		tool.tbl

# X-axis: 
# - 8192 pulses/rev @ motor, 8192 pulses/rev @ leadscrew, leadscrew pitch=10mm = 819.2 pulses/mm
# - PID tuning params. Deadband is set to +/- 3 pulses. 

[AXIS_0]
TYPE =                  LINEAR
MAX_VELOCITY =          300.0
MAX_ACCELERATION =      2500.0
BACKLASH =              0.000
FERROR =                200
MIN_FERROR =            200
INPUT_SCALE =           -1259.492
INPUT_SCALE_LINEAR = 	-200
OUTPUT_SCALE =          3
OUTPUT_SCALE_NEG =	-3
OUTPUT_OFFSET =         0.0
MIN_LIMIT =             -518.0
MAX_LIMIT =             10.0
HOME =                  0.0
HOME_OFFSET =           0.0
HOME_SEARCH_VEL =       200.0
HOME_LATCH_VEL =        -2.0
HOME_USE_INDEX =        NO
HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 		2
VEL_P =                 0.018
VEL_I =                 1.5
VEL_D =                 0.000011
VEL_FF0 =               0.0005
VEL_FF1 =               8e-05
VEL_MAX_OUTPUT = 		3
VEL_FILTER_FC = 		800
POS_P_LO =              110
POS_P_HI = 				500
POS_P_ERR =				0.03
POS_I =                 0
POS_D =                 0
POS_FF0 =               0
POS_FF1 =               1
POS_FF2 =				0
POS_DEADBAND= 			0.003
POS_MAX_OUTPUT = 		700
SCALE_P =				0
SCALE_I = 				0
SCALE_DEADBAND = 		0.0051
SCALE_MAXCORR = 		2

# Y-axes:
# - 8192 pulses/rev @ motor, 12288 pulses/rev @ leadscrew, leadscrew pitch=10mm = 1228.8 pulses/mm
# - Allow +/- 0,5mm (== 1mm) deviation between the two Y axes

[AXIS_1]
TYPE =                  LINEAR
MAX_VELOCITY =          300.0
MAX_ACCELERATION =      2500.0
BACKLASH =              0.000
FERROR =                5
MIN_FERROR =            1
INPUT_SCALE =           -1227.6
INPUT_SCALE_LINEAR_Y1 = -1000
INPUT_SCALE_LINEAR_Y2 = -1000
OUTPUT_SCALE =          3
OUTPUT_SCALE_NEG =	-3
OUTPUT_OFFSET =         0.0
VEL_MAX_OUTPUT =        3
MIN_LIMIT =             -630.0
MAX_LIMIT =             25.0
HOME =                  0.000
HOME_OFFSET =           0.0
HOME_SEARCH_VEL =       200.0
HOME_LATCH_VEL =        -2.0
HOME_USE_INDEX =        NO
HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 	1
VEL_P =                 0.045
VEL_I =                 8
VEL_D =                 0.000012
VEL_FF0 =               0.005
VEL_FF1 =               9e-05
VEL_MAX_OUTPUT = 		3
VEL_FILTER_FC = 		1000
POS_P_LO =              250
POS_P_HI = 				900
POS_P_ERR =				0.03
POS_I =                 0
POS_D =                 0
POS_FF0 =               0
POS_FF1 =               1
POS_FF2 =				0
POS_DEADBAND= 			0.0015
POS_MAX_OUTPUT = 		700
SLAVEAXES_MAXDEVIATION=	1
SCALE_P =		0
SCALE_I = 		20
SCALE_D = 		0
SCALE_DEADBAND = 	0.0015
SCALE_MAXCORR = 	2


# Z-axis:
# - 200 fullsteps/rev, 16usteps = 3200 steps/rev. lead pitch = 5mm, coupling 1:1. Steps/mm = 6400/5=640

[AXIS_2]
TYPE =                  LINEAR
MAX_VELOCITY =          70.0
MAX_ACCELERATION =      800.0
STEPGEN_MAX_VELOCITY = 	80
STEPGEN_MAXACCEL = 	1200
BACKLASH =              0.000
FERROR =                5.0
MIN_FERROR =            2.0
MIN_LIMIT =             -199.0
MAX_LIMIT =             6.0
DIRSETUP = 		10000		
DIRHOLD = 		10000
STEPLEN = 		5000
STEPSPACE = 		5000
STEP_SCALE = 		641
INPUT_SCALE_LINEAR =	-1000
P =                     150
I =                     0
D =                     0
FF0 =                   0
FF1 =                   1
FF2 =			1e-06
BIAS = 			0
SCALE_P =		0
SCALE_I = 		60
SCALE_DEADBAND = 	0.003
SCALE_MAXCORR = 	5
HOME =                  0.000
HOME_OFFSET =           0
HOME_SEARCH_VEL =       75.0
HOME_LATCH_VEL =        -2.0
HOME_USE_INDEX =        NO
HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 	0

[AXIS_3]
TYPE =                  ANGULAR
MAX_VELOCITY =          18000
MAX_ACCELERATION =      30000
STEPGEN_MAX_VELOCITY = 	25000
STEPGEN_MAXACCEL = 	32000
BACKLASH =              0.000
FERROR =                50.0
MIN_FERROR =            10.0
MIN_LIMIT =             -858993.4592
MAX_LIMIT =             858993.4592
DIRSETUP = 		1000		
DIRHOLD = 		1000
STEPLEN = 		1000
STEPSPACE = 		1000
STEP_SCALE = 		1.736111
HOME =                  0.000
HOME_OFFSET =           0
HOME_SEARCH_VEL =       0.0
HOME_LATCH_VEL =        0.0
HOME_USE_INDEX =        NO
HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 	0

SnSMill.hal:
# #######################################
#
# HAL file for DaBit's Stone-'n-Steel mill
# Derived from Ted Hyde's original hm2-servo config
#
# #####################################################################


# ###################################
# Core EMC/HAL Loads
# ###################################

# kinematics
loadrt trivkins

# motion controller, get name and thread periods from ini file
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[TRAJ]AXES

# standard components
loadrt pid names=xvelocity_pid,xposition_pid,xscale_pid,y1velocity_pid,y1position_pid,y1scale_pid,y2velocity_pid,y2position_pid,y2scale_pid,zservo_pid,zscale_pid
loadrt comp names=yjoints_comp
loadrt not names=yjointscomp_not,xhomed_not,yhomed_not
loadrt or2 names=yjoint_faultgen_or2_1,yjoint_faultgen_or2_2,coolant_or2
loadrt and2 names=xminsw_and2,xmaxsw_and2,yminsw_and2,ymaxsw_and2
loadrt sum2 names=xscale_sum2,y1scale_sum2,y2scale_sum2,zscale_sum2
loadrt offset names=offset_yjoints
loadrt biquad names=xvelocity_filter,y1velocity_filter,y2velocity_filter
loadrt abs names=xposerr_abs,y1poserr_abs,y2poserr_abs
loadrt lincurve names=xposgain_lincurve,y1posgain_lincurve,y2posgain_lincurve personality=2,2,2

loadrt sinesweep
loadrt sampler depth=16 cfg=ff

# hostmot2 driver
loadrt hostmot2

# load low-level driver
loadrt [HOSTMOT2](DRIVER) config=[HOSTMOT2](CONFIG)
setp hm2_[HOSTMOT2](BOARD).0.watchdog.timeout_ns 10000000

# load millturn helper component and correction component
loadrt millturn_helper
loadrt SnSMill_correction


# ################################################
# THREADS
# ################################################

addf hm2_[HOSTMOT2](BOARD).0.read          	servo-thread

addf motion-command-handler            	servo-thread
addf motion-controller					servo-thread
addf SnSMill-correction					servo-thread
addf millturn-helper.0					servo-thread

addf xvelocity_filter					servo-thread	
addf y1velocity_filter					servo-thread
addf y2velocity_filter					servo-thread
addf xscale_pid.do-pid-calcs			servo-thread
addf xscale_sum2						servo-thread
addf xposerr_abs						servo-thread
addf xposgain_lincurve					servo-thread
addf xposition_pid.do-pid-calcs			servo-thread
addf xvelocity_pid.do-pid-calcs			servo-thread
addf offset_yjoints.update-output 		servo-thread
addf offset_yjoints.update-feedback		servo-thread
addf y1scale_pid.do-pid-calcs			servo-thread
addf y1scale_sum2						servo-thread
addf y1poserr_abs						servo-thread
addf y1posgain_lincurve					servo-thread
addf y1position_pid.do-pid-calcs		servo-thread
addf y1velocity_pid.do-pid-calcs		servo-thread
addf y2scale_pid.do-pid-calcs			servo-thread
addf y2scale_sum2						servo-thread
addf y2poserr_abs						servo-thread
addf y2posgain_lincurve					servo-thread
addf y2position_pid.do-pid-calcs		servo-thread
addf y2velocity_pid.do-pid-calcs		servo-thread
addf zscale_pid.do-pid-calcs			servo-thread
addf zscale_sum2						servo-thread
addf zservo_pid.do-pid-calcs			servo-thread

addf yjoints_comp				servo-thread  
addf yjointscomp_not			servo-thread  
addf xhomed_not					servo-thread
addf yhomed_not					servo-thread
addf yjoint_faultgen_or2_1			servo-thread   
addf yjoint_faultgen_or2_2			servo-thread   
addf coolant_or2				servo-thread
addf xminsw_and2				servo-thread
addf xmaxsw_and2				servo-thread
addf yminsw_and2				servo-thread
addf ymaxsw_and2				servo-thread
addf sinesweep.0				servo-thread
addf sampler.0					servo-thread	
			
addf hm2_[HOSTMOT2](BOARD).0.write		servo-thread
addf hm2_[HOSTMOT2](BOARD).0.pet_watchdog	servo-thread

# ################
# X [0] Axis
# ################

# axis enable chain
net xenable <= axis.0.amp-enable-out
net xenable => xvelocity_filter.enable => xvelocity_pid.enable => xposition_pid.enable => xscale_pid.enable
net xenable => hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogena
 
# encoder feedback, rotary
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.index-mask-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.00.scale  [AXIS_0]INPUT_SCALE
net xpos-servo-fb hm2_[HOSTMOT2](BOARD).0.encoder.00.position => xposition_pid.feedback
net xvel <= hm2_[HOSTMOT2](BOARD).0.encoder.00.velocity => xvelocity_filter.in
net xvel-filt xvelocity_filter.out => xposition_pid.feedback-deriv => xvelocity_pid.feedback
setp xvelocity_filter.type 1
setp xvelocity_filter.f0 [AXIS_0]VEL_FILTER_FC
setp xvelocity_filter.Q 0.707

# encoder feedback, linear
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.index-mask-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.03.scale  [AXIS_0]INPUT_SCALE_LINEAR

# index homing, position feedback
net xindex_enable hm2_[HOSTMOT2](BOARD).0.encoder.03.index-enable <=> hm2_[HOSTMOT2](BOARD).0.encoder.00.index-enable <=> axis.0.index-enable <=> xposition_pid.index-enable <=> xscale_pid.index-enable
net xscalepos <= hm2_[HOSTMOT2](BOARD).0.encoder.03.position => xscale_pid.feedback => axis.0.motor-pos-fb

# set PID loop gains from inifile
setp xvelocity_pid.Pgain [AXIS_0]VEL_P
setp xvelocity_pid.Igain [AXIS_0]VEL_I
setp xvelocity_pid.Dgain [AXIS_0]VEL_D
setp xvelocity_pid.FF0 [AXIS_0]VEL_FF0
setp xvelocity_pid.FF1 [AXIS_0]VEL_FF1
setp xvelocity_pid.FF2 0.0
setp xvelocity_pid.maxoutput [AXIS_0]VEL_MAX_OUTPUT
setp xvelocity_pid.error-previous-target 1

net xpos-err xposition_pid.error xposerr_abs.in
net xpos-err-abs xposerr_abs.out xposgain_lincurve.in
setp xposgain_lincurve.x-val-00 0.0
setp xposgain_lincurve.y-val-00 [AXIS_0]POS_P_LO
setp xposgain_lincurve.x-val-01 [AXIS_0]POS_P_ERR
setp xposgain_lincurve.y-val-01 [AXIS_0]POS_P_HI
net xpospidP xposgain_lincurve.out xposition_pid.Pgain
setp xposition_pid.Igain [AXIS_0]POS_I
setp xposition_pid.Dgain [AXIS_0]POS_D
setp xposition_pid.FF0 [AXIS_0]POS_FF0
setp xposition_pid.FF1 [AXIS_0]POS_FF1
setp xposition_pid.FF2 [AXIS_0]POS_FF2
setp xposition_pid.deadband [AXIS_0]POS_DEADBAND
setp xposition_pid.maxoutput [AXIS_0]POS_MAX_OUTPUT
setp xposition_pid.error-previous-target 1


setp xscale_pid.Pgain [AXIS_0]SCALE_P
setp xscale_pid.Igain [AXIS_0]SCALE_I
setp xscale_pid.deadband [AXIS_0]SCALE_DEADBAND
setp xscale_pid.FF0 0.0
setp xscale_pid.maxerrorI [AXIS_0]SCALE_MAXCORR
setp xscale_pid.maxoutput [AXIS_0]SCALE_MAXCORR
setp xscale_pid.error-previous-target 1

# position command signals

# linear scale position PID

net xpos-cmd axis.0.motor-pos-cmd => SnSMill-correction.x-motorposcmd-in
net xjoint-cmd axis.0.joint-pos-cmd => SnSMill-correction.x-jointposcmd-in
net xpos-cmd-corrected SnSMill-correction.x-motorposcmd-out xscale_pid.command xscale_sum2.in0
net xpos-scalepidoutput xscale_pid.output => xscale_sum2.in1
net xpos-corrected xscale_sum2.out => xposition_pid.command

# X position PID -> X velocity PID -> Mesa 7i77
net xvel-cmd xposition_pid.output => xvelocity_pid.command
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout0-scalemax [AXIS_0]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout0-maxlim [AXIS_0]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout0-minlim [AXIS_0]OUTPUT_SCALE_NEG
net xmotor-command xvelocity_pid.output  =>  hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout0

# Home switch/index logic
net homesw-x <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-08-not => axis.0.home-sw-in

# X-axis limit switch logic
net xminsw-x hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-09-not => xminsw_and2.in0
net homesw-x xmaxsw_and2.in0
net x-is-homed <= axis.0.homed => xhomed_not.in
net x-not-homed <= xhomed_not.out => xminsw_and2.in1 => xmaxsw_and2.in1
net x-minlimsw <= xminsw_and2.out => axis.0.neg-lim-sw-in
net x-maxlimsw <= xmaxsw_and2.out => axis.0.pos-lim-sw-in


# ################
# Y [1] Axis, joint 1 (left)
# ################

# axis enable chain
net yenable1 <= axis.1.amp-enable-out
net yenable1 => y1velocity_filter.enable => y1velocity_pid.enable => y1position_pid.enable => y1scale_pid.enable

 
# encoder feedback, rotary
setp hm2_[HOSTMOT2](BOARD).0.encoder.01.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.01.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.01.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.01.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.01.index-mask-invert 0
setp  hm2_[HOSTMOT2](BOARD).0.encoder.01.scale  [AXIS_1]INPUT_SCALE
net y1pos-servo-fb hm2_[HOSTMOT2](BOARD).0.encoder.01.position => y1position_pid.feedback
net y1vel-uf <= hm2_[HOSTMOT2](BOARD).0.encoder.01.velocity => y1velocity_filter.in
net y1vel y1velocity_filter.out => y1position_pid.feedback-deriv => y1velocity_pid.feedback
setp y1velocity_filter.type 1
setp y1velocity_filter.f0 [AXIS_1]VEL_FILTER_FC
setp y1velocity_filter.Q 0.707

# encoder feedback, linear
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.index-mask-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.06.scale  [AXIS_1]INPUT_SCALE_LINEAR_Y1

net y1scalepos <= hm2_[HOSTMOT2](BOARD).0.encoder.06.position => y1scale_pid.feedback => axis.1.motor-pos-fb

# set PID loop gains from inifile
setp y1velocity_pid.Pgain [AXIS_1]VEL_P
setp y1velocity_pid.Igain [AXIS_1]VEL_I
setp y1velocity_pid.Dgain [AXIS_1]VEL_D
setp y1velocity_pid.FF0 [AXIS_1]VEL_FF0
setp y1velocity_pid.FF1 [AXIS_1]VEL_FF1
setp y1velocity_pid.FF2 0.0
setp y1velocity_pid.maxoutput [AXIS_1]VEL_MAX_OUTPUT
setp y1velocity_pid.error-previous-target 1

net y1pos-err y1position_pid.error y1poserr_abs.in
net y1pos-err-abs y1poserr_abs.out y1posgain_lincurve.in
setp y1posgain_lincurve.x-val-00 0.0
setp y1posgain_lincurve.y-val-00 [AXIS_1]POS_P_LO
setp y1posgain_lincurve.x-val-01 [AXIS_1]POS_P_ERR
setp y1posgain_lincurve.y-val-01 [AXIS_1]POS_P_HI
net y1pospidP y1posgain_lincurve.out y1position_pid.Pgain
setp y1position_pid.Igain [AXIS_1]POS_I
setp y1position_pid.Dgain [AXIS_1]POS_D
setp y1position_pid.FF0 [AXIS_1]POS_FF0
setp y1position_pid.FF1 [AXIS_1]POS_FF1
setp y1position_pid.FF2 [AXIS_1]POS_FF2
setp y1position_pid.deadband [AXIS_1]POS_DEADBAND
setp y1position_pid.maxoutput [AXIS_1]POS_MAX_OUTPUT
setp y1position_pid.error-previous-target 1

setp y1scale_pid.Pgain [AXIS_1]SCALE_P
setp y1scale_pid.Igain [AXIS_1]SCALE_I
setp y1scale_pid.Dgain [AXIS_1]SCALE_D
setp y1scale_pid.deadband [AXIS_1]SCALE_DEADBAND
setp y1scale_pid.FF0 0.0
setp y1scale_pid.maxerrorI [AXIS_1]SCALE_MAXCORR
setp y1scale_pid.maxoutput [AXIS_1]SCALE_MAXCORR
setp y1scale_pid.error-previous-target 1

# position command signals; correction from the scale and Z axis slant
net y1pos-cmd axis.1.motor-pos-cmd => SnSMill-correction.y-motorposcmd-in
net y1joint-cmd axis.1.joint-pos-cmd => SnSMill-correction.y-jointposcmd-in
net y1pos-cmd-corrected SnSMill-correction.y-motorposcmd-out => y1scale_pid.command => y1scale_sum2.in0
net y1pos-scalepidoutput y1scale_pid.output => y1scale_sum2.in1
net y1pos-corrected y1scale_sum2.out => y1position_pid.command

net y1vel-cmd y1position_pid.output => y1velocity_pid.command
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout1-scalemax [AXIS_1]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout1-maxlim [AXIS_1]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout1-minlim [AXIS_1]OUTPUT_SCALE_NEG
net y1motor-command  y1velocity_pid.output  =>  hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout1

# Home switch/index logic
net homesw-y <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-10-not => axis.1.home-sw-in
#net yindex_enable hm2_[HOSTMOT2](BOARD).0.encoder.06.index-enable <=> hm2_[HOSTMOT2](BOARD).0.encoder.01.index-enable <=> axis.1.index-enable <=> y1servo_pid.index-enable <=> y1scale_pid.index-enable

# Y-axis limit switch logic
net yminsw-y hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-11-not => yminsw_and2.in0
net homesw-y ymaxsw_and2.in0
net y-is-homed <= axis.1.homed => yhomed_not.in
net y-not-homed <= yhomed_not.out => yminsw_and2.in1 => ymaxsw_and2.in1
net y-minlimsw <= yminsw_and2.out => axis.1.neg-lim-sw-in
net y-maxlimsw <= ymaxsw_and2.out => axis.1.pos-lim-sw-in


# ################
# Y [2] Axis, joint 2 (right)
# ################

# axis enable chain
net yenable1 => y2velocity_filter.enable => y2velocity_pid.enable => y2position_pid.enable => y2scale_pid.enable
 
# encoder feedback
setp hm2_[HOSTMOT2](BOARD).0.encoder.02.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.02.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.02.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.02.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.02.index-mask-invert 0
setp  hm2_[HOSTMOT2](BOARD).0.encoder.02.scale  [AXIS_1]INPUT_SCALE
net ypos-fb2-int hm2_[HOSTMOT2](BOARD).0.encoder.02.position => y2position_pid.feedback => 
net y2vel-uf <= hm2_[HOSTMOT2](BOARD).0.encoder.02.velocity => y2velocity_filter.in
net y2vel y2velocity_filter.out => y2position_pid.feedback-deriv => y2velocity_pid.feedback
setp y2velocity_filter.type 1
setp y2velocity_filter.f0 [AXIS_1]VEL_FILTER_FC
setp y2velocity_filter.Q 0.707

# scale feedback
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.index-mask-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.05.scale  [AXIS_1]INPUT_SCALE_LINEAR_Y2

net y2scalepos-offsetted <= hm2_[HOSTMOT2](BOARD).0.encoder.05.position => y2scale_pid.feedback => offset_yjoints.fb-in
net y2scalepos offset_yjoints.fb-out


# set PID loop gains from inifile
setp y2velocity_pid.Pgain [AXIS_1]VEL_P
setp y2velocity_pid.Igain [AXIS_1]VEL_I
setp y2velocity_pid.Dgain [AXIS_1]VEL_D
setp y2velocity_pid.FF0 [AXIS_1]VEL_FF0
setp y2velocity_pid.FF1 [AXIS_1]VEL_FF1
setp y2velocity_pid.FF2 0.0
setp y2velocity_pid.maxoutput [AXIS_1]VEL_MAX_OUTPUT
setp y2velocity_pid.error-previous-target 1

net y2pos-err y2position_pid.error y2poserr_abs.in
net y2pos-err-abs y2poserr_abs.out y2posgain_lincurve.in
setp y2posgain_lincurve.x-val-00 0.0
setp y2posgain_lincurve.y-val-00 [AXIS_1]POS_P_LO
setp y2posgain_lincurve.x-val-01 [AXIS_1]POS_P_ERR
setp y2posgain_lincurve.y-val-01 [AXIS_1]POS_P_HI
net y2pospidP y2posgain_lincurve.out y2position_pid.Pgain
setp y2position_pid.Igain [AXIS_1]POS_I
setp y2position_pid.Dgain [AXIS_1]POS_D
setp y2position_pid.FF0 [AXIS_1]POS_FF0
setp y2position_pid.FF1 [AXIS_1]POS_FF1
setp y2position_pid.FF2 [AXIS_1]POS_FF2
setp y2position_pid.deadband [AXIS_1]POS_DEADBAND
setp y2position_pid.maxoutput [AXIS_1]POS_MAX_OUTPUT
setp y2position_pid.error-previous-target 1

setp y2scale_pid.Pgain [AXIS_1]SCALE_P
setp y2scale_pid.Igain [AXIS_1]SCALE_I
setp y2scale_pid.Dgain [AXIS_1]SCALE_D
setp y2scale_pid.deadband [AXIS_1]SCALE_DEADBAND
setp y2scale_pid.FF0 0.0
setp y2scale_pid.maxerrorI [AXIS_1]SCALE_MAXCORR
setp y2scale_pid.maxoutput [AXIS_1]SCALE_MAXCORR
setp y2scale_pid.error-previous-target 1

# position command signals
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout2-scalemax [AXIS_1]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout2-maxlim [AXIS_1]OUTPUT_SCALE
setp hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout2-minlim [AXIS_1]OUTPUT_SCALE_NEG

net y1pos-cmd-corrected => offset_yjoints.in
net y2pos_offsetted <= offset_yjoints.out => y2scale_pid.command => y2scale_sum2.in0
net y2pos-scalepidoutput y2scale_pid.output => y2scale_sum2.in1
net y2pos-corrected y2scale_sum2.out => y2position_pid.command
net y2vel-cmd y2position_pid.output => y2velocity_pid.command
net y2motor-command y2velocity_pid.output  =>  hm2_[HOSTMOT2](BOARD).0.7i77.0.1.analogout2

# Y-axis joint2 offset/squaring logic
setp offset_yjoints.offset 0.0

# index
#net yindex_enable hm2_[HOSTMOT2](BOARD).0.encoder.02.index-enable <=> hm2_[HOSTMOT2](BOARD).0.encoder.05.index-enable <=> y2servo_pid.index-enable <=> y2scale_pid.index-enable


# ################
# Z Axis
# ################

setp   hm2_5i25.0.stepgen.00.dirsetup        [AXIS_2]DIRSETUP
setp   hm2_5i25.0.stepgen.00.dirhold         [AXIS_2]DIRHOLD
setp   hm2_5i25.0.stepgen.00.steplen         [AXIS_2]STEPLEN
setp   hm2_5i25.0.stepgen.00.stepspace       [AXIS_2]STEPSPACE
setp   hm2_5i25.0.stepgen.00.position-scale  [AXIS_2]STEP_SCALE
setp   hm2_5i25.0.stepgen.00.step_type        0
setp   hm2_5i25.0.stepgen.00.control-type     1
setp   hm2_5i25.0.stepgen.00.maxaccel         [AXIS_2]STEPGEN_MAXACCEL
setp   hm2_5i25.0.stepgen.00.maxvel           [AXIS_2]STEPGEN_MAX_VELOCITY

# encoder feedback, linear
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.counter-mode 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.filter 1
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.index-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.index-mask 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.index-mask-invert 0
setp hm2_[HOSTMOT2](BOARD).0.encoder.04.scale  [AXIS_2]INPUT_SCALE_LINEAR

# set PID loop gains from inifile
setp zservo_pid.Pgain [AXIS_2]P
setp zservo_pid.Igain [AXIS_2]I
setp zservo_pid.Dgain [AXIS_2]D
setp zservo_pid.bias [AXIS_2]BIAS
setp zservo_pid.FF0 [AXIS_2]FF0
setp zservo_pid.FF1 [AXIS_2]FF1
setp zservo_pid.FF2 [AXIS_2]FF2
setp zservo_pid.maxoutput [AXIS_2]STEPGEN_MAX_VELOCITY
setp zservo_pid.error-previous-target 1

setp zscale_pid.Pgain [AXIS_2]SCALE_P
setp zscale_pid.Igain [AXIS_2]SCALE_I
setp zscale_pid.deadband [AXIS_2]SCALE_DEADBAND
setp zscale_pid.FF0 0.0
setp zscale_pid.maxerrorI [AXIS_2]SCALE_MAXCORR
setp zscale_pid.maxoutput [AXIS_2]SCALE_MAXCORR
setp zscale_pid.error-previous-target 1

net z-pos-cmd 	axis.2.motor-pos-cmd => SnSMill-correction.z-motorposcmd-in
net z-joint-cmd axis.2.joint-pos-cmd => SnSMill-correction.z-jointposcmd-in
net zpos-cmd-corrected SnSMill-correction.z-motorposcmd-out => zscale_pid.command => zscale_sum2.in0
net z-pos-fb     axis.2.motor-pos-fb   <=  hm2_[HOSTMOT2](BOARD).0.encoder.04.position => zscale_pid.feedback
net z-pos-pidout zscale_pid.output  => zscale_sum2.in1
net z-pos-summed zscale_sum2.out => zservo_pid.command
net z-servo-pos-fb 	hm2_5i25.0.stepgen.00.position-fb => zservo_pid.feedback
net z-vel	zservo_pid.output => hm2_5i25.0.stepgen.00.velocity-cmd
net z-enable     axis.2.amp-enable-out =>  hm2_5i25.0.stepgen.00.enable => zscale_pid.enable => zservo_pid.enable

net homesw-z <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-14-not => axis.2.home-sw-in


# ################
# Mill/turn helper component to allow A-axis to function as lathe
# ################

setp millturn-helper.0.joint-max-acceleration [AXIS_3]MAX_ACCELERATION
setp millturn-helper.0.joint-max-velocity [AXIS_3]MAX_VELOCITY
# The speed scale is used to go from rev/min to units/sec
setp millturn-helper.0.speed-scale 6
# And we need to know the unit system. Standard is degrees: 360 per rev.
setp millturn-helper.0.units-per-rev 360

net apos-cmd-in axis.3.motor-pos-cmd => millturn-helper.0.position-cmd
net apos-fb-out millturn-helper.0.position-fb => axis.3.motor-pos-fb
net millturn-helper-mode millturn-helper.0.mode
net millturn-helper-secspindlespeed millturn-helper.0.secondary-spindle-speed
net millturn-helper-isbusy millturn-helper.0.is-busy

# ################
# A Axis
# ################

setp   hm2_5i25.0.stepgen.01.dirsetup        [AXIS_3]DIRSETUP
setp   hm2_5i25.0.stepgen.01.dirhold         [AXIS_3]DIRHOLD
setp   hm2_5i25.0.stepgen.01.steplen         [AXIS_3]STEPLEN
setp   hm2_5i25.0.stepgen.01.stepspace       [AXIS_3]STEPSPACE
setp   hm2_5i25.0.stepgen.01.position-scale  [AXIS_3]STEP_SCALE
setp   hm2_5i25.0.stepgen.01.step_type        2
setp   hm2_5i25.0.stepgen.01.control-type     0
setp   hm2_5i25.0.stepgen.01.maxaccel         [AXIS_3]STEPGEN_MAXACCEL
setp   hm2_5i25.0.stepgen.01.maxvel           [AXIS_3]STEPGEN_MAX_VELOCITY

net a-enable    axis.3.amp-enable-out =>  hm2_5i25.0.stepgen.01.enable
net a-pos-cmd 	millturn-helper.0.joint-position-cmd => hm2_5i25.0.stepgen.01.position-cmd
net a-pos-fb 	hm2_5i25.0.stepgen.01.position-fb => millturn-helper.0.joint-position-fb

# ################
# Y-axis position verification: check if the Y-axes don't deviate too much
# ################

net y1scalepos => yjoints_comp.in0
net y2scalepos => yjoints_comp.in1
setp yjoints_comp.hyst [AXIS_1]SLAVEAXES_MAXDEVIATION
net yaxes_equal yjoints_comp.equal => yjointscomp_not.in
net slavedaxes_err <= yjointscomp_not.out

# ################
# Amplifier fault logic. Also (mis)used to signal slaved Y-axes position deviation
# sets-es are there until servos are wired completely
# ################

net jointXampfault <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-01-not => axis.0.amp-fault-in

net jointY1ampfault <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-02-not => yjoint_faultgen_or2_1.in0
net jointY2ampfault <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-03-not => yjoint_faultgen_or2_1.in1
net yjoints-ampfault <= yjoint_faultgen_or2_1.out => yjoint_faultgen_or2_2.in0
net slavedaxes_err => yjoint_faultgen_or2_2.in1
net jointYampfault_p <= yjoint_faultgen_or2_2.out => axis.1.amp-fault-in

net jointZampfault => axis.2.amp-fault-in
sets jointZampfault 0


# ################
# EStop chain.
# ################

net estop-out <= iocontrol.0.user-enable-out
net estop-ext => iocontrol.0.emc-enable-in <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.input-00

# ################
# Motor power relay control
# ################

#net motor-power => hm2_[HOSTMOT2](BOARD).0.7i77.0.0.output-00
#sets motor-power FALSE
net estop-ext <= hm2_[HOSTMOT2](BOARD).0.7i77.0.0.output-00

# ################
# Mist coolant solenoid
# ################

net mistcoolant <= iocontrol.0.coolant-mist => coolant_or2.in0
net floodcoolant <= iocontrol.0.coolant-flood => coolant_or2.in1
net mister-enable <= coolant_or2.out => hm2_[HOSTMOT2](BOARD).0.7i77.0.0.output-04 => hm2_[HOSTMOT2](BOARD).0.7i77.0.0.output-05


# ################
# Toolchanger
# ################

#loadusr -W hal_manualtoolchange
#net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change
#net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed
#net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number
#net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared

And for completeness:

postgui.hal
# MPG buttons to gmoccapy jog
net jog-x-plus xhc-hb04.button-macro3 => gmoccapy.jog-x-plus
net jog-x-minus xhc-hb04.button-macro1 => gmoccapy.jog-x-minus 

net jog-y-plus xhc-hb04.button-iszero => gmoccapy.jog-y-plus 
net jog-y-minus xhc-hb04.button-macro6 => gmoccapy.jog-y-minus

net jog-z-plus xhc-hb04.button-safe-z => gmoccapy.jog-z-plus 
net jog-z-minus xhc-hb04.button-macro7 => gmoccapy.jog-z-minus

# Use gmoccapy toolchanger..
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 tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared

# display tool offsets in gmoccapy
net tooloffset-x  gmoccapy.tooloffset-x  <=  motion.tooloffset.x
net tooloffset-z  gmoccapy.tooloffset-z  <=  motion.tooloffset.z

# spindle stuff
loadusr -W vlt5000_vfd --device=/dev/ttyUSB3
setp vlt5000-vfd.0.devslaveaddr 1
setp vlt5000-vfd.0.speedscale 0.05
net spindlespeed motion.spindle-speed-out-abs => vlt5000-vfd.0.commanded-speed
net spindleon motion.spindle-on => vlt5000-vfd.0.run
net spindleatspeed vlt5000-vfd.0.is-at-speed => motion.spindle-at-speed

# gmoccapy spindle bar
net spindlespeed => gmoccapy.spindle_feedback_bar
net spindleatspeed => gmoccapy.spindle_at_speed_led

SnS-xhc-hb04.hal
loadusr -W xhc-hb04 -I xhc-hb04-layoutbvh.ini -H

# Home button
net home halui.home-all <= xhc-hb04.button-home

# Absolute position LCD
net pos-x halui.axis.0.pos-feedback => xhc-hb04.x.pos-absolute
net pos-y halui.axis.1.pos-feedback => xhc-hb04.y.pos-absolute
net pos-z halui.axis.2.pos-feedback => xhc-hb04.z.pos-absolute

# Relative position LCD
net pos-rel-x halui.axis.0.pos-relative => xhc-hb04.x.pos-relative
net pos-rel-y halui.axis.1.pos-relative => xhc-hb04.y.pos-relative
net pos-rel-z halui.axis.2.pos-relative => xhc-hb04.z.pos-relative

# Jog wheel and axis selection button
net jog-x axis.0.jog-enable <= xhc-hb04.jog.enable-x
net jog-y axis.1.jog-enable <= xhc-hb04.jog.enable-y
net jog-z axis.2.jog-enable <= xhc-hb04.jog.enable-z
net jog-a axis.3.jog-enable <= xhc-hb04.jog.enable-a

net jog-scale xhc-hb04.jog.scale => axis.0.jog-scale axis.1.jog-scale axis.2.jog-scale axis.3.jog-scale
net jog-counts xhc-hb04.jog.counts => axis.0.jog-counts axis.1.jog-counts axis.3.jog-counts
net jog-counts-neg xhc-hb04.jog.counts-neg => axis.2.jog-counts
net jog-speed halui.jog-speed <= halui.max-velocity.value
net jog-stepup xhc-hb04.button-step xhc-hb04.stepsize-up

# Wheel for feedrate and spindle
setp halui.feed-override.scale 0.01
net jog-counts => halui.feed-override.counts
net jog-feed halui.feed-override.count-enable <= xhc-hb04.jog.enable-feed-override
net jog-feed2 halui.feed-override.value => xhc-hb04.feed-override

#BvH: spindle stop
net stop-spindle halui.spindle.stop <= xhc-hb04.button-spindle

setp halui.spindle-override.scale 0.01
net jog-counts => halui.spindle-override.counts
net jog-spindle halui.spindle-override.count-enable <= xhc-hb04.jog.enable-spindle-override
net jog-spindle2 halui.spindle-override.value => xhc-hb04.spindle-override
net spindle-rps motion.spindle-speed-cmd-rps => xhc-hb04.spindle-rps

# RESET/ESTOP button
net estop xhc-hb04.button-reset => halui.estop.activate

# Program control

loadrt flipflop names=flipflop_resume,flipflop_pause,flipflop_run

addf flipflop_resume servo-thread
addf flipflop_pause servo-thread
addf flipflop_run servo-thread

net button-stop xhc-hb04.button-stop => halui.program.stop
net button-start-pause xhc-hb04.button-start-pause => flipflop_pause.clk flipflop_resume.clk flipflop_run.clk

net is-paused halui.program.is-paused => flipflop_resume.data flipflop_pause.reset
net is-running halui.program.is-running => flipflop_pause.data flipflop_run.reset flipflop_resume.reset
net is-idle halui.program.is-idle => flipflop_run.data

net resume flipflop_resume.out => halui.program.resume
net pause flipflop_pause.out => halui.program.pause
net run flipflop_run.out => halui.program.run

#net step xhc-hb04.button-rewind => halui.program.step

# X=0, Y=0, Z=0 
#net x0 halui.mdi-command-06 xhc-hb04.button-x0
#net y0 halui.mdi-command-07 xhc-hb04.button-y0
#net z0 halui.mdi-command-08 xhc-hb04.button-z0
#net origin halui.mdi-command-09 xhc-hb04.button-goto-zero
#net safe-z halui.mdi-command-10 xhc-hb04.button-safe-z
#net park halui.mdi-command-11 xhc-hb04.button-x2

Please Log in or Create an account to join the conversation.

More
27 Oct 2014 23:44 #52447 by PCW
BTW tested a 7I77 with a fast host machine (Pentium G3258/H81 MB), 8 KHz is achievable with stock serial baud rate (2.5 MB)

This system shows very good RTAI latency (~4 usec base, ~3 usec servo thread latencies) and very consistent function times

Please Log in or Create an account to join the conversation.

Time to create page: 0.232 seconds
Powered by Kunena Forum