\input rccluginit.latex

\chapter{Other Features}

\section{Program Modes and Options}

Multi-RCCL provides several program-selectable options which will
cause the program and the manipulators to behave in different ways.

\subsection{Options}\label{options}

{\it Options} are used to
control behavior associated with the entire program.
Each option has an associated bit code, and may be set or
read back with the routines
\begin{verbatim}
        unsigned long rcclSetOptions (mask)
          unsigned long mask;

        unsigned long rcclClearOptions (mask)
          unsigned long mask;

        unsigned long rcclPutOptions (mask)
          unsigned long mask;

        unsigned long rcclGetOptions (mask)
          unsigned long mask;
\end{verbatim}
{\tt rcclSetOptions()} and {\tt rcclClearOptions} set or clear, respectively,
the options indicated by {\tt mask}. {\tt rcclPutOptions()} loads
all the options at once. {\tt rcclGetOptions()} returns the settings of
the options specified by {\tt mask}.

The program options currently implemented include
\begin{verbatim}
                             Default Value
        RCCL_ERROR_EXIT         not set
        RCCL_SIMULATE           not set
        RCCL_LEAVE_POWER_ON     not set
\end{verbatim}

{\tt RCCL_ERROR_EXIT}, if set, causes most RCCL and RCI
functions to print diagnostic information and exit the program in the event
of an error. This is useful in top level applications and development
work, because it saves the programmer from having to
perform explicit error checks on the routines.
If a particular function responds
to this option, it will be documented as doing so in the reference manual.
Setting the option also causes the RCI option {\tt EXIT_ON_ERROR}
to be set.

{\tt RCCL_SIMULATE}, {\bf if set before} the first call
to {\tt rcclCreate()},
will cause the program to run in simulator mode (see section \ref{simulate}).
(If it is set after the first call to {\tt rcclCreate()}, it will have
no effect.)

{\tt RCCL_LEAVE_POWER_ON} causes the robot arm power to be left on
when {\tt rcclRelease()} is called, regardless of the setting of that
function's {\tt powerOn} argument. The power will still be switched
off if the control task is terminated by an RCI abort.

\subsection{Modes}\label{modes}

{\it Modes} control activity specific to a particular
manipulator. They are set and
read with routines similar to those for the RCCL options:
\begin{verbatim}
        unsigned long rcclSetModes (mnp, mask)
          MANIP *mnp;
          unsigned long mask;

        unsigned long rcclClearModes (mnp, mask)
          MANIP *mnp;
          unsigned long mask;

        unsigned long rcclPutModes (mnp, mask)
          MANIP *mnp;
          unsigned long mask;

        unsigned long rcclGetModes (mnp, mask)
          MANIP *mnp;
          unsigned long mask;

        unsigned long rcclGetActiveModes (mnp, mask)
          MANIP *mnp;
          unsigned long mask;
\end{verbatim}
{\tt mnp} is the manipulator with which the modes
are associated.
{\tt rcclSetModes()} and {\tt rcclClearModes} set or clear, respectively,
the modes indicated by {\tt mask}. {\tt rcclPutModes()} loads
all the modes at once. {\tt rcclGetModes()} returns the settings of
the modes specified by {\tt mask}. Not all mode settings actually take effect
immediately; some take effect only with the next requested motion.
Because of this, {\tt rcclGetModes()} may not necessarily return the
mode settings that are currently active; this information should instead
be obtained with {\tt rcclGetActiveModes()}.

The following modes are currently implemented:
\begin{verbatim}
                             Takes Effect       Default Value
        TRACKING_MODE        immediately          not set
        INTEGRATE_MODE       immediately          not set
        T6O_EVAL             immediately          not set
        COMPLETE_AT_TB       with next motion     set
        GRAVITY_FEEDFORWARD  immediately          not set
\end{verbatim}

{\tt TRACKING_MODE}
causes the trajectory generator
to continue tracking the last target position when it
runs out of motion requests to execute. It is useful when
we don't want a ``break in the action'' to occur in the event of a time
gap between successive motion requests.

{\tt INTEGRATE_MODE}
enables integration in the PID servo loop controlling the robot's
actuators. This option is defined only for real manipulators
running on systems where the attached servo controller box does in fact
allow integration to be enabled or disabled.
It is principally intended for PUMA robots connected to the Unimation
controller. Enabling integration reduces the steady-state servo error
but can also reduce stability, particularly in cases where
a higher level feedback loop is implemented within the trajectory
generator.

{\tt T6O_EVAL} causes the trajectory generator
to maintain the {\it observed\/} values of {\bf T6} and the joint values in
the {\tt t6o} and {\tt j6o} fields of the {\tt MANIP} structure. This is
normally not
done because the information is frequently not needed and is
expensive to compute.

{\tt COMPLETE_AT_TB} tells the trajectory
generator that the time at which one motion
officially ends (and another begins) is the
{\it midpoint\/} of the transition to the next motion (except
for ``stop'' requests; see below). At this time,
the {\tt MANIP} structure's {\tt here} field is
updated, the motions' status flags are set correctly,
computations which have been requested with {\tt updateTrans()} are
carried out, and any end-of-motion signal that has been requested with
{\tt setMotionSig()} is delivered. If this option is {\bf not} set, then
the time at which a motion officially ends 
is the {\it beginning\/} of the transition to the next motion.
``stop'' requests form an exception to this
option: stop motions are always considered to end at the beginning
of the transition to the next motion.

{\tt GRAVITY_FEEDFORWARD} causes the trajectory
generator to compute the gravity loading for the manipulator and feed it
forward to the servo level controllers. This option is very site specific and
was implemented specifically for the Jet Propulsion Laboratory.

\subsection{The Parameter File}\label{params}

Some program control parameters are defined in an ASCII
file that is read by the system each time an RCCL program starts up.
The file is named {\tt .rciparams}; a standard copy exists
in the directory {\filefont \$RCCL/conf}.  The user can also create a private
copy of this file in her/his home directory (which overrides the system
version) or in the current directory (which overrides all other versions).

