\documentstyle[12pt,twoside,proof,sf,sltt,cvarl]{rccldoc}
\def\_{%
\expandafter\ifx\the\font\tt%
\char`\_%
\else%
\leavevmode\kern.06em\vbox{\hrule width.3em}%
\fi%
}
% define a few of my own macros ...
\newskip\tableboxskip
\tableboxskip = .125truein
\def\tablebox#1{\vbox{\hrule\hbox{\vrule\kern\tableboxskip
        \vbox{\kern\tableboxskip#1\kern\tableboxskip}
        \kern\tableboxskip\vrule}\hrule}}
%
\begin{document}
\pagenumbering{roman}
\input Cmode.tex
\title{Changes between old RCCL and Multi-RCCL}
\author{John Lloyd}

\date{August 1988}
\maketitle
\parskip = 2ptplus3pt

\begin{abstract}
This document describes the changes between the old RCCL system
(as described in the old {\it RCCL User's Guide}) and the new Multi-RCCL
that has been developed by McGill University and GE/RCA Advanced
Technology Laboratories for a project sponsored by the Jet Propulsion
Laboratory. It is intended mainly as a stop-gap measure until a
proper multi-RCCL user's manual can be completed.
\end{abstract}
\tableofcontents
\newpage
\pagenumbering{arabic}

\chapter{Introduction}

This document is a quick summary of the principle changes that have been
made between the old RCCL system, described in the manual
{\it RCCL User's Guide}, and the new Multi-RCCL system. 
A user's
guide is being prepared for this new system but has not been completed
at the time of this writing. Instead, users may consult this document
and the {\it Multi-RCCL Reference Manual}, which gives manual pages for
all of the functions and a few of the data structures. A description
of the concepts is contained in the paper
``Extending the RCCL Programming Environment to Multiple Robots and
Processors'', although a few of its details may be out of date.

This document is divided into a section describing changes to the old system,
a section describing new features, and a table summarizing all of the changes
to the old system.

\chapter{Changes to Old RCCL} 

\section{The MANIP structure}\label{mnp}

Because Multi-RCCL can control several robots from one program, it was
necessary to collect the variables describing the state of a robot into one
structure. A pointer to this structure, which is returned by the
routine {\tt rcclCreate()} (section \ref{pc}),
is also used to specify a particular manipulator
to the various motion control primitives.

The fields in the {\tt MANIP} structure which are visible to the programmer
include: 
\cverbatim
        TRSF *t6;
        TRSF *t6o;
        TRSF *here;
        TRSF *tool;
        TRSF *rest;

        POS *last;
        POS *park;

        JNTS *j6;
        JNTS *jvel;
        int conf;

        int completed;
        int handPos; @endcverbatim

{\tt t6} is the constantly updated setpoint value of T6. {\tt t6o} is
the {\it observed} value of T6, although this is only updated if the
mode {\tt T6O\_EVAL} is set (section \ref{pc}). {\tt here} is the value
of T6 at the end of the last motion request. {\tt tool} is the constantly
updated value of the TOOL transform. {\tt rest} is the static transform
corresponding to the {\tt park} position. {\tt last} and {\tt park}
are the position equations
\[
{\rm T6} \;=\; {\rm HERE}
\]
and
\[
{\rm T6} \;=\; {\rm REST},
\]
respectively.
{\tt j6} is the constantly updated joint angle setpoint, and
{\tt jvel} is the constantly updated joint setpoint velocity.
{\tt conf} is an integer describing the configuration of the manipulator.
{\tt completed} is an integer value that is maintained at zero 
by the trajectory generator 
whenever the motion queue is empty, and
{\tt handPos} is an integer describing the position of the hand.

A detailed definition of the {\tt MANIP} structure can be found in the manual
page. 

The entries in the {\tt MANIP} structure are usually
referenced by a pointer to it (which we will call {\tt mnp}). 
For instance, the construction
\cverbatim
        waitfor (completed); @endcverbatim
\noindent
which in old RCCL was used to wait for all the queued motion requests
to finish, is replaced in Multi-RCCL with the construction
\cverbatim
        waitfor (mnp->completed); @endcverbatim

To determine which manipulator a particular motion request should
apply to, the following motion control routines now
require a pointer to {\tt MANIP}
as a first argument:
\cverbatim
        comply (mnp, spec, values ...)
        distance (mnp, spec, values ...)
        limit (mnp, spec, values ...)
        lock (mnp, spec, values ...)
        move (mnp, pos)
        movecart (mnp, pos, tacc, time)
        moveconf (mnp, pos, tacc, time, conf)
        movejnts (mnp, pos, tacc, time)
        setConf (mnp, conf)
        setTime (mnp, tacc, time)
        setMod(mnp, mode)
        setCvel (mnp, trans, rot)
        stop (mnp, time)        @endcverbatim

All of these primitives are otherwise basically unchanged, except for the
{\tt move} and {\tt stop} functions, for which section \ref{move} should be
consulted.

\section{New program control primitives}\label{pc}
The old primitives
\cverbatim
        rccl_open (argc, argv)
        rccl_control ()
        rccl_release (poweroff)
        rccl_close() @endcverbatim
\noindent
have been replaced by a new set of primitives:
\cverbatim
        mnp = rcclCreate (robotName, cpumask)
        rcclStart ()
        rcclRelease (poweroff)
        rcclDelete (mnp) @endcverbatim

{\tt rcclCreate()} creates a trajectory server for the robot
{\tt robotName} on either a default CPU, or one of the CPUs specified
by {\tt cpumask}, and returns a pointer to
a {\tt MANIP} structure for it. 
The routine {\tt rcclDelete()} removes the trajectory
server. If {\tt robotName} is not the name of a robot known to the RCI
system, then an {\it object frame} is created, which is just a coordinate
frame in space that is serviced by the trajectory generator
and can be moved using any of the usual motion control primitives that
are not specific to a physical robot. The object frame is used in doing dual
arm control, and also happens to be a useful debugging feature
(see section \ref{obj}).

{\tt rcclStart()} and {\tt rcclRelease()} function more or less identically
to {\tt rccl\_start()} and {\tt rccl\_release()}.

The sample rate of the RCCL trajectory generator can be set and examined with
the primitives
\cverbatim
        rcclSetInterval (interval)
        rcclGetInterval () @endcverbatim

Bits describing 
program control options can be set, cleared, read back, and assigned
with the primitives
\cverbatim
        rcclSetOptions (mask)
        rcclClearOptions (mask)
        rcclGetOptions (mask)
        rcclPutOptions (mask) @endcverbatim
\noindent
The two options presently implemented are {\tt RCCL\_ERROR\_EXIT}, described
in section \ref{abort}, and {\tt RCCL\_SIMULATE}, which, if set before the
first call to 
{\tt rcclCreate()}, will cause the program to run in simulator mode.

Similarly, options, or {\it modes}, associated with a particular manipulator
can be controlled with the primitives
\cverbatim
        rcclSetModes (mnp, mask)
        rcclClearModes (mnp, mask)
        rcclGetModes (mnp, mask)
        rcclPutModes (mnp, mask) @endcverbatim
\noindent
Modes currently implemented include 
{\tt TRACKING\_MODE}, where a manipulator will continue to track the
last target position when the motion queue empties, {\tt INTEGRATE\_MODE},
which enables integration in the robot position control servo-loop,
and {\tt T6O\_EVAL}, which causes the trajectory generator to update
the {\tt t6o} field in the {\tt MANIP} structure with the observed value
of the manipulator T6 transform.

One last command is {\tt rcclBlock()}, which causes the planning 
task to wait until the trajectory generator has completed one full
control cycle. This provides a cheap synchronization
mechanism between the planning task
and the trajectory generator.

\section{Changes to makePosition}\label{mpos}

The {\tt makePosition()} command has had a few small changes made to
it from the old RCCL. These are:

\medskip
\begin{list}{}{}
\item[$\diamondsuit$]
The position equation is no longer ``optimized''. What you specify in the
argument list is what you get out. 
Equation optimization\footnote
{Multiplying together adjacent constant transforms.}, 
if possible, is done by RCCL when a move
request is made.

\item[$\diamondsuit$]
Instead of the global pointer {\tt t6}, the macro {\tt T6} is used to
indicate the manipulator transform frame. Another macro, {\tt TRANS},
can be used as a synonym. 

\item[$\diamondsuit$]
The manipulator transform can appear on either side
of the position equation.
\end{list}

\section{Synchronization and changes to the move primitives}\label{move}

The {\tt move} and {\tt stop} primitives now return, when successful,
a non-negative motion id which can be used to obtain information
about the motion or start and stop it.

To stop (or kill) a motion, the primitive
\cverbatim
        stopMotion (mid, code) @endcverbatim
\noindent
can be used, where {\tt mid} is the motion id and {\tt code} is a non-negative
status associated with the end of the motion.

If the primitive {\tt motionHold(mnp)} is called before the motion
is requested, then that motion will be queued but will
not be serviced, once it reaches the head of the queue, until it has been
given a go-ahead with the primitive
\cverbatim
        startMotion (mid, code) @endcverbatim
\noindent
This allows the motion to proceed, associating the indicated code with the
start of the motion.

Information about a motion's start code, stop code, its status (is it queued,
running, or finished?), and its scale value\footnote
{The scale value describes how far a motion is from
completion in terms of a number that varies from 0.0 to 1.0.}
can be obtained using the motion id and the following primitives:
\cverbatim
        motionStopCode (mid)
        motionStartCode (mid)
        motionStatus (mid)
        motionScale (mid) @endcverbatim

Macros which use the motion id
to allow us to wait for a motion to either start or complete
include:
\cverbatim
        waitForStart (mid)
        waitForStop (mid) @endcverbatim

Since the flags assigned to motions are re-used
after a certain number of motions, the motion id
becomes invalid after a while. To give the programmer a little more
flexibility, a few motion id numbers are reserved for management by 
the programmer. The call 
\cverbatim
        setMotionFlag (mnp, num) @endcverbatim
\noindent
will set the motion id for the next requested motion on {\tt mnp} to be
equal to {\tt num}, where {\tt num} must be in the range of values
reserved to the programmer.

To stop whatever motion happens to be in service, the primitive
\cverbatim
        stopCurrentMotion (mnp, code) @endcverbatim
\noindent
can be used; this will set the stop code associated with the current
motion to the indicated value.
To pause the motion currently being serviced
for either a specified or indefinite period of time, the primitives
\cverbatim
        pauseCurrentMotion (mnp, time, accel)
        resumeCurrentMotion (mnp) @endcverbatim
\noindent
are available.

Finally, the size of the motion queue can be set, to obtain different
blocking behaviors. If the motion queue size is set to 0, all
{\tt move} and {\tt stop} primitives will block until the
requested motion has completed.
If the motion queue size is 1, all motion primitives will block until the
requested motion is being serviced. Larger motion queue sizes 
of $N$ will cause
all motion primitives to block until only $N-1$ motions are present on the
queue. The command to set the motion queue size is
\cverbatim
        setMotionQueueSize (mnp, size) @endcverbatim

All motions on the queue can be flushed with the command
\cverbatim
        flushMotionQueue (mnp) @endcverbatim

\section{Changes to the ``wait'' primitives}\label{wait}

The macro {\tt waitfor()} has been changed so that it
no longer increments a flag and waits for it to drop to 0.
Instead, {\tt waitfor(cond)} simply waits for the expression
{\tt cond} to return true. Similarly, {\tt waitwhile(cond)} waits
for the expression {\tt cond} to return false.
These changes were made because they make the macros more general,
and also because the present system hardware makes it difficult
to increment an integer flag accessible by different processors.

\section{The new transform package}

The transform package has been largely overhauled, and the way in which
transforms are bound to functions or declared to be variables has been
changed radically.

Transforms are still described by the data type {\tt TRSF}, which now
contains, in itself, 
only the {\bf n}, {\bf o}, {\bf a}, and {\bf p} vectors. Any of the routines
which simply do computation with transforms can accept a pointer
to any {\tt TRSF} structure. Specific RCCL routines which bind transforms
to functions and do other such things, however, require that the transform be
allocated by the routine {\tt allocTrans()} (see below).

\subsection{Transform allocation}\label{talloc}

Transforms are allocated using the function
\cverbatim
        tr = allocTrans (name, pool) @endcverbatim
\noindent
where {\tt name} is an alphanumeric name for the transform and 
{\tt pool} is an integer specifying the memory pool
from which the memory for the transform should be
allocated. Under the present implementation, each CPU has a memory
pool, and so {\tt pool} is usually either a CPU number, or 0, which
indicates a default pool.
The various {\tt
gentr\_} primitives which allocate a transform and instantiate it 
with particular values also require a pool specification
as the second argument.
{\tt allocTrans()} simply initializes the transfrom to the identity. 

Transforms are freed with the call {\tt freeTrans(tr)}.

Since RCCL control functions may execute on different CPUs, the address
of a transform returned by {\tt allocTrans()} may not be valid at the control
level. The primitive 
\cverbatim
        tr = getTransByName (name) @endcverbatim
\noindent
can be used to obtain a valid pointer for the named transform from any part of
the RCCL program. Similarly, the routine
\cverbatim
        tr = getTransByAddr (paddr) @endcverbatim
\noindent
can also be used to obtain a valid pointer, using the planning level 
address {\tt paddr} as a key. 
To go the other way and find the name associated with a
transform, one can use the routine
\cverbatim
        getTransName (tr) @endcverbatim

Routines also exist to read and write transforms atomically:
\cverbatim
        readTrans (src, dest)
        writeTrans (dest, src) @endcverbatim

\subsection{Transform control}\label{tctrl}

The transform designations {\tt const()}, {\tt hold()}, {\tt varb()}, and
{\tt function()} do not exist any more. RCCL system transforms
now have the following designations:

\medskip
\begin{list}{}{}
\item[$\diamondsuit$]
{\it constant}. This does not mean that the transform value cannot change, but
it does mean that the trajectory generator will act as though it does not
for any given motion.
When a motion is requested which contains this transform in the
target position, the trajectory generator will make a copy of the transform
and use that, so that if the original transform value changes, the motion
will not notice\footnote
{This is actually like the {\tt hold()} transform designation in the old
system.}.
To declare a transform constant, the routine
\cverbatim
        setTransConst (tr) @endcverbatim
\item[]
should be called.

\item[$\diamondsuit$]
{\it variable}. This means that the transform is possibly being changed by
either the planning task or a monitor function, and any motion
which contains this transform in the target position should track the change.
The trajectory generator will {\bf not} use a copy of the
transform when computing the target setpoint.
To declare a transform variable, the routine
\cverbatim
        setTransVarb (tr) @endcverbatim
\item[]
should be called.

\item[$\diamondsuit$]
{\it bound to a function}. The trajectory generator is given
a modifying function which it should call with the transform as an argument. 
There are two ways in which transforms can be bound to functions.
\cverbatim
        transEval (tr, fxn, arg) @endcverbatim
\item[]
causes the specified transform to be updated constantly, using
the function {\tt fxn}, by the trajectory
generator, regardless of what motions may be happening.
One the other hand, the call
\cverbatim
        transMotionEval (tr, fxn, arg, mnp) @endcverbatim
\item[]
instructs the trajectory generator to only update the transform when
it is present in a target position for the specified manipulator {\tt mnp}
(this is like the function binding in old RCCL).
\end{list}
\medskip

When a transform is bound to function, that 
function is called by the trajectory generator with the following
argument sequence:
\cverbatim
        typedef struct {
                int arg;
                float time;
                float scale;
                MANIP *manip;
        } TRANS_ARGS;

        (*fxn)(tr, targs)
        TRSF *tr;
        TRANS_ARGS *targs;
        {
                ...
        } @endcverbatim

{\tt tr} is a pointer to the transform itself, and {\tt targs} is a list of
values that the function might find useful.
{\tt targs->arg} is the user argument {\tt arg} specified in the call
to {\tt transEval()} or {\tt transMotionEval()}. 
{\tt targs->time} is the current time, in milliseconds. If the function 
binding is tied to a motion (i.e., it was set up using {\tt transMotionEval},
then {\tt targs->scale} describes where the motion is with respect to
its target
(from 0.0 to 1.0), and {\tt targs->manip} is a pointer to
the {\tt MANIP} structure.

\section{Changes to the transform multiply routines}\label{tm}

The transform computation routines {\tt trmult()} and {\tt invert()}
have been renamed {\tt multTrsf()} and {\tt invertTrsf()} to make
their names more consistent with the other RCCL routines.
They have also been modified so that their source arguments may be the same as
the destination argument. This eliminates the need for the routines
{\tt trmultinp()} and {\tt invertinp()}.

New routines
\cverbatim
        multRiTrsf (tr, t1, t2)
        multLiTrsf (tr, t1, t2) @endcverbatim
\noindent
have been added which compute, respectively, the products 
\[
{\bf T}_r \;=\; {\bf T}_1 \; {\bf T}_2^{-1}
\]
and
\[
{\bf T}_r \;=\; {\bf T}_1^{-1} \; {\bf T}_2.
\]

The routine
\cverbatim
        identTrsf (tr) @endcverbatim
\noindent
sets a transform to the identity matrix.

\section{No joint-range data types}\label{norng}

In old RCCL, joint positions were stored at the RCCL level in ``range''
coordinates, which were equal to the conventional
joint position minus the minimum joint value. All range coordinates
hence started at 0. 
This wasn't overwhelmingly useful, caused some confusion, and
required the existence of extra routines to convert to and from range
coordinates. 

Range coordinates have been dropped. The convention is now to store all angle
values in radians and all distances in millimeters. Angle values are typically
converted to degrees when printed out, which is done by multiplying them
by the constant {\tt DEGTORAD}.

\section{Changes to the error handling and abort mechanism}\label{abort} 

The error handling and abort mechanism is taken directly from RCI.

Planning level RCCL functions generally indicate an error by returning either
-1 or {\tt NULL}. They also usually place additional error information on the
program {\it error stack} (q.v.). This is a list of error messages and
codes started at the point where a failure is first detected
and added to as lower level routines pass the error condition up to higher
level routines. It provides a convenient and fairly descriptive
traceback of what went wrong. The messages on the error stack can be printed
with the routine {\tt printErrors()}, so a typical programming paradigm 
for catching errors is
\cverbatim
        if (routine() < 0)
         { printErrors();
           exit(-1);
         }      @endcverbatim
If it is not considered necessary to exit from the program, the routine
{\tt clearErrors()} can be used to clear the error stack instead.

RCCL planning level routines do not normally force a program
exit when an error is detected.
They will do so, however, if the option {\tt RCCL\_ERROR\_EXIT} is set,
which can be done with the routine
\cverbatim
        rcclSetOptions (RCCL_ERROR_EXIT); @endcverbatim
\noindent
The option can be cleared with {\tt rcclClearOptions()}.

To issue an abort from the control level, the primitive
\cverbatim
        rciAbort (code, msgfmt, arg ...) @endcverbatim
\noindent
should be called, which causes an abort condition with the indicated code
and message. The message is formated according to the 
{\tt printf()} style {\tt msgfmt} and some variable number of 
arguments. When an abort is issued, all control tasks are released
and an abort handler is called.
The default abort handler
writes the message on the
user's terminal and forces a program exit. It is possible to recover
from abort conditions by replacing this
handler with one specified by the programmer.
To learn about this, one should
consult the {\it RCI User's Guide}. If the programmer does specify a
special abort handler, it should call the routine {\tt rcclAbortReset()}
before it returns.

A call to {\tt rciAbort()} takes the place of setting the {\tt terminate}
variable in the old system.

\section{Hand control}

The hand for a particular manipulator can be opened or closed
with the commands
\cverbatim
        OPEN_HAND (mnp)
        CLOSE_HAND (mnp) @endcverbatim
\noindent
The setting can be read back from the {\tt MANIP} structure itself.

\section{Teach program}

The teach program has been changed slightly and renamed {\tt rcclTeach()}.
Most of the visible changes involve some cleaning up of the available
commands. The teach control software is now integrated with
the RCCL trajectory generator, which means that bugs have 
disappeared like the one where the robot
would drop a bit when the teach routine returned. It is
necessary now, however, to call teach from an RCCL program.

Details on the teach program can be found in
the manual pages.

\chapter{New Features}

\section{Memory Objects}\label{obj}

RCCL programmers can make use of the RCI memory
object package to obtain shared
memory objects for communicating between the planning task and
functions executing at the control level. RCI memory objects are about as close
as we can get to ``shared variables'' without rewritting the C compiler
and the loader.

The old RCCL allowed the programmer to use global variables to communicate
between the planning task and the control level because everything was
executed on one CPU. Now, with multiple CPUs possible, global variables can
no longer be used. Instead, pieces of shared memory may be allocated
and accessed using a
set of special primitives.

A shared memory
object must be allocated by the planning task, which does this using
the call
\cverbatim
        mem = allocMem (name, size, pool) @endcverbatim
\noindent
{\tt name} is an alphanumeric name for the memory, {\tt size} is its size
in bytes, and {\tt pool} describes the memory pool from which the object
should be allocated. At the moment, memory pools are available on each CPU in
the system, so {\tt pool} should be set to either a CPU number, or 0,
which will cause a default pool to be selected. The primitive to
free a memory object is 
\cverbatim
        freeMem (mem) @endcverbatim

While the address returned by {\tt allocMem()}
can be used directly
by the planning task, it may not be valid inside a control task
since the memory layout is not necessarily uniform across CPUs.
To obtain a valid
memory object address, the primitive
\cverbatim
        mem = getMemByName (name) @endcverbatim
\noindent
should be called; this will look up the address of the memory using
its name as a key. Alternatively, the call
\cverbatim
        mem = getMemByAddr (ptr) @endcverbatim
\noindent
will locate a piece of memory planning task's address as a
key.

Memory objects can be read and written like any other memory location, 
but in case
atomic access is desired, the following primitives can be used:
\cverbatim
        readMem (mem, dest)
        writeMem (mem, src) @endcverbatim
\noindent
These routines atomically copy a memory object to (or from) a buffer
{\tt dest} (or {\tt src}) that is assumed to be the same size as the object.

\section{The vector routines}

The RCI library also provides a number of routines for adding,
subtracting, scaling, combining, printing, and scanning vectors,
where a vector is just an array of floats or doubles. A partial
list of these routines is:
\cverbatim
        addVf (vr, v1, v2, size)
        subtractVf (vr, v1, v2, size)
        scaleVf (vr, a, v1, size)
        combineVf (vr, a, v1, b, v2, size)

        printVf (fmt, v, size)
        scanVf (v, size) @endcverbatim
\noindent
These routines work with arrays of floats. 
Similar routines, whose names end in {\tt d} instead of {\tt f},
are available for doubles.

Since there are many RCCL data types which correspond to arrays of
numbers ({\tt DIFF}, {\tt VECT}, {\tt FORCE}, etc.), these routines can be
used as a generic package for manipulating them. For instance, a compact
way of converting a set of joint angles to degrees and printing them out
is the following:
\cverbatim
        JNTS jnts, temp;

        ...

        scaleVf ((float*)&temp, RADTODEG, (float*)&jnts, 6);
        printVf ("angles: %8.3f", (float*)&temp, 6); @endcverbatim
\noindent
The cast to {\tt float*} can be omitted on many machines (including
VAXen and SUNs) if one is not worried about portability

For details on these and more routines, see either the  {\it RCI User's
Guide} or the {\it RCI Reference Manual}.

\section{Quaternions}

Quaternions (type {\tt QTRN})
have been introduced as robot data types and routines 
exist for manipulating them.

Quaternions can be multiplied using the routines
\cverbatim
        multQtrn (qr, q1, q2)
        multRiQtrn (qr, q1, q2)
        multLiQtrn (qr, q1, q2) @endcverbatim
\noindent
{\tolerance=10000
which behave analogously to the transform routines {\tt trmult},
{\tt multRiQtrn()}, and {\tt multLiQtrn()}.
Quaternions can be inverted with
\cverbatim
        invertQtrn (qr, q1) @endcverbatim
\noindent
}and normalized with
\cverbatim
        unitQtrn (qr, q1) @endcverbatim
The routines
\cverbatim
        trsfToQtrn (qr, tr)
        qtrnToTrsf (tr, qr) @endcverbatim
\noindent
convert between a quaternion and the rotational part of a transformation.

\section{Object frames}

Object frames were mentioned in section \ref{pc}; they should not be confused
with the shared memory objects discussed in section \ref{obj}. 
They correspond to a ``virtual'', or imaginary, manipulator that can be
moved around with the usual motion control primitives. By having
real robots move to target positions that contain object frame T6
transforms, one or more real robots can be made to track a common object
frame. It was felt that this feature would be useful in doing work
in coordinated multi-arm control. The concept is discussed in more
detail in the paper ``Extending 
the RCCL Programming Environment to Multiple Robots and
Processors''.

Because object frames have no inertia or physical constraints, they
do not always have to be actually {\it moved} places; the can just be
put there. The primitive
\cverbatim
        maintain (mnp, pos) @endcverbatim
\noindent
puts an object frame at the indicated target position and leaves it
there, tracking the position until some other
motion request is specified for it.

\section{Moving in joint coordinates}

At long last, a motion primitive
which specifies a target position in joint coordinates has been
introduced. It is called {\tt movej()} and is called as follows:
\cverbatim
        movej (mnp, jnts) @endcverbatim
\noindent
{\tt mnp} is the pointer to the manipulator (object frames are not allowed!),
and {\tt jnts} is a pointer to a {\tt JNTS} structure specifying the desired
joint angles. The resulting motion is joint interpolated,
regardless of the default interpolation mode specified by
{\tt setmod()}.

\section{The RCCL parameter set}

RCI maintains a facility whereby named sets of parameters can be defined
in a file called {\tt .rciparams} and referenced by RCI/RCCL programs.
This provides a way for changing program behavior by altering
parameter settings in the file rather than having to recompile or
relink the program. Information about the parameter facility is found
in the {\it RCI User's Guide}, or in the manual page {\tt rciParameters}.

The built-in parameter set, named {\tt RCCL}, contains a few parameters
which can be used to control characteristics of RCCL programs.
The following parameters are defined:

\begin{desclist}
\item[\tt simulate]
Causes the RCCL program to be run in simulator mode.

\item[\tt rate]
Sets the sample interval at which the trajectory generator runs.

\item[\tt timeout]
Changes the control task timeout tolerance.

\item[\tt cpus]
Specifies the CPUs that may be used
in running an RCCL program.

\item[\tt tvel]
Sets the default manipulator translational velocity.

\item[\tt rvel]
Sets the default manipulator rotational velocity.
\end{desclist}

{\tolerance=10000
Most of the parameters are optional.
Detailed information on the {\tt RCCL} parameter set can be found
in the manual page {\tt RCCL\_params}.

}
\section{Monitor functions}

The old RCCL had a facility for assigning a monitor function to be
executed while a given motion was in progress. The routine to set this up was
called {\tt evalfn()}, and is still supported although it is now renamed 
and takes
extra arguments describing the manipulator associated with the motion and an
argument with which the function is called:
\cverbatim
        runMotionFxn (mnp, fxn, arg) @endcverbatim
\noindent
It is also possible to set up a monitor function that runs all the time,
regardless of whether or not any motions are in progress. The call to do this
is
\cverbatim
        runMonitorFxn (mnp, fxn, arg) @endcverbatim
\noindent
Although it is technically not necessary to associate a permanent monitor
function with a manipulator, it was easy to implement
this way. Each manipulator is
then associated with one motion monitor function and one
permanent monitor function. Once established, 
the permanent monitor function will run until {\tt runMonitorFxn()} is called
again with {\tt fxn} set to {\tt NULLF}.

\section{The RCI robot}

When controlling a robot, the RCCL trajectory generator attaches that robot
to itself using the RCI primitive {\tt rciAttachRobot()}. This routine
sets up a data structure called the robot descriptor (type {\tt RCI\_RBT}).
which contains pointers to structures
which describe the robot's joint level and kinematic parameters,
and a blackboard called {\tt HOW} which describes the run-time
state of the robot and its attached I/O devices and sensors. The robot
descriptor is also used in conjunction with a set of robot
control macros for operating the arm and sending data to its 
I/O output devices. Detailed information on the robot descriptor can be
obtained from the manual page {\tt RCI\_RBT}, or the
{\it RCI User's Guide}.

It is useful to have access to the descriptor for a robot being
controlled by RCCL, either to obtain data or parameters from it,
or to send commands to the robot that do not conflict with commands
normally used by the trajectory generator. The robot descriptor for
an RCCL program can be obtained from the {\tt MANIP} structure with the
macro
\cverbatim
        MANIP_ROBOT(mnp) @endcverbatim


\chapter{Table of Changes}

The following table lists all of the RCCL routines and variables
found in the old
version and describes their status with respect to Multi-RCCL. There
are four designations:

\medskip
\begin{list}{}{}
\item[$\diamondsuit$]
{\it Unchanged}. The routine/variable is still supported and no changes have
been made to it.

\item[$\diamondsuit$]
{\it Renamed}. The routine/variable has been renamed but is
otherwise unchanged. The new name is given in the ``notes'' column.

\item[$\diamondsuit$]
{\it Modified}. The functionality of the routine/variable has been
changed slightly.

\item[$\diamondsuit$]
{\it Replaced}. The functionality of the routine/variable has been replaced by
a new routine or group of routines. 

\item[$\diamondsuit$]
{\it Deleted}. The routine/variable is no longer supported. This has
mainly been the case for the ``debugging'' variables that were present
in the old system.
\end{list}
\medskip

The ``notes'' 
column gives a quick description of any changes, 
including the new name for the routine/variable, if appropriate,
and may also indicate the number of a section which explains the
changes in more detail.

\newpage
{\catcode`\_=12
\halign{%
\hskip\parindent\hbox to 2truein{#\hfil}&\hbox to 1 truein{#\hfil}&\hbox to
3truein{#\hfil}\cr
Function name&Status&Notes\cr
\noalign{\medskip\hrule\medskip}
\tt angle_to_jnts       &deleted  &not needed, no range type (\ref{norng})\cr
\tt assigndiff          &renamed  &{\tt copyDiff()}\cr
\tt assignforce         &renamed  &{\tt copyForce()}\cr
\tt assigntr            &renamed  &{\tt copyTrsf()}\cr
\tt assignvec           &renamed  &{\tt copyVect()}\cr
\tt completed           &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt comply              &modified &{\tt mnp} argument added (\ref{mnp})\cr
\tt const               &deleted  &transform package changed (\ref{tctrl})\cr
\tt cross               &renamed  &{\tt crossVect()}\cr
\tt degree_to_radian_j  &replaced &use {\tt scaleVf()} and {\tt DEGTORAD}\cr
\tt df_to_tr            &renamed  &{\tt diffToTrsf()}\cr
\tt dgtord_m            &replaced &use {\tt DEGTORAD}\cr
\tt difftr              &renamed  &{\tt transDiff()}\cr
\tt distance            &modified &{\tt mnp} argument added (\ref{mnp})\cr
\tt dot                 &renamed  &{\tt dotVect()}\cr
\tt eul                 &unchanged&\cr
\tt eulm                &unchanged&\cr
\tt evalfn              &replaced &use {\tt runMotionFxn()} (\ref{mnp})\cr
\tt force_ctl           &deleted  &old control flag\cr
\tt forcetr             &renamed  &{\tt transForce()}\cr
\tt fpi                 &deleted  &old debug variable\cr
\tt freepos             &replaced &use {\tt freePosition()}\cr
\tt freeposition        &unchanged&\cr
\tt freetrans           &replaced &changed to {\tt freeTrans()}\cr
\tt gensym              &deleted  &not needed\cr
\tt gentr_eul           &modified &added pool argument (\ref{talloc})\cr
\tt gentr_pao           &modified &added pool argument (\ref{talloc})\cr
\tt gentr_rot           &modified &added pool argument (\ref{talloc})\cr
\tt gentr_rpy           &modified &added pool argument (\ref{talloc})\cr
\tt gentr_trsl          &modified &added pool argument (\ref{talloc})\cr
\tt goalpos             &deleted  &not needed\cr
\tt hdpos &replaced &moved to {\tt MANIP} as {\tt handPos} (\ref{mnp})\cr
\tt here                &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt hold                &deleted  &transform package changed (\ref{tctrl})\cr
\tt invert              &replaced &use {\tt invertTrsf()} (\ref{tm})\cr
\tt invertinp   &deleted  &not needed; use {\tt invertTrsf()}(\ref{tm})\cr
\tt j6                  &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt jd  &replaced &moved to {\tt MANIP} structure as {\tt jvel} (\ref{mnp})\cr
\tt jnts_to_angle       &deleted  &not needed, no range type (\ref{norng})\cr
\tt lastpos             &deleted  &not needed\cr
\tt limit               &modified &{\tt mnp} argument added (\ref{mnp})\cr
\tt lock                &modified &{\tt mnp} argument added (\ref{mnp})\cr
\tt makeposition        &modified &argument syntax changed (\ref{mpos})\cr
\tt move                &modified &{\tt mnp} argument added (\ref{move})\cr
\tt movecart            &modified &{\tt mnp} argument added (\ref{move})\cr
\tt moveconf            &modified &{\tt mnp} argument added (\ref{move})\cr
\tt movejnts            &modified &{\tt mnp} argument added (\ref{move})\cr
\tt newtrans            &replaced &use {\tt allocTrans()} (\ref{talloc})\cr
\tt nextmove            &replaced &use {\tt stopCurrentMotion()}\cr
\tt noatoeul            &unchanged&\cr
\tt noatorpy            &unchanged&\cr
\tt optimize            &deleted  &not needed\cr
\tt park                &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt pi_m                &replaced &use {\tt PI}\cr
\tt pib2_m              &replaced &use {\tt PIB2}\cr
\tt pit2_m              &replaced &use {\tt PIT2}\cr
\tt print_RCIerror      &replaced &use RCI error mechanism (\ref{abort})\cr
\tt print_diff          &replaced &use {\tt printVf()}\cr
\tt print_force         &replaced &use {\tt printVf()}\cr
\tt print_jnts          &replaced &use {\tt printVf()}\cr
\tt print_terminate_code&replaced &use RCI error mechanism (\ref{abort})\cr
\tt print_torques       &replaced &use {\tt printVf()}\cr
\tt printe              &unchanged&but try {\tt printTrsf()} instead\cr
\tt printr              &unchanged&but try {\tt printTrsf()} instead\cr
\tt printrn             &unchanged&but try {\tt printTrsf()} instead\cr
\tt prints_out          &deleted  &not needed; old debug flag\cr
\tt printy              &unchanged&but try {\tt printTrsf()} instead\cr
\tt radian_to_degree_j  &replaced &use {\tt scaleVf()} and {\tt RADTODEG}\cr
\tt radian_to_range_j   &deleted  &not needed; no range type (\ref{norng})\cr
\tt range_to_radian_j   &deleted  &not needed; no range type (\ref{norng})\cr
\tt rccl_abort          &replaced &use {\tt rciAbort()} (\ref{abort})\cr
\tt rccl_close          &replaced &use {\tt rcclDelete()} (\ref{pc})\cr
\tt rccl_control        &replaced &use {\tt rcclStart()} (\ref{pc})\cr
\tt rccl_open           &replaced &use {\tt rcclCreate()} (\ref{pc})\cr
\tt rccl_precise        &replaced &use {\tt rcclSetMode(mnp,INTEGRATE_MODE)}\cr
\tt rccl_release        &replaced &use {\tt rcclRelease()} (\ref{pc})\cr
\tt RCIerror            &replaced &use RCI error mechanism (\ref{abort})\cr
\tt RCImessage          &replaced &use RCI error mechanism (\ref{abort})\cr
\tt rdtodg_m            &replaced &use {\tt RADTODEG}\cr
\tt read_diff           &replaced &use {\tt scanVf()}\cr
\tt read_force          &replaced &use {\tt scanVf()}\cr
\tt read_joints         &replaced &use {\tt scanVf()}\cr
\tt requestnb           &deleted  &not needed\cr
\tt rest                &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt rot                 &unchanged&\cr
\tt rotm                &unchanged&\cr
\tt rpy                 &unchanged&\cr
\tt rpym                &unchanged&\cr
\tt rtime               &replaced &use {\tt rciTime()}\cr
\tt sample              &replaced &use {\tt rcclSetInterval()}\cr
\tt setconf             &renamed  &{\tt setConf()}, {\tt mnp} arg added (\ref{mnp})\cr
\tt setime              &modified &{\tt setTime()}, {\tt mnp} arg added (\ref{mnp})\cr
\tt setmod              &modified &{\tt setMod()}, {\tt mnp} arg added (\ref{mnp})\cr
\tt setvel              &modified &{\tt setCvel()}, {\tt mnp} arg added (\ref{mnp})\cr
\tt stop                &modified &{\tt mnp} argument added (\ref{move})\cr
\tt t6                  &replaced &moved to {\tt MANIP} structure (\ref{mnp})\cr
\tt takerot             &unchanged&\cr
\tt taketrsl            &unchanged&\cr
\tt teach_pos           &replaced &use {\tt rcclTeach()}\cr
\tt terminate           &replaced &use {\tt rciAbort()} (\ref{abort})\cr
\tt there       &replaced &moved to {\tt MANIP} structure as {\tt last} (\ref{mnp})\cr
\tt timeincrement       &replaced &use {\tt rcclGetInterval()}\cr
\tt tr_to_df            &renamed  &{\tt trsfToDiff()}\cr
\tt trmult      &replaced &use {\tt multTrsf()} (\ref{tm})\cr
\tt trmultinp   &deleted  &not needed; use {\tt trmult()} (\ref{tm})\cr
\tt trmultinv   &replaced &use {\tt multRiTrsf()} (\ref{tm})\cr
\tt trsl                &unchanged&\cr
\tt trslm               &unchanged&\cr
\tt unit                &renamed  &{\tt unitVect()}\cr
\tt unitr               &replaced &use {\tt trident()}\cr
\tt update              &replaced &use {\tt updateTrans()}\cr
\tt vao                 &unchanged&\cr
\tt vaom                &unchanged&\cr
\tt varb                &deleted  &transform package changed (\ref{tctrl})\cr
\tt wait_until          &deleted  &use {\tt waitfor()}\cr
\tt wait_while          &renamed  &use {\tt waitwhile()}\cr
\tt waitas              &deleted  &use {\tt waitwhile()}\cr
\tt waitfor             &modified &doesn't increment argument (\ref{wait})\cr
\tt xunit               &unchanged&\cr
\tt yunit               &unchanged&\cr
\tt zunit               &unchanged&\cr
}
}
\hfil

\end{document}
