\chapter{Implementation}
+\hyphenation{im-ple-men-ta-tion im-ple-men-ta-tion-spe-ci-fic}
\todo{more?}
This chapter describes the implementation that was used for the aforementioned
experiments. It consists of the measuring programs themselves, which use 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 of by whitespace. In particular, the data on each
line are (with key name, in the order of appearance on the line):
-\begin{enumerate}
- \setlength{\itemsep}{1pt}
+\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
(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{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}[start=\value{logitems}]
+\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
the Roomba. Not used anymore.
\end{enumerate}
For turn moves (\magicvalue{move=turn}) follow:
-\begin{enumerate}[start=\value{logitems}]
+\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: common files used for all three experiments; green: files for
\subsection{Common part}
% no \file{} here please, we don't want "stuff.{cc,h}" in index...
-The files \code{stuff.\{cc,h\}} and \code{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 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 helper functions and variables,
-implementation-specific data structures 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{\file{target\_value\_input\_dialog.cc} and
-\file{target\_value\_input\_dialog.h}}
-These files contain the class \code{TargetValueInputDialog}
-\index{TargetValueInputDialog}, an implementation of a dialog box that allows
-the user to input a measured angle (although the names mention a ``target
-value'', it does that probably only to increase the confusion\ldots). This is a
-typical Qt dialog which 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.
+\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}
+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
orientation of the Roomba.
To achieve this, the class uses the Qt signal-slot
-mechanism~\cite{qt-signalslots}, and connects the \code{intValueChanged(int)}
-signal of the input box to the method \code{turn\_dialog\_value\_changed(int)},
+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}
+\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.
-\subsection{Implementation for Experiment~2}
-\subsection{Implementation for Experiment~3}
+After that, it instanciates 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.
-three single applications with same base: roomba\_test (main.cc),
-mean\_correction\_test (mean\_correction.cc), soft\_start\_test
-(soft\_start.cc).
+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 everytime 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.
-1) open UART connection
+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 timestamp\footnote{The Unix timestamp 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.
-2) register state callback for getting roomba sensor data
+\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 definied 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}
-3) while(input values or cancel) { drive() / turn() }
+\subsection{Implementation for Experiment~2:
+Application \prog{mean\_correction\_test}}
+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}.
-4) drive() / turn() use wiselib::ControlledMotion<OsModel,
-wiselib::RoombaModel> for moving specified angle/distance; and ask for measured
-values and write to log
+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.
-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 .
+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.
-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.
+\subsection{Implementation for Experiment~3: Application
+\prog{soft\_start\_test}}
+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 behaviour 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.
Computer platforms, and the Shawn sensor network simulator.
\subsection{Architecture}
+\label{sec:wiselib:arch}
\paragraph{Concepts and Models}
Wiselib makes strong uses of \definition{concepts} and \definition{models} as
central design objects. Concepts serve as an informal description of interfaces,
internal sensor data, using the \ac{ROI}\index{Roomba Open Interface} mentioned
earlier. For this purpose, it defines two concepts for Robot Motion:
-\paragraph{TurnWalkMotion concept}\index{TurnWalkMotion (concept)}
+\paragraph{\concept{TurnWalkMotion} concept}%\index{TurnWalkMotion (concept)}
This concept represents a simple robot that can turn on the spot and walk
straight, without automatic stopping.
\begin{description}
\item Types:
\begin{description}
- \item[\code{velocity\_t}] Type for velocity measurement
- \item[\code{angular\_velocity\_t}] Type for angular velocity measurement
+ \item[\fnfont{velocity\_t}] Type for velocity measurement
+ \item[\fnfont{angular\_velocity\_t}] Type for angular velocity measurement
\end{description}
\item \todo{clearpage?} Methods:
\begin{description}
- \item[\code{int turn(angular\_velocity\_t)}] turn the robot with a
+ \item[\fnfont{int turn(angular\_velocity\_t)}] turn the robot with a
constant angular velocity
- \item[\code{int move (velocity\_t)}] move the robot straight with a
+ \item[\fnfont{int move (velocity\_t)}] move the robot straight with a
constant velocity
- \item[\code{int stop()}] stop the robot
- \item[\code{int wait\_for\_stop()}] hold the execution until the robot has
- stopped
+ \item[\fnfont{int stop()}] stop the robot
+ \item[\fnfont{int wait\_for\_stop()}] hold the execution until the robot
+ has stopped
\end{description}
\end{description}
-\paragraph{Odometer concept}\index{Odometer (concept)}
+\paragraph{\concept{Odometer} concept}%\index{Odometer (concept)}
This concept represents an Odometer which tracks motions over time.
Whenever the object turns or moves, internal counters will adjust their
guessing of the object's traveled distance and current orientation.
\begin{description}
\item Types:
\begin{description}
- \item[\code{angle\_t}] Type for angle measurement
- \item[\code{distance\_t}] Type for distance measurement
+ \item[\fnfont{angle\_t}] Type for angle measurement
+ \item[\fnfont{distance\_t}] Type for distance measurement
\end{description}
\item Methods:
\begin{description}
- \item[\code{angle\_t angle()}] return the current angle
- \item[\code{int reset\_angle()}] reset the angle of the object
- \item[\code{distance\_t distance()}] return the current distance
- \item[\code{int reset\_distance()}] reset the distance of the object
- \item[\code{int register\_state\_callback (T *obj)}] register a callback
+ \item[\fnfont{angle\_t angle()}] return the current angle
+ \item[\fnfont{int reset\_angle()}] reset the angle of the object
+ \item[\fnfont{distance\_t distance()}] return the current distance
+ \item[\fnfont{int reset\_distance()}] reset the distance of the object
+ \item[\fnfont{int register\_state\_callback (T *obj)}] register a callback
that gets called when the state changes
- \item[\code{int unregister\_state\_callback (int)}] unregister a
+ \item[\fnfont{int unregister\_state\_callback (int)}] unregister a
previously registered callback
- \item[\code{int state()}] return the current state
+ \item[\fnfont{int state()}] return the current state
\end{description}
\end{description}
-\paragraph{ControlledMotion class}\index{ControlledMotion (class)}
-On top of the TurnWalkMotion and Odometer concepts builds the
-\textit{ControlledMotion}\index{ControlledMotion (class)} model. It takes
-implementations of each of these concepts as template parameters and extends the
-simple turn-and-walk paradigm by a temporal dimension, which let the robot stop
-after a specific time interval. In particular, it provides the following
-methods:
-\begin{description}
- \item[\code{int move\_distance(distance\_t, velocity\_t)}] move the robot
+\paragraph{ControlledMotion model}
+On top of the \concept{TurnWalkMotion} and \concept{Odometer} concepts builds
+the \class{ControlledMotion} model. It takes implementations of each of these
+concepts as template parameters and extends the simple turn-and-walk paradigm by
+a temporal dimension, which let the robot stop after a specific time interval.
+In particular, it provides the following methods:
+\begin{description}\item
+\begin{description} % to match with the indentation level above
+ \item[\fnfont{int move\_distance(distance\_t, velocity\_t)}] move the robot
straight by a given distance with a given velocity
- \item[\code{int turn\_about(angle\_t, angular\_velocity\_t)}] turn the robot
+ \item[\fnfont{int turn\_about(angle\_t, angular\_velocity\_t)}] turn the robot
about a given angle with a given angular distance
- \item[\code{int turn\_to(angle\_t, angular\_velocity\_t)}] turn the robot
+ \item[\fnfont{int turn\_to(angle\_t, angular\_velocity\_t)}] turn the robot
to a given orientation with a given angular distance
\end{description}
+\end{description}
The class first registers a callback function at the given Odometer instance,
and then uses its distance and angle values to control the robot over the
\paragraph{Underlying Roomba Implementation}
The actual communication with the Roomba is done in the
-\textit{RoombaModel}\index{RoombaModel (class)} class. It implements the
-aforementioned TurnWalkMotion\index{TurnWalkMotion (concept)} and
-Odometer\index{Odometer (concept)} concepts and therewith allows the interaction
-with a ControlledMotion\index{ControlledMotion (class)} instance. In particular,
-it manages the serial communication with the Roomba and translates the function
-calls \code{turn()}, \code{move()} and \code{stop()} of the TurnWalkMotion
-concept to the according parameters for the \ac{ROI} \cmd{Drive} command, reads
-a subset of the Roomba's sensors and presents the sensor data to the user, and,
-while implementing the Odometer concept, calculates the covered distance and
-angle from the Roomba's right and left wheel rotations.
+\class{RoombaModel} class. It implements the
+aforementioned \concept{TurnWalkMotion} and \concept{Odometer} concepts and
+therewith allows the interaction with a \class{ControlledMotion} instance. In
+particular, it manages the serial communication with the Roomba and translates
+the function calls \fnfont{turn()}, \fnfont{move()} and \fnfont{stop()} of the
+TurnWalkMotion concept to the according parameters for the \ac{ROI} \cmd{Drive}
+command, reads a subset of the Roomba's sensors and presents the sensor data to
+the user, and, while implementing the Odometer concept, calculates the covered
+distance and angle from the Roomba's right and left wheel rotations.
The sensor data is read from the Roomba using the \cmd{Stream} command on the
\ac{ROI}, which results in a sensor data packet (see Section
walks turned out as $2.27$, and for turning on the spot, $2.27 \times 115 =
261.05$ encoder counts per radian, which is the number of encoder counts per~mm
multiplicated with half the Roomba's wheelbase. So when new sensor data is read
-each 15~ms, the RoombaModel implementation calculates the Odometer
-\index{Odometer (concept)} distance and angle from these values.
-
-\todo{cite Wisebed book chapter on Roomba code}
+each 15~ms, the RoombaModel implementation calculates the \concept{Odometer}
+distance and angle from these values.