Esempio n. 1
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
Esempio n. 2
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