adjusted the symmetry score computation in vibration analysis
This commit is contained in:
@@ -152,35 +152,36 @@ def compute_speed_powers(spectrogram_data, smoothing_window=15):
|
|||||||
return min_values_smooth, max_values_smooth, avg_values_smooth, composite_variance_smooth
|
return min_values_smooth, max_values_smooth, avg_values_smooth, composite_variance_smooth
|
||||||
|
|
||||||
|
|
||||||
# This function uses a nuanced approach to allow the computation of a score that reflect both the shape
|
# This function allow the computation of a symmetry score that reflect the spectrogram apparent symmetry between
|
||||||
# similarity of a signal (via cross-correlation) and the energy level consistency across the signal
|
# measured axes on both the shape of the signal and the energy level consistency across both side of the signal
|
||||||
def compute_symmetry_analysis(all_angles, angles_energy):
|
def compute_symmetry_analysis(all_angles, spectrogram_data, measured_angles=[0, 90]):
|
||||||
# Split the signal in half
|
total_angles = len(all_angles)
|
||||||
first_half_indices = (0 <= all_angles) & (all_angles < 90)
|
angles_per_degree = total_angles / 360
|
||||||
second_half_indices = (90 <= all_angles) & (all_angles < 180)
|
midpoint_angle = np.mean(measured_angles)
|
||||||
x1, y1 = all_angles[first_half_indices], angles_energy[first_half_indices]
|
|
||||||
x2, y2 = all_angles[second_half_indices], angles_energy[second_half_indices]
|
|
||||||
|
|
||||||
# Reverse the second signal to compare them on a real symmetry
|
# Extend the spectrogram by adding half to the beginning (in order to not get an out of bounds error later)
|
||||||
x2, y2 = x2[::-1], y2[::-1]
|
half_spectrogram_length = total_angles // 2
|
||||||
|
extended_spectrogram = np.concatenate((spectrogram_data[-half_spectrogram_length:],
|
||||||
|
spectrogram_data), axis=0)
|
||||||
|
|
||||||
# Compute the similarity (using cross-correlation of the signals)
|
# Calculate the split index in center part of the extended spectrogram and get the segments bounds
|
||||||
similarity_factor = compute_curve_similarity_factor(x1, y1, x2, y2, CURVE_SIMILARITY_SIGMOID_K)
|
split_index = int(midpoint_angle * angles_per_degree + half_spectrogram_length)
|
||||||
|
start_index = split_index - half_spectrogram_length // 2
|
||||||
|
end_index = split_index + half_spectrogram_length // 2
|
||||||
|
|
||||||
# Because the signal of both half have approximately the same shape, this is not enough and we need to
|
# Slice out the two segments for comparison and flatten them for comparison
|
||||||
# add the total energy of each side in the equation to help discriminate differences in the symmetry
|
segment_1 = extended_spectrogram[start_index:split_index]
|
||||||
energy_first_half = np.sum(y1**2)
|
segment_2 = extended_spectrogram[split_index:end_index]
|
||||||
energy_second_half = np.sum(y2**2)
|
segment_1_flattened = segment_1.flatten()
|
||||||
energy_gap = np.abs(energy_first_half/energy_second_half - 1)
|
segment_2_flattened = segment_2.flatten()
|
||||||
|
|
||||||
# Compute an adjustement factor where close energies slightly increase the score and farther energies decrease the score
|
# Compute the correlation coefficient between the two halves of spectrogram
|
||||||
if energy_gap <= 0.1: adjustment_factor = 1 + energy_gap
|
correlation = np.corrcoef(segment_1_flattened, segment_2_flattened)[0, 1]
|
||||||
else: adjustment_factor = 1 / (1 + 3 * (energy_gap - 0.1))
|
adjusted_correlation = np.power(correlation, 0.75)
|
||||||
|
percentage_correlation_biased = (100 * adjusted_correlation) + 10
|
||||||
|
|
||||||
|
return np.clip(0, 100, percentage_correlation_biased)
|
||||||
|
|
||||||
# Adjust the similarity factor with the energy disparity
|
|
||||||
adjusted_similarity_factor = similarity_factor * adjustment_factor
|
|
||||||
|
|
||||||
return np.clip(adjusted_similarity_factor, 0, 100)
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Graphing
|
# Graphing
|
||||||
@@ -442,7 +443,8 @@ def vibrations_profile(lognames, klipperdir="~/klipper", kinematics="cartesian",
|
|||||||
sp_min_energy, sp_max_energy, sp_avg_energy, sp_composite_variance = compute_speed_powers(spectrogram_data)
|
sp_min_energy, sp_max_energy, sp_avg_energy, sp_composite_variance = compute_speed_powers(spectrogram_data)
|
||||||
motor_profiles, global_motor_profile = compute_motor_profiles(target_freqs, psds, all_angles_energy, main_angles)
|
motor_profiles, global_motor_profile = compute_motor_profiles(target_freqs, psds, all_angles_energy, main_angles)
|
||||||
|
|
||||||
symmetry_factor = compute_symmetry_analysis(all_angles, all_angles_energy)
|
# symmetry_factor = compute_symmetry_analysis(all_angles, all_angles_energy)
|
||||||
|
symmetry_factor = compute_symmetry_analysis(all_angles, spectrogram_data, main_angles)
|
||||||
print_with_c_locale(f"Machine estimated vibration symmetry: {symmetry_factor:.1f}%")
|
print_with_c_locale(f"Machine estimated vibration symmetry: {symmetry_factor:.1f}%")
|
||||||
|
|
||||||
# Analyze low variance ranges of vibration energy across all angles for each speed to identify clean speeds
|
# Analyze low variance ranges of vibration energy across all angles for each speed to identify clean speeds
|
||||||
|
|||||||
Reference in New Issue
Block a user