Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: RecceDG on February 07, 2024, 07:27:23 AM
-
OK.
So every
variable = mc.mcGetSomething(inst)
call that we see in macros like m6() etc are actually a
variable, rc = mc.mcGetSomething(inst)
call, where "rc" is the return code that indicates API success or failure.
For some reason, all the scripts people write handwave this away and blithely assume that API calls always work.
That might very well be true in 99.999% of the cases, but it is poor programming practice to not check error codes.
That means that functions like m6() need an error-checking function within them, like this:
function m6()
function wc(rc) -- wc stands for "welfare check"
if (not(rc == mc.MERROR_NOERROR))
-- Do something reasonable to abort m6()
end
end
-- Do tool change stuff here
local inst, rc = mc.mcGetInstance()
wc(rc) -- make sure we got our instance
-- etc..
end
I'm talking to some lua experts elsewhere to see if there is a way to do something like
local inst, wc(rc) = mc.mcGetInstance()
so as to make the syntax a little cleaner, and is seems that lua does not have a case or switch statement, so parsing all the various possible error codes is likely to be a bitch.
But it is worth discussing this: if an API call fails in a gCode replacement call like m6(), what should the function do to gracefully report the error to the user and stop the machine?
There has to be a best practice here.
Ideally there would be a global wc(rc) lua function that was written to do just that and came with Mach - maybe there is?
-
I think that once you have all this sorted you will become the forums, resident, Lua expert.
Keep up the good work - I am following with great interest.
Tweakie.
-
> I think that once you have all this sorted you will become the forums, resident, Lua expert.
Don't you put that evil on me, Ricky Bobby!
But this is less a lua issue than it is a process issue:
If I call a GCode linked to a lua script, and in that script an API call fails, we want to report the error and do something reasonable with the machine - which, in order of increasing drastic, is probably "FEED HOLD", "STOP", or "ESTOP".
Putting the error code into a text box is easy. Giving that error code some useful context so the operator can source and fix the problem is a little more challenging, but doable. How do I stop the machine if the API failed?
-
Hi, check out this post
https://www.machsupport.com/forum/index.php?topic=41630.msg272402#msg272402
You can also use mcCntlMacroStop in place of mcCntlMacroAlarm as used in the example
-
OK so this code:
if (rc ~= 0) then
msg = mc.mcCntlGetErrorString(inst, rc) --Get the returned error string
errorOut(msg)
return --Exit the function
end
local function errorOut(msg)
local inst = mc.mcGetInstance()
mc.mcSpindleSetDirection(inst, mc.MC_SPINDLE_OFF)
mc.mcCntlMacroAlarm(inst, 3, msg)
end
Can be simplified to this:
value, rc = mc.mcGetSomeValueFromAPI
if (not (rc = mc.MERROR_NOERROR) then
errorOut(rc)
end
local function errorOut(rc)
local inst, rc2 = mc.mcGetInstance()
local msg, rc2 = mc.mcCntlGetErrorString(inst, rc)
-- print some error message here
rc2 = mc.mcSpindleSetDirection(inst, mc.MC_SPINDLE_OFF)
rc2 = mc.mcCntlMacroAlarm(inst, 3, msg)
end
Do you see the problem? It's turtles all the way down!
If my safe error handling routine that I only call when the return code from an API call fails depends on API calls that must themselves have their return codes checked (and could fail!) where's the bottom?
I buy into stopping the spindle explicitly via API vice trying to feed the gcode interpreter an M30 or something, and by extension, we should probably stop coolant, mist, and all axis movement too, and setting the ALARM state makes sense... but I have to use the API to do it so I have to test the return codes and around and around we go.