Ejemplo n.º 1
0
  def execute(self, g):
    gcodes = self.printer.config.get("Macros", "G29").split("\n")
    self.printer.path_planner.wait_until_done()
    for gcode in gcodes:
      # If 'S' (imulate) remove M561 and M500 codes
      if (g.has_letter("S")) and ("RFS" in gcode):
        logging.debug("G29: Removing due to RFS: " + str(gcode))
      else:    # Execute the code
        G = Gcode({"message": gcode, "parent": g})
        self.printer.processor.resolve(G)
        self.printer.processor.execute(G)
        self.printer.path_planner.wait_until_done()

    probe_data = copy.deepcopy(self.printer.probe_points)
    bed_data = {
        "probe_data": {
            "x": [],
            "y": [],
            "z": []
        },
        "probe_type": "test" if g.has_letter("S") else "probe",
        "replicape_key": self.printer.config.replicape_key
    }
    for k, v in enumerate(probe_data):
      bed_data["probe_data"]["x"].append(probe_data[k]["X"])
      bed_data["probe_data"]["y"].append(probe_data[k]["Y"])
      bed_data["probe_data"]["z"].append(self.printer.probe_heights[k])

    Alarm.action_command("bed_probe_data", json.dumps(bed_data))
Ejemplo n.º 2
0
    def execute(self, g):
        heater_nr = g.get_int_by_letter("H", 0)
        heater_name = ["HBP", "E", "H", "A", "B",
                       "C"][heater_nr + 1]  # Map to name
        if not heater_name in self.printer.heaters:
            logging.warning("M303: Heater does not exist")
            return
        heater = self.printer.heaters[heater_name]
        temp = g.get_float_by_letter("S", 200.0)
        cycles = max(3, g.get_int_by_letter("N", 4))
        pre_cal = bool(g.get_int_by_letter("P", 0))
        tuning_algo_nr = g.get_int_by_letter("L", 0)
        if tuning_algo_nr not in [0, 1]:
            logging.warning(
                "Unknown tuning algorithm '{}'. Use one of 0, 1. Choosing 0.".
                format(tuning_algo_nr))
            tuning_algo_nr = 0
        tuning_algo = ["TL", "ZN"][tuning_algo_nr]

        tuner = Autotune(heater, temp, cycles, g, self.printer, pre_cal,
                         tuning_algo)
        tuner.run()
        logging.info("Max temp: {}, Min temp: {}, Ku: {}, Pu: {}".format(
            tuner.max_temp, tuner.min_temp, tuner.Ku, tuner.Pu))
        logging.info("Kp: {}, Ti: {}, Td: {}".format(heater.Kp, heater.Ti,
                                                     heater.Td))
        self.printer.send_message(
            g.prot, "Max temp: {}, Min temp: {}, Ku: {}, Pu: {}".format(
                tuner.max_temp, tuner.min_temp, tuner.Ku, tuner.Pu))
        self.printer.send_message(
            g.prot, "Kp: {}, Ti: {}, Td: {}".format(heater.Kp, heater.Ti,
                                                    heater.Td))
        self.printer.send_message(g.prot, "Settings by G-code: \n")
        self.printer.send_message(
            g.prot, "M130 P{} S{:.4f}\n".format(heater_nr, heater.Kp))
        self.printer.send_message(
            g.prot, "M131 P{} S{:.4f}\n".format(heater_nr, heater.Ti))
        self.printer.send_message(
            g.prot, "M132 P{} S{:.4f}\n".format(heater_nr, heater.Td))
        self.printer.send_message(g.prot, "Settings in local.cfg: \n")
        self.printer.send_message(
            g.prot, "pid_Kp_{} = {:.4f}\n".format(heater_name.lower(),
                                                  heater.Kp))
        self.printer.send_message(
            g.prot, "pid_Ti_{} = {:.4f}\n".format(heater_name.lower(),
                                                  heater.Ti))
        self.printer.send_message(
            g.prot, "pid_Td_{} = {:.4f}".format(heater_name.lower(),
                                                heater.Td))

        tune_data = {
            "tune_data": tuner.plot_temps,
            "tune_gcode": g.message,
            "replicape_key": self.printer.config.replicape_key
        }

        Alarm.action_command("pid_tune_data", json.dumps(tune_data))
