adjusted MHI calculation
This commit is contained in:
@@ -94,29 +94,40 @@ def pair_peaks(peaks1, freqs1, psd1, peaks2, freqs2, psd2):
|
|||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
|
||||||
def compute_mhi(similarity_coefficient, total_num_peaks, num_unpaired_peaks):
|
def compute_mhi(similarity_factor, signal1, signal2):
|
||||||
# Start with the similarity coefficient directly scaled to a percentage
|
num_unpaired_peaks = len(signal1.unpaired_peaks) + len(signal2.unpaired_peaks)
|
||||||
base_percentage = similarity_coefficient
|
num_paired_peaks = len(signal1.paired_peaks)
|
||||||
|
# Combine unpaired peaks from both signals, tagging each peak with its respective signal
|
||||||
|
combined_unpaired_peaks = [(peak, signal1) for peak in signal1.unpaired_peaks] + [
|
||||||
|
(peak, signal2) for peak in signal2.unpaired_peaks
|
||||||
|
]
|
||||||
|
psd_highest_max = max(signal1.psd.max(), signal2.psd.max())
|
||||||
|
|
||||||
|
# Iterate over the combined list of unpaired peaks
|
||||||
|
for peak, signal in combined_unpaired_peaks:
|
||||||
|
print(
|
||||||
|
f'Unpaired peak in belt {"1" if signal is signal1 else "2"} at {signal.freqs[peak]:.1f} Hz ({signal.psd[peak]:.1f})'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Start with the similarity factor directly scaled to a percentage
|
||||||
|
mhi = similarity_factor
|
||||||
|
|
||||||
# Bonus for ideal number of total peaks (1 or 2)
|
# Bonus for ideal number of total peaks (1 or 2)
|
||||||
if total_num_peaks <= DC_MAX_PEAKS:
|
if num_paired_peaks >= DC_MAX_PEAKS:
|
||||||
peak_bonus = 1.1 # Boost by 10% if the number of peaks is ideal
|
mhi *= DC_MAX_PEAKS / num_paired_peaks # Reduce MHI if more than ideal number of peaks
|
||||||
else:
|
|
||||||
peak_bonus = DC_MAX_PEAKS / total_num_peaks # Reduce MHI if more than ideal number of peaks
|
|
||||||
|
|
||||||
adjusted_percentage = base_percentage * peak_bonus
|
# Penalty from unpaired peaks weighted by their amplitude relative to the maximum PSD amplitude
|
||||||
|
unpaired_peak_penalty = 0
|
||||||
# Heavy penalty for unpaired peaks
|
|
||||||
if num_unpaired_peaks > DC_MAX_UNPAIRED_PEAKS_ALLOWED:
|
if num_unpaired_peaks > DC_MAX_UNPAIRED_PEAKS_ALLOWED:
|
||||||
unpaired_peak_penalty = num_unpaired_peaks * 5 # Applying a strong penalty factor for each unpaired peak
|
for peak, signal in combined_unpaired_peaks:
|
||||||
final_percentage = adjusted_percentage - unpaired_peak_penalty
|
unpaired_peak_penalty += (signal.psd[peak] / psd_highest_max) * 30
|
||||||
else:
|
print(f'penality for peak {peak}: {(signal.psd[peak] / psd_highest_max) * 30}')
|
||||||
final_percentage = adjusted_percentage
|
mhi -= unpaired_peak_penalty
|
||||||
|
|
||||||
# Ensure the result lies between 0 and 100 by clipping the computed value
|
# Ensure the result lies between 0 and 100 by clipping the computed value
|
||||||
final_percentage = np.clip(final_percentage, 0, 100)
|
mhi = np.clip(mhi, 0, 100)
|
||||||
|
|
||||||
return mhi_lut(final_percentage)
|
return mhi_lut(mhi)
|
||||||
|
|
||||||
|
|
||||||
# LUT to transform the MHI into a textual value easy to understand for the users of the script
|
# LUT to transform the MHI into a textual value easy to understand for the users of the script
|
||||||
@@ -146,12 +157,6 @@ def plot_compare_frequency(ax, signal1, signal2, signal1_belt, signal2_belt, max
|
|||||||
ax.plot(signal1.freqs, signal1.psd, label='Belt ' + signal1_belt, color=KLIPPAIN_COLORS['purple'])
|
ax.plot(signal1.freqs, signal1.psd, label='Belt ' + signal1_belt, color=KLIPPAIN_COLORS['purple'])
|
||||||
ax.plot(signal2.freqs, signal2.psd, label='Belt ' + signal2_belt, color=KLIPPAIN_COLORS['orange'])
|
ax.plot(signal2.freqs, signal2.psd, label='Belt ' + signal2_belt, color=KLIPPAIN_COLORS['orange'])
|
||||||
|
|
||||||
# Trace the "relax region" (also used as a threshold to filter and detect the peaks)
|
|
||||||
psd_lowest_max = min(signal1.psd.max(), signal2.psd.max())
|
|
||||||
peaks_warning_threshold = 0.20 * psd_lowest_max
|
|
||||||
ax.axhline(y=peaks_warning_threshold, color='black', linestyle='--', linewidth=0.5)
|
|
||||||
ax.fill_between(signal1.freqs, 0, peaks_warning_threshold, color='green', alpha=0.15, label='Relax Region')
|
|
||||||
|
|
||||||
# Trace and annotate the peaks on the graph
|
# Trace and annotate the peaks on the graph
|
||||||
paired_peak_count = 0
|
paired_peak_count = 0
|
||||||
unpaired_peak_count = 0
|
unpaired_peak_count = 0
|
||||||
@@ -464,9 +469,8 @@ def belts_calibration(lognames, kinematics, klipperdir='~/klipper', max_freq=200
|
|||||||
similarity_factor = (1 - (ss_res / ss_tot)) * 100
|
similarity_factor = (1 - (ss_res / ss_tot)) * 100
|
||||||
print_with_c_locale(f'Belts estimated similarity: {similarity_factor:.1f}%')
|
print_with_c_locale(f'Belts estimated similarity: {similarity_factor:.1f}%')
|
||||||
|
|
||||||
num_unpaired_peaks = len(unpaired_peaks1) + len(unpaired_peaks2)
|
# mhi = compute_mhi(similarity_factor, num_peaks, num_unpaired_peaks)
|
||||||
num_peaks = len(paired_peaks) + num_unpaired_peaks
|
mhi = compute_mhi(similarity_factor, signal1, signal2)
|
||||||
mhi = compute_mhi(similarity_factor, num_peaks, num_unpaired_peaks)
|
|
||||||
print_with_c_locale(f'[experimental] Mechanical health: {mhi}')
|
print_with_c_locale(f'[experimental] Mechanical health: {mhi}')
|
||||||
|
|
||||||
fig, ((ax1, ax3)) = plt.subplots(
|
fig, ((ax1, ax3)) = plt.subplots(
|
||||||
|
|||||||
Reference in New Issue
Block a user