diff --git a/Documentation/Abbreviation.tex b/Documentation/Abbreviation.tex index 847d365..cbce288 100644 --- a/Documentation/Abbreviation.tex +++ b/Documentation/Abbreviation.tex @@ -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} \ No newline at end of file diff --git a/Documentation/Chapters/03_Software.tex b/Documentation/Chapters/03_Software.tex index d95462c..ec05c05 100644 --- a/Documentation/Chapters/03_Software.tex +++ b/Documentation/Chapters/03_Software.tex @@ -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: diff --git a/Documentation/Chapters/04_Users Guide.tex b/Documentation/Chapters/04_Users Guide.tex index 5bbfd6c..0170793 100644 --- a/Documentation/Chapters/04_Users Guide.tex +++ b/Documentation/Chapters/04_Users Guide.tex @@ -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} \ No newline at end of file +\end{enumerate} + +\subsection{TCP Remote Control} +\label{sec:tcp_api} + +TODO. \ No newline at end of file diff --git a/Documentation/Helmholtz Cage Software Documentation.pdf b/Documentation/Helmholtz Cage Software Documentation.pdf index 1e6ce0e..7a9f5a7 100644 Binary files a/Documentation/Helmholtz Cage Software Documentation.pdf and b/Documentation/Helmholtz Cage Software Documentation.pdf differ