G-Code
Our G-Code API provides a way to use G-Codes to control Zaber devices. The library interprets the codes and outputs Zaber ASCII protocol stream commands. You can review the usage of Streams in this article and the stream commands in the protocol manual. This article assumes a basic understanding of G-Code.
Basic Usage
Starting with basic G-Code translation is easy.
# from zaber_motion.gcode import Translator
stream = device.get_stream(1)
stream.setup_live(1, 2)
translator = Translator.setup(stream)
translator.translate("G28")
translator.translate("G0 X100")
translator.translate("G0 Y100")
translator.translate("G0 X0 Y0")
translator.flush()
stream.disable()
First, you need to set up a live stream over the designated axes.
Then, set up an instance of the @class Translator
class over the stream.
Afterward, you can start translating G-Code by calling the @method Translate
method.
The device may not start moving immediately after calling @method Translate
because the instructions are buffered in the library for optimization.
Additionally, the movements are also queued in the device to allow for smooth motion.
To ensure that the library sends all the movements, call the @method Flush
method.
The method also waits for the device to finish all the queued movements.
At the end, we should call the @method Disabled
method to release the axes from the stream.
The @method Translate
method also returns a the @class TranslateResult
data class instance.
The instance contains generated commands as well as warnings produced during translation.
The warnings can be useful in determining ignored or unknown instructions.
result = translator.translate("G28 G999")
print(result)
# {'_commands': ['on a b line abs 0 0'],
# '_warnings': [{'_message': 'Unknown command G999.', '_from_block': 4, '_to_block': 8}]}
Additionally the translation can throw the @class GCodeSyntaxException
and the @class GCodeExecutionException
exceptions containing details of what went wrong.
Configuration
The translator's @method Setup
method takes additional argument for configuring the translator.
translator = Translator.setup(stream, TranslatorConfig(
axis_mappings=[
AxisMapping('X', axis_index=1),
AxisMapping('Y', axis_index=0)
],
axis_transformations=[
AxisTransformation("X", scaling=-1),
AxisTransformation("Y", translation=Measurement(20, Units.LENGTH_MILLIMETRES)),
],
))
You can use the configuration to remap translator axes or transform the coordinates of an axis.
For example, you can invert the axis by specifying scaling=-1
or offset it by 20 mm by specifying translation
.
Coordinate Systems
The translator support 9 coordinate system: G54
-G59
and G59.1
-G59.3
.
You can set coordinate system offset by programming G10 L2 P?
where P?
is the coordinate system number (G54
is P1
).
You can also retrieve currently used coordinate system or an offset of axis in a given coordinate system.
See the example below.
translator.translate("G10 L2 P3 X200 Y50") # set up offset for G56
translator.translate("G56") # select G56
print(translator.coordinate_system)
# prints G56
offset = translator.get_axis_coordinate_system_offset("G56", "X", Units.LENGTH_MILLIMETRES)
print(offset)
# prints 200
Interaction with Other Hardware
It's often useful to interact with other hardware on top of Zaber devices.
You can, for example, use M-code M3
to turn on a spindle of a milling machine with digital input on Zaber controller.
The example below demonstrates exactly that.
with open("C:\\prototype.tap") as file:
while True:
line = file.readline()
if not line:
break # EOF
else if line == "M3":
translator.flush() # finish all queued movements
stream.set_digital_output(1, True) # turn on digital output
time.sleep(30) # wait 30 seconds for the spindle to reach full speed
else:
translator.translate(line) # all the other instructions
It is crucial to always call the @method Flush
method before interacting with other hardware.
By calling the method, you ensure that the device has reached the final position in the submitted G-Code.
If you also perform some movement outside of G-Code, make sure to call the @method ResetPosition
method afterwards.
The method queries the device and updates translator's internal position to match the device.
Alternatively, you can use the @method SetPosition
method to update the position manually.
Using patterns like the one above, you can interact with any external hardware like PLC, laser, pumps, etc.
Stream Command Passthrough
We provide a special M-Code M700
that allows to pass stream commands directly to the underlying stream.
The commands are provided in G-Code comments with parentheses.
result = translator.translate("M700 (wait io ai 1 >= 0.5) (wait 200)")
print(result)
# {'_commands': ['wait io ai 1 >= 0.5', 'wait 200'],
# '_warnings': []}
The example above passes two commands to the stream.
The first one waits for analog input 1
to get above 0.5 V.
The second one then waits additional 200 ms.
Path Control Mode
The translator supports continuous path mode (G64
) where it rounds corners of line segments to maintain speed.
The current implementation has certain limitations.
Firstly, the corners are only rounded up to a specified path deviation from a corner
(in contrast to milling machines' ability to maintain constant milling speed).
You can specify the deviation with P
parameter; otherwise, the default value of 0.1 mm applies.
Secondly, the translator only looks ahead at two consequent linear movements and always reaches each segment at worst case as a tangent.
G64
is a default path control mode.
In addition to G64
the translator also supports exact path mode G61
and exact stop mode G61.1
.
Use these modes to enforce the exact travel of the specified path.
You may also use G9
exact stop instruction to enforce stopping after a single block.
Offline Translation
In addition to streaming G-Code directly to the device, we also provide a way to translate instructions without sending the commands. You can, for example, use this for simulation purposes or processing of the generated commands.
# from zaber_motion.gcode import OfflineTranslator
translator = OfflineTranslator.setup(DeviceDefinition(device_id=30331, axes=[
AxisDefinition(peripheral_id=70245, microstep_resolution=64),
AxisDefinition(peripheral_id=70245, microstep_resolution=64),
AxisDefinition(peripheral_id=70245, microstep_resolution=64),
], max_speed=Measurement(100, Units.VELOCITY_MILLIMETRES_PER_SECOND)))
result = translator.translate("G28")
print(result)
# {'_commands': ['on a b c line abs 0 0 0'], '_warnings': [] }
In order to create an offline translator, you have to specify information about the device. You can find this information by accessing device settings in Zaber Launcher.
The interface of the @class OfflineTranslator
class is nearly identical the one of the @class Translator
class
with notable exception of @method Translate
and @method Flush
methods being synchronous.
Supported Codes
The translator supports a wide range of semi-standard G-Codes and M-Codes.
G0
- traverse lineG1
- lineG2
,G3
- arc, without support for parametersR
andP
G4
- dwell (P
in seconds)G10
- set coordinate system (L2
only)G17
,G18
,G19
- plane selectionG21
- millimeter system selectionG28
,G28.1
- return to home, set home to the current positionG30
,G30.1
- return to secondary home, set secondary home to the current positionG53
- machine coordinate systemG54
-G59
,G59.1
-G59.3
- coordinate system selectionG61
,G61.1
,G64
- path control modeG90
,G91
- absolute/relative mode (G91
is default)G90.1
,G91.1
- absolute/relative arc distance mode (G91.1
is default)G92
,G92.1
- temporary work offset (not recommended)M2
,M30
- program stop and endM64
,M65
- set digital outputM66
- wait on input (E
not supported;L0
,L1
,L2
not supported;Q
not supported; useM700
when possible)M68
- set analog output
If you require support of some additional codes for your application, please let us know.
Non-supported Codes
There are some codes that we explicitly don't support at this moment.
G20
- inch system selectionG40
,G41
,G42
- tool radius compensationG43
,G44
,G49
- tool length compensationG93
- inverse time feed rate modeG95
- feed rate per revolution
Custom Codes
Here you find all non-standard codes specific to our implementation.
M700
- stream command passthrough