From fbbbbc85cf6b717a48c9c62cd39a219af0223655 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 19 Feb 2020 11:38:11 -0500 Subject: [PATCH] homing: Replace notify callback with a completion Update the endstop code to return its trigger completion object during home_start(). Update the toolhead class to take a completion object (instead of creating its own). This reduces the number of intermediate callbacks needed during a homing operation. Signed-off-by: Kevin O'Connor --- klippy/extras/bltouch.py | 7 +++---- klippy/homing.py | 25 ++++++++++++++----------- klippy/mcu.py | 16 +++++++--------- klippy/toolhead.py | 6 ++---- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/klippy/extras/bltouch.py b/klippy/extras/bltouch.py index 03613f08..cf9146fc 100644 --- a/klippy/extras/bltouch.py +++ b/klippy/extras/bltouch.py @@ -174,11 +174,10 @@ class BLTouchEndstopWrapper: for s, mcu_pos in self.start_mcu_pos: if s.get_mcu_position() == mcu_pos: raise homing.EndstopError("BLTouch failed to deploy") - def home_start(self, print_time, sample_time, sample_count, rest_time, - notify=None): + def home_start(self, print_time, sample_time, sample_count, rest_time): rest_time = min(rest_time, ENDSTOP_REST_TIME) - self.mcu_endstop.home_start(print_time, sample_time, sample_count, - rest_time, notify=notify) + return self.mcu_endstop.home_start(print_time, sample_time, + sample_count, rest_time) def get_position_endstop(self): return self.position_endstop cmd_BLTOUCH_DEBUG_help = "Send a command to the bltouch for debugging" diff --git a/klippy/homing.py b/klippy/homing.py index ad698bc0..6415b115 100644 --- a/klippy/homing.py +++ b/klippy/homing.py @@ -15,7 +15,6 @@ class Homing: self.toolhead = printer.lookup_object('toolhead') self.changed_axes = [] self.verify_retract = True - self.endstops_pending = -1 def set_no_verify_retract(self): self.verify_retract = False def set_axes(self, axes): @@ -41,10 +40,6 @@ class Homing: / s.get_step_dist()) for s in mcu_endstop.get_steppers()]) return move_t / max_steps - def _endstop_notify(self): - self.endstops_pending -= 1 - if not self.endstops_pending: - self.toolhead.signal_drip_mode_end() def homing_move(self, movepos, endstops, speed, probe_pos=False, verify_movement=False): # Notify start of homing/probing move @@ -59,17 +54,18 @@ class Homing: for es, name in endstops for s in es.get_steppers()] # Start endstop checking print_time = self.toolhead.get_last_move_time() - self.endstops_pending = len(endstops) + endstop_triggers = [] for mcu_endstop, name in endstops: rest_time = self._calc_endstop_rate(mcu_endstop, movepos, speed) - mcu_endstop.home_start( - print_time, ENDSTOP_SAMPLE_TIME, ENDSTOP_SAMPLE_COUNT, - rest_time, notify=self._endstop_notify) + wait = mcu_endstop.home_start(print_time, ENDSTOP_SAMPLE_TIME, + ENDSTOP_SAMPLE_COUNT, rest_time) + endstop_triggers.append(wait) + all_endstop_trigger = multi_complete(self.printer, endstop_triggers) self.toolhead.dwell(HOMING_START_DELAY) # Issue move error = None try: - self.toolhead.drip_move(movepos, speed) + self.toolhead.drip_move(movepos, speed, all_endstop_trigger) except CommandError as e: error = "Error during homing move: %s" % (str(e),) # Wait for endstops to trigger @@ -110,7 +106,7 @@ class Homing: "Endstop %s still triggered after retract" % (name,)) def home_rails(self, rails, forcepos, movepos): # Notify of upcoming homing operation - ret = self.printer.send_event("homing:home_rails_begin", rails) + self.printer.send_event("homing:home_rails_begin", rails) # Alter kinematics class to think printer is at forcepos homing_axes = [axis for axis in range(3) if forcepos[axis] is not None] forcepos = self._fill_coord(forcepos) @@ -155,6 +151,13 @@ class Homing: self.printer.lookup_object('stepper_enable').motor_off() raise +# Return a completion that completes when all completions in a list complete +def multi_complete(printer, completions): + if len(completions) == 1: + return completions[0] + cb = (lambda e: all([c.wait() for c in completions])) + return printer.get_reactor().register_callback(cb) + class CommandError(Exception): pass diff --git a/klippy/mcu.py b/klippy/mcu.py index fafaab9c..6793fdff 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -25,7 +25,6 @@ class MCU_endstop: self._min_query_time = self._last_sent_time = 0. self._next_query_print_time = self._end_home_time = 0. self._trigger_completion = self._home_completion = None - self._trigger_notify = None def get_mcu(self): return self._mcu def add_stepper(self, stepper): @@ -55,16 +54,14 @@ class MCU_endstop: self._query_cmd = self._mcu.lookup_command( "endstop_query_state oid=%c", cq=cmd_queue) def home_start(self, print_time, sample_time, sample_count, rest_time, - triggered=True, notify=None): + triggered=True): clock = self._mcu.print_time_to_clock(print_time) rest_ticks = int(rest_time * self._mcu.get_adjusted_freq()) - self._trigger_notify = notify self._next_query_print_time = print_time + self.RETRY_QUERY self._min_query_time = self._reactor.monotonic() self._last_sent_time = 0. self._home_end_time = self._reactor.NEVER self._trigger_completion = self._reactor.completion() - self._home_completion = self._reactor.completion() self._mcu.register_response(self._handle_endstop_state, "endstop_state", self._oid) self._home_cmd.send( @@ -73,6 +70,7 @@ class MCU_endstop: reqclock=clock) self._home_completion = self._reactor.register_callback( self._home_retry) + return self._trigger_completion def _handle_endstop_state(self, params): logging.debug("endstop_state %s", params) if params['#sent_time'] >= self._min_query_time: @@ -80,16 +78,14 @@ class MCU_endstop: self._last_sent_time = params['#sent_time'] else: self._min_query_time = self._reactor.NEVER - self._reactor.async_complete(self._trigger_completion, params) + self._reactor.async_complete(self._trigger_completion, True) def _home_retry(self, eventtime): if self._mcu.is_fileoutput(): return True while 1: - params = self._trigger_completion.wait(eventtime + 0.100) - if params is not None: + did_trigger = self._trigger_completion.wait(eventtime + 0.100) + if did_trigger is not None: # Homing completed successfully - if self._trigger_notify is not None: - self._trigger_notify() return True # Check for timeout last = self._mcu.estimated_print_time(self._last_sent_time) @@ -108,6 +104,8 @@ class MCU_endstop: self._home_cmd.send([self._oid, 0, 0, 0, 0, 0]) for s in self._steppers: s.note_homing_end(did_trigger=did_trigger) + if not self._trigger_completion.test(): + self._trigger_completion.complete(False) if not did_trigger: raise self.TimeoutError("Timeout during endstop homing") def query_endstop(self, print_time): diff --git a/klippy/toolhead.py b/klippy/toolhead.py index 85e4be53..c7c9f35a 100644 --- a/klippy/toolhead.py +++ b/klippy/toolhead.py @@ -441,7 +441,7 @@ class ToolHead: continue npt = min(self.print_time + DRIP_SEGMENT_TIME, next_print_time) self._update_move_time(npt) - def drip_move(self, newpos, speed): + def drip_move(self, newpos, speed, drip_completion): # Transition from "Flushed"/"Priming"/main state to "Drip" state self.move_queue.flush() self.special_queuing_state = "Drip" @@ -449,7 +449,7 @@ class ToolHead: self.reactor.update_timer(self.flush_timer, self.reactor.NEVER) self.move_queue.set_flush_time(self.buffer_time_high) self.idle_flush_print_time = 0. - self.drip_completion = self.reactor.completion() + self.drip_completion = drip_completion # Submit move try: self.move(newpos, speed) @@ -464,8 +464,6 @@ class ToolHead: self.trapq_free_moves(self.trapq, self.reactor.NEVER) # Exit "Drip" state self.flush_step_generation() - def signal_drip_mode_end(self): - self.drip_completion.complete(True) # Misc commands def stats(self, eventtime): for m in self.all_mcus: