Skip to content

Commit

Permalink
moved the checks in the onconnect handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Frix-x committed Jun 29, 2024
1 parent a49a571 commit a231de7
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 45 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ Follow these steps to install Shake&Tune on your printer:
# The maximum time in seconds to let Shake&Tune process the CSV files and generate the graphs.

# motor_freq:
# /!\ This option is only available in DangerKlipper /!\
# /!\ This option has limitations in stock Klipper and is best used with DangerKlipper /!\
# Frequencies of X and Y motor resonances to filter them using
# composite shapers. This require the `[input_shaper]` config
# composite shapers. This requires the `[input_shaper]` config
# section to be defined in your printer.cfg file to work.
# motor_freq_x:
# motor_freq_y:
# /!\ This option is only available in DangerKlipper /!\
# /!\ This option has limitations in stock Klipper and is best used with DangerKlipper /!\
# If motor_freq is not set, these two parameters can be used
# to configure different filters for X and Y motors. The same
# values are supported as for motor_freq parameter.
# motor_damping_ratio: 0.05
# /!\ This option is only available in DangerKlipper /!\
# Damping ratios of X and Y motor resonances.
# /!\ This option has limitations in stock Klipper and is best used with DangerKlipper /!\
# Damping ratios for X and Y motor resonances.
# motor_damping_ratio_x:
# motor_damping_ratio_y:
# /!\ This option is only available in DangerKlipper /!\
# /!\ This option has limitations in stock Klipper and is best used with DangerKlipper /!\
# If motor_damping_ratio is not set, these two parameters can be used
# to configure different filters for X and Y motors. The same values
# are supported as for motor_damping_ratio parameter.
Expand Down
14 changes: 12 additions & 2 deletions shaketune/motor_res_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, printer, freq_x: float, freq_y: float, damping_x: float, damp

self._original_shapers = {}

# Convolve two Klipper shapers into a new composite shaper
# Convolve two Klipper shapers into a new custom composite input shaping filter
@staticmethod
def convolve_shapers(L, R):
As = [a * b for a in L[0] for b in R[0]]
Expand All @@ -36,6 +36,11 @@ def convolve_shapers(L, R):

def apply_filters(self) -> None:
input_shaper = self._printer.lookup_object('input_shaper', None)
if input_shaper is None:
raise ValueError(
'Unable to apply Shake&Tune motor resonance filters: no [input_shaper] config section found!'
)

