/**
\page note_yarp_philosophy Software for Humanoid Robots: The YARP Approach

\tableofcontents

Researchers in humanoid robotics find themselves with a complicated
pile of hardware to control with an equally complicated pile of
software.  Achieving visual, auditory, and tactile perception while
performing elaborate motor control in real-time requires a lot of
processor cycles. The most practical way to get those cycles at the
moment is to have a cluster of computers. Every year the capabilities
of an individual machine grows, but so also do our demands; humanoid
robots stretch the limits of current technology, and are likely to do
so for the foreseeable future.  Moreover, software easily becomes
entangled with the hardware on which it runs and the devices that it
controls.  This limits modularity and code reuse which, in turn,
complicates software development and maintainability. In the last few
years we have been developing a software platform called YARP to ease
these tasks and improve the software quality on our robot platforms.
We want to reduce the effort devoted to infrastructure-level
programming to increase the time spent doing research-level
programming. At the same time, we would like to have stable robot
platforms to work with.  Today YARP is a platform for long-term
software development for applications that are real-time,
computation-intensive, and involve interfacing with diverse and
changing hardware.

We summarize here some of the lessons we have learned over
the years while working on various robots, some of which are
software engineering commonplaces and some of which are more
specific to long-term robotic research.




\section philosophy_many One processor is never enough.

Designing a robot control system as a set of processes running on a
set of computers is a good way to work. It minimizes time spent wrestling with
code optimization, rewriting other people's code, and maximizes
time spent actually doing research.  The heart of YARP is a
communications mechanism to make writing and running such processes as
easy as possible. Even where mobility is required this is not a limiting
factor if tethers or wireless communication are acceptable.



\section philosophy_module Modularity.

Code is better maintained and reused if it is organized in small
processes, each one performing a simple task. In a cluster of
computers some processes are bound to specific machines (usually when
they require a particular hardware device), and some
can run on any of the available computers.  With YARP it is easy to
write processes that are location independent and that can run on
different machines without code changes. This allows us to move
processes across the cluster at runtime to redistribute the
computational load on the CPUs, to recover from a hardware failure,
or to follow a physical device that has been moved to another machine.
YARP does not contain any means of automatically allocating processes
as in some approaches like GRID. We deliberately assign
this task to the developer.  The rationale is that: i) the link
between hardware and corresponding control software is subject to
constraints understood by the developer but cumbersome to encode,
particularly in a continually-changing research environment, and
 ii) in an heterogeneous network of processors, faster processors
might need to be allocated differently from slower processors. The
final behavior is that of a sort of ``soft real-time'' parallel
computation cluster without the more demanding requirements of a
real-time operating system.



\section philosophy_interfere Minimal interference.

As long as enough resources are available, the addition of new
components should minimally interfere with existing processes. This is
important, since often the actual performance of a robot controller
depends on the timing of various signals.  While this is not strictly
guaranteed by the YARP infrastructure, the problem is in practice
alleviated computationally by allowing the inclusion of more
processors to the network, and from the communication point of view by
the buffer policy.



\section philosophy_stopping Stopping hurts.

It is a commonplace that human cycles are much, much more expensive
than machine cycles.  In robotics, it turns out that the human
cost of stopping and restarting a process can be very high.
For example, that process may interface with some
custom hardware which requires a physical reset.
That reset many need to be carefully ordered with respect to when the
process is stopped and started.
There may be other dependent processes that need to be restarted in
turn, and other dependent hardware.
These ordering constraints are time-consuming to satisfy.
YARP does its part to minimize dependencies between processes.
Communication channels between processes can come and go without
process restarts.
A process that is killed or dies
unexpectedly does not require processes to which it connects to be
restarted. This also simplifies cooperation between people, as
it minimizes the need to synchronize development on different
parts of the system.



\section philosophy_humility Humility helps.

Over time, software for a sophisticated robot needs to aggregate code
written by many different people in many different contexts.
Doubtless that code will have dependencies on various communication,
image processing, and other libraries. Even the operating system on
which the software is developed can pose similar constraints. This is
especially true with code that relies heavily on the services offered
by the operating system (such as communication, scheduling,
synchronization primitives, and device driver interfaces).  Any
component that tries to place itself ``in control'' and has strong
constraints on what dependencies are permissible will not be tolerated
for long.  It certainly cannot co-exist with another component with
the same assumption of ``dominance''.  Although YARP offers support
for communication, image processing, interfacing to hardware etc., it
is written with an {\em open world} mindset.  We do not assume it will
be the only library used, and endeavor to be as friendly to other
libraries as possible.  YARP allows interconnecting many modules
seamlessly without subscribing to any specific programming style,
language interface, or demanding specifications as for instance in
CORBA or DCOM. Such systems,
although far more powerful than YARP, require a much tighter link
between the general algorithmic code and the communication layer.  We
have taken a more lightweight approach: YARP is a plain library linked
to user-level code that can be used directly just by instantiating
appropriate classes.  Finally, other programming languages can access
YARP as well, provided they can link and call C++ code.



\section philosophy_diversity Exploit diversity.

Different operating systems offer different features. Sometimes it is
easier to write code to perform a given task on one OS as opposed to
another. This can happen for example if device drivers for a given
board are provided only on a specific platform or if an algorithm is
available open source on another. We decided to reduce the
dependencies with the operating system. For this we use
ACE, an open source library providing a framework for
concurrent programming across a very wide range of operating
systems. YARP inherits the portability of ACE and has indeed been used
and tested on Windows, Linux and (in some incarnations) QNX 6.



YARP's core communication model was the survivor from an early
humanoid robot (called Kismet) controlled by a set of Motorola 68332
processors, an Apple Mac, and a loose network of PCs running QNX,
Linux, and Microsoft Windows.  Communication was a hodge-podge of
dual-port RAM, QNX message passing, CORBA, and raw sockets.  At one
point, three incompatible communication protocols layered over QNX
message passing were in use simultaneously.  This variety was a
consequence of organic growth, as developers added new modules to the
robot.  YARP began as one of the communication protocols built on QNX
message passing.  A key defining feature of YARP was that it was
<i>broad-minded</i>: it was implemented in the form of a library which
placed minimal constraints on user code; communication resources did
not need to be allocated at any particular time or place in a program;
reading messages could be blocking, polling, or callback based,
etc. This meant it could be easily added without disturbing existing
code, and communication could be moved across to the new protocol
piece by piece.

*/
