Just to provide another avenue, the auto tool change in question was ultimately achieved by having the sequence run via G code but having a subset of user defined M codes which compartmentalized the whole auto tool change sequence. Within these was also the usual "check for carousel in extended position" etc fault checking.
Then these were all brought together (again via G code) and made into the full M6 sequence (the M6 itself being re-defined to run the complete tool change G code).
It was felt that there would be advantages in having compartmentalized M codes for the individual segments of the procedure in case there were any crashes during the tool change sequence so that one could call a certain M code and carry out any rectifying actions in a step by step way.
For example, I left the probe in the spindle when I executed a tool change to get the tool I needed. Not the brightest thing to do, and because I didn't want to damage to probe I hit the E Stop. So, the carousel is sitting half way out and the whole machine is somewhere in the middle of a tool change. Having the ability to call smaller subsets of the tool change sequence via user defined M codes made it easy to retrieve the probe then send the carousel back to home. In other words, sort out the error and place the machine back into a known state.
Not knowing well the way classic ladder or python integrates with LCNC, can segments of code be run outside the entirety of the program? In other words with full and complete auto tool change routine written in classic ladder, would it still be able to send the carousel back to home position using the above example? Or can it only be run linearly from start to finish?
There are a million ways to skin a cat, one way no better or worse than the other. But having seen things like this first hand, I'm glad I have the facility to call smaller M codes to fix the rare occasion of an incomplete tool change.