\chapter{Implementation}
\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 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 thesis} in the directory \filepath{apps/pc\_apps/roomba\_tests}.

\section{Measuring}
\label{sec:impl:measuring}

The measuring implementation is a set of programs running on a x86-compatible
Linux system which uses the Wiselib to control a Roomba attached to the system
over a serial interface. It features a graphical user interface using the
Qt application framework. Basically, it carries out a movement with specified
parameters (velocity, and destination or angle, depending on the experiment),
then prompts the user to measure and input the actual destination or angle the
Roomba has moved after it has finished the movement. In this context, the user
can choose between two operation modes. In the manual mode, the user can control
the target values for the Roomba movement himself, in automatic mode, the
application uses a list of pre-programmed values for the target values, so the
user only has to input the measured data.

\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 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:
    \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
    beginning and the end of the movement, on the Roomba's left wheel
    (packet~ID \magicvalue{0x2b} in the \ac{ROI} Specification)
  \item\texttt{diff\_ticks\_right:} the difference of encoder counts between the
    beginning and the end of the movement, on the Roomba's right wheel
    (packet~ID \magicvalue{0x2c} in the \ac{ROI} Specification)
  \item\texttt{raw\_ticks\_left:} the absolute value of the encoder count of the
    Roomba's left wheel (packet~ID \magicvalue{0x2b})
  \item\texttt{raw\_ticks\_right:} the absolute value of the encoder count of
    the Roomba's right wheel (packet~ID \magicvalue{0x2c})
  \item\texttt{batt\_charge:} the charge of the Roomba's battery in mAh
    (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 voltage of the Roomba's battery in mV
    (packet~ID~\magicvalue{0x16})
  \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}) 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 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
    original viewing direction (measured by the user)
  \item\texttt{measured\_y:} originally, the distance shift perpendicular to the
    viewing direction of the Roomba. Not used anymore.
  \item\texttt{deviation\_orientation:} originally, the shift in orientation of
    the Roomba. Not used anymore.
\end{enumerate}
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 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}[htbp]
  \centering
  \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: 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 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{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{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.

\paragraph{Input dialog for measured orientation values}
\hyphenation{Tar-get-Va-lue-In-put-Dia-log}

\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.

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.

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.

\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}.

\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.

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.

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.

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.

\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}
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}.

\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.

\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.

\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.

\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.

\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.
