Ejemplo n.º 1
0
 def position(self):
     """ Return current machine position (after the latest command)
         Note that hal might still be moving motors and in this case
         function will block until motors stops.
         This function for tests only.
         :return current position.
     """
     hal.join()
     return self._position
Ejemplo n.º 2
0
 def _spindle(self, spindle_speed):
     hal.join()
     hal.spindle_control(100.0 * spindle_speed / SPINDLE_MAX_RPM)
Ejemplo n.º 3
0
 def do_command(self, gcode):
     """ Perform action.
     :param gcode: GCode object which represent one gcode line
     :return String if any answer require, None otherwise.
     """
     if gcode is None:
         return None
     answer = None
     logging.debug("got command " + str(gcode.params))
     # read command
     c = gcode.command()
     if c is None and gcode.has_coordinates():
         c = 'G1'
     # read parameters
     if self._absoluteCoordinates:
         coord = gcode.coordinates(self._position - self._local,
                                   self._convertCoordinates)
         coord = coord + self._local
         delta = coord - self._position
     else:
         delta = gcode.coordinates(Coordinates(0.0, 0.0, 0.0, 0.0),
                                   self._convertCoordinates)
         # coord = self._position + delta
     velocity = gcode.get('F', self._velocity)
     radius = gcode.radius(Coordinates(0.0, 0.0, 0.0, 0.0),
                           self._convertCoordinates)
     # check parameters
     if velocity < MIN_VELOCITY_MM_PER_MIN:
         raise GMachineException("feed speed too low")
     # select command and run it
     if c == 'G0':  # rapid move
         vl = max(MAX_VELOCITY_MM_PER_MIN_X,
                  MAX_VELOCITY_MM_PER_MIN_Y,
                  MAX_VELOCITY_MM_PER_MIN_Z,
                  MAX_VELOCITY_MM_PER_MIN_E)
         l = delta.length()
         if l > 0:
             proportion = abs(delta) / l
             if proportion.x > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_X / proportion.x)
                 if v < vl:
                     vl = v
             if proportion.y > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_Y / proportion.y)
                 if v < vl:
                     vl = v
             if proportion.z > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_Z / proportion.z)
                 if v < vl:
                     vl = v
             if proportion.e > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_E / proportion.e)
                 if v < vl:
                     vl = v
         self._move_linear(delta, vl)
     elif c == 'G1':  # linear interpolation
         self._move_linear(delta, velocity)
     elif c == 'G2':  # circular interpolation, clockwise
         self._move_circular(delta, radius, velocity, CW)
     elif c == 'G3':  # circular interpolation, counterclockwise
         self._move_circular(delta, radius, velocity, CCW)
     elif c == 'G4':  # delay in s
         if not gcode.has('P'):
             raise GMachineException("P is not specified")
         pause = gcode.get('P', 0)
         if pause < 0:
             raise GMachineException("bad delay")
         hal.join()
         time.sleep(pause)
     elif c == 'G17':  # XY plane select
         self._plane = PLANE_XY
     elif c == 'G18':  # ZX plane select
         self._plane = PLANE_ZX
     elif c == 'G19':  # YZ plane select
         self._plane = PLANE_YZ
     elif c == 'G20':  # switch to inches
         self._convertCoordinates = 25.4
     elif c == 'G21':  # switch to mm
         self._convertCoordinates = 1.0
     elif c == 'G28':  # home
         axises = gcode.has('X'), gcode.has('Y'), gcode.has('Z')
         if axises == (False, False, False):
             axises = True, True, True
         self.safe_zero(*axises)
         hal.join()
         if not hal.calibrate(*axises):
             raise GMachineException("failed to calibrate")
     elif c == 'G53':  # switch to machine coords
         self._local = Coordinates(0.0, 0.0, 0.0, 0.0)
     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
         if gcode.has_coordinates():
             self._local = self._position - gcode.coordinates(
                 Coordinates(self._position.x - self._local.x,
                             self._position.y - self._local.y,
                             self._position.z - self._local.z,
                             self._position.e - self._local.e),
                 self._convertCoordinates)
         else:
             self._local = self._position
     elif c == 'M3':  # spindle on
         spindle_rpm = gcode.get('S', self._spindle_rpm)
         if spindle_rpm < 0 or spindle_rpm > SPINDLE_MAX_RPM:
             raise GMachineException("bad spindle speed")
         self._spindle(spindle_rpm)
         self._spindle_rpm = spindle_rpm
     elif c == 'M5':  # spindle off
         self._spindle(0)
     elif c == 'M2' or c == 'M30':  # program finish, reset everything.
         self.reset()
     elif c == 'M84':  # disable motors
         hal.disable_steppers()
     # extruder and bed heaters control
     elif c == 'M104' or c == 'M109' or c == 'M140' or c == 'M190':
         if c == 'M104' or c == 'M109':
             heater = HEATER_EXTRUDER
         elif c == 'M140' or c == 'M190':
             heater = HEATER_BED
         else:
             raise Exception("Unexpected heater command")
         wait = c == 'M109' or c == 'M190'
         if not gcode.has("S"):
             raise GMachineException("temperature is not specified")
         t = gcode.get('S', 0)
         if ((heater == HEATER_EXTRUDER and t > EXTRUDER_MAX_TEMPERATURE) or
                 (heater == HEATER_BED and t > BED_MAX_TEMPERATURE) or
                 t < MIN_TEMPERATURE) and t != 0:
             raise GMachineException("bad temperature")
         self._heat(heater, t, wait)
     elif c == 'M105':  # get temperature
         try:
             et = hal.get_extruder_temperature()
         except (IOError, OSError):
             et = None
         try:
             bt = hal.get_bed_temperature()
         except (IOError, OSError):
             bt = None
         if et is None and bt is None:
             raise GMachineException("can not measure temperature")
         answer = "E:{} B:{}".format(et, bt)
     elif c == 'M106':  # fan control
         if gcode.get('S', 1) != 0:
             self._fan(True)
         else:
             self._fan(False)
     elif c == 'M107':  # turn off fan
         self._fan(False)
     elif c == 'M111':  # enable debug
         logging_config.debug_enable()
     elif c == 'M114':  # get current position
         hal.join()
         p = self.position()
         answer = "X:{} Y:{} Z:{} E:{}".format(p.x, p.y, p.z, p.e)
     elif c is None:  # command not specified(ie just F was passed)
         pass
     # commands below are added just for compatibility
     elif c == 'M82':  # absolute mode for extruder
         if not self._absoluteCoordinates:
             raise GMachineException("Not supported, use G90/G91")
     elif c == 'M83':  # relative mode for extruder
         if self._absoluteCoordinates:
             raise GMachineException("Not supported, use G90/G91")
     else:
         raise GMachineException("unknown command")
     # save parameters on success
     self._velocity = velocity
     logging.debug("position {}".format(self._position))
     return answer
