diff --git a/config/example.cfg b/config/example.cfg index 75684d16..98d1c0d1 100644 --- a/config/example.cfg +++ b/config/example.cfg @@ -115,6 +115,16 @@ nozzle_diameter: 0.500 filament_diameter: 3.500 # Diameter of the raw filament (in mm) as it enters the # extruder. This parameter must be provided. +#max_extrude_cross_section: +# Maximum area of the cross section of an extrusion line (in +# mm^2). If a move requests an extrusion rate that would exceed this +# value it will cause an error to be returned. The default is: 4.0 * +# nozzle_diameter^2 +#max_extrude_only_distance: 50.0 +# Maximum length (in mm of raw filament) that an extrude only move +# may be. If an extrude only move requests a distance greater than +# this value it will cause an error to be returned. The default is +# 50mm. max_velocity: 200000 # Maximum velocity (in mm/s) of the extruder motor for extrude only # moves. This parameter must be provided. diff --git a/docs/Todo.md b/docs/Todo.md index 71c68c3f..e16196e1 100644 --- a/docs/Todo.md +++ b/docs/Todo.md @@ -58,10 +58,6 @@ Safety features can be useful to detect a sensor failure (eg, thermistor short) that could otherwise cause the PID to command excessive heating. -* Possibly implement host based checking on the ratio between extrude - amount and head movement. - * Enforce acceleration and speed limits on extruder stepper motor. - Testing features ================ diff --git a/klippy/extruder.py b/klippy/extruder.py index 23ed7f54..9e3d8143 100644 --- a/klippy/extruder.py +++ b/klippy/extruder.py @@ -3,7 +3,7 @@ # Copyright (C) 2016 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. -import logging +import math, logging import stepper, heater, homing class PrinterExtruder: @@ -12,6 +12,11 @@ class PrinterExtruder: self.stepper = stepper.PrinterStepper(printer, config, 'extruder') nozzle_diameter = config.getfloat('nozzle_diameter') filament_diameter = config.getfloat('filament_diameter') + filament_area = math.pi * (filament_diameter * .5)**2 + max_cross_section = config.getfloat( + 'max_extrude_cross_section', 4. * nozzle_diameter**2) + self.max_extrude_ratio = max_cross_section / filament_area + self.max_e_dist = config.getfloat('max_extrude_only_distance', 50.) self.max_e_velocity = config.getfloat('max_velocity') self.max_e_accel = config.getfloat('max_accel') self.pressure_advance = config.getfloat('pressure_advance', 0.) @@ -30,7 +35,14 @@ class PrinterExtruder: move.end_pos, "Extrude below minimum temp") if not move.is_kinematic_move: # Extrude only move - limit accel and velocity + if move.axes_d[3] > self.max_e_dist: + raise homing.EndstopMoveError( + move.end_pos, "Extrude only move too long") move.limit_speed(self.max_e_velocity, self.max_e_accel) + elif move.extrude_r > self.max_extrude_ratio: + logging.debug("%s vs %s" % (move.extrude_r, self.max_extrude_ratio)) + raise homing.EndstopMoveError( + move.end_pos, "Move exceeds maximum extrusion cross section") def move(self, move_time, move): if self.need_motor_enable: self.stepper.motor_enable(move_time, 1)