forked from zietzm/Helmholtz_Test_Bench
Added calibration export function for magnetometers.
This commit is contained in:
+15
-3
@@ -175,7 +175,7 @@ class CoilConstantCalibration(Thread):
|
||||
field = g.MAGNETOMETER.field
|
||||
field_diff_mag = np.linalg.norm(field - ambient_field)
|
||||
sign = 1 if field[i] - ambient_field[i] >= 0 else -1
|
||||
k =(field_diff_mag * sign) / c
|
||||
k = (field_diff_mag * sign) / c
|
||||
k_samples.append(k)
|
||||
|
||||
# Save vector as principal coil direction if it is the last sample with the largest positive current
|
||||
@@ -272,6 +272,10 @@ class MagnetometerCalibration(Thread):
|
||||
# Zikmund, A. & Janosek, Michal. (2014). Calibration procedure for triaxial magnetometers without a compensating
|
||||
# system or moving parts.
|
||||
|
||||
# This contains the raw experiment data for exporting
|
||||
# Each row is a dict containing the applied vector and measured vector
|
||||
raw_data = []
|
||||
|
||||
# Find sensor offsets. They must be found prior to applying the chosen calibration algorithm
|
||||
# This will be accurate if the cage was recently calibrated
|
||||
self.cage_dev.set_field_compensated([0, 0, 0])
|
||||
@@ -279,6 +283,9 @@ class MagnetometerCalibration(Thread):
|
||||
time.sleep(self.calibration_interval)
|
||||
# The offsets can easily be read from the magnetometer
|
||||
offsets = g.MAGNETOMETER.field
|
||||
# Save data point to raw_data list
|
||||
raw_data.append({'applied_x': 0, 'applied_y': 0, 'applied_z': 0,
|
||||
'measured_x': offsets[0], 'measured_y': offsets[1], 'measured_z': offsets[2]})
|
||||
# Set new progress indicator for UI
|
||||
self.set_progress(True, 0)
|
||||
|
||||
@@ -299,12 +306,17 @@ class MagnetometerCalibration(Thread):
|
||||
time.sleep(self.calibration_interval)
|
||||
|
||||
# Read output and save to array for solver later
|
||||
reading = g.MAGNETOMETER.field - offsets
|
||||
raw_reading = g.MAGNETOMETER.field
|
||||
reading = raw_reading - offsets
|
||||
for i in range(3):
|
||||
row = {'m': reading[i], 'b_x': applied_vec[0], 'b_y': applied_vec[1], 'b_z': applied_vec[2]}
|
||||
# print("[Axis {}] {}".format(i, row))
|
||||
samples[i].append(row)
|
||||
|
||||
# Save data point to raw_data list
|
||||
raw_data.append({'applied_x': applied_vec[0], 'applied_y': applied_vec[1], 'applied_z': applied_vec[2],
|
||||
'measured_x': raw_reading[0], 'measured_y': raw_reading[1], 'measured_z': raw_reading[2]})
|
||||
|
||||
# Set new progress indicator for UI
|
||||
self.set_progress(True, vec_idx + 1)
|
||||
|
||||
@@ -315,7 +327,7 @@ class MagnetometerCalibration(Thread):
|
||||
sensor_parameters = self.solve_system(samples, offsets)
|
||||
|
||||
# Pass results to UI
|
||||
self.put_message('calibration_data', sensor_parameters)
|
||||
self.put_message('calibration_data', {'results': sensor_parameters, 'raw_data': raw_data})
|
||||
|
||||
def set_progress(self, offset_complete, test_vec_index):
|
||||
progress = int(offset_complete) * 0.2 + (test_vec_index / self.calibration_points) * 0.8
|
||||
|
||||
+60
-2
@@ -686,7 +686,7 @@ class CalibrateAmbientField(Frame):
|
||||
command=self.save_and_apply_ambient_calibration,
|
||||
state="disabled")
|
||||
self.ambient_field_save_results_button.grid(row=0, column=0, padx=5, pady=5)
|
||||
self.save_ambient_calibration_button = Button(save_ambient_field_results_frame, text="Export to CSV",
|
||||
self.save_ambient_calibration_button = Button(save_ambient_field_results_frame, text="Export raw CSV",
|
||||
command=self.save_to_csv_ambient_field,
|
||||
state="disabled",
|
||||
pady=5, padx=5)
|
||||
@@ -749,7 +749,7 @@ class CalibrateAmbientField(Frame):
|
||||
command=self.save_and_apply_coil_constants,
|
||||
state="disabled")
|
||||
self.coil_constant_save_results_button.grid(row=0, column=0, padx=5, pady=5)
|
||||
self.save_k_calibration_button = Button(save_coil_constant_results_frame, text="Export to CSV",
|
||||
self.save_k_calibration_button = Button(save_coil_constant_results_frame, text="Export raw CSV",
|
||||
command=self.save_to_csv_coil_constants,
|
||||
state="disabled",
|
||||
pady=5, padx=5)
|
||||
@@ -978,6 +978,8 @@ class CalibrateMagnetometer(Frame):
|
||||
self.angle_to_plane_result_vars = [StringVar(), StringVar(), StringVar()]
|
||||
self.angle_in_plane_result_vars = [StringVar(), StringVar(), StringVar()]
|
||||
self.residual_result_vars = [StringVar(), StringVar(), StringVar()]
|
||||
self.calibration_raw_results = None # Cached raw experiment data to allow for saving to csv.
|
||||
self.clipboard = "" # Clipboard string containing results
|
||||
|
||||
# UI Elements
|
||||
row_counter = 0
|
||||
@@ -1107,6 +1109,20 @@ class CalibrateMagnetometer(Frame):
|
||||
axis_data.grid(row=5, column=i + 1, padx=5, pady=5, sticky="nw")
|
||||
residual_unit = Label(calibration_results_frame, text="\u03BCT")
|
||||
residual_unit.grid(row=5, column=4, padx=5, pady=5, sticky="nw")
|
||||
# Save calibration buttons
|
||||
save_calibration_results_frame = Frame(calibration_results_frame)
|
||||
save_calibration_results_frame.grid(row=6, column=0, columnspan=5)
|
||||
# Save and apply
|
||||
self.export_calibration_button = Button(save_calibration_results_frame, text="Export raw to CSV",
|
||||
command=self.export_csv,
|
||||
state="disabled",
|
||||
pady=5, padx=5)
|
||||
self.export_calibration_button.grid(row=0, column=0, padx=5, pady=5)
|
||||
self.copy_calibration_button = Button(save_calibration_results_frame, text="Copy to clipboard",
|
||||
command=self.copy_to_clipboard,
|
||||
state="disabled",
|
||||
pady=5, padx=5)
|
||||
self.copy_calibration_button.grid(row=0, column=1, padx=5, pady=5)
|
||||
row_counter += 1
|
||||
|
||||
# This starts an endless polling loop
|
||||
@@ -1161,6 +1177,13 @@ class CalibrateMagnetometer(Frame):
|
||||
self.start_calibration_button.configure(text="Running...", state=DISABLED)
|
||||
|
||||
def display_calibration_results(self, results):
|
||||
# Cache raw experiment data for saving later
|
||||
self.calibration_raw_results = results['raw_data']
|
||||
|
||||
# Unpack the dict
|
||||
results = results['results']
|
||||
|
||||
# Display calibration in GUI
|
||||
for i in range(3):
|
||||
self.sensitivity_result_vars[i].set("{:.3f}".format(results[i]['sensitivity']))
|
||||
self.offset_result_vars[i].set("{:.3f}".format(results[i]['offset'] * 1e6))
|
||||
@@ -1168,6 +1191,28 @@ class CalibrateMagnetometer(Frame):
|
||||
self.angle_in_plane_result_vars[i].set("{:.3f}".format(results[i]['beta'] * 180/pi))
|
||||
self.residual_result_vars[i].set("{:.3e}".format(results[i]['residual'] * 1e6))
|
||||
|
||||
# Populate clipboard string
|
||||
self.clipboard = "\tX\tY\tZ\n"
|
||||
self.clipboard += "Sensitivity [-]"
|
||||
for i in range(3):
|
||||
self.clipboard += "\t{:.3f}".format(results[i]['sensitivity'])
|
||||
self.clipboard += "\nOffset [uT]"
|
||||
for i in range(3):
|
||||
self.clipboard += "\t{:.3f}".format(results[i]['offset'] * 1e6)
|
||||
self.clipboard += "\nAngle to XY Plane [deg]"
|
||||
for i in range(3):
|
||||
self.clipboard += "\t{:.3f}".format(results[i]['alpha'] * 180/pi)
|
||||
self.clipboard += "\nAngle in XY Plane [deg]"
|
||||
for i in range(3):
|
||||
self.clipboard += "\t{:.3f}".format(results[i]['beta'] * 180 / pi)
|
||||
self.clipboard += "\nResidual [uT]"
|
||||
for i in range(3):
|
||||
self.clipboard += "\t{:.3e}".format(results[i]['residual'] * 1e6)
|
||||
|
||||
# Enable save buttons
|
||||
self.export_calibration_button.configure(state="normal")
|
||||
self.copy_calibration_button.configure(state="normal")
|
||||
|
||||
def start_calibration_procedure(self):
|
||||
try:
|
||||
calibration_points = self.calibration_points_var.get()
|
||||
@@ -1180,6 +1225,19 @@ class CalibrateMagnetometer(Frame):
|
||||
except (DeviceAccessError, TclError) as e:
|
||||
messagebox.showwarning("Calibration failed", "Failed to start calibration:\n{}".format(e))
|
||||
|
||||
def export_csv(self):
|
||||
if self.calibration_raw_results is None:
|
||||
ui_print("Error: Failed to export non-existent calibration data.")
|
||||
return
|
||||
|
||||
save_dict_list_to_csv('magnetometer_calibration.csv', self.calibration_raw_results, query_path=True)
|
||||
ui_print("Saved calibration results to magnetometer_calibration.csv.")
|
||||
|
||||
def copy_to_clipboard(self):
|
||||
self.clipboard_clear()
|
||||
self.clipboard_append(self.clipboard)
|
||||
self.update()
|
||||
|
||||
|
||||
class HardwareConfiguration(Frame):
|
||||
"""Settings window to set program constants"""
|
||||
|
||||
Reference in New Issue
Block a user