A typical {\tt .rciparams} file looks like this:
\begin{verbatim}
        # system parameter defs for rci
        name = RCISYS   ARBCLOCK=5.0
        #
        # parameter set used by utility programs
        name=sysprogs   cpus=0x01 scheduling=ON_TRIGGER interval=20
        #
        # parameter set used by RCCL
        name=RCCL       cpus=0x3 simulate=0 interval=30 timeout=10
\end{verbatim}

Not all of the things in this file are relevant to RCCL; the parameter
sets named {\tt RCISYS} and {\tt sysprogs} are used by other parts
of the RCCL/RCI system.
In the example here, the RCCL parameters are at the bottom
and are denoted by the construction {\tt name=RCCL}.
All of the parameters have
the form {\tt <field>=<value>}, where {\tt <field>} is a field name
and {\tt <value>} is either an integer, a float, or a string
(delimited by either white space or by quotes ({\tt ""})). In the above
example, the parameters {\tt cpus}, {\tt simulate}, {\tt interval}, and
{\tt timeout} are defined.

In general, RCCL recognizes the following parameters:
\begin{verbatim}
           cpus         (hex integer)
           interval     (integer)
           speed        (float)
           tvel         (float)
           rvel         (float)
           simulate     (boolean integer OR string)
           timeout      (integer)
           scheduling   (string) 
           leavePowerOn (boolean integer)
\end{verbatim}

{\tt cpus} is a bitmask describing which CPUs can be used to
run the trajectory generator tasks. On single CPU systems, this parameter
must have the value {\tt 0x1}.

{\tt interval} defines the sample interval
(in milliseconds) at which the trajectory generator is run. It is the same
quantity which can be set or obtained within the program by
{\tt rcclSetInterval()} or {\tt rcclGetInterval()}

{\tt speed} is an optional velocity scale factor; if specified, all the
velocity settings in the program are multiplied by it. For instance, setting
{\tt speed=0.1} will cause manipulator motions to run roughly 1/10 as fast
(except for cases where the motion time is set explicitly
with {\tt setTime()}). This scaling factor is applied on top
of the
program scaling factor controlled by {\tt setSpeed()}.

{\tt tvel} and {\tt rvel} are optional
parameters which define the default translational and
rotational velocities for Cartesian interpolated motions.
These are the same quantities controlled by the primitive {\tt setCartVel()}.
If these parameters are not set, the program uses the defined constants
{\tt DEFAULT_TRANS_VEL} and {\tt DEFAULT_ROT_VEL}.

{\tt simulate} is an optional parameter, which, if set to
a non-zero integer, causes the
program to run in simulator mode (which has the same effect as
setting the option {\tt RCCL_SIMULATE} at the beginning
of the program).
The program will attempt to connect its robots to a simulator program
which is running on the current machine
and has the name of the current user. To explicitly
specify either the name of the
simulator, or the machine on which it is running,
the {\tt simulate} parameter can be given as a string instead. 
The format used by this string is described in {\tt simAddress(5)}.

{\tt timeout} is an optional parameter which defines the length of time the
trajectory generator task(s) will wait for a response from
the robots before deciding something is seriously wrong and aborting
the program. The units of
{\tt timeout} are control cycles, so if the control level is being run
at 50 msec.\ ({\it i.e.}, {\tt interval} is 50), and {\tt timeout} is set to
10, then the system will wait 500 msec.\ before issuing a timeout abort.
The default value of {\tt timeout} is 2. If the system real-time
response is poor and this value needs to be boosted, the highest
reasonable value is probably around 10.

{\tt scheduling} defines the scheduling discipline used by the trajectory
generator task(s). The default scheduling discipline is {\tt ON_TRIGGER}.
Other scheduling disciplines are {\tt ON_CLOCK} and {\tt ON_FUNCTION}.
It is also possible to set the scheduling discipline from within
an RCCL program by calling {\tt rcclScheduling()} before the
first call to {\tt rcclCreate()}.
Consult the manual page {\tt RCCL_params(5)} for details on what
these scheduling disciplines are all about.

{\tt leavePowerOn} causes the {\tt RCCL_LEAVE_POWER_ON} option 
(see above) to be set during the first call to {\tt rcclCreate()}.
This will cause the robot power to be left on after the 
program finishes, providing the program does not terminate with
an RCI abort.

More information about the RCCL parameters is given in the manual
page {\tt RCCL_params(5)}. Information about the format of the 
{\tt .rciparams} file may be found in the manual page
{\tt rciParameters(3)}.

\section{Error Handling and Recovery}\label{error}

\subsection{The Error Stack}\label{errorStack}

Most RCCL and RCI
routines return either {\tt NULL} or {\tt -1} if they fail, depending on
whether the routine normally returns a pointer or an integer. Also, they will
usually place diagnostic information on the task's {\it error stack\/}. This
is a special buffer used for storing error codes and messages.
The idea is that when some internal routine fails, it
places a code and a message on the error stack; when higher level routines
discover the error, they too can place information on the error stack. When
the error is discovered at the top level, the error stack contains a fairly
complete trace of what went wrong and where.

A typical thing for a top level application to do when it finds that a routine
has returned an
error is to print the contents of the error stack and exit. This is done with
the routine {\tt printErrors()}, and is commonly coded like this:
\begin{verbatim}
        if (routine() == -1)  /* error indicated by -1 in this case */
         { printErrors();
           exit(-1);
         }
\end{verbatim}

\begin{quote}
{\bf NOTE}: {\tt printErrors()} must not be called from the control
level. {\tt rciPrintErrors(NULL)} should be used instead. See below.
\end{quote}

One should verify that a routine does in fact use the error stack before
calling {\tt printErrors()}; otherwise, the error
stack is likely to be empty and nothing interesting will be printed.
When in doubt, consult the reference manual entry for the routine
in question.

Application software can also add its own error codes
and messages to the error stack.
The common way of doing this is to use the routine {\tt errorMsg()}:
\begin{verbatim}
        errorMsg (code, format, values ...)
          int code;
          char *format; 
