Dynamic soft limits

More
21 Sep 2025 23:17 - 21 Sep 2025 23:44 #335254 by Rockwood
Dynamic soft limits was created by Rockwood
Hey All,
I'm not sure if this is the right place for this. But I'm working with a Tormach 1500MX that has a PathPilot control.
I built a complicated fixture for running the same part over and over. I wanted to have the soft limits prevent the tool from hitting the fixture. Which means having different X and Y limits when the Z axis is low enough to have the tool in the fixture. Also to prevent Z from lowering into the fixture unless X and Y are correctly positioned.

I ended up with this added to tormach's postgui hal file:

#rockwood edit , the below is for setting dynamic soft limits to protect from crashing into fixture when in "run" mode, "Setup" accessed with the built in tormach keyswitch, will have full travel. All units are inches.
#If Z < -3.187: X and Y limits switch to narrow windows (X:[14.349-15.175], Y:[5.674-6.559]); else use factory limits.
# Z min is -3.187 by default; becomes -11.494 when BOTH X and Y are within their narrow windows.


#load and name components I will need later,  and2 components have to be added in "tormach_mill_ethercat_csp.hal" 
loadrt mux2 names=mux.xMin,mux.xMax,mux.yMin,mux.yMax,mux.zMin,mux.zMinSetup
loadrt comp names=comp.zBelow,comp.x_ge_min,comp.x_le_max,comp.y_ge_min,comp.y_le_max

# add stuff to servo thread
addf comp.zBelow     servo-thread
addf comp.x_ge_min   servo-thread
addf comp.x_le_max   servo-thread
addf comp.y_ge_min   servo-thread
addf comp.y_le_max   servo-thread
addf mux.xMin        servo-thread
addf mux.xMax        servo-thread
addf mux.yMin        servo-thread
addf mux.yMax        servo-thread
addf mux.zMin        servo-thread
addf mux.zMinSetup   servo-thread     
addf not.setup-mode  servo-thread      
addf and.narrow      servo-thread      
addf and.znarrow     servo-thread      
addf and.xInWin      servo-thread
addf and.yInWin      servo-thread
addf and.xyInWin     servo-thread


setp comp.x_ge_min.in0  14.349                                          # comp.x_ge_min.in0 is set to X narrow MIN setting
setp comp.x_le_max.in1  15.175                                          # comp.x_le_max.in1 is set to X narrow MAX setting
net motor.00.feedback-position comp.x_ge_min.in1 comp.x_le_max.in0      # current X postion is sent to *min.in0 and *max.in1

setp comp.y_ge_min.in0  5.674                                           # comp.y_ge_min.in1 is set to Y narrow MIN setting
setp comp.y_le_max.in1  6.559                                           # comp.Y_le_max.in1 is set to Y narrow MAX setting
net motor.01.feedback-position comp.y_ge_min.in1 comp.y_le_max.in0      # current Y postion is sent to *min.in0 and *max.in1

setp comp.zBelow.in1   -3.187                           # set in1 to our fixture height threshhold:
net motor.02.feedback-position  => comp.zBelow.in0      # assign current Z position to comp.zBelow.in0
net z-below-thresh     comp.zBelow.out                  #create z-below-thresh this is true when Z is extended into the fixture 

net x-ge-min            comp.x_ge_min.out    => and.xInWin.in0          # is X > than MIN?
net x-le-max            comp.x_le_max.out    => and.xInWin.in1          # is X < than MAX?
net x-inrange           and.xInWin.out                                  # if both are true than so is x-inrange

net y-ge-min            comp.y_ge_min.out    => and.yInWin.in0          # is Y > than MIN?
net y-le-max            comp.y_le_max.out    => and.yInWin.in1          # is Y < than MAX?
net y-inrange           and.yInWin.out                                  # if both then y-inrange

net x-inrange           => and.xyInWin.in0
net y-inrange           => and.xyInWin.in1
net both-inrange        and.xyInWin.out                                 # if both X and Y are in range, then both-inrange