shapers = input_shaper.get_shapers()
for shaper in shapers:
axis = shaper.axis
Expand Down Expand Up @@ -71,7 +76,7 @@ def apply_filters(self) -> None:
ConsoleOutput.print(
(
f'Error: the {axis} axis is not a ZV type shaper. Shake&Tune motor resonance filters '
'will be ignored for this axis... Thi is due to the size of the pulse train being too '
'will be ignored for this axis... This is due to the size of the pulse train being too '
'small and not allowing the convolved shapers to be applied... unless this PR is '
'merged: https://github.com/Klipper3d/klipper/pull/6460'
)
Expand Down Expand Up @@ -109,6 +114,11 @@ def apply_filters(self) -> None:

def remove_filters(self) -> None:
input_shaper = self._printer.lookup_object('input_shaper', None)
if input_shaper is None:
raise ValueError(
'Unable to deactivate Shake&Tune motor resonance filters: no [input_shaper] config section found!'
)

shapers = input_shaper.get_shapers()
for shaper in shapers:
axis = shaper.axis
Expand Down
79 changes: 42 additions & 37 deletions shaketune/shaketune.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,33 +58,19 @@ class ShakeTune:
def __init__(self, config) -> None:
self._config = config
self._printer = config.get_printer()
self.printer.register_event_handler('klippy:connect', self._on_klippy_connect)

self._initialize_danger_klipper()
self._initialize_console_output()
self._validate_resonance_tester()
self._initialize_config(config)
self._register_commands()
self._initialize_motor_resonance_filter()

# Check if Shake&Tune is running in DangerKlipper
def _initialize_danger_klipper(self) -> None:
# Check if Shake&Tune is running in DangerKlipper
global IN_DANGER
if importlib.util.find_spec('extras.danger_options') is not None:
IN_DANGER = True
IN_DANGER = importlib.util.find_spec('extras.danger_options') is not None

# Register the console print output callback to the corresponding Klipper function
def _initialize_console_output(self) -> None:
# Register the console print output callback to the corresponding Klipper function
gcode = self._printer.lookup_object('gcode')
ConsoleOutput.register_output_callback(gcode.respond_info)

# Check if the resonance_tester object is available in the printer
# configuration as it is required for Shake&Tune to work properly
def _validate_resonance_tester(self) -> None:
res_tester = self._printer.lookup_object('resonance_tester', None)
if res_tester is None:
raise self._config.error(
'No [resonance_tester] config section found in printer.cfg! Please add one to use Shake&Tune.'
)
self._initialize_config(config)
self._register_commands()
self._initialize_motor_resonance_filter()

# Initialize the ShakeTune object and its configuration
def _initialize_config(self, config) -> None:
Expand Down Expand Up @@ -155,30 +141,23 @@ def _register_commands(self) -> None:
self._printer.load_object(self._config, gcode_macro_name.lower())

# Register the motor resonance filters if they are defined in the config
# DangerKlipper is required for now or a degraded system forcing the ZV filter for
# both input shaping and motor resonance filter will be used instead. But this will
# DangerKlipper is required for the full feature but a degraded system forcing the ZV filter for
# both input shaping and motor resonance filter will be used instead in stock Klipper. But this might
# be improved in the future if https://github.com/Klipper3d/klipper/pull/6460 get merged
# TODO: To mitigate this issue, add a automated patch to klippy/chelper/kin_shaper.c
# TODO: To mitigate this issue, add an automated patch to klippy/chelper/kin_shaper.c
# (using a .diff file) to enable the motor filters in stock Klipper as well.
# But this will make the Klipper repo dirty to moonraker update manager, so I'm not
# sure how to handle this. Maybe with also a command to revert the patch? Or a
# manual command to apply the patch with a required user action?
def _initialize_motor_resonance_filter(self) -> None:
if self._motor_freq_x is not None and self._motor_freq_y is not None:
input_shaper = self._printer.lookup_object('input_shaper', None)
if input_shaper is None:
raise self._config.error(
(
'Error: motor resonance filters cannot be enabled because the standard '
'[input_shaper] Klipper config section is not configured!'
)
)

self._printer.register_event_handler('klippy:ready', self._on_klippy_ready)
gcode = self._printer.lookup_object('gcode')
gcode.register_command(
'MOTOR_RESONANCE_FILTER', self.cmd_MOTOR_RESONANCE_FILTER, desc='Enable/disable motor resonance filters'
'MOTOR_RESONANCE_FILTER',
self.cmd_MOTOR_RESONANCE_FILTER,
desc='Enable/disable the motor resonance filters',
)

self.motor_resonance_filter = MotorResonanceFilter(
self._printer,
self._motor_freq_x,
Expand All @@ -188,11 +167,37 @@ def _initialize_motor_resonance_filter(self) -> None:
IN_DANGER,
)

self._printer.register_event_handler('klippy:ready', self.handle_ready)
def _on_klippy_connect(self) -> None:
# Check if the resonance_tester object is available in the printer
# configuration as it is required for Shake&Tune to work properly
res_tester = self._printer.lookup_object('resonance_tester', None)
if res_tester is None:
raise self._config.error(
'No [resonance_tester] config section found in printer.cfg! Please add one to use Shake&Tune!'
)

# In case the user has configured a motor resonance filter, we need to make sure
# that the input shaper is configured as well in order to use them. This is because
# the input shaper object is the one used to actually applies the additional filters
if self._motor_freq_x is not None and self._motor_freq_y is not None:
input_shaper = self._printer.lookup_object('input_shaper', None)
if input_shaper is None:
raise self._config.error(
(
'No [input_shaper] config section found in printer.cfg! Please add one to use Shake&Tune '
'motor resonance filters!'
)
)

def handle_ready(self) -> None:
def _on_klippy_ready(self) -> None:
self.motor_resonance_filter.apply_filters()

# ------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------
# Following are all the Shake&Tune commands that are registered to the Klipper console
# ------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------

def cmd_EXCITATE_AXIS_AT_FREQ(self, gcmd) -> None:
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
static_freq_graph_creator = StaticGraphCreator(self._st_config)
Expand Down

0 comments on commit a231de7

Please sign in to comment.