Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5366ad0581 | ||
|
|
77bfc7ca42 | ||
|
|
ce0330a9d1 | ||
|
|
358773ddef | ||
|
|
d0930261f7 | ||
|
|
a03a3c2e4b | ||
|
|
c102d4145c | ||
|
|
c39f0fe781 | ||
|
|
6742a785d3 |
@@ -28,10 +28,6 @@ import locale
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
matplotlib.use('Agg')
|
matplotlib.use('Agg')
|
||||||
try:
|
|
||||||
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
|
||||||
except locale.Error:
|
|
||||||
locale.setlocale(locale.LC_TIME, 'C')
|
|
||||||
|
|
||||||
|
|
||||||
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" # For paired peaks names
|
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" # For paired peaks names
|
||||||
@@ -54,6 +50,22 @@ KLIPPAIN_COLORS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Set the best locale for time and date formating (generation of the titles)
|
||||||
|
try:
|
||||||
|
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
||||||
|
except locale.Error:
|
||||||
|
locale.setlocale(locale.LC_TIME, 'C')
|
||||||
|
|
||||||
|
# Override the built-in print function to avoid problem in Klipper due to locale settings
|
||||||
|
original_print = print
|
||||||
|
def print_with_c_locale(*args, **kwargs):
|
||||||
|
original_locale = locale.setlocale(locale.LC_ALL, None)
|
||||||
|
locale.setlocale(locale.LC_ALL, 'C')
|
||||||
|
original_print(*args, **kwargs)
|
||||||
|
locale.setlocale(locale.LC_ALL, original_locale)
|
||||||
|
print = print_with_c_locale
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Computation of the PSD graph
|
# Computation of the PSD graph
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -330,15 +342,15 @@ def compute_mhi(combined_data, similarity_coefficient, num_unpaired_peaks):
|
|||||||
def mhi_lut(mhi):
|
def mhi_lut(mhi):
|
||||||
if 0 <= mhi <= 30:
|
if 0 <= mhi <= 30:
|
||||||
return "Excellent mechanical health"
|
return "Excellent mechanical health"
|
||||||
elif 31 <= mhi <= 45:
|
elif 30 < mhi <= 45:
|
||||||
return "Good mechanical health"
|
return "Good mechanical health"
|
||||||
elif 46 <= mhi <= 55:
|
elif 45 < mhi <= 55:
|
||||||
return "Acceptable mechanical health"
|
return "Acceptable mechanical health"
|
||||||
elif 56 <= mhi <= 70:
|
elif 55 < mhi <= 70:
|
||||||
return "Potential signs of a mechanical issue"
|
return "Potential signs of a mechanical issue"
|
||||||
elif 71 <= mhi <= 85:
|
elif 70 < mhi <= 85:
|
||||||
return "Likely a mechanical issue"
|
return "Likely a mechanical issue"
|
||||||
elif 86 <= mhi <= 100:
|
elif 85 < mhi <= 100:
|
||||||
return "Mechanical issue detected"
|
return "Mechanical issue detected"
|
||||||
|
|
||||||
|
|
||||||
@@ -570,11 +582,15 @@ def belts_calibration(lognames, klipperdir="~/klipper", max_freq=200.):
|
|||||||
ax2 = fig.add_subplot(gs[1])
|
ax2 = fig.add_subplot(gs[1])
|
||||||
|
|
||||||
# Add title
|
# Add title
|
||||||
filename = lognames[0].split('/')[-1]
|
|
||||||
dt = datetime.strptime(f"{filename.split('_')[1]} {filename.split('_')[2]}", "%Y%m%d %H%M%S")
|
|
||||||
title_line1 = "RELATIVE BELT CALIBRATION TOOL"
|
title_line1 = "RELATIVE BELT CALIBRATION TOOL"
|
||||||
title_line2 = dt.strftime('%x %X')
|
|
||||||
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
||||||
|
try:
|
||||||
|
filename = lognames[0].split('/')[-1]
|
||||||
|
dt = datetime.strptime(f"{filename.split('_')[1]} {filename.split('_')[2]}", "%Y%m%d %H%M%S")
|
||||||
|
title_line2 = dt.strftime('%x %X')
|
||||||
|
except:
|
||||||
|
print("Warning: CSV filenames look to be different than expected (%s , %s)" % (lognames[0], lognames[1]))
|
||||||
|
title_line2 = lognames[0].split('/')[-1] + " / " + lognames[1].split('/')[-1]
|
||||||
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
||||||
|
|
||||||
# Plot the graphs
|
# Plot the graphs
|
||||||
|
|||||||
@@ -35,15 +35,12 @@ import locale
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
matplotlib.use('Agg')
|
matplotlib.use('Agg')
|
||||||
try:
|
|
||||||
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
|
||||||
except locale.Error:
|
|
||||||
locale.setlocale(locale.LC_TIME, 'C')
|
|
||||||
|
|
||||||
|
|
||||||
PEAKS_DETECTION_THRESHOLD = 0.05
|
PEAKS_DETECTION_THRESHOLD = 0.05
|
||||||
PEAKS_EFFECT_THRESHOLD = 0.12
|
PEAKS_EFFECT_THRESHOLD = 0.12
|
||||||
SPECTROGRAM_LOW_PERCENTILE_FILTER = 5
|
SPECTROGRAM_LOW_PERCENTILE_FILTER = 5
|
||||||
|
MAX_SMOOTHING = 0.1
|
||||||
|
|
||||||
KLIPPAIN_COLORS = {
|
KLIPPAIN_COLORS = {
|
||||||
"purple": "#70088C",
|
"purple": "#70088C",
|
||||||
@@ -52,6 +49,22 @@ KLIPPAIN_COLORS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Set the best locale for time and date formating (generation of the titles)
|
||||||
|
try:
|
||||||
|
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
||||||
|
except locale.Error:
|
||||||
|
locale.setlocale(locale.LC_TIME, 'C')
|
||||||
|
|
||||||
|
# Override the built-in print function to avoid problem in Klipper due to locale settings
|
||||||
|
original_print = print
|
||||||
|
def print_with_c_locale(*args, **kwargs):
|
||||||
|
original_locale = locale.setlocale(locale.LC_ALL, None)
|
||||||
|
locale.setlocale(locale.LC_ALL, 'C')
|
||||||
|
original_print(*args, **kwargs)
|
||||||
|
locale.setlocale(locale.LC_ALL, original_locale)
|
||||||
|
print = print_with_c_locale
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Computation
|
# Computation
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -73,7 +86,7 @@ def calibrate_shaper_with_damping(datas, max_smoothing):
|
|||||||
fr, zeta = compute_damping_ratio(psd, freqs)
|
fr, zeta = compute_damping_ratio(psd, freqs)
|
||||||
|
|
||||||
print("Recommended shaper is %s @ %.1f Hz" % (shaper.name, shaper.freq))
|
print("Recommended shaper is %s @ %.1f Hz" % (shaper.name, shaper.freq))
|
||||||
print("Axis has a resonant frequency ω0=%.1fHz with an estimated damping ratio ζ=%.3f" % (fr, zeta))
|
print("Axis has a main resonant frequency at %.1fHz with an estimated damping ratio of %.3f" % (fr, zeta))
|
||||||
|
|
||||||
return shaper.name, all_shapers, calibration_data, fr, zeta
|
return shaper.name, all_shapers, calibration_data, fr, zeta
|
||||||
|
|
||||||
@@ -182,9 +195,10 @@ def plot_freq_response_with_damping(ax, calibration_data, shapers, selected_shap
|
|||||||
ax2.yaxis.set_visible(False)
|
ax2.yaxis.set_visible(False)
|
||||||
|
|
||||||
best_shaper_vals = None
|
best_shaper_vals = None
|
||||||
no_vibr_shaper = None
|
lowest_vibration = float('inf')
|
||||||
no_vibr_shaper_freq = None
|
lowest_vibration_shaper = None
|
||||||
no_vibr_shaper_accel = 0
|
lowest_vibration_shaper_freq = None
|
||||||
|
lowest_vibration_shaper_accel = 0
|
||||||
|
|
||||||
# Draw the shappers curves and add their specific parameters in the legend
|
# 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 0% of vibrations (to be printed in the legend later)
|
||||||
@@ -199,10 +213,11 @@ def plot_freq_response_with_damping(ax, calibration_data, shapers, selected_shap
|
|||||||
linestyle = 'dashdot'
|
linestyle = 'dashdot'
|
||||||
selected_shaper_freq = shaper.freq
|
selected_shaper_freq = shaper.freq
|
||||||
best_shaper_vals = shaper.vals
|
best_shaper_vals = shaper.vals
|
||||||
if (shaper.vibrs * 100 == 0.) and (shaper_max_accel > no_vibr_shaper_accel):
|
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:
|
||||||
no_vibr_shaper_accel = shaper_max_accel
|
lowest_vibration = shaper.vibrs * 100
|
||||||
no_vibr_shaper = shaper.name
|
lowest_vibration_shaper_accel = shaper_max_accel
|
||||||
no_vibr_shaper_freq = shaper.freq
|
lowest_vibration_shaper = shaper.name
|
||||||
|
lowest_vibration_shaper_freq = shaper.freq
|
||||||
ax2.plot(freqs, shaper.vals, label=label, linestyle=linestyle)
|
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')
|
ax.plot(freqs, psd * best_shaper_vals, label='With %s applied' % (selected_shaper.upper()), color='cyan')
|
||||||
|
|
||||||
@@ -228,9 +243,17 @@ 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, 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')
|
ax.fill_between(freqs, peaks_warning_threshold, peaks_effect_threshold, color='orange', alpha=0.2, label='Warning Region')
|
||||||
|
|
||||||
# Final user recommendations added to the legend with an added 0% vibration shaper and the estimated damping ratio over stock Klipper's algorithms
|
# User recommendations are added to the legend: one is Klipper's original suggestion that is usually good for performances
|
||||||
ax2.plot([], [], ' ', label="Recommended shaper: %s @ %.1f Hz" % (selected_shaper.upper(), selected_shaper_freq))
|
# and the other one is the custom "low vibration" recommendation that looks for a suitable shaper that doesn't have excessive
|
||||||
ax2.plot([], [], ' ', label="Recommended low vibrations shaper: %s @ %.1f Hz" % (no_vibr_shaper.upper(), no_vibr_shaper_freq))
|
# 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))
|
ax2.plot([], [], ' ', label="Estimated damping ratio (ζ): %.3f" % (zeta))
|
||||||
|
|
||||||
# Add the main resonant frequency and damping ratio of the axis to the graph title
|
# Add the main resonant frequency and damping ratio of the axis to the graph title
|
||||||
@@ -311,11 +334,15 @@ def shaper_calibration(lognames, klipperdir="~/klipper", max_smoothing=None, max
|
|||||||
ax2 = fig.add_subplot(gs[1])
|
ax2 = fig.add_subplot(gs[1])
|
||||||
|
|
||||||
# Add title
|
# Add title
|
||||||
filename_parts = (lognames[0].split('/')[-1]).split('_')
|
|
||||||
dt = datetime.strptime(f"{filename_parts[3]} {filename_parts[4].split('.')[0]}", "%Y%m%d %H%M%S")
|
|
||||||
title_line1 = "INPUT SHAPER CALIBRATION TOOL"
|
title_line1 = "INPUT SHAPER CALIBRATION TOOL"
|
||||||
title_line2 = dt.strftime('%x %X') + ' -- ' + filename_parts[2].upper() + ' axis'
|
|
||||||
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
||||||
|
try:
|
||||||
|
filename_parts = (lognames[0].split('/')[-1]).split('_')
|
||||||
|
dt = datetime.strptime(f"{filename_parts[1]} {filename_parts[2]}", "%Y%m%d %H%M%S")
|
||||||
|
title_line2 = dt.strftime('%x %X') + ' -- ' + filename_parts[3].upper().split('.')[0] + ' axis'
|
||||||
|
except:
|
||||||
|
print("Warning: CSV filename look to be different than expected (%s)" % (lognames[0]))
|
||||||
|
title_line2 = lognames[0].split('/')[-1]
|
||||||
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
||||||
|
|
||||||
# Plot the graphs
|
# Plot the graphs
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ import locale
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
matplotlib.use('Agg')
|
matplotlib.use('Agg')
|
||||||
try:
|
|
||||||
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
|
||||||
except locale.Error:
|
|
||||||
locale.setlocale(locale.LC_TIME, 'C')
|
|
||||||
|
|
||||||
|
|
||||||
PEAKS_DETECTION_THRESHOLD = 0.05
|
PEAKS_DETECTION_THRESHOLD = 0.05
|
||||||
@@ -46,6 +42,22 @@ KLIPPAIN_COLORS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Set the best locale for time and date formating (generation of the titles)
|
||||||
|
try:
|
||||||
|
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale())
|
||||||
|
except locale.Error:
|
||||||
|
locale.setlocale(locale.LC_TIME, 'C')
|
||||||
|
|
||||||
|
# Override the built-in print function to avoid problem in Klipper due to locale settings
|
||||||
|
original_print = print
|
||||||
|
def print_with_c_locale(*args, **kwargs):
|
||||||
|
original_locale = locale.setlocale(locale.LC_ALL, None)
|
||||||
|
locale.setlocale(locale.LC_ALL, 'C')
|
||||||
|
original_print(*args, **kwargs)
|
||||||
|
locale.setlocale(locale.LC_ALL, original_locale)
|
||||||
|
print = print_with_c_locale
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Computation
|
# Computation
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -348,7 +360,7 @@ def setup_klipper_import(kdir):
|
|||||||
shaper_calibrate = importlib.import_module('.shaper_calibrate', 'extras')
|
shaper_calibrate = importlib.import_module('.shaper_calibrate', 'extras')
|
||||||
|
|
||||||
|
|
||||||
def vibrations_calibration(lognames, klipperdir="~/klipper", axisname=None, max_freq=200., remove=0):
|
def vibrations_calibration(lognames, klipperdir="~/klipper", axisname=None, max_freq=1000., remove=0):
|
||||||
setup_klipper_import(klipperdir)
|
setup_klipper_import(klipperdir)
|
||||||
|
|
||||||
# Parse the raw data and get them ready for analysis
|
# Parse the raw data and get them ready for analysis
|
||||||
@@ -368,11 +380,15 @@ def vibrations_calibration(lognames, klipperdir="~/klipper", axisname=None, max_
|
|||||||
ax1 = fig.add_subplot(gs[0])
|
ax1 = fig.add_subplot(gs[0])
|
||||||
ax2 = fig.add_subplot(gs[1])
|
ax2 = fig.add_subplot(gs[1])
|
||||||
|
|
||||||
filename_parts = (lognames[0].split('/')[-1]).split('_')
|
|
||||||
dt = datetime.strptime(f"{filename_parts[1]} {filename_parts[2].split('-')[0]}", "%Y%m%d %H%M%S")
|
|
||||||
title_line1 = "VIBRATIONS MEASUREMENT TOOL"
|
title_line1 = "VIBRATIONS MEASUREMENT TOOL"
|
||||||
title_line2 = dt.strftime('%x %X') + ' -- ' + axisname.upper() + ' axis'
|
|
||||||
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
fig.text(0.12, 0.965, title_line1, ha='left', va='bottom', fontsize=20, color=KLIPPAIN_COLORS['purple'], weight='bold')
|
||||||
|
try:
|
||||||
|
filename_parts = (lognames[0].split('/')[-1]).split('_')
|
||||||
|
dt = datetime.strptime(f"{filename_parts[1]} {filename_parts[2].split('-')[0]}", "%Y%m%d %H%M%S")
|
||||||
|
title_line2 = dt.strftime('%x %X') + ' -- ' + axisname.upper() + ' axis'
|
||||||
|
except:
|
||||||
|
print("Warning: CSV filename look to be different than expected (%s)" % (lognames[0]))
|
||||||
|
title_line2 = lognames[0].split('/')[-1]
|
||||||
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
fig.text(0.12, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
||||||
|
|
||||||
# Remove speeds duplicates and graph the processed datas
|
# Remove speeds duplicates and graph the processed datas
|
||||||
|
|||||||
@@ -63,7 +63,16 @@ def get_belts_graph():
|
|||||||
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
lognames = []
|
lognames = []
|
||||||
|
|
||||||
for filename in glob.glob('/tmp/raw_data_axis*.csv'):
|
globbed_files = glob.glob('/tmp/raw_data_axis*.csv')
|
||||||
|
if not globbed_files:
|
||||||
|
print("No CSV files found in the /tmp folder to create the belt graphs!")
|
||||||
|
sys.exit(1)
|
||||||
|
if len(globbed_files) < 2:
|
||||||
|
print("Not enough CSV files found in the /tmp folder. Two files are required for the belt graphs!")
|
||||||
|
sys.exit(1)
|
||||||
|
sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True)
|
||||||
|
|
||||||
|
for filename in sorted_files[:2]:
|
||||||
# Wait for the file handler to be released by Klipper
|
# Wait for the file handler to be released by Klipper
|
||||||
while is_file_open(filename):
|
while is_file_open(filename):
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
@@ -86,13 +95,13 @@ def get_belts_graph():
|
|||||||
def get_shaper_graph():
|
def get_shaper_graph():
|
||||||
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
|
|
||||||
|
# Get all the files and sort them based on last modified time to select the most recent one
|
||||||
globbed_files = glob.glob('/tmp/raw_data*.csv')
|
globbed_files = glob.glob('/tmp/raw_data*.csv')
|
||||||
if len(globbed_files) > 1:
|
if not globbed_files:
|
||||||
print("There is more than 1 measurement.csv found in the /tmp folder. Unable to plot the shaper graphs!")
|
print("No CSV files found in the /tmp folder to create the input shaper graphs!")
|
||||||
print("Please clean the files in the /tmp folder and start again.")
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
sorted_files = sorted(globbed_files, key=os.path.getmtime, reverse=True)
|
||||||
filename = globbed_files[0]
|
filename = sorted_files[0]
|
||||||
|
|
||||||
# Wait for the file handler to be released by Klipper
|
# Wait for the file handler to be released by Klipper
|
||||||
while is_file_open(filename):
|
while is_file_open(filename):
|
||||||
@@ -114,7 +123,15 @@ def get_vibrations_graph(axis_name):
|
|||||||
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
lognames = []
|
lognames = []
|
||||||
|
|
||||||
for filename in glob.glob('/tmp/adxl345-*.csv'):
|
globbed_files = glob.glob('/tmp/adxl345-*.csv')
|
||||||
|
if not globbed_files:
|
||||||
|
print("No CSV files found in the /tmp folder to create the vibration graphs!")
|
||||||
|
sys.exit(1)
|
||||||
|
if len(globbed_files) < 3:
|
||||||
|
print("Not enough CSV files found in the /tmp folder. At least 3 files are required for the vibration graphs!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for filename in globbed_files:
|
||||||
# Wait for the file handler to be released by Klipper
|
# Wait for the file handler to be released by Klipper
|
||||||
while is_file_open(filename):
|
while is_file_open(filename):
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|||||||
@@ -40,11 +40,15 @@ For those not using the full [Klippain](https://github.com/Frix-x/klippain), fol
|
|||||||
install_script: install.sh
|
install_script: install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**:
|
||||||
|
>
|
||||||
|
> If already using my old IS workflow scripts, please remove everything before installing this new module. This include the macros, the Python scripts, the `plot_graph.sh` and the `[gcode_shell_command plot_graph]` section.
|
||||||
|
|
||||||
## 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:
|
||||||
- `BELTS_SHAPER_CALIBRATION` for belt resonance graphs, useful for verifying belt tension and differential belt paths behavior.
|
- `BELTS_SHAPER_CALIBRATION` for belt resonance graphs, useful for verifying belt tension and differential belt paths behavior.
|
||||||
- `AXES_SHAPER_CALIBRATION` for input shaper graphs to mitigate ringing/ghosting by tuning Klipper's `[input_shaper]` system.
|
- `AXES_SHAPER_CALIBRATION` for input shaper graphs to mitigate ringing/ghosting by tuning Klipper's input shaper system.
|
||||||
- `VIBRATIONS_CALIBRATION` for machine vibration graphs to optimize your slicer speed profiles.
|
- `VIBRATIONS_CALIBRATION` for machine vibration graphs to optimize your slicer speed profiles.
|
||||||
- `EXCITATE_AXIS_AT_FREQ` to sustain a specific excitation frequency, useful to let you inspect and find out what is resonating.
|
- `EXCITATE_AXIS_AT_FREQ` to sustain a specific excitation frequency, useful to let you inspect and find out what is resonating.
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ For setting your Input Shaping filters, rely on the auto-computed values display
|
|||||||
* `2HUMP_EI` and `3HUMP_EI` are last-resort choices. Usually, they lead to a high level of smoothing in order to suppress the ringing while also using relatively low acceleration values. If they pop up as suggestions, it's likely your machine has underlying mechanical issues (that lead to pretty bad or "wide" graphs).
|
* `2HUMP_EI` and `3HUMP_EI` are last-resort choices. Usually, they lead to a high level of smoothing in order to suppress the ringing while also using relatively low acceleration values. If they pop up as suggestions, it's likely your machine has underlying mechanical issues (that lead to pretty bad or "wide" graphs).
|
||||||
- **Recommended Acceleration** (`accel<=...`): This isn't a standalone figure. It's essential to also consider the `vibr` and `sm` values as it's a compromise between the three. They will give you the percentage of remaining vibrations and the smoothing after Input Shaping, when using the recommended acceleration. Nothing will prevent you from using higher acceleration values; they are not a limit. However, when doing so, Input Shaping may not be able to suppress all the ringing on your parts. Finally, keep in mind that high acceleration values are not useful at all if there is still a high level of remaining vibrations: you should address any mechanical issues first.
|
- **Recommended Acceleration** (`accel<=...`): This isn't a standalone figure. It's essential to also consider the `vibr` and `sm` values as it's a compromise between the three. They will give you the percentage of remaining vibrations and the smoothing after Input Shaping, when using the recommended acceleration. Nothing will prevent you from using higher acceleration values; they are not a limit. However, when doing so, Input Shaping may not be able to suppress all the ringing on your parts. Finally, keep in mind that high acceleration values are not useful at all if there is still a high level of remaining vibrations: you should address any mechanical issues first.
|
||||||
- **The remaining vibrations** (`vibr`): This directly correlates with ringing. It correspond to the total value of the blue "after shaper" signal. Ideally, you want a filter with minimal or zero vibrations.
|
- **The remaining vibrations** (`vibr`): This directly correlates with ringing. It correspond to the total value of the blue "after shaper" signal. Ideally, you want a filter with minimal or zero vibrations.
|
||||||
- **Shaper recommendations**: This script will give you two recommandation. Pick the one that suit your needs:
|
- **Shaper recommendations**: This script will give you some tailored recommendations based on your graphs. Pick the one that suit your needs:
|
||||||
* The first is Klipper's original suggestion, for best performance and acceleration on your machine while also allowing a little bit of remaining vibrations.
|
* The "performance" shaper is Klipper's original suggestion that is good for high acceleration while also sometimes allowing a little bit of remaining vibrations. Use it if your goal is speed printing and you don't care much about some remaining ringing.
|
||||||
* The second aims for no remaining vibration to ensure the best print quality.
|
* The "low vibration" shaper aims for the lowest level of remaining vibration to ensure the best print quality with minimal ringing. This should be the best bet for most users.
|
||||||
- The final line provides the estimated damping ratio for the axis. This value is generated automatically and is only accurate if the graph displays a clear and well detached single peak.
|
* Sometimes, only a single recommendation called "best" shaper is presented. This means that either no suitable "low vibration" shaper was found (due to a high level of vibration or with too much smoothing) or because the "performance" shaper is also the one with the lowest vibration level.
|
||||||
- **Damping Ratio**: Displayed at the end, this estimatation is only reliable when the graph shows a distinct, standalone and clean peak. On a well tuned machine, setting the damping ratio (instead of Klipper's 0.1 default value) can further reduce the ringing at high accelerations and with higher square corner velocities.
|
- **Damping Ratio**: Displayed at the end, this estimatation is only reliable when the graph shows a distinct, standalone and clean peak. On a well tuned machine, setting the damping ratio (instead of Klipper's 0.1 default value) can further reduce the ringing at high accelerations and with higher square corner velocities.
|
||||||
|
|
||||||
Then, add to your configuration:
|
Then, add to your configuration:
|
||||||
|
|||||||
Reference in New Issue
Block a user