#these mux contain the limit values. 
setp mux.xMin.in0   -0.000001   #factory default
setp mux.xMax.in0    19.68500   #factory default

setp mux.yMin.in0   -0.000001   #factory default
setp mux.yMax.in0    13.77900   #factory default

setp mux.zMinSetup.in0    -14.0   #this is the factory default Min Z, IF we are in setup mode this should always be the value.
setp mux.zMinSetup.in1    -3.187  #this is a zMin just above the fixture. this is default when in run mode. it changes only when X and Y are in the narrow window.   

setp ini.2.max_limit 0.000001  #setting Z max to factory limit. this is a fixed value.

# Narrow windows: X and Y
setp mux.xMin.in1    14.349
setp mux.xMax.in1    15.175
setp mux.yMin.in1     5.674
setp mux.yMax.in1     6.559

setp mux.zMin.in1     -11.494  #this is 1mm below cutting height, to be allowed only when x and y are within window 

#modeswitchsig is from tormach, its TRUE when in setup mode. im flipping it and creating "not-setup" which just means run mode.
net modeswitchsig       => not.setup-mode.in
net not-setup       not.setup-mode.out

#if z-below-thresh and not setup, then we narrow x and Y windows
net z-below-thresh and.narrow.in0
net not-setup      and.narrow.in1
net narrow-enable  and.narrow.out
net narrow-enable  mux.xMin.sel
net narrow-enable  mux.xMax.sel
net narrow-enable  mux.yMin.sel
net narrow-enable  mux.yMax.sel

#mux.zmin setup just exists so we can go all the way down in setup mode
net not-setup mux.zMinSetup.sel 
net z-min-default mux.zMinSetup.out mux.zMin.in0    #This assigns a default Zmin -3.187 if in "run" mode, -14 if in "setup mode"

#If X and Y are in the window and not-setup then set the Zmin mux to true, changing our z min value
net both-inrange  and.znarrow.in0
net not-setup     and.znarrow.in1
net z-narrow      and.znarrow.out
net z-narrow      mux.zMin.sel

# set axis limits min/max from the muxes
net x-min-dyn  mux.xMin.out ini.0.min_limit
net x-max-dyn  mux.xMax.out ini.0.max_limit
net y-min-dyn  mux.yMin.out ini.1.min_limit
net y-max-dyn  mux.yMax.out ini.1.max_limit
net z-min-dyn  mux.zMin.out ini.2.min_limit
#Rockwood edit over
 


I've tested it, just jogging around and with MDI commands. It seems to be working. But this is my first time using linuxCNC. So I'd love a reality check from anyone more familiar. Does this make sense or is there a better way to do it? Am I adding too much to the servo thread? Is there something I should check to make sure I'm not slowing stuff down too much? 

In the future, I want to get rid of all the hard-coded numbers. I want to store them in another file or at least one clear location in the postgui file. Preferably, I could process the "narrow window" numbers from a work offset, so I can move the fixture in the future and change the offset. But I would want to then lock that or all offsets from being edited easily, maybe using the same setup mode keyswitch. I'm not sure how to handle that yet. If anyone has ideas, I'd love to hear them.

Thanks for your time!
 
Attachments:
Last edit: 21 Sep 2025 23:44 by Rockwood.

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

More
24 Sep 2025 12:01 #335364 by andypugh
Replied by andypugh on topic Dynamic soft limits
I think that this approach is probably valid, but will be necessarily comlex when building it from discrete HAL components.

You can look at the servo thread execution time with and without the added components to see if it is using a lot of CPU time, but it probably won't be.

Does Tormach include "halcompile" to create custom HAL components? If it does, then this is getting to the point where that might be worth doing.

linuxcnc.org/docs/stable/html/hal/comp.html

I always fancied the idea of being able to define limits as an STL file.
(STL because it's simple and easy to parse)
The following user(s) said Thank You: meister

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

Time to create page: 0.078 seconds
Powered by Kunena Forum