Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1e9269ba3 | ||
|
|
8e304a71ca | ||
|
|
5d54db0ca0 | ||
|
|
d52680738f | ||
|
|
f95c55230b | ||
|
|
0f7fa66af4 | ||
|
|
da10593ca7 | ||
|
|
060a800cc3 | ||
|
|
7c76be5077 | ||
|
|
a4c2ead732 | ||
|
|
6e884528c0 | ||
|
|
17ccddfa0f | ||
|
|
83f517758a | ||
|
|
c156459420 |
@@ -2,9 +2,10 @@
|
||||
###### STANDARD INPUT_SHAPER CALIBRATIONS ######
|
||||
################################################
|
||||
# Written by Frix_x#0161 #
|
||||
# @version: 1.4
|
||||
# @version: 1.5
|
||||
|
||||
# CHANGELOG:
|
||||
# v1.5: modified EXCITATE_AXIS_AT_FREQ to allow A or B belt testing
|
||||
# v1.4: added possibility to only run one axis at a time for the axes shaper calibration
|
||||
# v1.3: added possibility to override the default parameters
|
||||
# v1.2: added EXCITATE_AXIS_AT_FREQ to hold a specific excitating frequency on an axis and diagnose mechanical problems
|
||||
@@ -26,7 +27,7 @@
|
||||
|
||||
|
||||
[gcode_macro AXES_SHAPER_CALIBRATION]
|
||||
description: Run standard input shaper test for all axes
|
||||
description: Perform standard axis input shaper tests on one or both XY axes to select the best input shaper filter
|
||||
gcode:
|
||||
{% set verbose = params.VERBOSE|default(true) %}
|
||||
{% set min_freq = params.FREQ_START|default(5)|float %}
|
||||
@@ -51,7 +52,8 @@ gcode:
|
||||
M400
|
||||
|
||||
{% if verbose %}
|
||||
RESPOND MSG="X axis shaper graphs generation..."
|
||||
RESPOND MSG="X axis frequency profile generation..."
|
||||
RESPOND MSG="This may take some time (1-3min)"
|
||||
{% endif %}
|
||||
RUN_SHELL_COMMAND CMD=plot_graph PARAMS=SHAPER
|
||||
{% endif %}
|
||||
@@ -61,14 +63,15 @@ gcode:
|
||||
M400
|
||||
|
||||
{% if verbose %}
|
||||
RESPOND MSG="Y axis shaper graphs generation..."
|
||||
RESPOND MSG="Y axis frequency profile generation..."
|
||||
RESPOND MSG="This may take some time (1-3min)"
|
||||
{% endif %}
|
||||
RUN_SHELL_COMMAND CMD=plot_graph PARAMS=SHAPER
|
||||
{% endif %}
|
||||
|
||||
|
||||
[gcode_macro BELTS_SHAPER_CALIBRATION]
|
||||
description: Run custom demi-axe test to analyze belts on CoreXY printers
|
||||
description: Perform a custom half-axis test to analyze and compare the frequency profiles of individual belts on CoreXY printers
|
||||
gcode:
|
||||
{% set verbose = params.VERBOSE|default(true) %}
|
||||
{% set min_freq = params.FREQ_START|default(5)|float %}
|
||||
@@ -77,21 +80,33 @@ gcode:
|
||||
|
||||
TEST_RESONANCES AXIS=1,1 OUTPUT=raw_data NAME=b FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec}
|
||||
M400
|
||||
|
||||
TEST_RESONANCES AXIS=1,-1 OUTPUT=raw_data NAME=a FREQ_START={min_freq} FREQ_END={max_freq} HZ_PER_SEC={hz_per_sec}
|
||||
M400
|
||||
|
||||
{% if verbose %}
|
||||
RESPOND MSG="Belts graphs generation..."
|
||||
RESPOND MSG="Belts comparative frequency profile generation..."
|
||||
RESPOND MSG="This may take some time (3-5min)"
|
||||
{% endif %}
|
||||
RUN_SHELL_COMMAND CMD=plot_graph PARAMS=BELTS
|
||||
|
||||
|
||||
[gcode_macro EXCITATE_AXIS_AT_FREQ]
|
||||
description: Maintain a specified input shaper excitating frequency for some time to diagnose vibrations
|
||||
description: Maintain a specified input shaper excitation frequency for a period of time to diagnose and locate a source of vibration
|
||||
gcode:
|
||||
{% set FREQUENCY = params.FREQUENCY|default(25)|int %}
|
||||
{% set TIME = params.TIME|default(10)|int %}
|
||||
{% set AXIS = params.AXIS|default("x")|string|lower %}
|
||||
{% set frequency = params.FREQUENCY|default(25)|int %}
|
||||
{% set time = params.TIME|default(10)|int %}
|
||||
{% set axis = params.AXIS|default("x")|string|lower %}
|
||||
|
||||
TEST_RESONANCES OUTPUT=raw_data AXIS={AXIS} FREQ_START={FREQUENCY-1} FREQ_END={FREQUENCY+1} HZ_PER_SEC={1/(TIME/3)}
|
||||
{% if axis not in ["x", "y", "a", "b"] %}
|
||||
{ action_raise_error("AXIS selection invalid. Should be either x, y, a or b!") }
|
||||
{% endif %}
|
||||
|
||||
{% if axis == "a" %}
|
||||
{% set axis = "1,-1" %}
|
||||
{% elif axis == "b" %}
|
||||
{% set axis = "1,1" %}
|
||||
{% endif %}
|
||||
|
||||
TEST_RESONANCES OUTPUT=raw_data AXIS={axis} FREQ_START={frequency-1} FREQ_END={frequency+1} HZ_PER_SEC={1/(time/3)}
|
||||
M400
|
||||
|
||||
@@ -2,40 +2,17 @@
|
||||
###### VIBRATIONS AND SPEED OPTIMIZATIONS ######
|
||||
################################################
|
||||
# Written by Frix_x#0161 #
|
||||
# @version: 2.1
|
||||
# @version: 2.2
|
||||
|
||||
# CHANGELOG:
|
||||
# v2.2: allow custom accel values and set sane defaults (3k) to avoid using very high accels that produce bad results
|
||||
# v2.1: allow decimal entries for speed and increment and added the E axis as an option to be neasured
|
||||
# v2.0: added the possibility to measure mutliple axis
|
||||
# v1.0: first speed and vibrations optimization macro
|
||||
|
||||
|
||||
### What is it ? ###
|
||||
# This macro helps you to identify the speed settings that exacerbate the vibrations of the machine (ie. where the frame resonate badly).
|
||||
# It also helps to find the clean speed ranges where the machine is silent.
|
||||
# I had some strong vibrations at very specific speeds on my machine (52mm/s for example) and I wanted to find all these problematic speeds
|
||||
# to avoid them in my slicer profile and finally get the silent machine I was dreaming!
|
||||
|
||||
# It works by moving the toolhead at different speed settings while recording the vibrations using the ADXL chip. Then the macro call a custom script
|
||||
# to compute and find the best speed settings. The results can be found in your config folder using Fluidd/Mainsail file manager.
|
||||
|
||||
# The goal is to make it easy to set, share and use it.
|
||||
|
||||
# This macro is parametric and most of the values can be adjusted with their respective input parameters.
|
||||
# It can be called without any parameters - in which case the default values would be used - or with any combination of parameters as desired.
|
||||
|
||||
# Usage:
|
||||
# 1. DO YOUR INPUT SHAPER CALIBRATION FIRST !!! This macro should not be used before as it would be useless and the results invalid.
|
||||
# 2. Call the VIBRATIONS_CALIBRATION macro with the speed range you want to measure (default 20 to 200mm/s with 2mm/s increment).
|
||||
# Be carefull about the Z_HEIGHT variable that default to 20mm -> if your ADXL is under the nozzle, increase it to avoid a crash of the ADXL on the bed of the machine.
|
||||
# 3. Wait for it to finish all the measurement and compute the graph. Then look at it in the results folder.
|
||||
|
||||
|
||||
[gcode_macro VIBRATIONS_CALIBRATION]
|
||||
gcode:
|
||||
#
|
||||
# PARAMETERS
|
||||
#
|
||||
{% set size = params.SIZE|default(60)|int %} # size of the area where the movements are done
|
||||
{% set direction = params.DIRECTION|default('XY') %} # can be set to either XY, AB, ABXY, A, B, X, Y, Z
|
||||
{% set z_height = params.Z_HEIGHT|default(20)|int %} # z height to put the toolhead before starting the movements
|
||||
@@ -45,16 +22,18 @@ gcode:
|
||||
{% set max_speed = params.MAX_SPEED|default(200)|float * 60 %} # maximum feedrate for the movements
|
||||
{% set speed_increment = params.SPEED_INCREMENT|default(2)|float * 60 %} # feedrate increment between each move
|
||||
{% set feedrate_travel = params.TRAVEL_SPEED|default(200)|int * 60 %} # travel feedrate between moves
|
||||
|
||||
{% set accel = params.ACCEL|default(3000)|int %} # accel value used to move on the pattern
|
||||
{% set accel_chip = params.ACCEL_CHIP|default("adxl345") %} # ADXL chip name in the config
|
||||
|
||||
#
|
||||
# COMPUTED VALUES
|
||||
#
|
||||
{% set mid_x = printer.toolhead.axis_maximum.x|float / 2 %}
|
||||
{% set mid_y = printer.toolhead.axis_maximum.y|float / 2 %}
|
||||
{% set nb_samples = ((max_speed - min_speed) / speed_increment + 1) | int %}
|
||||
|
||||
{% set accel = [accel, printer.configfile.settings.printer.max_accel]|min %}
|
||||
{% set old_accel = printer.toolhead.max_accel %}
|
||||
{% set old_accel_to_decel = printer.toolhead.max_accel_to_decel %}
|
||||
{% set old_sqv = printer.toolhead.square_corner_velocity %}
|
||||
|
||||
{% set direction_factor = {
|
||||
'XY' : {
|
||||
'start' : {'x': -0.5, 'y': -0.5 },
|
||||
@@ -158,6 +137,9 @@ gcode:
|
||||
M83
|
||||
G90
|
||||
|
||||
# Set the wanted acceleration values (not too high to avoid oscillation, not too low to be able to reach constant speed on each segments)
|
||||
SET_VELOCITY_LIMIT ACCEL={accel} ACCEL_TO_DECEL={accel} SQUARE_CORNER_VELOCITY={[(accel / 1000), 5.0]|max}
|
||||
|
||||
# Going to the start position
|
||||
G1 Z{z_height}
|
||||
G1 X{mid_x + (size * direction_factor[direction].start.x) } Y{mid_y + (size * direction_factor[direction].start.y)} F{feedrate_travel}
|
||||
@@ -188,4 +170,7 @@ gcode:
|
||||
{% endif %}
|
||||
RUN_SHELL_COMMAND CMD=plot_graph PARAMS="VIBRATIONS {direction}"
|
||||
|
||||
# Restore the previous acceleration values
|
||||
SET_VELOCITY_LIMIT ACCEL={old_accel} ACCEL_TO_DECEL={old_accel_to_decel} SQUARE_CORNER_VELOCITY={old_sqv}
|
||||
|
||||
RESTORE_GCODE_STATE NAME=STATE_VIBRATIONS_CALIBRATION
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
######## CoreXY BELTS CALIBRATION SCRIPT ########
|
||||
#################################################
|
||||
# Written by Frix_x#0161 #
|
||||
# @version: 2.0
|
||||
# @version: 2.1
|
||||
|
||||
# CHANGELOG:
|
||||
# v2.1: replaced the TwoSlopNorm by a custom made norm to allow the script to work on older versions of matplotlib
|
||||
# v2.0: updated the script to align it to the new K-Shake&Tune module
|
||||
# v1.0: first version of this tool for enhanced vizualisation of belt graphs
|
||||
|
||||
@@ -473,9 +474,13 @@ def plot_difference_spectrogram(ax, data1, data2, signal1, signal2, similarity_f
|
||||
ax.set_title(f"Differential Spectrogram", fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold')
|
||||
ax.plot([], [], ' ', label=f'{textual_mhi} (experimental)')
|
||||
|
||||
# Draw the differential spectrogram with a specific norm to get light grey zero values and red for max values (vmin to vcenter is not used)
|
||||
norm = matplotlib.colors.TwoSlopeNorm(vcenter=np.min(combined_data), vmax=np.max(combined_data))
|
||||
ax.pcolormesh(bins, t, combined_data.T, cmap='RdBu_r', norm=norm, shading='gouraud')
|
||||
# Draw the differential spectrogram with a specific custom norm to get white or light orange zero values and red for max values
|
||||
colors = ['white', 'bisque', 'red', 'black']
|
||||
n_bins = [0, 0.12, 0.9, 1] # These values where found experimentaly to get a good higlhlighting of the differences only
|
||||
cm = matplotlib.colors.LinearSegmentedColormap.from_list('WhiteToRed', list(zip(n_bins, colors)))
|
||||
norm = matplotlib.colors.Normalize(vmin=np.min(combined_data), vmax=np.max(combined_data))
|
||||
ax.pcolormesh(bins, t, combined_data.T, cmap=cm, norm=norm, shading='gouraud')
|
||||
|
||||
ax.set_xlabel('Frequency (hz)')
|
||||
ax.set_xlim([0., max_freq])
|
||||
ax.set_ylabel('Time (s)')
|
||||
|
||||
@@ -164,7 +164,7 @@ def detect_peaks(psd, freqs, window_size=5, vicinity=3):
|
||||
# Graphing
|
||||
######################################################################
|
||||
|
||||
def plot_freq_response_with_damping(ax, calibration_data, shapers, selected_shaper, fr, zeta, max_freq):
|
||||
def plot_freq_response_with_damping(ax, calibration_data, shapers, performance_shaper, fr, zeta, max_freq):
|
||||
freqs = calibration_data.freq_bins
|
||||
psd = calibration_data.psd_sum[freqs <= max_freq]
|
||||
px = calibration_data.psd_x[freqs <= max_freq]
|
||||
@@ -194,32 +194,50 @@ def plot_freq_response_with_damping(ax, calibration_data, shapers, selected_shap
|
||||
ax2 = ax.twinx()
|
||||
ax2.yaxis.set_visible(False)
|
||||
|
||||
best_shaper_vals = None
|
||||
lowest_vibration = float('inf')
|
||||
lowest_vibration_shaper = None
|
||||
lowest_vibration_shaper_freq = None
|
||||
lowest_vibration_shaper_accel = 0
|
||||
lowvib_shaper_vibrs = float('inf')
|
||||
lowvib_shaper = None
|
||||
lowvib_shaper_freq = None
|
||||
lowvib_shaper_accel = 0
|
||||
|
||||
# Draw the shappers curves and add their specific parameters in the legend
|
||||
# This adds also a way to find the best shaper with 0% of vibrations (to be printed in the legend later)
|
||||
# This adds also a way to find the best shaper with a low level of vibrations (with a resonable level of smoothing)
|
||||
for shaper in shapers:
|
||||
shaper_max_accel = round(shaper.max_accel / 100.) * 100.
|
||||
label = "%s (%.1f Hz, vibr=%.1f%%, sm~=%.2f, accel<=%.f)" % (
|
||||
shaper.name.upper(), shaper.freq,
|
||||
shaper.vibrs * 100., shaper.smoothing,
|
||||
shaper_max_accel)
|
||||
linestyle = 'dotted'
|
||||
if shaper.name == selected_shaper:
|
||||
linestyle = 'dashdot'
|
||||
selected_shaper_freq = shaper.freq
|
||||
best_shaper_vals = shaper.vals
|
||||
if (shaper.vibrs * 100 < lowest_vibration or (shaper.vibrs * 100 == lowest_vibration and shaper_max_accel > lowest_vibration_shaper_accel)) and shaper.smoothing < MAX_SMOOTHING:
|
||||
lowest_vibration = shaper.vibrs * 100
|
||||
lowest_vibration_shaper_accel = shaper_max_accel
|
||||
lowest_vibration_shaper = shaper.name
|
||||
lowest_vibration_shaper_freq = shaper.freq
|
||||
ax2.plot(freqs, shaper.vals, label=label, linestyle=linestyle)
|
||||
ax.plot(freqs, psd * best_shaper_vals, label='With %s applied' % (selected_shaper.upper()), color='cyan')
|
||||
ax2.plot(freqs, shaper.vals, label=label, linestyle='dotted')
|
||||
|
||||
# Get the performance shaper
|
||||
if shaper.name == performance_shaper:
|
||||
performance_shaper_freq = shaper.freq
|
||||
performance_shaper_vibr = shaper.vibrs * 100.
|
||||
performance_shaper_vals = shaper.vals
|
||||
|
||||
# Get the low vibration shaper
|
||||
if (shaper.vibrs * 100 < lowvib_shaper_vibrs or (shaper.vibrs * 100 == lowvib_shaper_vibrs and shaper_max_accel > lowvib_shaper_accel)) and shaper.smoothing < MAX_SMOOTHING:
|
||||
lowvib_shaper_accel = shaper_max_accel
|
||||
lowvib_shaper = shaper.name
|
||||
lowvib_shaper_freq = shaper.freq
|
||||
lowvib_shaper_vibrs = shaper.vibrs * 100
|
||||
lowvib_shaper_vals = shaper.vals
|
||||
|
||||
# User recommendations are added to the legend: one is Klipper's original suggestion that is usually good for performances
|
||||
# and the other one is the custom "low vibration" recommendation that looks for a suitable shaper that doesn't have excessive
|
||||
# smoothing and that have a lower vibration level. If both recommendation are the same shaper, or if no suitable "low
|
||||
# vibration" shaper is found, then only a single line as the "best shaper" recommendation is added to the legend
|
||||
if lowvib_shaper != None and lowvib_shaper != performance_shaper and lowvib_shaper_vibrs <= performance_shaper_vibr:
|
||||
ax2.plot([], [], ' ', label="Recommended performance shaper: %s @ %.1f Hz" % (performance_shaper.upper(), performance_shaper_freq))
|
||||
ax.plot(freqs, psd * performance_shaper_vals, label='With %s applied' % (performance_shaper.upper()), color='cyan')
|
||||
ax2.plot([], [], ' ', label="Recommended low vibrations shaper: %s @ %.1f Hz" % (lowvib_shaper.upper(), lowvib_shaper_freq))
|
||||
ax.plot(freqs, psd * lowvib_shaper_vals, label='With %s applied' % (lowvib_shaper.upper()), color='lime')
|
||||
else:
|
||||
ax2.plot([], [], ' ', label="Recommended best shaper: %s @ %.1f Hz" % (performance_shaper.upper(), performance_shaper_freq))
|
||||
ax.plot(freqs, psd * performance_shaper_vals, label='With %s applied' % (performance_shaper.upper()), color='cyan')
|
||||
|
||||
# And the estimated damping ratio is finally added at the end of the legend
|
||||
ax2.plot([], [], ' ', label="Estimated damping ratio (ζ): %.3f" % (zeta))
|
||||
|
||||
# Draw the detected peaks and name them
|
||||
# This also draw the detection threshold and warning threshold (aka "effect zone")
|
||||
@@ -243,18 +261,6 @@ def plot_freq_response_with_damping(ax, calibration_data, shapers, selected_shap
|
||||
ax.fill_between(freqs, 0, peaks_warning_threshold, color='green', alpha=0.15, label='Relax Region')
|
||||
ax.fill_between(freqs, peaks_warning_threshold, peaks_effect_threshold, color='orange', alpha=0.2, label='Warning Region')
|
||||
|
||||
# User recommendations are added to the legend: one is Klipper's original suggestion that is usually good for performances
|
||||
# and the other one is the custom "low vibration" recommendation that looks for a suitable shaper that doesn't have excessive
|
||||
# smoothing (<0.1) and that have a lower vibration level. If both recommendation are the same shaper, or if no suitable "low
|
||||
# vibration" shaper is found, then only a single line as the "best shaper" recommendation is added to the legend
|
||||
if lowest_vibration_shaper != selected_shaper and lowest_vibration_shaper != None:
|
||||
ax2.plot([], [], ' ', label="Recommended performance shaper: %s @ %.1f Hz" % (selected_shaper.upper(), selected_shaper_freq))
|
||||
ax2.plot([], [], ' ', label="Recommended low vibrations shaper: %s @ %.1f Hz" % (lowest_vibration_shaper.upper(), lowest_vibration_shaper_freq))
|
||||
else:
|
||||
ax2.plot([], [], ' ', label="Recommended best shaper: %s @ %.1f Hz" % (selected_shaper.upper(), selected_shaper_freq))
|
||||
|
||||
# And the estimated damping ratio is finally added at the end of the legend
|
||||
ax2.plot([], [], ' ', label="Estimated damping ratio (ζ): %.3f" % (zeta))
|
||||
|
||||
# Add the main resonant frequency and damping ratio of the axis to the graph title
|
||||
ax.set_title("Axis Frequency Profile (ω0=%.1fHz, ζ=%.3f)" % (fr, zeta), fontsize=14, color=KLIPPAIN_COLORS['dark_orange'], weight='bold')
|
||||
@@ -326,7 +332,7 @@ def shaper_calibration(lognames, klipperdir="~/klipper", max_smoothing=None, max
|
||||
datas = [parse_log(fn) for fn in lognames]
|
||||
|
||||
# Calibrate shaper and generate outputs
|
||||
selected_shaper, shapers, calibration_data, fr, zeta = calibrate_shaper_with_damping(datas, max_smoothing)
|
||||
performance_shaper, shapers, calibration_data, fr, zeta = calibrate_shaper_with_damping(datas, max_smoothing)
|
||||
|
||||
fig = matplotlib.pyplot.figure()
|
||||
gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[4, 3])
|
||||
@@ -346,7 +352,7 @@ def shaper_calibration(lognames, klipperdir="~/klipper", max_smoothing=None, max
|
||||
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
||||
|
||||
# Plot the graphs
|
||||
peaks = plot_freq_response_with_damping(ax1, calibration_data, shapers, selected_shaper, fr, zeta, max_freq)
|
||||
peaks = plot_freq_response_with_damping(ax1, calibration_data, shapers, performance_shaper, fr, zeta, max_freq)
|
||||
plot_spectrogram(ax2, datas[0], peaks, max_freq)
|
||||
|
||||
fig.set_size_inches(8.3, 11.6)
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
###### INPUT SHAPER KLIPPAIN WORKFLOW ######
|
||||
############################################
|
||||
# Written by Frix_x#0161 #
|
||||
# @version: 2.0
|
||||
# @version: 2.1
|
||||
|
||||
# CHANGELOG:
|
||||
# v2.1: added more filesystem sync and file handler checks to avoid using corrupted CSV files by going to fast
|
||||
# v2.0: new version of this as a Python script (to replace the old bash script) and implement the newer and improved shaper plotting scripts
|
||||
# v1.7: updated the handling of shaper files to account for the new analysis scripts as we are now using raw data directly
|
||||
# v1.6: - updated the handling of shaper graph files to be able to optionnaly account for added positions in the filenames and remove them
|
||||
@@ -25,7 +26,6 @@
|
||||
# VIBRATIONS - To generate vibration diagram after calling the custom (Frix_x#0161) VIBRATIONS_CALIBRATION macro
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import time
|
||||
import glob
|
||||
@@ -55,6 +55,10 @@ def is_file_open(filepath):
|
||||
if os.path.samefile(fd, filepath):
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
# Klipper has already released the CSV file
|
||||
pass
|
||||
except PermissionError:
|
||||
# Unable to check for this particular process due to permissions
|
||||
pass
|
||||
return False
|
||||
|
||||
@@ -75,15 +79,20 @@ def get_belts_graph():
|
||||
for filename in sorted_files[:2]:
|
||||
# Wait for the file handler to be released by Klipper
|
||||
while is_file_open(filename):
|
||||
time.sleep(3)
|
||||
time.sleep(2)
|
||||
|
||||
# Extract the tested belt from the filename and rename/move the CSV file to the result folder
|
||||
belt = os.path.basename(filename).split('_')[3].split('.')[0].upper()
|
||||
new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[0], f'belt_{current_date}_{belt}.csv')
|
||||
shutil.move(filename, new_file)
|
||||
os.sync() # Sync filesystem to avoid problems
|
||||
|
||||
# Save the file path for later
|
||||
lognames.append(new_file)
|
||||
|
||||
# Wait for the file handler to be released by the move command
|
||||
while is_file_open(new_file):
|
||||
time.sleep(2)
|
||||
|
||||
# Generate the belts graph and its name
|
||||
fig = belts_calibration(lognames, KLIPPER_FOLDER)
|
||||
@@ -105,12 +114,17 @@ def get_shaper_graph():
|
||||
|
||||
# Wait for the file handler to be released by Klipper
|
||||
while is_file_open(filename):
|
||||
time.sleep(3)
|
||||
time.sleep(2)
|
||||
|
||||
# Extract the tested axis from the filename and rename/move the CSV file to the result folder
|
||||
axis = os.path.basename(filename).split('_')[3].split('.')[0].upper()
|
||||
new_file = os.path.join(RESULTS_FOLDER, RESULTS_SUBFOLDERS[1], f'resonances_{current_date}_{axis}.csv')
|
||||
shutil.move(filename, new_file)
|
||||
os.sync() # Sync filesystem to avoid problems
|
||||
|
||||
# Wait for the file handler to be released by the move command
|
||||
while is_file_open(new_file):
|
||||
time.sleep(2)
|
||||
|
||||
# Generate the shaper graph and its name
|
||||
fig = shaper_calibration([new_file], KLIPPER_FOLDER)
|
||||
@@ -134,7 +148,7 @@ def get_vibrations_graph(axis_name):
|
||||
for filename in globbed_files:
|
||||
# Wait for the file handler to be released by Klipper
|
||||
while is_file_open(filename):
|
||||
time.sleep(3)
|
||||
time.sleep(2)
|
||||
|
||||
# Cleanup of the filename and moving it in the result folder
|
||||
cleanfilename = os.path.basename(filename).replace('adxl345', f'vibr_{current_date}')
|
||||
@@ -146,6 +160,7 @@ def get_vibrations_graph(axis_name):
|
||||
|
||||
# Sync filesystem to avoid problems as there is a lot of file copied
|
||||
os.sync()
|
||||
time.sleep(5)
|
||||
|
||||
# Generate the vibration graph and its name
|
||||
fig = vibrations_calibration(lognames, KLIPPER_FOLDER, axis_name)
|
||||
|
||||
@@ -11,11 +11,11 @@ It operates in two steps:
|
||||
2. Relocates the graphs and associated CSV files to your Klipper config folder for easy access via Mainsail/Fluidd to eliminate the need for SSH.
|
||||
3. Manages the folder by retaining only the most recent results (default setting of keeping the latest three sets).
|
||||
|
||||
The [detailed documentation is here](./docs/README.md).
|
||||
Check out the **[detailed documentation of the Shake&Tune module here](./docs/README.md)**. You can also look at the documentation for each type of graph by directly clicking on them below to better understand your results and tune your machine!
|
||||
|
||||
| Belts graphs | Axis graphs | Vibrations measurement |
|
||||
| [Belts graph](./docs/macros/belts_tuning.md) | [Axis input shaper graphs](./docs/macros/axis_tuning.md) | [Vibrations graph](./docs/macros/vibrations_tuning.md) |
|
||||
|:----------------:|:------------:|:---------------------:|
|
||||
|  |  |  |
|
||||
| [<img src="./docs/images/belts_example.png">](./docs/macros/belts_tuning.md) | [<img src="./docs/images/axis_example.png">](./docs/macros/axis_tuning.md) | [<img src="./docs/images/vibrations_example.png">](./docs/macros/vibrations_tuning.md) |
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
# Klippain Shake&Tune module documentation
|
||||
|
||||

|
||||
|
||||
### Detailed documentation
|
||||
|
||||
1. [Input Shaping and tuning generalities](./is_tuning_generalities.md)
|
||||
1. [Belt graphs](./macros/belts_tuning.md)
|
||||
1. [Axis Input Shaper graphs](./macros/axis_tuning.md)
|
||||
1. [Klippain vibrations graphs](./macros/vibrations_tuning.md)
|
||||
First, check out **[input shaping and tuning generalities](./is_tuning_generalities.md)** to understand how it all works and what to look for when taking these measurements.
|
||||
Then look at the documentation for each type of graph by clicking on them below to better understand your results and tune your machine!
|
||||
|
||||
| [Belts graph](./macros/belts_tuning.md) | [Axis input shaper graphs](./macros/axis_tuning.md) | [Vibrations graph](./macros/vibrations_tuning.md) |
|
||||
|:----------------:|:------------:|:---------------------:|
|
||||
| [<img src="./images/belts_example.png">](./macros/belts_tuning.md) | [<img src="./images/axis_example.png">](./macros/axis_tuning.md) | [<img src="./images/vibrations_example.png">](./macros/vibrations_tuning.md) |
|
||||
|
||||

|
||||
|
||||
### Complementary ressources
|
||||
|
||||
|
||||
BIN
docs/banner_long.png
Normal file
BIN
docs/banner_long.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 740 KiB |
@@ -17,6 +17,7 @@ Call the `VIBRATIONS_CALIBRATION` macro with the direction and speed range you w
|
||||
|DIRECTION|"XY"|direction vector where you want to do the measurements. Can be set to either "XY", "AB", "ABXY", "A", "B", "X", "Y", "Z", "E"|
|
||||
|Z_HEIGHT|20|z height to put the toolhead before starting the movements. Be careful, if your ADXL is under the nozzle, increase it to avoid a crash of the ADXL on the bed of the machine|
|
||||
|VERBOSE|1|Wether to log the current speed in the console|
|
||||
|ACCEL|3000 (or max printer accel)|accel in mm/s^2 used for all the moves. Try to keep it relatively low to avoid bad oscillations that affect the measurements, but but high enough to reach constant speed for >~70% of the segments|
|
||||
|MIN_SPEED|20|minimum speed of the toolhead in mm/s for the movements|
|
||||
|MAX_SPEED|200|maximum speed of the toolhead in mm/s for the movements|
|
||||
|SPEED_INCREMENT|2|speed increments of the toolhead in mm/s between every movements|
|
||||
|
||||
Reference in New Issue
Block a user