- First working version of the TRICS collision protection module
This commit is contained in:
115
Busy.c
Normal file
115
Busy.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*------------------------------------------------------------------------
|
||||
A busy flag module for SICS.
|
||||
|
||||
Mark Koennecke, July 2002
|
||||
-------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
typedef struct BUSY__ {
|
||||
pObjectDescriptor pDes;
|
||||
int iBusy;
|
||||
}Busy;
|
||||
/*---------------------------------------------------------------------*/
|
||||
busyPtr makeBusy(void){
|
||||
busyPtr result = NULL;
|
||||
|
||||
result = (busyPtr)malloc(sizeof(Busy));
|
||||
if(!result){
|
||||
return NULL;
|
||||
}
|
||||
result->pDes = CreateDescriptor("BusyFlag");
|
||||
if(!result->pDes){
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
result->iBusy = 0;
|
||||
return result;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
void killBusy(void *self){
|
||||
busyPtr busy;
|
||||
if(self != NULL){
|
||||
busy = (busyPtr)self;
|
||||
if(busy->pDes != NULL){
|
||||
DeleteDescriptor(busy->pDes);
|
||||
}
|
||||
free(busy);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
void incrementBusy(busyPtr self){
|
||||
assert(self != NULL);
|
||||
self->iBusy++;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void decrementBusy(busyPtr self){
|
||||
assert(self != NULL);
|
||||
self->iBusy--;
|
||||
if(self->iBusy < 0){
|
||||
self->iBusy = 0;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void clearBusy(busyPtr self){
|
||||
assert(self != NULL);
|
||||
self->iBusy = 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void setBusy(busyPtr self, int val){
|
||||
assert(self != NULL);
|
||||
self->iBusy = val;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int isBusy(busyPtr self){
|
||||
assert(self != NULL);
|
||||
return self->iBusy;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int BusyAction(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
busyPtr self = NULL;
|
||||
char pBuffer[80];
|
||||
|
||||
self = (busyPtr)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
if(argc > 1){
|
||||
strtolower(argv[1]);
|
||||
if(usUser < SCGetRights(pCon)){
|
||||
SCWrite(pCon,"ERROR: no privilege to manipulate busy flag",eError);
|
||||
return 0;
|
||||
}
|
||||
if(strcmp(argv[1],"incr") == 0){
|
||||
incrementBusy(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"decr") == 0){
|
||||
decrementBusy(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"clear") == 0){
|
||||
clearBusy(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(pBuffer,"Busy = %d", isBusy(self));
|
||||
SCWrite(pCon,pBuffer,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
busyPtr findBusy(SicsInterp *pInter){
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
pCom = FindCommand(pInter,"busy");
|
||||
if(pCom != NULL){
|
||||
return (busyPtr)pCom->pData;
|
||||
}
|
||||
}
|
||||
|
||||
|
28
Busy.h
Normal file
28
Busy.h
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
A busy flag module for SICS.
|
||||
|
||||
Mark Koennecke, July 2002
|
||||
-------------------------------------------------------------------------*/
|
||||
#ifndef SICSBUSY
|
||||
#define SICSBUSY
|
||||
|
||||
|
||||
typedef struct BUSY__ *busyPtr;
|
||||
|
||||
busyPtr makeBusy(void);
|
||||
void killBusy(void *self);
|
||||
|
||||
void incrementBusy(busyPtr self);
|
||||
void decrementBusy(busyPtr self);
|
||||
void clearBusy(busyPtr self);
|
||||
void setBusy(busyPtr self, int val);
|
||||
|
||||
int isBusy(busyPtr self);
|
||||
|
||||
int BusyAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
busyPtr findBusy(SicsInterp *pInter);
|
||||
#endif
|
||||
|
41
Busy.w
Normal file
41
Busy.w
Normal file
@ -0,0 +1,41 @@
|
||||
\subsection{Busy}
|
||||
This class implements a busy flag which should be set when the interpreter
|
||||
is busy doing something, like scanning for instance. The primary use
|
||||
is for AMOR where operations are possible while writing data. This is
|
||||
not caught by the normal device executor logic. In the long run, this
|
||||
should become the standard way to control access to the
|
||||
interpreter. In order to ensure access control, a test for the busy
|
||||
flag is included into the SCMatchRights procedure. The busy flag is
|
||||
installed into the interpreter.
|
||||
|
||||
@o Busy.h @{
|
||||
/*------------------------------------------------------------------------
|
||||
A busy flag module for SICS.
|
||||
|
||||
Mark Koennecke, July 2002
|
||||
-------------------------------------------------------------------------*/
|
||||
#ifndef SICSBUSY
|
||||
#define SICSBUSY
|
||||
|
||||
|
||||
typedef struct BUSY__ *busyPtr;
|
||||
|
||||
busyPtr makeBusy(void);
|
||||
void killBusy(void *self);
|
||||
|
||||
void incrementBusy(busyPtr self);
|
||||
void decrementBusy(busyPtr self);
|
||||
void clearBusy(busyPtr self);
|
||||
void setBusy(busyPtr self, int val);
|
||||
|
||||
int isBusy(busyPtr self);
|
||||
|
||||
int BusyAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
busyPtr findBusy(SicsInterp *pInter);
|
||||
#endif
|
||||
|
||||
@}
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -49,7 +49,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \
|
||||
tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \
|
||||
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
|
||||
polterwrite.o fourlib.o
|
||||
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o
|
||||
|
||||
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
|
19
SCinter.c
19
SCinter.c
@ -51,9 +51,13 @@
|
||||
#include "splitter.h"
|
||||
#include "servlog.h"
|
||||
#include "macro.h"
|
||||
#include "interface.h"
|
||||
#include "obdes.h"
|
||||
|
||||
/* M.Z. */
|
||||
#include "definealias.h"
|
||||
|
||||
|
||||
#define MAXLEN 256
|
||||
#define MAXPAR 100
|
||||
|
||||
@ -545,4 +549,19 @@ extern char *SkipSpace(char *pPtr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void *FindDrivable(SicsInterp *pSics, char *name){
|
||||
pIDrivable pDriv;
|
||||
pDummy pDum = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
pCom = FindCommand(pSics,name);
|
||||
if(pCom != NULL){
|
||||
pDum = (pDummy)pCom->pData;
|
||||
if(pDum != NULL){
|
||||
return pDum->pDescriptor->GetInterface(pDum,DRIVEID);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -133,5 +133,13 @@ typedef struct __SINTER
|
||||
*/
|
||||
void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
FindDrivable tries to find Drivable object by the name given. Returns a
|
||||
pointer to the drivable interface in the case of success, NULL in
|
||||
case of failure. In order to save me fixing header files the pointer must
|
||||
be cast to the drivable interface pointer.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
void *FindDrivable(SicsInterp *pics, char *name);
|
||||
#endif
|
||||
|
||||
|
375
anticollider.c
Normal file
375
anticollider.c
Normal file
@ -0,0 +1,375 @@
|
||||
/*----------------------------------------------------------------------
|
||||
This is the implementation 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
|
||||
------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <tcl.h>
|
||||
#include "fortify.h"
|
||||
#include "lld.h"
|
||||
#include "motreglist.h"
|
||||
#include "anticollider.i"
|
||||
#include "anticollider.h"
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
As there should be only one AntiCollider in a system, I use a static
|
||||
pointer to the AntiCollider here in order to facilitate access.
|
||||
Otherwise more complex mechanisms must be divised in order to pass this
|
||||
pointer into ColliderSetValue and ColliderCheckStatus
|
||||
----------------------------------------------------------------------*/
|
||||
static pAntiCollider myCollider = NULL;
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
the replacement function for the motor's drivable interface SetValue
|
||||
function. It enters the new target into the motor list.
|
||||
---------------------------------------------------------------------*/
|
||||
static long ReplacementSetValue(void *pData, SConnection *pCon, float fTarget){
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
assert(myCollider != NULL);
|
||||
|
||||
pMot = FindMotFromDataStructure(myCollider->motorList,pData);
|
||||
if(pMot != NULL){
|
||||
SetRegMotTarget(pMot,fTarget);
|
||||
myCollider->isDirty = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------
|
||||
The replacement CheckStatus function for controlled motors.
|
||||
Start AntiCollider if not running and finish. Rest of work done by
|
||||
AntiCollider.
|
||||
-----------------------------------------------------------------------*/
|
||||
static int ReplacementCheckStatus(void *pData, SConnection *pCon){
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
assert(myCollider != NULL);
|
||||
|
||||
if(myCollider->isDirty == 1){
|
||||
myCollider->isDirty = 0;
|
||||
StartDevice(pServ->pExecutor,
|
||||
"anticollider",
|
||||
myCollider->pDes,
|
||||
myCollider,
|
||||
pCon,
|
||||
77.77);
|
||||
return HWIdle;
|
||||
} else {
|
||||
return HWIdle;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
The collider SetValue function
|
||||
-------------------------------------------------------------------------*/
|
||||
static long ColliderSetValue(void *pData, SConnection *pCon, float fTarget){
|
||||
pAntiCollider self = (pAntiCollider) pData;
|
||||
int iRet;
|
||||
pMotReg pMot = NULL;
|
||||
char pBueffel[80];
|
||||
char *ruenBuffer = NULL;
|
||||
|
||||
Tcl_DString command;
|
||||
|
||||
/*
|
||||
build command list
|
||||
*/
|
||||
if(self->colliderScript == NULL){
|
||||
SCWrite(pCon,"ERROR: no collider script defined",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Tcl_DStringInit(&command);
|
||||
Tcl_DStringAppend(&command,self->colliderScript,-1);
|
||||
iRet = LLDnodePtr2First(self->motorList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(self->motorList,&pMot);
|
||||
if(pMot != NULL){
|
||||
if(pMot->iActive){
|
||||
CreateTargetString(pMot,pBueffel);
|
||||
Tcl_DStringAppend(&command, pBueffel,-1);
|
||||
pMot->iActive = 0;
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->motorList);
|
||||
}
|
||||
printf("%s\n", Tcl_DStringValue(&command));
|
||||
|
||||
/*
|
||||
kill old collider sequence
|
||||
*/
|
||||
LLDdelete(self->sequenceList);
|
||||
self->sequenceList = LLDcreate(sizeof(Sequence));
|
||||
self->level = 0;
|
||||
|
||||
/*
|
||||
evaluate colliderScript
|
||||
*/
|
||||
iRet = Tcl_Eval(pServ->pSics->pTcl,Tcl_DStringValue(&command));
|
||||
if(iRet != TCL_OK){
|
||||
SCWrite(pCon,"ERROR: Movement not possible or bad collider script",eError);
|
||||
/*
|
||||
SCWrite(pCon,pServ->pSics->pTcl->result,eError);
|
||||
*/
|
||||
SCSetInterrupt(pCon,eAbortOperation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
we are set
|
||||
*/
|
||||
Tcl_DStringFree(&command);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------
|
||||
The Collider CheckStatus function
|
||||
-----------------------------------------------------------------------*/
|
||||
static int ColliderCheckStatus(void *pData, SConnection *pCon){
|
||||
int count = 0;
|
||||
pAntiCollider self = (pAntiCollider) pData;
|
||||
|
||||
assert(self);
|
||||
|
||||
if(SCGetInterrupt(pCon) != eContinue){
|
||||
return HWIdle;
|
||||
}
|
||||
|
||||
count = CheckAllMotors(self->motorList,pCon);
|
||||
if(count == 0){
|
||||
self->level++;
|
||||
count = StartLevel(self->level,
|
||||
self->sequenceList,
|
||||
self->motorList,
|
||||
pCon);
|
||||
if(count == 0){
|
||||
/*
|
||||
no more levels. All done
|
||||
*/
|
||||
return HWIdle;
|
||||
} else {
|
||||
return HWBusy;
|
||||
}
|
||||
} else {
|
||||
return HWBusy;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------
|
||||
Most of these are dummies........
|
||||
-----------------------------------------------------------------------*/
|
||||
static int ColliderHalt(void *pData){
|
||||
StopExe(pServ->pExecutor,"all");
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int ColliderLimits(void *self, float fVal, char *error,
|
||||
int iErren){
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static float ColliderGetValue(void *self, SConnection *pCon){
|
||||
return 77.77;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int StartLevel(int level, int sequenceList, int motorList, SConnection *pCon){
|
||||
Sequence seq;
|
||||
pMotReg pMot = NULL;
|
||||
int iRet;
|
||||
int count = 0;
|
||||
char pBueffel[132];
|
||||
|
||||
iRet = LLDnodePtr2First(sequenceList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(sequenceList,&seq);
|
||||
if(seq.level == level){
|
||||
pMot = FindMotEntry(motorList,seq.pMotor);
|
||||
if(pMot){
|
||||
StartRegMot(pMot,pCon,seq.target);
|
||||
count++;
|
||||
} else {
|
||||
sprintf(pBueffel,"ERROR: motor %s, requested from anticollider script",
|
||||
seq.pMotor);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
SCWrite(pCon,"ERROR: motor NOT found, fix script!",eError);
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(sequenceList);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void ListSequence(int sequenceList, SConnection *pCon){
|
||||
Sequence seq;
|
||||
int iRet;
|
||||
char pBueffel[132];
|
||||
|
||||
SCWrite(pCon,"level motor target",eValue);
|
||||
iRet = LLDnodePtr2First(sequenceList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(sequenceList,&seq);
|
||||
sprintf(pBueffel,"%d %s %f",seq.level,seq.pMotor,seq.target);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
iRet = LLDnodePtr2Next(sequenceList);
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void *ColliderGetInterface(void *pData, int iID) {
|
||||
pAntiCollider self = NULL;
|
||||
|
||||
self = (pAntiCollider)pData;
|
||||
assert(self);
|
||||
|
||||
if(iID == DRIVEID){
|
||||
return self->pDriv;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
void KillCollider(void *pData){
|
||||
pAntiCollider self = (pAntiCollider)pData;
|
||||
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
if(self->pDes != NULL){
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if(self->pDriv != NULL){
|
||||
free(self->pDriv);
|
||||
}
|
||||
if(self->colliderScript != NULL){
|
||||
free(self->colliderScript);
|
||||
}
|
||||
if(self->motorList > 0){
|
||||
KillMotList(self->motorList);
|
||||
}
|
||||
if(self->sequenceList > 0){
|
||||
LLDdelete(self->sequenceList);
|
||||
}
|
||||
free(self);
|
||||
myCollider = NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int AntiColliderFactory(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData,
|
||||
int argc, char *argv[]){
|
||||
|
||||
myCollider = (pAntiCollider)malloc(sizeof(AntiCollider));
|
||||
if(myCollider == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory when generating AntiCollider",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(myCollider,0,sizeof(AntiCollider));
|
||||
|
||||
myCollider->pDes = CreateDescriptor("AntiCollider");
|
||||
myCollider->pDriv = CreateDrivableInterface();
|
||||
if(!myCollider->pDes || !myCollider->pDriv){
|
||||
KillCollider(myCollider);
|
||||
SCWrite(pCon,"ERROR: out of memory when generating AntiCollider",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
myCollider->pDes->GetInterface = ColliderGetInterface;
|
||||
myCollider->pDriv->Halt = ColliderHalt;
|
||||
myCollider->pDriv->CheckLimits = ColliderLimits;
|
||||
myCollider->pDriv->SetValue = ColliderSetValue;
|
||||
myCollider->pDriv->CheckStatus = ColliderCheckStatus;
|
||||
myCollider->pDriv->GetValue = ColliderGetValue;
|
||||
|
||||
myCollider->motorList = LLDcreate(sizeof(void *));
|
||||
myCollider->sequenceList = LLDcreate(sizeof(Sequence));
|
||||
|
||||
AddCommand(pSics,"anticollision",AntiColliderAction,
|
||||
KillCollider,
|
||||
myCollider);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int AntiColliderAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData,
|
||||
int argc, char *argv[]){
|
||||
pAntiCollider self = (pAntiCollider)pData;
|
||||
Sequence seq;
|
||||
char pBueffel[256];
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
if(argc > 1){
|
||||
if(strcmp(argv[1],"clear") == 0){
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
LLDdelete(self->sequenceList);
|
||||
self->sequenceList = LLDcreate(sizeof(Sequence));
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"list") == 0){
|
||||
ListSequence(self->sequenceList,pCon);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,"ERROR : insufficient number of arguments to anticollision",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"script") == 0){
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
if(self->colliderScript != NULL){
|
||||
free(self->colliderScript);
|
||||
}
|
||||
self->colliderScript = strdup(argv[2]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"register") == 0){
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
if(FindDrivable(pSics,argv[2]) == NULL){
|
||||
sprintf(pBueffel,"ERROR: %s is NOT drivable, cannot register",argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
pMot = RegisterMotor(argv[2],pSics,
|
||||
ReplacementSetValue,
|
||||
ReplacementCheckStatus);
|
||||
if(pMot){
|
||||
LLDnodeAppendFrom(self->motorList,&pMot);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: out of memory registering motor",eError);
|
||||
return 0;
|
||||
}
|
||||
} else if(strcmp(argv[1],"add") == 0){
|
||||
if(argc < 5){
|
||||
SCWrite(pCon,
|
||||
"ERROR: InsUfficient number of arguments to anticollicion add",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
seq.level = atoi(argv[2]);
|
||||
strncpy(seq.pMotor,argv[3],79);
|
||||
seq.target = atof(argv[4]);
|
||||
LLDnodeAppendFrom(self->sequenceList,&seq);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
SCWrite(pCon,"ERROR: anticollider command not understood",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
25
anticollider.h
Normal file
25
anticollider.h
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
||||
int AntiColliderFactory(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData,
|
||||
int argc, char *argv[]);
|
||||
int AntiColliderAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
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
|
||||
|
||||
|
||||
|
||||
@}
|
2
danu.dat
2
danu.dat
@ -1,3 +1,3 @@
|
||||
226
|
||||
231
|
||||
NEVER, EVER modify or delete this file
|
||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
23
devexec.c
23
devexec.c
@ -7,6 +7,7 @@
|
||||
Substantial rewrite: Mark Koennecke, February 1997
|
||||
revised: Mark Koennecke, June 1997
|
||||
revised for use with tasker: Mark Koennecke, September 1997
|
||||
Locking added: Mark Koennecke, August 2002
|
||||
|
||||
Copyright:
|
||||
|
||||
@ -103,6 +104,7 @@
|
||||
int iEnd;
|
||||
long lTask;
|
||||
pTaskMan pTask;
|
||||
int iLock;
|
||||
} ExeList;
|
||||
|
||||
static pExeList pExecutor = NULL;
|
||||
@ -136,6 +138,7 @@
|
||||
pRes->iStatus = DEVDONE;
|
||||
pRes->pTask = pTask;
|
||||
pRes->lTask = -1;
|
||||
pRes->iLock = 0;
|
||||
return pRes;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -181,6 +184,11 @@
|
||||
{
|
||||
self->pOwner = pCon;
|
||||
}
|
||||
if(self->iLock == 1)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: instrument is locked",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* well create a new entry */
|
||||
self->iStop = 0;
|
||||
@ -478,7 +486,7 @@
|
||||
/* do nothing if not running */
|
||||
if(self->lTask < 0)
|
||||
{
|
||||
printf("Wait4Success finished very, very badly\n");
|
||||
printf("Nothing to wait for....\n");
|
||||
return self->iStatus;
|
||||
}
|
||||
|
||||
@ -749,6 +757,7 @@
|
||||
self->iEnd = 1;
|
||||
self->lTask = -1;
|
||||
self->iRun = 0;
|
||||
self->iLock = 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
@ -922,6 +931,18 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void LockDeviceExecutor(pExeList self)
|
||||
{
|
||||
assert(self);
|
||||
self->iLock = 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void UnlockDeviceExecutor(pExeList self)
|
||||
{
|
||||
assert(self);
|
||||
self->iLock = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
17
devexec.h
17
devexec.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 184 "devexec.w"
|
||||
#line 195 "devexec.w"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||
char *name);
|
||||
|
||||
#line 228 "devexec.w"
|
||||
#line 239 "devexec.w"
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
||||
|
||||
|
||||
#line 230 "devexec.w"
|
||||
#line 241 "devexec.w"
|
||||
|
||||
|
||||
/*
|
||||
@ -115,7 +115,7 @@
|
||||
int ContinueExecution(pExeList self);
|
||||
|
||||
|
||||
#line 248 "devexec.w"
|
||||
#line 259 "devexec.w"
|
||||
|
||||
/*-------------------------- Commands ------------------------------------*/
|
||||
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
@ -137,6 +137,15 @@
|
||||
connection with non blocking operation such as motors started
|
||||
with run.
|
||||
*/
|
||||
/*--------------------------- Locking ---------------------------------*/
|
||||
|
||||
#line 183 "devexec.w"
|
||||
|
||||
void LockDeviceExecutor(pExeList self);
|
||||
void UnlockDeviceExecutor(pExeList self);
|
||||
|
||||
|
||||
#line 281 "devexec.w"
|
||||
|
||||
/* -------------------------- Executor management -------------------------*/
|
||||
|
||||
|
28
devexec.tex
28
devexec.tex
@ -212,6 +212,29 @@ take care of invoking the apropriate commands on all registered counting
|
||||
devices.
|
||||
|
||||
|
||||
\subsubsection{Locking the Device Executor}
|
||||
In some instances user code may wish to lock the device executor. An
|
||||
example is a long running data saving operation. In order to do this
|
||||
two functions are provided:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$devlock {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ void LockDeviceExecutor(pExeList self);@\\
|
||||
\mbox{}\verb@ void UnlockDeviceExecutor(pExeList self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\subsubsection{The Rest}
|
||||
The rest of the interface includes initialisation and deletion routines
|
||||
and some access routines. With the devexec being such an important system
|
||||
@ -219,7 +242,7 @@ component a function {\bf GetExecutor} is provided which retrieves a pointer
|
||||
to the global SICS device executor.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
\verb@"devexec.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
@ -308,7 +331,8 @@ to the global SICS device executor.
|
||||
\mbox{}\verb@ connection with non blocking operation such as motors started@\\
|
||||
\mbox{}\verb@ with run.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*--------------------------- Locking ---------------------------------*/@\\
|
||||
\mbox{}\verb@ @$\langle$devlock {\footnotesize ?}$\rangle$\verb@ @\\
|
||||
\mbox{}\verb@/* -------------------------- Executor management -------------------------*/@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ pExeList GetExecutor(void);@\\
|
||||
|
14
devexec.w
14
devexec.w
@ -175,6 +175,17 @@ take care of invoking the apropriate commands on all registered counting
|
||||
devices.
|
||||
|
||||
|
||||
\subsubsection{Locking the Device Executor}
|
||||
In some instances user code may wish to lock the device executor. An
|
||||
example is a long running data saving operation. In order to do this
|
||||
two functions are provided:
|
||||
|
||||
@d devlock @{
|
||||
void LockDeviceExecutor(pExeList self);
|
||||
void UnlockDeviceExecutor(pExeList self);
|
||||
|
||||
@}
|
||||
|
||||
\subsubsection{The Rest}
|
||||
The rest of the interface includes initialisation and deletion routines
|
||||
and some access routines. With the devexec being such an important system
|
||||
@ -266,7 +277,8 @@ to the global SICS device executor.
|
||||
connection with non blocking operation such as motors started
|
||||
with run.
|
||||
*/
|
||||
|
||||
/*--------------------------- Locking ---------------------------------*/
|
||||
@<devlock@>
|
||||
/* -------------------------- Executor management -------------------------*/
|
||||
|
||||
pExeList GetExecutor(void);
|
||||
|
4
drive.c
4
drive.c
@ -237,7 +237,7 @@
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------
|
||||
This is meant to be called specially from DriveWrapper at at stage when
|
||||
This is meant to be called specially from DriveWrapper at a stage when
|
||||
we already know, that name is a drivable motor. Thus no error checking
|
||||
is performed. Do not use this in any other context!!!!
|
||||
*/
|
||||
@ -253,7 +253,7 @@
|
||||
char pBueffel[132];
|
||||
|
||||
/*
|
||||
treat motors separatetly in order to correct for zero points
|
||||
treat motors separately in order to correct for zero points
|
||||
Sighh.........
|
||||
*/
|
||||
pMot = FindMotor(pSics,name);
|
||||
|
1
event.h
1
event.h
@ -26,6 +26,7 @@
|
||||
|
||||
#define VALUECHANGE 0
|
||||
#define MOTDRIVE 1
|
||||
#define MOTEND 13
|
||||
#define MONITOR 2
|
||||
#define ROTSTART 3
|
||||
#define ROTMOVE 4
|
||||
|
26
interface.h
26
interface.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 345 "interface.w"
|
||||
#line 346 "interface.w"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
I N T E R F A C E S
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
/* ----------------------- The drivable interface -----------------------*/
|
||||
|
||||
#line 116 "interface.w"
|
||||
#line 117 "interface.w"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -44,14 +44,14 @@
|
||||
pIDrivable GetDrivableInterface(void *pObject);
|
||||
|
||||
|
||||
#line 370 "interface.w"
|
||||
#line 371 "interface.w"
|
||||
|
||||
|
||||
pIDrivable CreateDrivableInterface(void);
|
||||
|
||||
/* ------------------------ The countable interface ---------------------*/
|
||||
|
||||
#line 176 "interface.w"
|
||||
#line 177 "interface.w"
|
||||
|
||||
typedef struct {
|
||||
int ID;
|
||||
@ -68,23 +68,23 @@
|
||||
pICountable GetCountableInterface(void *pObject);
|
||||
|
||||
|
||||
#line 375 "interface.w"
|
||||
#line 376 "interface.w"
|
||||
|
||||
|
||||
pICountable CreateCountableInterface(void);
|
||||
|
||||
/* ------------------------- The CallBack Interface --------------------*/
|
||||
|
||||
#line 229 "interface.w"
|
||||
#line 230 "interface.w"
|
||||
|
||||
typedef void (*KillFuncIT)(void *pData);
|
||||
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
||||
void *pUserData);
|
||||
|
||||
#line 380 "interface.w"
|
||||
#line 381 "interface.w"
|
||||
|
||||
|
||||
#line 251 "interface.w"
|
||||
#line 252 "interface.w"
|
||||
|
||||
typedef struct __ICallBack *pICallBack;
|
||||
|
||||
@ -99,11 +99,11 @@
|
||||
int RemoveCallback(pICallBack pInterface, long iID);
|
||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||
|
||||
#line 381 "interface.w"
|
||||
#line 382 "interface.w"
|
||||
|
||||
/*---------------------- The Environment Interface --------------------*/
|
||||
|
||||
#line 309 "interface.w"
|
||||
#line 310 "interface.w"
|
||||
|
||||
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
||||
typedef struct {
|
||||
@ -113,13 +113,13 @@
|
||||
int (*HandleError)(void *self);
|
||||
} EVInterface, *pEVInterface;
|
||||
|
||||
#line 383 "interface.w"
|
||||
#line 384 "interface.w"
|
||||
|
||||
|
||||
#line 335 "interface.w"
|
||||
#line 336 "interface.w"
|
||||
|
||||
pEVInterface CreateEVInterface(void);
|
||||
|
||||
#line 384 "interface.w"
|
||||
#line 385 "interface.w"
|
||||
|
||||
#endif
|
||||
|
@ -60,6 +60,7 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pObjectDescriptor CreateDescriptor(char *name);@\\
|
||||
\mbox{}\verb@ void DeleteDescriptor(pObjectDescriptor self);@\\
|
||||
\mbox{}\verb@ pObjectDescriptor FindDescriptor(void *pData);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*============================================================================@\\
|
||||
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
|
||||
|
@ -55,6 +55,7 @@ Let's start with the objectdescriptor:
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pObjectDescriptor CreateDescriptor(char *name);
|
||||
void DeleteDescriptor(pObjectDescriptor self);
|
||||
pObjectDescriptor FindDescriptor(void *pData);
|
||||
|
||||
/*============================================================================
|
||||
Objects which do not carry data need a dummy descriptor. Otherwise
|
||||
|
64
motor.c
64
motor.c
@ -9,6 +9,7 @@
|
||||
Mark Koennecke, November 1996
|
||||
revised: Mark Koennecke, June 1997
|
||||
callback added: Mark Koennecke, August 1997
|
||||
endscript facility added: Mark Koennecke, August 2002
|
||||
|
||||
Copyright:
|
||||
|
||||
@ -195,7 +196,9 @@
|
||||
SCSetInterrupt(pCon,iVal);
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------------
|
||||
Refactor
|
||||
--------------------------------------------------------------------------*/
|
||||
static int MotorStatus(void *sulf, SConnection *pCon)
|
||||
{
|
||||
float fHard;
|
||||
@ -250,6 +253,8 @@
|
||||
/* motor thinks he is done */
|
||||
if( (iRet == OKOK) || (iRet == HWIdle))
|
||||
{
|
||||
MotorGetSoftPosition(self,pCon,&sCall.fVal);
|
||||
InvokeCallBack(self->pCall, MOTEND, &sCall);
|
||||
self->fPosition = fHard;
|
||||
if(absf(fHard - self->fTarget) > ObVal(self->ParArray,PREC))
|
||||
{
|
||||
@ -342,8 +347,7 @@
|
||||
iRetry = 0;
|
||||
return iRet;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
|
||||
/*---------------------------------------------------------------------------*/ pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
|
||||
{
|
||||
pMotor pM = NULL;
|
||||
|
||||
@ -380,6 +384,7 @@
|
||||
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
|
||||
pDriv->GetPosition(pDriv,&(pM->fPosition));
|
||||
pM->fTarget = pM->fPosition;
|
||||
pM->endScriptID = 0;
|
||||
|
||||
/* copy arguments */
|
||||
pM->pDriver = pDriv;
|
||||
@ -1027,7 +1032,32 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
SCWrite(pInfo->pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void KillScript(void *pData)
|
||||
{
|
||||
if(pData != NULL)
|
||||
{
|
||||
free(pData);
|
||||
}
|
||||
}
|
||||
/*------------------------ The endscript callback function ----------------*/
|
||||
static int EndScriptCallback(int iEvent, void *pEvent, void *pUser)
|
||||
{
|
||||
char *pScript = NULL;
|
||||
MotCallback *psCall;
|
||||
char pCommand[1024];
|
||||
int iRet;
|
||||
|
||||
assert(pEvent);
|
||||
assert(pUser);
|
||||
|
||||
psCall = (MotCallback *)pEvent;
|
||||
pScript = (char *)pUser;
|
||||
|
||||
sprintf(pCommand,"%s %f",pScript,psCall->fVal);
|
||||
iRet = Tcl_Eval(pServ->pSics->pTcl,pCommand);
|
||||
return iRet;
|
||||
}
|
||||
/*----------------------------------------------------------------------------
|
||||
The wrapper function for a motor. Commands currently supported are:
|
||||
|
||||
@ -1037,6 +1067,8 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
motorname reset : puts softlimits to default
|
||||
motorname interest : starts sending automatic
|
||||
notifications when driving
|
||||
motorname endscript : script to call when motor
|
||||
finishes driving
|
||||
-----------------------------------------------------------------------------*/
|
||||
int MotorAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -1122,7 +1154,6 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
DeleteTokenList(pList);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
|
||||
}
|
||||
else if(strcmp(pCurrent->text,"uninterest") == 0)
|
||||
{
|
||||
@ -1131,6 +1162,31 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
||||
DeleteTokenList(pList);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(pCurrent->text,"endscript") == 0) /* endscript */
|
||||
{
|
||||
if(!SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(self->endScriptID != 0)
|
||||
{
|
||||
RemoveCallback(self->pCall, self->endScriptID);
|
||||
self->endScriptID = 0;
|
||||
}
|
||||
pCurrent = pCurrent->pNext;
|
||||
if(!pCurrent)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: scriptname argument missing",eError);
|
||||
return 0;
|
||||
}
|
||||
self->endScriptID =
|
||||
RegisterCallback(self->pCall, MOTEND, EndScriptCallback,
|
||||
strdup(pCurrent->text), KillScript);
|
||||
SCRegister(pCon,pSics, self->pCall,self->endScriptID);
|
||||
DeleteTokenList(pList);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
else /* one of the parameter commands or error left now */
|
||||
{
|
||||
pName = pCurrent;
|
||||
|
1
motor.h
1
motor.h
@ -24,6 +24,7 @@
|
||||
MotorDriver *pDriver;
|
||||
float fTarget;
|
||||
float fPosition;
|
||||
long endScriptID;
|
||||
} Motor;
|
||||
typedef Motor *pMotor;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
125
motreg.c
Normal file
125
motreg.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
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
|
||||
-----------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "fortify.h"
|
||||
#include "motreg.h"
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
pMotReg RegisterMotor(char *name, SicsInterp *pSics,
|
||||
long (*NewSetValue)(void *pData, SConnection *pCon,
|
||||
float farget),
|
||||
int (*NewCheckStatus)(void *pData,SConnection *pCon) ){
|
||||
CommandList *pCom = NULL;
|
||||
pIDrivable pDriv = NULL;
|
||||
pMotReg pNew = NULL;
|
||||
|
||||
/*
|
||||
find motor data structures
|
||||
*/
|
||||
pCom = FindCommand(pSics,name);
|
||||
if(pCom == NULL){
|
||||
return NULL;
|
||||
}
|
||||
pDriv = GetDrivableInterface(pCom->pData);
|
||||
if(pDriv == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
everything seems OK. Allocate data structure and initialize
|
||||
*/
|
||||
pNew = (pMotReg)malloc(sizeof(MotReg));
|
||||
if(pNew == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew,0,sizeof(MotReg));
|
||||
|
||||
pNew->motorData = pCom->pData;
|
||||
pNew->motorName = strdup(name);
|
||||
pNew->originalSetValue = pDriv->SetValue;
|
||||
pNew->originalCheckStatus = pDriv->CheckStatus;
|
||||
pNew->iActive = 0;
|
||||
|
||||
pDriv->SetValue = NewSetValue;
|
||||
pDriv->CheckStatus = NewCheckStatus;
|
||||
|
||||
return pNew;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
void KillRegMot(void *pData){
|
||||
pMotReg self = (pMotReg)pData;
|
||||
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
if(self->motorName != NULL){
|
||||
free(self->motorName);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void SetRegMotTarget(pMotReg self, float fValue){
|
||||
assert(self);
|
||||
|
||||
self->targetPosition = fValue;
|
||||
self->iActive = 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void CreateTargetString(pMotReg self, char pBueffel[80]) {
|
||||
assert(self);
|
||||
|
||||
if(strlen(self->motorName) + 20 < 80) {
|
||||
sprintf(pBueffel," %s %12.4f ", self->motorName, self->targetPosition);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int RegMotMatch(pMotReg self, char *name){
|
||||
assert(self);
|
||||
if(strcmp(self->motorName, name) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
|
||||
int ret;
|
||||
long (*oldSet)(void *pmotorData, SConnection *pCon, float fValue);
|
||||
pIDrivable pDriv = NULL;
|
||||
|
||||
|
||||
assert(self);
|
||||
pDriv = GetDrivableInterface(self->motorData);
|
||||
assert(pDriv);
|
||||
oldSet = pDriv->SetValue;
|
||||
pDriv->SetValue = self->originalSetValue;
|
||||
ret = StartDevice(pServ->pExecutor, self->motorName,
|
||||
FindDescriptor(self->motorData),
|
||||
self->motorData,
|
||||
pCon,
|
||||
fValue);
|
||||
|
||||
pDriv->SetValue = oldSet;
|
||||
self->iActive = 1;
|
||||
return ret;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int CheckRegMot(pMotReg self, SConnection *pCon){
|
||||
int stat;
|
||||
|
||||
assert(self);
|
||||
stat = self->originalCheckStatus(self->motorData,pCon);
|
||||
if(stat != HWBusy){
|
||||
self->iActive = 0;
|
||||
}
|
||||
return stat;
|
||||
}
|
52
motreg.h
Normal file
52
motreg.h
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
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"
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
86
motreglist.c
Normal file
86
motreglist.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
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
|
||||
-------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "fortify.h"
|
||||
#include "lld.h"
|
||||
#include "motreglist.h"
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int MakeMotList(){
|
||||
return LLDcreate(sizeof(pMotReg));
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
pMotReg FindMotEntry(int iList, char *name){
|
||||
int iRet;
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(iList,&pMot);
|
||||
if(pMot != NULL){
|
||||
if(RegMotMatch(pMot,name)){
|
||||
return pMot;
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
pMotReg FindMotFromDataStructure(int iList, void *pData){
|
||||
int iRet;
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(iList,&pMot);
|
||||
if(pMot != NULL){
|
||||
if(pMot->motorData == pData){
|
||||
return pMot;
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int CheckAllMotors(int iList, SConnection *pCon){
|
||||
int iRet, count = 0;
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(iList,&pMot);
|
||||
if(pMot != NULL){
|
||||
CheckRegMot(pMot,pCon);
|
||||
if(pMot->iActive){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
void KillMotList(int iList){
|
||||
int iRet;
|
||||
pMotReg pMot = NULL;
|
||||
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0){
|
||||
LLDnodeDataTo(iList,&pMot);
|
||||
if(pMot != NULL){
|
||||
KillRegMot(pMot);
|
||||
}
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
LLDdelete(iList);
|
||||
}
|
27
motreglist.h
Normal file
27
motreglist.h
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
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"
|
||||
|
||||
|
||||
int MakeMotList();
|
||||
pMotReg FindMotEntry(int iList,char *name);
|
||||
pMotReg FindMotFromDataStructure(int iList, void *pData);
|
||||
int CheckAllMotors(int iList, SConnection *pCon);
|
||||
void KillMotList(int iList);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
8
nxamor.c
8
nxamor.c
@ -24,6 +24,7 @@
|
||||
#include "nxamor.h"
|
||||
#include "obpar.h"
|
||||
#include "motor.h"
|
||||
#include "status.h"
|
||||
|
||||
#define MAXMOT 13 /* must be same as in amor2t.c */
|
||||
#include "amor2t.i"
|
||||
@ -662,6 +663,7 @@ static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim,
|
||||
{
|
||||
char pBueffel[512], *pFile = NULL;
|
||||
int iRet, iFlag;
|
||||
Status oldStatus;
|
||||
|
||||
/*
|
||||
if arguments, check for psdsave
|
||||
@ -685,11 +687,17 @@ static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim,
|
||||
pFile = SNXMakeFileName(pSics,pCon);
|
||||
sprintf(pBueffel,"Writing file %s .....",pFile);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
|
||||
oldStatus = GetStatus();
|
||||
SetStatus(eWriting);
|
||||
LockDeviceExecutor(pServ->pExecutor);
|
||||
iRet = WriteAmorHeader(pFile,pCon);
|
||||
if(iRet)
|
||||
{
|
||||
iRet = WriteAmorTOF(pFile,pCon,pMeme);
|
||||
}
|
||||
SetStatus(oldStatus);
|
||||
UnlockDeviceExecutor(pServ->pExecutor);
|
||||
free(pFile);
|
||||
SCSendOK(pCon);
|
||||
return iRet;
|
||||
|
9
obdes.c
9
obdes.c
@ -133,3 +133,12 @@
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pObjectDescriptor FindDescriptor(void *pData)
|
||||
{
|
||||
pDummy pDum = NULL;
|
||||
|
||||
assert(pData);
|
||||
pDum = (pDummy)pData;
|
||||
return pDum->pDescriptor;
|
||||
}
|
||||
|
5
obdes.h
5
obdes.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 341 "interface.w"
|
||||
#line 342 "interface.w"
|
||||
|
||||
|
||||
#line 29 "interface.w"
|
||||
@ -32,6 +32,7 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pObjectDescriptor CreateDescriptor(char *name);
|
||||
void DeleteDescriptor(pObjectDescriptor self);
|
||||
pObjectDescriptor FindDescriptor(void *pData);
|
||||
|
||||
/*============================================================================
|
||||
Objects which do not carry data need a dummy descriptor. Otherwise
|
||||
@ -51,5 +52,5 @@ typedef struct {
|
||||
|
||||
#endif
|
||||
|
||||
#line 342 "interface.w"
|
||||
#line 343 "interface.w"
|
||||
|
||||
|
2
obpar.c
2
obpar.c
@ -167,7 +167,7 @@
|
||||
eStat = GetStatus();
|
||||
if(!((eStat == eEager) || (eStat == eBatch)) )
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: Cannot cahnge parameter while running");
|
||||
sprintf(pBueffel,"ERROR: Cannot change parameter while running");
|
||||
SCWrite(pCon, pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
3
ofac.c
3
ofac.c
@ -107,6 +107,7 @@
|
||||
#include "rs232controller.h"
|
||||
#include "lomax.h"
|
||||
#include "polterwrite.h"
|
||||
#include "anticollider.h"
|
||||
/*----------------------- Server options creation -------------------------*/
|
||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -289,6 +290,7 @@
|
||||
AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL);
|
||||
AddCommand(pInter,"MakeMaxDetector",LoMaxFactory,NULL,NULL);
|
||||
AddCommand(pInter,"PolterInstall",PolterInstall,NULL,NULL);
|
||||
AddCommand(pInter,"AntiCollisionInstall",AntiColliderFactory,NULL,NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void KillIniCommands(SicsInterp *pSics)
|
||||
@ -348,6 +350,7 @@
|
||||
RemoveCommand(pSics,"MakeRS232Controller");
|
||||
RemoveCommand(pSics,"MakeMaxDetector");
|
||||
RemoveCommand(pSics,"PolterInstall");
|
||||
RemoveCommand(pSics,"AntiColliderInstall");
|
||||
}
|
||||
|
||||
|
||||
|
@ -489,8 +489,8 @@ static int PoldiStart(pPolterdi self, SConnection *pCon)
|
||||
long lVal;
|
||||
|
||||
/* open everything again */
|
||||
NXopen(self->pFile,NXACC_RDWR,&hfil);
|
||||
if(!self->pFile)
|
||||
status = NXopen(self->pFile,NXACC_RDWR,&hfil);
|
||||
if(status != NX_OK)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
|
||||
return;
|
||||
|
1
sics.h
1
sics.h
@ -29,6 +29,7 @@
|
||||
#include "emon.h"
|
||||
#include "nserver.h"
|
||||
#include "servlog.h"
|
||||
|
||||
extern pServer pServ;
|
||||
|
||||
|
||||
|
101
sicsstatus.tcl
101
sicsstatus.tcl
@ -1,48 +1,75 @@
|
||||
a5l.length 80.000000
|
||||
flightpathlength 0.000000
|
||||
flightpathlength setAccess 1
|
||||
flightpath 0.000000
|
||||
flightpath setAccess 1
|
||||
delay 2500.000000
|
||||
delay setAccess 1
|
||||
hm CountMode timer
|
||||
hm preset 100.000000
|
||||
hm genbin 120.000000 35.000000 512
|
||||
hm init
|
||||
datafile focus-1001848.hdf
|
||||
datafile setAccess 3
|
||||
yfactor 1.420000
|
||||
yfactor setAccess 1
|
||||
xfactor 0.715000
|
||||
xfactor setAccess 1
|
||||
ps.listfile peaksearch.dat
|
||||
ps.listfile setAccess 2
|
||||
ps.scansteps 24
|
||||
ps.scansteps setAccess 2
|
||||
ps.scanpreset 1000000.000000
|
||||
ps.scanpreset setAccess 2
|
||||
ps.preset 1000.000000
|
||||
ps.preset setAccess 2
|
||||
ps.countmode monitor
|
||||
ps.countmode setAccess 2
|
||||
ps.cogcontour 0.200000
|
||||
ps.cogcontour setAccess 2
|
||||
ps.cogwindow 60
|
||||
ps.cogwindow setAccess 2
|
||||
ps.window 7
|
||||
ps.window setAccess 2
|
||||
ps.steepness 3
|
||||
ps.steepness setAccess 2
|
||||
ps.threshold 30
|
||||
ps.threshold setAccess 2
|
||||
ps.sttstep 3.000000
|
||||
ps.sttstep setAccess 2
|
||||
ps.sttend 70.000000
|
||||
ps.sttend setAccess 2
|
||||
ps.sttstart 5.000000
|
||||
ps.sttstart setAccess 2
|
||||
ps.omstep 3.000000
|
||||
ps.omstep setAccess 2
|
||||
ps.omend 30.000000
|
||||
ps.omend setAccess 2
|
||||
ps.omstart 0.000000
|
||||
ps.omstart setAccess 2
|
||||
ps.chistep 12.000000
|
||||
ps.chistep setAccess 2
|
||||
ps.chiend 180.000000
|
||||
ps.chiend setAccess 2
|
||||
ps.chistart 0.000000
|
||||
ps.chistart setAccess 2
|
||||
ps.phistep 3.000000
|
||||
ps.phistep setAccess 2
|
||||
ps.phiend 180.000000
|
||||
ps.phiend setAccess 2
|
||||
ps.phistart 0.000000
|
||||
ps.phistart setAccess 2
|
||||
hm3 CountMode timer
|
||||
hm3 preset 10.000000
|
||||
hm2 CountMode timer
|
||||
hm2 preset 3600.000000
|
||||
hm2 preset 10.000000
|
||||
hm1 CountMode timer
|
||||
hm1 preset 3600.000000
|
||||
dbfile UNKNOWN
|
||||
dbfile setAccess 2
|
||||
# Motor th
|
||||
th sign 1.000000
|
||||
th SoftZero 0.000000
|
||||
th SoftLowerLim 4.000000
|
||||
th SoftUpperLim 113.000000
|
||||
th Fixed -1.000000
|
||||
th InterruptMode 0.000000
|
||||
th AccessCode 2.000000
|
||||
hm1 preset 10.000000
|
||||
#Crystallographic Settings
|
||||
hkl lambda 1.179000
|
||||
hkl setub -0.017880 -0.074923 0.028280 -0.007008 -0.036800 -0.057747 0.160912 -0.009928 0.000627
|
||||
hkl hm 0
|
||||
det3dist 300.000000
|
||||
det3dist setAccess 1
|
||||
detdist3 0.000000
|
||||
detdist3 setAccess 1
|
||||
det3zeroy 128.000000
|
||||
det3zeroy setAccess 1
|
||||
det3zerox 128.000000
|
||||
det3zerox setAccess 1
|
||||
det2dist 300.000000
|
||||
det2dist setAccess 1
|
||||
detdist2 0.000000
|
||||
detdist2 setAccess 1
|
||||
det2zeroy 128.000000
|
||||
det2zeroy setAccess 1
|
||||
det2zerox 128.000000
|
||||
det2zerox setAccess 1
|
||||
det1dist 300.000000
|
||||
det1dist setAccess 1
|
||||
detdist1 0.000000
|
||||
detdist1 setAccess 1
|
||||
det1zeroy 128.000000
|
||||
det1zeroy setAccess 1
|
||||
det1zerox 128.000000
|
||||
@ -71,7 +98,7 @@ stt AccessCode 2.000000
|
||||
ch sign 1.000000
|
||||
ch SoftZero 0.000000
|
||||
ch SoftLowerLim 0.000000
|
||||
ch SoftUpperLim 212.000000
|
||||
ch SoftUpperLim 190.000000
|
||||
ch Fixed -1.000000
|
||||
ch InterruptMode 0.000000
|
||||
ch AccessCode 1.000000
|
||||
@ -127,7 +154,7 @@ phi AccessCode 2.000000
|
||||
chi sign 1.000000
|
||||
chi SoftZero 0.000000
|
||||
chi SoftLowerLim 0.000000
|
||||
chi SoftUpperLim 212.000000
|
||||
chi SoftUpperLim 190.000000
|
||||
chi Fixed -1.000000
|
||||
chi InterruptMode 0.000000
|
||||
chi AccessCode 1.000000
|
||||
@ -149,8 +176,6 @@ twotheta InterruptMode 0.000000
|
||||
twotheta AccessCode 2.000000
|
||||
lastscancommand cscan a4 10. .1 10 5
|
||||
lastscancommand setAccess 2
|
||||
banana CountMode timer
|
||||
banana preset 100.000000
|
||||
sample_mur 0.000000
|
||||
sample_mur setAccess 2
|
||||
email UNKNOWN
|
||||
@ -428,13 +453,11 @@ a1 SoftUpperLim 120.000000
|
||||
a1 Fixed -1.000000
|
||||
a1 InterruptMode 0.000000
|
||||
a1 AccessCode 2.000000
|
||||
batchroot /data/koenneck/src/sics
|
||||
batchroot setAccess 2
|
||||
user Uwe Filges
|
||||
user setAccess 2
|
||||
sample D20 30K SNP Okt 2001 GS
|
||||
sample setAccess 2
|
||||
title snp gs apd 30K
|
||||
title endtest called with 23.000000 :Driving:
|
||||
title setAccess 2
|
||||
starttime 2002-04-23 10:49:18
|
||||
starttime 2002-08-07 08:09:45
|
||||
starttime setAccess 2
|
||||
|
2
status.c
2
status.c
@ -59,6 +59,7 @@
|
||||
"Driving",
|
||||
"Running",
|
||||
"Running a scan",
|
||||
"Writing data",
|
||||
"Processing a batch file",
|
||||
"Halted",
|
||||
"Dead",
|
||||
@ -74,6 +75,7 @@
|
||||
"driving",
|
||||
"running",
|
||||
"scanning",
|
||||
"writing",
|
||||
"batch",
|
||||
"halt",
|
||||
"dead",
|
||||
|
Reference in New Issue
Block a user