Parametric G-Code; take axis name/ID from a variable?
04 Oct 2022 04:53 #253413
by swarren
Parametric G-Code; take axis name/ID from a variable? was created by swarren
I am writing a script to automate touch-off against a probe bar. I have written the same script 3 times; once each for the X, Y, and Z axes. The body of the script is identical in all 3 cases except for the axis name in the G38/G01 commands. Is there any way to use a variable for the axis name, so that I can either (a) use a sub-routine for the body of the script, or (b) make the scripts 100% identical so that it's easier to keep them in sync using "diff" or similar?
My current Z-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/100.ngc
My current X-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/103.ngc
My current Y-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/104.ngc
Some ideas that have been suggested:
a) Include all 3 of X, Y, Z axes in each G38/G01 command, and have separate probe_x/y/z_dir variables (with value -1 or 1 for the desired axis, and 0 for the other 2 axes, which will zero out the movement in unwanted directions). This will work, but will make the script a bit harder to read and understand.
b) Maybe "G10 L2 P0 R90" can be used to rotate between X/Y axes, but I'm not sure, and it won't work for Z.
Ideally, I'd love to do this: "G38.3 #<axis_name>[#<probe_dir> * #<probe_max_distance>] F[#<fast_probe_rate>]". However, variables can apparently only contain numbers, not strings/text:-(
Thanks for any ideas!
My current Z-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/100.ngc
My current X-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/103.ngc
My current Y-axis script: github.com/fortcollinscreatorhub/cnc/blo...cnc/nc_files/104.ngc
Some ideas that have been suggested:
a) Include all 3 of X, Y, Z axes in each G38/G01 command, and have separate probe_x/y/z_dir variables (with value -1 or 1 for the desired axis, and 0 for the other 2 axes, which will zero out the movement in unwanted directions). This will work, but will make the script a bit harder to read and understand.
b) Maybe "G10 L2 P0 R90" can be used to rotate between X/Y axes, but I'm not sure, and it won't work for Z.
Ideally, I'd love to do this: "G38.3 #<axis_name>[#<probe_dir> * #<probe_max_distance>] F[#<fast_probe_rate>]". However, variables can apparently only contain numbers, not strings/text:-(
Thanks for any ideas!
Please Log in or Create an account to join the conversation.
04 Oct 2022 21:38 - 04 Oct 2022 21:38 #253471
by andypugh
linuxcnc.org/docs/stable/html/gcode/o-co...ml#ocode:conditional
Replied by andypugh on topic Parametric G-Code; take axis name/ID from a variable?
O100 IF [#<axis> EQ 0]
G38.2 X100 F20
O100 ELSEIF [#<axis> EQ 1]
G38.2 Y100 F20
O100 ELSEIF [#<axis> EQ 2]
G38.2 Z100 F20
...
O100 ELSEIF [#<axis> EQ 9]
G38.2 W100 F20
O100 ELSE
(ABORT, Something went terribly wrong)
O100 ENDIF
linuxcnc.org/docs/stable/html/gcode/o-co...ml#ocode:conditional
Last edit: 04 Oct 2022 21:38 by andypugh.
Please Log in or Create an account to join the conversation.
05 Oct 2022 00:54 #253481
by swarren
Replied by swarren on topic Parametric G-Code; take axis name/ID from a variable?
That would work, but I'd essentially be replicating the program many times within the if statement. I was hoping for one statement that'd cover all the axes.
I'm thinking of just writing a custom M code in Python, since that allows much more flexible use of variables...
I'm thinking of just writing a custom M code in Python, since that allows much more flexible use of variables...
Please Log in or Create an account to join the conversation.
05 Oct 2022 04:11 #253491
by swarren
Replied by swarren on topic Parametric G-Code; take axis name/ID from a variable?
OK, so I've started to work out how to do this in a Python remap. A couple of questions:
1. linuxcnc.org/docs/stable/html/remap/rema...ming-embedded-python says:
2. How stable is this Python remap feature? Clearly if I write my code in G-Code, it's quite likely to keep working whenever I upgrade LinuxCNC. However, since Python remaps seem like a less commonly used and documented feature, I worry whether using it may cause headaches for some future maintainer of this machine, e.g. if I'm no longer involved in a few years and someone upgrades LinuxCNC, then everything breaks and they have a hard time fixing it if they aren't a programmer.
For the record, here's the very bare skeleton that I've been using to test the feature:
configs/sim/axis/axis.ini:
python/toplevel.py:
python/remap.py:
1. linuxcnc.org/docs/stable/html/remap/rema...ming-embedded-python says:
However, in practice my code is calling self.execute() after yielding, and works fine. Are the docs simply out-of-date, or are there cases where I'll see this randomly break if I'm unlucky?
- Code following a yield may not recursively call the interpreter, like with self.execute("<mdi command>"). This is an architectural restriction of the interpreter and is not fixable without a major redesign.
2. How stable is this Python remap feature? Clearly if I write my code in G-Code, it's quite likely to keep working whenever I upgrade LinuxCNC. However, since Python remaps seem like a less commonly used and documented feature, I worry whether using it may cause headaches for some future maintainer of this machine, e.g. if I'm no longer involved in a few years and someone upgrades LinuxCNC, then everything breaks and they have a hard time fixing it if they aren't a programmer.
For the record, here's the very bare skeleton that I've been using to test the feature:
configs/sim/axis/axis.ini:
[PYTHON]
PATH_PREPEND= python
TOPLEVEL= python/toplevel.py
LOG_LEVEL = 8
[RS274NGC]
REMAP= M400 py=fcch_probing
python/toplevel.py:
import remap
python/remap.py:
from interpreter import *
def fcch_probing(self, **words):
try:
self.execute("G91")
self.execute("G38.3 X1 F10")
yield INTERP_EXECUTE_FINISH
self.execute("G0 X-0.25")
self.execute("G38.3 X0.5 F2.5")
yield INTERP_EXECUTE_FINISH
self.execute("G0 X-0.5")
except InterpreterException as e:
self.set_errormsg(e.error_message)
return INTERP_ERROR
return INTERP_OK
Please Log in or Create an account to join the conversation.
05 Oct 2022 08:26 #253507
by andypugh
Replied by andypugh on topic Parametric G-Code; take axis name/ID from a variable?
Maybe only the probe moves, it depends on what the rest of the code does. You can pull out the correct probe result bu a computed parameter, for example.That would work, but I'd essentially be replicating the program many times within the if statement.
Please Log in or Create an account to join the conversation.
05 Oct 2022 09:16 #253509
by andypugh
Replied by andypugh on topic Parametric G-Code; take axis name/ID from a variable?
A remap should be as stable as Python, which isn't saying much. I would definitely target Python 3.
Please Log in or Create an account to join the conversation.
06 Oct 2022 05:52 #253592
by swarren
Replied by swarren on topic Parametric G-Code; take axis name/ID from a variable?
For anyone finding this thread later by Google, an update on the Python approach:
I've found an example of the problems that the documentation describe, where you can't issue and wait for multiple batches of G-Code commands within a Python remap. If I execute the remapped G-Code from the MDI, the code I wrote above works. If I execute the remapped code from 100.ngc which I trigger from an Axis UI button, then I get an error:
So, I guess I'll do this in plain old G-Code.
I've found an example of the problems that the documentation describe, where you can't issue and wait for multiple batches of G-Code commands within a Python remap. If I execute the remapped G-Code from the MDI, the code I wrote above works. If I execute the remapped code from 100.ngc which I trigger from an Axis UI button, then I get an error:
self.execute("G38.3 X1 F10")
yield INTERP_EXECUTE_FINISH
print(5070, self.params[5070])
# The execute() below works, if M400 executed from the MDI UI
# The execute() below raises the following, if M400 executed from 100.ngc, triggered from an Axis UI button:
# emc/task/emctask.cc 69: interp_error: exception during generator call: Traceback (most recent call last):
self.execute("G0 X-0.25")
So, I guess I'll do this in plain old G-Code.
Please Log in or Create an account to join the conversation.
Time to create page: 0.081 seconds