- 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 \
|
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 \
|
tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \
|
||||||
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.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
|
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
19
SCinter.c
19
SCinter.c
@ -51,9 +51,13 @@
|
|||||||
#include "splitter.h"
|
#include "splitter.h"
|
||||||
#include "servlog.h"
|
#include "servlog.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "obdes.h"
|
||||||
|
|
||||||
/* M.Z. */
|
/* M.Z. */
|
||||||
#include "definealias.h"
|
#include "definealias.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAXLEN 256
|
#define MAXLEN 256
|
||||||
#define MAXPAR 100
|
#define MAXPAR 100
|
||||||
|
|
||||||
@ -545,4 +549,19 @@ extern char *SkipSpace(char *pPtr);
|
|||||||
}
|
}
|
||||||
return NULL;
|
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);
|
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
|
#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
|
NEVER, EVER modify or delete this file
|
||||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
27
devexec.c
27
devexec.c
@ -7,6 +7,7 @@
|
|||||||
Substantial rewrite: Mark Koennecke, February 1997
|
Substantial rewrite: Mark Koennecke, February 1997
|
||||||
revised: Mark Koennecke, June 1997
|
revised: Mark Koennecke, June 1997
|
||||||
revised for use with tasker: Mark Koennecke, September 1997
|
revised for use with tasker: Mark Koennecke, September 1997
|
||||||
|
Locking added: Mark Koennecke, August 2002
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
||||||
@ -103,6 +104,7 @@
|
|||||||
int iEnd;
|
int iEnd;
|
||||||
long lTask;
|
long lTask;
|
||||||
pTaskMan pTask;
|
pTaskMan pTask;
|
||||||
|
int iLock;
|
||||||
} ExeList;
|
} ExeList;
|
||||||
|
|
||||||
static pExeList pExecutor = NULL;
|
static pExeList pExecutor = NULL;
|
||||||
@ -136,6 +138,7 @@
|
|||||||
pRes->iStatus = DEVDONE;
|
pRes->iStatus = DEVDONE;
|
||||||
pRes->pTask = pTask;
|
pRes->pTask = pTask;
|
||||||
pRes->lTask = -1;
|
pRes->lTask = -1;
|
||||||
|
pRes->iLock = 0;
|
||||||
return pRes;
|
return pRes;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -181,7 +184,12 @@
|
|||||||
{
|
{
|
||||||
self->pOwner = pCon;
|
self->pOwner = pCon;
|
||||||
}
|
}
|
||||||
|
if(self->iLock == 1)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: instrument is locked",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* well create a new entry */
|
/* well create a new entry */
|
||||||
self->iStop = 0;
|
self->iStop = 0;
|
||||||
pNew = CreateDevEntry(pDes,pData,fNew,name);
|
pNew = CreateDevEntry(pDes,pData,fNew,name);
|
||||||
@ -478,7 +486,7 @@
|
|||||||
/* do nothing if not running */
|
/* do nothing if not running */
|
||||||
if(self->lTask < 0)
|
if(self->lTask < 0)
|
||||||
{
|
{
|
||||||
printf("Wait4Success finished very, very badly\n");
|
printf("Nothing to wait for....\n");
|
||||||
return self->iStatus;
|
return self->iStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,6 +757,7 @@
|
|||||||
self->iEnd = 1;
|
self->iEnd = 1;
|
||||||
self->lTask = -1;
|
self->lTask = -1;
|
||||||
self->iRun = 0;
|
self->iRun = 0;
|
||||||
|
self->iLock = 0;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
@ -922,7 +931,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
void LockDeviceExecutor(pExeList self)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
self->iLock = 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
void UnlockDeviceExecutor(pExeList self)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
self->iLock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
19
devexec.h
19
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,
|
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name);
|
char *name);
|
||||||
|
|
||||||
#line 228 "devexec.w"
|
#line 239 "devexec.w"
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -73,7 +73,7 @@
|
|||||||
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
|
||||||
|
|
||||||
|
|
||||||
#line 230 "devexec.w"
|
#line 241 "devexec.w"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,7 +115,7 @@
|
|||||||
int ContinueExecution(pExeList self);
|
int ContinueExecution(pExeList self);
|
||||||
|
|
||||||
|
|
||||||
#line 248 "devexec.w"
|
#line 259 "devexec.w"
|
||||||
|
|
||||||
/*-------------------------- Commands ------------------------------------*/
|
/*-------------------------- Commands ------------------------------------*/
|
||||||
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
@ -137,7 +137,16 @@
|
|||||||
connection with non blocking operation such as motors started
|
connection with non blocking operation such as motors started
|
||||||
with run.
|
with run.
|
||||||
*/
|
*/
|
||||||
|
/*--------------------------- Locking ---------------------------------*/
|
||||||
|
|
||||||
|
#line 183 "devexec.w"
|
||||||
|
|
||||||
|
void LockDeviceExecutor(pExeList self);
|
||||||
|
void UnlockDeviceExecutor(pExeList self);
|
||||||
|
|
||||||
|
|
||||||
|
#line 281 "devexec.w"
|
||||||
|
|
||||||
/* -------------------------- Executor management -------------------------*/
|
/* -------------------------- Executor management -------------------------*/
|
||||||
|
|
||||||
pExeList GetExecutor(void);
|
pExeList GetExecutor(void);
|
||||||
|
28
devexec.tex
28
devexec.tex
@ -212,6 +212,29 @@ take care of invoking the apropriate commands on all registered counting
|
|||||||
devices.
|
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}
|
\subsubsection{The Rest}
|
||||||
The rest of the interface includes initialisation and deletion routines
|
The rest of the interface includes initialisation and deletion routines
|
||||||
and some access routines. With the devexec being such an important system
|
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.
|
to the global SICS device executor.
|
||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap4}
|
\begin{minipage}{\linewidth} \label{scrap5}
|
||||||
\verb@"devexec.h"@ {\footnotesize ? }$\equiv$
|
\verb@"devexec.h"@ {\footnotesize ? }$\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\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@ connection with non blocking operation such as motors started@\\
|
||||||
\mbox{}\verb@ with run.@\\
|
\mbox{}\verb@ with run.@\\
|
||||||
\mbox{}\verb@ */@\\
|
\mbox{}\verb@ */@\\
|
||||||
\mbox{}\verb@ @\\
|
\mbox{}\verb@/*--------------------------- Locking ---------------------------------*/@\\
|
||||||
|
\mbox{}\verb@ @$\langle$devlock {\footnotesize ?}$\rangle$\verb@ @\\
|
||||||
\mbox{}\verb@/* -------------------------- Executor management -------------------------*/@\\
|
\mbox{}\verb@/* -------------------------- Executor management -------------------------*/@\\
|
||||||
\mbox{}\verb@ @\\
|
\mbox{}\verb@ @\\
|
||||||
\mbox{}\verb@ pExeList GetExecutor(void);@\\
|
\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.
|
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}
|
\subsubsection{The Rest}
|
||||||
The rest of the interface includes initialisation and deletion routines
|
The rest of the interface includes initialisation and deletion routines
|
||||||
and some access routines. With the devexec being such an important system
|
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
|
connection with non blocking operation such as motors started
|
||||||
with run.
|
with run.
|
||||||
*/
|
*/
|
||||||
|
/*--------------------------- Locking ---------------------------------*/
|
||||||
|
@<devlock@>
|
||||||
/* -------------------------- Executor management -------------------------*/
|
/* -------------------------- Executor management -------------------------*/
|
||||||
|
|
||||||
pExeList GetExecutor(void);
|
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
|
we already know, that name is a drivable motor. Thus no error checking
|
||||||
is performed. Do not use this in any other context!!!!
|
is performed. Do not use this in any other context!!!!
|
||||||
*/
|
*/
|
||||||
@ -253,7 +253,7 @@
|
|||||||
char pBueffel[132];
|
char pBueffel[132];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
treat motors separatetly in order to correct for zero points
|
treat motors separately in order to correct for zero points
|
||||||
Sighh.........
|
Sighh.........
|
||||||
*/
|
*/
|
||||||
pMot = FindMotor(pSics,name);
|
pMot = FindMotor(pSics,name);
|
||||||
|
1
event.h
1
event.h
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#define VALUECHANGE 0
|
#define VALUECHANGE 0
|
||||||
#define MOTDRIVE 1
|
#define MOTDRIVE 1
|
||||||
|
#define MOTEND 13
|
||||||
#define MONITOR 2
|
#define MONITOR 2
|
||||||
#define ROTSTART 3
|
#define ROTSTART 3
|
||||||
#define ROTMOVE 4
|
#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
|
I N T E R F A C E S
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
/* ----------------------- The drivable interface -----------------------*/
|
/* ----------------------- The drivable interface -----------------------*/
|
||||||
|
|
||||||
#line 116 "interface.w"
|
#line 117 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -44,14 +44,14 @@
|
|||||||
pIDrivable GetDrivableInterface(void *pObject);
|
pIDrivable GetDrivableInterface(void *pObject);
|
||||||
|
|
||||||
|
|
||||||
#line 370 "interface.w"
|
#line 371 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pIDrivable CreateDrivableInterface(void);
|
pIDrivable CreateDrivableInterface(void);
|
||||||
|
|
||||||
/* ------------------------ The countable interface ---------------------*/
|
/* ------------------------ The countable interface ---------------------*/
|
||||||
|
|
||||||
#line 176 "interface.w"
|
#line 177 "interface.w"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ID;
|
int ID;
|
||||||
@ -68,23 +68,23 @@
|
|||||||
pICountable GetCountableInterface(void *pObject);
|
pICountable GetCountableInterface(void *pObject);
|
||||||
|
|
||||||
|
|
||||||
#line 375 "interface.w"
|
#line 376 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pICountable CreateCountableInterface(void);
|
pICountable CreateCountableInterface(void);
|
||||||
|
|
||||||
/* ------------------------- The CallBack Interface --------------------*/
|
/* ------------------------- The CallBack Interface --------------------*/
|
||||||
|
|
||||||
#line 229 "interface.w"
|
#line 230 "interface.w"
|
||||||
|
|
||||||
typedef void (*KillFuncIT)(void *pData);
|
typedef void (*KillFuncIT)(void *pData);
|
||||||
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
||||||
void *pUserData);
|
void *pUserData);
|
||||||
|
|
||||||
#line 380 "interface.w"
|
#line 381 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 251 "interface.w"
|
#line 252 "interface.w"
|
||||||
|
|
||||||
typedef struct __ICallBack *pICallBack;
|
typedef struct __ICallBack *pICallBack;
|
||||||
|
|
||||||
@ -99,11 +99,11 @@
|
|||||||
int RemoveCallback(pICallBack pInterface, long iID);
|
int RemoveCallback(pICallBack pInterface, long iID);
|
||||||
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
int RemoveCallback2(pICallBack pInterface, void *pUserData);
|
||||||
|
|
||||||
#line 381 "interface.w"
|
#line 382 "interface.w"
|
||||||
|
|
||||||
/*---------------------- The Environment Interface --------------------*/
|
/*---------------------- The Environment Interface --------------------*/
|
||||||
|
|
||||||
#line 309 "interface.w"
|
#line 310 "interface.w"
|
||||||
|
|
||||||
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -113,13 +113,13 @@
|
|||||||
int (*HandleError)(void *self);
|
int (*HandleError)(void *self);
|
||||||
} EVInterface, *pEVInterface;
|
} EVInterface, *pEVInterface;
|
||||||
|
|
||||||
#line 383 "interface.w"
|
#line 384 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 335 "interface.w"
|
#line 336 "interface.w"
|
||||||
|
|
||||||
pEVInterface CreateEVInterface(void);
|
pEVInterface CreateEVInterface(void);
|
||||||
|
|
||||||
#line 384 "interface.w"
|
#line 385 "interface.w"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,6 +60,7 @@ $\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@ pObjectDescriptor CreateDescriptor(char *name);@\\
|
\mbox{}\verb@ pObjectDescriptor CreateDescriptor(char *name);@\\
|
||||||
\mbox{}\verb@ void DeleteDescriptor(pObjectDescriptor self);@\\
|
\mbox{}\verb@ void DeleteDescriptor(pObjectDescriptor self);@\\
|
||||||
|
\mbox{}\verb@ pObjectDescriptor FindDescriptor(void *pData);@\\
|
||||||
\mbox{}\verb@ @\\
|
\mbox{}\verb@ @\\
|
||||||
\mbox{}\verb@/*============================================================================@\\
|
\mbox{}\verb@/*============================================================================@\\
|
||||||
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
|
\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);
|
pObjectDescriptor CreateDescriptor(char *name);
|
||||||
void DeleteDescriptor(pObjectDescriptor self);
|
void DeleteDescriptor(pObjectDescriptor self);
|
||||||
|
pObjectDescriptor FindDescriptor(void *pData);
|
||||||
|
|
||||||
/*============================================================================
|
/*============================================================================
|
||||||
Objects which do not carry data need a dummy descriptor. Otherwise
|
Objects which do not carry data need a dummy descriptor. Otherwise
|
||||||
|
66
motor.c
66
motor.c
@ -9,6 +9,7 @@
|
|||||||
Mark Koennecke, November 1996
|
Mark Koennecke, November 1996
|
||||||
revised: Mark Koennecke, June 1997
|
revised: Mark Koennecke, June 1997
|
||||||
callback added: Mark Koennecke, August 1997
|
callback added: Mark Koennecke, August 1997
|
||||||
|
endscript facility added: Mark Koennecke, August 2002
|
||||||
|
|
||||||
Copyright:
|
Copyright:
|
||||||
|
|
||||||
@ -195,7 +196,9 @@
|
|||||||
SCSetInterrupt(pCon,iVal);
|
SCSetInterrupt(pCon,iVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------
|
||||||
|
Refactor
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
static int MotorStatus(void *sulf, SConnection *pCon)
|
static int MotorStatus(void *sulf, SConnection *pCon)
|
||||||
{
|
{
|
||||||
float fHard;
|
float fHard;
|
||||||
@ -250,6 +253,8 @@
|
|||||||
/* motor thinks he is done */
|
/* motor thinks he is done */
|
||||||
if( (iRet == OKOK) || (iRet == HWIdle))
|
if( (iRet == OKOK) || (iRet == HWIdle))
|
||||||
{
|
{
|
||||||
|
MotorGetSoftPosition(self,pCon,&sCall.fVal);
|
||||||
|
InvokeCallBack(self->pCall, MOTEND, &sCall);
|
||||||
self->fPosition = fHard;
|
self->fPosition = fHard;
|
||||||
if(absf(fHard - self->fTarget) > ObVal(self->ParArray,PREC))
|
if(absf(fHard - self->fTarget) > ObVal(self->ParArray,PREC))
|
||||||
{
|
{
|
||||||
@ -342,8 +347,7 @@
|
|||||||
iRetry = 0;
|
iRetry = 0;
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/ pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
|
||||||
pMotor MotorInit(char *drivername, char *name, MotorDriver *pDriv)
|
|
||||||
{
|
{
|
||||||
pMotor pM = NULL;
|
pMotor pM = NULL;
|
||||||
|
|
||||||
@ -380,6 +384,7 @@
|
|||||||
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
|
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
|
||||||
pDriv->GetPosition(pDriv,&(pM->fPosition));
|
pDriv->GetPosition(pDriv,&(pM->fPosition));
|
||||||
pM->fTarget = pM->fPosition;
|
pM->fTarget = pM->fPosition;
|
||||||
|
pM->endScriptID = 0;
|
||||||
|
|
||||||
/* copy arguments */
|
/* copy arguments */
|
||||||
pM->pDriver = pDriv;
|
pM->pDriver = pDriv;
|
||||||
@ -1027,7 +1032,32 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
SCWrite(pInfo->pCon,pBueffel,eValue);
|
SCWrite(pInfo->pCon,pBueffel,eValue);
|
||||||
return 1;
|
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:
|
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 reset : puts softlimits to default
|
||||||
motorname interest : starts sending automatic
|
motorname interest : starts sending automatic
|
||||||
notifications when driving
|
notifications when driving
|
||||||
|
motorname endscript : script to call when motor
|
||||||
|
finishes driving
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
int MotorAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int MotorAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -1122,7 +1154,6 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(strcmp(pCurrent->text,"uninterest") == 0)
|
else if(strcmp(pCurrent->text,"uninterest") == 0)
|
||||||
{
|
{
|
||||||
@ -1131,6 +1162,31 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
|
|||||||
DeleteTokenList(pList);
|
DeleteTokenList(pList);
|
||||||
return 1;
|
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 */
|
else /* one of the parameter commands or error left now */
|
||||||
{
|
{
|
||||||
pName = pCurrent;
|
pName = pCurrent;
|
||||||
|
1
motor.h
1
motor.h
@ -24,6 +24,7 @@
|
|||||||
MotorDriver *pDriver;
|
MotorDriver *pDriver;
|
||||||
float fTarget;
|
float fTarget;
|
||||||
float fPosition;
|
float fPosition;
|
||||||
|
long endScriptID;
|
||||||
} Motor;
|
} Motor;
|
||||||
typedef Motor *pMotor;
|
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 "nxamor.h"
|
||||||
#include "obpar.h"
|
#include "obpar.h"
|
||||||
#include "motor.h"
|
#include "motor.h"
|
||||||
|
#include "status.h"
|
||||||
|
|
||||||
#define MAXMOT 13 /* must be same as in amor2t.c */
|
#define MAXMOT 13 /* must be same as in amor2t.c */
|
||||||
#include "amor2t.i"
|
#include "amor2t.i"
|
||||||
@ -662,6 +663,7 @@ static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim,
|
|||||||
{
|
{
|
||||||
char pBueffel[512], *pFile = NULL;
|
char pBueffel[512], *pFile = NULL;
|
||||||
int iRet, iFlag;
|
int iRet, iFlag;
|
||||||
|
Status oldStatus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if arguments, check for psdsave
|
if arguments, check for psdsave
|
||||||
@ -685,11 +687,17 @@ static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim,
|
|||||||
pFile = SNXMakeFileName(pSics,pCon);
|
pFile = SNXMakeFileName(pSics,pCon);
|
||||||
sprintf(pBueffel,"Writing file %s .....",pFile);
|
sprintf(pBueffel,"Writing file %s .....",pFile);
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
|
||||||
|
oldStatus = GetStatus();
|
||||||
|
SetStatus(eWriting);
|
||||||
|
LockDeviceExecutor(pServ->pExecutor);
|
||||||
iRet = WriteAmorHeader(pFile,pCon);
|
iRet = WriteAmorHeader(pFile,pCon);
|
||||||
if(iRet)
|
if(iRet)
|
||||||
{
|
{
|
||||||
iRet = WriteAmorTOF(pFile,pCon,pMeme);
|
iRet = WriteAmorTOF(pFile,pCon,pMeme);
|
||||||
}
|
}
|
||||||
|
SetStatus(oldStatus);
|
||||||
|
UnlockDeviceExecutor(pServ->pExecutor);
|
||||||
free(pFile);
|
free(pFile);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return iRet;
|
return iRet;
|
||||||
|
9
obdes.c
9
obdes.c
@ -133,3 +133,12 @@
|
|||||||
}
|
}
|
||||||
return 0;
|
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"
|
#line 29 "interface.w"
|
||||||
@ -32,6 +32,7 @@
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
pObjectDescriptor CreateDescriptor(char *name);
|
pObjectDescriptor CreateDescriptor(char *name);
|
||||||
void DeleteDescriptor(pObjectDescriptor self);
|
void DeleteDescriptor(pObjectDescriptor self);
|
||||||
|
pObjectDescriptor FindDescriptor(void *pData);
|
||||||
|
|
||||||
/*============================================================================
|
/*============================================================================
|
||||||
Objects which do not carry data need a dummy descriptor. Otherwise
|
Objects which do not carry data need a dummy descriptor. Otherwise
|
||||||
@ -51,5 +52,5 @@ typedef struct {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#line 342 "interface.w"
|
#line 343 "interface.w"
|
||||||
|
|
||||||
|
2
obpar.c
2
obpar.c
@ -167,7 +167,7 @@
|
|||||||
eStat = GetStatus();
|
eStat = GetStatus();
|
||||||
if(!((eStat == eEager) || (eStat == eBatch)) )
|
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);
|
SCWrite(pCon, pBueffel,eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
3
ofac.c
3
ofac.c
@ -107,6 +107,7 @@
|
|||||||
#include "rs232controller.h"
|
#include "rs232controller.h"
|
||||||
#include "lomax.h"
|
#include "lomax.h"
|
||||||
#include "polterwrite.h"
|
#include "polterwrite.h"
|
||||||
|
#include "anticollider.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -289,6 +290,7 @@
|
|||||||
AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL);
|
AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeMaxDetector",LoMaxFactory,NULL,NULL);
|
AddCommand(pInter,"MakeMaxDetector",LoMaxFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"PolterInstall",PolterInstall,NULL,NULL);
|
AddCommand(pInter,"PolterInstall",PolterInstall,NULL,NULL);
|
||||||
|
AddCommand(pInter,"AntiCollisionInstall",AntiColliderFactory,NULL,NULL);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void KillIniCommands(SicsInterp *pSics)
|
static void KillIniCommands(SicsInterp *pSics)
|
||||||
@ -348,6 +350,7 @@
|
|||||||
RemoveCommand(pSics,"MakeRS232Controller");
|
RemoveCommand(pSics,"MakeRS232Controller");
|
||||||
RemoveCommand(pSics,"MakeMaxDetector");
|
RemoveCommand(pSics,"MakeMaxDetector");
|
||||||
RemoveCommand(pSics,"PolterInstall");
|
RemoveCommand(pSics,"PolterInstall");
|
||||||
|
RemoveCommand(pSics,"AntiColliderInstall");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,8 +489,8 @@ static int PoldiStart(pPolterdi self, SConnection *pCon)
|
|||||||
long lVal;
|
long lVal;
|
||||||
|
|
||||||
/* open everything again */
|
/* open everything again */
|
||||||
NXopen(self->pFile,NXACC_RDWR,&hfil);
|
status = NXopen(self->pFile,NXACC_RDWR,&hfil);
|
||||||
if(!self->pFile)
|
if(status != NX_OK)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
|
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
|
||||||
return;
|
return;
|
||||||
|
1
sics.h
1
sics.h
@ -29,6 +29,7 @@
|
|||||||
#include "emon.h"
|
#include "emon.h"
|
||||||
#include "nserver.h"
|
#include "nserver.h"
|
||||||
#include "servlog.h"
|
#include "servlog.h"
|
||||||
|
|
||||||
extern pServer pServ;
|
extern pServer pServ;
|
||||||
|
|
||||||
|
|
||||||
|
101
sicsstatus.tcl
101
sicsstatus.tcl
@ -1,48 +1,75 @@
|
|||||||
a5l.length 80.000000
|
yfactor 1.420000
|
||||||
flightpathlength 0.000000
|
yfactor setAccess 1
|
||||||
flightpathlength setAccess 1
|
xfactor 0.715000
|
||||||
flightpath 0.000000
|
xfactor setAccess 1
|
||||||
flightpath setAccess 1
|
ps.listfile peaksearch.dat
|
||||||
delay 2500.000000
|
ps.listfile setAccess 2
|
||||||
delay setAccess 1
|
ps.scansteps 24
|
||||||
hm CountMode timer
|
ps.scansteps setAccess 2
|
||||||
hm preset 100.000000
|
ps.scanpreset 1000000.000000
|
||||||
hm genbin 120.000000 35.000000 512
|
ps.scanpreset setAccess 2
|
||||||
hm init
|
ps.preset 1000.000000
|
||||||
datafile focus-1001848.hdf
|
ps.preset setAccess 2
|
||||||
datafile setAccess 3
|
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 CountMode timer
|
||||||
hm2 preset 3600.000000
|
hm2 preset 10.000000
|
||||||
hm1 CountMode timer
|
hm1 CountMode timer
|
||||||
hm1 preset 3600.000000
|
hm1 preset 10.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
|
|
||||||
#Crystallographic Settings
|
#Crystallographic Settings
|
||||||
hkl lambda 1.179000
|
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 setub -0.017880 -0.074923 0.028280 -0.007008 -0.036800 -0.057747 0.160912 -0.009928 0.000627
|
||||||
hkl hm 0
|
hkl hm 0
|
||||||
det3dist 300.000000
|
detdist3 0.000000
|
||||||
det3dist setAccess 1
|
detdist3 setAccess 1
|
||||||
det3zeroy 128.000000
|
det3zeroy 128.000000
|
||||||
det3zeroy setAccess 1
|
det3zeroy setAccess 1
|
||||||
det3zerox 128.000000
|
det3zerox 128.000000
|
||||||
det3zerox setAccess 1
|
det3zerox setAccess 1
|
||||||
det2dist 300.000000
|
detdist2 0.000000
|
||||||
det2dist setAccess 1
|
detdist2 setAccess 1
|
||||||
det2zeroy 128.000000
|
det2zeroy 128.000000
|
||||||
det2zeroy setAccess 1
|
det2zeroy setAccess 1
|
||||||
det2zerox 128.000000
|
det2zerox 128.000000
|
||||||
det2zerox setAccess 1
|
det2zerox setAccess 1
|
||||||
det1dist 300.000000
|
detdist1 0.000000
|
||||||
det1dist setAccess 1
|
detdist1 setAccess 1
|
||||||
det1zeroy 128.000000
|
det1zeroy 128.000000
|
||||||
det1zeroy setAccess 1
|
det1zeroy setAccess 1
|
||||||
det1zerox 128.000000
|
det1zerox 128.000000
|
||||||
@ -71,7 +98,7 @@ stt AccessCode 2.000000
|
|||||||
ch sign 1.000000
|
ch sign 1.000000
|
||||||
ch SoftZero 0.000000
|
ch SoftZero 0.000000
|
||||||
ch SoftLowerLim 0.000000
|
ch SoftLowerLim 0.000000
|
||||||
ch SoftUpperLim 212.000000
|
ch SoftUpperLim 190.000000
|
||||||
ch Fixed -1.000000
|
ch Fixed -1.000000
|
||||||
ch InterruptMode 0.000000
|
ch InterruptMode 0.000000
|
||||||
ch AccessCode 1.000000
|
ch AccessCode 1.000000
|
||||||
@ -127,7 +154,7 @@ phi AccessCode 2.000000
|
|||||||
chi sign 1.000000
|
chi sign 1.000000
|
||||||
chi SoftZero 0.000000
|
chi SoftZero 0.000000
|
||||||
chi SoftLowerLim 0.000000
|
chi SoftLowerLim 0.000000
|
||||||
chi SoftUpperLim 212.000000
|
chi SoftUpperLim 190.000000
|
||||||
chi Fixed -1.000000
|
chi Fixed -1.000000
|
||||||
chi InterruptMode 0.000000
|
chi InterruptMode 0.000000
|
||||||
chi AccessCode 1.000000
|
chi AccessCode 1.000000
|
||||||
@ -149,8 +176,6 @@ twotheta InterruptMode 0.000000
|
|||||||
twotheta AccessCode 2.000000
|
twotheta AccessCode 2.000000
|
||||||
lastscancommand cscan a4 10. .1 10 5
|
lastscancommand cscan a4 10. .1 10 5
|
||||||
lastscancommand setAccess 2
|
lastscancommand setAccess 2
|
||||||
banana CountMode timer
|
|
||||||
banana preset 100.000000
|
|
||||||
sample_mur 0.000000
|
sample_mur 0.000000
|
||||||
sample_mur setAccess 2
|
sample_mur setAccess 2
|
||||||
email UNKNOWN
|
email UNKNOWN
|
||||||
@ -428,13 +453,11 @@ a1 SoftUpperLim 120.000000
|
|||||||
a1 Fixed -1.000000
|
a1 Fixed -1.000000
|
||||||
a1 InterruptMode 0.000000
|
a1 InterruptMode 0.000000
|
||||||
a1 AccessCode 2.000000
|
a1 AccessCode 2.000000
|
||||||
batchroot /data/koenneck/src/sics
|
|
||||||
batchroot setAccess 2
|
|
||||||
user Uwe Filges
|
user Uwe Filges
|
||||||
user setAccess 2
|
user setAccess 2
|
||||||
sample D20 30K SNP Okt 2001 GS
|
sample D20 30K SNP Okt 2001 GS
|
||||||
sample setAccess 2
|
sample setAccess 2
|
||||||
title snp gs apd 30K
|
title endtest called with 23.000000 :Driving:
|
||||||
title setAccess 2
|
title setAccess 2
|
||||||
starttime 2002-04-23 10:49:18
|
starttime 2002-08-07 08:09:45
|
||||||
starttime setAccess 2
|
starttime setAccess 2
|
||||||
|
2
status.c
2
status.c
@ -59,6 +59,7 @@
|
|||||||
"Driving",
|
"Driving",
|
||||||
"Running",
|
"Running",
|
||||||
"Running a scan",
|
"Running a scan",
|
||||||
|
"Writing data",
|
||||||
"Processing a batch file",
|
"Processing a batch file",
|
||||||
"Halted",
|
"Halted",
|
||||||
"Dead",
|
"Dead",
|
||||||
@ -74,6 +75,7 @@
|
|||||||
"driving",
|
"driving",
|
||||||
"running",
|
"running",
|
||||||
"scanning",
|
"scanning",
|
||||||
|
"writing",
|
||||||
"batch",
|
"batch",
|
||||||
"halt",
|
"halt",
|
||||||
"dead",
|
"dead",
|
||||||
|
Reference in New Issue
Block a user