Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
This commit is contained in:
189
motorsec.c
189
motorsec.c
@@ -47,6 +47,20 @@
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void SecMotorSetError(pMotor self, char *text)
|
||||
{
|
||||
hdbValue v;
|
||||
pHdb node;
|
||||
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "error");
|
||||
if(node != NULL){
|
||||
v = MakeHdbText(strdup(text));
|
||||
UpdateHipadabaPar(node,v,NULL);
|
||||
ReleaseHdbValue(&v);
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SecMotorGetPar(pMotor self, char *name, float *fVal)
|
||||
{
|
||||
@@ -106,15 +120,17 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew)
|
||||
}
|
||||
self->stopped = 0;
|
||||
self->stopReported = 0;
|
||||
self->fTarget = fNew;
|
||||
|
||||
v = MakeHdbFloat(fNew);
|
||||
status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
|
||||
SecMotorSetError(sulf,"None");
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
||||
if(node != NULL){
|
||||
v = MakeHdbText(strdup("run"));
|
||||
UpdateHipadabaPar(node,v,pCon);
|
||||
ReleaseHdbValue(&v);
|
||||
}
|
||||
v = MakeHdbFloat(fNew);
|
||||
status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -200,12 +216,17 @@ static int SecMotorLimits(void *sulf, float fVal, char *error, int iErrLen)
|
||||
{
|
||||
float fHard;
|
||||
pMotor self;
|
||||
int status;
|
||||
|
||||
assert(sulf);
|
||||
|
||||
self = (pMotor) sulf;
|
||||
|
||||
return SecMotorCheckBoundary(self, fVal, &fHard, error, iErrLen);
|
||||
status = SecMotorCheckBoundary(self, fVal, &fHard, error, iErrLen);
|
||||
if(status != 1){
|
||||
SecMotorSetError(sulf,error);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -231,10 +252,11 @@ static int checkPosition(pMotor self, SConnection * pCon)
|
||||
if (ABS(target - hard) > precision) {
|
||||
if (self->retryCount >= (int) maxretry) {
|
||||
SCPrintf(pCon, eLogError,
|
||||
"ERROR: Aborting %s after %d retries, off position by %f",
|
||||
"ERROR: aborting %s after %d retries, off position by %f",
|
||||
self->name, (int) maxretry, target - hard);
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
||||
assert(node != NULL);
|
||||
SecMotorSetError(self,"Aborted positioning after many retries");
|
||||
UpdateHipadabaPar(node, MakeHdbText("error"), pCon);
|
||||
return HWFault;
|
||||
}
|
||||
@@ -277,6 +299,7 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
|
||||
pHdb node = NULL;
|
||||
hdbValue v;
|
||||
float interrupt;
|
||||
char error[132];
|
||||
|
||||
assert(sulf);
|
||||
self = (pMotor) sulf;
|
||||
@@ -298,8 +321,20 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
|
||||
handleMoveCallback(self, pCon);
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "poserror") != NULL) {
|
||||
SCWrite(pCon,"WARNING: Position not reached",eLog);
|
||||
status = checkPosition(self, pCon);
|
||||
} else if (strstr(v.v.text, "restart") != NULL) {
|
||||
SCPrintf(pCon,eLog,"WARNING: restarting motor %s", self->name);
|
||||
SecMotorRun(self,pCon,self->fTarget);
|
||||
return HWBusy;
|
||||
} else if (strstr(v.v.text, "error") != NULL) {
|
||||
if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
|
||||
SecMotorSetError(sulf,error);
|
||||
}
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||
if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
|
||||
SecMotorSetError(sulf,error);
|
||||
}
|
||||
status = HWFault;
|
||||
} else {
|
||||
SCPrintf(pCon, eError, "ERROR: unknown motor status %s found",
|
||||
@@ -333,9 +368,16 @@ static float SecMotorGetValue(void *pData, SConnection * pCon)
|
||||
{
|
||||
int status;
|
||||
pMotor self = (pMotor) pData;
|
||||
hdbValue v;
|
||||
hdbValue v;
|
||||
char error[132];
|
||||
|
||||
|
||||
assert(pData);
|
||||
status = GetHdbProperty(self->pDescriptor->parNode,"geterror", error,sizeof(error));
|
||||
if(status == 1 && strcmp(error,"none") != 0) {
|
||||
SCPrintf(pCon,eError,"ERROR: Failed to read %s with %s", self->name, error);
|
||||
return -9999999.99;
|
||||
}
|
||||
status = GetHipadabaPar(self->pDescriptor->parNode, &v, pCon);
|
||||
if (status != 1) {
|
||||
return -9999999.99;
|
||||
@@ -423,7 +465,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
pHdb child = NULL;
|
||||
pMotor self = NULL;
|
||||
float fHard, fVal, sign, zero;
|
||||
char pBueffel[512], pError[132];
|
||||
char pBueffel[512], pError[132], *pPtr = NULL;
|
||||
int status;
|
||||
|
||||
self = (pMotor) userData;
|
||||
@@ -467,13 +509,14 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
self->name);
|
||||
SCWrite(pCon, pBueffel, eWarning);
|
||||
self->errorCount = 0;
|
||||
self->pDrivInt->iErrorCount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check for alarm condition
|
||||
*/
|
||||
SecMotorGetPar(self, "failafter", &fVal);
|
||||
if (self->pDrivInt->iErrorCount > (int) fVal) {
|
||||
if (self->pDrivInt->iErrorCount >= (int) fVal) {
|
||||
/* big alarm */
|
||||
ServerWriteGlobal("ERROR: !!! MOTOR ALARM !!! MOTOR ALARM !!!",
|
||||
eError);
|
||||
@@ -483,6 +526,8 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
ServerWriteGlobal(pBueffel, eError);
|
||||
SCSetInterrupt(pCon, eAbortBatch);
|
||||
self->pDrivInt->iErrorCount = 0;
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
||||
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
|
||||
return hdbAbort;
|
||||
}
|
||||
|
||||
@@ -490,10 +535,10 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
self->retryCount = 0;
|
||||
self->stopped = 0;
|
||||
self->posCount = 0;
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||
UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "status");
|
||||
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||
UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||
SetHipadabaPar(child, MakeHdbFloat(fHard), pCon);
|
||||
|
||||
@@ -504,6 +549,12 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
if (mm != NULL) {
|
||||
pCon = (SConnection *) mm->callData;
|
||||
SecMotorGetPar(self, "hardposition", &fVal);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||
if((pPtr = GetHdbProp(child,"geterror")) != NULL){
|
||||
SetHdbProperty(node,"geterror",pPtr);
|
||||
} else {
|
||||
SetHdbProperty(node,"geterror",NULL);
|
||||
}
|
||||
fVal = hardToSoftPosition(self, fVal);
|
||||
node->value.v.doubleValue = fVal;
|
||||
mm->v->v.doubleValue = fVal;
|
||||
@@ -518,6 +569,7 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
|
||||
pHdbMessage message)
|
||||
{
|
||||
pHdbDataMessage mm = NULL;
|
||||
pHdbPropertyChange pm = NULL;
|
||||
pMotor self = (pMotor) userData;
|
||||
float fVal;
|
||||
hdbValue v;
|
||||
@@ -532,6 +584,18 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
|
||||
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
/*
|
||||
forward geterror
|
||||
*/
|
||||
pm = GetPropertyChangeMessage(message);
|
||||
if(pm != NULL){
|
||||
if(strstr(pm->key,"geterror") != NULL){
|
||||
SetHdbProperty(self->pDescriptor->parNode,pm->key, pm->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
@@ -611,6 +675,80 @@ static hdbCallbackReturn SecMotorZeroCallback(pHdb node, void *userData,
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
char *pName;
|
||||
SConnection *pCon;
|
||||
float lastValue;
|
||||
} MotInfo, *pMotInfo;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void KillInfo(void *pData)
|
||||
{
|
||||
pMotInfo self = NULL;
|
||||
|
||||
assert(pData);
|
||||
self = (pMotInfo) pData;
|
||||
if (self->pName) {
|
||||
free(self->pName);
|
||||
}
|
||||
if (self->pCon != NULL) {
|
||||
SCDeleteConnection(self->pCon);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn InterestCallback(pHdb node, void *userData,
|
||||
pHdbMessage message)
|
||||
{
|
||||
pHdbDataMessage mm = NULL;
|
||||
pMotor self = (pMotor) userData;
|
||||
float fVal;
|
||||
hdbValue v;
|
||||
pMotInfo priv = (pMotInfo)userData;
|
||||
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
mm = GetHdbUpdateMessage(message);
|
||||
if (mm != NULL) {
|
||||
v = *mm->v;
|
||||
if(!SCisConnected(priv->pCon)){
|
||||
return hdbKill;
|
||||
}
|
||||
if(ABS(v.v.doubleValue - priv->lastValue) > .1) {
|
||||
SCPrintf(priv->pCon,eValue,"%s.position = %f",
|
||||
priv->pName, v.v.doubleValue);
|
||||
priv->lastValue = v.v.doubleValue;
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
pMotInfo priv = NULL;
|
||||
|
||||
priv = malloc(sizeof(MotInfo));
|
||||
if(priv == NULL){
|
||||
SCWrite(con,"ERROR: out of memory registering interest",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(nPar >= 1 && (strcmp(par[0]->value.v.text,"UNKNOWN") != 0)) {
|
||||
priv->pName = strdup(par[0]->value.v.text);
|
||||
} else {
|
||||
priv->pName = strdup(ccmd->objectNode->name);
|
||||
}
|
||||
priv->lastValue = .0;
|
||||
priv->pCon = SCCopyConnection(con);
|
||||
AppendHipadabaCallback(ccmd->objectNode,
|
||||
MakeHipadabaCallback(InterestCallback,priv,KillInfo));
|
||||
SCSendOK(con);
|
||||
return 1;
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pMotor SecMotorInit(char *name)
|
||||
{
|
||||
@@ -672,6 +810,7 @@ pMotor SecMotorInit(char *name)
|
||||
|
||||
child = MakeHipadabaNode("sign", HIPFLOAT, 1);
|
||||
SetHdbProperty(child, "__save", "true");
|
||||
SetHdbProperty(child, "priv", "user");
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
AppendHipadabaCallback(child,
|
||||
MakeHipadabaCallback(SecMotorSignCallback, pM,
|
||||
@@ -680,6 +819,7 @@ pMotor SecMotorInit(char *name)
|
||||
|
||||
child = MakeHipadabaNode("softzero", HIPFLOAT, 1);
|
||||
SetHdbProperty(child, "__save", "true");
|
||||
SetHdbProperty(child, "priv", "user");
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
AppendHipadabaCallback(child,
|
||||
MakeHipadabaCallback(SecMotorZeroCallback, pM,
|
||||
@@ -744,6 +884,13 @@ pMotor SecMotorInit(char *name)
|
||||
SetHdbProperty(child, "motname", name);
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeHipadabaNode("error", HIPTEXT, 1);
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
|
||||
AddSICSHdbPar(child, "name", usUser, MakeHdbText("UNKNOWN"));
|
||||
|
||||
|
||||
pM->endScriptID = 0;
|
||||
|
||||
/* initialise Drivable interface */
|
||||
@@ -791,6 +938,8 @@ static void SecMotorKill(void *data)
|
||||
free(self->pDrivInt);
|
||||
}
|
||||
|
||||
RemoveHdbNodeFromParent(self->objectNode,NULL);
|
||||
|
||||
if (self->pCall) {
|
||||
DeleteCallBackInterface(self->pCall);
|
||||
}
|
||||
@@ -821,3 +970,25 @@ int SecMotorFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
SecMotorKill, pNew);
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
everywhere we need to find a motor for a name quite frequently.......
|
||||
----------------------------------------------------------------------------*/
|
||||
pMotor FindMotor(SicsInterp * pSics, char *name)
|
||||
{
|
||||
CommandList *pC;
|
||||
pMotor pMot;
|
||||
|
||||
pC = FindCommand(pSics, name);
|
||||
if (!pC) {
|
||||
return NULL;
|
||||
}
|
||||
pMot = (pMotor) pC->pData;
|
||||
if (!pMot) {
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(pMot->pDescriptor->name, "Motor") != 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
return pMot;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user