Ejemplo n.º 3
0
 def execute(self, g):
     settings = self.printer.config.get_default_settings()
     # If no tokens are given, return the current settings
     if g.num_tokens() == 0:
         answer = "ok " + "\n".join([":".join(line) for line in settings])
         g.set_answer(answer)
     elif g.has_letter("U"):
         Alarm.action_command(
             "review_data",
             json.dumps({
                 "type": "review_data",
                 "message_title": "Config data ready",
                 "message_text": "Click to upload and view",
                 "message_type": "info",
                 "message_hide": False,
                 "data_type": "config_data",
                 "replicape_key": self.printer.config.replicape_key,
                 "data": settings
             }))
Ejemplo n.º 4
0
  def execute(self, g):
    bed_diameter_mm = g.get_float_by_letter("D", 140.0)    # Bed diameter
    # Number of circles
    circles = g.get_int_by_letter("C", 2)
    points_pr_circle = g.get_int_by_letter("P", 8)    # Points pr circle
    probe_start_height = g.get_float_by_letter("S", 6.0)    # Probe starting point above bed
    # Add probe point in 0, 0
    add_zero = bool(g.get_int_by_letter("Z", 1))
    probe_speed = g.get_float_by_letter("K", 3000)
    reverse = g.get_int_by_letter("R", 0)
    reverse = -1 if bool(reverse) else 1
    bed_comp = g.get_int_by_letter('B', 0)

    theta = np.linspace(0, reverse * 2 * np.pi, points_pr_circle, endpoint=False)

    probes = []
    r = bed_diameter_mm / 2
    for a in np.linspace(r, 0, circles, endpoint=False):
      for t in theta:
        x, y = a * np.cos(t), a * np.sin(t)
        probes.append((x, y))
    if add_zero:
      probes.append((0, 0))

    gcodes = "M561; (RFS) Reset bed matrix\n"
    for i, p in enumerate(probes):
      gcodes += "M557 P{0} X{1:+02.2f} Y{2:+02.2f} Z{3}\n".format(i, p[0], p[1], probe_start_height)
    gcodes += "    G32 ; Undock probe\n"
    gcodes += "    G28 ; Home steppers\n"
    for i in range(len(probes)):
      gcodes += "    G30 P{} S F{}; Probe point {}\n".format(i, probe_speed, i)
    gcodes += "    G31 ; Dock probe\n"
    if bed_comp:
      gcodes += "    M561 U; (RFS) Update the matrix based on probe data\n"
      gcodes += "    M561 S; Show the current matrix\n"
    gcodes += "    M500; (RFS) Save data\n"

    # Reset probe points
    self.printer.probe_points = []
    self.printer.config.set("Macros", "G29", gcodes)
    Alarm.action_command("new_g29", json.dumps(gcodes))
Ejemplo n.º 5
0
  def execute(self, g):
    width = g.get_float_by_letter("W", 180.0)    # Bed width
    depth = g.get_float_by_letter("D", 180.0)    # Bed depth
    points = g.get_int_by_letter("P", 16)    # Points in total
    probe_start_height = g.get_float_by_letter("S", 6.0)    # Probe starting point above bed
    probe_speed = g.get_float_by_letter("K", 3000)
    probe_offset_x = g.get_float_by_letter("X", 0)    # Offset X from starting point
    probe_offset_y = g.get_float_by_letter("Y", 0)    # Offset Y from starting point
    invert = 1 if g.has_letter("I") else 0    # Invert probing
    bed_comp = g.get_int_by_letter('B', 1)

    ppd = np.sqrt(points)

    probes = []
    for x in np.linspace(0, width, ppd):
      for y in np.linspace(0, depth, ppd):
        probes.append((x + probe_offset_x, y + probe_offset_y))

    gcodes = "; Generated by command '" + g.message + "'\n"

    gcodes += "M561; (RFS) Reset bed matrix\n"

    for i, p in enumerate(probes):
      gcodes += "M557 P{0} X{1:+02.2f} Y{2:+02.2f} Z{3}\n".format(i, p[0], p[1], probe_start_height)
    gcodes += "    G32 ; Undock probe\n"
    gcodes += "    G28 ; Home steppers\n"
    for i in range(len(probes)):
      if invert:
        gcodes += "    G30 P{} S F{}; Probe point {}\n".format(
            len(probes) - i - 1, probe_speed,
            len(probes) - i - 1)
      else:
        gcodes += "    G30 P{} S F{}; Probe point {}\n".format(i, probe_speed, i)
    gcodes += "    G31 ; Dock probe\n"
    if bed_comp:
      gcodes += "    M561 U; (RFS) Update the matrix based on probe data\n"
      gcodes += "    M561 S; Show the current matrix\n"
    gcodes += "    M500; (RFS) Save data\n"

    self.printer.config.set("Macros", "G29", gcodes)
    Alarm.action_command("new_g29", json.dumps(gcodes))
