getJls(3)

NAME
getJls, getKyn, getVarSize -- access to RCI data structures containing robot constants.

USAGE
#include <rci.h>

JLS *getJls(name)
   const char *name;

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

int getVarSize(name)
   const char *name;

ARGUMENTS

name --
    Name of the robot.

size --
    Place to return the size of the ext component of the KYN structure.

RESTRICTIONS
getJls() and getKyn(), and the pointers they return, can only be accessed from the planning level.

DESCRIPTION
These functions are used to obtain, or help allocate, the robot-specific data structures JLS, KYN, and VAR. More specific information on the data structures themselves can be found in the manual pages JLS(3), KYN(3), and VAR(3).

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 RCI_RBT (q.v.).

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

getJls() returns the 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 getJls() is called, an internal JLS structure is created, and subsequent calls simply return a pointer to the same structure.

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

getVarSize() returns size of the variable, or 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 ext component of the KYN structure, the actual definition of the VAR structure depends on the class of the robot. The class-specific type is called <CLASS>_VAR and is defined in the file h/<class>_kynvar.h. For instance, for PUMA robots, the VAR structure is called PUMA_VAR and is defined in h/puma_kynvar.h The size returned by getVarSize() can be used for allocating a block of memory to contain the 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:
        #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"));

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

ENotDefined --
    The named robot is not defined in the system tables.

EBadFxn --
    There is no internal access function defined with which to get the data structure.

EBadAccess --
    Can't open the required information file in $RCCL/conf.

EBadObj --
    The required information file in $RCCL/conf is corrupted or malformed.

EMemory --
    System is out of memory.

These routines will abort the program if called from the control level.

IMPLEMENTATION

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

We first describe a little bit about how the functions work. getJls() and getKyn() each call robot specific functions defined in the array rciRobotDataTable (located in the file 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 <class>_jls and <class>_kyn, where <class> denotes the robot class name. Each robot in the system has a file for its JLS structure and another file for its KYN structure. These files are kept in the directory $RCCL/conf. At the present time, the JLS information is stored in a binary file named <robotName>.JLS, and the kinematic information is stored in an ascii file named <robotName>.kyn (the lower case on .kyn denoting the fact the file contains text). The binary .JLS files is created from an acsii .jls file by the program makejls (q.v.); getJls() normally checks the dates on both files and calls makejls when the .JLS file is older.

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

The function <class>_jls() is called by getJls() with a pointer to the newly allocated JLS structure, as in
        <class>_jls (jls)
           JLS *jls;

Its job is to instantiate the function pointers contained in the JLS structure with the routines appropriate for the class.

The function <class>_kyn() is called by getKyn() with a pointer to the newly allocated KYN structure, and a file pointer referencing the ascii file <robotName>.kyn:
        <class>_kyn (kyn, fp)
           KYN *kyn;
           FILE *fp;

Its job is to read the necessary information from the file to instantiate both the gen and ext components of the KYN structure. The function must also set the routine pointers located in the gen component to the appropriate implementation routines for the robot's class. If an error is encountered while reading the file, <class>_kyn should call errorMsg() (q.v.) with the code EBadFile and a descriptive message, and then return -1. Otherwise, the it should return 1.

Adding a new robot class involves the following basic steps:

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 puma. The new directory should contain an Imakefile cloned from the directory for an existing robot class.

Define the class in h/robotClass.h --
    This involves assigning a #define name for the class.

Define new <CLASS>_KYN and <CLASS>_VAR structures --

    This involves creating and editing the file h/<class>_kynvar.h. It may be useful to clone an existing file, such as h/puma_kynvar.h.

Write the kinematic and dynamic functions --
    Routines must be supplied for (1) the encoderToAngle(), etc., functions of the JLS structure; see JLS(3) for a description of these, and (2) the kinematic and dynamic functions defined in the GEN_KYN component of the KYN structure; see KYN(3) and individual manual pages for a description of these. The functions need to be placed in the library 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 pumaKinematic.c, pumaJacob.c, pumaConfig.c, and pumaGravload.c (in the directory puma).

Write the <class>_jls and <class>_kyn functions --
    These functions must conform to the interfaces described above, and need need to be placed in the library 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 puma_jls.c and puma_kynvar.c.

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

SEE ALSO
JLS(3), KYN(3), VAR(3), rciGetJls(), makejls(1), RCI_RBT(3), errorMsg(3).