1880 lines
82 KiB
Plaintext
1880 lines
82 KiB
Plaintext
|
|
||
|
/**
|
||
|
@defgroup ImportantClasses Important Classes
|
||
|
@brief These classes are essential far all programs using Aria to control a robot.
|
||
|
|
||
|
@defgroup OptionalClasses Optional Classes
|
||
|
@brief These classes provide additional features that may be used in some programs.
|
||
|
|
||
|
@defgroup ActionClasses Predefined ArAction Classes
|
||
|
@brief These classes implement component behaviors as ArAction subclasses (see ArAction and the overview for more details on actions)
|
||
|
|
||
|
@defgroup DeviceClasses Device Interface Classes
|
||
|
@brief These classes provide interfaces to hardware devices such as sensors. Some use
|
||
|
"connector" objects for configure, connection and sometimes to create the
|
||
|
interface objects. Read documentation fro details.
|
||
|
|
||
|
@defgroup UtilityClasses Utility Classes
|
||
|
@brief These classes provide useful cross-platform system tools, math and string tools, and other miscellaneous programming utilities.
|
||
|
|
||
|
@defgroup MTX MTX/Pioneer LX Specific Classes
|
||
|
@brief These classes are only used on Pioneer LX and other MTX-type robots.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
\mainpage ARIA Developer's Reference Manual
|
||
|
|
||
|
MobileRobots <b>Advanced Robotics Interface for Applications (ARIA)</b>
|
||
|
|
||
|
<p>
|
||
|
Copyright 2002, 2003, 2004, 2005 ActivMedia Robotics, LLC. All rights reserved.<br>
|
||
|
Copyright 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. All rights reserved.<br>
|
||
|
Copyright 2011, 2012, 2013 Adept Technology. All rights reserved.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
\htmlonly
|
||
|
<style type="text/css">
|
||
|
dt.file {
|
||
|
font-family: monospace, typewriter, sans;
|
||
|
}
|
||
|
dl {
|
||
|
font-size: small;
|
||
|
margin-left: 10%;
|
||
|
margin-right: 10%;
|
||
|
}
|
||
|
</style>
|
||
|
\endhtmlonly
|
||
|
|
||
|
\section toc Contents
|
||
|
<ul>
|
||
|
<li>\ref intro
|
||
|
<ul>
|
||
|
<li>\ref javapython</li>
|
||
|
<li>\ref matlab</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref licensing</li>
|
||
|
<li>\ref AriaPackage
|
||
|
<ul>
|
||
|
<li>\ref arpack</li>
|
||
|
<li>\ref arpackother</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref codingConventions</li>
|
||
|
<li>\ref arCliServ</li>
|
||
|
<li>\ref commClasses
|
||
|
<ul>
|
||
|
<li>\ref connectRobot</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref HardwareConfiguration
|
||
|
<ul>
|
||
|
<li>\ref RobotParameterFiles</li>
|
||
|
<li>\ref RuntimeOptions</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref robot
|
||
|
<ul>
|
||
|
<li>\ref commands</li>
|
||
|
<li>\ref packetHandlers</li>
|
||
|
<li>\ref CommandPackets</li>
|
||
|
<li>\ref syncRobot</li>
|
||
|
<li>\ref stateReflection</li>
|
||
|
<li>\ref callback</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref ClientCommands
|
||
|
<ul>
|
||
|
<li>\ref robotDirectCommands</li>
|
||
|
<li>\ref robotMotionCommands</li>
|
||
|
<li>\ref actions</li>
|
||
|
<li>\ref actionDesired</li>
|
||
|
<li>\ref resolvers</li>
|
||
|
<li>\ref predefinedActions</li>
|
||
|
<li>\ref actionInteractions</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref rangeDevices</li>
|
||
|
<li>\ref functors</li>
|
||
|
<li>\ref userInput</li>
|
||
|
<li>\ref threading
|
||
|
<ul>
|
||
|
<li>\ref syncObject</li>
|
||
|
<li>\ref asynctasks</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>\ref aria</li>
|
||
|
</ul>
|
||
|
|
||
|
\subsection tocToolbox Additional tools in the ARIA toolbox:
|
||
|
<ul>
|
||
|
<li>\ref devices</li>
|
||
|
<li>\ref utility</li>
|
||
|
<li>\ref arconfig</li>
|
||
|
<li>\ref sockets</li>
|
||
|
<li>\ref arinfogroup</li>
|
||
|
<li>\ref maps</li>
|
||
|
<li>\ref ArNetworking</li>
|
||
|
<li>\ref sound</li>
|
||
|
</ul>
|
||
|
|
||
|
\subsection tocDevHelp Helpful information about C++ development with ARIA:
|
||
|
<ul>
|
||
|
<li>\ref emacs</li>
|
||
|
<li>\ref noneverydayC
|
||
|
<ul>
|
||
|
<li>\ref stl</li>
|
||
|
<li>\ref defaultArgs</li>
|
||
|
<li>\ref constructorChaining</li>
|
||
|
<li>\ref charsAndStrings</li>
|
||
|
<li>\ref arexport</li>
|
||
|
<li>\ref exceptions</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
\subsection tocAdv Advanced Usage:
|
||
|
<ul>
|
||
|
<li>\ref pieceMealUse</li>
|
||
|
<li>\ref hardConnectRobot
|
||
|
<ul>
|
||
|
<li>\ref openDevice</li>
|
||
|
<li>\ref devConnect</li>
|
||
|
<li>\ref connrw</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
\section intro Introduction
|
||
|
|
||
|
Welcome to ARIA, an object-oriented, robot control
|
||
|
applications-programming interface for MobileRobots (and ActivMedia)
|
||
|
intelligent mobile robots.
|
||
|
|
||
|
Written in the C++ language, ARIA is client-side software for easy,
|
||
|
high-performance access to and management of the robot, as well
|
||
|
as to the many accessory robot sensors and effectors. ARIA includes
|
||
|
many useful utilities for general robot programming and cross-platform
|
||
|
(Linux and Windows) programming as well.
|
||
|
|
||
|
You can access ARIA at different
|
||
|
levels, from simply sending commands to the robot through ArRobot
|
||
|
to development of higher-level intelligent behavior using @ref actions.
|
||
|
(For a description of how to integrate parts of ARIA with
|
||
|
your other code, see \ref pieceMealUse.)
|
||
|
|
||
|
An auxiliary library called ArNetworking is also included with ARIA.
|
||
|
ArNetworking provides an easy to use, extensible framework for communication with
|
||
|
remote programs over a network, such as MobileEyes.
|
||
|
|
||
|
This page contains an overview of ARIA. Read this overview to become familiar
|
||
|
with the ARIA library and how to get started using it.
|
||
|
Click a class or function link to view its details.
|
||
|
A selection of the most important ARIA classes is listed in @ref
|
||
|
ImportantClasses in the menu to the left, as well as @ref OptionalClasses, @ref
|
||
|
DeviceClasses, @ref UtilityClasses and @ref ActionClasses. All
|
||
|
classes are available in the full class list and hierarchy links on the left.
|
||
|
|
||
|
New users should view this document along with the ARIA examples, README.txt, and
|
||
|
your robot's operating manual as well.
|
||
|
|
||
|
You can download new versions of ARIA from http://robots.mobilerobots.com/ARIA
|
||
|
|
||
|
\subsection whouses What is ARIA? How does it relate to other MobileRobots software?
|
||
|
|
||
|
ARIA is a programming library (SDK) for C++ programmers
|
||
|
who want to access their MobileRobots or ActivMedia platform and accessories at either
|
||
|
a high or low level.
|
||
|
ARIA is also for those who have already prepared robot-control software and want to
|
||
|
deploy it on one or more MobileRobots or ActivMedia mobile robot platforms.
|
||
|
ARIA also provides various tools useful for robot programming in general.
|
||
|
|
||
|
In addition to providing a complete robot and accessory API to developers,
|
||
|
ARIA also serves as a
|
||
|
foundation for other libraries providing additional
|
||
|
capabilities: For creating applications with built-in advanced navigation routines,
|
||
|
you can use the additional ARNL or SONARNL libraries. To communicate with the
|
||
|
MobileEyes graphical display/control program, or for general
|
||
|
communication over the network, you can use ArNetworking. ArNetworking is
|
||
|
included with ARIA in the ArNetworking directory.
|
||
|
See the ArNetworking Reference
|
||
|
Manual for more information.
|
||
|
|
||
|
Other libraries are available as well for specialized purposes, including
|
||
|
speech synthesis and recognition, audio stream recording, playback and network
|
||
|
transmission, video image capture, color tracking, etc.
|
||
|
Browse the MobileRobots support web pages http://www.activrobots.com and
|
||
|
http://robots.mobilerobots.com for these libraries and other mobile robotics
|
||
|
resources, including the MobileSim simulator which can be used used for
|
||
|
programming and debugging before driving an actual robot.
|
||
|
|
||
|
Programmers working with ARIA should be familiar with
|
||
|
using typical C++ concepts, including
|
||
|
using classes and objects with simple inheritance, pointers, memory management,
|
||
|
the STL containers, and the compiling and linking process. (See below
|
||
|
for notes about accessing ARIA from Python or Java.) Experience with
|
||
|
multiple threads is also helpful.
|
||
|
|
||
|
Read on for information about the key pieces of ARIA and how to get started.
|
||
|
See the README.txt file for a brief practical overview of ARIA software development
|
||
|
on Linux and Windows. Many example programs are available as well.
|
||
|
|
||
|
\subsection javapython Java and Python
|
||
|
|
||
|
ARIA, ArNetworking, ARNL and SONARNL now work in Java and Python! Each library has a
|
||
|
Java wrapper and a Python
|
||
|
wrapper. This means that you can write
|
||
|
ARIA programs in Java or Python almost as if ARIA itself was written in these
|
||
|
languages. This wrapper is automatically generated by <a
|
||
|
href="http://www.swig.org">SWIG</a>,
|
||
|
and the Python and Java APIs are almost the same as the
|
||
|
C++ library. Exceptions will be noted in this reference manual.
|
||
|
|
||
|
Read javaExamples/README.txt file for directions on how to use
|
||
|
the Java wrapper and pythonExamples/README.txt for directions
|
||
|
on how to use the Python wrapper, and likewise see <a class="file"
|
||
|
href="../ArNetworking/javaExamples">ArNetworking/javaExamples</a>
|
||
|
and <a class="file" href="../ArNetworking/pythonExamples">ArNetworking/pythonExamples</a> for information about and examples of the
|
||
|
ArNetworking Java and Python wrappers.
|
||
|
|
||
|
\subsection matlab Matlab
|
||
|
|
||
|
A subset of essential robot control and accessor functions from ARIA are now also available for use in
|
||
|
Matlab. See matlab/README.txt for instructions on how to create
|
||
|
and use this interface, and notes on what is available and what its requirements and supported platforms are.
|
||
|
|
||
|
\section licensing License and Sharing
|
||
|
|
||
|
ARIA is released under the GNU Public License, which means that the entire
|
||
|
source code is included and may be copied. However, if you
|
||
|
distribute any work which incorporates ARIA, you must also distribute the entire
|
||
|
source code to that work, including ARIA with any modifications you may have
|
||
|
made, under the same license terms. Read the included <a
|
||
|
href="../LICENSE.txt">license text</a> for
|
||
|
details. We open-sourced ARIA under the GPL not only for your convenience,
|
||
|
but also so that you could share your enhancements to the software with the
|
||
|
robotics community (you can share them via the aria-users mailing list). If
|
||
|
you wish your enhancements to make it into the ARIA baseline, you will
|
||
|
need to assign the copyright on those changes to MobileRobots, contact
|
||
|
aria-support@mobilerobots.com with these changes or with questions about
|
||
|
this.
|
||
|
|
||
|
Accordingly, please do share your work, and please sign up for the
|
||
|
exclusive ARIA-users@mobilerobots.com newslist so that you can benefit
|
||
|
from others' work, too.
|
||
|
|
||
|
For answers to frequently asked questions about what the GPL allows
|
||
|
and requires, see http://www.gnu.org/licenses/gpl-faq.html .
|
||
|
|
||
|
On the other hand, ARIA may be also licensed for proprietary, closed-source applications.
|
||
|
Contact sales@mobilerobots.com for details.
|
||
|
|
||
|
\section AriaPackage The ARIA Package
|
||
|
|
||
|
\subsection arpack ARIA/
|
||
|
|
||
|
\htmlonly
|
||
|
<dl>
|
||
|
<dt class="file">README.txt</dt>
|
||
|
<dd>Getting started; essential info. Includes tips on installing
|
||
|
ARIA, rebuilding it, building example programs, and
|
||
|
using platform development tools.
|
||
|
Also see the README files in the examples/, advanced/, and tests/
|
||
|
directories.</dd>
|
||
|
|
||
|
<dt class="file">LICENSE.txt</dt>
|
||
|
<dd>GPL license for redistributing ARIA or programs using ARIA</dd>
|
||
|
|
||
|
<dt class="file">Changes.txt</dt>
|
||
|
<dd>Summary of changes featured in each version of ARIA</dd>
|
||
|
|
||
|
<dt class="file">INSTALL.txt</dt>
|
||
|
<dd>Detailed instructions for installing ARIA on different platforms</dd>
|
||
|
|
||
|
<dt class="file">docs/</dt>
|
||
|
<dd>Library reference documentation (this manual).</dd>
|
||
|
|
||
|
<dt class="file">examples/</dt>
|
||
|
<dd>ARIA example programs -- a good place to start. Also see the Examples
|
||
|
section of this reference manual; selected examples are also linked from
|
||
|
classes and methods used by those examples.
|
||
|
</dd>
|
||
|
|
||
|
|
||
|
<dt class="file">include/</dt>
|
||
|
<dd>Header files for ARIA</dd>
|
||
|
|
||
|
<dt class="file">src/</dt>
|
||
|
<dd>ARIA C++ source code files</dd>
|
||
|
|
||
|
<dt class="file">params/</dt>
|
||
|
<dd>Robot definition (parameter) files (p3dx.p, for example).
|
||
|
Mostly used transparently by ARIA, but can be customized
|
||
|
if neccesary.
|
||
|
</dd>
|
||
|
|
||
|
<dt class="file">lib/</dt>
|
||
|
<dd>Win32 DLL export library (.lib) files and Linux shared library (.so)
|
||
|
files</dd>
|
||
|
|
||
|
<dt class="file">bin/</dt>
|
||
|
<dd>Win32 binaries and DLLs</dd>
|
||
|
</dl>
|
||
|
\endhtmlonly
|
||
|
|
||
|
\subsection arpackother Other ARIA Files of Note
|
||
|
|
||
|
\htmlonly
|
||
|
<dl>
|
||
|
<dt class="file">Aria.sln</dt> <dd>MS Visual C++ workspace for building
|
||
|
ARIA libraries and examples</dd>
|
||
|
<dt class="file">Aria.vcproj</dt> <dd>MSVC++ project file used in Aria.sln
|
||
|
for the ARIA library.</dd>
|
||
|
<dt class="file">Makefile</dt> <dd>Linux makefile for building ARIA and
|
||
|
examples</dd>
|
||
|
<dt class="file">Makefile.dep</dt> <dd>Linux file dependency rules (used internally
|
||
|
by Makefile)</dd>
|
||
|
<dt class="file">utils/</dt>
|
||
|
<dd>Utility programs, used internally by MobileRobots software development,
|
||
|
plus some file format conversion tools
|
||
|
</dd>
|
||
|
<dt class="file">ArNetworking/</dt> <dd>Networking infrastructure library,
|
||
|
included with ARIA, but a separate library</dd>
|
||
|
<dt class="file">tests/</dt> <dd>Test files, somewhat esoteric but
|
||
|
useful during ARIA development</dd>
|
||
|
<dt class="file">advanced/</dt> <dd>Advanced demos and examples, not
|
||
|
always for the faint of heart (or ARIA novice)</dd>
|
||
|
<dt class="file">pythonExamples/</dt> <dd>Information about and examples of
|
||
|
using ARIA via Python</dd>
|
||
|
<dt class="file">javaExamples/</dt> <dd>Information about and examples of
|
||
|
using ARIA via Java</dd>
|
||
|
<dt class="file">python/</dt> <dd>Contains ARIA Python module and
|
||
|
other files</dd>
|
||
|
<dt class="file">java/</dt> <dd>Contains ARIA Java package and other
|
||
|
files</dd>
|
||
|
</dl>
|
||
|
\endhtmlonly
|
||
|
|
||
|
\section codingConventions Documentation and Coding Convention
|
||
|
|
||
|
ARIA follows the following coding conventions:
|
||
|
|
||
|
<ol>
|
||
|
<li>Class names begin with "Ar" and are in mixed case.</li>
|
||
|
<li>Enums and other constants either begin with a capital letter or are all in caps.</li>
|
||
|
<li>Avoid preprocessor definitions whenever possible (instead using enumerations or inline methods)</li>
|
||
|
<li>Member variables in classes are prefixed with 'my'.</li>
|
||
|
<li>Static variables in classes are prefixed with 'our'.</li>
|
||
|
<li>Member function names start with a lower case.</li>
|
||
|
<li>Capitalize each word except the first one in a variable or method name; <code>likeThisForExample</code></li>
|
||
|
<li>All classes may be used in a multi-threaded program, either by being
|
||
|
inherently threadsafe, or (more typically) by providing an API for protecting it by
|
||
|
locking mutexes. See class documentation for notes on access from
|
||
|
multiple threads.
|
||
|
</li>
|
||
|
</ol>
|
||
|
|
||
|
@sa @ref emacs
|
||
|
|
||
|
\section arCliServ ARIA-Robot Client-Server Relationship
|
||
|
|
||
|
For those of you who are familiar with SRI International's Saphira
|
||
|
software and ActivMedia Robotics' mobile robots and their related
|
||
|
technologies, the underlying client-server control architecture for
|
||
|
the mobile platform, sensors, and accessories hasn't changed much in
|
||
|
ARIA. It's just gotten a lot better and more accessible.
|
||
|
|
||
|
The core mobile robot "server" proceses are implemented in the Pioneer and AmigoBot Operating
|
||
|
System firmware (ARCOS, AROS, P2OS, AmigOS, etc.), which runs
|
||
|
on the robot's microcontroller.
|
||
|
These proceses manage the more critical and time-sensitive low-level tasks of robot control and operation, including
|
||
|
maintaining requested motion and heading state and estimating position from odometry, as well as acquiring sensor information
|
||
|
(sonar and compass, for example) and driving many accessory components like
|
||
|
the PTZ camera, TCM2 compass/inclinometer, and the Pioneer 5-DOF
|
||
|
Arm. The robot, its microcontroller, firmware, and integrated devices (such as
|
||
|
sonar) together are sometimes referred
|
||
|
to as the "robot platform". The robot firmware does not, however, perform any high-level robotic tasks.
|
||
|
Rather, it is the job of an intelligent client running on a connected
|
||
|
PC to perform these application-level robotic control strategies and tasks,
|
||
|
such as obstacle detection and avoidance, sensor fusion, localization,
|
||
|
features recognition, mapping, intelligent navigation, PTZ camera
|
||
|
control, Arm motion, and much more. ARIA's role is to support these client applications
|
||
|
and their communcation with the robot firmware, to any devices that connect to
|
||
|
the computer rather than the robot platform, and to remote software via a
|
||
|
network.
|
||
|
|
||
|
The heart of ARIA is the ArRobot class. This class manages the communication
|
||
|
cycle with the firmware, receiving and providing access to data about the
|
||
|
robot platform's operating state,
|
||
|
triggering tasks within that cycle and determining commands to be sent back
|
||
|
to the robot (see @ref actions and @ref syncRobot). It also serves as a container for references to other ARIA objects
|
||
|
(such as range devices) and a toolbox of general functions related to the mobile
|
||
|
robot.
|
||
|
|
||
|
Through its @ref actions infrastructure, ARIA provides a powerful
|
||
|
mechanism for combining independent behaviors to achieve
|
||
|
coordinated motion control and intelligent guidance. With
|
||
|
Actions, you easily implement the motion aspects of applications
|
||
|
such as guided teleoperation, visual tracking, autonomous navigation, etc.
|
||
|
|
||
|
Other ARIA classes provide interfaces to
|
||
|
access and control accessory sensors and devices,
|
||
|
including operation and state reflection for sonar and laser range
|
||
|
finders, pan-tilt units, arms, inertial navigation devices, and many
|
||
|
others.
|
||
|
|
||
|
|
||
|
\section commClasses Robot Communication
|
||
|
|
||
|
One of the most important functions of ARIA, and one of the first and
|
||
|
things that your application program must do, is to establish
|
||
|
the connection between an ArRobot object instance and the robot platform
|
||
|
operating system (firmware).
|
||
|
|
||
|
In addition to the mobile robot itself, some accessories,
|
||
|
such as the sonar, the Pioneer Gripper, PTZ cameras, Pioneer Arm, compass, and others, are
|
||
|
internally connected to the robot microcontroller's AUX or digital I/O
|
||
|
lines, and use the robot connection as well (therefore the interface
|
||
|
classes for these objects require a reference to an ArRobot object,
|
||
|
which must be connected for the devices to work). Other accessories, such as
|
||
|
the SICK laser, video capture cards, etc. are connected directly to the onboard
|
||
|
computer.
|
||
|
|
||
|
There are several ways to connect a computer running ARIA to the robot's
|
||
|
microcontroller or to a simulator.
|
||
|
<a href="figures/Robot_Communication_Options.png">This figure</a> provides
|
||
|
a schematic overview of the many ARIA-robot communication options.
|
||
|
Consult your robot Operations Manual for more information about computer-robot
|
||
|
hardware setup and communications.
|
||
|
|
||
|
\subsection connectRobot Connecting with a Robot or the Simulator
|
||
|
|
||
|
An ArRobotConnector object is used to set up and
|
||
|
perform the connection to the robot, based on robot parameter files,
|
||
|
and run-time configuration via command-line
|
||
|
arguments (see \ref HardwareConfiguration). Similarly, ArLaserConnector
|
||
|
is used to connect to laser rangefinding devices. (Other connectors are
|
||
|
also used for other kinds of accessory devices.)
|
||
|
ArRobotConnector and ArLaserConnector are used in most of the example programs, including
|
||
|
@ref simpleConnect.cpp, @ref wander.cpp, and @ref demo.cpp. (Some
|
||
|
example still use the older ArSimpleConnector).
|
||
|
ArRobotConnector will first try to connect to
|
||
|
a simulator on a local TCP port, and if no simulator is running, it will then
|
||
|
connect to the robot on a local serial port.
|
||
|
This makes it easy to develop and debug your program using the simulator, then
|
||
|
simply copy it onto the robot's computer and run without modification.
|
||
|
ArRobotConnector also parses some command line arguments if supplied, which
|
||
|
can explicitly specify a remote hostname and/or port to connect with via TCP,
|
||
|
or to specify an alternate local serial port to use for robot connection,
|
||
|
as well as other options. If a program uses ArRobotConnector, running it
|
||
|
with the "-help" command line argument will print a list of options.
|
||
|
|
||
|
Here is an example which uses ArRobotConnector to connect the ArRobot and
|
||
|
ArLaserConnector to connect to a laser rangefinder.
|
||
|
@code
|
||
|
#include "Aria.h"
|
||
|
int main(int argc, char** argv)
|
||
|
{
|
||
|
Aria::init();
|
||
|
ArArgumentParser parser(&argc, argv);
|
||
|
parser.loadDefaultArguments();
|
||
|
ArRobot robot;
|
||
|
ArRobotConnector robotConnector(&parser, &robot);
|
||
|
|
||
|
// Try connecting to the robot.
|
||
|
if(!robotConnector.connectRobot(&robot))
|
||
|
{
|
||
|
// Error!
|
||
|
ArLog::log(ArLog::Terse, "Error, could not connect to robot.\n");
|
||
|
robotConnector.logOptions();
|
||
|
Aria::exit(1);
|
||
|
}
|
||
|
|
||
|
// Run the ArRobot processing/task cycle thread.
|
||
|
robot.runAsync(true);
|
||
|
|
||
|
ArLaserConnector laserConnector(&parser, &robot, &robotConnector);
|
||
|
|
||
|
// Parse command line arguments (there may be arguments specifying
|
||
|
// what lasers to try to connect to)
|
||
|
if(!Aria::parseArgs())
|
||
|
{
|
||
|
Aria::logOptions();
|
||
|
Aria::exit(2);
|
||
|
}
|
||
|
|
||
|
// Try connecting to all lasers specified in the robot's parameter file
|
||
|
// and in command line arguments
|
||
|
if(!laserConnector.connectLasers())
|
||
|
{
|
||
|
ArLog::log(ArLog::Terse, "Error, could not connect to lasers.\n");
|
||
|
Aria::logOptions();
|
||
|
Aria::exit(3);
|
||
|
}
|
||
|
|
||
|
// Now we're connected, and the robot and laser objects are running in
|
||
|
// background threads reading and processing data. (You can get access
|
||
|
// to the ArLaser objects using ArRobot::findLaser() or
|
||
|
// ArRobot::getLaserMap().
|
||
|
...
|
||
|
@endcode
|
||
|
|
||
|
|
||
|
\section HardwareConfiguration Specifying Details about Robot and Device Connections
|
||
|
|
||
|
On any individual robot, there are many possible combinations of hardware
|
||
|
accessories, and several options for connecting accessories to the robot
|
||
|
and computer. The device interface and connector classes (ArRobotConnector,
|
||
|
ArLaserConnector, etc.) need information about what devices are connected
|
||
|
and how they are connected, especially if they vary from their defaults.
|
||
|
|
||
|
This information is obtained from two sources: ARIA's parameter file(s) for
|
||
|
the robot,
|
||
|
and from program runtime arguments via ArArgumentParser (which reads
|
||
|
default program argument values from /etc/Aria.args (on Linux) and the ARIAARGS
|
||
|
environment variable (on both Linux and Windows), then reads current
|
||
|
program arguments from the command line).
|
||
|
|
||
|
Some examples of hardware configuration options that may need to be
|
||
|
specified are what kinds of laser rangefinders are connected, and
|
||
|
to which ports, laser connection and data parameters, what kind
|
||
|
of GPS is connected and to what port (if a GPS is used). Furthermore,
|
||
|
if you are connecting to a robot over a wireless TCP connection from an offboard
|
||
|
computer rather than an onboard computer, you must provide a runtime
|
||
|
command line argument giving the robot network name (and optionally port number).
|
||
|
|
||
|
\subsection RobotParameterFiles Robot Parameter Files
|
||
|
|
||
|
Robot parameter files are read by ARIA after a connection to the robot is
|
||
|
made and the robot type and individual name are obtained (see @ref
|
||
|
connectRobot). These files provide ARIA with robot-specific conversion factors
|
||
|
and physical charactaristics, as well as accessory device connection information.
|
||
|
|
||
|
See @ref ParamFiles for more information.
|
||
|
|
||
|
\subsection RuntimeOptions Program Runtime Options
|
||
|
|
||
|
Various classes in ARIA (notably the Connector classes) use program runtime
|
||
|
options (a/k/a command-line arguments).
|
||
|
|
||
|
See @ref CommandLineOptions for a summary of all the options that various
|
||
|
classes in ARIA accept.
|
||
|
|
||
|
Arguments are provided to other ARIA classes by an ArArgumentParser
|
||
|
object. All ARIA programs should create an ArArgumentParser, call
|
||
|
ArArgumentParser::loadDefaultArguments() to load any arguments that
|
||
|
appear in the <code>/etc/Aria.args</code> file or <code>ARIAARGS</code> environment variable,
|
||
|
and provide that object to any class constructors that accept it.
|
||
|
Once all such objects are created, you can call Aria::logOptions() to
|
||
|
print out a summary of all relevant options (e.g. call Aria::logOptions();
|
||
|
and Aria::exit() if ArArgumentParser::checkHelpAndWarnUnparsed() returns
|
||
|
<code>true</code>, because the user gave the <code>--help</code> option). Finally, call
|
||
|
Aria::parseArgs() to cause each of them to check the ArArgumentParser for
|
||
|
their respective arguments.
|
||
|
|
||
|
|
||
|
|
||
|
\section robot ArRobot
|
||
|
|
||
|
ArRobot is the heart of an ARIA program, acting as
|
||
|
robot communications gateway, central manager
|
||
|
of robot state, tool for synchronizing program-added tasks and callbacks,
|
||
|
ArAction objects, etc.
|
||
|
|
||
|
\subsection commands Client Commands and Server Information Packets
|
||
|
|
||
|
Client-server communications between ARIA and a
|
||
|
mobile robot platform or simulator use packet-based
|
||
|
protocols. (In this context, the <i>client</i> is the software using
|
||
|
ARIA to operate a robot, and the <i>server</i> is the robot platform's firmware.)
|
||
|
The details of the client-server protocol can be found in your robot's
|
||
|
Operations or Technical Manual.
|
||
|
|
||
|
ArRobot (using the
|
||
|
ArDeviceConnection, ArRobotPacketReceiver, ArRobotPacketSender, ArRobotPacket,
|
||
|
and ArSerialConnection classes)
|
||
|
handles the details of constructing and sending a
|
||
|
command packets to the robot as well as receiving and decoding
|
||
|
the packets recieved from the robot server.
|
||
|
|
||
|
\subsection packetHandlers Packet Handlers
|
||
|
|
||
|
Server Information Packets (SIPs) are packets sent by the robot server
|
||
|
containing information updates about the
|
||
|
robot and its accessories.
|
||
|
The <i>standard SIP</i> is sent by the
|
||
|
robot to a connected client automatically every 100 milliseconds
|
||
|
(this frequency may be configured in the firmware parameters).
|
||
|
It contains the robot's current position and estimates,
|
||
|
current translational and rotational speeds, sonar
|
||
|
reading updates, battery voltage, analog and digital I/O states, and more.
|
||
|
These data are stored and used
|
||
|
by ArRobot's State Reflection (see \ref stateReflection
|
||
|
below) and are accessible via methods of the ArRobot class.
|
||
|
(Note, within the ArRobot source code the standard SIP is also called a "motor" packet.)
|
||
|
|
||
|
<i>Extended SIPs</i> use the same packet format as the
|
||
|
standard SIP, but with a different packet "type" code. Examples of extended
|
||
|
SIPs include I/O port data, data from the gripper, or special robot
|
||
|
data like raw encoder data.
|
||
|
To receive extended SIPs, the client program
|
||
|
must request them. In ARIA, this is normally done by the device interface
|
||
|
classes (see @ref devices) when they are initialized or when the robot connection is established.
|
||
|
You may also attach your own custom packet handlers to ArRobot using
|
||
|
ArRobot::addPacketHandler(). You can use this to do your own additional processing
|
||
|
of extended SIP data, or if creating an alternate implementation of a device
|
||
|
interface class.
|
||
|
|
||
|
\subsection CommandPackets Command Packets
|
||
|
|
||
|
To control the robot platform, a client program sends <i>command packets</i>
|
||
|
through the robot connection. This can be done using %ArRobot's @ref
|
||
|
robotMotionCommands, using @ref actions, or at the most basic level,
|
||
|
@ref robotDirectCommands.
|
||
|
Each of these methods results in command packets sent to
|
||
|
the robot. This means that if both Actions and motion commands are used,
|
||
|
or if independent program modules are sending motion commands, they may conflict.
|
||
|
See \ref ClientCommands below for more about sending motion commands.
|
||
|
|
||
|
|
||
|
\subsection syncRobot Robot Synchronization Cycle
|
||
|
|
||
|
The standard SIP is sent on a constant cycle, and reception of this
|
||
|
SIP triggers a new iteration of ArRobot's
|
||
|
<i>synchronized task processing cycle</i>.
|
||
|
This cycle consists of a series of tasks,
|
||
|
including SIP packet handling, invocation of sensor interpretation tasks, action handling and
|
||
|
resolution, state reflection, and invocation of user tasks, in that order.
|
||
|
Since the task cycle is (normally) triggered by the
|
||
|
reception of each SIP (unless the robot platform begins to fails to send SIPs
|
||
|
or the task cycle is explicitly dissasociated from the robot connection -- see
|
||
|
below), each task will be invoked in a predictable order,
|
||
|
have the most recent data to act upon, no task will miss an opportunity
|
||
|
to use a SIP, and as long as the tasks do not take too much time to execute,
|
||
|
each SIP is handled as soon as possible after the robot sends it.
|
||
|
|
||
|
@image html ArRobot_Task_Cycle.png Overview of the ArRobot task cycle
|
||
|
|
||
|
To begin the processing cycle, call ArRobot::run() to enter
|
||
|
the cycle synchronously, or ArRobot::runAsync() to run the cycle
|
||
|
in a new background thread. ArRobot::stopRunning() stops the
|
||
|
processing cycle.
|
||
|
|
||
|
ArRobot provides methods to add your own sensor-interpretation
|
||
|
and generic user task callbacks. To add a task callback, create an ArFunctor
|
||
|
function object (see \ref functors) and
|
||
|
then add it using ArRobot::addSensorInterpTask() or
|
||
|
ArRobot::addUserTask(). These tasks
|
||
|
can be removed using ArRobot::remSensorInterpTask() or
|
||
|
ArRobot::remUserTask().
|
||
|
|
||
|
ArRobot locks it's mutex (see ArRobot::lock() and ArRobot::unlock()) during
|
||
|
each iteration of the task cycle, so your task callbacks must not lock this
|
||
|
mutex--a deadlock will occur.
|
||
|
(However, locks must still be used for safe access to any other thread
|
||
|
or ArAsyncTask, such as lasers and other range devices, or ARNL's planning or
|
||
|
localization tasks.) This mutex lock protects ArRobot data from
|
||
|
modification by other threads (if they correctly use the lock during access),
|
||
|
and interruption of the series of tasks. So if you access ArRobot from any other thread (including the main
|
||
|
thread, if you used ArRobot::runAsync() to run the task cycle), you must
|
||
|
use ArRobot::lock() and ArRobot::unlock() to lock and unlock the robot before
|
||
|
and after any method call or use of any data in ArRobot.
|
||
|
|
||
|
It is also possible to run the processing cycle without a connection to a robot,
|
||
|
if desired.
|
||
|
This alternative cycle is not triggered by receiving a packet, instead it has its own
|
||
|
steady, "chained" cycle time (default is 100 milliseconds which you may
|
||
|
examine and reset with ArRobot::getCycleTime() and
|
||
|
ArRobot::setCycleTime()).
|
||
|
You may also explicitly disassociate ArRobot's processing cycle from incoming
|
||
|
SIP processing at any time by calling ArRobot::setCycleChained() ("Chained" means that it is
|
||
|
the end of a previous cycle that triggers the next after suitable delay to meet
|
||
|
the desired cycle frequency). However, in doing so,
|
||
|
you may degrade performance, as the robot's cycle will only be
|
||
|
run every ArRobot::getCycleTime() milliseconds, and each time only the most recently
|
||
|
read (oldest) SIP is used (even if the robot has sent more than one since the
|
||
|
last cycle).
|
||
|
|
||
|
|
||
|
ArRobot's synchronization task list is ipmlemented as a tree, with five
|
||
|
major branches. Though it is uncommon to do so, a client program may modify this
|
||
|
tree or disable branch tasks of the tree.
|
||
|
If a particular task is disabled, none of its
|
||
|
children will be called.
|
||
|
The root of the task tree can be obtained by calling ArRobot::getSyncTaskRoot(),
|
||
|
which returns an ArSyncTask object.
|
||
|
|
||
|
|
||
|
@warning A user task or sensor interpretation task must run quickly. If one or more
|
||
|
user tasks or actions runs such that the task cycle takes too long (more that 100ms)
|
||
|
then the performance and behavior of the robot and of ARIA-robot communications
|
||
|
will be negatively affected. In particular, do not call any functions that
|
||
|
could block or wait for an unknown amount of time (such as locking a mutex
|
||
|
that could be locked for a long time by another thread)
|
||
|
or do any long loops waiting for a condition. Long-running activity can be performed
|
||
|
in a separate asynchronous thread (See ArASyncTask) instead, and results can be
|
||
|
shared with the user task via storage which is protected by a mutex only during
|
||
|
immediate reading and writing of the storage variables.
|
||
|
|
||
|
|
||
|
\subsection stateReflection State Reflection
|
||
|
|
||
|
State reflection in the ArRobot class is the way ARIA maintains
|
||
|
a snapshot of the robot's operating conditions and values, such
|
||
|
as estimated pose, current velocity, battery voltage, etc.
|
||
|
as extracted from the latest standard SIP. ArRobot methods for
|
||
|
examining these values include ArRobot::getPose(), ArRobot::getX(),
|
||
|
ArRobot::getY(), ArRobot::getTh(), ArRobot::getVel(), ArRobot::getRotVel(),
|
||
|
ArRobot::getBatteryVoltage(), ArRobot::isLeftMotorStalled(),
|
||
|
ArRobot::isRightMotorStalled(), ArRobot::getCompass(),
|
||
|
ArRobot::getAnalogPortSelected(), ArRobot::getAnalog(), ArRobot::getDigIn(),
|
||
|
ArRobot::getDigOut().
|
||
|
|
||
|
The standard SIP also contains sonar reading updates, which are
|
||
|
reflected in ArRobot and examined with the methods:
|
||
|
ArRobot::getNumSonar(), ArRobot::getSonarRange(), ArRobot::isSonarNew(),
|
||
|
ArRobot::getSonarReading(), ArRobot::getClosestSonarRange(),
|
||
|
ArRobot::getClosestSonarNumber(). The sonar interface class, ArSonarDevice,
|
||
|
also receives this information (see \ref rangeDevices).
|
||
|
|
||
|
ArRobot also uses the state reflection task to send previously requested
|
||
|
motion commands (see @ref robotMotionCommands) to the robot, so the motion
|
||
|
commands sent to the robot reflects those desired values set in ArRobot's state
|
||
|
reflection by actions or motion command methods, and also so that the watchdog
|
||
|
on the robot does not time out and disable the robot (if no motion command is
|
||
|
set, ArCommands::PULSE is sent each cycle).
|
||
|
You can further tune state reflection's motion command sending rate if neccesary with ArRobot::setStateReflectionRefreshTime().)
|
||
|
If desired, you may turn the motion-control state reflector off in the
|
||
|
ArRobot::ArRobot() constructor (set the @a doStateReflection parameter to
|
||
|
false). This will cause motion command functions to only be send the command once directly to the
|
||
|
robot whenever they are called, rather than storing the command to send each cycle.
|
||
|
|
||
|
\subsection callback Robot Callbacks
|
||
|
|
||
|
There are a number of useful callbacks invoked by ArRobot on connection
|
||
|
events. You can add and remove them with the functions
|
||
|
ArRobot::addConnectCB(), ArRobot::remConnectCB(),
|
||
|
ArRobot::addFailedConnectCB(), ArRobot::remFailedConnectCB(),
|
||
|
ArRobot::addDisconnectNormallyCB(), ArRobot::remDisconnectNormallyCB(),
|
||
|
ArRobot::addDisconnectOnErrorCB(), ArRobot::remDisconnectOnErrorCB(),
|
||
|
ArRobot::addRunExitCB(), ArRobot::remRunExitCB(). Read their individual
|
||
|
documentation pages for details.
|
||
|
|
||
|
@sa @ref robotConnectionCallbacks.cpp
|
||
|
|
||
|
|
||
|
\section ClientCommands Controlling the robot with Commands and Actions
|
||
|
|
||
|
Your ARIA client can drive the robot and run its various accessories
|
||
|
through ArRobot's Direct Commands, Motion Commands, or through Actions.
|
||
|
|
||
|
@note The robot's movement speed will be limited by several parameters. First,
|
||
|
the maximum velocities, accelerations and decelerations given in ARIA's robot
|
||
|
parameter file (.p file) (TransVelMax,
|
||
|
RotVelMax, TransAccel, TransDecel, RotAccel, RotDecel, and for the Seekur only,
|
||
|
LatVelMax, LatAccel and LatDecel) are used to limit motion
|
||
|
commands sent by ARIA, if the value is nonzero. Next, the max velocities given in the
|
||
|
robot firmware (ARCOS) configuration are used to limit motion commands recieved by the robot.
|
||
|
All of these maximum values can be changed at runtime with the ArRobot::setTransVelMax(),
|
||
|
ArRobot::setRotVelMax(), and for the Seekur only, ArRobot::setLatVelMax() calls.
|
||
|
These calls change the parameters in the robot firmware, as well as in ARIA.
|
||
|
That is, they override any maximum values given in the robot parameter file (.p file).
|
||
|
Finally, the "Top" parameters in the firmware (ARCOS) configuration limit
|
||
|
speeds; these cannot be changed at runtime, only using the configuration
|
||
|
program. Most robot parameter files use 0 values as maximums, disabling ARIA's
|
||
|
initial limiting check; however, to make the Seekur easier to initially teleoperate at safe
|
||
|
speeds, the velocity limits in seekur.p are set. Change these limits to 0 to remove
|
||
|
those speed limits, and use the platform's defaults, or use ArRobot's methods to
|
||
|
change them at program runtime.
|
||
|
|
||
|
\subsection robotDirectCommands Direct Commands
|
||
|
|
||
|
At the lowest level of robot access, you may send any command packet directly to the robot
|
||
|
or simulator platform through ArRobot. Direct commands consist of a 1-byte command
|
||
|
number followed by none or more arguments, as defined by the robot's
|
||
|
operating system (ARCOS, AROS, P2OS, AmigOS, etc.). For example, the command
|
||
|
number 4, ENABLE, enables the robot's motors if accompanied by the
|
||
|
argument 1, and disables the motors with the argument 0.
|
||
|
Use ArRobot::com() for commands that
|
||
|
have no argument, such as PULSE; ArRobot::comInt() for a 2-byte integer
|
||
|
argument, signed or unsigned, such as the motors ENABLE command;
|
||
|
ArRobot::com2Bytes() for commands that accept two individual bytes
|
||
|
as the argument, such as the VEL2 command; and ArRobot::comStr() or
|
||
|
ArRobot::comStrN() for a null-terminated or fixed-length
|
||
|
string argument, respectively, such as the sonar POLLING
|
||
|
sequencing command.
|
||
|
|
||
|
The ArCommands class contains an enum with all the direct commands;
|
||
|
ArCommands::ENABLE, for example. Not all Direct Commands are supported by every
|
||
|
MobileRobots robot, but unrecognized (or malformed)
|
||
|
commands are simply ignored.
|
||
|
|
||
|
Please consult your robot's technical manual for details, such
|
||
|
as the Chapter 6 in the Pioneer 3
|
||
|
Operations Manual, for client command numbers and syntax.
|
||
|
|
||
|
For most commands, a method exists in ArRobot that either sends the command
|
||
|
immediately, or stores it for the state reflection task to send. However,
|
||
|
the direct command methods allow you to send any unusual or special commands
|
||
|
directly to the robot platform or simulator, without any intervening processing.
|
||
|
|
||
|
\subsection robotMotionCommands Motion Command Functions
|
||
|
|
||
|
At a level just above ArRobot's Direct Commands are the Motion
|
||
|
Command Functions. These are explicit simple movement commands sent by ArRobot's
|
||
|
state reflection task.
|
||
|
For example, ArRobot::setVel() to set the translational velocity,
|
||
|
ArRobot::setRotVel to set rotational velocity, ArRobot::setVel2() to
|
||
|
or set each wheel speeds separately, ArRobot::setHeading() to set a
|
||
|
global heading angle to turn to, ArRobot::move() to drive a given distance,
|
||
|
or ArRobot::stop() to stop all motion. ArRobot also provides methods
|
||
|
for setting speed limits beyond the limits set in the firmware configuration.
|
||
|
These motion functions work at part of with @ref stateReflection, and ArRobot may
|
||
|
resend commands each cycle to try to achieve the desired state.
|
||
|
|
||
|
Be aware that a Direct or a Motion Command may conflict with controls
|
||
|
from Actions or other upper-level processes and lead to unexpected
|
||
|
consequences. Use ArRobot::clearDirectMotion() to cancel the overriding
|
||
|
effect of a previously set Motion Command so that your Action is able to regain
|
||
|
control the robot. Or limit the time a Motion Command prevents other
|
||
|
motion actions with ArRobot::setDirectMotionPrecedenceTime(). Otherwise,
|
||
|
the Motion Command will prevent actions forever. Use
|
||
|
ArRobot::getDirectMotionPrecedenceTime() to see how long a Motion
|
||
|
Command takes precedence once set.
|
||
|
|
||
|
\subsection actions Actions
|
||
|
|
||
|
While simple sequences motion commands can be easy to use, trying to achieve
|
||
|
more sophisticated motion using only motion commands
|
||
|
can quickly become difficult. To make it possible to define
|
||
|
complex behaviors out of independent, reusable components,
|
||
|
ARIA provides the higher-level <i>Actions</i> system.
|
||
|
Actions are individual objects that independently
|
||
|
provide motion requests which are evaluated and then combined each cycle
|
||
|
to produce a final set of movement commands. This allows you to build complex
|
||
|
behavior from simple building blocks for dynamic and continuous motion control.
|
||
|
|
||
|
Actions are defined by creating a subclass of the ArAction the base class
|
||
|
which overloads the ArAction::fire() method.
|
||
|
See the <code>@ref actionExample.cpp</code> example program.
|
||
|
ARIA also includes some useful pre-made action classes (see @ref ActionClasses
|
||
|
for a list). Include these in your programs, or use them as examples when
|
||
|
creating your own custom ArAction subclass.
|
||
|
|
||
|
Actions are attached to an ArRobot object with ArRobot::addAction(), along with
|
||
|
a priority which determines its position in the action list.
|
||
|
ArAction::setRobot() is called on an action object when it is added to a robot.
|
||
|
You can override this in your action subclass. (For example, this would be useful to add a
|
||
|
connection callback, if there were some calculations you wished to do
|
||
|
upon connection to the robot.)
|
||
|
|
||
|
Actions are evaluated by ArRobot's <i>action resolver</i> in descending order of priority
|
||
|
(highest priority first, lowest priority last) in each task cycle just prior
|
||
|
to @ref stateReflection. The action resolver invokes each action's fire()
|
||
|
method, combining their desired motion commands (the ArActionDesired objects
|
||
|
they return) to a
|
||
|
single ArActionDesired object, which is then used in state reflection to send
|
||
|
motion commands to the robot.
|
||
|
|
||
|
@note Sending simple motion commands (e.g. by using ArRobot::setVel()) while
|
||
|
actions are also active can result in conflicts between your simple motion
|
||
|
commands and the action resolver's commands. See the discussion of
|
||
|
@ref robotMotionCommands above.
|
||
|
|
||
|
As the resolver is invoking each action, by it passes
|
||
|
the current desired motion combined from the previously invoked, higher priority
|
||
|
actions, as the currentDesired argument to fire().
|
||
|
This can be useful information if
|
||
|
needed. (For example, a stall-recovery action could
|
||
|
be programmed not to exert its motion effects if it has been
|
||
|
pre-empted by a stop action, so this stall-recovery action would check
|
||
|
currentDesired to see if either the "strength" is "used up" or if there is a maximum
|
||
|
velocity, and if so, reset its own state.) However, there is no need
|
||
|
for an action to pay attention to the currentDesired if not necessary.
|
||
|
|
||
|
@warning An action must run quickly. If one or more actions or robot
|
||
|
user tasks runs such that the task cycle takes too long (more that 100ms)
|
||
|
then the performance and behavior of the robot and of ARIA-robot communications
|
||
|
will be negatively affected. In particular, do not call any functions that
|
||
|
could block or wait for an unknown amount of time (such as locking a mutex
|
||
|
that could be locked for a long time by another thread)
|
||
|
or do any long loops waiting for a condition. Long-running activity can be performed
|
||
|
in a separate asynchronous thread (See ArASyncTask) instead, and results can be
|
||
|
shared with the action via storage which is protected by a mutex only during
|
||
|
immediate reading and writing of the storage variables.
|
||
|
|
||
|
\subsection actionDesired Action Desired
|
||
|
|
||
|
ArActionDesired objects are used to pass desired action channel values
|
||
|
and strengths out of an ArAction::fire() method back to the resolver.
|
||
|
An ArActionDesired object should always be
|
||
|
reset (ArActionDesired::reset()) before it is reused.
|
||
|
|
||
|
There are six action channels: velocity (ArActionDesired::setVel),
|
||
|
heading (ArActionDesired::setDeltaHeading or
|
||
|
ArActionDesired::setHeading for absolute heading),
|
||
|
maximum forward translational velocity
|
||
|
(ArActionDesired::setMaxVel), maximum reverse translational velocity
|
||
|
(ArActionDesired::setMaxNegVel), and maximum rotational velocity
|
||
|
(ArActionDesired::setMaxRotVel).
|
||
|
|
||
|
An action gives each channel a strength between 0.0, the lowest, and 1.0,
|
||
|
the highest. Strengths are used by the resolver to compute the
|
||
|
relative effect of the associated channel when combining multiple
|
||
|
actions' desired movements.
|
||
|
|
||
|
The maximum velocity, maximum negative velocity, and maximum
|
||
|
rotational velocity channels simply impose speed limits and thereby
|
||
|
indirectly control the robot.
|
||
|
|
||
|
For more advanced usage, ArActionDesired objects can be merged
|
||
|
(ArActionDesired::merge) and averaged (ArActionDesired::startAverage,
|
||
|
ArActionDesired::addAverage, ArActionDesired::endAverage).
|
||
|
|
||
|
\subsection resolvers The Action Resolver
|
||
|
|
||
|
ArResolver is the base action resolver class. ArPriorityResolver is
|
||
|
the default resolver used by ArRobot.
|
||
|
|
||
|
The resolver used by ArRobot may be changed by calling ArRobot::setResolver,
|
||
|
if you wish to create an alternative ArResolver implementation.
|
||
|
There may only be one resolver per ArRobot object.
|
||
|
(Though a resolver could contain
|
||
|
within it multiple resolvers of its own.) Note that although a robot has
|
||
|
one particular resolver bound to it, a resolver instance is not tied to
|
||
|
any robot.
|
||
|
|
||
|
The priority resolver works by iterating through the action list in descending
|
||
|
priority (from greatest priority value to lowest), setting each robot movement channel (trans. velocity, heading,
|
||
|
max. velocity, etc.) based on
|
||
|
the contributing actions' desired values (as returned from their fire() methods)
|
||
|
in proportion to their
|
||
|
respective strengths as well as the actions' priorities, updating each movement channel
|
||
|
until its strength becomes 1.0 or the action
|
||
|
list is exhausted. Once a channel's accumulated strength reaches 1.0, no more changes may be made to
|
||
|
that channel (this is how higher priority actions can prevent lower priority
|
||
|
actions from changing a channel). Same-priority actions are averaged together if
|
||
|
they both provide outputs for the same channel.
|
||
|
|
||
|
As an example, the following table illustrates at each step an action's desired value
|
||
|
and strength for the <b>velocity</b> channel, and the resulting change to
|
||
|
the resolver's final velocity channel value and strength decision,
|
||
|
for four fictional actions (A, B, C and D):
|
||
|
|
||
|
<table border="1" cellspacing="0" style="td, th { font-size: 90%; }" summary="Example result for velocity channel from four enabled actions">
|
||
|
<tr><th>step #</th> <th>action</th> <th>priority</th> <th>value of action's desired-velocity channel</th> <th>strength of action's desired-velocity channel</th> <th>current final velocity value</th> <th>current final velocity strength</th></tr>
|
||
|
<tr><td>1</td> <td>A</td> <td>4</td> <td>-400</td> <td>0.25</td> <td>-400</td> <td>0.25</td></tr>
|
||
|
<tr><td>2</td> <td>B</td> <td>3</td> <td>-100</td> <td>1.0</td> <td colspan="2" rowspan="2" valign="middle" align="center">Combined for use in step 4</td></tr>
|
||
|
<tr><td>3</td> <td>C</td> <td>3</td> <td>200</td> <td>0.50</td> </tr>
|
||
|
<tr><td>4</td> <td>B&C</td> <td>3</td> <td>0</td> <td>0.75</td> <td>-100</td> <td>1.0</td></tr></td></tr>
|
||
|
<tr><td>5</td> <td>D</td> <td>1</td> <td>500</td> <td>0.50</td> <td>no change</td> <td>no change</td></tr>
|
||
|
<tr><th colspan="3" align="left">final result</th><td></td><td></td><td>-100</td><td>1.0</td></tr>
|
||
|
</table>
|
||
|
|
||
|
|
||
|
Notice in the example that the same-priority actions B and C are
|
||
|
averaged before being combined with the previously computed values from step 1.
|
||
|
The resulting combination is:
|
||
|
( (B desired velocity: -100) X (B velocity strength: 1.0) +
|
||
|
(C desired velocity: 200) X (C velocity strength: 0.5) ) / 2 => (-100 + 100) / 2 => 0
|
||
|
Therefore actions B and C end up cancelling each other out. Combining this result with
|
||
|
the "currentDesired" values computed in step 1 gives
|
||
|
(step 1 desired velocity: -400) X (step 1 velocity strength: 0.25) + (step 4
|
||
|
desired velocity: 0) X
|
||
|
(step 4 velocity strength: 0.75) => -100.
|
||
|
|
||
|
In this example, it turns out that at step 5, action D has no effect since the
|
||
|
strength for this channel has reached 1.0 at step 4, before that action was
|
||
|
considered by the resolver.
|
||
|
|
||
|
The same method is used for all of the other channels.
|
||
|
|
||
|
\subsection predefinedActions Predefined Actions
|
||
|
|
||
|
ARIA includes several predefined action classes.
|
||
|
See @ref ActionClasses for a list. Include these in your programs, or use them as examples when
|
||
|
creating your own custom ArAction subclass.
|
||
|
|
||
|
<i>Movement</i> action classes have an "ArAction" prefix and set
|
||
|
either or both the translational velocity (setVel) and heading
|
||
|
(setDeltaHeading and setHeading) channels to effect motion. <i>Limiting</i> action classes
|
||
|
are prefixed with "ArActionLimiter" and set one or more of the
|
||
|
maximum translational and rotational velocity channels, to slow down or
|
||
|
prevent motion, usually based on conditions such as nearby sensor readings.
|
||
|
|
||
|
See the ArAction base class's list of subclasses.
|
||
|
|
||
|
\subsection actionInteractions Mixing Actions
|
||
|
|
||
|
Actions are most useful when mixed. The @ref teleopActionsExample.cpp
|
||
|
example program is a good
|
||
|
example of mixing limiting and movement actions. It creates
|
||
|
several limiting actions, including Limiter, LimiterFar, and so
|
||
|
on, and two movement actions, joydriveAct and
|
||
|
keydriveAct. The limiting actions have higher priority than the
|
||
|
movement ones, thereby preventing driving if it might be potentially unsafe
|
||
|
due to obstacles detected by sensors.
|
||
|
|
||
|
This example also illustrates fundamental, yet very powerful features
|
||
|
of ARIA actions and how they contribute to the overall behavior of the
|
||
|
mobile robot. Because they are individuals, contributing discretely to
|
||
|
the movements of the robot, actions are easily reusable. For example, a
|
||
|
limiting action that prevents the robot from crashing
|
||
|
into a wall when translating forward, can be used, as is, in
|
||
|
another ARIA program and have the identical effect, except that
|
||
|
instead of driving the robot with a joystick, the new program's
|
||
|
lower-priority movement action might use color-tracking to have the
|
||
|
robot follow a rolling ball. The ball-following action doesn't need
|
||
|
to know anything about the finer arts of safe navigation--the
|
||
|
higher-priority limiting actions take care of that.
|
||
|
|
||
|
Another ARIA example program, @ref wander.cpp demonstrates how
|
||
|
different movement actions can be used and how they interact. The
|
||
|
stall-recover action in wander (ArActionStallRecover) influences the
|
||
|
robot's movements only when the motors are stalled, disabling the
|
||
|
lower priority actions by using up all translational and rotational
|
||
|
strength until the robot has extracted from the stall. You should also
|
||
|
examine %ArActionStallRecover.cpp in the src/ directory
|
||
|
to see how the action changes its motion control
|
||
|
influences based on the stall state.
|
||
|
Also note how ArActionAvoidFront and ArActionConstantVelocity
|
||
|
interact.
|
||
|
|
||
|
\subsection actionGroups Action Groups
|
||
|
|
||
|
Action groups allow you to easily enable (activate) or disable (de-activate)
|
||
|
a set of actions at once.
|
||
|
You must first create an ArActionGroup attached to an ArRobot. Then, when you
|
||
|
add an ArAction to the ArActionGroup, it is automatically added to the ArRobot, as
|
||
|
well as to the group.
|
||
|
|
||
|
Several predefined action groups are provided by ARIA.
|
||
|
|
||
|
@sa @ref actionGroupExample.cpp
|
||
|
|
||
|
|
||
|
\section rangeDevices Range Devices
|
||
|
|
||
|
Range devices (ArRangeDevice) are abstractions of sensors which detect
|
||
|
the presence of obstacles in the space around the robot, providing
|
||
|
a series of spatial readings over time.
|
||
|
ARIA's range device classes transform all readings into specific points in the same
|
||
|
two-dimensional global coordinate system. (This is the same coordinate system
|
||
|
as ArRobot's pose).
|
||
|
|
||
|
Currently, the main
|
||
|
ArRangeDevice implementations included with ARIA are: sonar (ArSonarDevice),
|
||
|
laser (ArLaser and subclasses), the robot bumpers (ArBumpers), and the "table-sensing" infrared
|
||
|
sensors of a PeopleBot (ArIRs). Camera and 3D range devices (MobileRanger
|
||
|
devices) are supported by separate software.
|
||
|
In addition, ArForbiddenRangeDevice is a "virtual" range device that creates range readings
|
||
|
that border "forbidden area" and "forbidden line" regions
|
||
|
in an ArMap, and ArRangeDeviceFilter processes the output
|
||
|
another ArRangeDevice object in a few ways and provides the processed data through the
|
||
|
ArRangeDevice interface. Its parameters can be modified on line through
|
||
|
ArConfig.
|
||
|
|
||
|
ArRangeDevice holds two kinds of ArRangeBuffer objects to store readings:
|
||
|
<i>current</i> and
|
||
|
<i>cumulative</i>, though not all ArRangeDevice implementations supply data to the
|
||
|
cumulative buffer. The current buffer contains the
|
||
|
most recent set of readings; the cumulative buffer contains readings gathered
|
||
|
over a longer period time, limited by the buffer's size (see
|
||
|
ArRangeBuffer::setSize()).
|
||
|
|
||
|
Some range devices also provide "raw" readings, which are the original values given
|
||
|
by the device itself. Some range devices are also considered "Planar", which
|
||
|
means that the readings may undergo some processing to remove duplicates etc.,
|
||
|
and which include raw readings. This includes the lasers.
|
||
|
|
||
|
Range devices are connected to a specific ArRobot instance, to obtain
|
||
|
position and other information from the robot when readings are received and
|
||
|
stored, and also to provide a way to find all range devices attached to the robot.
|
||
|
Some range devices use the robot connection to communicate to their device (e.g.
|
||
|
ArSonarDevice,
|
||
|
ArBumpers, ArIRs).
|
||
|
Attach an ArRangeDevice to your ArRobot object with ArRobot::addRangeDevice() and
|
||
|
remove it with ArRobot::remRangeDevice(). The list of all attached devices
|
||
|
can be queried using ArRobot::findRangeDevice() and ArRobot::hasRangeDevice().
|
||
|
The list can be obtained by calling ArRobot::getRangeDeviceList().
|
||
|
|
||
|
(Note that although sonar are integrated with the robot microcontroller, and
|
||
|
the microcontroller always sends sonar data to the robot (if the robot has
|
||
|
sonar), you still must attach an ArSonarDevice object to the robot to use it.)
|
||
|
|
||
|
ArRangeDevice also includes some methods to help find the closest reading to the
|
||
|
robot within a selected box, or a polar sector:
|
||
|
ArRangeDevice::currentReadingPolar(),
|
||
|
ArRangeDevice::currentReadingBox(),
|
||
|
ArRangeDevice::cumulativeReadingPolar(),
|
||
|
ArRangeDevice::cumulativeReadingBox().
|
||
|
|
||
|
ArRobot also includes similar methods to do common operations on all
|
||
|
attached range devices,
|
||
|
including ArRobot::checkRangeDevicesCurrentPolar(),
|
||
|
ArRobot::checkRangeDevicesCurrentBox(),
|
||
|
ArRobot::checkRangesDevicesCumulativePolar(), and
|
||
|
ArRobot::checkRangeDevicesCumulativeBox() to find the closest range reading
|
||
|
to the robot within some region.
|
||
|
|
||
|
Each range device has a mutex
|
||
|
(Use ArRangeDevice::lockDevice() and ArRangeDevice::unlockDevice() to lock
|
||
|
and unlock it)
|
||
|
so that it can be accessed safely by multiple threads. For
|
||
|
example, ArLMS2xx uses a thread to read data from a laser, but the
|
||
|
checkRangeDevice functions in ArRobot lockDevice() so they can read
|
||
|
the data without conflicting with ArLMS2xx's data-reading thread, then use
|
||
|
unlockDevice() when done. See \ref threading for more about threading in ARIA.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section functors Functors
|
||
|
|
||
|
Functors are used throughout ARIA.
|
||
|
Functor is short for function pointer. A Functor lets you call a
|
||
|
function without knowing the declaration of the function. Instead, the
|
||
|
compiler and linker figure out how to properly call the function.
|
||
|
|
||
|
Function pointers are fully supported by the C language. C++ treats
|
||
|
function pointers like C, but to call class methods, an instance object
|
||
|
is required, as well as type information about the class.
|
||
|
Therefore, ARIA contains a set of template classes to contain this information.
|
||
|
|
||
|
ARIA makes heavy use of ArFunctors as "callback" functions.
|
||
|
To instantiate a functor, you first need to
|
||
|
identify how many arguments the function needs and if it returns a
|
||
|
value. Many times a pointer to the abstract ArFunctor base class is used, which
|
||
|
can be invoked with no arguments and no return value.
|
||
|
Subclasses are used for functions with different numbers of arguments
|
||
|
and return values. ArFunctor1, ArFunctor2,
|
||
|
ArRetFunctor, ArRetFunctor1, and ArRetFunctor2 for example. When invoked,
|
||
|
the arguments may be supplied which are passed to the target function or
|
||
|
method, and a return value may also be given. The types for the arguments
|
||
|
and/or return value are given as template arguments.
|
||
|
|
||
|
When creating a functor object, however, you must also provide the type
|
||
|
and instance of an object to invoke the method of; or explicitly state
|
||
|
that the function is a class-less global function. Do this by using one
|
||
|
of the concrete base classes of ArFunctor instead of the abstract classes:
|
||
|
ArFunctorC, ArFunctor1C, ArFunctor2C, ArRetFunctorC, ArRetFunctor1C,
|
||
|
ArRetFunctor2C, ArGlobalFunctor, ArGlobalFunctor1, etc.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
@code
|
||
|
class ExampleClass {
|
||
|
public:
|
||
|
void aFunction(int n);
|
||
|
};
|
||
|
|
||
|
...
|
||
|
|
||
|
ExampleClass obj;
|
||
|
ArFunctor1C<ExampleClass, int> functor(&obj, &ExampleClass::aFunction);
|
||
|
|
||
|
...
|
||
|
|
||
|
functor.invoke(42);
|
||
|
@endcode
|
||
|
|
||
|
<code>ExampleClass</code> is a class which contains a function called
|
||
|
<code>aFunction()</code>. The functor <code>functor</code> is declared
|
||
|
as an <code>ArFunctor1C</code>, a functor which invokes a class method
|
||
|
and takes one argument. The template parameters specify the type of the
|
||
|
class (<code>ExampleClass</code>) and the type of the method argument
|
||
|
(<code>int</code>). <code>functor</code> is then initialized with
|
||
|
a pointer to the <code>ExampleClass</code> instance to call the
|
||
|
method on, and a pointer to the class method to call. When a functor
|
||
|
is contained within the class, it is typcially initialized in the
|
||
|
constructor, giving <code>this</code> as the object instance.
|
||
|
|
||
|
A functor must be initialized with the method to call and, if a "C" functor,
|
||
|
a class instance. An unitilialized functor will crash at runtime when invoked.
|
||
|
|
||
|
It is also possible to give values for the method arguments in the functor
|
||
|
initialization, see ArFunctor documentation for details.
|
||
|
|
||
|
Once the functor object is created in this fashion, it can now be
|
||
|
passed to another function or object that wants a callback functor. And the
|
||
|
method <code>ExampleClass::aFunction()</code> will be called on the object
|
||
|
<code>obj</code> when the functor is invoked.
|
||
|
|
||
|
To invoke a functor, simply call the invoke() function
|
||
|
on the functor. If it takes arguments, call invoke() with those
|
||
|
arguments. If the functor has a return value, call invokeR. The
|
||
|
return value of the function will be passed back through the invokeR()
|
||
|
function. If the functor was initialized with argument values,
|
||
|
and invoke() is called without argument values, the argument values
|
||
|
provided at initialization are passed.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section userInput Keyboard and Joystick Input
|
||
|
|
||
|
ARIA provides several classes getting live joystick and keyboard input,
|
||
|
and action classes (see @ref actions) that use that input to drive the robot.
|
||
|
|
||
|
ArJoyHandler is a cross-platform interface to joystick data.
|
||
|
It's key functions are ArJoyHandler::getButtons, ArJoyHandler::getAdjusted,
|
||
|
ArJoyHandler::setSpeeds, and ArJoyHandler::getDoubles.
|
||
|
|
||
|
ArKeyHandler is a cross-platform interface for recieving single keystroke
|
||
|
events (instead of buffered lines of text).
|
||
|
It's key function is ArKeyHandler::addKeyHandler,
|
||
|
which binds a specific key to a given functor. It contains an enum
|
||
|
ArKeyHandler::KEY that contains values for special keys.
|
||
|
You can also attach a key handler to a robot with ArRobot::attachKeyHandler(),
|
||
|
which adds some default key handlers, including a handler for Escape that
|
||
|
disconnects and exits the program (especially useful on Windows, where Ctrl-C
|
||
|
or the terminal close box won't properly clean up).
|
||
|
Since a PC can only have ony keyboard, ARIA keeps an ArKeyHandler pointer
|
||
|
globally, which may be queried with Aria::getKeyHandler().
|
||
|
|
||
|
@note if you are using Linux, creating a key handler will make the program hang
|
||
|
if put into the background with Ctrl-Z.
|
||
|
|
||
|
ARIA provides two simple actions, ArActionKeydrive and ArActionJoydrive, to
|
||
|
drive a robot from keyboard and joystick input.
|
||
|
These actions are used by
|
||
|
the @ref teleopActionsExample.cpp example program.
|
||
|
ARIA also provides a more flexible
|
||
|
ArActionRatioInput, which can combine several input sources (such as keyboard,
|
||
|
computer joystick, robot-platform (microcontroller) joystick,
|
||
|
or teleoperation commands recieved via ArNetworking) in a more
|
||
|
consistent and configurable manner. See the class documentation for more
|
||
|
details.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section threading Threading
|
||
|
|
||
|
ARIA is highly multi-threaded. This section presents some of the
|
||
|
critical concepts behind writing threaded ARIA code.
|
||
|
|
||
|
ARIA provides a number of support classes to make it easier to write
|
||
|
object-oriented threaded code. They are: ArASyncTask, ArCondition,
|
||
|
ArMutex, and ArThread.
|
||
|
|
||
|
Thread-safe code mostly means proper coordination between threads when
|
||
|
handling the same data. You want to avoid the problem of one
|
||
|
or more threads reading or writing the data at the same time that other
|
||
|
threads read or write the data.
|
||
|
data. To prevent this problem from happening, the data needs to be
|
||
|
protected with synchronization objects.
|
||
|
|
||
|
\subsection syncObject Thread Syncronizing Objects
|
||
|
|
||
|
In ARIA, the synchronization objects are ArMutex and ArCondition.
|
||
|
ArMutex is the most useful one. ArMutex (<i>mutex</i> is short for <i>mut</i>ual
|
||
|
<i>ex</i>clusion.) provides a wrapper around system calls (pthreads functions
|
||
|
on Linux and CriticalSection functions on Windows) that
|
||
|
exclude other threads from continuing while the mutex object is "locked".
|
||
|
When threads lock a mutex while accessing shared data, it is ensured
|
||
|
that only one thread is accessing that shared data at a time.
|
||
|
Therefore, the proper way to use a mutex is to lock it right
|
||
|
before accessing the shared data, and to always unlock it when done.
|
||
|
If the mutex is not already locked, then it becomes locked and the thread
|
||
|
continues. If the mutex is already locked by another thread, then it blocks
|
||
|
in the lock call until the other thread unlocks it. If a mutex is never
|
||
|
unlocked (e.g. a function returns due to an error condition without unlocking
|
||
|
it), then any further attempts to lock it will block forever, creating
|
||
|
a "deadlock".
|
||
|
See the mutex example program to see how ArMutex is used. The documentation of a method
|
||
|
may indicate whether locking is necessary before using it; in general,
|
||
|
when using an object that may be shared by other threads,
|
||
|
all threads using it must lock the same mutex (usually contained within
|
||
|
the object's class with methods provided for locking and unlocking) while using
|
||
|
the object.
|
||
|
|
||
|
ArCondition is an occasionally used utility that puts the current thread to sleep until another thread
|
||
|
signals it to wake up and continue executing. This can be used to wait in a
|
||
|
thread for an indefinite amount of time until some event occurs in a another
|
||
|
thread which signals the ArCondition.
|
||
|
|
||
|
\subsection asynctasks Asynchronous Task Class
|
||
|
|
||
|
ARIA provides the ArASyncTask which can be subclassed to implement a
|
||
|
long-running thread and its state
|
||
|
as an object. As opposed to robot-syncronized tasks, asynchronous tasks run
|
||
|
in seperate threads. Like ArMutex, this class wraps the operating system's threading
|
||
|
calls in a cross-platform way. Typically, an ArASyncTask will reperesent a
|
||
|
thread that runs in a loop for the entire program.
|
||
|
|
||
|
To use ArASyncTask, derive a class from ArASyncTask and
|
||
|
override the ArASyncTask::runThread() function. This function is
|
||
|
automatically called within the new thread when that new thread
|
||
|
gets created. To create and start the thread, call
|
||
|
ArASyncTask::create(). When the ArASyncTask::runThread() function
|
||
|
exits, the thread will exit and be destroyed. Seperate threads can
|
||
|
request that the task exit by calling ArASyncTask::stopRunning(), and within the thread,
|
||
|
you can check for this request with ArASyncTask::getRunningWithLock().
|
||
|
|
||
|
This class is mainly a convenience wrapper around ArThread so that you
|
||
|
can easily create your own object that encapsulates the concept of a
|
||
|
thread.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section aria Global Data
|
||
|
|
||
|
The static Aria class contains miscellaneous global data in ARIA.
|
||
|
|
||
|
ARIA contains a list of all the ArRobot instances. Use the
|
||
|
Aria::findRobot() to find a robot by name, or use Aria::getRobotList()
|
||
|
to get a list of the robots.
|
||
|
|
||
|
Use Aria::getDirectory() to find ARIA's top-level path
|
||
|
(Usually either <code>C:\\Program Files\\MobileRobots\\%Aria</code> on Windows, or
|
||
|
<code>/usr/local/Aria</code> on Linux). This is useful,
|
||
|
for instance, to locate
|
||
|
robot parameter files for individual operational details. Use
|
||
|
Aria::setDirectory() to change this path for the run of the program if
|
||
|
you feel the need to override what ARIA has decided.
|
||
|
|
||
|
Call Aria::init() at program start to perform global initialization, and use
|
||
|
Aria::exit() to exit all ARIA threads before exiting your program.
|
||
|
|
||
|
The Aria class also contains global objects for sharing configuration
|
||
|
parameters and other information: see \ref arconfig and \ref arinfogroup
|
||
|
sections below.
|
||
|
|
||
|
@sa @ref arconfig
|
||
|
@sa @ref arinfogroup
|
||
|
|
||
|
|
||
|
|
||
|
\section devices Device and Accessory Interface Classes
|
||
|
|
||
|
ARIA includes classes to communicate with various kinds of devices.
|
||
|
|
||
|
(Many of these devices are optional accessories, and not all robots have them
|
||
|
installed.)
|
||
|
|
||
|
Some are mentioned below. See @ref DeviceClasses for a list.
|
||
|
|
||
|
<ul>
|
||
|
<li>Range devices. See @ref rangeDevices for more about range devices.
|
||
|
<ul>
|
||
|
<li>The various subclasses of ArLaser are for laser rangefinder sensors. Use ArLaserConnector
|
||
|
to automatically create and set up ArLaser objects of the appropriate
|
||
|
types based on robot and program configuration parameters. The lasers created by ArLaserConnector will be available as ArLaser objects stored in ArRobot.</li>
|
||
|
<li>ArSonarDevice for Pioneer and Amigobot built-in sonar.</li>
|
||
|
<li>ArBumpers treats the robot's bumper switch triggers as positions for range device
|
||
|
readings.</li>
|
||
|
<li>ArRangeDeviceFilter provides an ArRangeDevice interface to data from any
|
||
|
other range device that has been filtered in different ways.</li>
|
||
|
<li>ArForbiddenRangeDevice is a virtual range device that returns readings
|
||
|
indicating the edges of forbidden lines and forbidden areas from
|
||
|
an ArMap</li>
|
||
|
<li>ArIRs treats triggers of a Peoplebot's infrared "table" sensors as
|
||
|
positions for range device readings.</li>
|
||
|
</ul>
|
||
|
devices
|
||
|
</li>
|
||
|
|
||
|
<li>Pan/Tilt servos and camera bases.
|
||
|
ArPTZ defines a common interface, and subclasses access specific devices,
|
||
|
including:
|
||
|
<ul>
|
||
|
<li>ArVCC4 provides pan, tilt, zoom and other control of a Canon camera
|
||
|
via the robot microcontroller's AUX serial port.</li>
|
||
|
<li>ArSonyPTZ provides pan, tilt, zoom and other actions of a Sony camera
|
||
|
via the robot microcontroller's AUX serial port.</li>
|
||
|
<li>ArDPPTU provides control of a Directed Perceptions Pan/Tilt unit (used
|
||
|
for stereo cameras).</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
<li>ArAnalogGyro provides data from the optional analog gyro on Pioneer,
|
||
|
PeopleBot, PatrolBot, PowerBot or AmigoBot. If the HasGyro parameter in the robot's
|
||
|
internal firmware configuration is 2 (the default on most robots), then the robot automatically uses the gyro for
|
||
|
position correction before sending its pose estimate to ARIA. However,
|
||
|
if GyroType is 1, then create an ArAnalogGyro object to begin receiving data
|
||
|
from the robot and allow it to apply those corrections to the position in the
|
||
|
ArRobot object.
|
||
|
|
||
|
The gyro also measures its own temperature as part of its operation,
|
||
|
and ArAnalogGyro makes that value available as well.
|
||
|
</li>
|
||
|
|
||
|
<li>ArGripper provides access to a Pioneer gripper.</li>
|
||
|
|
||
|
<li>ArP2Arm provides access to a Pioneer arm.</li>
|
||
|
|
||
|
<li>ArTCM2 provides access to an on-board TCM2 compass, if present.</li>
|
||
|
|
||
|
<li>ArACTS_1_2 communicates with the ACTS program to get object tracking
|
||
|
information.
|
||
|
|
||
|
<li>ArVersalogicIO provides access to the digital and analog I/O ports
|
||
|
on Versalogic motherboards (Linux only). (Support depends on
|
||
|
whether the robot has a Versalogic motherboard, and which board it has.)</li>
|
||
|
</li>
|
||
|
|
||
|
<li>ArSystemStatus provides data about the operating system (Linux only)
|
||
|
such as CPU usage and wireless network signal strength.
|
||
|
</li>
|
||
|
|
||
|
<li>ArGPS provides access to data received from a Global Positioning System
|
||
|
device. Subclasses implement special actions required for specific devices,
|
||
|
such as ArNovatelGPS for the NovAtel G2 and similar devices and ArTrimbleGPS
|
||
|
for the Trimble GPS. Use ArGPSConnector to create the appropriate ArGPS device
|
||
|
based on robot and program configuration parameters.
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
Some device interfaces are provided by additional libraries, as well. See
|
||
|
those libraries for details.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section utility Utility Classes
|
||
|
|
||
|
Some of the general-purpose utility classes included with are ArMath, ArUtil, ArTime, ArPose, ArLog,
|
||
|
ArSectors, ArRingQueue, ArLineFinder, the GPS-related subclasses of Ar3DPoint, ArMD5Calculator
|
||
|
(and the functions in md5.h), ArMutex, ArCondition and ArASyncTask. See @ref
|
||
|
UtilityClasses for a list of utility classes.
|
||
|
|
||
|
\section arconfig ArConfig
|
||
|
|
||
|
ArConfig is a mechanism for storing configuration parameters for different
|
||
|
independent modules in a text file. The global Aria class
|
||
|
maintains a global ArConfig pointer which any program module may access.
|
||
|
Use ArConfig::addParam to register a new parameter with ArConfig, and use
|
||
|
ArConfig::addProcessFileCB to register a callback functor called when the
|
||
|
configuration changes (by loading the file with ArConfig::parseFile, or other
|
||
|
means such as an update from a remote client via ArNetworking).
|
||
|
|
||
|
\section arinfogroup Shared Info Groups
|
||
|
|
||
|
In a program composed of multiple independent modules, it is often necessary
|
||
|
to exchange or combine data between them in a general and immediate way. To do this, ARIA provides
|
||
|
the ArStringInfoGroup class, of which the global ARIA class contains an instance
|
||
|
(in addition to an ArConfig instance used specifically for configuration information
|
||
|
which changes infrequently, by loading a file or by user input.)
|
||
|
An example of ArStringInfoGroup is the ArServerInfoStrings class contained in
|
||
|
the ArNetworking auxiliary library. At program initialization, a callback
|
||
|
functor may be added to the global ArStringInfoGroup object which on invocation immediately passes a
|
||
|
string key/value pair from the ArStringInfoGroup object over to an ArServerInfoStrings
|
||
|
object, which provides access to this data over the network (e.g. to MobileEyes).
|
||
|
Independent components of the program may then change the values in the InfoGroup
|
||
|
object without needing any special
|
||
|
knowledge of the recipients of the data (in this example is the
|
||
|
ArServerInfoStrings class). Since MobileEyes displays this data in a small table
|
||
|
next to other robot information like position in speed, this is a useful way
|
||
|
to provide informative statistics about the robot and software's current operation.
|
||
|
(On Linux, for example, you could use the ArSystemStatus class to publish
|
||
|
information from the operating system, like CPU load).
|
||
|
|
||
|
\section maps Maps
|
||
|
|
||
|
In mobile robot applications, you will often need to store a map of the robot's
|
||
|
environment to use in navigation, localization, etc. ARIA provides the ArMap
|
||
|
class for reading map data from a file, obtaining and modifying its contents in your
|
||
|
application, and writing it back to file. An ArMap contains data about the
|
||
|
sensed/sensable environment (walls, obstacles, etc.), and human-provided
|
||
|
objects such as goal points.
|
||
|
|
||
|
The \ref MapFileFormat page describes the map file format in detail.
|
||
|
|
||
|
ARNL, SONARNL and MobileSim all use ArMap format map files.
|
||
|
|
||
|
\section sockets Sockets
|
||
|
|
||
|
The ArSocket class is a wrapper around the socket network
|
||
|
communication layer of your operating system. ARIA mostly uses
|
||
|
ArSocket to open a server port and to connect to another server port.
|
||
|
|
||
|
To connect to a port, simply construct a socket containing the
|
||
|
hostname or IP address of the host, a port number, and the ARIA socket
|
||
|
type (TCP or UDP). For example:
|
||
|
|
||
|
@code
|
||
|
ArSocket sock("host.name.com", 4040, ArSocket::TCP);
|
||
|
@endcode
|
||
|
|
||
|
Or call the ArSocket::connect() function, such as:
|
||
|
|
||
|
@code
|
||
|
ArSocket sock;
|
||
|
sock.connect("host.name.com", 4040, ArSocket::TCP);
|
||
|
@endcode
|
||
|
|
||
|
To open a server on (for example) port 4040, simply construct a socket:
|
||
|
|
||
|
@code
|
||
|
ArSocket sock(4040, true, ArSocket::TCP);
|
||
|
@endcode
|
||
|
|
||
|
Or call <code>open(4040, ArSocket::TCP)</code> on an ArSocket object constructed
|
||
|
with the default constructor.
|
||
|
|
||
|
|
||
|
\section ArNetworking ArNetworking
|
||
|
|
||
|
For a more advanced networking infrastructure, see <a target="_top"
|
||
|
href="../ArNetworking/docs/index.html">the ArNetworking companion
|
||
|
library</a>,
|
||
|
distributed with ARIA. ArNetworking provides an extensible system of
|
||
|
data requests and updates between client and server applications via TCP or
|
||
|
UDP, using the same base "packet" concept as robot communication.
|
||
|
For example, use ArNetworking to connect multiple robots working together,
|
||
|
off-board user interfaces to on-board control servers, or robot control programs to
|
||
|
off-board data resources.
|
||
|
|
||
|
\section sound Sound and Speech
|
||
|
|
||
|
|
||
|
ARIA provides foundation sound support, and separate libraries use this
|
||
|
for speech and network audio.
|
||
|
|
||
|
<ol>
|
||
|
|
||
|
<li>ARIA's ArSoundsQueue provides a method for handling sound output
|
||
|
generated by various components of a large ARIA application in sequence
|
||
|
and in loops.
|
||
|
It is a sound playback and speech synthesis manager, which
|
||
|
uses a thread-safe queue of sound and speech synthesis requests, and runs
|
||
|
a background processing thread for it. Use this for most of your non-trivial
|
||
|
audio playback and voice synthesis needs.
|
||
|
The speech synthesis libraries, the voice recognition library, and the NetAudio
|
||
|
library are designed to be used in conjunction with this class to coordinate their
|
||
|
usage of the sound device.
|
||
|
</li>
|
||
|
|
||
|
<li>ARIA's ArSoundPlayer provides a basic cross-platform sound-file playback
|
||
|
capability.
|
||
|
Sound files are in WAV (Windows RIFF) format. This class provides static methods
|
||
|
that can be used by ArSoundsQueue for sound file playback.
|
||
|
</li>
|
||
|
|
||
|
<li>Separate libraries provide wrappers around some
|
||
|
speech synthesis (Text-to-speech) and recognition products:
|
||
|
<ul>
|
||
|
<li>The ArSpeechSynth_Festival library uses the free Festival system from the
|
||
|
University of Edinburgh to perform speech synthesis. It provides
|
||
|
the ArFestival class as a wrapper around Festival.
|
||
|
</li>
|
||
|
<li>The ArSpeechSynth_Cepstral library uses the Swift library from
|
||
|
Cepstral, Inc. to perform speech synthesis. It provides the ArCepstral
|
||
|
class for this. ArCepstral offers a few extra features over
|
||
|
ArFestival, and Cepstral, Inc. provides high quality voices for use with Swift.
|
||
|
</li>
|
||
|
<li>The ArSpeechRec_Sphinx library uses Sphinx from Carnegie Mellon
|
||
|
University to perform speech recognition. ArSphinx provides an interface to this.
|
||
|
</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
<p>Functions common to both of the speech synthesis libraries are included in a base
|
||
|
class, ArSpeechSynth.
|
||
|
</p>
|
||
|
|
||
|
<li>The separate ArNetAudio library provides network voice audio recording, transmission and playback:
|
||
|
<ul>
|
||
|
<li>ArNetAudioServer automatically decodes and plays or records and
|
||
|
encodes audio for a network server (typically running on a robot's on-board
|
||
|
computer) and sends and receives the encoded audio to/from a client.</li>
|
||
|
<li>ArNetAudioClient automatically decodes and plays or records and
|
||
|
encodes audio for a network client, sending and receiving the encoded
|
||
|
audio to/from a server (i.e. a robot's on-board computer).</li>
|
||
|
<li>ArNetAudioIO is the common class performing cross-platform Audio I/O
|
||
|
(via the free PortAudio library), and voice encoding/decoding (via the free Speex codec).
|
||
|
It is used by ArNetAudioClient and ArNetAudioServer, but is also available for
|
||
|
stand alone use.
|
||
|
</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
|
||
|
</ol>
|
||
|
|
||
|
\section emacs Emacs
|
||
|
|
||
|
Here is the configuration specification the developers at MobileRobots
|
||
|
Inc. use in their .emacs files, in case you want to modify the
|
||
|
code using emacs and not deal with differences in indentation and
|
||
|
such.
|
||
|
|
||
|
<pre>
|
||
|
(setq c-default-style '((other . "user")))
|
||
|
(c-set-offset 'substatement-open 0)
|
||
|
(c-set-offset 'defun-block-intro 2)
|
||
|
(c-set-offset 'statement-block-intro 2)
|
||
|
(c-set-offset 'substatement 2)
|
||
|
(c-set-offset 'topmost-intro -2)
|
||
|
(c-set-offset 'arglist-intro '++)
|
||
|
(c-set-offset 'statement-case-intro '*)
|
||
|
(c-set-offset 'member-init-intro 2)
|
||
|
(c-set-offset 'inline-open 0)
|
||
|
(c-set-offset 'brace-list-intro 2)
|
||
|
(c-set-offset 'statement-cont 0)
|
||
|
(defvar c-mode-hook 'c++-mode)
|
||
|
</pre>
|
||
|
|
||
|
\section noneverydayC Non-everyday use of C++
|
||
|
|
||
|
ARIA uses some features of C++ that some programmers may not be aware of yet,
|
||
|
and includes some workarounds for platform differences.
|
||
|
|
||
|
\subsection stl Standard Template Library
|
||
|
|
||
|
ARIA makes heavy use of the C++ standard template library (STL). So you
|
||
|
should understand the STL in order to get the best use from some of
|
||
|
the more advanced parts of ARIA.
|
||
|
|
||
|
\subsection defaultArgs Default Arguments
|
||
|
|
||
|
In the function declaration a default value for an argument may be specified.
|
||
|
Arguments with default values may then be omitted from the function call.
|
||
|
|
||
|
For example, after declaring this function with a default value for its integer
|
||
|
argument:
|
||
|
@code
|
||
|
void foo(int number = 3);
|
||
|
@endcode
|
||
|
it can be used in two different ways:
|
||
|
@code
|
||
|
// Use the default value for the argument:
|
||
|
foo();
|
||
|
|
||
|
// Or, use don't use the default:
|
||
|
foo(99);
|
||
|
@endcode
|
||
|
|
||
|
This behavior is quite useful for having defaults for more obscure options
|
||
|
you will usually not need to change, but still allowing you to change them if
|
||
|
necessary without making ARIA more complex.
|
||
|
|
||
|
Also note that the function definition must not have the assignment in
|
||
|
it, only the declaration. Therefore the definition if our example function would
|
||
|
look like this:
|
||
|
@code
|
||
|
void foo(int number)
|
||
|
{
|
||
|
//...
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
\subsection constructorChaining Constructor Chaining
|
||
|
|
||
|
Constructor chaining is quite simple though sometimes not used by C++ programmers. Each
|
||
|
constructor can give arguments to the constructors of the member
|
||
|
variables it contains and to the constructors of classes from which it inherits. For
|
||
|
example if you have:
|
||
|
|
||
|
@code
|
||
|
class BaseClass
|
||
|
{
|
||
|
public:
|
||
|
BaseClass(int someNumber);
|
||
|
};
|
||
|
@endcode
|
||
|
and
|
||
|
@code
|
||
|
class SubClass : public BaseClass
|
||
|
{
|
||
|
public:
|
||
|
SubClass(void);
|
||
|
int anotherNumber;
|
||
|
};
|
||
|
@endcode
|
||
|
When you write your constructor for SubClass you can initialize both
|
||
|
baseClass and anotherNumber:
|
||
|
@code
|
||
|
SubClass::SubClass(void) : BaseClass(3), anotherNumber(37)
|
||
|
{
|
||
|
// ...
|
||
|
}
|
||
|
@endcode
|
||
|
Note how the constructors to be initialized must follow a colon (:) after the
|
||
|
constructor, and be separated by commas. Member variables
|
||
|
must be initialized in the order they are in the class. Note
|
||
|
that initializing integers is not all that unique or useful, but using
|
||
|
this to initialize callback \ref functors is quite useful.
|
||
|
|
||
|
Constructor chaining is used in many many places by ARIA, thus it must
|
||
|
be understood in order to understand ARIA, but the above is all that
|
||
|
really needs to be known.
|
||
|
|
||
|
\subsection charsAndStrings Chars and Strings, Win workaround
|
||
|
|
||
|
During development problems were encountered with Windows if
|
||
|
a <code>std::string</code> was passed into a DLL. Thus for all input to ARIA
|
||
|
<code>const char *</code> is used, but for all internal storage and all reporting
|
||
|
<code>std::string</code>s are passed back out of ARIA.
|
||
|
|
||
|
\subsection arexport AREXPORT
|
||
|
|
||
|
Because of the Windows set up for using DLLs, this macro is used
|
||
|
to take care of the required declaration attributes for DLLs. Largely
|
||
|
users do not need to worry about <code>AREXPORT</code>, but only functions which have
|
||
|
<code>AREXPORT</code> and inline functions are usable with DLLs in Windows (all of the
|
||
|
ARIA functions which are documented in this manual are usable).
|
||
|
|
||
|
\subsection exceptions Exceptions
|
||
|
|
||
|
ARIA neither throws nor catches any exceptions.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
\section Advanced Topics and Esoterica
|
||
|
|
||
|
\subsection pieceMealUse Piecemeal Use of ARIA
|
||
|
|
||
|
The most basic layer of ARIA is ArDeviceConnection and subclasses, which
|
||
|
handle low-level communication with the robot server. On top of the
|
||
|
connection layer, we have a packet layer--ArBasePacket and
|
||
|
ArRobotPacket--the basic algorithms for constructing command packets
|
||
|
and decoding server information packets.
|
||
|
|
||
|
Above the packet layer is the packet handler classes,
|
||
|
ArRobotPacketReceiver and ArRobotPacketSender, when send and receive
|
||
|
packets to and from the robot. Finally, on top of all these lowest
|
||
|
layers is ArRobot, which is a gathering point for all things, but can
|
||
|
be used in a quite basic format without all of the bells and whistles.
|
||
|
ArRobot has built-in tasks, actions, state reflection and so forth, all
|
||
|
of which can be disabled from the constructor (ArRobot::ArRobot) and
|
||
|
ignored or reimplemented.
|
||
|
|
||
|
Also note that if all you do is turn off state reflection, which only
|
||
|
affects sending ArRobot-mediated motion commands to the robot, not
|
||
|
receiving SIPs from the robot, none of the other activities which
|
||
|
ArRobot engages on its loop will take up hardly any time, so it
|
||
|
probably isn't worth building your own set of tasks, but the power to
|
||
|
do so is there for the intrepid.
|
||
|
|
||
|
One other thing worth noting is that you can call ArRobot::loopOnce()
|
||
|
and it will run through its loop a single time and return. This is so
|
||
|
that you can use ARIA from your own control structure. If you are
|
||
|
using loopOnce you may also find it beneficial to call
|
||
|
ArRobot::incCounter, so that the loop counter will be updated. You
|
||
|
could also just call ArRobot::packetHandler, ArRobot::actionHandler,
|
||
|
or ArRobot::stateReflector on your own, as these are the most
|
||
|
important internal functions, though if you make your own loop you
|
||
|
should probably call ArRobot::incCounter any way that you do it, as
|
||
|
this is how sonar are known to be new or not, and such.
|
||
|
|
||
|
We recommend that whatever you do you use the same type of strict
|
||
|
threading/locking that ARIA observes.
|
||
|
|
||
|
|
||
|
\subsection hardConnectRobot Connecting with a Robot or the Simulator the hard way
|
||
|
|
||
|
ArDeviceConnection is ARIA's communications object; ArSerialConnection
|
||
|
and ArTcpConnection are its built-in children most commonly used to
|
||
|
manage communication between a MobileRobots or ActivMedia robot or the robot
|
||
|
simulator, respectively. These classes are not device-specific,
|
||
|
however, so use ArSerialConnection, for instance, to also configure a
|
||
|
serial port and establish a connection with a robot accessory, such as
|
||
|
with the SICK laser range finder.
|
||
|
|
||
|
|
||
|
\subsection openDevice Opening the Connection
|
||
|
|
||
|
After creating and opening a device connection, associate it with its
|
||
|
ARIA device handlers, most commonly with ArRobot::setDeviceConnection
|
||
|
for the robot or the simulator.
|
||
|
|
||
|
For example, early in an ARIA program, specify the connection device and
|
||
|
associate it with the robot:
|
||
|
|
||
|
@code
|
||
|
ArTcpConnection con;
|
||
|
ArRobot robot;
|
||
|
@endcode
|
||
|
|
||
|
Later in the program, after initializing the ARIA system
|
||
|
(Aria::init(); is mandatory), set the Connection port to its default
|
||
|
values (for TCP, host is "localhost" and port number is 8101), and
|
||
|
then open the port:
|
||
|
|
||
|
@code
|
||
|
con.setPort();
|
||
|
if (!con.openSimple())
|
||
|
{
|
||
|
printf("Open failed.");
|
||
|
Aria::shutdown();
|
||
|
return 1;
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
TCP and Serial connections have their own implementation of open which
|
||
|
is not inherited, but has default arguments that make the generic open
|
||
|
work for the all default cases. And open returns a status integer
|
||
|
which can be passed to the re-implemented and inherited
|
||
|
ArDeviceConnection::getOpenMessage in order to retrieve related status
|
||
|
string, which is useful in reporting errors to the user without having
|
||
|
to know about the underlying device.
|
||
|
|
||
|
\subsection devConnect Robot Client-Server Connection
|
||
|
|
||
|
After associating the device with the robot, now connect with the
|
||
|
robot's servers, ArRobot::blockingConnect or ArRobot::asyncConnect, for
|
||
|
example, to establish the client-server connection between ARIA
|
||
|
ArRobot and the robot microcontroller or robot
|
||
|
simulator. The blockingConnect method doesn't return from the call until
|
||
|
a connection succeeds or fails:
|
||
|
|
||
|
@code
|
||
|
robot.setDeviceConnection(&con);
|
||
|
if (!robot.blockingConnect())
|
||
|
{
|
||
|
printf("Could not connect to robot... Exiting.");
|
||
|
Aria::shutdown();
|
||
|
return 1;
|
||
|
}
|
||
|
@endcode
|
||
|
|
||
|
The previous examples connect with the simulator through a TCP
|
||
|
socket on your PC. Use <code>tcpConn.setPort(host, port)</code> to set the TCP
|
||
|
hostname or IP address and related socket number to another machine on
|
||
|
the network. For instance, use <code>tcpConn.setPort("bill", 8101);</code> to
|
||
|
connect to the simulator which is running on the networked computer
|
||
|
"bill" through port 8101.
|
||
|
|
||
|
Replace <code>ArTcpConnection con;</code> with <code>ArSerialConnection con;</code>
|
||
|
to connect with a robot through the default serial port (<code>/dev/ttyS0</code>
|
||
|
or <code>COM1</code>), or another you specify with ArSerialConnection::setPort(),
|
||
|
such as <code>con.setPort("COM3");</code>.
|
||
|
|
||
|
At some point, you may want to open the port with the more
|
||
|
verbose <code>con.open()</code>.
|
||
|
|
||
|
\subsection connrw Connection Read, Write, Close and Timestamping
|
||
|
|
||
|
The two main functions of a device connection are
|
||
|
ArDeviceConnection::read and ArDeviceConnection::write. Simple
|
||
|
enough. ArDeviceConnection::close also is inherited and important. You
|
||
|
probably won't use direct read or write to the robot device, although
|
||
|
you could. Rather, ArRobot provides a host of convenient methods that
|
||
|
package your robot commands, and gather and distribute the various
|
||
|
robot information packets, so that you don't have to attend those
|
||
|
mundane details. See the next section for details.
|
||
|
|
||
|
All ArDeviceConnection subclasses have support for timestamping
|
||
|
(ArDeviceConnection::getTimeRead). With the robot connection,
|
||
|
timestamping merely says what time a robot SIP came in, which can be
|
||
|
useful for interpolating the robot's location more precisely.
|
||
|
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|