Ejemplo n.º 6
0
  def execute(self, g):
    if g.has_letter("P"):    # Load point
      index = g.get_int_by_letter("P")
      try:
        point = self.printer.probe_points[index]
      except IndexError:
        logging.warning("G30 point P%d not yet defined. Aborting.", index)
        return
    else:
      # If no probe point is specified, use current position
      # this value is in metres
      # convert to millimetres as we are using this value for a G0 call
      point = self.printer.path_planner.get_current_pos(mm=True, ideal=True)
      logging.debug("G30: current position (mm) :  X{} Y{} Z{}".format(
          point["X"], point["Y"], point["Z"]))
    """ do not convert to SI m because used as is in gcode command, below """
    if g.has_letter("X"):    # Override X
      point["X"] = g.get_float_by_letter("X")
    if g.has_letter("Y"):    # Override Y
      point["Y"] = g.get_float_by_letter("Y")
    if g.has_letter("Z"):    # Override Z
      point["Z"] = g.get_float_by_letter("Z")

    # Get probe length, if present, else use value from config.
    if g.has_letter("D"):
      probe_length = g.get_float_by_letter("D") / 1000.
    else:
      probe_length = self.printer.config.getfloat('Probe', 'length')

    # Get probe speed, if present, else use value from config.
    if g.has_letter("F"):
      probe_speed = g.get_float_by_letter("F") / 60000.    # m/s
    else:
      probe_speed = self.printer.config.getfloat('Probe', 'speed')

    # Get acceleration, if present, else use value from config.
    if g.has_letter("Q"):
      probe_accel = g.get_float_by_letter("Q") / 3600000.    # m/s^2
    else:
      probe_accel = self.printer.config.getfloat('Probe', 'accel')

    # Find the Probe offset
    # values in config file are in metres, need to convert to millimetres
    offset_x = self.printer.config.getfloat('Probe', 'offset_x') * 1000
    offset_y = self.printer.config.getfloat('Probe', 'offset_y') * 1000
    offset_z = self.printer.config.getfloat('Probe', 'offset_z') * 1000

    logging.debug("G30: probing from point (mm) : X{} Y{} Z{}".format(
        point["X"] + offset_x, point["Y"] + offset_y, point["Z"]))

    # Move to the position
    G0 = Gcode({
        "message":
            "G0 X{} Y{} Z{}".format(point["X"] + offset_x, point["Y"] + offset_y, point["Z"]),
        "parent":
            g
    })
    self.printer.processor.resolve(G0)
    self.printer.processor.execute(G0)
    self.printer.path_planner.wait_until_done()

    bed_dist = self.printer.path_planner.probe(probe_length, probe_speed,
                                               probe_accel) * 1000.0    # convert to mm
    logging.info("G30: adjusting offset using Z-probe offset by " + str(offset_z))
    bed_dist = bed_dist - offset_z    # apply z offset
    bed_dist = round(bed_dist, 3)

    logging.debug("Bed dist: " + str(bed_dist) + " mm")

    self.printer.send_message(
        g.prot, "Found Z probe distance {0:.2f} mm at (X, Y) = ({1:.2f}, {2:.2f})".format(
            bed_dist, point["X"], point["Y"]))

    Alarm.action_command("bed_probe_point", json.dumps([point["X"], point["Y"], bed_dist]))

    # Must have S to save the probe bed distance
    # this is required for calculation of the bed compensation matrix
    # NOTE: the use of S in G30 means "save".
    if g.has_letter("S"):
      if not g.has_letter("P"):
        logging.warning("G30: S-parameter was set, but no index (P) was set.")
      else:
        self.printer.probe_heights[index] = bed_dist
