2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# Z-Probe support
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# Copyright (C) 2017-2019  Kevin O'Connor <kevin@koconnor.net>
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# This file may be distributed under the terms of the GNU GPLv3 license.
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import pins, homing, manual_probe
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-12 22:51:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								HINT_TIMEOUT = """
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Make sure to home the printer before probing. If the probe
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-14 15:30:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								did not move far enough to trigger, then consider reducing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								the Z axis minimum position so the probe can travel further
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								(the Z minimum position can be negative).
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-12 22:51:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class PrinterProbe:
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-24 21:41:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def __init__(self, config, mcu_probe):
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.printer = config.get_printer()
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.name = config.get_name()
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-24 21:41:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.mcu_probe = mcu_probe
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.speed = config.getfloat('speed', 5.0)
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-18 12:25:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.x_offset = config.getfloat('x_offset', 0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.y_offset = config.getfloat('y_offset', 0.)
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-17 14:00:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.z_offset = config.getfloat('z_offset')
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:34:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.probe_calibrate_z = 0.
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-14 15:30:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Infer Z position to move to during a probe
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if config.has_section('stepper_z'):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            zconfig = config.getsection('stepper_z')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.z_position = zconfig.getfloat('position_min', 0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            pconfig = config.getsection('printer')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.z_position = pconfig.getfloat('minimum_z_position', 0.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Multi-sample support (for improved accuracy)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.sample_count = config.getint('samples', 1, minval=1)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.sample_retract_dist = config.getfloat('sample_retract_dist', 2.,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                   above=0.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        atypes = {'median': 'median', 'average': 'average'}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.samples_result = config.getchoice('samples_result', atypes,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                               'average')
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.samples_tolerance = config.getfloat('samples_tolerance', 0.100,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                 minval=0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.samples_retries = config.getint('samples_tolerance_retries', 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                             minval=0)
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-24 21:41:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Register z_virtual_endstop pin
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.printer.lookup_object('pins').register_chip('probe', self)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:47:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Register PROBE/QUERY_PROBE commands
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode = self.printer.lookup_object('gcode')
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.register_command('PROBE', self.cmd_PROBE,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    desc=self.cmd_PROBE_help)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.register_command('QUERY_PROBE', self.cmd_QUERY_PROBE,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    desc=self.cmd_QUERY_PROBE_help)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.register_command('PROBE_CALIBRATE', self.cmd_PROBE_CALIBRATE,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    desc=self.cmd_PROBE_CALIBRATE_help)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.register_command('PROBE_ACCURACY', self.cmd_PROBE_ACCURACY,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                    desc=self.cmd_PROBE_ACCURACY_help)
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-26 09:44:45 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def setup_pin(self, pin_type, pin_params):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if pin_type != 'endstop' or pin_params['pin'] != 'z_virtual_endstop':
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:47:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            raise pins.error("Probe virtual endstop only useful as endstop pin")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if pin_params['invert'] or pin_params['pullup']:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise pins.error("Can not pullup/invert probe virtual endstop")
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return self.mcu_probe
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-18 12:25:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_offsets(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.x_offset, self.y_offset, self.z_offset
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _probe(self, speed):
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-08 14:23:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        homing_state = homing.Homing(self.printer)
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        pos = toolhead.get_position()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        pos[2] = self.z_position
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-08 21:49:56 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        endstops = [(self.mcu_probe, "probe")]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        verify = self.printer.get_start_args().get('debugoutput') is None
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            homing_state.homing_move(pos, endstops, speed,
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                     probe_pos=True, verify_movement=verify)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except homing.CommandError as e:
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-12 22:51:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            reason = str(e)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if "Timeout during endstop homing" in reason:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                reason += HINT_TIMEOUT
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            raise homing.CommandError(reason)
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-22 12:24:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        pos = toolhead.get_position()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info("probe at %.3f,%.3f is z=%.6f" % (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            pos[0], pos[1], pos[2]))
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.reset_last_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 11:04:55 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return pos[:3]
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _move(self, coord, speed):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        curpos = toolhead.get_position()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for i in range(len(coord)):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if coord[i] is not None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                curpos[i] = coord[i]
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead.move(curpos, speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-02 17:24:33 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.reset_last_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _calc_mean(self, positions):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        count = float(len(positions))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return [sum([pos[i] for pos in positions]) / count
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for i in range(3)]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def _calc_median(self, positions):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        z_sorted = sorted(positions, key=(lambda p: p[2]))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        middle = len(positions) // 2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if (len(positions) & 1) == 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # odd number of samples
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return z_sorted[middle]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # even number of samples
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self._calc_mean(z_sorted[middle-1:middle+1])
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def run_probe(self, params={}):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        speed = self.gcode.get_float(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "PROBE_SPEED", params, self.speed, above=0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sample_count = self.gcode.get_int(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLES", params, self.sample_count, minval=1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sample_retract_dist = self.gcode.get_float(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLE_RETRACT_DIST", params, self.sample_retract_dist, above=0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        samples_tolerance = self.gcode.get_float(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLES_TOLERANCE", params, self.samples_tolerance, minval=0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        samples_retries = self.gcode.get_int(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLES_TOLERANCE_RETRIES", params, self.samples_retries, minval=0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        samples_result = self.gcode.get_str(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLES_RESULT", params, self.samples_result)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        retries = 0
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        positions = []
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        while len(positions) < sample_count:
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # Probe position
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            pos = self._probe(speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            positions.append(pos)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # Check samples tolerance
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            z_positions = [p[2] for p in positions]
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if max(z_positions) - min(z_positions) > samples_tolerance:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if retries >= samples_retries:
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    raise homing.CommandError(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        "Probe samples exceed samples_tolerance")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.gcode.respond_info(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    "Probe samples exceed tolerance. Retrying...")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                retries += 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                positions = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Retract
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if len(positions) < sample_count:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                liftpos = [None, None, pos[2] + sample_retract_dist]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self._move(liftpos, speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 13:52:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Calculate and return result
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if samples_result == 'median':
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return self._calc_median(positions)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self._calc_mean(positions)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    cmd_PROBE_help = "Probe Z-height at current XY position"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def cmd_PROBE(self, params):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        pos = self.run_probe(params)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info("Result is z=%.6f" % (pos[2],))
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    cmd_QUERY_PROBE_help = "Return the status of the z-probe"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def cmd_QUERY_PROBE(self, params):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        print_time = toolhead.get_last_move_time()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-26 10:45:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        res = self.mcu_probe.query_endstop(print_time)
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "probe: %s" % (["open", "TRIGGERED"][not not res],))
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    cmd_PROBE_ACCURACY_help = "Probe Z-height accuracy at current XY position"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def cmd_PROBE_ACCURACY(self, params):
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-10 15:11:11 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        speed = self.gcode.get_float(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "PROBE_SPEED", params, self.speed, above=0.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sample_count = self.gcode.get_int("SAMPLES", params, 10, minval=1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sample_retract_dist = self.gcode.get_float(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "SAMPLE_RETRACT_DIST", params, self.sample_retract_dist, above=0.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        pos = toolhead.get_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-10 15:11:11 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info("PROBE_ACCURACY at X:%.3f Y:%.3f Z:%.3f"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                " (samples=%d retract=%.3f speed=%.1f\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                % (pos[0], pos[1], pos[2],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                   sample_count, sample_retract_dist, speed))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # Probe bed sample_count times
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        positions = []
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-10 15:11:11 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        while len(positions) < sample_count:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Probe position
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 13:47:15 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            pos = self._probe(speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            positions.append(pos)
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-10 15:11:11 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # Retract
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            liftpos = [None, None, pos[2] + sample_retract_dist]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self._move(liftpos, speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Calculate maximum, minimum and average values
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        max_value = max([p[2] for p in positions])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        min_value = min([p[2] for p in positions])
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-29 22:56:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        range_value = max_value - min_value
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 14:16:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        avg_value = self._calc_mean(positions)[2]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        median = self._calc_median(positions)[2]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # calculate the standard deviation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        deviation_sum = 0
							 | 
						
					
						
							
								
									
										
										
										
											2019-07-10 15:11:11 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for i in range(len(positions)):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            deviation_sum += pow(positions[i][2] - avg_value, 2.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sigma = (deviation_sum / len(positions)) ** 0.5
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Show information
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info(
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-29 22:56:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "probe accuracy results: maximum %.6f, minimum %.6f, range %.6f, "
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-18 00:23:32 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "average %.6f, median %.6f, standard deviation %.6f" % (
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-29 22:56:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            max_value, min_value, range_value, avg_value, median, sigma))
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def probe_calibrate_finalize(self, kin_pos):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if kin_pos is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:34:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        z_offset = self.probe_calibrate_z - kin_pos[2]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.respond_info(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "%s: z_offset: %.3f\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "The SAVE_CONFIG command will update the printer config file\n"
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:34:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "with the above and restart the printer." % (self.name, z_offset))
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        configfile = self.printer.lookup_object('configfile')
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:34:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        configfile.set(self.name, 'z_offset', "%.3f" % (z_offset,))
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    cmd_PROBE_CALIBRATE_help = "Calibrate the probe's z_offset"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def cmd_PROBE_CALIBRATE(self, params):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-04 20:36:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        manual_probe.verify_no_manual_probe(self.printer)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Perform initial probe
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        curpos = self.run_probe(params)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Move away from the bed
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:34:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.probe_calibrate_z = curpos[2]
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        curpos[2] += 5.
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:32:01 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self._move(curpos, self.speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Move the nozzle over the probe point
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        curpos[0] += self.x_offset
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        curpos[1] += self.y_offset
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-08 12:32:01 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self._move(curpos, self.speed)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 18:20:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Start manual probe
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        manual_probe.ManualProbeHelper(self.printer, params,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                       self.probe_calibrate_finalize)
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# Endstop wrapper that enables probe specific features
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								class ProbeEndstopWrapper:
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def __init__(self, config):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.printer = config.get_printer()
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-02 22:04:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode = self.printer.lookup_object('gcode')
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.position_endstop = config.getfloat('z_offset')
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-02 22:04:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        gcode_macro = self.printer.try_load_module(config, 'gcode_macro')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.activate_gcode = gcode_macro.load_template(
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-07 10:51:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            config, 'activate_gcode', '')
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-02 22:04:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.deactivate_gcode = gcode_macro.load_template(
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-07 10:51:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            config, 'deactivate_gcode', '')
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Create an "endstop" object to handle the probe pin
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ppins = self.printer.lookup_object('pins')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        pin = config.get('pin')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        pin_params = ppins.lookup_pin(pin, can_invert=True, can_pullup=True)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        mcu = pin_params['chip']
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        mcu.register_config_callback(self._build_config)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.mcu_endstop = mcu.setup_pin('endstop', pin_params)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Wrappers
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.get_mcu = self.mcu_endstop.get_mcu
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.add_stepper = self.mcu_endstop.add_stepper
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.get_steppers = self.mcu_endstop.get_steppers
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.home_start = self.mcu_endstop.home_start
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.home_wait = self.mcu_endstop.home_wait
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.query_endstop = self.mcu_endstop.query_endstop
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.TimeoutError = self.mcu_endstop.TimeoutError
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _build_config(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        kin = self.printer.lookup_object('toolhead').get_kinematics()
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-13 21:39:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for stepper in kin.get_steppers():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if stepper.is_active_axis('z'):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.add_stepper(stepper)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def home_prepare(self):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 18:10:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        start_pos = toolhead.get_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.activate_gcode.run_gcode_from_command()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 18:10:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if toolhead.get_position()[:3] != start_pos[:3]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise homing.CommandError(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                "Toolhead moved during probe activate_gcode script")
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.mcu_endstop.home_prepare()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def home_finalize(self):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 18:10:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        start_pos = toolhead.get_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.deactivate_gcode.run_gcode_from_command()
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 18:10:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if toolhead.get_position()[:3] != start_pos[:3]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise homing.CommandError(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                "Toolhead moved during probe deactivate_gcode script")
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.mcu_endstop.home_finalize()
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 19:29:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_position_endstop(self):
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-27 09:47:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return self.position_endstop
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-23 12:26:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-03 18:54:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# Helper code that can probe a series of points and report the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# position at each point.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class ProbePointsHelper:
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 10:32:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def __init__(self, config, finalize_callback, default_points=None):
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-20 11:28:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.printer = config.get_printer()
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 10:32:57 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.finalize_callback = finalize_callback
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-20 11:28:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.probe_points = default_points
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-17 20:47:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.name = config.get_name()
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode = self.printer.lookup_object('gcode')
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-20 11:28:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Read config settings
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if default_points is None or config.get('points', None) is not None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            points = config.get('points').split('\n')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                points = [line.split(',', 1) for line in points if line.strip()]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.probe_points = [(float(p[0].strip()), float(p[1].strip()))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                     for p in points]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            except:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                raise config.error("Unable to parse probe points in %s" % (
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-17 20:47:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    self.name))
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-20 11:28:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.horizontal_move_z = config.getfloat('horizontal_move_z', 5.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.speed = config.getfloat('speed', 50., above=0.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 16:37:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.use_offsets = False
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-20 11:28:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Internal probing state
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.lift_speed = self.speed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.probe_offsets = (0., 0., 0.)
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-03 18:54:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.results = []
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-17 20:47:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def minimum_points(self,n):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if len(self.probe_points) < n:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise self.printer.config_error(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                "Need at least %d probe points for %s" % (n, self.name))
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 16:37:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def use_xy_offsets(self, use_offsets):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.use_offsets = use_offsets
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-21 14:48:01 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_lift_speed(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.lift_speed
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _move_next(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        toolhead = self.printer.lookup_object('toolhead')
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-25 10:55:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Lift toolhead
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        speed = self.lift_speed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if not self.results:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Use full speed to first probe position
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            speed = self.speed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        curpos = toolhead.get_position()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        curpos[2] = self.horizontal_move_z
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead.move(curpos, speed)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 11:25:56 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Check if done probing
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 12:15:39 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if len(self.results) >= len(self.probe_points):
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.gcode.reset_last_position()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            toolhead.get_last_move_time()
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-23 19:20:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            res = self.finalize_callback(self.probe_offsets, self.results)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if res != "retry":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return True
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.results = []
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 11:25:56 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Move to next XY probe point
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        curpos[:2] = self.probe_points[len(self.results)]
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-14 16:37:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.use_offsets:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            curpos[0] -= self.probe_offsets[0]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            curpos[1] -= self.probe_offsets[1]
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-03 13:07:22 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        toolhead.move(curpos, self.speed)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 11:51:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.gcode.reset_last_position()
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return False
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 13:07:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def start_probe(self, params):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-04 20:36:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        manual_probe.verify_no_manual_probe(self.printer)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 13:07:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Lookup objects
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        probe = self.printer.lookup_object('probe', None)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        method = self.gcode.get_str('METHOD', params, 'automatic').lower()
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.results = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if probe is None or method != 'automatic':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Manual probe
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-26 13:07:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.lift_speed = self.speed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.probe_offsets = (0., 0., 0.)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._manual_probe_start()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # Perform automatic probing
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.lift_speed = min(self.speed, probe.speed)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.probe_offsets = probe.get_offsets()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.horizontal_move_z < self.probe_offsets[2]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise self.gcode.error("horizontal_move_z can't be less than"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                   " probe's z_offset")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        while 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            done = self._move_next()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if done:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                break
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-21 14:44:28 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            pos = probe.run_probe(params)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.results.append(pos)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def _manual_probe_start(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        done = self._move_next()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if not done:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            manual_probe.ManualProbeHelper(self.printer, {},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                           self._manual_probe_finalize)
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-09 22:54:24 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _manual_probe_finalize(self, kin_pos):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if kin_pos is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.results.append(kin_pos)
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-31 15:30:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self._manual_probe_start()
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-03 18:54:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-06 01:00:33 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								def load_config(config):
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-24 21:41:25 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return PrinterProbe(config, ProbeEndstopWrapper(config))
							 |