Overview
The RoboCar system comprises three major software sub-systems:
I/O Processor -- real time data acquisition and control;
Main Processor -- direct control of the robot device;
Mothership -- the GROUNDS command and telemetry system;
Please refer to the main page Overview document for a diagram and general
descriptions of the components.
The PIC I/O processor will be programmed in native code
using MPASM.
It will format all of the input signals into a serial
data stream that will be passed to the TINI Main Processor.
The data stream to the main processor will consist of 8 bytes, repeating
in the following order:
Input from Main Processor
The I/O processor will also receive a serial output data stream from the
Main Processor and format signals to control the RoboCar motors and Locator
Signal.
The data stream from the main processor will consist of 5 bytes, repeating
in the following order:
The main processor will be programmed in Java with native
access methods in `C' where required. This will allow it to be fairly portable
and network aware. It can run on the TINI Java board or on an external
host with a, generally serial, connection to the actual robot device. The
rest of this document will describe the Main Processor's common features
and point out places where different platforms provide alternatives.
The main operational access is via classes which implement the Command
interface. Each instance of a Command encapsulates a set of operations
for the robot to perform. The contents and scope of the instructions varies
according to the which Command Interpreter Level is targeted, as indicated
below. When each command is completed by its appropriate level, the Command
class is reset to reflect what (we hope) actually happened and returned
to the caller.
A few `emergency' commands, for instance Interrupt and Quit,
will cause the robot to stop doing whatever it is doing and return for
new instructions. There are also command classes for status and parameter
setting that are discussed below. The contents and format of all commands
is in the RoboCar Command document.
The heart of the Main Processor is a set of four hierarchical
'Command Interpreters' which execute robot commands at increasing levels
of specificity. Each of the interpreters implements the InterpreterLevel
interface:
Goal -- Purpose in life, e.g., Map environment, Swarm with others, etc.
Strategy -- Main task set, e.g., Map by following walls, Map by criss-crossing
space...
Tactical -- Sequence of operations for a sub-task, e.g., Drive to wall
then backup and turn;
Device -- Atomic set of controls to perform an individual operation, e.g.,
Drive Speed, Turn Radius, etal
Device Level
The lowest
Device level converts individual operational instructions,
motion, locator signaling, etc., from a description common to all RoboCar
devices to the specific information needed to control the actual robot
hardware. For instance, all distances are measured in centimeters, but
the actual device may need encoder counts or a motor-on time as the controlling
data. The scope of the
devCommand is a single atomic robot operation
such as: "turn 90 deg left, go 50 cm, broadcast this locator data, and
stop when you hit something". The Device class is abstract and extended
by each kind of RoboCar in order to correctly describe the actual capabilities
of the robot.
The Device class contains a set of robot specific 'controls' and communication
modules as described below.
ControlData interface
ControlData is an abstract base class which encapsulates
the handling of all the real and derived control signals in the robot.
It is fundamentally responsible for parsing the appropriate input sensor
data from the I/O Processor into the system common format, and converting
output control data into the format required by the I/O Processor. All
of the information is based on the state of the DataIO class for this device.
The following classes extend ControlData to describe individual sensors
and controls:
Drive -- drive speed and distance (abstract);
Turn -- steering radius and heading change (abstract);
Bumpers -- data from the binary bumper input switches (abstract);
Locator -- Locator Signal, for both sending and receiving (abstract);
Battery -- voltage and (dis)charge rate (abstract);
Pir -- data from the binary Passive IR detector (abstract);
ElapsedTime -- amount of time elapsed;
Position -- estimated robot position and heading in the environment;
EndState -- status mask to terminate operation, indicates what actually
happened on completion;
The classes labeled abstract need to be fully implemented
by each kind of RoboCar device. They implement the 'top half' of the processing
needed -- to deal with the common data formats; but the 'bottom half' that
deals with the device specific formats still needs to be implemented. Those
that are not abstract are derived from the state of other controls or known
classes and can (usually) be used without modification.
DataIO Interface
The Device class for each kind of robot contains an extension of the
DataIO
abstract base class that is specific to the robot's communication and command
needs. The interface describes methods needed to wrap the actual I/O processor
data stream in order to manage it transparently. It also implements an
independent "IOthread
" thread to read and write to the I/O Processor
on the robot. There are a number of implementations, including:
simDataIO -- an I/O simulator connects to a simple command line
monitor. Using the simulator, Main Processor code may be tested directly
on the development host thus avoiding repeated download cycles and giving
access to debuggers, et al, on the host system. Details of the simulator
will be developed adhoc;
rcDataIO -- the 'real' roboCar I/O processor;
dcDataIO -- the Descartes radio link;
Tactical Level
The
Tactical level implements devCommand sequences to independently
perform sub-tasks such as searching for a wall or locator signal. It is
also responsible for maintaining a map of the environment which is updated
as the robot bumps into things and finds its way around. It will be implemented
as a set of weighted state machines which can be built and modified on
the fly...TBD. The tactCommand specifies which machine to execute and parameters
for its execution.
Strategy Level
The Strategy level implements sequences of tactCommands to perform larger
tasks such as various approaches to creating a map of the environment.
It can use the map maintained by the Tactical level to plan routes and
decide how to handle obstacles It will be implemented as a set of weighted
state machines which can be built and modified on the fly...TBD. The stratCommand
specifies which machine to execute and parameters for its execution.
Goal Level
The
Goal level implements sequences of stratCommands to achieve
objectives requested by 'god', or the Mothership at least. It will
be implemented as a set of weighted state machines which can be built and
modified on the fly...TBD. The goalCommand specifies which machine to execute
and parameters for its execution. A sequence of goals may be specified
at the level as well, such that the RoboCar could independently decide
to stop mapping the environment and start playing with another robot.
Other Components
Besides the Command Interpreters there are a number of other useful sub-systems
in the Main Processor code. Like the DataIO class, some of these components
use separate threads to perform their tasks independently.
Command Input and Execution
External RoboCar commands can be issued from a number of sources. To make
this as transparent as possible the
commandIF interface encapsulates
the operations needed to receive and parse a command. This interface is
used by the
cmdFactory class to create new Command objects which
it stores in a private FIFO queue. The cmdFactory constructor starts a
new
cmdThread thread "CmdThreadN" for each commandIF that is specified.
These threads wait on their data sources and insert Commands into the cmdFactory's
queue as they are received. There are a number of commandIF implementations:
commandIFlocal -- gets commands and parameters from the local console (stdin);
commandIFj2ee -- gets commands from the Mothership using RMI;
The
cmdExecute class extracts Commands from the queue and sends
them to the appropriate Command Interpreter level. The executor and the
interpreters all run in the main thread of the process so they are sequential
in operation. Due to this, the cmdFactory itself sends Interrupt commands
directly to the Goal level where they propagate down while executing in
the CmdThreadN, and thus cause the main thread to stop what it is doing.
Telemetry
The T
elemetry class contains all the logic necessary to log data
to a local file or external system. All of the Command Interpreters, and
the IOthread, log their commands and results using the Telemetry object.
All logging is in a simple XML format described in the RoboCar Telemetry
document. If external logging is enabled the Telemetry object starts a
new "
TELEthread" thread to execute the appropriate s
erverIF
methods. The serverIF interface defines the methods needed connect and
write to, for instance, the Mothership using RMI. There are a number
of serverIF implementations:
serverIFj2ee -- sends XML telemetry to the Mothership using RMI;
Parameter Management
The
Params class contains system initialization and state saving
functions. When the restore() method is called it tries to read the "
robo.properties"
file to set the device's ID, operating parameters, and a number of static
boolean values to control trace and error messages, among other things
(which can be intuited by looking at the source file...). It also tries
to read a saved state file named in the properties file. If the state file
exists it is read into memory and used to set adjustment parameters for
the Device, as well as state tables for the other Command Interpreter levels.
When the store() method is called, all the properties and parameters are
written out to their respective files. This can be used to initialize these
files to default values.
Each type of saved parameter has a specific class that extends the ParamData
abstract base class. Objects of these classes can be accessed through the
Params object. The classes are:
DevParamList -- contains the adjustment parameters for the device controls:
driveParam -- parameters for converting distances and speeds to actual
device data:
driveSet -- individual set of parameters for one drive speed;
turnParam -- parameters for converting turn radii and headings to
actual device data:
turnSet -- individual set of parameters for one turn radius speed;
TactParamList -- parameters for the Tactical level;
StratParamList -- parameters for the Strategy level;
GoalParamList -- parameters for the Goal level;
Mothership
The GROUNDS system running on the Mothership collects data from multiple
external devices, both robots and tracking or measurement systems, and
logs the data in a local database. It also supplies interfaces for external
programs to select relevant data from the logging database, or directly
from the devices, and to feed commands back to the devices. The external
programs can be either standalone or Web browser based. Details can be
found in the Grounds documentation. The basic modules are:
EJB container -- the Java Enterprise Edition 'operating
system' which hosts GROUNDS;
CloudScape database -- a relational DB for logging data, accessed
through GROUNDS ;
Web server -- a GROUNDS interface for use by standard web browsers;
dataCollector bean -- the Enterprise Java Bean (EJB) used to
log data and get commands;
dataSelector bean -- the EJB used to get logged data and monitor
real time responses;
table accessor beans -- a set of EJBs used to access various
database tables;
Process and Thread Structure
From all of the foregoing it should be apparent that there are four main
"processes" that comprise the entire RoboCar system. First, the I/O Processor,
the actual robot's controller, either an embedded system or the real RoboCar's
PIC chip. Second, the Main Process running on the TINI Java card, or as
a proxy on some external host. Third, the GROUNDS system running on the
Mothership. And last but not least, the external Monitoring and Command
programs which may be running anywhere on the net.
Each of these process has a number of separate threads of execution:
The I/O Processor (in the case of the PIC chip at least) has a main
program loop which collects and formats data to be sent to the robot and
the Main Process, and an interrupt loop which handles the time sensitive
data I/O functions.
The Main Processor has a number of concurrent threads, as described
above. The primary threads are:
main -- default -- Initializes the system and runs the Command Interpreters;
DataIO -- IOthread -- handles the serial communication between the
I/O and Main Processors;
telemetry -- TELEthread -- handles logging communication with Mothership;
cmdThread -- CmdThreadN -- one or more command input listeners;
Each Command Interpreter level may start threads of its own as well.
The Mothership uses the EJB container to manage execution threads, such
that requests are processed in a timely manner. One of the features of
the J2EE system is that the programmer doesn't need to deal with explicit
thread or resource management.
The external 'experiment' programs have yet to be designed and can be
arbitrarily complex.
Communication
Locator Signal -- Direct Inter-Car Communication
The RoboCar infrared Locator Signal is used to broadcast
16 bits of data to other devices. The entire signal is provided by the
Main Processor and formatted for broadcast by the I/O Processor. The data
consists of:
Device Identifier -- 4 bits. Unique to each RoboCar device including
Charging Stations, with 0 being unused. This implies that there can be
a maximum of 15 RoboCars and Charging Stations in a community;
Device Status -- 4 bits. To synchronize community behaviors:
Destination Identifier -- 4 bits. RoboCar ID of destination car
for the following command. 0 would indicate a broadcast request;
Command -- 4 bits. To enable community behaviors:
RoboCars will be able to detect broadcast signal data
from all directions. The Locator Signal strength detector will only be
used for finding a particular signal's source.
Mothership Communication
In most cases communication between the GROUNDS system and external processes
or RoboCars uses ASCII formatted XML. The actual communication channel
depends on the system, but may be:
RMI using J2EE interfaces
Standard socket() [for TINI Java card]
Web based
The data formats are described in the GROUNDS documentation.