bdring / FluidNC

The next generation of motion control firmware
Other
1.62k stars 386 forks source link

Feature: The ability to exit out of a Macro mid script #1318

Open rvalotta opened 2 months ago

rvalotta commented 2 months ago

Machine Context

With the recent addition of Flow control the ability to bail out of the script if certain conditions are met would be helpful.

Feature Description

LinuxCNC documents M99 which is documented as returning from a numbered program

https://linuxcnc.org/docs/html/gcode/o-code.html#ocode:fanuc-style-programs

Usually it is used along side M98 but as there is no support for functions numbered or otherwise it can be omited... The same code is supported by GRBLHal as well

Other Approaches

Not sure how else to do this outside adding the functionality to the macro processor

How I Can Help

I can provide code examples to test with

MitchBradley commented 2 months ago

Would an IF construct that ends at the end of the file or macro do the job?

rvalotta commented 2 months ago

Some examples that could be applied for a tool change macro.

You can see this being used in the following script for the rapidchange atc that was developed for grblhal. https://github.com/greilick-industries/rcatc-scripts-grblhal/blob/main/macros/TC.macro

yes if's could be used to encapsulate the whole function but it would not be as clean or easy to read

MitchBradley commented 2 months ago

We don't support subroutines inside of files or macros. The entire file or macro is treated as a unit, i.e. a subroutine. I'm not sure to what extent M99 depends on the smaller-than-file subroutine construct. What do you think?

rvalotta commented 2 months ago

It is being used only to short circuit the gcode incase something isn't right... I mean if could be re-written to its is nested if / else but I believe its harder to read at that point...

MitchBradley commented 2 months ago

If something goes wrong, what should happen in the calling context? Should it continue on or should the exit propagate, as with an alarm?

rvalotta commented 2 months ago

M99 Should just return the the calling script or exit out if there is no calling script.
M30 (Which is implemented) is a program end

So if new tool equals current tool just return back and continue to run the code from where you left off and not evaluate the rest of the programming. M30 would be the one that is used to exit the program... Off to report that bug to the developer of the script i linked above realizing the mistake that was made there :)

Neither of them need to throw an error as a print can be used to display what is going on at each so the user is aware.

MitchBradley commented 2 months ago

So if new tool equals current tool just return back and continue to run the code from where you left off and not evaluate the rest of the programming.

"continue to run the code from where you left off" and "not evaluate the rest of the programming" seem contradictory.

rvalotta commented 2 months ago

If you think of it in terms of M6_macro a M99 would resume running your gcode while a M30 would end it and not continue the original gcode that called the tool change.

MitchBradley commented 2 months ago

If M99 is used in the case where "something isn't right", shouldn't that information be propagated to the caller? Suppose that I have a macro like "prepare_for_tool_change" that, say, docks the dust shoe. That is in turn called from a higher level "do_tool_change" macro. If "prepare.." fails and executes M99, shouldn't "do.." also fail?

rvalotta commented 2 months ago

I've seen people to (print, with a error message) more so then a complete failure

rvalotta commented 2 months ago

Not when you think of it as the M6 T2 in your gcode is calling another script. Continue to run the code refers to the original gcode that was called. Not evaluate the rest of the programming refers to the code below the M99 that does not need to run

Hope that clears it up

bdring commented 2 months ago

It seems like you could do what you want with the proper nesting of if statements.

With that said, the fail case is an important one. Currently gcode or FluidNC can generate errors, like soft or hard limit alarms. FluidNC cannot proceed safely when an alarm happens, so it kills all jobs.

We currently do not have an elegant way to force an alarm with a gcode conditional. Say you want to alarm out if someone asks for a tool position that does not exist. We have no way to do that other than hacking a gcode alarm condition.

We might want something like M30 P<alarm?>

MitchBradley commented 2 months ago

$Alarm/Send=5