final tweaks
[bachelor-thesis/written-stuff.git] / Ausarbeitung / implementation.tex
1 \chapter{Implementation}
2 \hyphenation{im-ple-men-ta-tion im-ple-men-ta-tion-spe-ci-fic}
3 This chapter describes the implementation that was used for the aforementioned
4 experiments. It consists of the measuring programs themselves, which use the
5 Wiselib Roomba Control, and are written in C++. Additionally, there are several
6 Bash and Perl scripts to assist in the analysis of the measured data.
7
8 All code used for this thesis resides in the Wiselib source tree\footnote{see
9 \url{https://github.com/ibr-alg/wiselib/}, or the \acs{CDROM} attached at the
10 end of this thesis} in the directory \filepath{apps/pc\_apps/roomba\_tests}.
11
12 \section{Measuring}
13 \label{sec:impl:measuring}
14
15 The measuring implementation is a set of programs running on a x86-compatible
16 Linux system which uses the Wiselib to control a Roomba attached to the system
17 over a serial interface. It features a graphical user interface using the
18 Qt application framework. Basically, it carries out a movement with specified
19 parameters (velocity, and destination or angle, depending on the experiment),
20 then prompts the user to measure and input the actual destination or angle the
21 Roomba has moved after it has finished the movement. In this context, the user
22 can choose between two operation modes. In the manual mode, the user can control
23 the target values for the Roomba movement himself, in automatic mode, the
24 application uses a list of pre-programmed values for the target values, so the
25 user only has to input the measured data.
26
27 \paragraph{Logging}
28 All measured data is written to a log file in the current directory whose name
29 is based on the type of experiment performed. Every line in that log file
30 describes one measurement made by the user, and consists of pairs of the form
31 \code{key=value}, separated by white space. In particular, the data on each
32 line are (with key name, in the order of appearance on the line):
33 \begin{enumerate}[noitemsep]
34 \item\texttt{svn:} the \ac{SVN} or Git revision the program was compiled from
35 (statically compiled into the program)
36 \item\texttt{roomba\_id:} the ID of the Roomba the measurement was performed
37 with (given by the user)
38 \item\texttt{ground\_type:} the ground type used for measurement:
39 \magicvalue{iz250flur} for laminated floor, \magicvalue{seminarraum}
40 for carpet floor (given by the user)
41 \item\texttt{diff\_ticks\_left:} the difference of encoder counts between the
42 beginning and the end of the movement, on the Roomba's left wheel
43 (packet~ID \magicvalue{0x2b} in the \ac{ROI} Specification)
44 \item\texttt{diff\_ticks\_right:} the difference of encoder counts between the
45 beginning and the end of the movement, on the Roomba's right wheel
46 (packet~ID \magicvalue{0x2c} in the \ac{ROI} Specification)
47 \item\texttt{raw\_ticks\_left:} the absolute value of the encoder count of the
48 Roomba's left wheel (packet~ID \magicvalue{0x2b})
49 \item\texttt{raw\_ticks\_right:} the absolute value of the encoder count of
50 the Roomba's right wheel (packet~ID \magicvalue{0x2c})
51 \item\texttt{batt\_charge:} the charge of the Roomba's battery in mAh
52 (packet~ID~\magicvalue{0x19})
53 \item\texttt{batt\_capacity:} the capacity of the Roomba's battery in mAh
54 (packet~ID~\magicvalue{0x1a})
55 \item\texttt{batt\_voltage:} the voltage of the Roomba's battery in mV
56 (packet~ID~\magicvalue{0x16})
57 \item\texttt{batt\_voltage:} the current of the Roomba's battery in mA
58 (packet~ID~\magicvalue{0x17})
59 \item\texttt{move:} movement type; \magicvalue{straight} for straight moves,
60 \magicvalue{turn} for turn moves (given by the user while selecting the
61 experiment type)
62 \newcounter{logitems}\setcounter{logitems}{\value{enumi}+1}
63 \end{enumerate}
64 For straight moves (\magicvalue{move=straight}) follow:
65 \begin{enumerate}[noitemsep,start=\value{logitems}]
66 \item\texttt{input\_distance}: the target distance in mm sent to the Roomba
67 via the \ac{ROI} \cmd{Drive} command (given by the user in manual mode,
68 or determined by the program in automatic mode)
69 \item\texttt{velocity:} (the velocity in mm/s sent to the Roomba via the
70 \ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
71 determined by the program in automatic mode)
72 \item\texttt{measured\_x:} the actual covered distance in mm in the Roomba's
73 original viewing direction (measured by the user)
74 \item\texttt{measured\_y:} originally, the distance shift perpendicular to the
75 viewing direction of the Roomba. Not used anymore.
76 \item\texttt{deviation\_orientation:} originally, the shift in orientation of
77 the Roomba. Not used anymore.
78 \end{enumerate}
79 For turn moves (\magicvalue{move=turn}) follow:
80 \begin{enumerate}[noitemsep,start=\value{logitems}]
81 \item\texttt{turn\_angle:} the turn angle in degree sent to the Roomba via the
82 \ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
83 determined by the program in automatic mode)
84 \item\texttt{measured\_angle:} the actual turned angle of the Roomba in degree
85 (measured by the user)
86 \item\texttt{velocity:} the velocity in mm/s sent to the Roomba via the
87 \ac{ROI} \cmd{Drive} command (given by the user in manual mode, or
88 determined by the program in automatic mode)
89 \end{enumerate}
90
91 \begin{figure}[htbp]
92 \centering
93 \includegraphics[width=0.9\textwidth]{images/Implementation-Diagram.pdf}
94 \caption[File structure of the measuring implementation]{Simplified file
95 structure of the measuring implementation\label{fig:impl:struct}\\
96 yellow: common files used for all three experiments; \\
97 green: files for Experiment~1; blue: files for Experiment~2; \\red: files
98 for Experiment~3.\\
99 An arrow from node $x$ to node $y$ is to be read as ``$y$ depends from
100 $x$''.}
101 \end{figure}
102
103 Figure~\ref{fig:impl:struct} shows the file layout of the measuring
104 implementation. It reuses components where ever possible, and therefore
105 consists of three parts (green, blue, red) specific for the three performed
106 experiments (see Sections~\ref{sec:exp1}, \ref{sec:exp2} and~\ref{sec:exp3}), as
107 well as a common part (yellow), which contains the elements of the
108 implementation shared by the other three parts.
109
110 \subsection{Common part}
111 % no \file{} here please, we don't want "stuff.{cc,h}" in index...
112 The files \filefont{stuff.\{cc,h\}} and
113 \filefont{target\_value\_input\_dialog.\{cc,h\}} build up the general part of
114 the implementation (shown with a yellow background in
115 Figure~\ref{fig:impl:struct}). These are included in all other three parts of
116 the implementation.
117
118 \paragraph{Global declarations}
119 These files \file{stuff.cc} and \file{stuff.h} contain global helper functions
120 and variables, data structures specific to the implementation, and all kinds of
121 convenient typedefs. In particular, there are functions for formatting and
122 logging messages to a log file, according to the format described above. While
123 \file{stuff.h} contains the declarations and typedefs, \file{stuff.cc} contains
124 the appropriate definitions. Besides, since \file{stuff.h} is included
125 indirectly in most other source files, it also includes the Wiselib headers
126 needed for Roomba control.
127
128 \paragraph{Input dialog for measured orientation values}
129 \hyphenation{Tar-get-Va-lue-In-put-Dia-log}
130
131 \begin{figure}
132 \centering
133 \includegraphics[width=0.4\textwidth]{images/target_value_input_dialog.png}
134 \caption{The \class{TargetValueInputDialog}}
135 \end{figure}
136
137 The class \class{TargetValueInputDialog}, which is an implementation of a simple
138 dialog box using the Qt widget framework, resides in the files
139 \file{target\_value\_input\_dialog.cc} and
140 \file{target\_value\_input\_dialog.h}. This dialog allows the user to input a
141 measured angle (although the name mentions a ``target value'', which is probably
142 named this way only for the sake of confusion\ldots). It contains an input box
143 with adjacent spin box for entering the measured value, OK and Cancel buttons,
144 and also information about the target orientation and the current real
145 orientation as well as the current capacity of the Roomba's battery.
146
147 When the dialog is displayed, it obtains the orientation as it was before the
148 last movement, and the target angle, and sets the input box to the specified
149 target value. When the input box is changed, the dialog calculates the new
150 orientation from the last orientation and the value in the input box, and
151 displays this new orientation. This way, the user can simply enter the measured
152 angle by increasing or decreasing the value by operating the spin box, and
153 adjusting the value until the displayed orientation reflects the real
154 orientation of the Roomba.
155
156 To achieve this, the class uses the Qt signal-slot
157 mechanism~\cite{qt-signalslots}, and connects the \fnfont{intValueChanged(int)}
158 signal of the input box to the method
159 \fnfont{turn\_dialog\_value\_changed(int)},
160 which performs the calculation and display of the new value.
161
162 \subsection{Implementation for Experiment~1: Application \prog{roomba\_test}}
163 The implementation for Experiment~1 is used to build the application
164 \prog{roomba\_test}. Its main part is constituted by the file \file{main.cc},
165 which uses the global definitions of \file{stuff.h} and the dialog box from
166 \file{target\_value\_input\_dialog.h}.
167
168 \paragraph{Initial setup}
169 The program first checks for command line arguments, where it expects the type
170 of test performed and if automatic or manual mode, the ground type, and the
171 Roomba's ID, or the \code{-{}-help} switch to display a usage message.
172
173 After that, it instantiates and initializes a \class{RoombaModel} instance,
174 while also providing for the needed instances of the \concept{Timer} concept
175 and the \concept{SerialCommunication} concept, which is needed for the serial
176 communication with the Roomba. Furthermore, an instance of
177 \class{ControlledMotion} is initialized by passing the \class{RoombaModel}
178 instance. This instance is later used to control the Roomba's movements.
179
180 Due to an implementation detail inside the \class{RoombaModel} class, the sensor
181 data returned by the class itself may be corrupt if it is read while new sensor
182 data packets arriving from the Roomba are processed. To prevent this corruption,
183 we register a callback function which gets called every time new sensor data is
184 available (i.~e. the sensor data packets have been fully processed, which is
185 every 15~ms as we are using the \cmd{Stream} command), and let the callback
186 function perform a deep copy of the sensor values we are interested in.
187
188 If the user has specified automated measurement on the command line, an array of
189 velocities and target values is set up, as described in
190 Section~\ref{sec:exp1:setup}, and slightly scrambled to ensure independence of
191 the measurements. Furthermore, the file name for the log file to record the
192 measured values is determined from the operation mode, the type of experiment
193 performed, and the Unix time stamp\footnote{The Unix time stamp is a signed
194 integer which is defined as the seconds elapsed since January 1st, 1970, 0:00
195 \ac{UTC}}. To ease measurement of angles, if the type of experiments are turn
196 movements, the user is prompted once to input the current orientation of the
197 Roomba.
198
199 \paragraph{Input/measurement loop}
200 The rest of the program consists of a loop which does the following things:
201 \begin{enumerate}[noitemsep]
202 \item \textbf{In manual mode:} Prompt the user for a new pair of velocity and
203 input value \\
204 \textbf{In automatic mode:} For each pair of velocity and input value
205 specified in the previously defined arrays, do the following:
206 \item Carry out the specified movement using the \class{ControlledMotion}
207 instance
208 \item Prompt the user for the measured value using the
209 \class{TargetValueInputDialog} for angles, or a simple Qt
210 \class{QInputDialog} for distances
211 \item Write the values to the log file, as specified at the beginning of this
212 section, using the log function from \file{stuff.h}
213 \item Repeat until the user cancels.
214 \end{enumerate}
215
216 \subsection{Implementation for Experiment~2:
217 Application \prog{mean\_correction\_test}}
218 \label{sec:impl:mean}
219 Additionally, the program \prog{mean\_correction\_test} for Experiment~2 uses
220 the class \class{CorrectedMeanMotion} from \file{corrected\_mean\_motion.h}.
221 This class adapts the input value according to the fit function determined from
222 the data in Experiment~1 (see Chapter~\ref{sec:exp2}), and exposes the exact
223 interface as \class{ControlledMotion} does. Thus, both classes are easily
224 interchangeable, and \class{CorrectedMeanMotion} serves as an example of the
225 stackability principle mentioned in Section~\ref{sec:wiselib:arch}.
226
227 The essential parts of \class{CorrectedMeanMotion} are the functions
228 \fnfont{set\_profile} to specify the fit function (i.~e. the ground type),
229 and \fnfont{move\_distance} and \fnfont{turn\_to} which use that specified fit
230 function to adapt the input value (angle or distance) and then move the Roomba
231 around accordingly. As in the implementation of \class{ControlledMotion}, the
232 encoding counts of the Roomba's wheels are monitored to determine when the
233 Roomba has to be stopped.
234
235 The main function in \file{mean\_correction.cc} is mostly the same as in
236 \file{main.cc}, except that it does not use a \class{ControlledMotion}
237 instance but a \class{CorrectedMeanMotion} instance to control the Roomba. The
238 profile that \class{CorrectedMeanMotion} uses is determined by the floor type
239 given on the command line.
240
241 \subsection{Implementation for Experiment~3: Application
242 \prog{soft\_start\_test}}
243 \label{sec:impl:soft}
244 As the implementation for Experiment~2, the application \prog{soft\_start\_test}
245 which is built from the file \file{soft\_start.cc} has the same basic layout as
246 \file{main.cc} from Experiment~1. As previously, it defines a custom movement in
247 the class \class{SoftStartMotion} (file \file{soft\_start\_motion.h}), which
248 is also compatible with the interface defined by \class{ControlledMotion}. This
249 class causes the Roomba to constantly accelerate at the start of the movement,
250 and also constantly decelerate at the end of its movement, until the target
251 distance or angle is reached.
252
253 Internally, the class defines a time interval for the duration of the start and
254 stop processes, and breaks down the process into multiple acceleration steps
255 which each increase the velocity by a constant value, so for sufficient steps,
256 the acceleration remains nearly constant. Therefore, a timer is used, which
257 increases resp. decreases the velocity over time (depending if starting or
258 stopping), until the target velocity or zero is reached, and sends \cmd{Drive}
259 commands to the Roomba over the \ac{ROI}. The methods \fnfont{move\_distance}
260 and \fnfont{turn\_to} on the other hand calculate the distance at which
261 the deceleration process begins, and fire the initial timer to increase the
262 velocity.
263
264 \section{Evaluation}
265 \label{sec:impl:eval}
266 For evaluation of the log files, a few Bash and Perl scripts were used. They
267 use Gnuplot to plot graphs and \ac{GNU} R for statistical analysis, and reside
268 in the Wiselib source tree under \filepath{apps/pc\_apps/roomba\_tests/logs}.
269
270 \paragraph{\prog{graph.sh}}
271 This wrapper script uses Gnuplot to create interactive 3-dimensional plots of
272 the original behavior from Experiment~1, and also includes the fit function as
273 determined by \ac{GNU} through linear regression. For each pair of ground type
274 (carpet floor, laminate floor) and experiment type (straight movement, turn on
275 spot), it opens a Gnuplot window containing a graph with the target value on the
276 $x$ axis, the velocity on the $y$ axis and the measured value on the $z$ axis,
277 and the fit function. The user can rotate and tilt the
278 plot with the mouse.
279
280 \paragraph{\prog{graph-mean.sh}} This script does the same as \prog{graph.sh},
281 except it visualizes the measured data from Experiment~2 (Mean Correction), and
282 a fit function for that data.
283
284 \paragraph{\prog{graph-soft.sh}} Also, like both scripts mentioned above, this
285 script uses the measured data from Experiment~3 (Constant Start/Stop
286 Acceleration), and fit function for that data.
287
288 \paragraph{\prog{graph-mean-soft.sh}} This wrapper script plots both results
289 from Experiment~2 and 3 into one coordinate system, for better comparison. It
290 does not include the fit functions.
291
292 \paragraph{\prog{graph-errorlines.sh}} In contrast to the other scripts,
293 \prog{graph-errorlines.sh} plots the 2D graphs seen in
294 Chapters~\ref{sec:exp1},~\ref{sec:exp2} and~\ref{sec:exp3}, with target value on
295 the $x$ axis, measured value on the $y$ axis, and velocities as single
296 functions each.
This page took 0.068748 seconds and 5 git commands to generate.