- First working version of the TRICS collision protection module
This commit is contained in:
275
anticollider.w
Normal file
275
anticollider.w
Normal file
@ -0,0 +1,275 @@
|
||||
\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);
|
||||
@}
|
||||
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
|
||||
|
||||
|
||||
|
||||
@}
|
Reference in New Issue
Block a user