diff --git a/docs/macros/axes_shaper_calibrations.md b/docs/macros/axes_shaper_calibrations.md index 5219c6a..a502abe 100644 --- a/docs/macros/axes_shaper_calibrations.md +++ b/docs/macros/axes_shaper_calibrations.md @@ -20,6 +20,8 @@ Then, call the `AXES_SHAPER_CALIBRATION` macro and look for the graphs in the re |MAX_SMOOTHING|None|max smoothing allowed when calculating shaper recommendations| |TRAVEL_SPEED|120|speed in mm/s used for all the travel movements (to go to the start position prior to the test)| |Z_HEIGHT|None|Z height wanted for the test. This value can be used if needed to override the Z value of the probe_point set in your `[resonance_tester]` config section| +|MAX_SCALE|None|Maximum energy value to scale the input shaper graph. Useful for comparing multiple consecutive tests by forcing the same energy scale| + > **Note** > diff --git a/docs/macros/compare_belts_responses.md b/docs/macros/compare_belts_responses.md index 04457bb..4093f59 100644 --- a/docs/macros/compare_belts_responses.md +++ b/docs/macros/compare_belts_responses.md @@ -21,6 +21,7 @@ Then, call the `COMPARE_BELTS_RESPONSES` macro and look for the graphs in the re |ACCEL_PER_HZ|None (default to `[resonance_tester]` value)|accel per Hz value used for the test| |TRAVEL_SPEED|120|speed in mm/s used for all the travel movements (to go to the start position prior to the test)| |Z_HEIGHT|None|Z height wanted for the test. This value can be used if needed to override the Z value of the probe_point set in your `[resonance_tester]` config section| +|MAX_SCALE|None|Maximum energy value to scale the belts graph. Useful for comparing multiple consecutive tests by forcing the same energy scale| > **Note** > diff --git a/shaketune/cli.py b/shaketune/cli.py index 345d287..f133ffa 100644 --- a/shaketune/cli.py +++ b/shaketune/cli.py @@ -28,9 +28,14 @@ def configure_graph_creator(graph_type, args, dummy_config): elif graph_type == 'static frequency': config_kwargs |= {'accel_per_hz': args.accel_per_hz, 'freq': args.frequency, 'duration': args.duration} elif graph_type == 'belts comparison': - config_kwargs |= {'kinematics': args.kinematics, 'accel_per_hz': args.accel_per_hz} + config_kwargs |= {'kinematics': args.kinematics, 'accel_per_hz': args.accel_per_hz, 'max_scale': args.max_scale} elif graph_type == 'input shaper': - config_kwargs |= {'scv': args.scv, 'max_smoothing': args.max_smoothing, 'accel_per_hz': args.accel_per_hz} + config_kwargs |= { + 'scv': args.scv, + 'max_smoothing': args.max_smoothing, + 'accel_per_hz': args.accel_per_hz, + 'max_scale': args.max_scale, + } elif graph_type == 'vibrations profile': config_kwargs |= {'kinematics': args.kinematics, 'accel': args.accel} @@ -70,6 +75,9 @@ def main(): belts_parser.add_argument('-k', '--klipper_dir', default='~/klipper', help='Main klipper directory') belts_parser.add_argument('--kinematics', help='Machine kinematics configuration') belts_parser.add_argument('--accel_per_hz', type=float, help='Accel per Hz used during the measurement') + belts_parser.add_argument( + '--max_scale', type=lambda x: int(float(x)), help='Maximum energy value to scale the belts graph' + ) # Input Shaper graph parser shaper_parser = subparsers.add_parser('input_shaper', help='Create input shaper graph') @@ -78,6 +86,9 @@ def main(): shaper_parser.add_argument('--scv', type=float, default=5.0, help='Square corner velocity') shaper_parser.add_argument('--max_smoothing', type=float, help='Maximum shaper smoothing to allow') shaper_parser.add_argument('--accel_per_hz', type=float, help='Accel per Hz used during the measurement') + shaper_parser.add_argument( + '--max_scale', type=lambda x: int(float(x)), help='Maximum energy value to scale the input shaper graph' + ) # Vibrations graph parser vibrations_parser = subparsers.add_parser('vibrations', help='Create vibrations profile graph') diff --git a/shaketune/commands/axes_shaper_calibration.py b/shaketune/commands/axes_shaper_calibration.py index 5931a24..9c28ca1 100644 --- a/shaketune/commands/axes_shaper_calibration.py +++ b/shaketune/commands/axes_shaper_calibration.py @@ -38,6 +38,7 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: max_sm = gcmd.get_float('MAX_SMOOTHING', default=None, minval=0) feedrate_travel = gcmd.get_float('TRAVEL_SPEED', default=120.0, minval=20.0) z_height = gcmd.get_float('Z_HEIGHT', default=None, minval=1) + max_scale = gcmd.get_int('MAX_SCALE', default=None, minval=1) if accel_per_hz == '': accel_per_hz = None @@ -74,7 +75,7 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: # Configure the graph creator creator = st_process.get_graph_creator() - creator.configure(scv, max_sm, accel_per_hz) + creator.configure(scv, max_sm, accel_per_hz, max_scale) # set the needed acceleration values for the test toolhead_info = toolhead.get_status(systime) diff --git a/shaketune/commands/compare_belts_responses.py b/shaketune/commands/compare_belts_responses.py index 29dd277..318f492 100644 --- a/shaketune/commands/compare_belts_responses.py +++ b/shaketune/commands/compare_belts_responses.py @@ -33,6 +33,7 @@ def compare_belts_responses(gcmd, config, st_process: ShakeTuneProcess) -> None: accel_per_hz = gcmd.get_float('ACCEL_PER_HZ', default=None) feedrate_travel = gcmd.get_float('TRAVEL_SPEED', default=120.0, minval=20.0) z_height = gcmd.get_float('Z_HEIGHT', default=None, minval=1) + max_scale = gcmd.get_int('MAX_SCALE', default=None, minval=1) if accel_per_hz == '': accel_per_hz = None @@ -47,7 +48,7 @@ def compare_belts_responses(gcmd, config, st_process: ShakeTuneProcess) -> None: # Configure the graph creator motors_config_parser = MotorsConfigParser(config, motors=None) creator = st_process.get_graph_creator() - creator.configure(motors_config_parser.kinematics, accel_per_hz) + creator.configure(motors_config_parser.kinematics, accel_per_hz, max_scale) if motors_config_parser.kinematics in {'corexy', 'limited_corexy'}: filtered_config = [a for a in AXIS_CONFIG if a['axis'] in ('a', 'b')] diff --git a/shaketune/dummy_macros.cfg b/shaketune/dummy_macros.cfg index 8a9f4c9..b58f3c3 100644 --- a/shaketune/dummy_macros.cfg +++ b/shaketune/dummy_macros.cfg @@ -51,6 +51,7 @@ gcode: {% set accel_per_hz = params.ACCEL_PER_HZ %} {% set travel_speed = params.TRAVEL_SPEED|default(120) %} {% set z_height = params.Z_HEIGHT %} + {% set max_scale = params.MAX_SCALE %} {% set params_filtered = { "FREQ_START": freq_start if freq_start is not none else '', "FREQ_END": freq_end if freq_end is not none else '', @@ -58,6 +59,7 @@ gcode: "ACCEL_PER_HZ": accel_per_hz if accel_per_hz is not none else '', "TRAVEL_SPEED": travel_speed, "Z_HEIGHT": z_height if z_height is not none else '' + "MAX_SCALE": max_scale if max_scale is not none else '' } %} _COMPARE_BELTS_RESPONSES {% for key, value in params_filtered.items() if value is defined and value is not none and value != '' %}{key}={value} {% endfor %} @@ -74,6 +76,7 @@ gcode: {% set max_smoothing = params.MAX_SMOOTHING %} {% set travel_speed = params.TRAVEL_SPEED|default(120) %} {% set z_height = params.Z_HEIGHT %} + {% set max_scale = params.MAX_SCALE %} {% set params_filtered = { "FREQ_START": freq_start if freq_start is not none else '', "FREQ_END": freq_end if freq_end is not none else '', @@ -84,6 +87,7 @@ gcode: "MAX_SMOOTHING": max_smoothing if max_smoothing is not none else '', "TRAVEL_SPEED": travel_speed, "Z_HEIGHT": z_height if z_height is not none else '' + "MAX_SCALE": max_scale if max_scale is not none else '' } %} _AXES_SHAPER_CALIBRATION {% for key, value in params_filtered.items() if value is defined and value is not none and value != '' %}{key}={value} {% endfor %} diff --git a/shaketune/graph_creators/belts_graph_creator.py b/shaketune/graph_creators/belts_graph_creator.py index 52d6b61..68d1e3d 100644 --- a/shaketune/graph_creators/belts_graph_creator.py +++ b/shaketune/graph_creators/belts_graph_creator.py @@ -28,9 +28,12 @@ def __init__(self, config: ShakeTuneConfig): self._kinematics: Optional[str] = None self._accel_per_hz: Optional[float] = None - def configure(self, kinematics: Optional[str] = None, accel_per_hz: Optional[float] = None) -> None: + def configure( + self, kinematics: Optional[str] = None, accel_per_hz: Optional[float] = None, max_scale: Optional[int] = None + ) -> None: self._kinematics = kinematics self._accel_per_hz = accel_per_hz + self._max_scale = max_scale def create_graph(self, measurements_manager: MeasurementsManager) -> None: computer = BeltsGraphComputation( @@ -38,6 +41,7 @@ def create_graph(self, measurements_manager: MeasurementsManager) -> None: kinematics=self._kinematics, max_freq=self._config.max_freq, accel_per_hz=self._accel_per_hz, + max_scale=self._max_scale, st_version=self._version, ) computation = computer.compute() @@ -70,12 +74,14 @@ def __init__( kinematics: Optional[str], max_freq: float, accel_per_hz: Optional[float], + max_scale: Optional[int], st_version: str, ): self.measurements = measurements self.kinematics = kinematics self.max_freq = max_freq self.accel_per_hz = accel_per_hz + self.max_scale = max_scale self.st_version = st_version def compute(self): @@ -132,6 +138,7 @@ def compute(self): 'st_version': self.st_version, 'measurements': self.measurements, 'max_freq': self.max_freq, + 'max_scale': self.max_scale, } def _compute_signal_data(self, data: np.ndarray, common_freqs: np.ndarray, max_freq: float): diff --git a/shaketune/graph_creators/plotter.py b/shaketune/graph_creators/plotter.py index 93c134f..694bab6 100644 --- a/shaketune/graph_creators/plotter.py +++ b/shaketune/graph_creators/plotter.py @@ -329,6 +329,7 @@ def plot_belts_graph(self, data): st_version = data['st_version'] measurements = data['measurements'] max_freq = data['max_freq'] + max_scale = data['max_scale'] fig, axes = plt.subplots( 1, @@ -401,7 +402,7 @@ def plot_belts_graph(self, data): ax_1.plot(signal2.freqs, signal2.psd, label='Belt ' + signal2_belt, color=self.KLIPPAIN_COLORS['purple']) psd_highest_max = max(signal1.psd.max(), signal2.psd.max()) ax_1.set_xlim([0, max_freq]) - ax_1.set_ylim([0, psd_highest_max * 1.1]) + ax_1.set_ylim([0, max_scale if max_scale is not None else psd_highest_max * 1.1]) # Annotate peaks paired_peak_count = 0 @@ -645,6 +646,7 @@ def plot_input_shaper_graph(self, data): max_smoothing = data['max_smoothing'] scv = data['scv'] st_version = data['st_version'] + max_scale = data['max_scale'] fig = plt.figure(figsize=(15, 11.6)) gs = fig.add_gridspec( @@ -712,7 +714,7 @@ def plot_input_shaper_graph(self, data): ax_1.plot(freqs, py, label='Y', color='green') ax_1.plot(freqs, pz, label='Z', color='blue') ax_1.set_xlim([0, max_freq]) - ax_1.set_ylim([0, psd.max() * 1.05]) + ax_1.set_ylim([0, max_scale if max_scale is not None else psd.max() * 1.05]) ax_1_2 = ax_1.twinx() ax_1_2.yaxis.set_visible(False) diff --git a/shaketune/graph_creators/shaper_graph_creator.py b/shaketune/graph_creators/shaper_graph_creator.py index 0e24e09..ede8f69 100644 --- a/shaketune/graph_creators/shaper_graph_creator.py +++ b/shaketune/graph_creators/shaper_graph_creator.py @@ -45,11 +45,16 @@ def __init__(self, config: ShakeTuneConfig): self._accel_per_hz: Optional[float] = None def configure( - self, scv: float, max_smoothing: Optional[float] = None, accel_per_hz: Optional[float] = None + self, + scv: float, + max_smoothing: Optional[float] = None, + accel_per_hz: Optional[float] = None, + max_scale: Optional[int] = None, ) -> None: self._scv = scv self._max_smoothing = max_smoothing self._accel_per_hz = accel_per_hz + self._max_scale = max_scale def create_graph(self, measurements_manager: MeasurementsManager) -> None: computer = ShaperGraphComputation( @@ -58,6 +63,7 @@ def create_graph(self, measurements_manager: MeasurementsManager) -> None: scv=self._scv, accel_per_hz=self._accel_per_hz, max_freq=self._config.max_freq, + max_scale=self._max_scale, st_version=self._version, ) computation = computer.compute() @@ -86,6 +92,7 @@ def __init__( scv: float, max_smoothing: Optional[float], max_freq: float, + max_scale: Optional[int], st_version: str, ): self.measurements = measurements @@ -93,6 +100,7 @@ def __init__( self.scv = scv self.max_smoothing = max_smoothing self.max_freq = max_freq + self.max_scale = max_scale self.st_version = st_version def compute(self): @@ -223,6 +231,7 @@ def compute(self): 'max_smoothing': self.max_smoothing, 'scv': self.scv, 'st_version': self.st_version, + 'max_scale': self.max_scale, } # Find the best shaper parameters using Klipper's official algorithm selection with