From 850cf9e034e8f740ffdb34287da9f7b6d7073aba Mon Sep 17 00:00:00 2001 From: jupfi Date: Sun, 10 Dec 2023 18:15:35 +0100 Subject: [PATCH] Backlash correction for tuner. --- src/nqrduck_autotm/controller.py | 30 ++++++++++++++++++++++++++++++ src/nqrduck_autotm/model.py | 10 ++++++++++ src/nqrduck_autotm/view.py | 13 +++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/nqrduck_autotm/controller.py b/src/nqrduck_autotm/controller.py index 4b3c6c6..14e80a0 100644 --- a/src/nqrduck_autotm/controller.py +++ b/src/nqrduck_autotm/controller.py @@ -619,6 +619,7 @@ class AutoTMController(ModuleController): """ logger.debug("Homing") self.send_command("h") + self.module.model.tuning_stepper.last_direction = 1 @pyqtSlot(str) def on_stepper_changed(self, stepper: str) -> None: @@ -654,6 +655,18 @@ class AutoTMController(ModuleController): def send_stepper_command(self, steps: int, stepper : Stepper) -> None: """Send a command to the stepper motor based on the number of steps.""" + # Here we handle backlash of the tuner + # Determine the direction of the current steps + current_direction = np.sign(steps) # This will be -1,or 1 + if stepper.TYPE == "Tuning": + logger.debug("Stepper last direction: %s", stepper.last_direction) + logger.debug("Current direction: %s", current_direction) + if stepper.last_direction != current_direction: + steps = (abs(steps) + stepper.BACKLASH_STEPS) * current_direction + + stepper.last_direction = current_direction + logger.debug("Stepper last direction: %s", stepper.last_direction) + motor_identifier = stepper.TYPE.lower()[0] command = f"m{motor_identifier}{steps}" confirmation = self.send_command(command) @@ -738,5 +751,22 @@ class AutoTMController(ModuleController): logger.debug("Deleting position: %s", position) self.module.model.delete_saved_position(position) + def generate_mech_lut(self, start_frequency: str, stop_frequency: str, frequency_step: str) -> None: + """Generate a lookup table for the specified frequency range and voltage resolution. + + Args: + start_frequency (str): The start frequency in Hz. + stop_frequency (str): The stop frequency in Hz. + frequency_step (str): The frequency step in Hz. + """ + logger.debug("Generating mech LUT") + + # We create the lookup table + LUT = MechanicalLookupTable( + start_frequency, stop_frequency, frequency_step + ) + + + diff --git a/src/nqrduck_autotm/model.py b/src/nqrduck_autotm/model.py index fa590d5..10bc75a 100644 --- a/src/nqrduck_autotm/model.py +++ b/src/nqrduck_autotm/model.py @@ -240,7 +240,13 @@ class SavedPosition(): class TuningStepper(Stepper): TYPE = "Tuning" MAX_STEPS = 1e6 + BACKLASH_STEPS = 45 + def __init__(self) -> None: + super().__init__() + # Backlash stepper + self.last_direction = None + class MatchingStepper(Stepper): TYPE = "Matching" MAX_STEPS = 1e6 @@ -285,6 +291,7 @@ class MechanicalLookupTable(LookupTable): TYPE = "Mechanical" pass class AutoTMModel(ModuleModel): + available_devices_changed = pyqtSignal(list) serial_changed = pyqtSignal(QSerialPort) data_points_changed = pyqtSignal(list) @@ -309,6 +316,9 @@ class AutoTMModel(ModuleModel): self.saved_positions = [] + self.el_lut = None + self.mech_lut = None + @property def available_devices(self): return self._available_devices diff --git a/src/nqrduck_autotm/view.py b/src/nqrduck_autotm/view.py index bcdcf3f..2d5ad33 100644 --- a/src/nqrduck_autotm/view.py +++ b/src/nqrduck_autotm/view.py @@ -73,6 +73,15 @@ class AutoTMView(ModuleView): ) ) + # On clicking of the generateLUTButton call the generate_lut method + self._ui_form.generateLUTButton.clicked.connect( + lambda: self.module.controller.generate_mech_lut( + self._ui_form.startfrequencyBox.text(), + self._ui_form.stopfrequencyBox.text(), + self._ui_form.frequencystepBox.text(), + ) + ) + # On clicking of the viewLUTButton call the view_lut method self._ui_form.viewelLUTButton.clicked.connect(self.view_el_lut) @@ -351,6 +360,10 @@ class AutoTMView(ModuleView): def view_el_lut(self) -> None: """Creates a new Dialog that shows the currently active electrical LUT.""" logger.debug("View LUT") + if self.module.model.el_lut is None: + logger.debug("No LUT available") + self.add_error_text("No LUT available") + return self.lut_window = self.LutWindow(self.module) self.lut_window.show()