Source code for scripts.g_code_osc_fn
#!/usr/bin/env python
"""\
g_code_osc_fn.py : demonstration of creating an oscillatory motion represented as a G-code using a simple function
This is a fully self-contained script, i.e. it does not require any special libraries.
This emits a NC program with speeds faster than the grbl defaults. Please issue
the following commands using a terminal emulator to set the non-volatile
registers:
$110=2000
$120=500
Afterward, the $$ command should show these entries:
$110=2000.000 (x max rate, mm/min)
$120=500.000 (x accel, mm/sec^2)
"""
# Redefine the print function to be compatible with Python 3. This is a good
# practice even if we are using Python 2.
from __future__ import print_function
# Import the standard math functions into the current namespace.
import math
#================================================================
# Define a few useful functions to emit lines of G-code.
[docs]def emit_prelude(output):
"""Emit a header of G-code commands to reset the machine modes to a known
standard state, including the following:
G21 units are mm
G90 absolute distance mode
G17 select XY plane for arcs
G94 set units/mm feed rate mode
G54 use default work coordinates
"""
output.write("G21 G90 G17 G94 G54\n")
return
[docs]def emit_rapid_move(output, x_position):
"""Emit a single-axis rapid move to the given location at the maximum speed. The
position precision is limited to three decimal places.
:param x_position: target position in mm
"""
output.write("G0 X%.3f\n" % x_position)
return
[docs]def emit_move(output, x_position, speed):
"""Emit a single-axis move to the given location at the given speed. The
precision is limited to three decimal places.
:param x_position: target position in mm
:param speed: motion rate in mm/min
"""
output.write("G1 X%.3f F%0.3F\n" % (x_position,speed))
return
#================================================================
[docs]def curve(time, frequency = 0.2, magnitude = 2.0):
"""Return a single-axis position value representing a position on a curved path at a given time.
:param time: time in seconds
:param frequency: rate in cycles/second (Hz)
:return: position in mm
"""
# Some elementary functions and calculus: the sin function accepts an argument in radians;
# one complete cycle takes 2pi radians.
return magnitude * math.sin(time * frequency * 2 * math.pi)
#================================================================
# The following section is run when this is loaded as a script.
if __name__ == "__main__":
# Specify the name of the NC G-code file to generate.
filename = "osc_fn.nc"
print("Writing output to %s" % filename)
# Open the file and begin writing out G-Code.
with open(filename,"w") as output:
emit_prelude(output)
# specify the time step for each path segment in seconds
dt = 0.2
# specify the magnitude of the oscillation in millimeters
mag = 2.0
# specify the initial frequency in cycle/sec (Hz)
f0 = 0.2
# compute the initial time and position
t0 = 0.0
x0 = curve(t0, frequency = f0, magnitude = mag)
freq = f0
# rapid to the start point
emit_rapid_move(output, x0)
# iteration to compute a fixed number of samples
duration = 60
for i in range(int(duration/dt)):
# keep speeding up by adjusting the frequency
freq += 0.005 * dt
# compute the time and position of the next sample
t1 = t0 + dt
x1 = curve(t1, frequency = freq, magnitude = mag)
# Estimate the feed rate in mm/min. The move command expects speeds
# in mm/min, so the mm/sec rate is scaled by 60 sec/min.
feed_rate = 60 * abs(x1 - x0) / dt
# Keep the feed rate from getting too low.
if feed_rate < 20.0: feed_rate = 20.0
# Generate a move command to the new position, using the feed rate
# so that the move should take dt seconds.
emit_move(output, x1, feed_rate)
# update the time and position for next cycle
t0 = t1
x0 = x1