\input manualMacros.tex
\manBegin
\manPageInfo{RCI Reference Manual}{}{}
\manTitle{getJls}{3}
\manSection{NAME}
{\tt \manName{getJls}},
{\tt \manName{getKyn}},
{\tt \manName{getVarSize}}
-- access to RCI data structures containing robot constants.
\manSection{USAGE}
\cverbatim
#include <rci.h>

JLS *getJls(name)
   const char *name;

KYN *getKyn(name, size)
   const char *name;
   int *size;

int getVarSize(name)
   const char *name; @endcverbatim
\manSection{ARGUMENTS}
\manItem{{\tt name} --}
Name of the robot.
\manItem{{\tt size} --}
Place to return the size of the {\tt ext} component of the {\tt KYN} 
structure.
\manSection{RESTRICTIONS}
{\tt getJls()} and {\tt getKyn()}, and the pointers they return,
can only be accessed from the planning level.
\manSection{DESCRIPTION}
These functions are used to obtain, or help allocate, the robot-specific 
data structures {\tt JLS}, {\tt KYN}, and {\tt VAR}.
More specific information on the data structures themselves can be found
in the manual pages {\tt JLS(3)}, {\tt KYN(3)}, and {\tt VAR(3)}.

\manInset{{\bf NOTE}:
For each robot attached to an RCI robot control task, versions
of these data structures are
allocated automatically and referenced through pointers in the 
robot structure {\tt RCI_RBT} (q.v.).}

The routines {\tt getJls()} and {\tt getKyn()} provide structures
that can only be used by the RCI planning
level. If the structures are needed at the control level,
the routines {\tt rciGetJls()} and {\tt rciGetKyn()} (q.v.) should be
used instead.

{\tt getJls()} returns the {\tt JLS} structure (q.v.) for a robot.
This structure defines the conversions between actuator and joint coordinates,
various parameters relating to calibration, and joint limit values.
The first time {\tt getJls()} is called, an internal {\tt JLS} structure
is created, and subsequent calls simply return a pointer to the
same structure.

{\tt getKyn()} returns the {\it kinematic/dynamic}, or 
{\tt KYN}, structure (q.v.)
associated with a
robot, which contains kinematic constants and dynamic parameters.
The {\tt KYN} structure also contains pointers to a generic set of routines
for doing various kinematic and dynamic computations.
The {\tt KYN} structure contains two fields, {\tt gen} and {\tt ext}.
The {\tt gen} field points to a structure 
of type {\tt GEN_KYN}, which contains parameters generic
to most robots. The {\tt ext} field points to a structure whose
type depends on the class
of the robot. Each type for each class
is called {\tt <CLASS>_KYN} and is defined in the file 
{\filefont h/<class>_kynvar.h}. For instance, for PUMA robots, it
is called {\tt PUMA_KYN} and is defined in {\filefont h/puma_kynvar.h}
If the argument {\tt size} supplied to {\tt genKyn()} 
is not {\tt NULL}, it is used to
return the size of this class-specific data type.

{\tt getVarSize()} returns size of the {\it variable}, or {\tt VAR},
structure associated with each robot. This structure contains fields for
storing run-time information (like 
the sines and cosines of the joints angles) that we might want to store to
avoid having to recompute them later in the same control cycle.
Like the {\tt ext} component of the {\tt KYN} structure, the
actual definition of the {\tt VAR} structure depends on the class of the
robot. The class-specific type is called {\tt <CLASS>_VAR} and is defined in
the file  {\filefont h/<class>_kynvar.h}. For instance, for PUMA robots, the {\tt
VAR} structure is called {\tt PUMA_VAR} and is defined in {\filefont
h/puma_kynvar.h} 
The size returned by {\tt getVarSize()} can be used for allocating
a block of memory to contain the {\tt VAR} structure.

To obtain pointers to the robot specific structures, it is necessary
to use casts. 
For instance, suppose we are working with a PUMA robot named
``Zeus''. Then the following code fragment might be used to access
the PUMA specific data structures:
\cverbatim
        #include <rci.h>
        #include <puma_kynvar.h>

        JLS *jls;
        KYN *kyn;
        PUMA_KYN *pkyn;
        PUMA_VAR *pvar;

        jls = getJls("Zeus");
        kyn = getKyn("Zeus", (int*)NULL);
        pkyn = (PUMA_KYN *)kyn->ext;
        pvar = (PUMA_VAR *)malloc (getVarSize ("Zeus")); @endcverbatim

\manSection{DIAGNOSTICS}
{\tt getJls()} and {\tt getKyn()} return {\tt NULL} if they are unable to
allocate or find structures for the specified robot. {\tt getVarSize()} 
returns {\tt -1} if it is unable to locate the specified robot.
Error information is reported on the
{\it errorStack} (q.v.). Returned error codes are accessible with 
{\tt getErrorCode()}:

\manItem{{\tt ENotDefined} --}
The named robot is not defined in the system tables.
\manItem{{\tt EBadFxn} --}
There is no internal access function defined with which to get the data
structure.
\manItem{{\tt EBadAccess} --}
Can't open the required information file in {\filefont \$RCCL/conf}.
\manItem{{\tt EBadObj} --}
The required information file in {\filefont \$RCCL/conf} is corrupted or
malformed.
\manItem{{\tt EMemory} --}
System is out of memory.

These routines will abort the program if called from the control level.
\manSection{IMPLEMENTATION}

This section describes how to install new {\it get} functions for
a different class of robot.

