forked from zietzm/Helmholtz_Test_Bench
Added new files and components to the software documentation.
This commit is contained in:
@@ -173,3 +173,4 @@
|
||||
\newacronym{pla}{PLA}{Polylactic Acid, a thermoplastic polyester}
|
||||
\newacronym{pc}{PC}{Personal Computer}
|
||||
\newacronym{tbd}{TBD}{To Be Determined}
|
||||
\newacronym{mpi}{MPI}{Message Passing Interface}
|
||||
@@ -163,6 +163,22 @@ To execute the sequence without blocking the \gls{ui}, a separate execution thre
|
||||
Hardware control is acquired upon creation of the thread, or an exception is returned otherwise.
|
||||
More details on the execution thread is provided in Section \ref{sec:csv_exec}.
|
||||
|
||||
\myparagraph{Magnetometer Calibration Mode Class \code{CalibrateMagnetometer}}
|
||||
This class constructs magnetometer calibration interface.
|
||||
It is placed in the application's main area, its layout is shown in Figure TODO.
|
||||
This class creates and manages a separate execution thread defined in \code{calibration.py} to preform the calibration without blocking the \gls{ui}.
|
||||
Hardware control is acquired upon creation of the thread, or an exception is returned otherwise.
|
||||
More details on the calibration thread is provided in Section \ref{sec:calibration_processes}.
|
||||
Communication with the running thread is preformed by means of the \code{view\_mpi\_queue} queue variable, which is regularly polled in \code{update\_view}.
|
||||
This is where different \gls{mpi} commands are delegated to their respective handlers.
|
||||
For example, the live completion status and final calibration results are handled here.
|
||||
It should be of note, that the calibration threads do not store any results or information, instead these are contained in variables defined near the top of \code{\_\_init\_\_}.
|
||||
|
||||
\myparagraph{Ambient Field Calibration Mode Class \code{CalibrateAmbientField}}
|
||||
This class consists of an identical structure to the Magnetometer Calibration View Class.
|
||||
The only major difference is that this view provides an interface for two calibration procedures; The ambient field and the coil constants.
|
||||
All relevant calibration worker threads can also be found in \code{calibration.py}.
|
||||
|
||||
\myparagraph{Settings Page Class \code{Configuration}}
|
||||
The program settings page is constructed in this class.
|
||||
It provides a \gls{ui} to edit application settings and also controls the reading and writing of configuration files.
|
||||
@@ -218,6 +234,19 @@ Apart from the main class this file contains functions to read data from a \gls{
|
||||
There is also a function to generate a plot of the data for display in the \gls{ui}.
|
||||
The line plot is modified to visually reflect the discrete and nearly instantaneous change of fields in the test bench (see result in Figure \ref{fig:ui_overview}).
|
||||
|
||||
\subsection{Calibration Procedures \code{calibration.py}}
|
||||
\label{sec:calibration_processes}
|
||||
This file contains the worker thread objects \code{AmbientFieldCalibration}, \code{CoilConstantCalibration}, and \code{MagnetometerCalibration}.
|
||||
All of these threads start by checking for and acquiring hardware during instantiation, while still in the main thread.
|
||||
Then upon running, the main code in \code{calibration\_procedure} is executed; This function may freely block and make use of sleep commands.
|
||||
Typically, calibration procedures should save two data detail levels: Processed data that is displayed as a final result, and detailed, raw data points that can be exported by the user to apply custom algorithms or verify the applications function.
|
||||
|
||||
The calibration procedures communicate with the main thread via a \gls{mpi} queue.
|
||||
Depending on whether the procedure completes successfully or not, a \code{finished} or \code{failed} status signal is sent.
|
||||
In addition, a \code{calibration\_data} message is sent together with ``\code{finished}'' to convey the final results to the main thread.
|
||||
Other signals may also be used, such as \code{progress} to indicate the current completion status to the main thread.
|
||||
Data that should be passed to the calibration procedure from the main thread, is done so through the constructor.
|
||||
|
||||
\subsection{Configuration Handling File \code{config\_handling.py}}
|
||||
\label{sec:config_handling}
|
||||
This file contains functions and variables for reading and writing configuration files.
|
||||
@@ -254,23 +283,56 @@ The long names can be obtained from the \code{get\_long\_column\_header} functio
|
||||
|
||||
The file also provides functions to allow the user to choose a filename and clear the logged data.
|
||||
|
||||
\subsection{Hardware Control Libraries}
|
||||
\myparagraph{PS2000B \gls{psu} Control Library \code{PS2000B.py}}
|
||||
The code necessary to control the power supply units was adapted from S. Sprößig \cite{PS2000B_lib} with only minor modifications.
|
||||
The library provides the class \code{PS2000B} and some supporting functions.
|
||||
Each instance of the class represents a physical \gls{psu}.
|
||||
These objects can be used to access status information and command the device, for example to set currents and voltages.
|
||||
More information can be found in the readme file provided by the original author.
|
||||
\subsection{TCP Remote Control \code{socket\_control.py}}
|
||||
This class is responsible for enabling TCP control of the Helmholtz cage hardware.
|
||||
In addition, it is the sole data path for magnetometer data to ingress into the control software.
|
||||
As with all other software components, the command processing thread accesses the hardware using the global \code{g.CAGE\_DEVICE} and \code{g.MAGNETOMETER} instances, and uses the proxy model to prevent control collisions.
|
||||
|
||||
The main modification to this library done as part of this thesis, was to implement independent commanding of both \gls{psu} channels.
|
||||
The \code{socket\_control.py} file defines the \code{SocketInterfaceThread} class, which provides a listener thread to accept incoming TCP connections.
|
||||
The listener thread instance is defined at application start-up in \code{main.py}.
|
||||
For each established connection, a \code{ClientConnectionThread} instance is created.
|
||||
All the main logic and command parsing is handled the client connection/session threads.
|
||||
The \gls{api} is documented in Chapter \ref{sec:tcp_api} and also in the application source code.
|
||||
|
||||
Note: Following an application crash, the application may present an error in acquiring the TCP port.
|
||||
This may be fixed by waiting a few minutes, or restarting the computer.
|
||||
Perhaps this special case can be fixed with a more rigorous exit handler in the future.
|
||||
|
||||
\subsection{Hardware Control Libraries}
|
||||
|
||||
\myparagraph{``\code{PSUDevice}'' Abstract Class and PSU Drivers \code{psu\_device.py} / \code{PS2000B.py}}
|
||||
|
||||
An abstract class \code{PSUDevice} describing any compatible power supply object is used to allow for quick and easy addition of new device support.
|
||||
This improvement was implemented since power supplies may be replaced or upgraded on a moderately frequent basis.
|
||||
The abstract class exposes functions to set currents and voltages, and also to query the current device status.
|
||||
QL355TP devices are natively supported with the \code{PSUDeviceQL355TP} object, that is also defined in \code{psu\_device.py}.
|
||||
|
||||
Since the code was at some point migrated to require a consistent interface for PSU objects, the original PS2000B library had to be put in a wrapper class (\code{PSUDevicePS2000B}).
|
||||
The external library provides the class \code{PS2000B} and some supporting functions, and was adapted from S. Sprößig \cite{PS2000B_lib} with only minor modifications.
|
||||
More information can be found in the read me file provided by the original author.
|
||||
The library objects provide effectively the same set of functions advertised by the abstract class, as such the wrapper is quite trivial.
|
||||
In the future, it may make sense to migrate the library code directly into the \code{PSUDevicePS2000B} class.
|
||||
|
||||
The main modification to the PS2000B library done as part of this thesis, was to implement independent commanding of both \gls{psu} channels.
|
||||
For this an additional parameter \code{channel} (integer type, 0 or 1) was added to all methods of the \code{PS2000B} class that interact with the device.
|
||||
Additionally the properties \code{PS2000B.output1}, \code{PS2000B.voltage1} and \code{PS2000B.current1} were duplicated to support the second channel (e.g. \code{PS2000B.output2}).
|
||||
|
||||
\myparagraph{Arduino Command \gls{api} \code{arduino.py}}
|
||||
To control the Arduino microcontroller the online library from \cite{Arduino_lib} was integrated without major modifications.
|
||||
To use it, the provided \code{prototype.ino} file needs to be transferred to the Arduino.
|
||||
An object of class \code{Arduino} can then be used to control the board (connected via \gls{usb}) with methods that closely resemble the ones used in the standard Arduino programming language.
|
||||
More details can be found in the readme file provided by the original author \cite{Arduino_lib}.
|
||||
\myparagraph{Arduino Command \gls{api} \code{arduino.py} / \code{arduino\_device.py}}
|
||||
To control the Arduino microcontroller, an interface and wrapper class is used.
|
||||
First, the online library from \cite{Arduino_lib} is integrated without major modifications to expose a hardware control \gls{api}.
|
||||
It communicates with the provided \code{prototype.ino} Arduino program to allow toggling and control of its pins with methods that closely resemble the ones used in the standard Arduino programming language.
|
||||
More details can be found in the read me file provided by the original author \cite{Arduino_lib}.
|
||||
|
||||
The \code{Arduino} class is then wrapped in the \code{ArduinoDevice} class defined in \code{arduino\_device.py}, to expose a more polarity-switcher-relevant \gls{api}.
|
||||
This simplifies its use in the already complex \code{HelmholtzCageDevice} function.
|
||||
|
||||
\myparagraph{Magnetometer Device \code{magnetometer.py}}
|
||||
The magnetometer object is hardware-agnostic, and merely mirrors the state of an external physical device.
|
||||
To enable quick and optimal compatibility with new magnetometer devices, data is ingested by means of the TCP port and the application functions purely as a listener.
|
||||
External magnetometer interface scripts will first push their data according to the \gls{api} defined in \code{socker\_control.py}, which will then be forwarded to the global \code{MagnetometerProxy} instance.
|
||||
This means the magnetometer proxy object is purely passive, and functions like a simple data container.
|
||||
|
||||
The magnetometer object mirrors the state of the TCP connection, which is presented as a connected/disconnected state.
|
||||
|
||||
\section{Conversion to Executable}
|
||||
The program is compiled to a .exe executable file to enable simple use without a Python installation. For this, the "Auto Py to Exe" tool developed by B. Vollebregt \cite{auto_py_to_exe} is used. The resulting files are distributed in a separate repository on the \gls{irs} git server.\footnote{\url{https://egit.irs.uni-stuttgart.de/zietzm/Helmholtz_Test_Bench_Releases}} When a new software version is ready for publication, the following procedure should be used to release it:
|
||||
|
||||
@@ -452,4 +452,9 @@ Figure \ref{fig:settingspure} shows a screenshot of the \gls{ui} layout with the
|
||||
\item Press "Save current config" button to update the current configuration file
|
||||
\item Press "Save current config as..." button to save to a new configuration file, set new file name in file dialogue (e.g. "myconfig.ini")
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{TCP Remote Control}
|
||||
\label{sec:tcp_api}
|
||||
|
||||
TODO.
|
||||
Binary file not shown.
Reference in New Issue
Block a user