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))
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))
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 }))
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))
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))
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
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]))
def execute(self, g): text = g.get_message()[len("M117"):] if text[0] == ' ': text = text[1:] Alarm.action_command("display_message", text.rstrip())