- JulCho now reads data in tow bunches, speeds and rest for optimization
This commit is contained in:
78
julcho.c
78
julcho.c
@ -7,6 +7,11 @@
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, June-July 2006
|
||||
*
|
||||
* Parameter updating is to slow, therefore it happens in two groups now:
|
||||
* actspeed and actphase are requested more frequently, so they go separate
|
||||
*
|
||||
* Mark Koennecke, October 2006
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
@ -33,6 +38,9 @@
|
||||
#define ROPAR -811
|
||||
#define NOMEM -812
|
||||
#define HALT -813
|
||||
/*--------------------- update flags -------------------------------------*/
|
||||
#define ALL 1
|
||||
#define SPEED 2
|
||||
/*------------------------- chopper internal names -----------------------*/
|
||||
#define CH1N "snail"
|
||||
#define CH2N "master"
|
||||
@ -46,6 +54,7 @@ typedef struct {
|
||||
int errorCode;
|
||||
time_t lastUpdate;
|
||||
int updateIntervall;
|
||||
int speedUpdate;
|
||||
int halt;
|
||||
}JulCho, *pJulCho;
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -383,12 +392,45 @@ static int ReadJulChoFlags(pJulCho self){
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int UpdateJulChoParameters(pJulCho self){
|
||||
static int UpdateJulChoParameters(pJulCho self, int what){
|
||||
int status, intData[5];
|
||||
double doubleData[5];
|
||||
char reply[255];
|
||||
|
||||
if(time(NULL) < self->lastUpdate + self->updateIntervall){
|
||||
assert(what == ALL || what == SPEED);
|
||||
|
||||
if(what == SPEED){
|
||||
if(time(NULL) < self->speedUpdate + self->updateIntervall){
|
||||
return 1;
|
||||
}
|
||||
} else{
|
||||
if(time(NULL) < self->lastUpdate + self->updateIntervall){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
status = JulChoTransact(self,"RAS",reply,255);
|
||||
if(status < 0){
|
||||
self->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
if(!splitJulChoInt(reply,intData)){
|
||||
self->errorCode = BADREPLY;
|
||||
}
|
||||
setJulChoIntPar(self->parNode,"actspeed",intData);
|
||||
|
||||
status = JulChoTransact(self,"RAP",reply,255);
|
||||
if(status < 0){
|
||||
self->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
if(!splitJulChoDouble(reply,doubleData)){
|
||||
self->errorCode = BADREPLY;
|
||||
}
|
||||
setJulChoDoublePar(self->parNode,"actphase",doubleData);
|
||||
|
||||
if(what != ALL){
|
||||
self->speedUpdate = time(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -402,15 +444,6 @@ static int UpdateJulChoParameters(pJulCho self){
|
||||
}
|
||||
setJulChoIntPar(self->parNode,"nomspeed",intData);
|
||||
|
||||
status = JulChoTransact(self,"RAS",reply,255);
|
||||
if(status < 0){
|
||||
self->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
if(!splitJulChoInt(reply,intData)){
|
||||
self->errorCode = BADREPLY;
|
||||
}
|
||||
setJulChoIntPar(self->parNode,"actspeed",intData);
|
||||
|
||||
status = JulChoTransact(self,"RNP",reply,255);
|
||||
if(status < 0){
|
||||
@ -422,15 +455,6 @@ static int UpdateJulChoParameters(pJulCho self){
|
||||
}
|
||||
setJulChoDoublePar(self->parNode,"nomphase",doubleData);
|
||||
|
||||
status = JulChoTransact(self,"RAP",reply,255);
|
||||
if(status < 0){
|
||||
self->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
if(!splitJulChoDouble(reply,doubleData)){
|
||||
self->errorCode = BADREPLY;
|
||||
}
|
||||
setJulChoDoublePar(self->parNode,"actphase",doubleData);
|
||||
|
||||
status = JulChoTransact(self,"RGW",reply,255);
|
||||
if(status < 0){
|
||||
@ -496,6 +520,7 @@ static int UpdateJulChoParameters(pJulCho self){
|
||||
status = ReadJulChoFlags(self);
|
||||
|
||||
self->lastUpdate = time(NULL);
|
||||
self->speedUpdate = time(NULL);
|
||||
return status;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -551,6 +576,15 @@ static void JulChoErrorcodeToString(int code, char *pError, int iLen){
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int testParGroup(char *name){
|
||||
if(strstr(name,"actspeed") != NULL ||
|
||||
strstr(name,"actphase") != NULL){
|
||||
return SPEED;
|
||||
} else {
|
||||
return ALL;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int JulChoGetCallback(void *userData, void *callData,
|
||||
pHdb currentNode, hdbValue v){
|
||||
@ -564,7 +598,7 @@ static int JulChoGetCallback(void *userData, void *callData,
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
status = UpdateJulChoParameters(self);
|
||||
status = UpdateJulChoParameters(self,testParGroup(currentNode->name));
|
||||
if(status != 1 && pCon != NULL){
|
||||
JulChoErrorcodeToString(self->errorCode, error,127);
|
||||
snprintf(buffer,255,"ERROR: %s occurred reading par",error);
|
||||
@ -966,7 +1000,7 @@ static int JulChoGetPar(pCodri pDriv, char *parname,
|
||||
self->errorCode = NOTPAR;
|
||||
return 0;
|
||||
}
|
||||
if(!UpdateJulChoParameters(self)){
|
||||
if(!UpdateJulChoParameters(self,testParGroup(parname))){
|
||||
return 0;
|
||||
}
|
||||
val = formatValue(target->value);
|
||||
|
13
sinqhttp.c
13
sinqhttp.c
@ -46,6 +46,7 @@ static char subsample[] = {"/admin/processhmdata.egi"};
|
||||
#define BADSTATUS -707
|
||||
#define BADAUTH -708
|
||||
#define HMNOMEMORY -709
|
||||
#define BADSUBSAMPLE -710
|
||||
/*=====================================================================
|
||||
our driver private data structure
|
||||
======================================================================*/
|
||||
@ -94,6 +95,9 @@ static int sinqHttpCheckResponse(pSinqHttp self){
|
||||
|
||||
self->failCount = 0;
|
||||
pPtr = ghttp_get_body(self->syncRequest);
|
||||
if(pPtr == NULL){
|
||||
return 1;
|
||||
}
|
||||
len = ghttp_get_body_len(self->syncRequest);
|
||||
if(len > 511){
|
||||
len = 510;
|
||||
@ -232,12 +236,12 @@ static int SinqHttpConfigure(pHistDriver self, SConnection *pCon,
|
||||
httpStatus = ghttp_process(pPriv->syncRequest);
|
||||
confData = (char *)ghttp_get_body(pPriv->syncRequest);
|
||||
if(httpStatus != ghttp_done){
|
||||
confData = (char *)ghttp_get_error(pPriv->syncRequest);
|
||||
confData = (char *)ghttp_get_error(pPriv->syncRequest);
|
||||
snprintf(confCommand,511,"ERROR: http error %s occurred",
|
||||
confData);
|
||||
SCWrite(pCon,confCommand,eError);
|
||||
return 0;
|
||||
} else {
|
||||
} else if(confData != NULL){
|
||||
if(strstr(confData,"ERROR") != NULL){
|
||||
snprintf(confCommand,511,"%s",confData);
|
||||
SCWrite(pCon,confCommand,eError);
|
||||
@ -511,6 +515,11 @@ static HistInt *SinqHttpSubSample(pHistDriver self, SConnection *pCon,
|
||||
}
|
||||
|
||||
len = ghttp_get_body_len(pPriv->syncRequest);
|
||||
if(len <= 0){
|
||||
strncpy(pPriv->hmError,"ERROR: no data returned from subsampling", 511);
|
||||
pPriv->errorCode = BADSUBSAMPLE;
|
||||
return NULL;
|
||||
}
|
||||
resultdata = malloc(len+4);
|
||||
if(resultdata == NULL){
|
||||
strncpy(pPriv->hmError,
|
||||
|
@ -896,6 +896,7 @@ static void slsdspCodeToText(int code, char *text, int textlen){
|
||||
return DEVFAULT;
|
||||
break;
|
||||
case BADECHO:
|
||||
case TIMEOUT:
|
||||
for(i = 0; i < 10; i++){
|
||||
iRet = NETAvailable(pMe->pSock,0);
|
||||
if(iRet == 1){
|
||||
@ -904,8 +905,6 @@ static void slsdspCodeToText(int code, char *text, int textlen){
|
||||
}
|
||||
return DEVREDO;
|
||||
break;
|
||||
case TIMEOUT:
|
||||
return DEVREDO;
|
||||
default:
|
||||
SLSClose(self);
|
||||
iRet = SLSInit(self);
|
||||
|
91
tabledrive.c
91
tabledrive.c
@ -55,7 +55,7 @@ static int TableDriveCheckLimits(void *pData, float fVal, char *error,
|
||||
strncpy(error,"Path Table Not Defined!",25);
|
||||
return 0;
|
||||
}
|
||||
if(fVal < 0. || fVal > self->tableLength){
|
||||
if(fVal < 1. || fVal >= self->tableLength){
|
||||
strncpy(error,"Out of Range",25);
|
||||
return 0;
|
||||
}
|
||||
@ -95,23 +95,11 @@ static int findOrientingMotor(pTableDrive self, ptdMotor moti){
|
||||
return 0;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static float interpolateLocate(tdEntry lower, tdEntry upper,
|
||||
float value, int count){
|
||||
float diff, result = count -1;
|
||||
|
||||
result = count;
|
||||
diff = upper.position - lower.position;
|
||||
value -= lower.position;
|
||||
if(ABS(diff) > .00001){
|
||||
result += value/diff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static float locatePosition(tdMotor moti, SConnection *pCon){
|
||||
int status, count = 0;
|
||||
int status;
|
||||
float value;
|
||||
tdEntry entry, back;
|
||||
double diff;
|
||||
tdEntry lower, upper;
|
||||
|
||||
status = MotorGetSoftPosition(moti.pMot,pCon,&value);
|
||||
if(!status) {
|
||||
@ -119,17 +107,37 @@ static float locatePosition(tdMotor moti, SConnection *pCon){
|
||||
}
|
||||
status = LLDnodePtr2First(moti.table);
|
||||
while(status != 0){
|
||||
LLDnodeDataTo(moti.table,&entry);
|
||||
if(entry.position > value){
|
||||
if(count == 0){
|
||||
return 1.;
|
||||
}
|
||||
LLDnodePtr2Prev(moti.table);
|
||||
LLDnodeDataTo(moti.table,&back);
|
||||
return interpolateLocate(back,entry,value, count);
|
||||
}
|
||||
count++;
|
||||
status = LLDnodePtr2Next(moti.table);
|
||||
LLDnodeDataTo(moti.table,&lower);
|
||||
status = LLDnodePtr2Next(moti.table);
|
||||
if(status != 0) {
|
||||
LLDnodeDataTo(moti.table,&upper);
|
||||
} else {
|
||||
/*
|
||||
* end of table
|
||||
*/
|
||||
return lower.tablePos;
|
||||
}
|
||||
/**
|
||||
* we have to deal with ascending and descending tables. This is
|
||||
* why we have to have some funny logic here
|
||||
*/
|
||||
if(upper.position > lower.position){
|
||||
/*
|
||||
* ascending table
|
||||
*/
|
||||
if(value >= lower.position && value < upper.position){
|
||||
diff = upper.position - lower.position;
|
||||
return lower.tablePos + (value - lower.position)/diff;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* descending table
|
||||
*/
|
||||
if(value <= lower.position && value > upper.position){
|
||||
diff = lower.position - upper.position;
|
||||
return lower.tablePos + ABS(value - lower.position)/diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -999.99;
|
||||
}
|
||||
@ -143,7 +151,7 @@ static void findBracket(tdMotor moti, float value, ptdEntry upper,
|
||||
status = LLDnodePtr2First(moti.table);
|
||||
while(status != 0){
|
||||
LLDnodeDataTo(moti.table,lower);
|
||||
if(lower->tablePos >= targetCount){
|
||||
if(lower->tablePos == targetCount){
|
||||
LLDnodeDataTo(moti.table,upper);
|
||||
if(LLDnodePtr2Next(moti.table)){
|
||||
LLDnodeDataTo(moti.table,upper);
|
||||
@ -161,8 +169,12 @@ static float findTarget(tdMotor moti, float value){
|
||||
|
||||
targetCount = (int)floor(value);
|
||||
findBracket(moti,value,&upper,&lower);
|
||||
diff = upper.position - lower.position;
|
||||
return (float)lower.position + (value - targetCount)*diff;
|
||||
if(ABS(targetCount - value) < .00001){
|
||||
return lower.position;
|
||||
} else {
|
||||
diff = upper.position - lower.position;
|
||||
return (float)lower.position + (value - targetCount)*diff;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void checkSync(pTableDrive self, SConnection *pCon, float value){
|
||||
@ -212,6 +224,14 @@ static float TableDriveGetValue(void *pData, SConnection *pCon){
|
||||
self->currentPosition = value;
|
||||
return value;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void tableSetPar(pMotor pMot, char *name, float value){
|
||||
ObPar *ob = NULL;
|
||||
|
||||
ob = ObParFind(pMot->ParArray,name);
|
||||
assert(ob != NULL);
|
||||
ob->fVal = value;
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
* Before I can drive the motors, I have to release the software limits..
|
||||
-------------------------------------------------------------------------*/
|
||||
@ -225,8 +245,9 @@ static void liberateMotors(pTableDrive self, SConnection *pCon){
|
||||
LLDnodeDataTo(self->motorTable,&moti);
|
||||
MotorGetPar(moti.pMot,"hardupperlim",&upper);
|
||||
MotorGetPar(moti.pMot,"hardlowerlim",&lower);
|
||||
MotorSetPar(moti.pMot,pCon,"softupperlim",upper);
|
||||
MotorSetPar(moti.pMot,pCon,"softlowerlim",lower);
|
||||
|
||||
tableSetPar(moti.pMot,"softupperlim",upper);
|
||||
tableSetPar(moti.pMot,"softlowerlim",lower);
|
||||
status = LLDnodePtr2Next(self->motorTable);
|
||||
}
|
||||
}
|
||||
@ -249,8 +270,8 @@ static void closeMotors(pTableDrive self, SConnection *pCon){
|
||||
upper = tdLower.upper + (self->currentPosition - targetCount)*diff;
|
||||
diff = tdUpper.lower - tdLower.lower;
|
||||
lower = tdLower.lower + (self->currentPosition - targetCount)*diff;
|
||||
MotorSetPar(moti.pMot,pCon,"softupperlim",upper);
|
||||
MotorSetPar(moti.pMot,pCon,"softlowerlim",lower);
|
||||
tableSetPar(moti.pMot,"softupperlim",upper);
|
||||
tableSetPar(moti.pMot,"softlowerlim",lower);
|
||||
status = LLDnodePtr2Next(self->motorTable);
|
||||
}
|
||||
}
|
||||
@ -381,6 +402,8 @@ static int TableDriveCheckStatus(void *pData, SConnection *pCon){
|
||||
TableDriveGetValue(self,pCon);
|
||||
closeMotors(self,pCon);
|
||||
return status;
|
||||
} else {
|
||||
return HWBusy;
|
||||
}
|
||||
break;
|
||||
case OUTOFSYNC:
|
||||
|
Reference in New Issue
Block a user