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