配置信息
powershell
复制代码
[probe]
pin: !PD4
x_offset: 0
y_offset: 0
z_offset: -0.20 #the distance between nozzle and level switch
speed: 10
samples: 2 #probe one point three times get an average
samples_result: average
sample_retract_dist: 5
samples_tolerance: 0.05 # precision
samples_tolerance_retries: 5
入口
python
复制代码
def load_config(config):
return PrinterProbe(config, ProbeEndstopWrapper(config))
初始化
python
复制代码
class PrinterProbe:
def __init__(self, config, mcu_probe):
self.printer = config.get_printer()
self.name = config.get_name()
self.mcu_probe = mcu_probe
self.speed = config.getfloat('speed', 5.0, above=0.)
self.lift_speed = config.getfloat('lift_speed', self.speed, above=0.)
self.x_offset = config.getfloat('x_offset', 0.)
self.y_offset = config.getfloat('y_offset', 0.)
self.z_offset = config.getfloat('z_offset')
self.probe_calibrate_z = 0.
self.multi_probe_pending = False
self.last_state = False
self.last_z_result = 0.
self.gcode_move = self.printer.load_object(config, "gcode_move")
# 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.,
note_valid=False)
else:
pconfig = config.getsection('printer')
self.z_position = pconfig.getfloat('minimum_z_position', 0.,
note_valid=False)
# Multi-sample support (for improved accuracy)
self.sample_count = config.getint('samples', 1, minval=1)
self.sample_retract_dist = config.getfloat('sample_retract_dist', 2.,
above=0.)
atypes = {'median': 'median', 'average': 'average'}
self.samples_result = config.getchoice('samples_result', atypes,
'average')
self.samples_tolerance = config.getfloat('samples_tolerance', 0.100,
minval=0.)
self.samples_retries = config.getint('samples_tolerance_retries', 0,
minval=0)
# Register z_virtual_endstop pin
self.printer.lookup_object('pins').register_chip('probe', self)
# Register homing event handlers
self.printer.register_event_handler("homing:homing_move_begin",
self._handle_homing_move_begin)
self.printer.register_event_handler("homing:homing_move_end",
self._handle_homing_move_end)
self.printer.register_event_handler("homing:home_rails_begin",
self._handle_home_rails_begin)
self.printer.register_event_handler("homing:home_rails_end",
self._handle_home_rails_end)
self.printer.register_event_handler("gcode:command_error",
self._handle_command_error)
# Register PROBE/QUERY_PROBE commands
self.gcode = self.printer.lookup_object('gcode')
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)
self.gcode.register_command('PROBE_ACCURACY', self.cmd_PROBE_ACCURACY,
desc=self.cmd_PROBE_ACCURACY_help)
self.gcode.register_command('Z_OFFSET_APPLY_PROBE',
self.cmd_Z_OFFSET_APPLY_PROBE,
desc=self.cmd_Z_OFFSET_APPLY_PROBE_help)
初始化打印机对象和探针参数 :
self.printer
:通过 config.get_printer()
获取打印机对象。
self.name
:通过 config.get_name()
获取探针名称。
self.mcu_probe
:保存传入的 MCU 探针对象。
速度设置:speed
、lift_speed
、x_offset
、y_offset
、z_offset
和 probe_calibrate_z
等控制探针的移动速度和偏移。
推断探针的 Z 轴位置 :
根据配置文件,确定探针在探测过程中的 Z 轴移动位置。
如果配置中有 stepper_z
段,使用其中 position_min
定义的 Z 轴最小位置。
否则,从 printer
配置的 minimum_z_position
获取 Z 轴最小位置。配置里minimum_z_position: -5
多重采样设置(提高测量精度) :
sample_count
:设定采样次数,以便进行多次测量来提高精度。
sample_retract_dist
:设定每次采样后探针提升的距离。
samples_result
:采样结果的处理方式,可以选择 'median'(中位数)或 'average'(平均值)。
samples_tolerance
和 samples_retries
:设定采样的误差容忍度和重试次数,用于提高多重采样的稳定性。
注册探针的 Z 虚拟端点 :
使用 self.printer.lookup_object('pins').register_chip('probe', self)
将探针注册为 Z 虚拟端点,使其在打印机控制系统中可以作为端点来使用。
注册归位事件处理器 :
homing
相关事件处理器会在归位过程的不同阶段触发,分别在归位移动开始和结束时执行 _handle_homing_move_begin
和 _handle_homing_move_end
,在归位轨道的开始和结束时执行 _handle_home_rails_begin
和 _handle_home_rails_end
。如果在 GCode 命令中遇到错误,则会触发 _handle_command_error
。
注册 GCode 命令 :
PROBE
:触发一次探针操作。
QUERY_PROBE
:查询探针状态。
PROBE_CALIBRATE
:校准探针的 Z 轴偏移。
PROBE_ACCURACY
:测量探针的精度。
Z_OFFSET_APPLY_PROBE
:将当前 Z 轴偏移应用到探针。
python
复制代码
class ProbeEndstopWrapper:
def __init__(self, config):
self.printer = config.get_printer()
self.position_endstop = config.getfloat('z_offset')
self.stow_on_each_sample = config.getboolean(
'deactivate_on_each_sample', True)
gcode_macro = self.printer.load_object(config, 'gcode_macro')
self.activate_gcode = gcode_macro.load_template(
config, 'activate_gcode', '')
self.deactivate_gcode = gcode_macro.load_template(
config, 'deactivate_gcode', '')
# 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']
self.mcu_endstop = mcu.setup_pin('endstop', pin_params)
self.printer.register_event_handler('klippy:mcu_identify',
self._handle_mcu_identify)
# 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
# multi probes state
self.multi = 'OFF'
初始化打印机对象和配置参数 :
self.printer
使用 config.get_printer()
获取打印机对象。
self.position_endstop
设定了 z_offset
(Z 轴端点偏移量),用于定义探针的初始位置或偏移。
self.stow_on_each_sample
用于配置探针是否在每次采样后停放,默认为 True
。
加载 GCode 宏 :
使用 gcode_macro
对象从配置中加载探针激活和停用的 GCode 模板:
activate_gcode
:在探针激活时执行的 GCode。
deactivate_gcode
:在探针停用时执行的 GCode。
创建端点对象 :
使用 pins
对象(通过 self.printer.lookup_object('pins')
获得)查找探针的 pin
(引脚)配置。
通过 lookup_pin()
配置引脚参数,包括是否可以反转或上拉电阻,随后得到引脚参数 pin_params
。
使用引脚所在的 mcu
芯片设置一个 endstop
引脚对象 mcu_endstop
,负责处理探针状态。
注册事件处理程序 :
注册事件 klippy:mcu_identify
,当触发该事件时调用 _handle_mcu_identify
方法。这个方法通常用于在初始化或连接时对探针或端点进行识别和确认。
简化调用的包装函数 :
定义一些包装函数用于直接调用 mcu_endstop
对象的相关方法,包括:
get_mcu
:获取探针所在的 MCU 对象。
add_stepper
:将步进电机添加到探针控制中。
get_steppers
:获取当前与探针关联的步进电机。
home_start
和 home_wait
:用于控制探针的归位和等待状态。
query_endstop
:查询端点的当前状态(是否被触发)。
多重探针状态 :
定义 self.multi
,表示多重探针采样状态,默认为 'OFF'
。
python
复制代码
class ProbePointsHelper:
def __init__(self, config, finalize_callback, default_points=None):
self.printer = config.get_printer()
self.finalize_callback = finalize_callback
self.probe_points = default_points
self.name = config.get_name()
self.gcode = self.printer.lookup_object('gcode')
# Read config settings
if default_points is None or config.get('points', None) is not None:
self.probe_points = config.getlists('points', seps=(',', '\n'),
parser=float, count=2)
self.horizontal_move_z = config.getfloat('horizontal_move_z', 5.)
self.speed = config.getfloat('speed', 50., above=0.)
self.use_offsets = False
# Internal probing state
self.lift_speed = self.speed
self.probe_offsets = (0., 0., 0.)
self.results = []
该对象会在 bed_mesh 和 delta_calibrate 模块加载时进行初始化,并传入回调函数和探测点points等信息。
探测判断
python
复制代码
# delta 校准
ProbePointsHelper.start_probe (probe.py) -> ProbePointsHelper._move_next (probe.py) ->
DeltaCalibrate.probe_finalize (delta_calibrate.py)
# bed_mesh 校准
ProbePointsHelper.start_probe (probe.py) -> ProbePointsHelper._move_next (probe.py) ->
BedMeshCalibrate.probe_finalize (bed_mesh.py)
探测是否结束代码逻辑
python
复制代码
def _move_next(self):
toolhead = self.printer.lookup_object('toolhead')
# Lift toolhead
speed = self.lift_speed
if not self.results:
# Use full speed to first probe position
speed = self.speed
toolhead.manual_move([None, None, self.horizontal_move_z], speed)
# Check if done probing
if len(self.results) >= len(self.probe_points):
toolhead.get_last_move_time()
res = self.finalize_callback(self.probe_offsets, self.results)
if res != "retry":
return True
self.results = []
# Move to next XY probe point
nextpos = list(self.probe_points[len(self.results)])
if self.use_offsets:
nextpos[0] -= self.probe_offsets[0]
nextpos[1] -= self.probe_offsets[1]
toolhead.manual_move(nextpos, self.speed)
return False
提升探针或工具头
通过调用 toolhead.manual_move
,将探针或工具头移动到指定的高度 self.horizontal_move_z
。
如果这是第一次探测(self.results
为空),会使用较快的初始速度(self.speed
)。否则使用探针提升速度(self.lift_speed
)。
检查探测是否完成
检查已完成探测点的数量是否达到预定的探测点总数(len(self.probe_points)
)。
如果所有点都探测完成:
调用 toolhead.get_last_move_time()
记录最后的移动时间。
执行 self.finalize_callback
,处理探测结果(如计算网格调整数据等)。
处理探测结果
finalize_callback
返回值决定后续操作:
如果返回值不是 "retry"
,探测结束,方法返回 True
。
如果返回值为 "retry"
,表示需要重新探测,清空结果 self.results
并从头开始。
移动到下一个探测点
确定下一个探测点的坐标:
从 self.probe_points
列表中取出对应位置的点。
如果启用了偏移(self.use_offsets
),会调整 X、Y 坐标以考虑探针的实际偏移量。
将探针移动到下一个点,准备进行探测。
返回继续探测
方法返回 False
,表示探测未完成,需要继续执行探测流程。