Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
TitusLabs committed Apr 25, 2023
2 parents b856115 + 97a62ae commit 73d62dc
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 48 deletions.
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ always be perfect - no matter which nozzle or new flex-plate is being tested.

## Documentation

Visit the [Wiki](https://github.com/protoloft/klipper_z_calibration/wiki) to view the full documentation.
Visit the [Wiki](https://github.com/protoloft/klipper_z_calibration/wiki) to view the full documentation for this Klipper plugin.

The latest release notes are [here](https://github.com/protoloft/klipper_z_calibration/wiki/Changelog).

Expand All @@ -36,7 +36,7 @@ The latest release notes are [here](https://github.com/protoloft/klipper_z_calib

A great how-to video by Kapman: [https://youtu.be/oQYHFecsTto](https://youtu.be/oQYHFecsTto)

##### And if you are looking for an RRF version of this automatic z-offset calibration
### And if you are looking for an RRF version of this automatic z-offset calibration

You can find one [here](https://github.com/pRINTERnOODLE/Auto-Z-calibration-for-RRF-3.3-or-later-and-Klicky-Probe) from pRINTERnOODLE - This is really fantastic to see :tada:

Expand All @@ -46,10 +46,6 @@ And if you like my work and want to support me, you can do so here:

[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/X8X1C0DTD)

## A Quick Demonstration

<div style="width: 100%; height: 0px; position: relative; padding-bottom: 56.250%;"><iframe src="https://streamable.com/e/wclrmc" frameborder="0" width="100%" height="100%" allowfullscreen style="width: 100%; height: 100%; position: absolute;"></iframe></div>

## Disclaimer

You use it at your onw risk! I'm not responsible for any damage that might result. Although,
Expand Down
54 changes: 43 additions & 11 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,52 @@ KLIPPER_PATH="${HOME}/klipper"
SYSTEMDDIR="/etc/systemd/system"
MOONRAKER_CONFIG="${HOME}/printer_data/config/moonraker.conf"
MOONRAKER_FALLBACK="${HOME}/klipper_config/moonraker.conf"
NUM_INSTALLS=0

# Force script to exit if an error occurs
set -e

# Step 1: Check for root user
verify_ready()
{
# check for root user
if [ "$EUID" -eq 0 ]; then
echo "This script must not run as root"
exit -1
fi
# output used number of installs
if [[ $NUM_INSTALLS == 0 ]]; then
echo "Defaulted to one klipper install, if more than one instance, use -n"
else
echo "Number of Installs Selected: $NUM_INSTALLS"
fi
# Fall back to old config
if [ ! -f "$MOONRAKER_CONFIG" ]; then
echo "${MOONRAKER_CONFIG} does not exist. Falling back to ${MOONRAKER_FALLBACK}"
MOONRAKER_CONFIG="$MOONRAKER_FALLBACK"
fi
}

# Step 2: Verify Klipper has been installed
check_klipper()
{
if [ "$(sudo systemctl list-units --full -all -t service --no-legend | grep -F "klipper.service")" ]; then
echo "Klipper service found!"
if [[ $NUM_INSTALLS == 0 ]]; then
if [ "$(sudo systemctl list-units --full -all -t service --no-legend | grep -F "klipper.service")" ]; then
echo "Klipper service found!"
else
echo "Klipper service not found, please install Klipper first"
exit -1
fi
else
echo "Klipper service not found, please install Klipper first"
exit -1
fi

for (( klip = 1; klip<=$NUM_INSTALLS; klip++ )); do
if [ "$(sudo systemctl list-units --full -all -t service --no-legend | grep -F "klipper-$klip.service")" ]; then
echo "klipper-$klip.service found!"
else
echo "klipper-$klip.service NOT found, please ensure you've entered the correct number of klipper instances you're running!"
exit -1
fi
done
fi
}

# Step 3: Check folders
Expand Down Expand Up @@ -100,9 +123,17 @@ add_updater()
# Step 7: Restarting Klipper
restart_klipper()
{
echo -n "Restarting Klipper... "
sudo systemctl restart klipper
echo "[OK]"
if [[ $NUM_INSTALLS == 0 ]]; then
echo -n "Restarting Klipper... "
sudo systemctl restart klipper
echo "[OK]"
else
for (( klip = 1; klip<=$NUM_INSTALLS; klip++)); do
echo -n "Restarting Klipper-$klip... "
sudo systemctl restart klipper-$klip
echo "[OK]"
done
fi
}

uinstall()
Expand All @@ -122,15 +153,16 @@ uinstall()

usage()
{
echo "Usage: $(basename $0) [-k <Klipper path>] [-m <Moonraker config file>] [-u]" 1>&2;
echo "Usage: $(basename $0) [-k <Klipper path>] [-m <Moonraker config file>] [-n <number klipper instances>] [-u]" 1>&2;
exit 1;
}

# Command parsing
while getopts ":k:m:uh" OPTION; do
while getopts ":k:m:n:uh" OPTION; do
case "$OPTION" in
k) KLIPPER_PATH="$OPTARG" ;;
m) MOONRAKER_CONFIG="$OPTARG" ;;
n) NUM_INSTALLS="$OPTARG" ;;
u) UNINSTALL=1 ;;
h | ?) usage ;;
esac
Expand Down
104 changes: 73 additions & 31 deletions z_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ def __init__(self, config):
self.config = config
self.printer = config.get_printer()
self.switch_offset = config.getfloat('switch_offset', 0.0, above=0.)
# max_deviation is deprecated
self.max_deviation = config.getfloat('max_deviation', 1.0, above=0.)
self.offset_margins = self._get_offset_margins('offset_margins',
'-1.0,1.0')
self.speed = config.getfloat('speed', 50.0, above=0.)
# clearance is deprecated
self.clearance = config.getfloat('clearance', None, above=0.)
self.safe_z_height = config.getfloat('safe_z_height', None, above=0.)
self.samples = config.getint('samples', None, minval=1)
self.tolerance = config.getfloat('samples_tolerance', None, above=0.)
self.retries = config.getint('samples_tolerance_retries',
Expand Down Expand Up @@ -107,10 +112,13 @@ def handle_connect(self):
self.retries = probe.samples_retries
if self.lift_speed is None:
self.lift_speed = probe.lift_speed
if self.clearance is None:
self.clearance = probe.z_offset * 2
if self.clearance < 3:
# clearance is deprecated
if self.clearance is not None and self.clearance == 0:
self.clearance = 20 # defaults to 20mm
if self.safe_z_height is None:
self.safe_z_height = probe.z_offset * 2
if self.safe_z_height < 3:
self.safe_z_height = 20 # defaults to 20mm
if self.samples_result is None:
self.samples_result = probe.samples_result
def handle_home_rails_end(self, homing_state, rails):
Expand Down Expand Up @@ -171,9 +179,7 @@ def cmd_PROBE_Z_ACCURACY(self, gcmd):
self.retract_dist, above=0.)
toolhead = self.printer.lookup_object('toolhead')
pos = toolhead.get_position()
if pos[2] < self.clearance:
# no clearance, better to move up
self._move([None, None, pos[2] + self.clearance], lift_speed)
self._move_safe_z(pos, lift_speed)
# move to z-endstop position
self._move(list(self.nozzle_site), self.speed)
pos = toolhead.get_position()
Expand Down Expand Up @@ -237,6 +243,19 @@ def _parse_xy(self, name, site):
except:
raise self.config.error("Unable to parse %s in %s"
% (name, self.config.get_name()))
def _get_offset_margins(self, name, default):
try:
margins = self.config.get(name, default).split(',')
for i, val in enumerate(margins):
margins[i] = float(val)
if len(margins) == 1:
val = abs(margins[0])
margins[0] = -val
margins[1] = val
return margins
except:
raise self.config.error("Unable to parse %s in %s"
% (name, self.config.get_name()))
def _probe(self, mcu_endstop, z_position, speed, wiggle=False):
toolhead = self.printer.lookup_object('toolhead')
pos = toolhead.get_position()
Expand All @@ -258,6 +277,16 @@ def _probe(self, mcu_endstop, z_position, speed, wiggle=False):
return curpos
def _move(self, coord, speed):
self.printer.lookup_object('toolhead').manual_move(coord, speed)
def _move_safe_z(self, pos, lift_speed):
# clearance is deprecated
if self.clearance is not None:
if pos[2] < self.clearance:
# no clearance, better to move up (relative)
self._move([None, None, pos[2] + self.clearance], lift_speed)
else:
if pos[2] < self.safe_z_height:
# no safe z position, better to move up (absolute)
self._move([None, None, self.safe_z_height], lift_speed)
def _calc_mean(self, positions):
count = float(len(positions))
return [sum([pos[i] for pos in positions]) / count
Expand All @@ -271,22 +300,26 @@ def _calc_median(self, positions):
# even number of samples
return self._calc_mean(z_sorted[middle-1:middle+1])
def _log_config(self):
logging.debug("Z-CALIBRATION: switch_offset=%.3f, max_deviation=%.3f,"
" speed=%.3f, samples=%i, tolerance=%.3f, retries=%i,"
" samples_result=%s, lift_speed=%.3f, clearance=%.3f,"
" probing_speed=%.3f, second_speed=%.3f,"
" retract_dist=%.3f, position_min=%.3f,"
" probe_nozzle_x=%.3f, probe_nozzle_y=%.3f,"
" probe_switch_x=%.3f, probe_switch_y=%.3f,"
" probe_bed_x=%.3f, probe_bed_y=%.3f"
% (self.switch_offset, self.max_deviation, self.speed,
logging.debug("Z-CALIBRATION: switch_offset=%.3f,"
" offset_margins=%.3f,%.3f, speed=%.3f,"
" samples=%i, tolerance=%.3f, retries=%i,"
" samples_result=%s, lift_speed=%.3f,"
" safe_z_height=%.3f, probing_speed=%.3f,"
" second_speed=%.3f, retract_dist=%.3f,"
" position_min=%.3f, probe_nozzle_x=%.3f,"
" probe_nozzle_y=%.3f, probe_switch_x=%.3f,"
" probe_switch_y=%.3f, probe_bed_x=%.3f,"
" probe_bed_y=%.3f"
% (self.switch_offset, self.offset_margins[0],
self.offset_margins[1], self.speed,
self.samples, self.tolerance, self.retries,
self.samples_result, self.lift_speed, self.clearance,
self.probing_speed, self.second_speed,
self.retract_dist, self.position_min,
self.nozzle_site[0], self.nozzle_site[1],
self.switch_site[0], self.switch_site[1],
self.bed_site[0], self.bed_site[1]))
self.samples_result, self.lift_speed,
self.safe_z_height, self.probing_speed,
self.second_speed, self.retract_dist,
self.position_min, self.nozzle_site[0],
self.nozzle_site[1], self.switch_site[0],
self.switch_site[1], self.bed_site[0],
self.bed_site[1]))
class EndstopWrapper:
def __init__(self, config, endstop):
self.mcu_endstop = endstop
Expand All @@ -306,13 +339,12 @@ def __init__(self, helper, gcmd):
self.probe = helper.printer.lookup_object('probe')
self.toolhead = helper.printer.lookup_object('toolhead')
self.gcode_move = helper.printer.lookup_object('gcode_move')
self.max_deviation = helper.max_deviation
self.offset_margins = helper.offset_margins
def _probe_on_site(self, endstop, site, check_probe=False, split_xy=False,
wiggle=False):
pos = self.toolhead.get_position()
if pos[2] < self.helper.clearance:
# no clearance, better to move up
self.helper._move([None, None, pos[2] + self.helper.clearance],
self.helper.lift_speed)
self.helper._move_safe_z(pos, self.helper.lift_speed)
# move to position
if split_xy:
self.helper._move([site[0], pos[1], None], self.helper.speed)
Expand Down Expand Up @@ -399,18 +431,28 @@ def calibrate_z(self):
" new offset=%.6f"
% (probe_zero, switch_zero, nozzle_zero,
self.helper.switch_offset, offset))
self.gcmd.respond_info("Z-CALIBRATION: position_endstop=%.3f -"
" offset=%.6f --> new z position_endstop=%.3f"
self.gcmd.respond_info("HINT: z position_endstop=%.3f - offset=%.6f"
" --> possible z position_endstop=%.3f"
% (self.helper.position_z_endstop, offset,
self.helper.position_z_endstop - offset))
# check max deviation
if abs(offset) > self.helper.max_deviation:
# check offset margins
if (self.max_deviation is not None # deprecated
and abs(offset) > self.max_deviation):
self.helper.end_gcode.run_gcode_from_command()
raise self.helper.printer.command_error("Offset is larger as"
raise self.helper.printer.command_error("Offset is greater than"
" allowed: offset=%.3f"
" > max_deviation=%.3f"
% (offset,
self.helper.max_deviation))
self.max_deviation))
elif (offset < self.offset_margins[0]
or offset > self.offset_margins[1]):
self.helper.end_gcode.run_gcode_from_command()
raise self.helper.printer.command_error("Offset %.3f is outside"
" the configured range of"
" min=%.3f and max=%.3f"
% (offset,
self.offset_margins[0],
self.offset_margins[1]))
# set new offset
self._set_new_gcode_offset(offset)
# set states
Expand Down

0 comments on commit 73d62dc

Please sign in to comment.