Added transformation matrix input to gui

This commit is contained in:
2022-08-16 15:27:06 +02:00
parent 6b1a27d9ae
commit 88f85607be
2 changed files with 143 additions and 11 deletions
+131 -11
View File
@@ -332,7 +332,8 @@ class ManualMode(Frame):
pass
else: # this really should never happen
ui_print("Unexpected value encountered: compensate =", compensate)
messagebox.showerror("Unexpected Value!", ("Unexpected value encountered: compensate =", compensate))
messagebox.showerror("Unexpected Value!",
("Unexpected value encountered: compensate =", compensate))
except helmholtz_cage_device.DeviceBusy:
ui_print("Error: Could not acquire control. Is the HW already in use?")
@@ -644,7 +645,7 @@ class CalibrateAmbientField(Frame):
ambient_field_results_frame.grid(row=row_counter, column=1, padx=(100, 0), pady=5, sticky="nw")
for i, label in enumerate(['X', 'Y', 'Z']):
axis_label = Label(ambient_field_results_frame, text=label)
axis_label.grid(row=0, column=i+1, padx=5, pady=(5, 0), sticky="nw")
axis_label.grid(row=0, column=i + 1, padx=5, pady=(5, 0), sticky="nw")
# Ambient field value (A)
ambient_field_results_label = Label(ambient_field_results_frame, text="Ambient Field:")
ambient_field_results_label.grid(row=1, column=0, padx=5, pady=5, sticky="nw")
@@ -653,7 +654,7 @@ class CalibrateAmbientField(Frame):
textvariable=self.ambient_field_result_vars[i],
width=15,
state='readonly')
axis_data.grid(row=1, column=i+1, padx=5, pady=5, sticky="nw")
axis_data.grid(row=1, column=i + 1, padx=5, pady=5, sticky="nw")
ambient_field_results_unit = Label(ambient_field_results_frame, text="A")
ambient_field_results_unit.grid(row=1, column=4, padx=5, pady=5, sticky="nw")
# Ambient field value (microtesla)
@@ -675,7 +676,7 @@ class CalibrateAmbientField(Frame):
textvariable=self.ambient_field_residual_vars[i],
width=15,
state='readonly')
axis_data.grid(row=3, column=i+1, padx=5, pady=5, sticky="nw")
axis_data.grid(row=3, column=i + 1, padx=5, pady=5, sticky="nw")
ambient_field_residual_unit = Label(ambient_field_results_frame, text="\u03BCT")
ambient_field_residual_unit.grid(row=3, column=4, padx=5, pady=5, sticky="nw")
# Save calibration buttons
@@ -791,7 +792,7 @@ class CalibrateAmbientField(Frame):
messagebox.showerror("Calibration error", "Error occured during calibration:\n{}".format(arg))
self.reactivate_buttons()
elif cmd == 'progress':
self.calibration_procedure_progress_var.set(min(int(arg*100), 100))
self.calibration_procedure_progress_var.set(min(int(arg * 100), 100))
elif cmd == 'ambient_data':
self.update_ambient_calibration_results(arg)
elif cmd == 'coil_constant_results':
@@ -975,6 +976,9 @@ class CalibrateMagnetometer(Frame):
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
self.mgm_to_helmholtz_cos_trans = [[DoubleVar(value=1), DoubleVar(value=0), DoubleVar(value=0)],
[DoubleVar(value=0), DoubleVar(value=1), DoubleVar(value=0)],
[DoubleVar(value=0), DoubleVar(value=0), DoubleVar(value=1)]]
# UI Elements
row_counter = 0
@@ -1120,6 +1124,93 @@ class CalibrateMagnetometer(Frame):
self.copy_calibration_button.grid(row=0, column=1, padx=5, pady=5)
row_counter += 1
# RIGHT Bottom COLUMN
# Input coordinate system conversion matrix
row_counter = 0
input_cos_frame = LabelFrame(self.right_column, text="Input MGM to Helmholtz COS Transformation Matrix")
input_cos_frame.grid(row=row_counter, column=2, padx=(100, 0), pady=20, sticky="nw")
for i, label in enumerate(['X', 'Y', 'Z']):
axis_label = Label(input_cos_frame, text=label)
axis_label.grid(row=0, column=i + 1, padx=5, pady=5, sticky="nw")
# Axis sensitivities
sensitivity_results_label = Label(input_cos_frame, text="X")
sensitivity_results_label.grid(row=1, column=0, padx=5, pady=5, sticky="nw")
for i in range(3):
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[0][i],
width=15)
axis_data.grid(row=1, column=i + 1, padx=5, pady=5, sticky="nw")
sensitivity_results_unit = Label(input_cos_frame, text="-")
sensitivity_results_unit.grid(row=1, column=4, padx=5, pady=5, sticky="nw")
# Axis offsets
offset_results_label = Label(input_cos_frame, text="Y")
offset_results_label.grid(row=2, column=0, padx=5, pady=5, sticky="nw")
for i in range(3):
if i == 0:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[0][1],
width=15,
state='readonly')
self.mgm_to_helmholtz_cos_trans[1][0] = self.mgm_to_helmholtz_cos_trans[0][1]
if i == 1:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[1][i],
width=15)
if i == 2:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[1][i],
width=15)
axis_data.grid(row=2, column=i + 1, padx=5, pady=5, sticky="nw")
offset_results_unit = Label(input_cos_frame, text="-")
offset_results_unit.grid(row=2, column=4, padx=5, pady=5, sticky="nw")
# Angle to XY coil plane
angle_to_plane_label = Label(input_cos_frame, text="Z")
angle_to_plane_label.grid(row=3, column=0, padx=5, pady=5, sticky="nw")
for i in range(3):
if i == 0:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[0][2],
width=15,
state='readonly')
self.mgm_to_helmholtz_cos_trans[2][0] = self.mgm_to_helmholtz_cos_trans[0][2]
if i == 1:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[1][2],
width=15,
state='readonly')
self.mgm_to_helmholtz_cos_trans[2][1] = self.mgm_to_helmholtz_cos_trans[1][2]
if i == 2:
axis_data = Entry(input_cos_frame,
textvariable=self.mgm_to_helmholtz_cos_trans[2][i],
width=15)
axis_data.grid(row=3, column=i + 1, padx=5, pady=5, sticky="nw")
angle_to_plane_unit = Label(input_cos_frame, text="-")
angle_to_plane_unit.grid(row=3, column=4, padx=5, pady=5, sticky="nw")
# Note on input
label = "Note: Input orthogonal, normalized transformation Matrix."
axis_note = Label(input_cos_frame, text=label)
axis_note.grid(row=4, column=0, padx=5, pady=5, columnspan=5, sticky="nw")
# Save calibration buttons
save_input_cos_frame = Frame(input_cos_frame)
save_input_cos_frame.grid(row=6, column=0, columnspan=5)
# Save and apply
self.export_cos_trans_button = Button(save_input_cos_frame, text="Export raw to CSV",
command=self.export_csv,
state="normal",
pady=5, padx=5)
self.export_cos_trans_button.grid(row=0, column=0, padx=5, pady=5)
self.copy_cos_trans_matrix_button = Button(save_input_cos_frame, text="Copy to clipboard",
command=self.copy_to_clipboard,
state="normal",
pady=5, padx=5)
self.copy_cos_trans_matrix_button.grid(row=0, column=1, padx=5, pady=5)
self.normalize_matrix_button = Button(save_input_cos_frame, text="Normalize matrix",
command=self.matrix_normalize,
state="normal",
pady=5, padx=5)
self.normalize_matrix_button.grid(row=0, column=2, padx=5, pady=5)
row_counter += 1
# This starts an endless polling loop
self.update_view()
@@ -1154,7 +1245,7 @@ class CalibrateMagnetometer(Frame):
messagebox.showerror("Calibration error", "Error occured during calibration:\n{}".format(arg))
self.reactivate_buttons()
elif cmd == 'progress':
self.calibration_procedure_progress_var.set(min(int(arg*100), 100))
self.calibration_procedure_progress_var.set(min(int(arg * 100), 100))
elif cmd == 'calibration_data':
self.display_calibration_results(arg)
else:
@@ -1182,8 +1273,8 @@ class CalibrateMagnetometer(Frame):
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))
self.angle_to_plane_result_vars[i].set("{:.3f}".format(results[i]['alpha'] * 180/pi))
self.angle_in_plane_result_vars[i].set("{:.3f}".format(results[i]['beta'] * 180/pi))
self.angle_to_plane_result_vars[i].set("{:.3f}".format(results[i]['alpha'] * 180 / pi))
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
@@ -1196,7 +1287,7 @@ class CalibrateMagnetometer(Frame):
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 += "\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)
@@ -1207,6 +1298,7 @@ class CalibrateMagnetometer(Frame):
# Enable save buttons
self.export_calibration_button.configure(state="normal")
self.copy_calibration_button.configure(state="normal")
self.export_mgm_button.configure(state="normal")
def start_calibration_procedure(self):
try:
@@ -1233,6 +1325,33 @@ class CalibrateMagnetometer(Frame):
self.clipboard_append(self.clipboard)
self.update()
def matrix_normalize(self):
try:
ui_print("Input matrix to be normalized:")
# Normalize Matrix
matrix = [[self.mgm_to_helmholtz_cos_trans[0][0].get(), self.mgm_to_helmholtz_cos_trans[0][1].get(),
self.mgm_to_helmholtz_cos_trans[0][2].get()],
[self.mgm_to_helmholtz_cos_trans[1][0].get(), self.mgm_to_helmholtz_cos_trans[1][1].get(),
self.mgm_to_helmholtz_cos_trans[1][2].get()],
[self.mgm_to_helmholtz_cos_trans[2][0].get(), self.mgm_to_helmholtz_cos_trans[2][1].get(),
self.mgm_to_helmholtz_cos_trans[2][2].get()]]
matrix = np.array(matrix)
ui_print(matrix)
matrix_max = matrix.max()
matrix_min = matrix.min()
matrix = (matrix - matrix_min) / (matrix_max - matrix_min)
ui_print("Normalized matrix:")
ui_print(matrix)
for i in range(3):
for j in range(3):
self.mgm_to_helmholtz_cos_trans[i][j].set(matrix[i][j])
except:
# Couldn't compute matrix -> use unity matrix
ui_print("Could not normalize matrix, reverted to unity matrix!")
self.mgm_to_helmholtz_cos_trans = [[DoubleVar(value=1), DoubleVar(value=0), DoubleVar(value=0)],
[DoubleVar(value=0), DoubleVar(value=1), DoubleVar(value=0)],
[DoubleVar(value=0), DoubleVar(value=0), DoubleVar(value=1)]]
class HardwareConfiguration(Frame):
"""Settings window to set program constants"""
@@ -1431,7 +1550,8 @@ class HardwareConfiguration(Frame):
# Check if value is within safe limits
config_key = self.entries[key][3] # get handle by which value is indexed in config file
value_ok = helmholtz_cage_device.value_in_limits(g.AXIS_NAMES[i], config_key, value) # perform value check
value_ok = helmholtz_cage_device.value_in_limits(g.AXIS_NAMES[i], config_key,
value) # perform value check
if value_ok == 'OK': # value is within safe limits
config.edit_config(g.AXIS_NAMES[i], config_key, value) # write new value to config file
@@ -1637,7 +1757,7 @@ class ConfigureLogging(Frame):
self.checkbox_vars[key] = BooleanVar(value=True) # create variable for checkbox and put it in dictionary
checkbox = Checkbutton(self.checkbox_frame, text=name, # generate checkbox
variable=self.checkbox_vars[key], onvalue=True, offvalue=False)
checkbox.grid(row=row+1, column=column, padx=(0, 20), sticky=W) # place checkbox in UI
checkbox.grid(row=row + 1, column=column, padx=(0, 20), sticky=W) # place checkbox in UI
self.checkboxes.append(checkbox) # add created checkbox to list of all checkboxes
row += 1
if row > 8: