forked from zietzm/Helmholtz_Test_Bench
renamed test stand to test bench
This commit is contained in:
1 parent
606cfa1f40
commit
3e8490d353
5 files changed
+57
-35
No files matched your search
+21
-21
@@ -110,7 +110,7 @@ class TopMenu:
|
||||
|
||||
|
||||
class ManualMode(Frame):
|
||||
# Mode for manually setting currents and fields on the test stand.
|
||||
# Mode for manually setting currents and fields on the test bench.
|
||||
# Inherits the Frame object from Tkinter and is placed in the mainArea of the application window.
|
||||
def __init__(self, parent, controller):
|
||||
Frame.__init__(self, parent) # initialize the frame object
|
||||
@@ -267,7 +267,7 @@ class ManualMode(Frame):
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = self.controller.pages[ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
def power_down(self): # called on "power down" button press
|
||||
@@ -275,13 +275,13 @@ class ManualMode(Frame):
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = self.controller.pages[ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
def execute(self): # called on "Execute!" button press
|
||||
# reads values from the entry fields and commands the test stand accordingly
|
||||
# reads values from the entry fields and commands the test bench accordingly
|
||||
|
||||
vector = np.array([0, 0, 0], dtype=float) # initialize vector to later send to test stand
|
||||
vector = np.array([0, 0, 0], dtype=float) # initialize vector to later send to test bench
|
||||
i = 0
|
||||
try: # try to read values from the entry fields
|
||||
for var in self.entry_vars:
|
||||
@@ -296,24 +296,24 @@ class ManualMode(Frame):
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = self.controller.pages[ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
def execute_field(self, vector): # convert magnetic field vector and send to test stand
|
||||
def execute_field(self, vector): # convert magnetic field vector and send to test bench
|
||||
ui_print("Field executing:", vector, "\u03BCT")
|
||||
compensate = self.compensate.get() # read out if compensate ambient field checkbox is ticked
|
||||
if compensate: # ambient field should be compensated
|
||||
func.set_field(vector * 1e-6) # convert to Tesla and send to test stand
|
||||
func.set_field(vector * 1e-6) # convert to Tesla and send to test bench
|
||||
elif not compensate: # ambient field should not be compensated
|
||||
func.set_field_simple(vector * 1e-6) # convert to Tesla and send to test stand
|
||||
func.set_field_simple(vector * 1e-6) # convert to Tesla and send to test bench
|
||||
else: # this really should never happen
|
||||
ui_print("Unexpected value encountered: compensate =", compensate)
|
||||
messagebox.showerror("Unexpected Value!", ("Unexpected value encountered: compensate =", compensate))
|
||||
|
||||
@staticmethod
|
||||
def execute_current(vector): # send current vector to the test stand
|
||||
def execute_current(vector): # send current vector to the test bench
|
||||
ui_print("Current executing:", vector, "A")
|
||||
func.set_current_vec(vector) # command test stand
|
||||
func.set_current_vec(vector) # command test bench
|
||||
|
||||
|
||||
class ExecuteCSVMode(Frame):
|
||||
@@ -468,7 +468,7 @@ class ExecuteCSVMode(Frame):
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = self.controller.pages[ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
def reinitialize(self): # called on "Reinitialize devices" button press
|
||||
@@ -476,7 +476,7 @@ class ExecuteCSVMode(Frame):
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = self.controller.pages[ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
def display_plot(self): # generate and display a plot of the data loaded from a csv file
|
||||
@@ -625,7 +625,7 @@ class Configuration(Frame):
|
||||
self.buttons_frame.grid(row=row_counter, column=0, sticky=W, padx=20)
|
||||
|
||||
# Create and place buttons
|
||||
# button to read the values from all fields, update the config and reinitialize the test stand
|
||||
# button to read the values from all fields, update the config and reinitialize the test bench
|
||||
implement_button = Button(self.buttons_frame, text="Update and Reinitialize", command=self.implement,
|
||||
pady=5, padx=5, font=BIG_BUTTON_FONT)
|
||||
implement_button.grid(row=0, column=0, padx=5)
|
||||
@@ -785,9 +785,9 @@ class ConfigureLogging(Frame):
|
||||
|
||||
self.log_file = None # string containing path of log file
|
||||
self.regular_logging = False # True if data should be logged regularly
|
||||
self.event_logging = False # True if data should be logged every time a command is sent to the test stand
|
||||
# log_datapoint() has to be called wherever a command is sent to the test stand and data should be logged
|
||||
# it does not happen automatically whenever something is sent to the test stand
|
||||
self.event_logging = False # True if data should be logged every time a command is sent to the test bench
|
||||
# log_datapoint() has to be called wherever a command is sent to the test bench and data should be logged
|
||||
# it does not happen automatically whenever something is sent to the test bench
|
||||
# It is done mainly in the functions for UI buttons, but rather inconsistently ToDo(optional): make consistent
|
||||
|
||||
self.grid_rowconfigure(ALL, weight=1)
|
||||
@@ -853,14 +853,14 @@ class ConfigureLogging(Frame):
|
||||
|
||||
# create checkbox variable for logging in regular time intervals
|
||||
self.regular_logging_var = BooleanVar(value=True)
|
||||
# create checkbox variable for logging whenever test stand is commanded
|
||||
# create checkbox variable for logging whenever test bench is commanded
|
||||
self.event_logging_var = BooleanVar(value=True)
|
||||
self.log_interval = DoubleVar(value=1) # create variable for logging interval entry field
|
||||
|
||||
# create checkboxes for regular and event logging:
|
||||
self.regular_logging_checkbox = Checkbutton(self.settings_frame, text="Log in regular intervals",
|
||||
variable=self.regular_logging_var, onvalue=True, offvalue=False)
|
||||
self.event_logging_checkbox = Checkbutton(self.settings_frame, text="Log whenever test stand is commanded",
|
||||
self.event_logging_checkbox = Checkbutton(self.settings_frame, text="Log whenever test bench is commanded",
|
||||
variable=self.event_logging_var, onvalue=True, offvalue=False)
|
||||
self.regular_logging_checkbox.grid(row=0, column=0, sticky=W)
|
||||
self.event_logging_checkbox.grid(row=1, column=0, sticky=W, columnspan=3)
|
||||
@@ -943,7 +943,7 @@ class ConfigureLogging(Frame):
|
||||
def stop_logging(self): # stop the data logging, called by "Stop Logging" button
|
||||
ui_print("Stopped data logging. Remember to save data to file!")
|
||||
self.regular_logging = False # tell everything its time to stop periodic logging
|
||||
self.event_logging = False # tell everything its time to stop logging on test stand commands
|
||||
self.event_logging = False # tell everything its time to stop logging on test bench commands
|
||||
self.write_to_file_button["state"] = "normal" # enable write to file button
|
||||
self.stop_logging_button["state"] = "disabled" # disable stop logging button
|
||||
self.start_logging_button["state"] = "normal" # enable start logging button
|
||||
@@ -1015,7 +1015,7 @@ class ConfigureLogging(Frame):
|
||||
|
||||
|
||||
class StatusDisplay(Frame):
|
||||
# status display to show information on test stand status in real time
|
||||
# status display to show information on test bench status in real time
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def __init__(self, parent, controller):
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
# This file contains all classes and functions directly related to the operation of the helmholtz test stand.
|
||||
# This file contains all classes and functions directly related to the operation of the helmholtz test bench.
|
||||
# The two main classes are Axis and ArduinoCtrl, see their definitions for details.
|
||||
|
||||
# import packages:
|
||||
@@ -16,7 +16,7 @@ import globals as g
|
||||
|
||||
|
||||
class Axis:
|
||||
# Main class representing an axis (x,y,z) of the test stand
|
||||
# Main class representing an axis (x,y,z) of the test bench
|
||||
# contains static and dynamic status information about this axis and methods to control it
|
||||
|
||||
def __init__(self, index, device, PSU_channel, arduino_pin):
|
||||
@@ -117,7 +117,7 @@ class Axis:
|
||||
messagebox.showerror("PSU Error!", "Error while powering down %s: \n%s" % (self.name, e))
|
||||
|
||||
def set_signed_current(self, value):
|
||||
# sets current with correct polarity on this axis, this is the primary way to control the test stand
|
||||
# sets current with correct polarity on this axis, this is the primary way to control the test bench
|
||||
|
||||
# ui_print("Attempting to set current", value, "A")
|
||||
self.target_current = value # show target value in object attribute for status display, logging etc.
|
||||
@@ -146,14 +146,14 @@ class Axis:
|
||||
self.target_field = value # update object attribute for display
|
||||
self.target_field_comp = value # same as above, bc no compensation
|
||||
current = value / self.coil_constant # calculate needed current
|
||||
self.set_signed_current(current) # command the test stand
|
||||
self.set_signed_current(current) # command the test bench
|
||||
|
||||
def set_field(self, value): # forms magnetic field as specified by value, corrected for ambient field
|
||||
self.target_field = value # update object attribute for display
|
||||
field = value - self.ambient_field # calculate needed field after compensation
|
||||
self.target_field_comp = field # update object attribute for display
|
||||
current = field / self.coil_constant # calculate needed current
|
||||
self.set_signed_current(current) # command the test stand
|
||||
self.set_signed_current(current) # command the test bench
|
||||
|
||||
|
||||
class ArduinoCtrl(Arduino):
|
||||
@@ -216,7 +216,7 @@ def value_in_limits(axis, key, value): # Check if value is within safe limits (
|
||||
return 'OK'
|
||||
|
||||
|
||||
def setup_all(): # main test stand initialization function
|
||||
def setup_all(): # main test bench initialization function
|
||||
# creates device objects for all PSUs and Arduino and sets their values
|
||||
# initializes an object of class Axis for all three axes (x,y,z)
|
||||
|
||||
@@ -386,7 +386,7 @@ def set_current_vec(vector): # sets currents on each axis according to given ve
|
||||
axis.target_field = 0 # set target field attribute to 0 to show that current, not field is controlled atm
|
||||
axis.target_field_comp = 0 # as above
|
||||
|
||||
axis.set_signed_current(vector[i]) # command test stand to set the current
|
||||
axis.set_signed_current(vector[i]) # command test bench to set the current
|
||||
except ValueError as e: # current was too high
|
||||
ui_print(e) # print out the error message
|
||||
i += 1
|
||||
|
||||
+7
-7
@@ -47,7 +47,7 @@ class ExecCSVThread(Thread):
|
||||
|
||||
def execute_sequence(self, array, delay, parent, controller):
|
||||
# main execution method of the class
|
||||
# runs through array with times and desired fields and commands test stand accordingly
|
||||
# runs through array with times and desired fields and commands test bench accordingly
|
||||
|
||||
# array format: [time (s), xField (T), yField (T), zField (T)]
|
||||
func.power_down_all() # sets outputs on PSUs to 0 and Arduino pins to LOW before starting
|
||||
@@ -73,12 +73,12 @@ class ExecCSVThread(Thread):
|
||||
field_vec = array[i, 1:4] # extract desired field vector
|
||||
ui.ui_print("%0.5f s: t = %0.2f s, target field vector ="
|
||||
% (time.time() - t_zero, array[i, 0]), field_vec * 1e6, "\u03BCT")
|
||||
func.set_field(field_vec) # send field vector to test stand
|
||||
func.set_field(field_vec) # send field vector to test bench
|
||||
controller.StatusDisplay.update_labels() # update status display after change
|
||||
|
||||
# log change to the log file if user has selected event logging in the Configure Logging window
|
||||
logger = controller.pages[ui.ConfigureLogging] # get object of logging configurator
|
||||
if logger.event_logging: # data should be logged when test stand is commanded
|
||||
if logger.event_logging: # data should be logged when test bench is commanded
|
||||
logger.log_datapoint() # log data
|
||||
|
||||
i = i + 1 # next row
|
||||
@@ -115,17 +115,17 @@ def read_csv_to_array(filepath): # convert a given csv file to a numpy array
|
||||
|
||||
|
||||
def check_array_ok(array):
|
||||
# check if any magnetic fields in an array exceed the test stand limits and if so display a warning message
|
||||
# check if any magnetic fields in an array exceed the test bench limits and if so display a warning message
|
||||
values_ok = True
|
||||
for i in [0, 1, 2]: # go through axes/columns
|
||||
max_val = g.AXES[i].max_comp_field[1] # get limits the test stand can do
|
||||
max_val = g.AXES[i].max_comp_field[1] # get limits the test bench can do
|
||||
min_val = g.AXES[i].max_comp_field[0]
|
||||
data = array[:, i + 1] # extract data for this axis from array
|
||||
# noinspection PyTypeChecker
|
||||
if any(data > max_val) or any(data < min_val): # if any datapoint is out of bounds
|
||||
values_ok = False
|
||||
if not values_ok: # show warning pop-up if values are exceeding limits
|
||||
messagebox.showwarning("Value Limits Warning!", "Found field values exceeding limits of test stand."
|
||||
messagebox.showwarning("Value Limits Warning!", "Found field values exceeding limits of test bench."
|
||||
"\nSee plot and check values in csv.")
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ def plot_field_sequence(array, width, height): # create plot of fixed size (pix
|
||||
|
||||
figure.suptitle("Magnetic Field Sequence") # set figure title
|
||||
|
||||
# modify data to show instantaneous jumps in field to reflect test stand operation
|
||||
# modify data to show instantaneous jumps in field to reflect test bench operation
|
||||
new_array = np.array([[0, 0, 0, 0]], dtype=float) # initialize modified array, zeros to show start from no fields
|
||||
|
||||
last_vals = [0, 0, 0] # [x,y,z] field values from last data point (zero here), used to create step in data
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Helmholtz Cage Control Software
|
||||
|
||||
This software is used to control the magnetic field test bench at the Institute for Space Systems (IRS) at
|
||||
the University of Stuttgart. The test bench consists of three Helmholtz coil pairs, one in each spatial axis.
|
||||
The amount of current flowing through these coils is controlled by two PS2000B power supply units.
|
||||
The polarity is switched by a set of relays that are controller by an Arduino Uno.
|
||||
|
||||
This repository contains the source code and is used to develop and modify the program. Releases are distributed
|
||||
in a [separate repository](https://egit.irs.uni-stuttgart.de/zietzm/Helmholtz_Test_Bench_Releases/releases).
|
||||
|
||||
## Installation
|
||||
1. Download latest release from
|
||||
[distribution repository](https://egit.irs.uni-stuttgart.de/zietzm/Helmholtz_Test_Bench_Releases/releases)
|
||||
2. Unpack ZIP-Folder
|
||||
3. Run `Helmholtz Cage Control.exe`
|
||||
|
||||
Alternatively use the `Helmholtz Cage Control.exe` from the `Release` folder in this repository.
|
||||
|
||||
## Users Guide
|
||||
For detailed instructions please refer to `Users Guide.pdf`.
|
||||
|
||||
##
|
||||
BIN
Binary file not shown.
Reference in new issue
Block a user