Ejemplo n.º 7
0
  def execute(self, g):
    # Catch most letters to tell user use may have been in error.
    if g.has_letter("P"):
      self.printer.send_message(
          g.prot, "Warning: P not supported for G30.1, proceeding as if none existed.")
    if g.has_letter("X"):    # Override X
      self.printer.send_message(
          g.prot, "Warning: X not supported for G30.1, proceeding as if none existed.")
    if g.has_letter("Y"):    # Override Y
      self.printer.send_message(
          g.prot, "Warning: Y not supported for G30.1, proceeding as if none existed.")
    if g.has_letter("Z"):    # Override Z
      Z_new = g.get_float_by_letter("Z")
    else:
      Z_new = 0

    # Usable letters listed here
    # Get probe length, if present, else use value from config.
    if g.has_letter("D"):
      probe_length = g.get_float_by_letter("D") / 1000.
    else:
      probe_length = self.printer.config.getfloat('Probe', 'length')

    # Get probe speed. If not preset, use printer's current speed.
    if g.has_letter("F"):
      probe_speed = g.get_float_by_letter("F") / 60000.0
    else:
      probe_speed = self.printer.config.getfloat('Probe', 'speed')

    # Get acceleration. If not present, use value from config.
    if g.has_letter("Q"):
      probe_accel = g.get_float_by_letter("Q") / 3600000.0
    else:
      probe_accel = self.printer.config.getfloat('Probe', 'accel')

    point = self.printer.path_planner.get_current_pos(mm=True, ideal=True)
    logging.debug("G30.1: current position (mm) :  X{} Y{} Z{}".format(
        point["X"], point["Y"], point["Z"]))
    logging.debug("G30.1: will set bed to Z{}".format(Z_new))

    # Find the Probe offset
    # values in config file are in metres, need to convert to millimetres
    offset_x = self.printer.config.getfloat('Probe', 'offset_x') * 1000
    offset_y = self.printer.config.getfloat('Probe', 'offset_y') * 1000
    offset_z = self.printer.config.getfloat('Probe', 'offset_z') * 1000

    logging.debug("G30.1: probing from point (mm) : X{} Y{} Z{}".format(
        point["X"] + offset_x, point["Y"] + offset_y, point["Z"]))

    # Move to the position
    G0 = Gcode({
        "message":
            "G0 X{} Y{} Z{}".format(point["X"] + offset_x, point["Y"] + offset_y, point["Z"]),
        "parent":
            g
    })
    self.printer.processor.resolve(G0)
    self.printer.processor.execute(G0)
    self.printer.path_planner.wait_until_done()
    bed_dist = self.printer.path_planner.probe(probe_length, probe_speed,
                                               probe_accel) * 1000.0    # convert to mm
    logging.info("G30: adjusting offset using Z-probe offset by " + str(offset_z))
    bed_dist = bed_dist - offset_z    # apply z offset

    # calculated required offset to make bed equal to Z0 or user's specified Z.
    # should be correct, assuming probe starts at Z(5), requested Z(0)  probe Z(-0.3), adjusted global Z should be 5.3
    # assuming probe starts at Z(5), and probe result is -0.3. This says real probe start was 5.3.
    # if we want to start printing at 0.2 above bed, new z should be 5.1.
    # 5 - (-0.3) - 0.2 = 5.1

    Z_adjusted = point["Z"] - bed_dist - Z_new
    logging.debug("Bed dist: " + str(bed_dist) + " mm")
    logging.debug("Old Z{}, New Z{}.".format(point["Z"], Z_adjusted))

    self.printer.send_message(g.prot, "Offsetting Z by {} to Z{}".format(bed_dist, Z_adjusted))
    # wiley's advice on bypassing sending via G92
    pos = {}
    pos["Z"] = Z_adjusted / 1000.0
    path = G92Path(pos, self.printer.feed_rate)
    self.printer.path_planner.add_path(path)

    # not sure if next part is necessary
    Alarm.action_command("bed_probe_point", json.dumps([point["X"], point["Y"], bed_dist]))
Ejemplo n.º 8
0
 def execute(self, g):
   text = g.get_message()[len("M117"):]
   if text[0] == ' ':
     text = text[1:]
   Alarm.action_command("display_message", text.rstrip())