\chapter{Implementation}
-
-\todo{?}
+\hyphenation{im-ple-men-ta-tion im-ple-men-ta-tion-spe-ci-fic}
This chapter describes the implementation that was used for the aforementioned
experiments. It consists of the measuring programs themselves, which use the
Wiselib Roomba Control, and are written in C++. Additionally, there are several
-Bash scripts to help with the analysis of the measured data.
+Bash and Perl scripts to assist in the analysis of the measured data.
All code used for this thesis resides in the Wiselib source tree\footnote{see
\url{https://github.com/ibr-alg/wiselib/}, or the \acs{CDROM} attached at the
-end of this book} in the directory \filepath{apps/pc\_apps/roomba\_tests}.
+end of this thesis} in the directory \filepath{apps/pc\_apps/roomba\_tests}.
\section{Measuring}
\label{sec:impl:measuring}
application uses a list of pre-programmed values for the target values, so the
user only has to input the measured data.
-All measured data is written to a log file in the current directory, whose name
+\paragraph{Logging}
+All measured data is written to a log file in the current directory whose name
is based on the type of experiment performed. Every line in that log file
-describes one measurement made by the user, and consists of key-value pairs
-linked together with equality signs and separated of each other by whitespace.
-In particular, the data on each line are (with key name, in the order of
-appearance on the line):
-\begin{enumerate}
- \item\texttt{svn:} the SVN or Git revision the program was compiled from
+describes one measurement made by the user, and consists of pairs of the form
+\code{key=value}, separated by white space. In particular, the data on each
+line are (with key name, in the order of appearance on the line):
+\begin{enumerate}[noitemsep]
+ \item\texttt{svn:} the \ac{SVN} or Git revision the program was compiled from
(statically compiled into the program)
\item\texttt{roomba\_id:} the ID of the Roomba the measurement was performed
with (given by the user)
- \item\texttt{ground\_type} the ground type used for measurement:
+ \item\texttt{ground\_type:} the ground type used for measurement:
\magicvalue{iz250flur} for laminated floor, \magicvalue{seminarraum}
for carpet floor (given by the user)
\item\texttt{diff\_ticks\_left:} the difference of encoder counts between the
(packet~ID~\magicvalue{0x19})
\item\texttt{batt\_capacity:} the capacity of the Roomba's battery in mAh
(packet~ID~\magicvalue{0x1a})
- \item\texttt{batt\_voltage:} the applied voltage of the Roomba's battery in mV
+ \item\texttt{batt\_voltage:} the voltage of the Roomba's battery in mV
(packet~ID~\magicvalue{0x16})
- \item\texttt{batt\_voltage:} the current going out of the Roomba's battery in
- mA (packet~ID~\magicvalue{0x17})
- \item\texttt{move:} \magicvalue{straight} for straight moves,
- \magicvalue{turn} for turn moves
+ \item\texttt{batt\_voltage:} the current of the Roomba's battery in mA
+ (packet~ID~\magicvalue{0x17})
+ \item\texttt{move:} movement type; \magicvalue{straight} for straight moves,
+ \magicvalue{turn} for turn moves (given by the user while selecting the
+ experiment type)
\newcounter{logitems}\setcounter{logitems}{\value{enumi}+1}
\end{enumerate}
-For straight moves (\magicvalue{move=straight}) follows:
-\begin{enumerate}[start=\value{logitems}]
+For straight moves (\magicvalue{move=straight}) follow:
+\begin{enumerate}[noitemsep,start=\value{logitems}]
\item\texttt{input\_distance}: the target distance in mm sent to the Roomba
via the \ac{ROI} \cmd{Drive} command (given by the user in manual mode,
or determined by the program in automatic mode)
- \item\texttt{velocity:} (the velocity in mm/s sent to the Roomba over the
+ \item\texttt{velocity:} (the velocity in mm/s sent to the Roomba via the
\ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
determined by the program in automatic mode)
\item\texttt{measured\_x:} the actual covered distance in mm in the Roomba's
\item\texttt{deviation\_orientation:} originally, the shift in orientation of
the Roomba. Not used anymore.
\end{enumerate}
-For straight moves (\magicvalue{move=turn}) follows:
-\begin{enumerate}[start=\value{logitems}]
+For turn moves (\magicvalue{move=turn}) follow:
+\begin{enumerate}[noitemsep,start=\value{logitems}]
\item\texttt{turn\_angle:} the turn angle in degree sent to the Roomba via the
\ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
determined by the program in automatic mode)
\item\texttt{measured\_angle:} the actual turned angle of the Roomba in degree
(measured by the user)
- \item\texttt{velocity:} (the velocity in mm/s sent to the Roomba over the
+ \item\texttt{velocity:} the velocity in mm/s sent to the Roomba via the
\ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
determined by the program in automatic mode)
\end{enumerate}
-\begin{figure}
+\begin{figure}[htbp]
\centering
- \includegraphics[width=\textwidth]{images/Implementation-Diagram.pdf}
+ \includegraphics[width=0.9\textwidth]{images/Implementation-Diagram.pdf}
\caption[File structure of the measuring implementation]{Simplified file
structure of the measuring implementation\label{fig:impl:struct}\\
- yellow: general files used for all three experiments; green: files for
- Experiment~1; blue: files for Experiment~2; red: files for Experiment~3}
+ yellow: common files used for all three experiments; \\
+ green: files for Experiment~1; blue: files for Experiment~2; \\red: files
+ for Experiment~3.\\
+ An arrow from node $x$ to node $y$ is to be read as ``$y$ depends from
+ $x$''.}
\end{figure}
Figure~\ref{fig:impl:struct} shows the file layout of the measuring
-implementation. It reuses components whereever possible, and therefore
-consists of three parts specific for the three performed experiments (see
-Sections~\ref{sec:exp1}, \ref{sec:exp2} and~\ref{sec:exp3}), as well as a
-general part, which contains the elements of the implementation common to the
-other three parts.
+implementation. It reuses components where ever possible, and therefore
+consists of three parts (green, blue, red) specific for the three performed
+experiments (see Sections~\ref{sec:exp1}, \ref{sec:exp2} and~\ref{sec:exp3}), as
+well as a common part (yellow), which contains the elements of the
+implementation shared by the other three parts.
-\subsection{General part}
-The files \file{stuff.cc}, \file{stuff.h},
-\file{target\_value\_input\_dialog.cc} and \file{target\_value\_input\_dialog.h}
-build up the general part of the implementation. These are the files shown with
-a yellow background in Figure~\ref{fig:impl:struct}, and are included in all
-other three parts of the implementation.
+\subsection{Common part}
+% no \file{} here please, we don't want "stuff.{cc,h}" in index...
+The files \filefont{stuff.\{cc,h\}} and
+\filefont{target\_value\_input\_dialog.\{cc,h\}} build up the general part of
+the implementation (shown with a yellow background in
+Figure~\ref{fig:impl:struct}). These are included in all other three parts of
+the implementation.
-\paragraph{\file{stuff.cc} and \file{stuff.h}}
-Both of these files contain global functions for logging text to a file,
-according to the format described above. Also there
+\paragraph{Global declarations}
+These files \file{stuff.cc} and \file{stuff.h} contain global helper functions
+and variables, data structures specific to the implementation, and all kinds of
+convenient typedefs. In particular, there are functions for formatting and
+logging messages to a log file, according to the format described above. While
+\file{stuff.h} contains the declarations and typedefs, \file{stuff.cc} contains
+the appropriate definitions. Besides, since \file{stuff.h} is included
+indirectly in most other source files, it also includes the Wiselib headers
+needed for Roomba control.
-\subsection{Implementation for Experiment~1}
-\subsection{Implementation for Experiment~2}
-\subsection{Implementation for Experiment~3}
+\paragraph{Input dialog for measured orientation values}
+\hyphenation{Tar-get-Va-lue-In-put-Dia-log}
-three single applications with same base: roomba\_test (main.cc),
-mean\_correction\_test (mean\_correction.cc), soft\_start\_test
-(soft\_start.cc).
+\begin{figure}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/target_value_input_dialog.png}
+ \caption{The \class{TargetValueInputDialog}}
+\end{figure}
+
+The class \class{TargetValueInputDialog}, which is an implementation of a simple
+dialog box using the Qt widget framework, resides in the files
+\file{target\_value\_input\_dialog.cc} and
+\file{target\_value\_input\_dialog.h}. This dialog allows the user to input a
+measured angle (although the name mentions a ``target value'', which is probably
+named this way only for the sake of confusion\ldots). It contains an input box
+with adjacent spin box for entering the measured value, OK and Cancel buttons,
+and also information about the target orientation and the current real
+orientation as well as the current capacity of the Roomba's battery.
-user interface: Qt.
+When the dialog is displayed, it obtains the orientation as it was before the
+last movement, and the target angle, and sets the input box to the specified
+target value. When the input box is changed, the dialog calculates the new
+orientation from the last orientation and the value in the input box, and
+displays this new orientation. This way, the user can simply enter the measured
+angle by increasing or decreasing the value by operating the spin box, and
+adjusting the value until the displayed orientation reflects the real
+orientation of the Roomba.
-manual tests (user is asked for new values every time) or automated tests (user
-only asked for measured values).
+To achieve this, the class uses the Qt signal-slot
+mechanism~\cite{qt-signalslots}, and connects the \fnfont{intValueChanged(int)}
+signal of the input box to the method
+\fnfont{turn\_dialog\_value\_changed(int)},
+which performs the calculation and display of the new value.
-1) open UART connection
+\subsection{Implementation for Experiment~1: Application \prog{roomba\_test}}
+The implementation for Experiment~1 is used to build the application
+\prog{roomba\_test}. Its main part is constituted by the file \file{main.cc},
+which uses the global definitions of \file{stuff.h} and the dialog box from
+\file{target\_value\_input\_dialog.h}.
-2) register state callback for getting roomba sensor data
+\paragraph{Initial setup}
+The program first checks for command line arguments, where it expects the type
+of test performed and if automatic or manual mode, the ground type, and the
+Roomba's ID, or the \code{-{}-help} switch to display a usage message.
-3) while(input values or cancel) { drive() / turn() }
+After that, it instantiates and initializes a \class{RoombaModel} instance,
+while also providing for the needed instances of the \concept{Timer} concept
+and the \concept{SerialCommunication} concept, which is needed for the serial
+communication with the Roomba. Furthermore, an instance of
+\class{ControlledMotion} is initialized by passing the \class{RoombaModel}
+instance. This instance is later used to control the Roomba's movements.
-4) drive() / turn() use wiselib::ControlledMotion<OsModel,
-wiselib::RoombaModel> for moving specified angle/distance; and ask for measured
-values and write to external log file, including battery status, roomba/wiselib
-internal angles/distances (ticks), svn revision, floor type, roomba ID
+Due to an implementation detail inside the \class{RoombaModel} class, the sensor
+data returned by the class itself may be corrupt if it is read while new sensor
+data packets arriving from the Roomba are processed. To prevent this corruption,
+we register a callback function which gets called every time new sensor data is
+available (i.~e. the sensor data packets have been fully processed, which is
+every 15~ms as we are using the \cmd{Stream} command), and let the callback
+function perform a deep copy of the sensor values we are interested in.
-additionally, mean correction test uses
-CorrectedMeanMotion from corrected\_mean\_motion.h, implements same concept like
-wiselib::ControlledMotion and takes care of target value by using the
-calculated fit function .
+If the user has specified automated measurement on the command line, an array of
+velocities and target values is set up, as described in
+Section~\ref{sec:exp1:setup}, and slightly scrambled to ensure independence of
+the measurements. Furthermore, the file name for the log file to record the
+measured values is determined from the operation mode, the type of experiment
+performed, and the Unix time stamp\footnote{The Unix time stamp is a signed
+integer which is defined as the seconds elapsed since January 1st, 1970, 0:00
+\ac{UTC}}. To ease measurement of angles, if the type of experiments are turn
+movements, the user is prompted once to input the current orientation of the
+Roomba.
-additionally, soft start/stop test uses
-SoftStartMotion from soft\_start\_motion.h, implements same
-concept like wiselib::ControlledMotion and takes care of increasing/decreasing
-velocity via timer.
+\paragraph{Input/measurement loop}
+The rest of the program consists of a loop which does the following things:
+\begin{enumerate}[noitemsep]
+ \item \textbf{In manual mode:} Prompt the user for a new pair of velocity and
+ input value \\
+ \textbf{In automatic mode:} For each pair of velocity and input value
+ specified in the previously defined arrays, do the following:
+ \item Carry out the specified movement using the \class{ControlledMotion}
+ instance
+ \item Prompt the user for the measured value using the
+ \class{TargetValueInputDialog} for angles, or a simple Qt
+ \class{QInputDialog} for distances
+ \item Write the values to the log file, as specified at the beginning of this
+ section, using the log function from \file{stuff.h}
+ \item Repeat until the user cancels.
+\end{enumerate}
+
+\subsection{Implementation for Experiment~2:
+Application \prog{mean\_correction\_test}}
+\label{sec:impl:mean}
+Additionally, the program \prog{mean\_correction\_test} for Experiment~2 uses
+the class \class{CorrectedMeanMotion} from \file{corrected\_mean\_motion.h}.
+This class adapts the input value according to the fit function determined from
+the data in Experiment~1 (see Chapter~\ref{sec:exp2}), and exposes the exact
+interface as \class{ControlledMotion} does. Thus, both classes are easily
+interchangeable, and \class{CorrectedMeanMotion} serves as an example of the
+stackability principle mentioned in Section~\ref{sec:wiselib:arch}.
+
+The essential parts of \class{CorrectedMeanMotion} are the functions
+\fnfont{set\_profile} to specify the fit function (i.~e. the ground type),
+and \fnfont{move\_distance} and \fnfont{turn\_to} which use that specified fit
+function to adapt the input value (angle or distance) and then move the Roomba
+around accordingly. As in the implementation of \class{ControlledMotion}, the
+encoding counts of the Roomba's wheels are monitored to determine when the
+Roomba has to be stopped.
+
+The main function in \file{mean\_correction.cc} is mostly the same as in
+\file{main.cc}, except that it does not use a \class{ControlledMotion}
+instance but a \class{CorrectedMeanMotion} instance to control the Roomba. The
+profile that \class{CorrectedMeanMotion} uses is determined by the floor type
+given on the command line.
+
+\subsection{Implementation for Experiment~3: Application
+\prog{soft\_start\_test}}
+\label{sec:impl:soft}
+As the implementation for Experiment~2, the application \prog{soft\_start\_test}
+which is built from the file \file{soft\_start.cc} has the same basic layout as
+\file{main.cc} from Experiment~1. As previously, it defines a custom movement in
+the class \class{SoftStartMotion} (file \file{soft\_start\_motion.h}), which
+is also compatible with the interface defined by \class{ControlledMotion}. This
+class causes the Roomba to constantly accelerate at the start of the movement,
+and also constantly decelerate at the end of its movement, until the target
+distance or angle is reached.
+
+Internally, the class defines a time interval for the duration of the start and
+stop processes, and breaks down the process into multiple acceleration steps
+which each increase the velocity by a constant value, so for sufficient steps,
+the acceleration remains nearly constant. Therefore, a timer is used, which
+increases resp. decreases the velocity over time (depending if starting or
+stopping), until the target velocity or zero is reached, and sends \cmd{Drive}
+commands to the Roomba over the \ac{ROI}. The methods \fnfont{move\_distance}
+and \fnfont{turn\_to} on the other hand calculate the distance at which
+the deceleration process begins, and fire the initial timer to increase the
+velocity.
\section{Evaluation}
\label{sec:impl:eval}
-\todo{}
-
-bash/perl scripts in wiselib/trunk/pc\_apps/roomba\_tests/logs, using gnuplot
+For evaluation of the log files, a few Bash and Perl scripts were used. They
+use Gnuplot to plot graphs and \ac{GNU} R for statistical analysis, and reside
+in the Wiselib source tree under \filepath{apps/pc\_apps/roomba\_tests/logs}.
-graph.sh: create 3d plots (input value, input velocity, measured value) from
-original behvaiour data, including fit function calculated by GNU R statistics
-software, for {carpet floor, laminate floor} $\times$ {drive straight, turn on
-spot}
+\paragraph{\prog{graph.sh}}
+This wrapper script uses Gnuplot to create interactive 3-dimensional plots of
+the original behavior from Experiment~1, and also includes the fit function as
+determined by \ac{GNU} through linear regression. For each pair of ground type
+(carpet floor, laminate floor) and experiment type (straight movement, turn on
+spot), it opens a Gnuplot window containing a graph with the target value on the
+$x$ axis, the velocity on the $y$ axis and the measured value on the $z$ axis,
+and the fit function. The user can rotate and tilt the
+plot with the mouse.
-graph-mean.sh: do the same for mean correction data, including fit function from
-original data
+\paragraph{\prog{graph-mean.sh}} This script does the same as \prog{graph.sh},
+except it visualizes the measured data from Experiment~2 (Mean Correction), and
+a fit function for that data.
-graph-soft.sh: do the same for soft start/stop data, including fit function from
-original data
+\paragraph{\prog{graph-soft.sh}} Also, like both scripts mentioned above, this
+script uses the measured data from Experiment~3 (Constant Start/Stop
+Acceleration), and fit function for that data.
-graph-mean-soft.sh: 3d plot with mean correction and soft start/stop data, for
-comparison of both
+\paragraph{\prog{graph-mean-soft.sh}} This wrapper script plots both results
+from Experiment~2 and 3 into one coordinate system, for better comparison. It
+does not include the fit functions.
-graph-errorlines.sh: create 2d plots input value -> measured value, with
-multiple velocities in each graph. also split graphs up for {carpet floor,
-laminate floor} $\times$ {drive straight, turn on spot}. no fit function.
+\paragraph{\prog{graph-errorlines.sh}} In contrast to the other scripts,
+\prog{graph-errorlines.sh} plots the 2D graphs seen in
+Chapters~\ref{sec:exp1},~\ref{sec:exp2} and~\ref{sec:exp3}, with target value on
+the $x$ axis, measured value on the $y$ axis, and velocities as single
+functions each.