\end{verbatim}
The error code is the first argument to the routine. The message is
specified by a {\tt printf()} style format string (second
argument) followed by a variable
number of arguments containing values referred to by the format string.
As an example of using the error stack, consider the following program:
\begin{verbatim}
        main()
        {
                if (routine1() == -1)
                 { printErrors();
                   exit (-1);
                 }
        }

        routine1()
        {
                char *fxnName = "routine1()";

                if (routine2() == -1)
                 { errorMsg (1, "%s -- function call failed\n", fxnName);
                   return (-1);
                 }
                return (1);
        }

        routine2()
        {
                char *fxnName = "routine2()";

                errorMsg (1, "%s -- not written yet!\n", fxnName);
                return (-1);
        } 
\end{verbatim}
Running this will produce the following output:
\begin{verbatim}
        routine1() -- function call failed
        routine2() -- not written yet!
\end{verbatim}

If, instead of exiting, the application software wishes to continue
running, it should clear the error stack by calling {\tt clearErrors()}.
Interactive programs will frequently print the error stack, clear the errors,
and continue running, as in
\begin{verbatim}
        if (routine() == -1)
         { printErrors();
           clearErrors();
         }
\end{verbatim}

It is also possible to reference the error codes on the error stack.
These are primarily intended for use by software (versus messages,
which are mainly for users to look at). In cases where
software continues to run after detecting an error, error codes
may be useful in helping the software decide what sort of action to take.
The routine {\tt getErrorCode(n)}
returns the error code from the $n$-th position on the stack, where 0
corresponds to the information most recently added.
Application code which uses the error codes typically looks
something like this:
\begin{verbatim}
        if (routine() == -1)
         { if (getErrorCode(0) == ENotSetup)
            { setUpData();
            }
         } 
\end{verbatim}

Error codes are also sometimes ``passed on'' when a calling routine
adds its own information to the error stack:
\begin{verbatim}
        if (routine() == -1)
         { errorMsg (getErrorCode(0), "routine() failed\n");
           return (-1);
         } 
\end{verbatim}

The error codes used by RCCL/RCI are defined in the file
{\tt <errorCodes.h>}.
Error codes aren't used as much as the error messages.

Each RCI task has its own private error stack, which becomes
the current stack when the task's context is invoked.
If you call {\tt errorMsg()} from the planning level and then
from the control level, the first message will go to the
standard error stack, and the second will go to the control
task's error stack.

To explicitly reference the error stack for an RCI task 
from {\it outside} that task's context, one may use the routines
\begin{verbatim}
        rciPrintErrors (td)
        rciErrorMsg (td, code, fmt, ...)
        rciClearErrors (td);
        rciGetErrorCode (td, n)
\end{verbatim}
These behave identically to the error stack routines described above,
except that they use the error stack of the RCI task whose
descriptor is specified by the additional first argument.
If the supplied task descriptor is {\tt NULL}, then the current
error stack is used. {\tt rciPrintErrors()} can also be called from
the control level, whereas {\tt printErrors()} cannot. 
Recall that to get the descriptor for the RCI task associated with a
particular manipulator {\tt mnp}, one may use the macro
{\tt MANIP_TASK(mnp)}.

When an error occurs at the control level, and one wishes
to exit the program, it is necessary to call {\tt rciAbort()}
instead of {\tt exit()} (see section \ref{rciabort}). 
There is a special form of {\tt rciAbort()}, called
{\tt rciAbortErrors()}, which transfers the messages on the error stack into
the abort message buffer and then calls {\tt rciAbort()} itself. 
A piece of code that invokes this looks like:
\begin{verbatim}
        if (routine() == -1)
         { rciAbortErrors();
           return;
         }
\end{verbatim}

