\input manualMacros.tex
\manBegin
\manPageInfo{RCI Reference Manual}{}{}
\manTitle{robotComfxns}{7}
\manSection{NAME}
{\tt \manName{robotComfxns}}
-- RCI robot communication function interface.
\manSection{INTERFACE}
\cverbatim
(rbt->startup)(td, rbt)
   RCI_DESC *td;
   RCI_RBT *rbt;

(rbt->input)(td, rbt)
   RCI_DESC *td;
   RCI_RBT *rbt;

(rbt->output)(td, rbt)
   RCI_DESC *td;
   RCI_RBT *rbt;

(rbt->release)(td, rbt, code)
   RCI_DESC *td;
   RCI_RBT *rbt;
   int code; 

(rbt->ready)(rbt->readyArg)
   RCI_RBT *rbt;

(rbt->wakeup)(rbt->wakeupArg)
   RCI_RBT *rbt; @endcverbatim
\manSection{ARGUMENTS}
\manItem{{\tt td} --}
Pointer to RCI task descriptor.
\manItem{{\tt rbt} --}
Pointer to the robot descriptor.
\manItem{{\tt code} --}
Code describing the conditions associated with the release.
\manSection{DESCRIPTION}
The robot interface functions constitute a package that interfaces an
RCI control task to a particular robot. 
In general, each type of robot will require a
different set of functions. Pointers to the interface functions
are contained in the {\tt RCI_RBT} structure, which is set up whenever
a robot is attached to a task (see {\tt rciAttachRobot(3)}).

The general characteristic and ``duties'' of the
interface functions are described here.

The principle purpose of the interface functions is to maintain
the {\tt HOW} structure and process the {\tt CHG} macros for the
robot in question. 
They should be called from an appropriate
place within the task control functions (see {\tt rciControlFxns(7)}).
They can make use of the information in the
{\tt RCI_RBT} structure
and the robot
constants defined in the {\tt JLS} structure (q.v.).
To communicate with the robot, they usually use a physical device
interfaced to by an RCI device driver (see {\tt IOdevice(7)}).
An RCI device driver is allocated to each robot by the
{\tt rciAttachRobot()} routine, and a pointer
to it can be obtained from the {\tt RCI_RBT} structure with the
macro {\tt ROBOT_DEV(rbt)}.
Functions can pass information to each other by writing in
the {\tt notice} field of the robot descriptor.

The robot {\it startup} function should be called from 
within the control task's {\it startup} function. 
It should connect to the robot controller (the RCI driver {\tt attach} routine
is designed for this) and then read back whatever information is
required from the robot to
initialize the {\tt HOW} structure. This will typically
include the {\tt robotID} and {\tt controllerID} fields (which are
used to check that we are talking to the ``right'' robot), and the
{\tt options}, {\tt numAdc}, {\tt numDac}, {\tt numPioIn}, {\tt numPioOut},
and {\tt numSlu} fields, which define what devices and I/O features are
available on the robot (see {\tt HOW(3)}). The robot {\it startup} function should
also send to the robot necessary information such as the sample
rate that the control is to be run at (the function can obtain this
information be reading the {\tt RCI_TCB} structure (q.v.)). If the sample
rate changes during the control session, of course, the robot should
presumably be advised; the {\tt RCI_TCB} field {\tt newRate} can be used
to determine when this happens. The RCI driver functions {\tt read} and
{\tt write} are intended for doing data transfers with the robot
interface device.
Lastly, the {\it startup} function is responsible for instantiating the
function pointers {\tt rbt->ready} and {\tt rbt->wakeup}, along with their
call arguments {\tt rbt->readyArg} and {\tt rbt->wakeupArg}. This is done by
the {\it startup} function to provide greater flexibility: for instance,
it may be desired to make direct use of the RCI driver function {\tt testRead}
as the {\tt wakeup} function.

The {\it input} function is normally called once during every
control cycle, from the control task's {\it control} function.
It is responsible for reading back from the robot all
the data being updated in the {\tt HOW} structure. It is also responsible
for doing limit checking (see {\tt SET_CHECKING(3)}).
Many of the fields in {\tt HOW} are not read directly back from the
robot but computed based on other information read in from the robot.
For instance, the function {\tt puma_input()} reads in encoder values
from the PUMA robot and places them directly into the {\tt enc} field.
It then computes the {\tt ang} field by using the 
{\tt encoderToAngle()} conversion function contained in the {\tt JLS}
structure. The velocities are also computed by differencing
old and new position values.