Ejemplo n.º 4
0
 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.has_coordinates():
         c = 'G1'
     # read parameters
     if self._absoluteCoordinates:
         coord = gcode.coordinates(self._position, self._convertCoordinates)
         coord = coord + self._local
         delta = coord - self._position
     else:
         delta = gcode.coordinates(Coordinates(0.0, 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)
     radius = gcode.radius(self._radius, self._convertCoordinates)
     # 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_linear(delta, STEPPER_MAX_VELOCITY_MM_PER_MIN)
     elif c == 'G1':  # linear interpolation
         self._move_linear(delta, velocity)
     elif c == 'G2':  # circular interpolation, clockwise
         self._circular(delta, radius, velocity, CW)
     elif c == 'G3':  # circular interpolation, counterclockwise
         self._circular(delta, radius, velocity, CCW)
     elif c == 'G4':  # delay in s
         hal.join()
         time.sleep(pause)
     elif c == 'G17':  # XY plane select
         self._plane = PLANE_XY
     elif c == 'G18':  # ZX plane select
         self._plane = PLANE_ZX
     elif c == 'G19':  # YZ plane select
         self._plane = PLANE_YZ
     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 == 'G53':  # switch to machine coords
         self._local = Coordinates(0.0, 0.0, 0.0, 0.0)
     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.coordinates(Coordinates(0.0, 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
     self._radius = radius
     logging.debug("position {}".format(self._position))
Ejemplo n.º 5
0
 def do_command(self, gcode):
     """ Perform action.
     :param gcode: GCode object which represent one gcode line
     :return String if any answer require, None otherwise.
     """
     if gcode is None:
         return None
     answer = None
     logging.debug("got command " + str(gcode.params))
     # read command
     c = gcode.command()
     if c is None and gcode.has_coordinates():
         c = 'G1'
     # read parameters
     if self._absoluteCoordinates:
         coord = gcode.coordinates(self._position - self._local,
                                   self._convertCoordinates)
         coord = coord + self._local
         delta = coord - self._position
     else:
         delta = gcode.coordinates(Coordinates(0.0, 0.0, 0.0, 0.0),
                                   self._convertCoordinates)
         # coord = self._position + delta
     velocity = gcode.get('F', self._velocity)
     radius = gcode.radius(Coordinates(0.0, 0.0, 0.0, 0.0),
                           self._convertCoordinates)
     # check parameters
     if velocity < MIN_VELOCITY_MM_PER_MIN:
         raise GMachineException("feed speed too low")
     # select command and run it
     if c == 'G0':  # rapid move
         vl = max(MAX_VELOCITY_MM_PER_MIN_X,
                  MAX_VELOCITY_MM_PER_MIN_Y,
                  MAX_VELOCITY_MM_PER_MIN_Z,
                  self._get_extruder_max_speed())
         l = delta.length()
         if l > 0:
             proportion = abs(delta) / l
             if proportion.x > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_X / proportion.x)
                 if v < vl:
                     vl = v
             if proportion.y > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_Y / proportion.y)
                 if v < vl:
                     vl = v
             if proportion.z > 0:
                 v = int(MAX_VELOCITY_MM_PER_MIN_Z / proportion.z)
                 if v < vl:
                     vl = v
             if proportion.e > 0:
                 v = int(self._get_extruder_max_speed() / proportion.e)
                 if v < vl:
                     vl = v
         self._move_linear(delta, vl)
     elif c == 'G1':  # linear interpolation
         self._move_linear(delta, velocity)
     elif c == 'G2':  # circular interpolation, clockwise
         self._move_circular(delta, radius, velocity, CW)
     elif c == 'G3':  # circular interpolation, counterclockwise
         self._move_circular(delta, radius, velocity, CCW)
     elif c == 'G4':  # delay in s
         if not gcode.has('P'):
             raise GMachineException("P is not specified")
         pause = gcode.get('P', 0)
         if pause < 0:
             raise GMachineException("bad delay")
         hal.join()
         time.sleep(pause)
     elif c == 'G17':  # XY plane select
         self._plane = PLANE_XY
     elif c == 'G18':  # ZX plane select
         self._plane = PLANE_ZX
     elif c == 'G19':  # YZ plane select
         self._plane = PLANE_YZ
     elif c == 'G20':  # switch to inches
         self._convertCoordinates = 25.4
     elif c == 'G21':  # switch to mm
         self._convertCoordinates = 1.0
     elif c == 'G28':  # home
         axises = gcode.has('X'), gcode.has('Y'), gcode.has('Z')
         if axises == (False, False, False):
             axises = True, True, True
         self.safe_zero(*axises)
         hal.join()
         if not hal.calibrate(*axises):
             raise GMachineException("failed to calibrate")
     elif c == 'G53':  # switch to machine coords
         raise GMachineException('Not supported')
         # TODO not sure what local/machine coordinates mean and how to handle this with multiple extruders
         # self._local = Coordinates(0.0, 0.0, 0.0, 0.0)
     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
         raise GMachineException('Not supported')
         # if gcode.has_coordinates():
         #     self._local = self._position - gcode.coordinates(
         #         Coordinates(self._position.x - self._local.x,
         #                     self._position.y - self._local.y,
         #                     self._position.z - self._local.z,
         #                     self._position.e - self._local.e),
         #         self._convertCoordinates)
         # else:
         #     self._local = self._position
     elif c == 'M2' or c == 'M30':  # program finish, reset everything.
         self.reset()
     elif c == 'M72':
         audio_id = int(gcode.get('P', 0))
         if audio_id not in AUDIO_FILES:
             raise GMachineException('Audio ID not recognized')
         audio_filepath = AUDIO_BASE_FILEPATH + AUDIO_FILES[audio_id]
         logging.info('playing audio from {}'.format(audio_filepath))
         AudioPlayer.play(audio_filepath)
     elif c == 'M84':  # disable motors
         hal.disable_steppers()
     elif c == 'M111':  # enable debug
         logging_config.debug_enable()
     elif c == 'M114':  # get current position
         hal.join()
         p = self.position()
         answer = "X:{} Y:{} Z:{} E:{}".format(p.x, p.y, p.z, p.e)
     elif c == 'T':  # select tool (extruder)
         self._set_extruder(int(gcode.get('T')))
     elif c is None:  # command not specified(ie just F was passed)
         pass
     # commands below are added just for compatibility
     elif c == 'M82':  # absolute mode for extruder
         if not self._absoluteCoordinates:
             raise GMachineException("Not supported, use G90/G91")
     elif c == 'M83':  # relative mode for extruder
         if self._absoluteCoordinates:
             raise GMachineException("Not supported, use G90/G91")
     else:
         raise GMachineException("unknown command")
     # save parameters on success
     self._velocity = velocity
     logging.debug("position {}".format(self._position))
     return answer