We first describe a little bit about how the functions work.
{\tt getJls()} and {\tt getKyn()} each call robot specific functions
defined in the array {\tt rciRobotDataTable} (located in the file
{\filefont robots/robotDataTab.c}). 
Different functions are used for each class of robot (``PUMA'' is an example
of a robot class), and they have the canonical names
{\tt <class>_jls} and {\tt <class>_kyn}, where {\tt <class>} denotes
the robot class name.
Each robot in the system has a file for
its {\tt JLS} structure and another file for its {\tt KYN} structure.
These files are kept in the directory {\filefont \$RCCL/conf}.
At the present time, 
the {\tt JLS} information is stored in a binary file named 
{\tt <robotName>.JLS}, and the kinematic information is stored in an ascii
file named {\tt <robotName>.kyn} (the
lower case on {\tt .kyn} denoting the fact the file contains text).
The binary {\tt .JLS} files is created from an acsii {\tt .jls} file
by the program {\tt makejls} (q.v.); {\tt getJls()} normally checks
the dates on both files and calls {\tt makejls} when the {\tt .JLS} file
is older.

\manInset{{\bf NOTE}: The use of a binary {\tt .JLS} file is
probably on the way out. On the VxWorks implementation, the binary
file is not used, and the ascii {\tt .jls} file is read directly by
each RCCL/RCI program.}

The function {\tt <class>_jls()} is called by {\tt getJls()}
with a pointer to the newly allocated {\tt JLS} structure, as in
\cverbatim
        <class>_jls (jls)
           JLS *jls; @endcverbatim
\noindent
Its job is to instantiate the function pointers contained in the
{\tt JLS} structure with the routines appropriate for the class.

The function {\tt <class>_kyn()} is called by {\tt getKyn()}
with a pointer to the newly allocated {\tt KYN} structure, and a
file pointer referencing the ascii file {\tt <robotName>.kyn}:
\cverbatim
        <class>_kyn (kyn, fp)
           KYN *kyn; 
           FILE *fp; @endcverbatim
\noindent
Its job is to read the necessary information from
the file to instantiate both the
{\tt gen} and {\tt ext} components of 
the {\tt KYN} structure. The function must also
set the routine pointers located in the {\tt gen} component
to the appropriate implementation routines for the robot's class.
If an error is encountered while reading the file, {\tt <class>_kyn} should
call {\tt errorMsg()} (q.v.) with the code {\tt EBadFile} and a descriptive 
message, and then return {\tt -1}. Otherwise, the it should
return {\tt 1}.

Adding a new robot class involves the following basic steps:

\manItem{{\it Create a new directory for the class} --}
The source modules for functions specific to a robot class
are generally placed in a directory that has the same name
as that class. For instance, code specific to the PUMA robot
is defined in the directory {\tt puma}. The new directory
should contain an {\tt Imakefile} cloned from the directory
for an existing robot class. 

\manItem{{\it Define the class in {\filefont h/robotClass.h}} --}
This involves assigning a {\tt \#define} name for the class.

\manItem{{\it Define new {\tt <CLASS>_KYN} and {\tt <CLASS>_VAR} structures}
--} 
This involves creating and editing the file {\filefont h/<class>_kynvar.h}.
It may be useful to clone an existing file, such as 
{\filefont h/puma_kynvar.h}.

\manItem{{\it Write the kinematic and dynamic functions} --}
Routines must be supplied for (1) the {\tt encoderToAngle()}, etc.,
functions of the {\tt JLS} structure; see {\tt JLS(3)} for a description
of these, and (2) the kinematic and dynamic functions defined in the
{\tt GEN_KYN} component of the {\tt KYN} structure; see {\tt KYN(3)} and
individual manual pages 
for a description of these. 
The functions need to be placed in the library {\filefont lib/rciCtrl.a}.
It may be useful to clone
existing functions for a similar type of robot.
The relevant functions for the PUMA are located
in the files {\tt pumaKinematic.c}, {\tt pumaJacob.c},
{\tt pumaConfig.c}, and {\tt pumaGravload.c} (in the directory {\tt puma}).

\manItem{{\it Write the {\tt <class>_jls} and {\tt <class>_kyn} functions} --}
These functions must conform to the interfaces
described above, and need
need to be placed in the library {\filefont lib/rciUser.a}.
Again, it is probably easiest to clone such functions
from existing ones; the functions for the PUMA are defined in the files
{\tt puma_jls.c} and {\tt puma_kynvar.c}.

\manItem{{\it Update {\tt rciRobotDataTable}} --}
This involves editing the file {\filefont robots/robotDataTab.c}.
First, the file {\filefont h/<class>_kynvar.h} will have to be included
near the top. Second, new entries will need to be created in
{\tt rciRobotDataTable}. Each entry consists of (1) the name of
a robot, (2) its class as defined in {\filefont h/robotClass.h}, 
(3) the function {\tt <class>_jls}, (4) the function {\tt <class>_kyn},
(5) the size of the {\tt <CLASS>_KYN} structure, and (6) the size of
the {\tt <CLASS>_VAR} structure, and (7) the entry points
for the robot communication functions (see {\tt robotComfxns(7)}). 
After editing, the file can be
compilied and reinstalled by running {\tt make libs} in the
directory {\tt robots}.

\manSection{SEE ALSO}
\rightskip=0ptplus1fil
{\tt JLS(3)}, {\tt KYN(3)}, {\tt VAR(3)}, {\tt rciGetJls()}, 
{\tt makejls(1)}, {\tt RCI_RBT(3)},
{\tt errorMsg(3)}. 

\manEnd
\end
