Files
sicspsi/amor2t.c
koennecke a5f315b56a - Added Sycamore protocol and command context to SICS
- Added sinfo to SICS
- Added driver for TCP/IP Astrium velocity selector
- Added driver for TCP/IP Astrium chopper controller
2005-12-22 22:16:13 +00:00

1040 lines
32 KiB
C

/*---------------------------------------------------------------------------
A M O R 2 T
A class for controlling the two theta movement of the reflectometer
AMOR at SINQ. It is not clear if this class may be useful for other
reflectometers, too. At AMOR the two theta movement of the detector is
realized by translating the detector along x and z. Also it can be
tilted in omega. Furthermore the height of two diaphragms has to be
adjusted when moving two theta as well. In polarizing mode the analyzer
mirror has to be moved as well.
copyright: see copyright.h
Mark Koennecke, September 1999
Bugs fixed, analyzer included for A2T. Then there is a second thing:
aoz2t which allows to scan the analyzer in two-theta during alignment
of the instrument. As all the parameters are already held in the a2t
structures this extra was added into this module.
Mark Koennecke, May-June 2000
Introduced DIAFLAG to switch off diaphragm calculation.
Mark Koennecke, July 2005
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "fortify.h"
#include <tcl.h>
#include "sics.h"
#include "motor.h"
#include "obpar.h"
#define DEBUG 1
#define MAXMOT 13
#define MAXPAR 14
#include "amor2t.i"
#include "amor2t.h"
/*
Defines for accessing various motors and variables. Definition of motor: see
annotated AMOR drawing.
*/
/* monochromator omega */
#define MOTMOM 0
/* sample omega */
#define MOTSOM 1
/* detector height movement */
#define MOTCOZ 2
/* detector movement along main axis */
#define MOTCOX 3
/* sample holder height movement */
#define MOTSTZ 4
/* whole sample table height movement */
#define MOTSOZ 5
/* lift for diaphragm 4*/
#define MOTD4B 6
/* lift for diaphragm 5 */
#define MOTD5B 7
/* detector omega movement */
#define MOTCOM 8
/* lift for analyzer */
#define MOTAOZ 9
/* analyzer omega */
#define MOTAOM 10
/* detector 2 movement */
#define MOTC3Z 11
/*======================================================================
The core of it all: The calculation of the settings for the various
motors.
========================================================================*/
static void clearRunFlags(pAmor2T self)
{
int i;
for(i = 0; i < MAXMOT; i++)
{
self->toStart[i].pMot = NULL;
}
}
/*---------------------------------------------------------------------*/
static int CalculateAMORE(pAmor2T self, SConnection *pCon, float fNew)
{
float fMOM, fSOM, fSTZ, fSOZ, fAOM, fAOZ, fC3Z, fconstAOM;
double fAngle, fX, fZ, fZ2, fBase, fPIR;
float fCOZ, fCOX, fCOM;
int iRet;
#ifdef DEBUG
char pBueffel[132];
#endif
/* get the necessary angles first */
iRet = MotorGetSoftPosition(self->aEngine[MOTMOM],pCon,&fMOM);
if(iRet != 1)
{
return iRet;
}
iRet = MotorGetSoftPosition(self->aEngine[MOTSOM],pCon,&fSOM);
if(iRet != 1)
{
return iRet;
}
iRet = MotorGetSoftPosition(self->aEngine[MOTSTZ],pCon,&fSTZ);
if(iRet != 1)
{
return iRet;
}
iRet = MotorGetSoftPosition(self->aEngine[MOTSOZ],pCon,&fSOZ);
if(iRet != 1)
{
return iRet;
}
/* calculate base height of sample table */
fBase = fSOZ + ObVal(self->aParameter,PARDH);
fPIR = 180. / 3.1415926;
clearRunFlags(self);
/* calculation for detector */
fAngle = fNew - 2*fMOM;
if(fAngle < 0)
{
fAngle = fAngle + 360.;
}
fAngle /= fPIR;
fX = ObVal(self->aParameter,PARDS)*cos(fAngle);
fZ = ObVal(self->aParameter,PARDS)*sin(fAngle);
self->toStart[0].pMot = self->aEngine[MOTCOX];
strcpy(self->toStart[0].pName,self->aEngine[MOTCOX]->name);
self->toStart[0].fTarget = fX - ObVal(self->aParameter,PARDS);
self->toStart[1].pMot = self->aEngine[MOTCOZ];
strcpy(self->toStart[1].pName,self->aEngine[MOTCOZ]->name);
self->toStart[1].fTarget = fZ + fBase -
ObVal(self->aParameter,PARDDH);
self->toStart[2].pMot = self->aEngine[MOTCOM];
strcpy(self->toStart[2].pName,self->aEngine[MOTCOM]->name);
self->toStart[2].fTarget = fNew - 2*fMOM;
if(ObVal(self->aParameter,DIAFLAG) > .0)
{
/* calculation for diaphragm 4 */
fZ = ObVal(self->aParameter,PARDD4) * sin(fAngle);
self->toStart[3].pMot = self->aEngine[MOTD4B];
strcpy(self->toStart[3].pName,self->aEngine[MOTD4B]->name);
self->toStart[3].fTarget = fBase + fZ -
ObVal(self->aParameter,PARD4H);
/* calculation for diaphragm 5 */
fZ = ObVal(self->aParameter,PARDD5) * sin(fAngle);
self->toStart[4].pMot = self->aEngine[MOTD5B];
strcpy(self->toStart[4].pName,self->aEngine[MOTD5B]->name);
self->toStart[4].fTarget = fBase + fZ -
ObVal(self->aParameter,PARD5H);
#ifdef DEBUG
sprintf(pBueffel,"2T COZ COX COM D4B D5B ");
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f",
fNew, self->toStart[1].fTarget, self->toStart[0].fTarget,
self->toStart[2].fTarget, self->toStart[3].fTarget,
self->toStart[4].fTarget);
SCWrite(pCon,pBueffel,eValue);
#endif
}
if(ObVal(self->aParameter,ANAFLAG) > 0)
{
/* the analyzer height */
fZ = ObVal(self->aParameter,PARADIS)*sin(fAngle);
fAOZ = fBase + fZ - ObVal(self->aParameter,PARANA);
self->toStart[5].pMot = self->aEngine[MOTAOZ];
strcpy(self->toStart[5].pName,self->aEngine[MOTAOZ]->name);
self->toStart[5].fTarget = fAOZ;
/* analyzer omega */
self->toStart[6].pMot = self->aEngine[MOTAOM];
strcpy(self->toStart[6].pName,self->aEngine[MOTAOM]->name);
self->toStart[6].fTarget = fNew/2.
+ ObVal(self->aParameter,PARAOM);
/* C3Z */
fZ2 = (ObVal(self->aParameter,PARDS) - ObVal(self->aParameter,
PARADIS))*sin(fAngle + (fNew/fPIR) );
self->toStart[7].pMot = self->aEngine[MOTC3Z];
strcpy(self->toStart[7].pName,self->aEngine[MOTC3Z]->name);
self->toStart[7].fTarget = fBase + fZ + fZ2 -
ObVal(self->aParameter,PARDDD) -
self->toStart[1].fTarget;
#ifdef DEBUG
sprintf(pBueffel,"2T AOZ AOM C3Z");
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%6.2f %6.2f %6.2f %6.2f",
fNew, self->toStart[5].fTarget, self->toStart[6].fTarget,
self->toStart[7].fTarget);
SCWrite(pCon,pBueffel,eValue);
#endif
}
return 1;
}
/*=======================================================================
Calculations for Analyzer two theta
=========================================================================*/
static int CalculateANA2T(pAmor2T self, SConnection *pCon, float fNew)
{
double fBase, fPIR;
float fAOZ, fIncident, fSOM, fMOM, fDiffracted, fDistance, fX, fZ;
int iRet;
#ifdef DEBUG
char pBueffel[132];
#endif
/* calculate base height of analyzer table */
iRet = MotorGetSoftPosition(self->aEngine[MOTSOZ],pCon,&fAOZ);
if(iRet != 1)
{
return iRet;
}
fBase = fAOZ + ObVal(self->aParameter,PARANA);
fPIR = 180. / 3.1415926;
/* Calculate the incident angle at the analyzer */
iRet = MotorGetSoftPosition(self->aEngine[MOTSOM],pCon,&fSOM);
if(iRet != 1)
{
return iRet;
}
iRet = MotorGetSoftPosition(self->aEngine[MOTMOM],pCon,&fMOM);
if(iRet != 1)
{
return iRet;
}
fIncident = fMOM + 2. * fSOM;
/* calculate the angle of the diffracted beam against the
horizon at the analyzer.
fDiffracted = fIncident - 2. * AOM.
There is a problem here. We should read AOM in order to get the
value. However in the context of an omega - two-theta scan on AOM
and ana2t, it is fNew.
*/
fDiffracted = fIncident - fNew;
clearRunFlags(self);
/* calculation for detector */
fDiffracted /= fPIR;
fDistance = ObVal(self->aParameter,PARDS) -
ObVal(self->aParameter, PARANA);
fX = fDistance*cos(fDiffracted);
fZ = fDistance*sin(fDiffracted);
self->toStart[0].pMot = self->aEngine[MOTCOX];
strcpy(self->toStart[0].pName,self->aEngine[MOTCOX]->name);
self->toStart[0].fTarget = fX - fDistance;
self->toStart[1].pMot = self->aEngine[MOTCOZ];
strcpy(self->toStart[1].pName,self->aEngine[MOTCOZ]->name);
self->toStart[1].fTarget = fZ + fBase -
ObVal(self->aParameter,PARDDH);
self->toStart[2].pMot = self->aEngine[MOTCOM];
strcpy(self->toStart[2].pName,self->aEngine[MOTCOM]->name);
self->toStart[2].fTarget = -fDiffracted*fPIR;
/* calculation for diaphragm 5 */
if(ObVal(self->aParameter,DIAFLAG) > .0)
{
fZ = ObVal(self->aParameter,PARDD5) * sin(fDiffracted);
self->toStart[3].pMot = self->aEngine[MOTD5B];
strcpy(self->toStart[3].pName,self->aEngine[MOTD5B]->name);
self->toStart[3].fTarget = fBase + fZ -
ObVal(self->aParameter,PARD5H);
}
#ifdef DEBUG
sprintf(pBueffel,"2T COX COZ COM D5B ");
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"%6.2f %6.2f %6.2f %6.2f %6.2f ",
fNew, self->toStart[0].fTarget, self->toStart[1].fTarget,
self->toStart[2].fTarget,self->toStart[3].fTarget);
SCWrite(pCon,pBueffel,eValue);
#endif
return 1;
}
/*========================================================================
Definition of interface functions.
=========================================================================*/
static long A2TSetValue(void *pData, SConnection *pCon, float fNew)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* calculation */
iRet = CalculateAMORE(self,pCon,fNew);
if(iRet != 1)
{
return iRet;
}
/* start them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->SetValue(self->toStart[i].pMot,pCon,
self->toStart[i].fTarget);
if(iRet != OKOK)
{
return iRet;
}
}
}
return OKOK;
}
/*--------------------------------------------------------------------*/
static long ANA2TSetValue(void *pData, SConnection *pCon, float fNew)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* calculation */
iRet = CalculateANA2T(self,pCon,fNew);
if(iRet != 1)
{
return iRet;
}
/* start them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->SetValue(self->toStart[i].pMot,pCon,
self->toStart[i].fTarget);
if(iRet != OKOK)
{
return iRet;
}
}
}
return OKOK;
}
/*-------------------------------------------------------------------------*/
static int A2THalt(void *pData)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* stop them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->Halt(self->toStart[i].pMot);
}
}
return OKOK;
}
/*-----------------------------------------------------------------------*/
static int A2TCheck(void *pData, float fNew, char *error, int iErrLen)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
SConnection *pDumCon = NULL;
assert(self);
pDumCon = SCCreateDummyConnection(pServ->pSics);
assert(pDumCon);
/* calculation */
iRet = CalculateAMORE(self,pDumCon,fNew);
SCDeleteConnection(pDumCon);
if(iRet != 1)
{
return iRet;
}
/* check them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->CheckLimits(self->toStart[i].pMot,
self->toStart[i].fTarget,
error,iErrLen);
if(iRet != 1)
{
return iRet;
}
}
}
return 1;
}
/*-------------------------------------------------------------------*/
static int ANA2TCheck(void *pData, float fNew, char *error, int iErrLen)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
SConnection *pDumCon = NULL;
assert(self);
pDumCon = SCCreateDummyConnection(pServ->pSics);
assert(pDumCon);
/* calculation */
iRet = CalculateANA2T(self,pDumCon,fNew);
SCDeleteConnection(pDumCon);
if(iRet != 1)
{
return iRet;
}
/* check them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->CheckLimits(self->toStart[i].pMot,
self->toStart[i].fTarget,
error,iErrLen);
if(iRet != 1)
{
return iRet;
}
}
}
return 1;
}
/*------------------------------------------------------------------------*/
static int A2TStatus(void *pData, SConnection *pCon)
{
int i, iRet;
pIDrivable pDriv = NULL;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* check them all */
for(i = 0; i < MAXMOT; i++)
{
if(self->toStart[i].pMot == NULL)
{
continue;
}
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
self->toStart[i].pMot,DRIVEID);
if(pDriv != NULL)
{
iRet = pDriv->CheckStatus(self->toStart[i].pMot,pCon);
if( (iRet != OKOK) && (iRet != HWIdle) )
{
return iRet;
}
}
}
return iRet;
}
/*------------------------------------------------------------------------*/
static float A2TGetValue(void *pData, SConnection *pCon)
{
float fVal, fMOM, fResult;
int iRet;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* get COM */
iRet = MotorGetSoftPosition(self->aEngine[MOTCOM], pCon, &fVal);
if(!iRet)
{
return -9999.99;
}
/* get MOM */
iRet = MotorGetSoftPosition(self->aEngine[MOTMOM], pCon, &fMOM);
if(!iRet)
{
return -9999.99;
}
/* retrocalculate 2 theta */
fResult = fVal + 2*fMOM;
return fResult;
}
/*------------------------------------------------------------------------*/
static float ANA2TGetValue(void *pData, SConnection *pCon)
{
float fVal, fMOM, fResult;
int iRet;
pAmor2T self = (pAmor2T) pData;
assert(self);
/* get AOM */
iRet = MotorGetSoftPosition(self->aEngine[MOTAOM], pCon, &fVal);
if(!iRet)
{
return -9999.99;
}
return 2. * fVal;
}
/*-----------------------------------------------------------------------*/
static void *A2TGetInterface(void *pData, int iID)
{
pAmor2T self = (pAmor2T) pData;
assert(self);
if(iID == DRIVEID)
{
return self->pDriv;
}
return NULL;
}
/*------------------------------------------------------------------------*/
static int A2TSave(void *pData, char *name, FILE *fd)
{
int i;
pAmor2T self = (pAmor2T) pData;
assert(self);
fprintf(fd,"%s detectord %f \n", name, ObVal(self->aParameter,PARDS));
fprintf(fd,"%s sampleh %f \n", name, ObVal(self->aParameter,PARDH));
fprintf(fd,"%s d4d %f \n", name, ObVal(self->aParameter,PARDD4));
fprintf(fd,"%s d5d %f \n", name, ObVal(self->aParameter,PARDD5));
fprintf(fd,"%s interrupt %f \n", name, ObVal(self->aParameter,PARINT));
fprintf(fd,"%s detectorh %f \n", name, ObVal(self->aParameter,PARDDH));
fprintf(fd,"%s d4h %f \n", name, ObVal(self->aParameter,PARD4H));
fprintf(fd,"%s d5h %f \n", name, ObVal(self->aParameter,PARD5H));
fprintf(fd,"%s anah %f \n", name, ObVal(self->aParameter,PARANA));
fprintf(fd,"%s anad %f \n", name, ObVal(self->aParameter,PARADIS));
fprintf(fd,"%s anaflag %f \n", name, ObVal(self->aParameter,ANAFLAG));
fprintf(fd,"%s c2h %f \n", name, ObVal(self->aParameter,PARDDD));
fprintf(fd,"%s aomconst %f \n", name, ObVal(self->aParameter,PARAOM));
fprintf(fd,"%s diaflag %f \n", name, ObVal(self->aParameter,DIAFLAG));
return 1;
}
/*------------------------------------------------------------------------*/
static void A2TList(pAmor2T self, SConnection *pCon, char *name)
{
char pBueffel[132];
Tcl_DString tString;
assert(pCon);
assert(self);
Tcl_DStringInit(&tString);
sprintf(pBueffel,
"%s.detectord %f \n", name, ObVal(self->aParameter,PARDS));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.sampleh %f \n", name, ObVal(self->aParameter,PARDH));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.d4d %f \n", name, ObVal(self->aParameter,PARDD4));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.d5d %f \n", name, ObVal(self->aParameter,PARDD5));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.interrupt %f \n", name, ObVal(self->aParameter,PARINT));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.detectorh %f \n", name, ObVal(self->aParameter,PARDDH));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.d4h %f \n", name, ObVal(self->aParameter,PARD4H));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.d5h %f \n", name, ObVal(self->aParameter,PARD5H));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.anah %f \n", name, ObVal(self->aParameter,PARANA));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.anad %f \n", name, ObVal(self->aParameter,PARADIS));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.anaflag %f \n", name, ObVal(self->aParameter,ANAFLAG));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.c2h %f \n", name, ObVal(self->aParameter,PARDDD));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.aomconst %f \n", name, ObVal(self->aParameter,PARAOM));
Tcl_DStringAppend(&tString,pBueffel,-1);
sprintf(pBueffel,
"%s.diaflag %f \n", name, ObVal(self->aParameter,DIAFLAG));
Tcl_DStringAppend(&tString,pBueffel,-1);
SCWrite(pCon,Tcl_DStringValue(&tString),eValue);
Tcl_DStringFree(&tString);
}
/*------------------------------------------------------------------------*/
static void A2TKill(void *pData)
{
pAmor2T self = (pAmor2T) pData;
if(self == NULL)
return;
if(self->pDes)
DeleteDescriptor(self->pDes);
if(self->pDriv)
free(self->pDriv);
if(self->aParameter)
ObParDelete(self->aParameter);
free(self);
}
/*--------------------------------------------------------------------------
Initialization: All is done from the Factory function. This takes an Tcl
array as parameter which is supposed to hold the names of all motors.
This must fail if one of the motors cannot be accessed.
--------------------------------------------------------------------------*/
int Amor2TFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pAmor2T pNew, pAOM = NULL;
int i, iRet;
char pBueffel[512];
const char *pMot = NULL;
if(argc < 4)
{
SCWrite(pCon,
"ERROR: Insufficient number of arguments to Amor2tFactory",
eError);
return 0;
}
/* allocate space ..............*/
pNew = (pAmor2T)malloc(sizeof(Amor2T));
if(!pNew)
{
SCWrite(pCon,"ERROR: out of memory in Amor2TFactory",eError);
return 0;
}
memset(pNew,0,sizeof(Amor2T));
pNew->pDes = CreateDescriptor("Amor2T");
pNew->aParameter = ObParCreate(MAXPAR);
pNew->pDriv = CreateDrivableInterface();
if( (!pNew->pDes) || (!pNew->aParameter) || (!pNew->pDriv) )
{
SCWrite(pCon,"ERROR: out of memory in Amor2TFactory",eError);
A2TKill(pNew);
return 0;
}
/* find the motors*/
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"mom",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for mom motr found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTMOM] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTMOM])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"som",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for som motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTSOM] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTSOM])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"coz",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for coz motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTCOZ] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTCOZ])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"cox",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for cox motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTCOX] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTCOX])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"stz",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for stz motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTSTZ] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTSTZ])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"soz",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for soz motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTSOZ] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTSOZ])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"d4b",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for d4b motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTD4B] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTD4B])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"d5b",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for d5b motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTD5B] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTD5B])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"com",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for com motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTCOM] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTCOM])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"aoz",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for aoz motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTAOZ] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTAOZ])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"aom",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for aom motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTAOM] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTAOM])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"c3z",TCL_GLOBAL_ONLY);
if(!pMot)
{
SCWrite(pCon,"ERROR: no value for c3z motor found",eError);
A2TKill(pNew);
return 0;
}
pNew->aEngine[MOTC3Z] = FindMotor(pSics,(char *)pMot);
if(!pNew->aEngine[MOTC3Z])
{
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
/* initialize parameters */
ObParInit(pNew->aParameter,PARDS,"detectord",1400.,usMugger);
ObParInit(pNew->aParameter,PARDH,"sampleh",50.,usMugger);
ObParInit(pNew->aParameter,PARDD4,"d4d",100.,usMugger);
ObParInit(pNew->aParameter,PARDD5,"d5d",200.,usMugger);
ObParInit(pNew->aParameter,PARINT,"interrupt",0.,usMugger);
ObParInit(pNew->aParameter,PARDDH,"detectorh",40.,usMugger);
ObParInit(pNew->aParameter,PARD4H,"d4h",40.,usMugger);
ObParInit(pNew->aParameter,PARD5H,"d5h",400.,usMugger);
ObParInit(pNew->aParameter,PARANA,"anah",400.,usMugger);
ObParInit(pNew->aParameter,PARADIS,"anad",600.,usMugger);
ObParInit(pNew->aParameter,ANAFLAG,"anaflag",-1.,usMugger);
ObParInit(pNew->aParameter,PARDDD,"c2h",100.,usMugger);
ObParInit(pNew->aParameter,PARAOM,"aomconst",3.,usMugger);
ObParInit(pNew->aParameter,DIAFLAG,"diaflag",1.,usMugger);
/* initialize interfaces */
pNew->pDes->GetInterface = A2TGetInterface;
pNew->pDes->SaveStatus = A2TSave;
pNew->pDriv->Halt = A2THalt;
pNew->pDriv->CheckLimits = A2TCheck;
pNew->pDriv->SetValue = A2TSetValue;
pNew->pDriv->CheckStatus = A2TStatus;
pNew->pDriv->GetValue = A2TGetValue;
/* copy data structure for second command for aom2t */
pAOM = (pAmor2T)malloc(sizeof(Amor2T));
if(!pAOM)
{
A2TKill(pNew);
SCWrite(pCon,"ERROR: out of memory in Amor2TFactory",eError);
return 0;
}
memcpy(pAOM,pNew,sizeof(Amor2T));
pAOM->pDriv = CreateDrivableInterface();
pAOM->pDes = CreateDescriptor("Amor2T");
if(!pAOM->pDriv || !pAOM->pDes )
{
A2TKill(pNew);
SCWrite(pCon,"ERROR: out of memory in Amor2TFactory",eError);
return 0;
}
/* set modified interface functions */
pAOM->pDes->GetInterface = A2TGetInterface;
pAOM->pDriv->Halt = A2THalt;
pAOM->pDriv->CheckLimits = ANA2TCheck;
pAOM->pDriv->SetValue = ANA2TSetValue;
pAOM->pDriv->GetValue = ANA2TGetValue;
pAOM->pDriv->CheckStatus = A2TStatus;
/* install commands */
iRet = AddCommand(pSics,argv[1],
Amor2TAction,A2TKill,pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s NOT created",
argv[1]);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
iRet = AddCommand(pSics,argv[3],
Amor2TAction,free,pAOM);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s NOT created",
argv[1]);
SCWrite(pCon,pBueffel,eError);
A2TKill(pNew);
return 0;
}
return 1;
}
/*----------------------------------------------------------------------*/
int Amor2TAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pAmor2T self = (pAmor2T)pData;
char pBueffel[256];
float fVal;
double dVal;
ObPar *pPar = NULL;
int iRet;
assert(self);
if(argc > 1)
{
strtolower(argv[1]);
/* deal with list */
if(strcmp(argv[1],"list") == 0)
{
A2TList(self,pCon,argv[0]);
return 1;
}
/* otherwise it should be a parameter command */
if(argc >= 3)
{
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: failed to convert %s to number",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = ObParSet(self->aParameter,argv[0],argv[1],(float)dVal,pCon);
if(iRet)
{
SCSendOK(pCon);
}
return iRet;
}
else
{
pPar = ObParFind(self->aParameter,argv[1]);
if(!pPar)
{
sprintf(pBueffel,"ERROR: parameter %s NOT found",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
sprintf(pBueffel,"%s.%s = %f",argv[0],pPar->name, pPar->fVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
else
{
fVal = self->pDriv->GetValue(self,pCon);
sprintf(pBueffel," %s = %f", argv[0], fVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}