aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/toolhead.py
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2019-06-25 21:25:01 -0400
committerKevinOConnor <kevin@koconnor.net>2019-07-10 10:43:20 -0400
commit43064d197d6fd6bcc55217c5e9298d86bf4ecde7 (patch)
treed63636e8d5327affc605efd5e5c1c360ee040c7a /klippy/toolhead.py
parentd6cce8a55753965e9b00f9ee0caa328323380ced (diff)
downloadkutter-43064d197d6fd6bcc55217c5e9298d86bf4ecde7.tar.gz
kutter-43064d197d6fd6bcc55217c5e9298d86bf4ecde7.tar.xz
kutter-43064d197d6fd6bcc55217c5e9298d86bf4ecde7.zip
homing: Implement homing via new toolhead "drip" movement
Rework the low-level implementation of homing movement. The existing mechanism buffers all homing movement into the micro-controller prior to starting the home. Replace with a system that buffers all movement into the host look-ahead buffer and then "drip feed" those moves to the micro-controllers. Then clear the host look-ahead buffer when all endstops trigger. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy/toolhead.py')
-rw-r--r--klippy/toolhead.py66
1 files changed, 60 insertions, 6 deletions
diff --git a/klippy/toolhead.py b/klippy/toolhead.py
index 33eb0ad7..48754b61 100644
--- a/klippy/toolhead.py
+++ b/klippy/toolhead.py
@@ -194,6 +194,11 @@ class MoveQueue:
STALL_TIME = 0.100
+DRIP_SEGMENT_TIME = 0.050
+DRIP_TIME = 0.150
+class DripModeEndSignal(Exception):
+ pass
+
# Main code to track events (and their timing) on the printer toolhead
class ToolHead:
def __init__(self, config):
@@ -238,6 +243,7 @@ class ToolHead:
self.last_print_start_time = 0.
self.idle_flush_print_time = 0.
self.print_stall = 0
+ self.drip_completion = None
# Setup iterative solver
ffi_main, ffi_lib = chelper.get_ffi()
self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free)
@@ -282,12 +288,24 @@ class ToolHead:
self.printer.send_event("toolhead:sync_print_time",
curtime, est_print_time, self.print_time)
def get_next_move_time(self):
- if self.special_queuing_state:
- # Transition from "Flushed"/"Priming" state to main state
- self.special_queuing_state = ""
- self.need_check_stall = -1.
- self.reactor.update_timer(self.flush_timer, self.reactor.NOW)
- self._calc_print_time()
+ if not self.special_queuing_state:
+ return self.print_time
+ if self.special_queuing_state == "Drip":
+ # In "Drip" state - wait until ready to send next move
+ while 1:
+ if self.drip_completion.test():
+ raise DripModeEndSignal()
+ curtime = self.reactor.monotonic()
+ est_print_time = self.mcu.estimated_print_time(curtime)
+ wait_time = self.print_time - est_print_time - DRIP_TIME
+ if wait_time <= 0. or self.mcu.is_fileoutput():
+ return self.print_time
+ self.drip_completion.wait(curtime + wait_time)
+ # Transition from "Flushed"/"Priming" state to main state
+ self.special_queuing_state = ""
+ self.need_check_stall = -1.
+ self.reactor.update_timer(self.flush_timer, self.reactor.NOW)
+ self._calc_print_time()
return self.print_time
def _full_flush(self):
# Transition from "Flushed"/"Priming"/main state to "Flushed" state
@@ -405,6 +423,42 @@ class ToolHead:
self.commanded_pos[3] = extrude_pos
def get_extruder(self):
return self.extruder
+ def drip_move(self, newpos, speed):
+ # Validate move
+ move = Move(self, self.commanded_pos, newpos, speed)
+ if move.axes_d[3]:
+ raise homing.CommandError("Invalid drip move")
+ if not move.move_d or not move.is_kinematic_move:
+ return
+ self.kin.check_move(move)
+ speed = math.sqrt(move.max_cruise_v2)
+ # Transition to "Flushed" state and then to "Drip" state
+ self._full_flush()
+ self.special_queuing_state = "Drip"
+ self.need_check_stall = self.reactor.NEVER
+ self.reactor.update_timer(self.flush_timer, self.reactor.NEVER)
+ self.move_queue.set_flush_time(self.reactor.NEVER)
+ self.drip_completion = self.reactor.completion()
+ # Split move into many tiny moves and queue them
+ num_moves = max(1, int(math.ceil(move.min_move_t / DRIP_SEGMENT_TIME)))
+ inv_num_moves = 1. / float(num_moves)
+ submove_d = [d * inv_num_moves for d in move.axes_d]
+ prev_pos = move.start_pos
+ for i in range(num_moves-1):
+ next_pos = [p + d for p, d in zip(prev_pos, submove_d)]
+ self.move_queue.add_move(Move(self, prev_pos, next_pos, speed))
+ prev_pos = next_pos
+ self.move_queue.add_move(Move(self, prev_pos, move.end_pos, speed))
+ # Transmit moves
+ self._calc_print_time()
+ try:
+ self.move_queue.flush()
+ except DripModeEndSignal as e:
+ self.move_queue.reset()
+ # Return to "Flushed" state
+ self._full_flush()
+ def signal_drip_mode_end(self):
+ self.drip_completion.complete(True)
# Misc commands
def stats(self, eventtime):
for m in self.all_mcus: