\section{Wiselib}
-The \definition{Wiselib}\cite{wiselib} is a C++\index{C++} algorithm library for
+The \definition{Wiselib}\cite{wiselib} is a C++ algorithm library for
sensor networks, containing for example algorithms for routing, localization and
time synchronization, and is strongly focused on portability and cross-platform
development. In particular, it allows the user to develop applications that run
on different hardware platforms without the need to change the code, and it
strongly uses C++ templates to achieve that feature. Amongst the supported
-platforms are diverse sensor node platforms, like iSense, Contiki and TinyOS,
-but there are as well implementations for the diverse x86-compatible Personal
-Computer platforms, and the Shawn sensor network simulator.
+platforms are diverse sensor node platforms, like iSense\footnote{see
+\url{http://www.coalesenses.com/index.php?page=isense-hardware}},
+Contiki\footnote{\url{http://www.sics.se/contiki/about-contiki.html}}, and
+TinyOS\footnote{\url{http://www.tinyos.net/}}, but there is as well support for
+the diverse x86-compatible Personal Computer platforms, and the Shawn sensor
+network simulator\footnote{\url{http://shawn.sourceforge.net}}.
\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,
functionality, so a function call will be immediately resolved to a specific
model at compile time without the need for an additional function call as it is
the case with virtual inheritance. Furthermore, this also allows usage on
-platforms which do not have support for C++, as the bytecode generated by the
+platforms which do not support C++, as the byte code generated by the
compiler does not include C++ specific extensions (no virtual function tables,
and templates are resolved at compile time) and can be linked against any
Standard C Library.
This makes cross-platform development easily possible. For example, to implement
-a routing algorithm, one can rely on the concept of a Radio to send and receive
+a routing algorithm, one can rely on the concept of a radio to send and receive
data packets, without needing to implement code specific to the used radio
hardware. The users of that routing algorithm can now choose which radio model
they want to use, according to their needs and the underlying hardware, provided
-that their radio model also implements the same Radio concept that the routing
-algorithm uses.
+that their radio model also implements the same radio concept used by the
+routing algorithm.
\begin{figure}
\centering
\end{figure}
Besides algorithms, and basic concepts and models, the Wiselib also consists of
two other main parts: the internal interface and the external interface (see
-Figure \ref{fig:wiselib-arch}).
+Figure~\ref{fig:wiselib-arch}).
\paragraph{External Interface}
The \definition{External Interface} provides access to the underlying \ac{OS},
-like iSense, Contiki, Shawn\ldots and defines concepts like a Radio or a Timer.
+like iSense, Contiki, Shawn, etc. and defines concepts like a radio or a timer.
Thus, the concepts are as generic as possible to match all supported operating
systems and provide a light-weight abstraction to the underlying \ac{OS}. These
-concepts sometimes extend the generic concepts, for example there is a TxRadio
+concepts sometimes extend the generic concepts. As an example there is a
+concept \concept{TxRadio}
which has the ability to set the transmission power on the radio. The models
-(for example an iSenseRadioModel or a ShawnTimerModel) implement these concepts
+(for example an \class{iSenseRadioModel} or a \class{ShawnTimerModel}) implement
+these concepts
on the specific operating system, and can be passed around as template
parameters.
\paragraph{Internal Interface}
The \definition{Internal Interface} defines concepts and models for data
-structures that can be used in algorithms. This allows to specialize for
-restricted platforms; for instance a wireless sensor node without dynamic memory
+structures that can be used in algorithms. This allows the specialization for
+platforms with more restricted resources; for instance a wireless sensor node
+without dynamic memory
management can use a static implementation of lists and other containers,
-whereas a full-grown desktop can use the dynamic implementation provided by the
+whereas a full-grown desktop machine can use the dynamic implementation provided
+by the
C++ \ac{STL}. For this purpose, the Wiselib also contains the
-\acused{pSTL}\definition{\acl{pSTL}} (\acs{pSTL}) which implements a
-subset of the \ac{STL} without the use of dynamic memory allocation.
+\acused{pSTL}\definition{pico Standard Template Library} (\acs{pSTL}) which
+implements a subset of the \ac{STL} without the use of dynamic memory
+allocation.
\paragraph{Stackability}
Another central design principle used in the Wiselib is
\subsection{Roomba Control}
Even more interesting is the fact that the Wiselib includes code to control an
iRobot Roomba\index{Roomba} over a serial interface, and getting access to its
-internal sensor data, using the \acl{ROI}\index{\acl{ROI}} mentioned earlier.
-For this purpose, it defines two concepts for Robot Motion:
+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:
+ \item 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
-\definition{ControlledMotion} model. It takes implementations of each of these
+\paragraph{ControlledMotion model}
+The \class{ControlledMotion} model builds on top of the \concept{TurnWalkMotion}
+and \concept{Odometer} concepts. 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.
+a temporal dimension, which makes 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
+\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
-TurnWalkMotion instance. Everytime the state of the robot changes (i.~e. new
-data from its sensors are received), it compares the new actual values with the
+TurnWalkMotion instance. Every time the state of the robot changes (i.~e. new
+data from its sensors is received), it compares the new actual values with the
target values given by the user through the functions above, and if the actual
values exceed the target values, the robot is stopped.
\paragraph{Underlying Roomba Implementation}
-The actual communication with the Roomba is done in the \definition{RoombaModel}
-class. It implements the aforementioned TurnWalkMotion \index{TurnWalkMotion
-(concept)} and Odometer \index{Odometer (concept)} concepts and therewith allows
-the interaction with a ControlledMotion 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.
+The actual communication with the Roomba is done in the
+\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. It also reads a subset of the Roomba's sensors and presents the sensor
+data to the user. Finally, while implementing the Odometer concept, it
+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
\ref{sec:roi-stream-packet}) every 15~ms, and $66.67$ packets per second. At a
speed of 19,200 baud in mode \ac{8N1}, the maximum size of a data packet is
$19,200 \div (66.67 \times 9) = 32$ byte, so at the moment only the sensor
-packets \emph{encoder counts left/right} (IDs~\magicnumber{0x2b},
-\magicnumber{0x2c}, 2+2 bytes), \emph{battery voltage/current/charge/capacity}
-(IDs~\magicnumber{0x16}, \magicnumber{0x17}, \magicnumber{0x19},
-\magicnumber{0x1a}, 2+2+2+2 bytes) are streamed, which add up to 18 data bytes +
+packets \emph{encoder counts left/right} (IDs~\magicvalue{0x2b},
+\magicvalue{0x2c}, 2+2 bytes), \emph{battery voltage/current/charge/capacity}
+(IDs~\magicvalue{0x16}, \magicvalue{0x17}, \magicvalue{0x19},
+\magicvalue{0x1a}, 2+2+2+2 bytes) are streamed, which add up to 18 data bytes +
3 header/checksum bytes. There has currently been no success yet in
communicating at the higher speed of 115,200 baud.
-Also there has been research to use the distance and angle values that the
-Roomba itself provides (sensor packet~IDs \magicnumber{0x13} and
-\magicnumber{0x14}). However, according to the \ac{ROI} Specification these
+Also research has been done to use the distance and angle values that the
+Roomba itself provides (sensor packet~IDs \magicvalue{0x13} and
+\magicvalue{0x14}). However, according to the \ac{ROI} Specification these
values are integer values, and the value is reset to zero every time it is read.
By using the \cmd{Stream} command on the \ac{ROI} and therefore reading these
values every 15~ms, the Roomba cannot move fast enough to increment these values
-to \magicnumber{1}, so everytime \magicnumber{0} is read. It is obvious that
+to \magicvalue{1}, so every time \magicvalue{0} is read. It is obvious that
these sensor values are not suited for such rapid evaluations, and can only be
used for larger distances and angles. Nevertheless, since the Wiselib Roomba
control needs to keep track of the Roomba's current position and orientation as
fast as possible to maintain a certain accuracy in movement, the distance and
angle values as provided by the Roomba itself cannot be used. On the other hand,
working with the Roomba's wheel encoder counts (sensor packet~IDs
-\magicnumber{0x2b} and \magicnumber{0x2c}) has proven itself quite acceptable.
+\magicvalue{0x2b} and \magicvalue{0x2c}) has proven itself quite acceptable.
After a few test runs, the number of encoder counts per~mm for straight
-walks turned out as $2.27$, and for turning on the spot, $2.27 \times 115 =
+walks turned out to be $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}
+multiplied by half the Roomba's wheelbase. So when new sensor data is read
+each 15~ms, the RoombaModel implementation calculates the \concept{Odometer}
+distance and angle from these values.