controlFxns(7)

NAME
controlFxns -- description of the RCI task control functions.

USAGE
This man page describes how RCI control task functions (as set up by rciControlFxns()) are called by the task monitor. The functions associated with an RCI control task are called by the monitor with the following arguments:
startup(td, arg)
   RCI_DESC *td;
   int arg;

control(td, arg)
   RCI_DESC *td;
   int arg;

release(td, arg, code)
   RCI_DESC *td;
   int arg, code;

ARGUMENTS

td --
    Pointer to task descriptor of the current RCI task.

arg --
    User specified argument.

code --
    Code indicating the nature of the release condition.

DESCRIPTION
This man page gives a detailed description of the way in which the RCI task control functions interface to the rest of the system.

The control functions are called during an RCI control session. The sequence in which they are called during the control session is described in the following piece of pseudo code:

        controlSession:

                startup(td, arg);

                while (task not released)
                 { if (task ready)
                    { control(td, arg);
                    }
                 }
        release:
                release(td, arg, code);

Superimposed on the above code is the following error behaviour: if the monitor detects an error, such as a timeout or an abort by another task, then it does a "goto release" as soon as no control functions are running. The release function determines the nature of the release condition (i.e., a normal release request or some sort of error) by examining its second argument code (described below).

Each control function is called with the task descriptor td and a user specified function value as arguments. Much of the information used by that function is obtained by making appropriate references to that task descriptor. This includes the parameters and scratch variables in the task control block (RCI_TCB, q.v.), and the structure describing the I/O device (see IOdevice(3)). In addition, if robots are attached to the task, robot descriptors can be be obtained with the macro TASKROBOT(td, num), where "num" is the index of the attached robot within the task (returned from the call rciAttachRobot()). Given the task descriptor td, the following constructions may be used to obtain the various structures:

   RCI_TCB *tcb;        /* task control block */
   IO_DEVICE *dev;      /* IO device */
   RCI_RBT *rbt;        /* a robot structure */
   HOW *how;            /* a HOW structure */
   JLS *jls;            /* a joint level structure */
   KYN *kyn;            /* a robot dependent kyn structure */
   void *var;           /* a robot dependent var structure */

   /* for any task ... */

   tcb = TASKTCB(td);
   dev = TASKDEV(td);

   /* and for one with an attached robot ... */

   rbt = TASKROBOT(td, num);
   how = rbt->how;
   jls = rbt->jls;
   kyn = rbt->kyn;
   var = rbt->var;

The startup function is used to initialize attached devices, set up data structures, and obtain pointers to shared memory (created by the planning task) using the getSharedMemory() or getGlobalMemory() calls. Pointers to shared regions, once obtained, can be stored for quick access in the sharedMem and globalMem fields of the task control block. Private memory, allocated out of memory local to the control task, can be stored in the privateMem field. These fields are cleared at the end of the control session.

The control function is the "bread and butter" control function. It is called once per control cycle, and does I/O and calls the interface functions for any attached robots.

Fields in the task control block that are of immediate interest to the control function include the cycleCount, and the flag newRate, which is set whenever the control cycle rate is changed with the rciRate() primitive. The new interval and offset can then be obtained from the interval and offset fields. newRate is cleared at the end of the control cycle during which it was set.

The release function is responsible for "closing up shop" when the task is released. Reasons for tasks being released include error conditions or a normal release request caused by a call to rciRelease() in the planning task. The release function can determine the nature of the release condition by examining an integer code which is passed to it as a second argument. The possible values of code, defined in <rciMonitor.h>, are:

RELEASE_REQ --
    Normal release; rciRelease() called from planning task.

EXTERNAL_ABORT --
    Abort issued by another task.

RUN_TIMEOUT --

    Control task took too long to execute (the check for this condition is not currently implemented).

BLK_TIMEOUT --

    Control task had to wait too long to wake up.

LAG_TIMEOUT --

    Task far too far behind schedule.

STARTUP_FXN_ERR --

    Abort was issued inside the task's startup function.

CONTROL_FXN_ERR --

    Abort was issued inside the task's control function, or during a function called with rciExecute().

DIAGNOSTICS

Errors that occur at the control level generally result in an abort condition being raised through a call to rciAbort(). The abort condition can be raised either by the monitor or by the control functions themselves.

Abort codes that are generated by the monitor are:

ERunTimeout --
    Task took too long to execute.

EBlkTimeout --
    Task had to wait too long to run.

ELagTimeout --
    Task fell too far behind schedule.

SEE ALSO
HOW(3), CHG(3), JLS(3), RCI_TCB(3), IOdevice(7), rciAbort(3), rciControlFxns(3), rciAttachRobot(3), TASKROBOT(3), rbtComfxns(7).