317 lines
13 KiB
OpenEdge ABL
317 lines
13 KiB
OpenEdge ABL
\subsection{The Velocity Selector}
|
|
A velocity selector is a kind of turbine in the neutron beam. Only neutrons
|
|
which manage to travel through the device between two turbine blades make it
|
|
through the device, the rest is annihilated in the blades or the turbine
|
|
housing. Thus, a velocity selector is a kind of monochromator.
|
|
The behaviour of a velocity selector is determined by two
|
|
parameters: the rotation speed and the dejustment of the velocity selector
|
|
to the neutron beam, the tilt angle. The velocity
|
|
(wavelength) of the neutrons coming through is determined by the rotation speed
|
|
of the thing. The tilt angle determines the velocity distribution function.
|
|
|
|
Velocity selectors have a few peculiarities due to the fact that they
|
|
rotate rather quickly. This may give rise to resonances at certain
|
|
rotation speeds which may damage the device and the surroundings of it. This
|
|
problem is coped with by having forbidden regions of rotation speeds which
|
|
cannot be selected. The second implication of the fast rotation is, that the
|
|
rotation needs to stop or be below a certain threshold before the tilt
|
|
angle may be changed. So, changing tilt has to go in three steps:
|
|
first stop rotation, drive tilt, accelerate rotation to the former speed.
|
|
Tilt is usually controlled by some stepper motor.
|
|
|
|
The rotation speed of the velocity selector needs to be monitored at regular
|
|
intervalls. If it goes out of tolerances, a error handling procedure must be
|
|
initiated. Furthermore logging of the rotation speeds of the velocity
|
|
selector may be required. All this is already realised in the environment
|
|
controller code. In order to minimise duplication of code, these facilities
|
|
are implemented by installing a environment controller for the velocity
|
|
selector. This environement controller will have a dummy driver which does
|
|
not allow the velocity selector to be driven through the environment
|
|
controller. An object is installed into the SICServer with the name of the
|
|
velocity selector and watch appended to it. Through this object such things
|
|
as tolerances, error handling procedures and logging of velocity selector
|
|
values can be configured. The only task left for the velocity selector code
|
|
is to maintain the proper state of the environment controller mode at
|
|
apropriate places.
|
|
|
|
|
|
From this introduction the necessary datastructure for this beast can be
|
|
easily deduced. Besides the usual objectdescriptor we need:
|
|
\begin{itemize}
|
|
\item A list of forbidden regions, realised as a standard linked list of
|
|
min, max values.
|
|
\item A motor to drive the tilt with.
|
|
\item Fields to hold rotation and tilt and some auxilliary parameters.
|
|
\item Various interrupt to trigger in case of failures.
|
|
\item As an interface a drivable interface for the rotation is needed in
|
|
oder to use the device executor for changing rotation speed.
|
|
\item A pointer to the environment controller object monitoring the velocity
|
|
selector.
|
|
\item A driver for actually driving the velocity selector.
|
|
\end{itemize}
|
|
A suitable datastructure looks like this:
|
|
|
|
@d data @{
|
|
/*------------------ The velocity selector datastructure -----------------*/
|
|
|
|
typedef struct __VelSel {
|
|
pObjectDescriptor pDes;
|
|
char *pName;
|
|
pIDrivable pDrivInt;
|
|
pICallBack pCall;
|
|
int iForbidden;
|
|
ObPar *pPar;
|
|
pMotor pTilt;
|
|
float fRot;
|
|
float fTilt;
|
|
pEVControl pMonitor;
|
|
pVelSelDriv pDriv;
|
|
} VelSel;
|
|
/*----------------- Forbidden region single item -------------------------*/
|
|
typedef struct __Verbot {
|
|
float fMin;
|
|
float fMax;
|
|
} Verbot, *pVerbot;
|
|
|
|
@}
|
|
The fields are:
|
|
\begin{description}
|
|
\item[pDes] The usual object descriptor.
|
|
\item[pName] The velocity selector name.
|
|
\item[pDrivInt] The drivable interface.
|
|
\item[pCall] The callback interface.
|
|
\item[iForbidden] The handle to the lsit of forbidden regions.
|
|
\item[pPar] The velocity selector parameters.
|
|
\item[pTilt] The motor to use for tilting the turbine.
|
|
\item[pMonitor] The environment controller object representing the velocity
|
|
selector in the environment control subsystem.
|
|
\item[pDriv] The velocity selector driver.
|
|
\end{description}
|
|
Verbot is a trivial little data structure holding a single forbidden
|
|
region for the vlocity selector. This is the structure held in the
|
|
forbidden list. Please note that the upper and lower limits of the
|
|
device are held in that list as well.
|
|
|
|
In order to interface with this a few functions will be defined. All
|
|
functions starts with VS. Functions returning an int return 0 on failure, 1
|
|
on success for the rest of this discussion. The first set of functions
|
|
deals with creating and configuring a velocity selector.
|
|
|
|
@d proto1 @{
|
|
typedef struct __VelSel *pVelSel;
|
|
typedef struct __VelSelDriv *pVelSelDriv;
|
|
|
|
pVelSel VSCreate(pMotor pTilt, pVelSelDriv pDriv);
|
|
void VSDestroy(void *self);
|
|
|
|
int VSAddVerbot(pVelSel self, float fMin, float fMax);
|
|
int VSSetPar(pVelSel self,SConnection *pCon, char *name, float fVal);
|
|
int VSGetPar(pVelSel self,char *name, float *fVal);
|
|
int VSGetRotation(pVelSel self, float *fRot);
|
|
int VSGetTilt(pVelSel self, float *fTilt);
|
|
@}
|
|
|
|
Most functions take a pointer to a velocity selector data structure as
|
|
first parameter. This parameter is not discussed furtheron.
|
|
\begin{description}
|
|
\item[VSCreate] Creates a velocity selector object. A driver and a
|
|
motor for the tiliting operation need to be given as parameters. On
|
|
return either a pointer to a newly allocated velocity selector data
|
|
structure is returned or NULL as indication of failure.
|
|
The velocity selector will make sure that the tilt motor is only
|
|
accessible with internal
|
|
privilege. This effectively reserves the tilt motor to the velocity
|
|
selector object. This obliges the velocity selector to set a lower
|
|
privilege
|
|
while running that motor and to set it back again afterwards.
|
|
The idea behind this
|
|
scheme is to prevent a user from accidentally tampering with the tilt motor
|
|
without passing through the velocity selector interface.
|
|
\item[VSDestroy] is a function which properly frees all data
|
|
structures associated with the velocity selector. This is the function
|
|
to specify as KillFunction for the interpreter.
|
|
\item[VSAddVerbot] adds a forbidden region between fMin and fmax
|
|
rotation speeds.
|
|
\item[VSSetPar, VSGetPar] set and retrive velocity selector
|
|
parameters. Parameter names given as parameter name are the same as in
|
|
the user documentation.
|
|
\item[VSGetRotation] retrieves the current rotation speed.
|
|
\item[VSGetTilt] retrieves the current tilt angle.
|
|
\end{description}
|
|
|
|
@d protos2 @{
|
|
/*
|
|
int VSSetRotation(pVelSel self, SConnection *pCon, float fNew);
|
|
int VSSetTilt(pVelSel self, SConnection *pCon, float FNewTilt);
|
|
*/
|
|
int VSSetTiltRot(pVelSel self, SConnection *pCon,
|
|
float fNewRot, float fNewTilt);
|
|
@}
|
|
|
|
\begin{description}
|
|
\item[VSSetTiltRot] sets both rotation speed and tilt angle to new
|
|
values.
|
|
\end{description}
|
|
|
|
Please note, that further manipulation functions are hidden in the Drivable
|
|
interface functions for the rotation which this module defines.
|
|
|
|
|
|
Another common task for a velocity selector is to measure its loss current.
|
|
This is done regularly in order to catch possible problems with the
|
|
velocity selector early on.
|
|
|
|
@d protos4 @{
|
|
int VSGetLossCurrent(pVelSel self, SConnection *pCon, float *fLoss);
|
|
@}
|
|
|
|
|
|
Last not least a velocity selector needs an interface to the interpreter as
|
|
well. As usual there are two functions: a creation function and a bigger
|
|
action function which takes the widget commands.
|
|
|
|
@d protos3 @{
|
|
int VelSelFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
int VelSelAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
@}
|
|
|
|
\subsubsection{The velocity selector driver}
|
|
As usual for hardware devices in SICS the velocity selector consists of the
|
|
logical selector described above and a hardware driver which takes care of
|
|
simulating actual hardware or talking to it. This driver is described here.
|
|
@d Driver @{
|
|
typedef struct __VelSelDriv {
|
|
void *pPrivate;
|
|
void (*DeletePrivate)(void *pData);
|
|
float fTolerance;
|
|
int (*Halt)(pVelSelDriv self);
|
|
int (*GetError)(pVelSelDriv self,
|
|
int *iCode, char *pError,
|
|
int iErrlen);
|
|
int (*TryAndFixIt)(pVelSelDriv self,
|
|
int iCode);
|
|
int (*GetRotation)(pVelSelDriv self,
|
|
float *fRot);
|
|
int (*SetRotation)(pVelSelDriv self,
|
|
float fRot);
|
|
int (*GetStatus)(pVelSelDriv self,
|
|
int *iCall, float *fCur);
|
|
int (*GetDriverText)(pVelSelDriv self,
|
|
char *pText,
|
|
int iTextLen);
|
|
int (*GetLossCurrent)(pVelSelDriv self,
|
|
float *fLoss);
|
|
int (*Init)(pVelSelDriv self,
|
|
SConnection *pCon);
|
|
}VelSelDriv;
|
|
@}
|
|
|
|
pPrivate is an area where individual drivers may store their necessary data.
|
|
DeletePrivate is a function which will be automatically called when the
|
|
driver is destroyed with pPrivate passed as parameter. This functions
|
|
purpose is to destroy pPrivate and remove all memory associated with it.
|
|
Each driver is resonsible for filling the right thing in here.
|
|
|
|
The description of the rest of the functions is very much like as described
|
|
for the motor interface. Possible return values for GetStatus can be:
|
|
\begin{itemize}
|
|
\item VSNOCON: connection to velocity selector lost.
|
|
\item VSACCEL: selector accelerating or breaking.
|
|
\item VSFAIL: velocity selector failure.
|
|
\item VSOK: all fine, at requested velocity.
|
|
\end{itemize}
|
|
|
|
Special is the GetDriverText which is meant to
|
|
return a formatted string of hardware specific information from the device.
|
|
This is put into pText, but maximum iTextlen characters.
|
|
|
|
Another special is the GetLossCurrent. This is a special self test of the
|
|
velocity selector which helps to identify possible problems with the device
|
|
early on. This test must be made regularly and, of course, the driver must
|
|
support it.
|
|
|
|
Init is meant to do what it says, initialize the velocity selector. This is
|
|
here in order to support restarting the velocity selector in case of a
|
|
problem.
|
|
|
|
At the time of writing (Juli 1997) two drivers for velocity selectors exist:
|
|
a simulation driver and a driver for a Dornier velocity selector run
|
|
through a Macintosh--PC terminal server communicating with the velocity
|
|
selector control PC. Please note, that the Dornier program had been slightly
|
|
modified in order to make this scheme work.
|
|
|
|
@o velo.h -d @{
|
|
/*-------------------------------------------------------------------------
|
|
|
|
V E L O C I T Y S E L E C T O R
|
|
|
|
Header file for the SICS velocity selector module. For documentation
|
|
see velo.w.
|
|
|
|
Mark Koennecke, Juli 1997
|
|
|
|
copyright: see implementation file
|
|
-----------------------------------------------------------------------------*/
|
|
#ifndef SICSVELO
|
|
#define SICSVELO
|
|
|
|
/*------------------------- live & death & shape ------------------------*/
|
|
@< proto1 @>
|
|
/*------------------------- drive around -----------------------------------*/
|
|
@< protos2 @>
|
|
@< protos4 @>
|
|
/*------------------------- Interpreter interface ------------------------*/
|
|
@< protos3 @>
|
|
#endif
|
|
@}
|
|
|
|
@o velo.i -d @{
|
|
/*--------------------------------------------------------------------------
|
|
|
|
Internal header file describing the velocity selector data structure.
|
|
|
|
Mark Koennecke, Juli, 1997
|
|
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef VELOINTERNAL
|
|
#define VELOINTERNAL
|
|
@< data @>
|
|
#define VELOREDO 2
|
|
#define VELOFAIL 0
|
|
#define VELOOK 1
|
|
|
|
#define VSNOCON 0
|
|
#define VSOK 1
|
|
#define VSACCEL -7
|
|
#define VSFAIL -2
|
|
|
|
#endif
|
|
|
|
@}
|
|
|
|
@o velodriv.h -d @{
|
|
/*--------------------------------------------------------------------------
|
|
V E L O C I T Y S E L E C T O R D R I V E R
|
|
|
|
Header file for the velocity selector driver and its related functions.
|
|
|
|
Mark Koennecke, Juli 1997
|
|
copyright: see implementation file
|
|
-----------------------------------------------------------------------------*/
|
|
#ifndef VELODRIV
|
|
#define VELODRIV
|
|
#include <tcl.h>
|
|
@< Driver @>
|
|
/*-------------------- live & death ----------------------------------------*/
|
|
pVelSelDriv VSCreateSim(void);
|
|
pVelSelDriv VSCreateDornierSINQ(char *name,Tcl_Interp *pTcl);
|
|
|
|
void VSDeleteDriver(pVelSelDriv self);
|
|
|
|
#endif
|
|
@}
|
|
|