diff --git a/Release/Helmholtz Control.exe b/Release/Helmholtz Control.exe deleted file mode 100644 index 0eeba01..0000000 Binary files a/Release/Helmholtz Control.exe and /dev/null differ diff --git a/src/calibration.py b/src/calibration.py index 6430c5c..cdd0f29 100644 --- a/src/calibration.py +++ b/src/calibration.py @@ -8,6 +8,7 @@ import scipy.optimize from src.utility import ui_print from src.exceptions import DeviceBusy, DeviceAccessError import src.globals as g +#from src.user_interface import CalibrateMagnetometer.mgm_to_helmholtz_cos_trans class AmbientFieldCalibration(Thread): @@ -237,11 +238,12 @@ class CoilConstantCalibration(Thread): class MagnetometerCalibration(Thread): TEST_VECTOR_MAGNITUDE = 100e-6 # In Tesla. Chosen so it can be achieved with a 3A PSU. - def __init__(self, view_queue, calibration_points, calibration_interval): + def __init__(self, view_queue, calibration_points, calibration_interval,mgm_to_helmholtz_cos_trans): Thread.__init__(self) self.view_queue = view_queue self.calibration_points = calibration_points self.calibration_interval = calibration_interval + self.matrix_trans_mgm_to_hh = [[x.get() for x in row] for row in mgm_to_helmholtz_cos_trans] # Hardware checks are done in the init method to allow for exception handling in main thread # This means the run method should/must be called directly after Thread object creation. @@ -282,7 +284,7 @@ class MagnetometerCalibration(Thread): # Sleep for a certain duration to allow psu to stabilize output and magnetometer to supply readings time.sleep(self.calibration_interval) # The offsets can easily be read from the magnetometer - offsets = g.MAGNETOMETER.field + offsets = self.matrix_trans_mgm_to_hh.dot(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]}) @@ -306,7 +308,7 @@ class MagnetometerCalibration(Thread): time.sleep(self.calibration_interval) # Read output and save to array for solver later - raw_reading = g.MAGNETOMETER.field + raw_reading = self.matrix_trans_mgm_to_hh.dot(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]} diff --git a/src/user_interface.py b/src/user_interface.py index 14b2962..a9dcfff 100644 --- a/src/user_interface.py +++ b/src/user_interface.py @@ -1047,7 +1047,7 @@ class CalibrateMagnetometer(Frame): calibration_procedure_progress.grid(row=0, column=1, padx=10, pady=10, sticky="we") row_counter += 1 - # RIGHT COLUMN + # CENTER COLUMN # Magnetometer calibration results row_counter = 0 calibration_results_frame = LabelFrame(self.right_column, text="Magnetometer Results") @@ -1126,7 +1126,7 @@ class CalibrateMagnetometer(Frame): self.copy_calibration_button.grid(row=0, column=1, padx=5, pady=5) row_counter += 1 - # LEFT COLUMN + # RIGHT COLUMN # Input coordinate system conversion matrix row_counter = 0 input_cos_frame = LabelFrame(self.right_column, text="Input MGM to Helmholtz COS Transformation Matrix") @@ -1148,20 +1148,9 @@ class CalibrateMagnetometer(Frame): 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 = 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") @@ -1169,29 +1158,19 @@ class CalibrateMagnetometer(Frame): 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 = 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." + label = "Note:" axis_note = Label(input_cos_frame, text=label) - axis_note.grid(row=4, column=0, padx=5, pady=5, columnspan=5, sticky="nw") + axis_note.grid(row=4, column=0, padx=5, pady=5, sticky="nw") + label = "-Transfers fields value of Helmholtz cage to COS of MGM\n-B_mgm = mgm_T_hh * B_hh" + axis_note = Label(input_cos_frame, anchor='w', justify='left', text=label) + axis_note.grid(row=4, column=1, padx=5, pady=5, columnspan=4, sticky="nw") # Save calibration buttons save_input_cos_frame = Frame(input_cos_frame) save_input_cos_frame.grid(row=6, column=0, columnspan=5) @@ -1206,7 +1185,7 @@ class CalibrateMagnetometer(Frame): 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", + self.normalize_matrix_button = Button(save_input_cos_frame, text="Orthonormalize matrix", command=self.matrix_normalize, state="normal", pady=5, padx=5) @@ -1324,21 +1303,21 @@ class CalibrateMagnetometer(Frame): ui_print("Saved calibration results to magnetometer_calibration.csv.") def export_csv_cos_trans_matrix(self): - if self.mgm_to_helmholtz_cos_trans is None: + cos_trans_matrix = [ + {'XX': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[0][0].get()), + 'XY': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[0][1].get()), + 'XZ': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[0][2].get()), + 'YX': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[1][0].get()), + 'YY': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[1][1].get()), + 'YZ': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[1][2].get()), + 'ZX': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[2][0].get()), + 'ZY': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[2][1].get()), + 'ZZ': "{:.5f}".format(self.mgm_to_helmholtz_cos_trans[2][2].get())} + ] + if cos_trans_matrix is None: ui_print("Error: Failed to export non-existent coordinate transformation matrix.") return - # Populate clipboard for coordinate transformation matrix - cos_trans_matrix_message = "X, Y, Z\n" - cos_trans_matrix_message += "X, {:.5f}".format(self.mgm_to_helmholtz_cos_trans[0][0].get()) - cos_trans_matrix_message += ", {:.5f}".format(self.mgm_to_helmholtz_cos_trans[0][1].get()) - cos_trans_matrix_message += ", {:.5f}\n".format(self.mgm_to_helmholtz_cos_trans[0][2].get()) - cos_trans_matrix_message += "Y, {:.5f}".format(self.mgm_to_helmholtz_cos_trans[1][0].get()) - cos_trans_matrix_message += ", {:.5f}".format(self.mgm_to_helmholtz_cos_trans[1][1].get()) - cos_trans_matrix_message += ", {:.5f}\n".format(self.mgm_to_helmholtz_cos_trans[1][2].get()) - cos_trans_matrix_message += "Z, {:.5f}".format(self.mgm_to_helmholtz_cos_trans[2][0].get()) - cos_trans_matrix_message += ", {:.5f}".format(self.mgm_to_helmholtz_cos_trans[2][1].get()) - cos_trans_matrix_message += ", {:.5f}\n".format(self.mgm_to_helmholtz_cos_trans[2][2].get()) - save_dict_list_to_csv('magnetometer_cos_trans_matrix.csv', cos_trans_matrix_message, query_path=True) + save_dict_list_to_csv('magnetometer_cos_trans_matrix.csv', cos_trans_matrix, query_path=True) ui_print("Saved MGM to Helmholtz coordinate transformation matrix to magnetometer_cos_trans_matrix.csv.") def copy_to_clipboard(self): @@ -1369,10 +1348,16 @@ class CalibrateMagnetometer(Frame): matrix = [[x.get() for x in row] for row in self.mgm_to_helmholtz_cos_trans] 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:") + #matrix_max = matrix.max() + #matrix_min = matrix.min() + #matrix = (matrix - matrix_min) / (matrix_max - matrix_min) + + def gram_schmidt_columns(X): + Q, R = np.linalg.qr(X) + return Q + + matrix = gram_schmidt_columns(matrix) + ui_print("Normalized matrix (Gram-Schmidt):") ui_print(matrix) for i in range(3): for j in range(3):