Files
PyCNC/gmachine.py
T
Nikolay Khabarov b70dd3c9ea first commit
2017-05-10 04:25:12 +03:00

140 lines
4.8 KiB
Python

#!/usr/bin/env python
import time
import logging
import hal
from coordinates import Coordinates
from config import *
class GMachineException(Exception):
""" Exceptions while processing gcode line.
"""
pass
class GMachine(object):
""" Main object which control and keep state of whole machine: steppers,
spindle, extruder etc
"""
def __init__(self):
""" Initialization.
"""
self._position = Coordinates(0.0, 0.0, 0.0)
# init variables
self._velocity = 0
self._spindle_rpm = 0
self._pause = 0
self._local = None
self._convertCoordinates = 0
self._absoluteCoordinates = 0
self.reset()
hal.init()
def destroy(self):
self.home()
hal.join()
def reset(self):
""" Reinitialize all program configurable thing.
"""
self._velocity = 1000
self._spindle_rpm = 1000
self._pause = 0
self._local = Coordinates(0.0, 0.0, 0.0)
self._convertCoordinates = 1.0
self._absoluteCoordinates = True
def _spindle(self, spindle_speed):
hal.spindle_control(100.0 * spindle_speed / SPINDLE_MAX_RPM)
def _move(self, delta, velocity):
delta = delta.round(1.0 / STEPPER_PULSES_PER_MM)
if delta.is_zero():
return
np = self._position + delta
if not np.is_in_aabb(Coordinates(0.0, 0.0, 0.0),
Coordinates(TABLE_SIZE_X_MM, TABLE_SIZE_Y_MM, TABLE_SIZE_Z_MM)):
raise GMachineException("out of effective area")
hal.move_linear(delta, velocity)
# save position
self._position = np
def home(self):
""" Move head to park position
"""
d = Coordinates(0, 0, -self._position.z)
self._move(d, STEPPER_MAX_VELOCITY_MM_PER_MIN)
d = Coordinates(-self._position.x, -self._position.y, 0)
self._move(d, STEPPER_MAX_VELOCITY_MM_PER_MIN)
def do_command(self, gcode):
""" Perform action.
:param gcode: GCode object which represent one gcode line
"""
if gcode is None:
return
logging.debug("got command " + str(gcode.params))
# read command
c = gcode.command()
if c is None and gcode.isXYZ():
c = 'G1'
# read parameters
if self._absoluteCoordinates:
coord = gcode.getXYZ(self._position, self._convertCoordinates)
coord = coord + self._local
delta = coord - self._position
else:
delta = gcode.getXYZ(Coordinates(0.0, 0.0, 0.0), self._convertCoordinates)
coord = self._position + delta
velocity = gcode.get('F', self._velocity)
spindle_rpm = gcode.get('S', self._spindle_rpm)
pause = gcode.get('P', self._pause)
# check parameters
if velocity <= 0 or velocity > STEPPER_MAX_VELOCITY_MM_PER_MIN:
raise GMachineException("bad feed speed")
if spindle_rpm < 0 or spindle_rpm > SPINDLE_MAX_RPM:
raise GMachineException("bad spindle speed")
if pause < 0:
raise GMachineException("bad delay")
# select command and run it
if c == 'G0': # rapid move
self._move(delta, STEPPER_MAX_VELOCITY_MM_PER_MIN)
elif c == 'G1': # linear interpolation
self._move(delta, velocity)
elif c == 'G4': # delay in s
hal.join()
time.sleep(pause)
elif c == 'G20': # switch to inches
self._convertCoordinates = 25.4
elif c == 'G21': # switch to mm
self._convertCoordinates = 1.0
elif c == 'G28': # home
self.home()
elif c == 'G90': # switch to absolute coords
self._absoluteCoordinates = True
elif c == 'G91': # switch to relative coords
self._absoluteCoordinates = False
elif c == 'G92': # switch to local coords
self._local = self._position - \
gcode.getXYZ(Coordinates(0.0, 0.0, 0.0), self._convertCoordinates)
elif c == 'M3': # spinle on
self._spindle(spindle_rpm)
elif c == 'M5': # spindle off
self._spindle(0)
elif c == 'M2' or c == 'M30': # program finish, reset everything.
self.reset()
elif c == 'M111': # enable debug
logging.getLogger().setLevel(logging.DEBUG)
elif c is None: # command not specified(for example, just F was passed)
pass
else:
raise GMachineException("unknown command")
# save parameters on success
self._velocity = velocity
self._spindle_rpm = spindle_rpm
self._pause = pause
logging.debug("position {}, {}, {}".format(
self._position.x, self._position.y, self._position.z))