The {\it output} function is also normally called once
every control cycle from the {\it control} function.
It is responsible for scanning commands which have been entered into
the {\tt CHG} structure (q.v.) with the various {\tt CHG} macros, checking
that they meet the required range and limit requirements, and shipping the
commands off to the robot. The {\tt CHG} macros work by storing the
information required for the command in the appropriate field of the {\TT CHG}
structure, and then, lastly, setting the subfield {\tt .com} to indicate 
to the {\it output} function that
a command has been entered. The setting of the {\tt .com} field is atomic, so
that commands can be called from tasks outside of the task to which the
structure belongs. The {\it output()} function must poll the required
{\tt .com} fields, process those commands that have been set, and then clear
the field.

The {\it release} function is called whenever the task is released, for
whatever reason; it is normally called from the task's
{\tt release} function.
The release function
will usually just interrupt the robot and let it know that
the control session is over, 
and (if the {\tt powerOnRelease} field of the {\tt HOW}
structure is clear) tell it to turn the power off. 
It expects a release code to be passed to it as a third argument.
The different values of these release codes are:

\manItem{{\tt RBT_NORMAL} --}
The task is releasing normally (as would be indicated by the
task's release function receiving a {\tt RELEASE_REQ} code).

\manItem{{\tt RBT_SOFTERROR} --}
An error has occured but the robot can be released with the power turned
on, if such a request is indicated by {\tt how->powerOnRelease}.

\manItem{{\tt RBT_HARDERROR} --}
An error has occured and the robot power should be shut off.

The {\it ready} function, and its argument {\tt readyArg},
is instantiated by the {\it startup} function.
It is a polling function that returns 1 if the robot is ready to handle an
{\it input} function, and 0 if it is not. 

The {\it wakeup} function, and its argument {\tt wakeupArg},
is instantiated by the {\it startup} function.
Its purpose is to send a wakeup signal to the robot controller telling it to
beging gathering data for another control cycle. This function is only used
when the RCI system is regulating the control cycle timing (which is the
case when the control task is running
{\tt ON_CLOCK} or {\tt ON_TRIGGER}).

\manSection{INSTALLATION}

As with device drivers, the easiest way to write a set of robot interface
functions is to clone an existing set. The functions for the PUMA
are defined in the file {\filefont puma/puma_comfxns.c}. 

It is recommended that all functions relating to a particular type of
robot be kept in a directory specific to that robot. 
Typically, the communication functions reside in the 
directory for their associated robot. The {\tt make} command
{\tt "make libs"} causes the communication function module(s)
to be compiled and loaded into the library {\filefont lib/rciCtrl.a}.

The robot interface functions also have to be declared in the table
{\tt rciRobotDataTable}, in the file {\filefont robots/robotDataTab.c}. 
The table consists of a set of entries for each robot configured
into the system. Each entry contains (1) the name of the robot,
(2) its class, (3) functions to help instantiate the robot's
{\tt JLS} and {\tt KYN} structures, (4) the sizes of the robot
class-specific components of the {\tt KYN} and {\tt VAR} structures,
and (5) pointers to the startup, input, output, and release functions.
{\tt NULLF} function pointers are permitted; they
simply state that there is no function to call.

\manSection{DIAGNOSTICS}
The robot interface functions return a negative value if they detect
an error; in this case, they should also issue an RCI abort prior
to returning.

Abort codes which are specifically intended for RCI aborts
issued by the robot interface functions include:

\manItem{{\tt ERobotError} --}
The robot itself reported an error condition.
\manItem{{\tt ELimit} --}
A indicator that some sort of general limit condition was met.
\manItem{{\tt EBadCmd} --}
Bad command or illegal command values set via the {\tt CHG} macros.
\manItem{{\tt EMaxPos} --}
Position bounds exceeded on a robot joint.
\manItem{{\tt EMaxVel} --}
Velocity limits exceeded on a robot joint.
\manItem{{\tt EMaxTor} --}
Torque limits exceeded on a robot joint.
\manItem{{\tt EReqPos} --}
Robot command would move the robot out of bounds.
\manItem{{\tt EReqVel} --}
Robot command would cause maximum velocity limits to be exceeded.
\manItem{{\tt EReqTor} --}
Robot command would cause maximum torque limits to be exceeded.
\manItem{{\tt ETooMany} --}
Too many commands were issued to the {\tt CHG} interface at once;
command buffer overflow.
\manItem{{\tt EEStop} --}
Emergency halt switch set for robot (this error code is not implemented for
the PUMA).

\manSection{SEE ALSO}
\rightskip=0ptplus1fil
{\tt HOW(3)}, {\tt CHG(3)}, {\tt JLS(3)}, {\tt RCI_TCB(3)}, {\tt
IOdevice(7)}, {\tt rciControlFxns(3)}, {\tt rciAbort(3)},
{\tt rciAttachRobot(3)},
{\tt SET_CHECKING(3)}.
\manEnd
\end
