Files
sics/anticollider.w
2012-11-15 12:39:51 +11:00

278 lines
9.7 KiB
OpenEdge ABL

\subsubsection{The Anti Collider}
In some cases certain instrument positions can only be reached through
special sequences of drive instructions. Usually because some concrete
blocks or unduly bulky sample environment devices are in the path of
the instrument. Such cases can not be handled through primitive motor
limits. Handling such cases is the objective of the Anti Collider.
The first thing needed is that motors involved with such complex
movements are registered with the Anti Collider. In this stage the
Anti Collider will take over the SetValue and CheckStatus functions of
the drivable interface of the motor. SetValue will be replaced by a
function which will register the drive request with the Anti
Collider. CheckStatus will be replaced by a version which checks with
the Anti Collider if the complex movement has finished.
It is expected that coordinated and complex movements are initiated
within a single command. The first checkpoint where the complex
movement can be analyzed and coordinated the is when the device
executor calls CheckStatus for the first time. CheckStatus will detect
this condition and proceeds to call a Tcl procedure which then has to
create a r\"unb\"uffer which holds the necessary commands to drive the
complex movement. Or returns an error if the movement is not
possible. This scheme allows the instrument scientist to adapt the
way how the instrument moves to new sample environment devices, new
ideas or the growth of experience. Moreover this scheme allows to
handle all instruments with just a single module. As the Anti Collider
has taken over the SetValue method of the drivable interface of the
motor a command is provided which allows to start the actual motor.
The user supplied Tcl script receives as arguments a list of motor and
target values to be driven. The script then has to return either an
error if the movement is not possible or the name of a r\"unb\"uffer
which performs the movement.
The first thing needed for all this is a data structure which holds
the registration information and status of the controlled motor. This
information will be kept in a list holding the data tsrucutre given
below:
@d motreg @{
typedef struct __MOTREG {
void *motorData;
char *motorName;
float targetPosition;
long (*originalSetValue)(void *motorData,
SConnection *pCon,
float fTarget);
int (*originalCheckStatus)(void *motorData,
SConnection *pCon);
int iActive;
} MotReg, *pMotReg;
@}
The fields are:
\begin{description}
\item[motorData] The motor data structure.
\item[motorName] The name of the motor operating.
\item[targetPosition] The requested target position for this motor.
\item[originalSetValue] the original motor starting function.
\item[originalCheckStatus] The original status checking function.
\item[iActive] A flag denoting if the motor has been started by the
Anti Collider. This causes the motors status to be checked which
checking status. If the motor becomes idle, this is set to 0 again.
\end{description}
The following interface functions are defined for this datastructure:
@d motregint @{
pMotReg RegisterMotor(char *name, SicsInterp *pSics,
long (*SetValue)(void *pData, SConnection *pCon, float
fTarget),
int (*CheckStatus)(void *pData, SConnection *pCon));
void KillRegMot(void *self);
void SetRegMotTarget(pMotReg self, float target);
void CreateTargetString(pMotReg self, char pBueffel[80]);
int RegMotMatch(pMotReg self, char *name);
int StartRegMot(pMotReg self, SConnection *pCon, float fValue);
int CheckRegMot(pMotReg self, SConnection *pCon);
@}
The functions in detail:
\begin{description}
\item[RegisterMotor] tries to find the motor name in the interpreter
pSics. Then all necessary manipulations are performed in order to
register the motor. In ths case of success a pointer to a new RegMot
data structure is returned. In the event of failure, NULL is
returned. Of course this function has to take the function pointers to
the drivable interface functions to replace as parameters.
\item[KillRegMot] kills a RegMot structure.
\item[SetRegMotTarget] sets a new target for a complex movement.
\item[CreateTragetString] creates in pBueffel this motors contribution
to a complex movement.
\item[RegMotMatch] returns 1 (true) if the string name matches the name stored
for this motor. Else 0. This will be used when searching for a
registered motor in the list.
\item[StartRegMot] will actually cause a real motor to start driving
towards the target given in fValue. The return value is the result of
the original motors SetValue method.
\item[CheckRegMot] checks for error conditions on the motor.
\end{description}
Moreover it is convenient to define a couple of convenience functions
for handling the list of registered motors. The actual list is
managed through the lld functions as everywhere within SICS.
@d motlist @{
int MakeMotList();
pMotReg FindMotEntry(int iList,char *name);
pMotReg FindMotFromDataStructure(int iList, void *pData);
int CheckAllMotors(int iList, SConnection *pCon);
void KillMotList(int iList);
void StopAllMotors(int iList);
void DeactivateAllMotors(int iList);
@}
The functions:
\begin{description}
\item[MakeMotList] creates a new list for MotReg structures and
returns the handle for it.
\item[FindMotEntry] locates a motor in the list by name. If a matching
motor can be found, this function returns a pointer to the motors
MotReg structure. In the case of failure NULL is returned.
\item[FindMotFromDataStructure] locates a motor in the list through
the pointer to its data structure. . If a matching
motor can be found, this function returns a pointer to the motors
MotReg structure. In the case of failure NULL is returned.
\item[CheckAllMotors] checks all the active motors for the finished
condition. The number of running motors is returned. 0 if none is running.
\item[KillMotList] kills the list and all entries in it.
\end{description}
In order to know how the anticollider has to run the motors a means is
needed to hold the sequence of motors to drive. This information must
be configured from the anticollider script. The information is held in
another list in a special data structure.
@d seqlist @{
typedef struct {
int level;
char pMotor[80];
float target;
}Sequence;
int StartLevel(int level, int sequenceList, int motorList,
SConnection *pCon);
@}
The fields and functions are:
\begin{description}
\item[level] The level at which this motor shall be started.
\item[pMotor] The name of the motor to start.
\item[target] The target value for the motor.
\item[StartLevel] starts all motors belonging to a the level
specified. Returns the number of motors started or ) if none is
started. This last condition is also the condition when levels are
exhausted and we need to finish running the anticollider.
\end{description}
The anticollider itself is characterized through the following data
structure:
@d antidat @{
typedef struct __ANTICOLLIDER{
pObjectDescriptor pDes;
pIDrivable pDriv;
int motorList;
int sequenceList;
char *colliderScript;
int isDirty;
int level;
}AntiCollider, *pAntiCollider;
@}
The fields are:
\begin{description}
\item[pDes] The object descriptor required by SICS.
\item[motorList] The list of registered motors.
\item[colliderScript] the Tcl script called to calculate the movement.
\item[iDirty] a flag which is set to 1 (true) when a new movement must
be calculated.
\end{description}
Most of the anticolliders functionality is implemented in interface
functions. The interface to the outside world is purely defined
through the interpreter functions.
@d antiint @{
int AntiColliderFactory(SConnection *pCon, SicsInterp *pSics,
void *pData,
int argc, char *argv[]);
int AntiColliderAction(SConnection *pCon, SicsInterp *pSics,
void *pData,
int argc, char *argv[]);
@}
@o motreg.h @{
/*-------------------------------------------------------------------------
R e g M o t
This is a helper module for the Anti Collider. It handles all the
stuff necessary for dealing with a single motor. For more
information see the file anticollider.tex.
copyright: see file copyright
Mark Koennecke, August 2002
-----------------------------------------------------------------------*/
#ifndef REGMOT
#define REGMOT
#include "sics.h"
@<motreg@>
/*----------------------------------------------------------------------*/
@<motregint@>
#endif
@}
@o motreglist.h @{
/*-----------------------------------------------------------------------
A couple of utility functions for handling a list of MotReg
structures . This is a helper module for the anticollider collision
control system. See anticollider.tex for more details.
copyright: see file copyright
Mark Koennecke, August 2002
-------------------------------------------------------------------------*/
#ifndef MOTREGLIST
#define MOTREGLIST
#include "motreg.h"
@<motlist@>
#endif
@}
@o anticollider.i @{
/*-------------------------------------------------------------------------
Anticollider internal data structure definition. Generated from
anticollider.w. Do not edit.
-------------------------------------------------------------------------*/
@<antidat@>
@<seqlist@>
@}
@o anticollider.h @{
/*----------------------------------------------------------------------
This is the header file for the AntiCollider, a complex movements
control module for SICS. See anticoliider.tex for more information.
copyright: see file copyright
Mark Koennecke, August 2002
------------------------------------------------------------------------*/
#ifndef ANTICOLLIDER
#define ANTICOLLIDER
@<antiint@>
#endif
@}