Added new files and components to the software documentation.

This commit is contained in:
2021-11-10 22:08:35 +01:00
parent 6ab3778692
commit 1fc059a656
4 changed files with 82 additions and 14 deletions
+1
View File
@@ -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}
+75 -13
View File
@@ -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:
+6 -1
View File
@@ -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.