From dae3a87fae4881f5efdae62f5c1a965e0f29deff Mon Sep 17 00:00:00 2001 From: Michael Fritsche Date: Fri, 19 Jun 2026 13:01:02 +0200 Subject: [PATCH 1/2] feat: add gimbal autotune preset --- autotune/data_selection_window.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/autotune/data_selection_window.py b/autotune/data_selection_window.py index 6dec9d8..48b933a 100644 --- a/autotune/data_selection_window.py +++ b/autotune/data_selection_window.py @@ -67,6 +67,30 @@ def __init__(self, filename): "input": "vehicle_rates_setpoint/yaw.0", "output": "vehicle_angular_velocity/xyz[2].0", }, + "GimbalRollRate": { + "input": "motor_state/roll.effort_cmd.0", + "output": "motor_angular_rates/roll.angular_rate.0", + }, + "GimbalPitchRate": { + "input": "motor_state/pitch.effort_cmd.0", + "output": "motor_angular_rates/pitch.angular_rate.0", + }, + "GimbalYawRate": { + "input": "motor_state/yaw.effort_cmd.0", + "output": "motor_angular_rates/yaw.angular_rate.0", + }, + "GimbalRollAtt": { + "input": "motor_control/motor_commands.roll.angular_rate_setpoint.0", + "output": "attitude_info/roll.0", + }, + "GimbalPitchAtt": { + "input": "motor_control/motor_commands.pitch.angular_rate_setpoint.0", + "output": "attitude_info/pitch.0", + }, + "GimbalYawAtt": { + "input": "motor_control/motor_commands.yaw.angular_rate_setpoint.0", + "output": "attitude_info/yaw.0", + }, } self.presets = {} From 3040c5064f61a161d2bdd0f9be627061a88a87be Mon Sep 17 00:00:00 2001 From: Michael Fritsche Date: Fri, 19 Jun 2026 13:07:38 +0200 Subject: [PATCH 2/2] fix(autotune): don't crash if no preset fits --- autotune/data_selection_window.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/autotune/data_selection_window.py b/autotune/data_selection_window.py index 48b933a..060cb74 100644 --- a/autotune/data_selection_window.py +++ b/autotune/data_selection_window.py @@ -192,10 +192,12 @@ def openFile(self): self.combo_y.clear() self.combo_y.addItems(list_names) - # Trigger preset selection + # Trigger preset selection. If no preset matches the available + # topics, leave the input/output combos for manual configuration. self.fillPresets() - self.combo_preset.setCurrentIndex(0) - self.selectPreset(0) + if self.presets: + self.combo_preset.setCurrentIndex(0) + self.selectPreset(0) def fillPresets(self): self.combo_preset.clear() @@ -218,7 +220,10 @@ def printRangeError(self): msg.exec_() def selectPreset(self, index): - preset_key = list(self.presets.keys())[index] + preset_keys = list(self.presets.keys()) + if index < 0 or index >= len(preset_keys): + return + preset_key = preset_keys[index] preset = self.presets[preset_key] (index_u, index_y) = self.findInputOutputIndex(preset)