added dummy macros automatic loading
This commit is contained in:
12
README.md
12
README.md
@@ -29,18 +29,26 @@ Follow these steps to install the Shake&Tune module in your printer:
|
|||||||
1. Then, append the following to your `printer.cfg` file and restart Klipper (if prefered, you can include only the needed macros: using `*.cfg` is a convenient way to include them all at once):
|
1. Then, append the following to your `printer.cfg` file and restart Klipper (if prefered, you can include only the needed macros: using `*.cfg` is a convenient way to include them all at once):
|
||||||
```
|
```
|
||||||
[shaketune]
|
[shaketune]
|
||||||
# result_folder: ~/printer_data/config/K-ShakeTune_results
|
# result_folder: ~/printer_data/config/ShakeTune_results
|
||||||
|
# The folder where the results will be stored. It will be created if it doesn't exist.
|
||||||
# number_of_results_to_keep: 3
|
# number_of_results_to_keep: 3
|
||||||
|
# The number of results to keep in the result_folder. The oldest results will
|
||||||
|
# be automatically deleted after each runs.
|
||||||
# keep_raw_csv: False
|
# keep_raw_csv: False
|
||||||
|
# If True, the raw CSV files will be kept in the result_folder alongside the
|
||||||
|
# PNG graphs. If False, they will be deleted and only the graphs will be kept.
|
||||||
|
# show_macros_in_webui: True
|
||||||
|
# Mainsail and Fluidd doesn't create buttons for "system" macros that are not in the
|
||||||
|
# printer.cfg file. If you want to see the macros in the webui, set this to True.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Ensure your machine is homed, then invoke one of the following macros as needed:
|
Ensure your machine is homed, then invoke one of the following macros as needed:
|
||||||
|
- `EXCITATE_AXIS_AT_FREQ` to maintain a specific excitation frequency, useful to inspect and find out what is resonating.
|
||||||
- `AXES_MAP_CALIBRATION` to automatically find Klipper's `axes_map` parameter for your accelerometer orientation (be careful, this is experimental for now and known to give bad results).
|
- `AXES_MAP_CALIBRATION` to automatically find Klipper's `axes_map` parameter for your accelerometer orientation (be careful, this is experimental for now and known to give bad results).
|
||||||
- `COMPARE_BELTS_RESPONSES` for a differential belt resonance graph, useful for checking relative belt tensions and belt path behaviors on a CoreXY printer.
|
- `COMPARE_BELTS_RESPONSES` for a differential belt resonance graph, useful for checking relative belt tensions and belt path behaviors on a CoreXY printer.
|
||||||
- `AXES_SHAPER_CALIBRATION` for standard input shaper graphs, used to mitigate ringing/ghosting by tuning Klipper's input shaper filters.
|
- `AXES_SHAPER_CALIBRATION` for standard input shaper graphs, used to mitigate ringing/ghosting by tuning Klipper's input shaper filters.
|
||||||
- `CREATE_VIBRATIONS_PROFILE` for vibrations graphs as a function of toolhead direction and speed, used to find problematic ranges where the printer could be exposed to more VFAs and optimize your slicer speed profiles and TMC driver parameters.
|
- `CREATE_VIBRATIONS_PROFILE` for vibrations graphs as a function of toolhead direction and speed, used to find problematic ranges where the printer could be exposed to more VFAs and optimize your slicer speed profiles and TMC driver parameters.
|
||||||
- `EXCITATE_AXIS_AT_FREQ` to maintain a specific excitation frequency, useful to inspect and find out what is resonating.
|
|
||||||
|
|
||||||
For further insights on the usage of these macros and the generated graphs, refer to the [K-Shake&Tune module documentation](./docs/README.md).
|
For further insights on the usage of these macros and the generated graphs, refer to the [K-Shake&Tune module documentation](./docs/README.md).
|
||||||
|
|||||||
67
shaketune/dummy_macros.cfg
Normal file
67
shaketune/dummy_macros.cfg
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# This file contains dummy gcode macros to inject them at Klipper startup
|
||||||
|
# by the Shake&Tune plugin in order to make them available in the UI.
|
||||||
|
# Indeed, system macros in Klipper are not available as buttons in Mainsail/Fluidd
|
||||||
|
# and this is a workaround to have a good and friendly UX when using Shake&Tune.
|
||||||
|
|
||||||
|
|
||||||
|
[gcode_macro EXCITATE_AXIS_AT_FREQ]
|
||||||
|
description: dummy
|
||||||
|
gcode:
|
||||||
|
{% set dummy = params.FREQUENCY|default(25) %}
|
||||||
|
{% set dummy = params.DURATION|default(10) %}
|
||||||
|
{% set dummy = params.ACCEL_PER_HZ %}
|
||||||
|
{% set dummy = params.AXIS|default('x') %}
|
||||||
|
{% set dummy = params.TRAVEL_SPEED|default(120) %}
|
||||||
|
{% set dummy = params.Z_HEIGHT %}
|
||||||
|
_EXCITATE_AXIS_AT_FREQ {rawparams}
|
||||||
|
|
||||||
|
|
||||||
|
[gcode_macro AXES_MAP_CALIBRATION]
|
||||||
|
description: dummy
|
||||||
|
gcode:
|
||||||
|
{% set dummy = params.Z_HEIGHT|default(20) %}
|
||||||
|
{% set dummy = params.SPEED|default(80) %}
|
||||||
|
{% set dummy = params.ACCEL|default(1500) %}
|
||||||
|
{% set dummy = params.TRAVEL_SPEED|default(120) %}
|
||||||
|
{% set dummy = params.ACCEL_CHIP %}
|
||||||
|
_AXES_MAP_CALIBRATION {rawparams}
|
||||||
|
|
||||||
|
|
||||||
|
[gcode_macro COMPARE_BELTS_RESPONSES]
|
||||||
|
description: dummy
|
||||||
|
gcode:
|
||||||
|
{% set dummy = params.FREQ_START|default(5) %}
|
||||||
|
{% set dummy = params.FREQ_END|default(133.33) %}
|
||||||
|
{% set dummy = params.HZ_PER_SEC|default(1) %}
|
||||||
|
{% set dummy = params.ACCEL_PER_HZ %}
|
||||||
|
{% set dummy = params.TRAVEL_SPEED|default(120) %}
|
||||||
|
{% set dummy = params.Z_HEIGHT %}
|
||||||
|
_COMPARE_BELTS_RESPONSES {rawparams}
|
||||||
|
|
||||||
|
|
||||||
|
[gcode_macro AXES_SHAPER_CALIBRATION]
|
||||||
|
description: dummy
|
||||||
|
gcode:
|
||||||
|
{% set dummy = params.FREQ_START|default(5) %}
|
||||||
|
{% set dummy = params.FREQ_END|default(133.33) %}
|
||||||
|
{% set dummy = params.HZ_PER_SEC|default(1) %}
|
||||||
|
{% set dummy = params.ACCEL_PER_HZ %}
|
||||||
|
{% set dummy = params.AXIS|default('all') %}
|
||||||
|
{% set dummy = params.SCV %}
|
||||||
|
{% set dummy = params.MAX_SMOOTHING %}
|
||||||
|
{% set dummy = params.TRAVEL_SPEED|default(120) %}
|
||||||
|
{% set dummy = params.Z_HEIGHT %}
|
||||||
|
_AXES_SHAPER_CALIBRATION {rawparams}
|
||||||
|
|
||||||
|
|
||||||
|
[gcode_macro CREATE_VIBRATIONS_PROFILE]
|
||||||
|
description: dummy
|
||||||
|
gcode:
|
||||||
|
{% set dummy = params.SIZE|default(100) %}
|
||||||
|
{% set dummy = params.Z_HEIGHT|default(20) %}
|
||||||
|
{% set dummy = params.MAX_SPEED|default(200) %}
|
||||||
|
{% set dummy = params.SPEED_INCREMENT|default(2) %}
|
||||||
|
{% set dummy = params.ACCEL|default(3000) %}
|
||||||
|
{% set dummy = params.TRAVEL_SPEED|default(120) %}
|
||||||
|
{% set dummy = params.ACCEL_CHIP %}
|
||||||
|
_CREATE_VIBRATIONS_PROFILE {rawparams}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
# [gcode_macro AXES_MAP_CALIBRATION]
|
|
||||||
# gcode:
|
|
||||||
# {% set z_height = params.Z_HEIGHT|default(20)|int %} # z height to put the toolhead before starting the movements
|
|
||||||
# {% set speed = params.SPEED|default(80)|float * 60 %} # feedrate for the movements
|
|
||||||
# {% set accel = params.ACCEL|default(1500)|int %} # accel value used to move on the pattern
|
|
||||||
# {% set feedrate_travel = params.TRAVEL_SPEED|default(120)|int * 60 %} # travel feedrate between moves
|
|
||||||
# {% set accel_chip = params.ACCEL_CHIP|default("adxl345") %} # ADXL chip name in the config
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .helpers.console_output import ConsoleOutput
|
from .helpers.console_output import ConsoleOutput
|
||||||
@@ -24,81 +25,77 @@ class ShakeTune:
|
|||||||
|
|
||||||
res_tester = self._printer.lookup_object('resonance_tester')
|
res_tester = self._printer.lookup_object('resonance_tester')
|
||||||
if res_tester is None:
|
if res_tester is None:
|
||||||
config.error('No [resonance_tester] config section found in printer.cfg! Please add one to use Shake&Tune')
|
config.error('No [resonance_tester] config section found in printer.cfg! Please add one to use Shake&Tune.')
|
||||||
|
|
||||||
self.timeout = config.getfloat('timeout', 2.0, above=0.0)
|
self.timeout = config.getfloat('timeout', 2.0, above=0.0)
|
||||||
|
result_folder = config.get('result_folder', default='~/printer_data/config/ShakeTune_results')
|
||||||
result_folder = config.get('result_folder', default='~/printer_data/config/K-ShakeTune_results')
|
|
||||||
result_folder_path = Path(result_folder).expanduser() if result_folder else None
|
result_folder_path = Path(result_folder).expanduser() if result_folder else None
|
||||||
keep_n_results = config.getint('number_of_results_to_keep', default=3, minval=0)
|
keep_n_results = config.getint('number_of_results_to_keep', default=3, minval=0)
|
||||||
keep_csv = config.getboolean('keep_raw_csv', default=False)
|
keep_csv = config.getboolean('keep_raw_csv', default=False)
|
||||||
|
show_macros = config.getboolean('show_macros_in_webui', default=True)
|
||||||
dpi = config.getint('dpi', default=150, minval=100, maxval=500)
|
dpi = config.getint('dpi', default=150, minval=100, maxval=500)
|
||||||
|
|
||||||
self._config = ShakeTuneConfig(result_folder_path, keep_n_results, keep_csv, dpi)
|
self._config = ShakeTuneConfig(result_folder_path, keep_n_results, keep_csv, dpi)
|
||||||
ConsoleOutput.register_output_callback(gcode.respond_info)
|
ConsoleOutput.register_output_callback(gcode.respond_info)
|
||||||
|
|
||||||
|
commands = [
|
||||||
|
('EXCITATE_AXIS_AT_FREQ', self.cmd_EXCITATE_AXIS_AT_FREQ, 'Maintain a specified excitation frequency for a period of time to diagnose and locate a source of vibration'),
|
||||||
|
('AXES_MAP_CALIBRATION', self.cmd_AXES_MAP_CALIBRATION, 'Perform a set of movements to measure the orientation of the accelerometer and help you set the best axes_map configuration for your printer'),
|
||||||
|
('COMPARE_BELTS_RESPONSES', self.cmd_COMPARE_BELTS_RESPONSES, 'Perform a custom half-axis test to analyze and compare the frequency profiles of individual belts on CoreXY printers'),
|
||||||
|
('AXES_SHAPER_CALIBRATION', self.cmd_AXES_SHAPER_CALIBRATION, 'Perform standard axis input shaper tests on one or both XY axes to select the best input shaper filter'),
|
||||||
|
('CREATE_VIBRATIONS_PROFILE', self.cmd_CREATE_VIBRATIONS_PROFILE, 'Perform a set of movements to measure the orientation of the accelerometer and help you set the best axes_map configuration for your printer')
|
||||||
|
]
|
||||||
|
command_descriptions = {name: desc for name, _, desc in commands}
|
||||||
|
|
||||||
|
for name, command, description in commands:
|
||||||
gcode.register_command(
|
gcode.register_command(
|
||||||
'EXCITATE_AXIS_AT_FREQ',
|
f'_{name}' if show_macros else name,
|
||||||
self.cmd_EXCITATE_AXIS_AT_FREQ,
|
command,
|
||||||
desc=self.cmd_EXCITATE_AXIS_AT_FREQ_help,
|
desc=description
|
||||||
)
|
|
||||||
gcode.register_command(
|
|
||||||
'AXES_MAP_CALIBRATION',
|
|
||||||
self.cmd_AXES_MAP_CALIBRATION,
|
|
||||||
desc=self.cmd_AXES_MAP_CALIBRATION_help,
|
|
||||||
)
|
|
||||||
gcode.register_command(
|
|
||||||
'COMPARE_BELTS_RESPONSES',
|
|
||||||
self.cmd_COMPARE_BELTS_RESPONSES,
|
|
||||||
desc=self.cmd_COMPARE_BELTS_RESPONSES_help,
|
|
||||||
)
|
|
||||||
gcode.register_command(
|
|
||||||
'AXES_SHAPER_CALIBRATION',
|
|
||||||
self.cmd_AXES_SHAPER_CALIBRATION,
|
|
||||||
desc=self.cmd_AXES_SHAPER_CALIBRATION_help,
|
|
||||||
)
|
|
||||||
gcode.register_command(
|
|
||||||
'CREATE_VIBRATIONS_PROFILE',
|
|
||||||
self.cmd_CREATE_VIBRATIONS_PROFILE,
|
|
||||||
desc=self.cmd_CREATE_VIBRATIONS_PROFILE_help,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd_EXCITATE_AXIS_AT_FREQ_help = (
|
# Load the dummy macros with their description in order to show them in the web interfaces
|
||||||
'Maintain a specified excitation frequency for a period of time to diagnose and locate a source of vibration'
|
if show_macros:
|
||||||
)
|
pconfig = self._printer.lookup_object('configfile')
|
||||||
|
dirname = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
filename = os.path.join(dirname, 'dummy_macros.cfg')
|
||||||
|
try:
|
||||||
|
dummy_macros = pconfig.read_config(filename)
|
||||||
|
except Exception as err:
|
||||||
|
raise config.error("Cannot load Shake&Tune dummy macro '%s'" % (filename,)) from err
|
||||||
|
for macro in dummy_macros.get_prefix_sections(''):
|
||||||
|
section = macro.get_name()
|
||||||
|
command = section.split(' ', 1)[1]
|
||||||
|
if command in command_descriptions:
|
||||||
|
description = command_descriptions[command]
|
||||||
|
else:
|
||||||
|
description = 'Shake&Tune macro'
|
||||||
|
macro.fileconfig._sections[section]['description'] = description
|
||||||
|
self._printer.load_object(dummy_macros, section)
|
||||||
|
|
||||||
|
|
||||||
def cmd_EXCITATE_AXIS_AT_FREQ(self, gcmd) -> None:
|
def cmd_EXCITATE_AXIS_AT_FREQ(self, gcmd) -> None:
|
||||||
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
||||||
excitate_axis_at_freq(gcmd, self._pconfig)
|
excitate_axis_at_freq(gcmd, self._pconfig)
|
||||||
|
|
||||||
cmd_AXES_MAP_CALIBRATION_help = 'Perform a set of movements to measure the orientation of the accelerometer and help you set the best axes_map configuration for your printer'
|
|
||||||
|
|
||||||
def cmd_AXES_MAP_CALIBRATION(self, gcmd) -> None:
|
def cmd_AXES_MAP_CALIBRATION(self, gcmd) -> None:
|
||||||
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
||||||
axes_map_finder = AxesMapFinder(self._config)
|
axes_map_finder = AxesMapFinder(self._config)
|
||||||
st_thread = ShakeTuneThread(self._config, axes_map_finder, self._printer.get_reactor(), self.timeout)
|
st_thread = ShakeTuneThread(self._config, axes_map_finder, self._printer.get_reactor(), self.timeout)
|
||||||
axes_map_calibration(gcmd, self._pconfig, st_thread)
|
axes_map_calibration(gcmd, self._pconfig, st_thread)
|
||||||
|
|
||||||
cmd_COMPARE_BELTS_RESPONSES_help = 'Perform a custom half-axis test to analyze and compare the frequency profiles of individual belts on CoreXY printers'
|
|
||||||
|
|
||||||
def cmd_COMPARE_BELTS_RESPONSES(self, gcmd) -> None:
|
def cmd_COMPARE_BELTS_RESPONSES(self, gcmd) -> None:
|
||||||
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
||||||
belt_graph_creator = BeltsGraphCreator(self._config)
|
belt_graph_creator = BeltsGraphCreator(self._config)
|
||||||
st_thread = ShakeTuneThread(self._config, belt_graph_creator, self._printer.get_reactor(), self.timeout)
|
st_thread = ShakeTuneThread(self._config, belt_graph_creator, self._printer.get_reactor(), self.timeout)
|
||||||
compare_belts_responses(gcmd, self._pconfig, st_thread)
|
compare_belts_responses(gcmd, self._pconfig, st_thread)
|
||||||
|
|
||||||
cmd_AXES_SHAPER_CALIBRATION_help = (
|
|
||||||
'Perform standard axis input shaper tests on one or both XY axes to select the best input shaper filter'
|
|
||||||
)
|
|
||||||
|
|
||||||
def cmd_AXES_SHAPER_CALIBRATION(self, gcmd) -> None:
|
def cmd_AXES_SHAPER_CALIBRATION(self, gcmd) -> None:
|
||||||
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
||||||
shaper_graph_creator = ShaperGraphCreator(self._config)
|
shaper_graph_creator = ShaperGraphCreator(self._config)
|
||||||
st_thread = ShakeTuneThread(self._config, shaper_graph_creator, self._printer.get_reactor(), self.timeout)
|
st_thread = ShakeTuneThread(self._config, shaper_graph_creator, self._printer.get_reactor(), self.timeout)
|
||||||
axes_shaper_calibration(gcmd, self._pconfig, st_thread)
|
axes_shaper_calibration(gcmd, self._pconfig, st_thread)
|
||||||
|
|
||||||
cmd_CREATE_VIBRATIONS_PROFILE_help = 'Perform a set of movements to measure the orientation of the accelerometer and help you set the best axes_map configuration for your printer'
|
|
||||||
|
|
||||||
def cmd_CREATE_VIBRATIONS_PROFILE(self, gcmd) -> None:
|
def cmd_CREATE_VIBRATIONS_PROFILE(self, gcmd) -> None:
|
||||||
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
ConsoleOutput.print(f'Shake&Tune version: {ShakeTuneConfig.get_git_version()}')
|
||||||
vibration_profile_creator = VibrationsGraphCreator(self._config)
|
vibration_profile_creator = VibrationsGraphCreator(self._config)
|
||||||
|
|||||||
Reference in New Issue
Block a user