# PID loop test HAL config file for servos # # Do not run this script while you are running emc! # Run it with: # halrun -I motenc_pidtest.hal # first load the motenc driver loadrt hal_motenc # and create a 1mS thread loadrt threads name1=motenc.thread period1=1000000 # then load the PID module, for three PID loops loadrt pid num_chan=3 # and load the signal generator module loadrt siggen # hook functions to realtime thread addf motenc.0.encoder-read motenc.thread addf motenc.0.digital-in-read motenc.thread addf siggen.0.update motenc.thread addf pid.0.do-pid-calcs motenc.thread addf pid.1.do-pid-calcs motenc.thread addf pid.2.do-pid-calcs motenc.thread addf motenc.0.digital-out-write motenc.thread addf motenc.0.dac-write motenc.thread # create three position feedback signals # connect position feedback signals to encoders net Xpos-fb <= motenc.0.enc-00-position net Ypos-fb <= motenc.0.enc-01-position net Zpos-fb <= motenc.0.enc-02-position # set feedback scaling # this is just an example # 8192 counts/rev * 10 turns per inch = 81920 counts/in # setp motenc.0.enc-00-scale 81920 setp motenc.0.enc-01-scale 81920 setp motenc.0.enc-02-scale 81920 # NOTE: you may want to comment out everything after here, # and run it... manually move the machine X axis by 1 inch # and verify that Xpos-fb changes by exactly 1 inch. Then # do the same for Y and Z. Change the scale factors above # as needed until it is right. Once you know that the # scaling is correct, uncomment the following stuff and # continue on. # connect position feedback to PID loop net Xpos-fb => pid.0.feedback net Ypos-fb => pid.1.feedback net Zpos-fb => pid.2.feedback # create PID to DAC output signals # connect output signals to DACs net Xoutput => motenc.0.dac-00-value net Youtput => motenc.0.dac-01-value net Zoutput => motenc.0.dac-02-value # set offset and scale so that +/-1.00 on output # signals is +/-10V at the physical DAC pins setp motenc.0.dac-00-gain 10 setp motenc.0.dac-01-gain 10 setp motenc.0.dac-02-gain 10 setp motenc.0.dac-00-offset 0 setp motenc.0.dac-01-offset 0 setp motenc.0.dac-02-offset 0 # connect output signals to output of PID loops 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 1 setp pid.1.maxoutput 1 setp pid.2.maxoutput 1 # 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. setp pid.0.Pgain 0.01 setp pid.0.Igain 0 setp pid.0.Dgain 0 setp pid.0.bias 0 setp pid.0.FF0 0 setp pid.0.FF1 0 setp pid.0.FF2 0 # deadband should be just over 1 count setp pid.0.deadband 0.000015 setp pid.1.Pgain 0.01 setp pid.1.Igain 0 setp pid.1.Dgain 0 setp pid.1.bias 0 setp pid.1.FF0 0 setp pid.1.FF1 0 setp pid.1.FF2 0 setp pid.1.deadband 0.000015 setp pid.2.Pgain 0.01 setp pid.2.Igain 0 setp pid.2.Dgain 0 setp pid.2.bias 0 setp pid.2.FF0 0 setp pid.2.FF1 0 setp pid.2.FF2 0 setp pid.2.deadband 0.000015 # create three position command signals # eventually, these will come from EMC # connect position commands to PID input net Xpos-cmd => pid.0.command net Ypos-cmd => pid.1.command net Zpos-cmd => pid.2.command # connect the signal generator sine and cosine outputs # to X and Y position commands # this will make the machine move in a circle # Note that Z isn't connected to anything, so its position # command will be zero. # NOTE: once the PID loops are tuned, you might want to # connect the position commands to the triangle or even # square wave outputs, to see how well the machine responds # to direction reversals (triangle) or step changes in # position (square). Note that step changes in position # will in general run the motors full blast in an attempt # to get to the new position as quickly as possible. # Proceed with caution, keep siggen.0.amplitude small # until you know that the movement is stable, then increase # it in small increments only. net Xpos-cmd <= siggen.0.sine net Ypos-cmd <= siggen.0.cosine # set the siggen parameters for a 0.5" diameter circle, once every 10 seconds # once the PID loops are tuned, the size and/or speed can be increased setp siggen.0.frequency 0.1 setp siggen.0.offset 0 setp siggen.0.amplitude 0.25 # create a bit signal to enable/disable the PID loops # connect the signal to all three PID blocks net pid-enable => pid.0.enable net pid-enable => pid.1.enable net pid-enable => pid.2.enable # you can either turn pid-enable on and off using the # "halcmd sets" command, or you can connect it to a # digital input and turn it on and off with an external # switch # The line below sets the signal to 0 to ensure that the PID # loops are off until you explicitly turn them on. sets pid-enable 0 # The line below connects the signal to a digital input. # Uncomment and change the input number if that's what you # want to do #linksp pid-enable <= motenc.0.in-00 # load realtime portion of scope loadrt scope_rt # start up scope user interface loadusr halscope # start realtime execution start # end of halcmd file, at this point the motors are "live" # and if you ran this script with "halrun -I" # you can do tuning and other experimentation # to shut down and clean up, simply exit halcmd.