2019-08-06 22:03:42 +03:00
|
|
|
# Perform Z Homing at specific XY coordinates.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2019 Florian Heilmann <Florian.Heilmann@gmx.net>
|
|
|
|
#
|
|
|
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
|
|
|
|
|
|
|
class SafeZHoming:
|
|
|
|
def __init__(self, config):
|
|
|
|
self.printer = config.get_printer()
|
|
|
|
try:
|
|
|
|
x_pos, y_pos = config.get("home_xy_position",
|
2019-09-18 16:37:33 +03:00
|
|
|
default=",").split(',')
|
2019-08-06 22:03:42 +03:00
|
|
|
self.home_x_pos, self.home_y_pos = float(x_pos), float(y_pos)
|
|
|
|
except:
|
|
|
|
raise config.error("Unable to parse home_xy_position in %s" % (
|
|
|
|
config.get_name()))
|
|
|
|
|
|
|
|
self.z_hop = config.getfloat("z_hop", default=0.0)
|
|
|
|
self.z_hop_speed = config.getfloat('z_hop_speed', 15., above=0.)
|
|
|
|
self.max_z = config.getsection('stepper_z').getfloat('position_max')
|
|
|
|
self.speed = config.getfloat('speed', 50.0, above=0.)
|
2019-10-01 16:07:21 +03:00
|
|
|
self.move_to_previous = config.getboolean('move_to_previous', False)
|
2020-08-17 07:05:41 +03:00
|
|
|
self.printer.load_object(config, 'gcode_move')
|
2019-08-06 22:03:42 +03:00
|
|
|
self.gcode = self.printer.lookup_object('gcode')
|
2020-02-13 04:19:18 +03:00
|
|
|
self.prev_G28 = self.gcode.register_command("G28", None)
|
2019-08-06 22:03:42 +03:00
|
|
|
self.gcode.register_command("G28", self.cmd_G28)
|
|
|
|
|
|
|
|
if config.has_section("homing_override"):
|
|
|
|
raise config.error("homing_override and safe_z_homing cannot"
|
2019-09-18 16:37:33 +03:00
|
|
|
+" be used simultaneously")
|
2019-08-06 22:03:42 +03:00
|
|
|
|
2020-04-25 05:49:13 +03:00
|
|
|
def cmd_G28(self, gcmd):
|
2019-08-06 22:03:42 +03:00
|
|
|
toolhead = self.printer.lookup_object('toolhead')
|
|
|
|
|
|
|
|
# Perform Z Hop if necessary
|
|
|
|
if self.z_hop != 0.0:
|
2019-09-18 16:37:33 +03:00
|
|
|
# Check if Z axis is homed or has a known position
|
2020-08-17 05:43:03 +03:00
|
|
|
curtime = self.printer.get_reactor().monotonic()
|
|
|
|
kin_status = toolhead.get_kinematics().get_status(curtime)
|
2019-11-25 03:16:21 +03:00
|
|
|
if 'z' in kin_status['homed_axes']:
|
2019-09-18 16:37:33 +03:00
|
|
|
# Check if the zhop would exceed the printer limits
|
2020-08-17 05:43:03 +03:00
|
|
|
pos = toolhead.get_position()
|
2019-09-18 16:37:33 +03:00
|
|
|
if pos[2] + self.z_hop > self.max_z:
|
2020-04-25 05:49:13 +03:00
|
|
|
gcmd.respond_info(
|
2019-09-18 16:37:33 +03:00
|
|
|
"No zhop performed, target Z out of bounds: " +
|
2020-04-25 05:49:13 +03:00
|
|
|
str(pos[2] + self.z_hop))
|
2019-09-18 16:37:33 +03:00
|
|
|
elif pos[2] < self.z_hop:
|
2020-08-17 05:43:03 +03:00
|
|
|
self._perform_z_hop()
|
2019-08-06 22:03:42 +03:00
|
|
|
else:
|
2020-08-17 05:43:03 +03:00
|
|
|
self._perform_z_hop()
|
2020-03-02 07:00:41 +03:00
|
|
|
if hasattr(toolhead.get_kinematics(), "note_z_not_homed"):
|
|
|
|
toolhead.get_kinematics().note_z_not_homed()
|
2019-08-06 22:03:42 +03:00
|
|
|
|
|
|
|
# Determine which axes we need to home
|
2020-04-25 05:49:13 +03:00
|
|
|
need_x, need_y, need_z = [gcmd.get(axis, None) is not None
|
|
|
|
for axis in "XYZ"]
|
2020-04-22 18:55:25 +03:00
|
|
|
if not need_x and not need_y and not need_z:
|
|
|
|
need_x = need_y = need_z = True
|
2019-08-06 22:03:42 +03:00
|
|
|
|
|
|
|
# Home XY axes if necessary
|
|
|
|
new_params = {}
|
|
|
|
if need_x:
|
|
|
|
new_params['X'] = '0'
|
|
|
|
if need_y:
|
|
|
|
new_params['Y'] = '0'
|
|
|
|
if new_params:
|
2020-04-22 19:40:32 +03:00
|
|
|
g28_gcmd = self.gcode.create_gcode_command("G28", "G28", new_params)
|
|
|
|
self.prev_G28(g28_gcmd)
|
2020-08-05 18:52:23 +03:00
|
|
|
|
2019-08-06 22:03:42 +03:00
|
|
|
# Home Z axis if necessary
|
|
|
|
if need_z:
|
2020-08-05 18:52:23 +03:00
|
|
|
# Throw an error if X or Y are not homed
|
2020-08-17 05:43:03 +03:00
|
|
|
curtime = self.printer.get_reactor().monotonic()
|
|
|
|
kin_status = toolhead.get_kinematics().get_status(curtime)
|
2020-08-05 18:52:23 +03:00
|
|
|
if ('x' not in kin_status['homed_axes'] or
|
|
|
|
'y' not in kin_status['homed_axes']):
|
|
|
|
raise gcmd.error("Must home X and Y axes first")
|
|
|
|
# Move to safe XY homing position
|
2020-08-17 05:43:03 +03:00
|
|
|
prevpos = toolhead.get_position()
|
|
|
|
toolhead.manual_move([self.home_x_pos, self.home_y_pos], self.speed)
|
2019-08-06 22:03:42 +03:00
|
|
|
# Home Z
|
2020-04-22 19:40:32 +03:00
|
|
|
g28_gcmd = self.gcode.create_gcode_command("G28", "G28", {'Z': '0'})
|
|
|
|
self.prev_G28(g28_gcmd)
|
2019-09-18 16:37:33 +03:00
|
|
|
# Perform Z Hop again for pressure-based probes
|
|
|
|
if self.z_hop:
|
2020-08-17 05:43:03 +03:00
|
|
|
toolhead.manual_move([None, None, self.z_hop], self.z_hop_speed)
|
2019-09-18 16:37:33 +03:00
|
|
|
# Move XY back to previous positions
|
|
|
|
if self.move_to_previous:
|
2020-08-17 05:43:03 +03:00
|
|
|
toolhead.manual_move(prevpos[:2], self.speed)
|
2019-09-18 16:37:33 +03:00
|
|
|
|
2020-08-17 05:43:03 +03:00
|
|
|
def _perform_z_hop(self):
|
2019-09-18 16:37:33 +03:00
|
|
|
toolhead = self.printer.lookup_object('toolhead')
|
|
|
|
# Perform the Z-Hop
|
2020-08-17 05:43:03 +03:00
|
|
|
pos = toolhead.get_position()
|
2019-09-18 16:37:33 +03:00
|
|
|
toolhead.set_position(pos, homing_axes=[2])
|
2020-08-17 05:43:03 +03:00
|
|
|
toolhead.manual_move([None, None, pos[2]+self.z_hop], self.z_hop_speed)
|
2019-08-06 22:03:42 +03:00
|
|
|
|
|
|
|
def load_config(config):
|
|
|
|
return SafeZHoming(config)
|