Care should be taken to not let errors from routines
that use the error stack go undetected, or 
information will collect on the stack.
The error stacks for the control tasks are cleared automatically
at the start of every control cycle.
For more information on the error stack, see the manual pages
{\tt errorStack(3)} and {\tt rciErrorStack(3)}, or the {\it RCI User's Guide}.

\subsection{Aborting}\label{rciabort}

It is illegal to call {\tt exit()} from the control level. Instead,
RCI provides an abort utility which allows a program to be aborted
(from anywhere) by calling the following routine:
\begin{verbatim}
        rciAbort (code, format, values ...)
          int code;
          char *format;
\end{verbatim}
The first argument specifies a code associated with the abort,
while the second and following arguments specify an abort message
using a {\tt printf()} style format string
and a variable number of value arguments.

Internally, {\tt rciAbort()} causes
a {\tt SIGHUP} signal to be sent to the planning level, where it is
caught by RCI system software. All control tasks are released, which
(for RCCL) means the trajectory generator is switched off.
The default action is then to print the abort
message, along with some other information (which RCI task called
the abort, what CPU was it running on, how many control cycles
had elapsed) and exit the program.

As an example, consider the following simple program:
\begin{verbatim}
        #include <rccl.h>

        abortAtOnce (arg, mnp)
        int arg;
        MANIP *mnp;
        {
                rciAbort (10, "Aborting for fun, arg=%d\n", arg);
        }

        main()
        {
                MANIP *mnp;

                mnp = rcclCreate ("foo", 0);
                rcclStart();
                printf ("Here we go ...\n");
                runMonitorFxn (mnp, abortAtOnce, 123);
                while(1);
        }
\end{verbatim}
This will produce the following output and exit:
\begin{verbatim}
        Here we go ...

        RCI ABORT: task 'RCCL1' on cpu 1, cycle 6
        Aborting for fun, arg=123
\end{verbatim}

Aborts may be issued by the application code at any time. They may
also be issued by the trajectory generator if the manipulator hits
a joint limit or encounters a singularity, or some other aspect of
the control process fails. Aborts will also be issued sometimes in the case
of internal software failure.

More information on {\tt rciAbort()} may be found in the manual pages,
or in the {\it RCI User's Guide}.

\subsection{Catching Aborts Yourself}

As seen in the previous section, the default action for an abort handler to is
to print information about the abort and exit the program. This is often
satisfactory, but for some applications the user may wish to catch aborts
and process them within the program.

The RCI routine
\begin{verbatim}
        (*rciAbortHandler)(handlerFxn)
          int (*handlerFxn)();
\end{verbatim}
specifies an application defined function to be called when an
abort occurs and returns a pointer to the previous handler.
The system will still catch the abort signal and shut down the
trajectory generator and other RCI tasks,
but it will call the handler function instead of printing the
abort information and exiting.
The handler is called with the following arguments:
\begin{verbatim}
        handler (code, msg, td)
        int code;
        char *msg;
        RCI_DESC *td;
        {
                ...
        }
\end{verbatim}
{\tt code} and {\tt msg} are the code and message specified
by the call to {\tt rciAbort()}. {\tt td} points to the descriptor
of the RCI task which initiated the abort.

The handler can do various things. For example, it can print out the abort
information and exit the program, similar to what the default handler does
(although establishing the handler might then be
somewhat pointless). It might be used to print out extra debugging information
before exiting; this is a common application when systems are under
development.
Or it might just return, in which case the program goes on as before,
except the trajectory generator has been shut off and must be started again by
calling {\tt rcclStart()}.

Usually, if it desirable to keep executing the program after an abort,
the best way to do
this is to {\tt longjmp()} out of the abort handler to some defined checkpoint
and restart the trajectory generator from there. If you don't know what
{\tt longjmp()} is, then you should find out (check either a
C programming guide or the UNIX manual page for {\tt longjmp(3)}, or
ask whichever programmer at your site has the longest hair).

An example of using an abort handler with {\tt longjmp} is given by the
following program:
\begin{verbatim}
        #include <rccl.h>
        #include <setjmp.h>

        jmp_buf env;

        handleAbort (code, msg, td)
        int code;
        char *msg;
        RCI_DESC *td;
        {
                printf ("\nABORT called\n");
                rcclAbortReset();
                longjmp (env, 1);
        }

        doAbort (arg, mnp)
        int arg;
        MANIP *mnp;
        {
                rciAbort (10, "");                      /*1*/
        }

        main()
        {
                MANIP *mnp;
                int first = YES;

                rciAbortHandler (handleAbort);
                mnp = rcclCreate ("foo", 0);
                if (setjmp (env))
                 { first = NO;
                 }
                printf ("Starting ...\n");
                rcclStart();
                if (first == YES)
                 { runMonitorFxn (mnp, doAbort, 123);
                 }
                while(1);
        }
\end{verbatim}
The program starts, aborts itself, catches the abort
with its own handler, and then starts up again. Notice
that the call to {\tt rciAbort()} gives a null message,
since no use is made of the message by the handler (\cref{1}).
Another discussion of using {\tt longjmp()} with
{\tt rciAbort()} is found in the {\it RCI User's Guide}.

There are several caveats that should be observed when doing things with abort
handlers. The first is that many of the RCCL routines are not re-entrant
(if you don't know what re-entrant is, consult your local system guru).
Basically, this means that things might fail if you call an RCCL or
RCI routine from a handler while another (or perhaps the same)
RCCL or RCI function is in progress in the main program. For instance,
consider what might
happen if the main program is inside a call to {\tt allocTrans()} when
an abort fires. If the handler ``long jumps'' out to a catch point, the
original call to {\tt allocTrans()} will never return properly
and some of its internal data structures could be left in an
undefined state. Technically, this is a problem with most UNIX packages
as well; for instance, the {\tt stdio} library is not guaranteed to function
correctly if its routines are exited in this way. Similar problems
can occur if one tries to call library routines inside a signal handler.

The RCCL routine {\tt rcclAbortReset()} should be called
before doing a {\tt longjmp()} out of a handler. This does a few things to try
and fix up the system state, although it is not guaranteed to be perfect.
In general, care should be taken not to {\tt longjmp()} out of routines that
allocate memory or manipulator objects, such as {\tt allocTrans()},
{\tt allocMem()}, {\tt rcclCreate()}, etc. Motion request primitives are
generallysafer because the motion queue is reset when {\tt rcclStart()} is
called.

\subsection{Program Crashes}

When you run a regular UNIX program and an exception occurs
like a divide by zero or a memory fault, you generally get a message
like
\begin{verbatim}
        Floating exception (core dumped)
        %
\end{verbatim}
or
\begin{verbatim}
        Segmentation fault (core dumped)
        %
\end{verbatim}
The same thing will happen with an RCCL program, if the
exception occurs {\it within the planning task\/}. If instead the
exception occurs in one of the control tasks, then
what happens depends on the host system.

On MicroVAX and Sun4 systems, the exception results in a
signal being sent to the RCI planning level, 
which then prints out some diagnostic
information and exits the program.
The information printed includes the CPU
on which the exception occurred, some information about the type of exception,
a {\tt pc} (program counter), and a stack trace. A program crash for
a divide by zero on CPU 1 might look like this:
\begin{verbatim}
        Program Crash on CPU 1
        arithmetic trap, pc = 0x68 (floating divide by zero fault)

        Stack trace follows --

         PC values  arguments

               68 :         0    864ac
            24927 :     8c200
            17fb9 :     3c4d4        0
            1caa4 :     3c4d4
            1c7b2 :     3cb40
            1c738 :         1
\end{verbatim}
The {\tt pc} and the stack trace are useful in deciding where the
crash occurred. The {\tt pc} is the exact place where the program was executing
when the exception happened. The stack trace lists the
call addresses (on the left) and arguments
(on the right) for the routines leading up to
the exception point. The deepest routines are
listed in top. Although this is not a symbolic stack dump,
one can use the UNIX debugger {\tt adb} to find out what routine
names correspond to the indicated addresses.

A word of caution regarding stack dumps on SPARC machines: all the routines
will be listed as though they were called with six arguments, even if they
were not. This is an artifact of the SPARC hardware. If the routine was
called with more than six long words of argument, only the first six will be
printed. If fewer than six long words of argument were used, then one should
just ignore the remaining words.

There is insufficient space here to go into great detail about
interpreting stack dumps. One can look at the document
{\filefont doc/stacktrace.doc}, which describes how to do this for
VAXen (the idea for other machines is similar). You might ask
why a core dump is not created instead of
a simple stack trace. The reason is that the control level
may be executing on another CPU, and uploading a core dump
from the remote CPU was just a bit too complicated to implement right now.

On SGI systems, a crash at the control level will generate
a core file for the RCI control level. A signal is sent to the RCI planning
level, which then prints a message similar to
\begin{verbatim}
        Program crash in RCI control level. Check core file.
\end{verbatim}
and forces a program exit.

On VxWorks systems, a crash at the control level will result
in the usual VxWorks exception message and the suspension of the
VxWorks task, called {\tt rciCtrl}, which implements the RCI control level. 
The RCI planning level is {\it not} notified. However, when the
planning level exits, the task {\tt rciCtrl} is not deleted
(as normally happens), but is left around for examination 
by VxWorks debugging primitives.

\section{The Simulator}\label{simulate}

RCCL/RCI supplies a program, named {\tt robotsim}, that
provides 3D graphic simulation for one or more robots.
These robots can be ``connected to'' and controlled
by an RCCL program. The simulator provides
a way to graphically preview programs, single
step individual control cycles, and provide simulated
sensor inputs.

To use {\tt robotsim}, the user
needs to do two things:

\begin{list}{}{}
\item[1.]Start the simulator program running, using a command like
\begin{verbatim}
        % robotsim <robotName>
\end{verbatim}
\item[]It may be preferable to do this in 
a separate window, since the simulator normally prints
messages while it operates (although this can be suppressed
with the {\tt -s} option).

\item[2.]Set the RCCL program itself to run in simulator mode. 
There are several ways of doing this, as discussed in the
following section.

\end{list}
\subsection{Making RCCL Use the Simulator}

An RCCL program will run in simulator mode if 
\begin{verbatim}
        rcclSetOptions (RCCL_SIMULATE)
\end{verbatim}
is called at the very beginning of the
program (before the first call to {\tt rcclCreate()}), 
or if the {\tt RCCL} parameter {\tt simulate} is set
to a non-zero value in the {\tt .rciparams} file 
(see section \ref{params}). RCCL will then
connect its robots to a simulator program instead of
to a real robot controller. 

Simulator programs have ``names''
so as to distinquish them from one another and allow different
ones to be run on the same system at the same time. The program
{\tt robotsim}, for example, normally sets its name
to the user name under which it is invoked. Unless told
otherwise, RCCL will try to connect its robots to a
simulator program which is running on the current machine
and has the name of the current user. To specify a
simulator running on a different machine or with a
different name, the {\tt simulate} parameter can be set
to a simulator {\it address string} instead of a
non-zero integer. Similarly, the routine
\begin{verbatim}
        rcclSetSimulator("<address string>")
\end{verbatim}
can be called in place of {\tt rcclSetOptions(RCCL_SIMULATE)}.
In both cases the address string can specify the desired
simulator name, and/or the host machine on which it is running.
The format of the address string is described in the manual
page {\tt simAddress(5)}.

When running the
simulator, particularly on the same machine,
it may be desirable to ``turn down'' the RCCL sample interval,
because of the computational load introduced by the
simulator. When doing simulation runs, this author usually sets the
trajectory generator to run at 100 msec., either by using
the {\tt interval} parameter in the {\tt .rciparams} file,
or by calling {\tt rcclSetInterval()}.

In simulation mode,
the trajectory generator is run off of {\tt SIGALRM}
instead of a kernel level interrupt. The advantage of this is that the
``control level'' is now run in UNIX user mode.
In particular, it is possible
to set breakpoints in the control level functions and step
through them with a debugger. This capability proved invaluable when
developing the RCCL system code, 
particularly the trajectory generator.

One problem is that the simulator's use of {\tt SIGALRM} prevents
application software from using this signal. Specifically,
it means that application software must not call {\tt sleep()}
(which uses {\tt SIGALRM}), but must use {\tt nap()} instead.

\subsection{Simulator Features}

By default, the simulator will create a graphics window 
containing a representation of the robot(s) being simulated.
Graphics are available on systems with Xwindows, SunView, or
GL (the SGI graphics library). Xwindows and SunView use
wireframe graphics (with backface removal), while GL uses
full shaded graphics.

Specific features of the simulator program presently include:

\begin{list}{}{}

\item[$\diamondsuit$]
the ability to ``simulate'' more than one robot;

\item[$\diamondsuit$]
a configuration file that can be used to define 
other graphic objects to be displayed in addition to the robot;

\item[$\diamondsuit$]
an interactive mode which allows the user to single step
through control cycles and set various ``inputs'' to the simulated
robot controller;

\item[$\diamondsuit$]
the ability to control the graphics view point by moving a
mouse cursor across the window;

\item[$\diamondsuit$]
an optional graphic ``teach pendant'', attached to the
graphics window, which can be used to simulate
teach pendant inputs to the RCCL or RCI application.

\end{list}

For detailed information about the simulator program, the manual
page {\tt robotsim(1)} should be consulted. The simulator is
still in a state of development, and new features are frequently
appearing. 

If the simulator is run interactively, then there are commands which allow the
operator to set sensors to specific values. The interactive mode also
allows the operator to single-step through different control cycles,
setting different sensor values at different points. This can be useful, but
is also tedious, and many applications involving real-world input
can be debugged more easily by using {\tt rciPrintf()} on-line.

The limitation of the simulator is that it simulates only arm
movements: it has no knowledge of the workspace around it or real-world
events.
Dynamics are only roughly simulated in the form of gravity loadings.
However, adding modules to do dynamic
modeling or collision detection should not be difficult.

\subsection{A Sample Program Running in Simulation}

The best way to learn about the simulator is
to run it, so to this end the reader is encouraged to run the following
example program. 

\subsubsection*{planning level module}
\cverbatimfile{exampleCode/sim.c}
\subsubsection*{control level module}
\cverbatimfile{exampleCode/simCtrl.c}
{\it
\rightskip=0ptplus1fil
NOTE -- this example should run on all PUMA robots.
It lives at {\tt sim.c} and {\tt simCtrl.c} in
{\filefont \$RCCL/demo.rccl}.

}
\medskip

This program is essentially the same as the program ``simple'', except
that a few changes have been made to demonstrate the simulator features.

Before running the program, the user needs to set the simulator program
running. This is best done with the command
\begin{verbatim}
        % robotsim <robotName> -p rcclpark
\end{verbatim}

{\tt <robotName>} should be the name of the default system robot.
The option {\tt -p rcclpark} tells the simulator to start with
the robot in the {\tt rcclpark} position. This is not essential, but it saves
the program from having to first move
the robot there. As was indicated above, it is desirable to run the simulator
on a separate terminal or in another window, since it will
try to print things.
To some extent, the simulator emulates the {\tt moper} program that
is normally loaded into Unimatation controllers, and so when it starts up it
prints the same messages as {\tt moper}:
\begin{verbatim}
        <robotName> Moper started
        <robotName> listening
\end{verbatim}
Although the simulator handles robots other than PUMAs, it acts
as though they all have a Unimate controller.

If running the simulator in another window is impossible, then you probably
want to run it in the background, in silent mode so it won't print anything.
Do this with the command
\begin{verbatim}
        robotsim <robotName> -p rcclpark -s &
\end{verbatim}

The simulator is now running and waiting for a connection
from an RCCL (or RCI)
program. To put itself into simulation mode,
the example program here
explicitly sets the {\tt RCCL_SIMULATE}
option and sets the control interval to 100 msec.\ (\cref{1}, \cref{2}),
so there
is no need to make any changes in the {\tt .rciparams} file.
When the program starts up, the simulator will come alive by
printing
\begin{verbatim}
        <robotName> active (slave)
\end{verbatim}
The program moves the manipulator to an initial position,
does a straight line motion to a point 100 mm.\ along the $x$ axis,
stops, and returns to the initial position. When the program
calls {\tt rcclRelease()}, the simulator will print
\begin{verbatim}
        <robotName> released
        <robotName> listening
\end{verbatim}
and go back to waiting for another program to connect to it.
In particular, the above program can be run again without having to
restart the simulator -- the simulator program, as a separate process,
acts like a running robot controller and responds to whatever RCCL or
RCI program tries to connect to it. To exit from the simulator,
simply break out of it using the interrupt character.

The simulator allows the RCCL system
to create
trajectory log files in either joint or Cartesian coordinates.
This is the purpose of the variables {\tt setpJlf} (for ``setpoint joint log
file'') and {\tt setpClf} (``setpoint Cartesian log file'').
Whenever either of these is set to a valid file pointer, and the trajectory
generator is running in simulation mode, then the output
setpoints for each control cycle are printed into the
respective file.
Information is printed to {\tt setpJlf} in joint coordinates,
using the format
\begin{verbatim}
        <mcount>[T] <jval1> <jval2> <jval3> ... 
\end{verbatim}
where {\tt mcount} is the motion count for that cycle, {\tt 'T'} is
printed if the motion is in transition, and the {\tt <jvaln>} are
the joint values (degrees for rotational joints and millimeters
for prismatic joints).
Information is printed to {\tt setpClf} in Cartesian coordinates,
for which the format is similar:
\begin{verbatim}
        <mcount>[B] <px> <py> <pz> <ang> <ux> <uy> <uz>
\end{verbatim}
{\tt px}, {\tt py}, and {\tt pz} are the translational coordinates,
in millimeters, {\tt ang} is the equivalent angle of rotation, in degrees,
and {\tt ux}, {\tt uy}, and {\tt uz} are the normalized coordinates
of the equivalent axis of rotation. This representation is used
for rotations because it is less ambiguous than
Euler angles.
A special line is also printed into each log file
every time a new motion segment begins, giving information about what sort of
motion segment it is and what some of its parameters are.
Trajectory logging continues until the file pointers
are cleared by the planning level.

The program opens the files {\tt "jlf"} and {\tt "clf"} at
(\cref{5}); the {\tt setpJlf} and {\tt setpClf} variables
are set at (\cref{6}). The call to {\tt rcclBlock()} makes sure that the
trajectory generator has noticed that they are set and
has started recording before
the program proceeds further. When the program has finished executing,
the files should be in the current directory waiting for examination.

\section{General Notes on the Environment}

This section describes how to compile and run RCCL programs.
Some of the description is implementation specific. The information
given here is supplied in greater depth in the
{\it RCCL/RCI Startup and Installation Guide}. In case
of conflict, the latter should take priority.

\subsection{The User's UNIX Environment}\label{unixenv}

The first thing an RCCL/RCI user must do is set up an environment.
This is best done by making a few entries in
her/his {\tt .cshrc} file. The basic set of entries is
illustrated by this example:
\begin{verbatim}
        setenv  RCCL /u1/rccl
        setenv  MANPATH $RCCL/man:/usr/man
        setenv  C_LD $RCCL/bin/ld  # for MicroVAX systems only
        set     path=(. $RCCL/bin ... ... )
        #
        alias   talkRobotX   'termlink -d /dev/RobotX -s 9600'
        alias   loadRobotX   'down -d /dev/RobotX -e 10000 -a 10000 \
                              $RCCL/lsi11/RobotX -t'
\end{verbatim}
Each of these will be described below.

The environment variable {\tt RCCL}
should be set to the root directory of the RCCL system (which is
{\filefont /u1/rccl} in the example). All further references to the
root directory
can now be made relative to this.

The environment variable {\tt MANPATH}
should be set to a list of directories used by the UNIX
{\tt man} program when
looking for entries. It should contain {\filefont \$RCCL/man} 
in addition to the
usual directory {\filefont /usr/man}; this will make RCCL reference 
manual pages
available on-line. {\tt MANPATH} may have a different
name on some UNIX systems.

On MicroVAX systems only, the environment variable {\tt C_LD} 
must be set to
{\filefont \$RCCL/bin/ld}.

The user's path should be set to contain {\filefont \$RCCL/bin}, {\bf ahead}
of {\filefont /bin} and {\filefont /usr/bin}.

The aliases {\tt loadRobotX} and {\tt talkRobotX} are specific
to systems interfaced to the Unimate PUMA controller. They are used
to load and talk to the interface software that runs in the controller
box, and are described in the next section.

\subsection{Starting Things Up}\label{startup}

The information in this section is mostly specific
to systems interfaced to Unimate Mark X controllers.
Again, more detailed information is given in the 
{\it RCCL/RCI Startup and Installation Guide}.
This section will review the basic steps.

\begin{list}{}{}
\item[1.]Check that the robot controller
is powered up. If not, turn it on. In the case
of the Unimate controller,
get out of VAL and into ODT (the LSI11 prom
monitor), which is easily done by toggling the
controller's ``run/halt'' switch.

\item[2.]Check that the necessary RCI interface software is running on the
robot controller (for Unimation controllers, this software is bundled into a
program called {\tt moper}). The easiest way to tell if this is true is to try
and run the RCCL program and see if the system complains about not being able 
to connect to the controller. If there is a problem, the program will
abort with a set of messages that look something like:
\begin{verbatim}
        RCI ABORT: task 'RCCL1' on cpu 1, cycle 0
        rbtStartup() -- cannot connect to robot
        priAttach() -- other end not listening
\end{verbatim}
\item[]A similar thing will happen if the program is being run in
simulator mode and the simulator program is not running.

\item[]The {\tt moper} program used on Unimation controllers
is downloaded from the host machine
through the controller's serial console line,
using a program called {\tt down}.  The controller is assumed to be initially
in ODT. {\tt down} takes several arguments describing the entry point,
the load address, the name of the UNIX file containing the {\tt moper}
executable,
the UNIX serial device connected to the controller console line,
and a flag telling {\tt down} to exit after it has started {\tt moper} up.
These arguments are usually bundled into an alias called
{\tt loadRobotX}, such as the one defined in the
above {\tt .cshrc} example. 
The {\tt .cshrc} file in {\tt \$RCCL} contains
the sample load aliases {\tt load260}, {\tt load560}, and {\tt load760},
which load the default {\tt moper} programs (defined in 
{\filefont \$RCCL/lsi11})
for typical PUMA 260, 560, and 760 robot/controller combinations.
Another alias, {\tt talkRobotX}, is usually defined as well; this invokes
the program {\tt termlink} and is used
to create a virtual terminal interface to
{\tt moper} (over the controller's serial line) once it is loaded.

\item[3.]Check that the robot is calibrated. Again, if it is not, the RCCL
program will exit with an error saying so. To calibrate the PUMA robots,
one usually uses the program {\tt pumacal}, which is described in the
manual pages.
\end{list}

In summary, a typical startup procedure will be given as an
example. The example system consists of a PUMA 560 with
a Unimation Mark II controller connected to the RCCL host system.
Assume that the robot is named {\tt Fred} and that all of its
aliases are set up accordingly.
\begin{verbatim}
        # Turn on robot controller and toggle the run/halt switch
        # to force an exit from VAL.
        # Download moper using the alias loadFred:

                % loadFred
                disabled logins
                 a.text 19760, a.data 3056, a.bss 1334

                Starting address is 4096
                Entry address is 4096
                Loading 24150 bytes ...

                Loading completed.
                Program terminated
                %

        # Now calibrate the robot.

                % pumacal Fred
                %
\end{verbatim}

You should now be able to run RCCL applications indefinitely, until the
controller is powered off; {\tt moper} will remain up and the robot
should stay calibrated even if the host system crashes.

\subsection{Compiling RCCL programs}\label{rcc}

\subsubsection{Using non-ansi compilers}

If you are compiling RCCL applications using a non-ansi C compiler,
you may need to define some special preprocessor symbols so that the
compiler can handle the RCCL/RCI include files.

\begin{desclist}

\bgroup
\catcode`\#=11

\item[\tt #define NO\_PROTOTYPES 1]
Define this if your compiler does not understand prototypes (which
applies to some compilers on SunOS and BSD systems).

\item[\tt #define const]
Define this if your compiler does not understand {\tt const} (which applies
to some compilers on SunOS and BSD systems).

\item[\tt #define void int]
Define this if your compiler does not understand {\tt void} (which applies
to some compilers on BSD systems).

\egroup

\end{desclist}

If made inside the application source code, these definitions
should {\it precede} the inclusion of any RCCL/RCI header files. You may want
to put whatever definitions you use in an include file of their own.

Alternatively, the definitions can be made directly
on the command line for {\tt cc} (or {\tt rcc}, described in the next 
section). Usually the {\tt -D}
option is used to do this. The arguments to define everything
would look like
\begin{verbatim}
      cc file.c -DNO_PROTOTYPES -Dconst= -Dvoid=int
\end{verbatim}

\subsubsection{The {\tt rcc} command}

RCCL programs should be compiled with the
special {\tt rcc} command instead of {\tt cc} (the usual UNIX command
for the C compiler).
{\tt rcc} is a front
end to {\tt cc} which functions identically
except that (1) it automatically references the necessary RCCL
libraries and include directories (including the math library {\tt lm}), (2)
it automatically names its output
file after the first distinct  module that appears in its argument
list, and (3) it takes the necessary
steps to ensure that code in the control level modules is
loaded contiguously and can hence be easily
locked down (or loaded into an auxiliary CPU) when necessary.

When using the {\tt rcc} command,
all modules
containing code or data referenced by the control level
should be grouped together and placed on the command
line to the right of the special keyword argument ``{\tt CTRL}'':
\begin{verbatim}
        % rcc <planning level files> CTRL <control level files>
\end{verbatim}
Other than this, {\tt rcc} accepts all the usual
arguments used by {\tt cc}, including
{\tt -c}, which suppresses the link phase to permit separate
compilation.

We will now present a couple of examples.
The example program in section \ref{simple} is contained in the
single file {\tt simple.560.c}. There are no control level
modules. To compile it, we simply
do
\begin{verbatim}
        % rcc simple.560.c
\end{verbatim}
The necessary libraries and include directories
will be referenced automatically, and the executable will be placed
in the file {\tt simple.560}. To name the executable
something else, just the usual {\tt -o} option can be used:
\begin{verbatim}
        % rcc simple.560.c -o a.out
\end{verbatim}

As a more complicated example, consider the example program in section
\ref{zigzag}. This is contained in two files, {\tt zigzag.560.c} and
{\tt zigzagCtrl.560.c}. The second module contains control level code,
so the compilation command looks like this:
\begin{verbatim}
        % rcc zigzag.560.c CTRL zigzagCtrl.560.c
\end{verbatim}
The executable will be placed in the file {\tt zigzag.560}. The modules
could also be compiled separately, as follows:
\begin{verbatim}
        % rcc -c zigzag.560.c
        % rcc -c CTRL zigzagCtrl.560.c
        % rcc zigzag.560.o CTRL zigzagCtrl.560.o
\end{verbatim}

As a last example, suppose we have the planning level files
{\tt plan1.c} and {\tt plan2.c}, the control level files
{\tt ctrl1.c} and {\tt ctrl2.c}, and a library {\tt mylib.a},
which contains code that will be executed by both the planning and
control levels.
This can be compiled with the command
\begin{verbatim}
        % rcc -c plan1.c plan2.c CTRL ctrl1.c ctrl2.c myLib.a
\end{verbatim}

More information on the {\tt rcc} command can be found
in the manual page {\tt rcc(1)}, and the {\it RCCL/RCI Startup
and Installation Guide}.

\subsection{The Utility Programs}\label{utilprog}

There are a set of programs available for moving the robot arm around
({\tt move}), calibrating it ({\tt pumacal}),
putting its joints in limp, or ``free'' mode ({\tt free}), putting
the joints in weightless mode ({\tt zerograv}), and measuring
calibration parameters ({\tt primecal} and {\tt potcal}).
These programs are {\bf not} written using RCCL; instead, they are written
using a separate, joint-level-only, trajectory generator called
CHASE, which lives in the directory {\filefont \$RCCL/chase}. Each of these
programs is described in the {\it RCI User's Guide}, as well as in individual
manual pages.

In general, the utility programs take the name of the robot to be
controlled as an argument. If no name is given, then the name
of the system default robot, defined in the file
{\filefont conf/defaultRobot},
is assumed.

There is also a general purpose calculator program, called
{\tt arc} (which stands rather lamely for ``A Robotics Calculator'').
It is something of a cross between a basic infix calculator,
RCCL, and ``Matlab''. It permits evaluation of arithmetic expressions
(including matrices), variable assignment, and various functions, including
many of the RCCL functions for manipulating transforms and
vectors, as well as the kinematic functions
for specific robots.

\subsection{The Utility Routines}

RCI provides some utility routines which
may used by RCCL applications. Only a couple of the more useful ones will be
described here. More information may be obtained from either the 
{\it RCI Reference Manual} or the {\it RCI User's Guide}.

The routine
\begin{verbatim}
        char *getDefaultRobot() 
\end{verbatim}
reads the file {\filefont \$RCCL/conf/defaultRobot} to obtain the name of
the {\it default} system robot. This is mainly useful for sites which
make predominant use of one robot.

The routine
\begin{verbatim}
        getRobotPosition (jvalues, posName, robotName)
          float *jvalues;
          char *posName;
          char *robotName; 
\end{verbatim}
reads the file {\filefont \$RCCL/conf/<robotName>.pos} and looks for a set
of joint values named {\tt posName}. If found, they are returned
in the array {\tt jvalues}.

\subsection{Limitations}

There are a few things RCCL users should avoid, or at least be wary of:

\begin{desclist}

\item[{\it control level syscalls\/} --]
System calls should be avoided from the control level. This restriction
is mandatory on Sun4 and MicroVAX systems, where system calls
will result in a program crash. On systems such as VxWorks
and the SGI machines, where the real-time support is provided directly
by the host operating system, system calls are possible but
care should be used because they are often time consuming
and may interfere with the control level timing.

\item[{\it signals\/} --]
Do not use the UNIX signals {\tt SIGHUP} or {\tt SIGXCPU}. These have been
expropriated by RCI for signaling abort and crash conditions. Also,
when running with the simulator, do not use the signal
{\tt SIGARLM}. The simulator uses this to control the trajectory task.
This also means that one cannot use {\tt sleep()} when running
an RCCL program under the simulator,
since this uses {\tt SIGALRM}. Instead, the routines {\tt delay()} or
{\tt nap()} may be used.

\item[{\it forking\/} --]
Sun4 systems do not tolerate a call to {\tt fork()} or
{\tt vfork()} from the planning level while the trajectory
generator is turned on.
\end{desclist}

\newpage
\chapter*{References}\bigskip

{
\def\ref #1{\par
\noindent {\bf #1}\quad\hangindent=2\parindent\hangafter=1\relax}

\ref{[Allworth 81]}
S.T. Allworth,
{\it Introduction to Real-Time Software Design}.
MacMillan Press, Ltd., London,
1981.

\ref{[Hayward and Paul 1986]}
Vincent Hayward and Richard Paul,
``Robot Manipulator Control Under UNIX: RCCL, a Robot Control C Library''.
{\it International Journal of Robotics Research},
Winter, pp. 94 -- 111.
(Vol. 5, No. 4)

\ref{[Kernighan and Ritchie 1978]}
Brian K. Kernighan and Dennis Ritchie,
{\it The C Programming Language}.
Prentice-Hall, Englewood Cliffs, New Jersey 07632,
1978.

\ref{[Lee 1982]}
C.S.G. Lee,
``Robot Arm Kinematics, Dynamics, and Control''.
{\it Computer},
December 1982, pp. 62 -- 80.
(Vol. 15, No. 12)

\ref{[Lloyd, et al 1988]}
John Lloyd, Mike Parker, and Rick McClain,
``Extending the RCCL Programming Environment to Multiple
Robots and Processors''.
{\it IEEE Conference on Robotics and Automation},
Philadelphia, Pa., April 24-29, 1988, pp. 465 -- 469

\ref{[Lloyd 1985]}
John Lloyd,
``Implementation of a Robot Control Development Environment'',
(M. Eng. Thesis).
Dept. of Electrical Engineering, McGill University, Montreal, Canada,
December 1985.

\ref{[Paul 1981]}
Richard P. Paul,
{\it Robot Manipulators: Mathematics, Programming, and Control}.
MIT Press, Cambridge, Mass.,
1981.

\ref{[Paul and Shimano 1976]}
Richard P. Paul and Bruce Shimano,
``Compliance and Control''.
{\it Proceedings of the Joint Automatic Control Conference},
West Lafayette, Indiana, July 27 -- 30, 1976,
pp. 694 -- 699.

}

\newpage
\done
