Abort tool changes
-
I'm using a particular tool number (
T49
) to identify a touch probe (for CNC purposes). Part of the tool change process (intpre.g
) is to detect the touch probe is plugged into the machine (because a lot of Aliexpress touch probes are normally open, it makes sense to confirm the touch probe is plugged in before potentially ramming it into the machine).I have a macro that looks for a status change on the touch probe in
tpre.g
, and runsabort {}
when the touch probe is not detected. This successfully exits out oftpre.g
buttpost.g
is still executed, and the tool number is still successfully changed toT49
. I've tried using M99 instead (same behaviour asabort {}
) and runningT-1 P0
inside the tool change macros themselves, but it doesn't seem possible right now to fully abort a tool change.I think it would be a useful safety feature, particularly for CNC purposes, to allow tool changes to be aborted - that way it would allow the currently selected tool number to act as a 'guard' - for example macros that need a touch probe check if the current tool number is the probe tool, and exit if not. In the current situation, the tool number is changed regardless of whether the
tpre.g
ortpost.g
were aborted or not.E: I should probably add, this is likely safe inside a running gcode file because the
abort{}
will successfully cancel the "print" - but it still leavesT49
active even after the print is finished. -
@NineMile yes working out how best to handle aborting system macros is on the list.
Issues related:
-
@T3P3Tony Ah thanks, wasn't sure if the first link applied to tool changes as it wasn't mentioned, good to see it's on the list
-
@NineMile its not explicitly tool changes - system macros as a whole being aborted opens up a big can of worms about how to correctly handle them.
For example if you abort a tool change macro during tFreeN.g - is a tool still fitted or not? Is there still an the active tool, if none, then how do you prevent the potentially dangerous situation of the machine trying to pick up another tool and smashing the still fitted tool into to new tool.
Aborting homing is potentially easier because when an axis is set to home, it is marked as unhomed before the macro is run, so aborting it would leave it as unhomed. Often homing macros are sub macros called by homeall, so if you abort a "homex.g", during home all. should all the nested macros abort and the overall "homeall" fail - what if some axes had homed successfully already?
Aborting pause/cancel/stop - also could leave the machine in strange undetermined states. if pause is aborted is the machine actually now still active and should continue operation? That sounds like a bad idea. There may be some macros that we prevent an abort operation from touching for this reason.
Aborting bed mesh levelling should cancel the mesh operation and discard the partial mesh, but does it revert to the mesh that was loaded when the mesh operation started (if there was one) or revert to no mesh loaded?
Arguably for at least some of these aborts, especially during tool changes, the machine should be in a (new) state of "undetermined" and then refuse to do anything until there is user intervention (how do you define user intervention though). Its not a universally acceptable solution to pop up a UI element because not everyone used a UI directly to interact with the controller. In my mind it could be something similar to a "fault" state with a heater, where specific explicit steps need to be taken to return the machine to a point where it can continue operation.
None of this is to imply that we don't want to implement this, or make it somehow your job to suggest the correct operation for all these cases, just to explain why it its not a "quick fix"!
-
@T3P3Tony Yep, that makes perfect sense - don't worry, I wasn't expecting a quick fix and realise there's much wider implications for RRF as a whole - thanks for explaining.
Given that there's such a wide range of situations where a system macro could be aborted and the recovery for each of these is different, and for different use cases across CNC, FDM etc, maybe the simplest approach is to trigger a recovery macro (e.g.
tpre-recover.g
orrecover.g
with a variable set to identify where the abort was triggered) that itself is not abortable and once complete, deems the machine to be in a known and ready-to-run state again.If no recovery macro exists for the system macro that was aborted, maybe the best thing to do in that situation is to treat it as an emergency and halt. That way, explicit non-emergency behaviour has to be user or machine specific
But I know little about the internals of RRF to know if that's feasible so I'll step back now I know it's on the radar!
-
I think one thing that would be helpful in the short(er) term, specifically from a tool-changing perspective, is to make sure that
tpre.g
is never run iftfree.g
experiences an error, andtpost.g
is never run iftpre.g
experienced an error.It seems to me that regardless of system-wide macro behaviour around aborts and recovery, a tool change can never be deemed safe or complete unless all 3 macros execute in order, without any errors.
I just had a situation that could've caused damage, because a syntax error in
tpre.g
aborted that particular macro (and cancelled the print file), but a tool length probe intpost.g
was still executed, and attempted to probe the length of a tool that had not been installed (because the prompt to install the tool was not popped up due to the error). -
@NineMile Given how close 3.5 is to release and the possible scale of the impact of changes in this area I suspect there will not be a quick fix. I would suggest that for now you use a global to track the tool change state and use this to abort operations in later macros if things are not in the expected state. I've had something similar to this for some time on my toolchanger and it seems to work reasonably well.
-
@T3P3Tony I think it would be logical to add a fault state possibility to all the different subsystems, eg. tools, axes and to machine (or system) level, similar to heaters.
For example, if a tool change macro fails, that could trigger a fault state on the tool, raise a "toolchange-fault" event, and also change the current machine state to paused.
I think it would make sense to pass a "cause" to a pause (or any automatically called) macro and let the user decide what to execute depending on what caused the pause, eg. user-request, toolchange-fault, heater-fault, etc...I think handling aborts in system-level macros could put the whole machine into a fault-state which in turn could further prevent running any other "doing" action, eg. tool change, move, home, etc. which would change any current (physical?) state.
There is something here that has to be thought out: allow executing "disable" commands in system-wide fault state, eg. turn off heater, spindle, motor, power, etc. So it is not that easy to just prevent any executive command to run.
I think resetting any fault could be done in a standardized way, just like how resetting a heater-fault works already with M562. Maybe it could be extended to be able to reset any sort of fault (selectively). Then the user could decide whether it wants an UI popup, or it recovers automatically from an event macro, or issues the command by hand, etc...
Just my thoughts...