282 lines
11 KiB
OpenEdge ABL
282 lines
11 KiB
OpenEdge ABL
\subsection{Chopper Controller}
|
|
Yet another way to deal with a controller has been devised for
|
|
SICS. This uses the concept of a general controller which can have
|
|
parameters enquired and set. Furthermore it may have parameters which
|
|
may be driven like a motor or environment controller through special
|
|
adapters . This scheme is
|
|
used for the chopper controller for FOCUS.
|
|
\begin{itemize}
|
|
\item A driver for a particular controller which allows to set and get
|
|
parameters.
|
|
\item The general controller object which holds things together.
|
|
\item An adapter object which allows to drive special parameters in a general
|
|
controller. Such adapter objects can be configured for each drivable parameter
|
|
in a controller.
|
|
\item An adapter to an environment controller driver.
|
|
\end{itemize}
|
|
The test case for this way of doing things is a controller for running
|
|
choppers. This is why it gets the name.
|
|
|
|
The chopper system in question is the FOCUS chopper system. There are two
|
|
choppers, a fermi chopper and a disk chopper. This system can be run in two
|
|
different modes: In synchronous mode both choppers run at a
|
|
predefined ratio of speeds. For instance the fermi chopper is two
|
|
times faster then the disk chopper. This means, that setting a new
|
|
value for one chopper also changes the speed of the other chopper. In
|
|
asynchronous mode both choppers operate independently. Also the ration
|
|
to use for synchronous mode can be changed. Another parameter which
|
|
frequently changes is the phase of the two choppers. In order to
|
|
compensate for the fligh path between the two choppers there is a
|
|
small angular displacement of the choppers against each other which
|
|
varies with wavelength.
|
|
|
|
\subsubsection{The Controller Driver}
|
|
The controller driver is represented by the following data structure:
|
|
@d codri @{
|
|
typedef struct __CODRI *pCodri;
|
|
typedef struct __CODRI {
|
|
int (*Init)(pCodri self);
|
|
int (*Close)(pCodri self);
|
|
int (*Delete)(pCodri self);
|
|
int (*SetPar)(pCodri self,
|
|
char *parname,
|
|
float fValue);
|
|
int (*SetPar2)(pCodri self,
|
|
char *parname,
|
|
char *value);
|
|
int (*GetPar)(pCodri self,
|
|
char *parname,
|
|
char *pBuffer,
|
|
int iBufLen);
|
|
int (*CheckPar)(pCodri self,
|
|
char *parname);
|
|
int (*GetError)(pCodri self, int *iCode,
|
|
char *pError,
|
|
int iErrLen);
|
|
int (*TryFixIt)(pCodri self, int iCode);
|
|
int (*Halt)(pCodri self);
|
|
char *pParList;
|
|
void *pPrivate;
|
|
}Codri;
|
|
|
|
@}
|
|
All functions take a pointer to the controller driver itself as a
|
|
parameter. All functions except TryFixIt and CheckPar
|
|
return 0 on failure and 1 for success.
|
|
\begin{description}
|
|
\item[Init] initializes the controller driver. The parameters argc,
|
|
argv are main() style parameters for the initialization of the
|
|
controller driver.
|
|
\item[Close] closes the connection to the controller but does not delete a thing.
|
|
\item[Delete] closes the connection to the controller and deletes private data structures. Called when deleting the controller.
|
|
\item[SetPar] tries to set the parameter parname to the value
|
|
fValue. The last is floating point which covers the frequent
|
|
occurence of numeric values.
|
|
\item[SetPar2] The same as SetPar but uses text string as input for
|
|
parameter setting.
|
|
\item[GetPar] retrieves the parameter parname formatted as text. The
|
|
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
|
bytes permissable for pBuffer.
|
|
\item[CheckPar] When parameters are driven a means is needed to find
|
|
out about the progress of operations and errors during the
|
|
operation. This is done by CheckPar for the parameter parname. The
|
|
return value of this function must be one of the HWBusy, HWError,
|
|
HWDone family documented in the motor driver object description.
|
|
\item[GetError] retrieves the last error. An integer error code is
|
|
placed into iCode and a textual description of the problem is written
|
|
to pError. Maximum iErrLen bytes are copied to pError.
|
|
\item[TryFixIt] tries to fix the error condition specified by iCode in
|
|
software if this possible. TryFisIt returns HWRedo if the last command
|
|
needs to resent, HWFault if the problem could not be fixed and HWOK if
|
|
the error can be ignored or was fully resolved.
|
|
\item[pParList] is text string containing a comma separated list of
|
|
all parameters understood by this driver.
|
|
\item[pPrivate] Is a pointer to a driver specific specific data
|
|
structure. This data structure shall not be messed with by upper level code.
|
|
\end{description}
|
|
|
|
\subsubsection{The Controller Object}
|
|
This is the general controller object visible from the SICS
|
|
interpreter. This object allows to list all possible
|
|
parameters. Internal functions are provided for setting
|
|
parameters. But this is meant to be operated through a drive adapter
|
|
object (see below) in SICS. Thus the interface to this object
|
|
includes:
|
|
@d chocoint @{
|
|
typedef struct __CHOCO *pChoco;
|
|
/*------------------------------------------------------------------------*/
|
|
int CHGetParameter(pChoco self, char *pParName,
|
|
char *pParValue, int iBuflen);
|
|
|
|
pCodri CHGetDriver(pChoco self);
|
|
int CHList(pChoco self, SConnection *pCon, char *name);
|
|
/*------------------------------------------------------------------------*/
|
|
void KillChoco(void *pData);
|
|
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
@}
|
|
\begin{description}
|
|
\item[CHGetParameter] retrieves the value of the parameter ParName
|
|
converted to text. Maximum iBufLen of result or error text are copied into the
|
|
buffer pParvalue.
|
|
\item[CHGetDriver] returns a pointer to the controller driver. This
|
|
function will be used by the drive adapters for interfacing with the
|
|
driver directly.
|
|
\item[CHList] prints a listing of all parameters to the client
|
|
described by pCon. name is the name of the controller.
|
|
\item[ChocoAction] is the SICS interpreter interface function for the
|
|
controller.
|
|
\item[ChocoFactory] is the SICS interpreter interface function which
|
|
installs a controller into SICS.
|
|
\end{description}
|
|
|
|
Most of the actual work of the controller is left to the driver. Thus
|
|
the internal data structure for a controller object is very simple:
|
|
@d chocodata @{
|
|
typedef struct __CHOCO {
|
|
pObjectDescriptor pDes;
|
|
pCodri pDriv;
|
|
} Choco;
|
|
@}
|
|
It consists just of the standard SICS object descriptor and a pointer
|
|
to the driver.
|
|
|
|
\subsubsection{The Drive And Environment Adapters}
|
|
Most of the work of the drive adaptor is hidden in the functions
|
|
implementing the drivable interface. Thus the interface to the
|
|
DriveAdapter is fairly simple:
|
|
@d adapter @{
|
|
typedef struct __CHADAPTER *pCHAdapter;
|
|
/*-----------------------------------------------------------------------*/
|
|
int CHAdapterFactory(SConnection *pCon, SicsInterp *pSics,
|
|
void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
int CHAdapterAction(SConnection *pCon, SicsInterp *pSics,
|
|
void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
pEVDriver MakeControllerEnvironmentDriver(int argc, char *argv[]);
|
|
|
|
@}
|
|
\begin{description}
|
|
\item[CHAdapterFactory] is the SICS interpreter factory function for
|
|
creating a drive adapter.
|
|
\item[CHAdapterAction] is the SICS interpreter function for
|
|
representing the object in SICS. Just a single action is supported:
|
|
request the value of the parameter.
|
|
\item[MakeControllerEnvironmentDriver] creates an environment control
|
|
driver for a parameter in a general controller object.
|
|
\end{description}
|
|
|
|
The data structure for the drive adapter is slightly more interesting:
|
|
@d adadata @{
|
|
typedef struct __CHADAPTER {
|
|
pObjectDescriptor pDes;
|
|
pCodri pDriv;
|
|
pIDrivable pInt;
|
|
float fUpper;
|
|
float fLower;
|
|
float fTarget;
|
|
char *pParName;
|
|
}CHAdapter;
|
|
@}
|
|
\begin{description}
|
|
\item[pDes] is the standard object descriptor.
|
|
\item[pDriv] is a pointer to the controller driver.
|
|
\item[pInt] is a pointer to the drivable interface implemented by the
|
|
adapter.
|
|
\item[fUpper] upper limit for the parameter.
|
|
\item[fLower] lower limit for the parameter.
|
|
\item[pParName] is the name of the parameter which is driven through
|
|
this adapter.
|
|
\end{description}
|
|
|
|
This is the data structure for the private part of the environment
|
|
controller driver:
|
|
@d evada @{
|
|
typedef struct __CHEV {
|
|
char *pParName;
|
|
pCodri pDriv;
|
|
int iLastError;
|
|
}CHev, *pCHev;
|
|
@}
|
|
|
|
@o codri.h @{
|
|
/*-------------------------------------------------------------------------
|
|
C o n t r o l l e r D r i v e r
|
|
|
|
This file contains the description of the data structure for a
|
|
general controller driver.
|
|
|
|
Mark Koennecke, January 1998
|
|
--------------------------------------------------------------------------*/
|
|
#ifndef CODRIV
|
|
#define CODRIV
|
|
#define CHFAIL -1
|
|
#define CHREDO -2
|
|
#define CHOK -3
|
|
@<codri@>
|
|
#endif
|
|
|
|
@}
|
|
|
|
@o choco.h @{
|
|
/*-----------------------------------------------------------------------
|
|
C h o p p e r C o n t r o l l e r
|
|
|
|
This is both the header file for a general controller and a SICS
|
|
chopper controller.
|
|
|
|
Mark Koennecke, January 1998
|
|
--------------------------------------------------------------------------*/
|
|
#ifndef CHOCOSICS
|
|
#define CHOCOSICS
|
|
#include "codri.h"
|
|
@<chocoint@>
|
|
#ifdef CHOCOINTERNAL
|
|
@<chocodata@>
|
|
#endif
|
|
#endif
|
|
@}
|
|
|
|
|
|
@o chadapter.h @{
|
|
/*------------------------------------------------------------------------
|
|
C H a d a p t e r
|
|
|
|
This is the header file for a drive adapter for collaboration with a
|
|
general device controller as implemented in choco.*
|
|
|
|
Mark Koennecke, January 1998
|
|
--------------------------------------------------------------------------*/
|
|
#ifndef SICSCHADA
|
|
#define SICSCHADA
|
|
#include "codri.h"
|
|
@<adapter@>
|
|
#ifdef CHADAINTERNAL
|
|
@<adadata@>
|
|
@<evada@>
|
|
#endif
|
|
#endif
|
|
@}
|
|
|
|
|
|
\subsubsection{To Do}
|
|
This scheme seems to be quite promising for handling many SICS
|
|
objects. The following enhancements could be considered. Allow to set
|
|
certain primitive parameters without a drivable interface.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|