- Added hmslave.c

- Tasub only drives required motors
- Tasub handles fixed motors more gracefully
This commit is contained in:
koennecke
2007-05-30 11:57:50 +00:00
parent 55893f9133
commit 9737722b8c
9 changed files with 355 additions and 6 deletions

View File

@ -333,6 +333,7 @@ static float invokeReadScript(pConfigurableVirtualMotor self,
if(status != TCL_OK){ if(status != TCL_OK){
snprintf(self->scriptError,510,"ERROR: Tcl subsystem reported %s", snprintf(self->scriptError,510,"ERROR: Tcl subsystem reported %s",
Tcl_GetStringResult(pTcl)); Tcl_GetStringResult(pTcl));
SCWrite(pCon,self->scriptError,eError);
} }
return atof(Tcl_GetStringResult(pTcl)); return atof(Tcl_GetStringResult(pTcl));
} }

View File

@ -454,6 +454,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
if(v1.arrayLength != v2.arrayLength){ if(v1.arrayLength != v2.arrayLength){
return 0; return 0;
} }
if(v1.v.intArray == NULL || v2.v.intArray == NULL){
return 0;
}
for(i = 0; i < v1.arrayLength; i++){ for(i = 0; i < v1.arrayLength; i++){
if(v1.v.intArray[i] != v2.v.intArray[i]){ if(v1.v.intArray[i] != v2.v.intArray[i]){
return 0; return 0;
@ -466,6 +469,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
if(v1.arrayLength != v2.arrayLength){ if(v1.arrayLength != v2.arrayLength){
return 0; return 0;
} }
if(v1.v.floatArray == NULL || v2.v.floatArray == NULL){
return 0;
}
for(i = 0; i < v1.arrayLength; i++){ for(i = 0; i < v1.arrayLength; i++){
if(ABS(v1.v.floatArray[i] - v2.v.floatArray[i]) > .01){ if(ABS(v1.v.floatArray[i] - v2.v.floatArray[i]) > .01){
return 0; return 0;

293
hmslave.c Normal file
View File

@ -0,0 +1,293 @@
/**
* This is a histogram memory driver for a slave histogram. This is for
* supporting multiple banks of histogram memory data in one physical
* histogram memory, possibly with different dimensions. On HM will connect
* to the physical histogram memory server and configure and control it and
* also handle bank 0. Other HM's may use this slave drive to to connect to
* the main HM for retrieving further banks. Thus this HM just becomes a
* data container for bank data. And this is the driver for such slave HM's.
* It mostly implements empty functions as control is through the main HM. The
* execption is data loading which will load the associated bank from the
* main HM.
*
* This is as of March 2007 defunct. The reason is that there are problems
* with buffering the data.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2007
*/
#include <sics.h>
#include <countdriv.h>
#include <counter.h>
#include <HistMem.h>
#include <HistMem.i>
#include <stringdict.h>
#include <HistDriv.i>
#include <hmdata.h>
typedef struct {
pHistMem master;
int bank;
}*HMSlave, sHMSlave;
/*-------------------------------------------------------------------
Configures the HM from the options in pOpt and the HM data structure
Returns 1 on success, 0 on failure
---------------------------------------------------------------------*/
static int HMSlaveConfigure(pHistDriver self, SConnection *pCon,
pStringDict pOpt, SicsInterp *pSics){
HMSlave pPriv = NULL;
char buffer[80], error[256];
pPriv =(HMSlave)self->pPriv;
if(StringDictGet(pOpt,"master",buffer, 79) == 1){
pPriv->master = (pHistMem)FindCommandData(pServ->pSics,buffer,"HistMem");
if(pPriv->master == NULL){
snprintf(error,255,"ERROR: failed to find master HM %s", buffer);
SCWrite(pCon,error,eError);
return 0;
}
} else {
SCWrite(pCon,"ERROR: required configuration option master missing",
eError);
return 0;
}
if(StringDictGet(pOpt,"bank",buffer, 79) == 1){
pPriv->bank = atoi(buffer);
} else {
SCWrite(pCon,"ERROR: required configuration option bank missing",
eError);
return 0;
}
return 1;
}
/*--------------------------------------------------------------------
Start histogramming, Returns HWFault on failure, 1 on success
----------------------------------------------------------------------*/
static int HMSlaveStart(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return 1;
}
/*--------------------------------------------------------------------
Stops histogramming, Returns HWFault on failure, 1 on success
----------------------------------------------------------------------*/
static int HMSlaveHalt(pHistDriver self){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return 1;
}
/*--------------------------------------------------------------------
Checks histogramming status, Returns HWFault on failure,
HWIdle when finished, HWBusy when counting
----------------------------------------------------------------------*/
static int HMSlaveCountStatus(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return HWIdle;
}
/*--------------------------------------------------------------------
Get info on error after last HWFault, returns 1 always.
Puts an int error code into *code and errLen chars of
error description into error
----------------------------------------------------------------------*/
static int HMSlaveGetError(pHistDriver self,int *code,
char *error, int errLen){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
strncpy(error,"Weird status: slaves do not err..",errLen);
*code = -77;
return 1;
}
/*--------------------------------------------------------------------
Try to fix the HM error in code. Returns COREDO when the last
operation needs to be redone, COTERM when the error cannot be
fixed.
----------------------------------------------------------------------*/
static int HMSlaveFixIt(pHistDriver self,int code){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return COTERM;
}
/*--------------------------------------------------------------------
GetData reads updates the internal cache of monitor values
from the hardware, Returns 1 or HWFault
----------------------------------------------------------------------*/
static int HMSlaveGetData(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return 1;
}
/*--------------------------------------------------------------------
GetMonitor reads the monitor value i. Returns either the monitor
value or -9999 if no such monitor exists or an error occurred
----------------------------------------------------------------------*/
static long HMSlaveGetMonitor(pHistDriver self,int i, SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return -9999;
}
/*--------------------------------------------------------------------
GetTime reads the total counting time. Returns either the
value or -9999.99 if no such value exists or an error occurred
----------------------------------------------------------------------*/
static float HMSlaveGetTime(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return -9999.99;
}
/*--------------------------------------------------------------------
Pause histogramming, Returns HWFault on failure, 1 on success
----------------------------------------------------------------------*/
static int HMSlavePause(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return 1;
}
/*--------------------------------------------------------------------
Continue histogramming, Returns HWFault on failure, 1 on success
----------------------------------------------------------------------*/
static int HMSlaveContinue(pHistDriver self,SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
return 1;
}
/*--------------------------------------------------------------------
Free the data associated with the private data structure of the driver
----------------------------------------------------------------------*/
static int HMSlaveFree(pHistDriver self){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
if(pPriv != NULL){
free(pPriv);
}
self->pPriv = NULL;
return 1;
}
/*-------------------------------------------------------------------
* fixTimebinning assures that our time binning dn the masters
* time binning are the same. So that diemsnions are right
* ------------------------------------------------------------------*/
static int fixTimeBinning(pHistDriver self, SConnection *pCon){
HMSlave pPriv = NULL;
pPriv =(HMSlave)self->pPriv;
if(isInTOFMode(pPriv->master->pDriv->data) &&
getNoOfTimebins(pPriv->master->pDriv->data) !=
getNoOfTimebins(self->data)){
self->data->tofMode = 1;
self->data->nTimeChan = getNoOfTimebins(pPriv->master->pDriv->data);
if(!resizeBuffer(self->data)) {
SCWrite(pCon,
"ERROR: out of memory allocating HMData for slave",
eError);
return 0;
}
}
return 1;
}
/*--------------------------------------------------------------------
Set The HM data or a subset of it. Returns HWFault or 1
----------------------------------------------------------------------*/
static int HMSlaveSetHistogram(pHistDriver self,
SConnection *pCon,
int i, int iStart, int iEnd, HistInt *pData){
HMSlave pPriv = NULL;
HistInt *start = NULL;
pPriv =(HMSlave)self->pPriv;
if(fixTimeBinning(self,pCon) == 1){
start = self->data->localBuffer + iStart;
memcpy(start,pData,(iEnd - iStart)*sizeof(HistInt));
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------
Set HM to a preset value, Returns HWFault on failure, 1 on success
----------------------------------------------------------------------*/
static int HMSlavePreset(pHistDriver self,SConnection *pCon,
HistInt value){
HMSlave pPriv = NULL;
int i;
pPriv =(HMSlave)self->pPriv;
if(fixTimeBinning(self,pCon) == 1){
for(i = 0; i < getHMDataLength(self->data); i++){
self->data->localBuffer[i] = value;
}
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------
get The HM data or a subset of it. Returns HWFault or 1
----------------------------------------------------------------------*/
static int HMSlaveGetHistogram(pHistDriver self,
SConnection *pCon,
int i, int iStart, int iEnd, HistInt *pData){
HMSlave pPriv = NULL;
pPriv = (HMSlave)self->pPriv;
return pPriv->master->pDriv->GetHistogram(pPriv->master->pDriv,
pCon, pPriv->bank, iStart, iEnd, pData);
}
/*--------------------------------------------------------------------
Make the HMDriver, returns a driver or NULL on failure
----------------------------------------------------------------------*/
pHistDriver MakeHMSlaveHM(pStringDict pOption){
pHistDriver pNew = NULL;
HMSlave pPriv = NULL;
/* create the general driver */
pNew = CreateHistDriver(pOption);
if(!pNew){
return NULL;
}
/*Create private data structure*/
pPriv = (HMSlave)malloc(sizeof(sHMSlave));
if(pPriv == NULL){
return NULL;
}
pNew->pPriv = pPriv;
/* add our options */
StringDictAddPair(pOption,"master","unknown");
StringDictAddPair(pOption,"bank","1");
/* configure all those functions */
pNew->Configure = HMSlaveConfigure;
pNew->Start = HMSlaveStart;
pNew->Halt = HMSlaveHalt;
pNew->GetCountStatus = HMSlaveCountStatus;
pNew->GetError = HMSlaveGetError;
pNew->TryAndFixIt = HMSlaveFixIt;
pNew->GetData = HMSlaveGetData;
pNew->GetHistogram = HMSlaveGetHistogram;
pNew->SetHistogram = HMSlaveSetHistogram;
pNew->GetMonitor = HMSlaveGetMonitor;
pNew->GetTime = HMSlaveGetTime;
pNew->Preset = HMSlavePreset;
pNew->FreePrivate = HMSlaveFree;
pNew->Pause = HMSlavePause;
pNew->Continue = HMSlaveContinue;
return pNew;
}

View File

@ -588,7 +588,7 @@ static void ignoreError(void *data, char *text){
int i, byte_zahl; int i, byte_zahl;
hsize_t chunkdims[H5S_MAX_RANK]; hsize_t chunkdims[H5S_MAX_RANK];
hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK]; hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK];
hsize_t size[2]; hsize_t size[H5S_MAX_RANK];
hsize_t maxdims[H5S_MAX_RANK]; hsize_t maxdims[H5S_MAX_RANK];
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
@ -992,7 +992,7 @@ static void ignoreError(void *data, char *text){
int rank; int rank;
hssize_t myStart[H5S_MAX_RANK]; hssize_t myStart[H5S_MAX_RANK];
hsize_t mySize[H5S_MAX_RANK]; hsize_t mySize[H5S_MAX_RANK];
hsize_t size[1],maxdims[H5S_MAX_RANK]; hsize_t size[H5S_MAX_RANK],maxdims[H5S_MAX_RANK];
hid_t filespace,dataspace; hid_t filespace,dataspace;
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
@ -1006,6 +1006,7 @@ static void ignoreError(void *data, char *text){
{ {
myStart[i] = iStart[i]; myStart[i] = iStart[i];
mySize[i] = iSize[i]; mySize[i] = iSize[i];
size[i] = iSize[i];
} }
iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims); iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims);
dataspace = H5Screate_simple (rank, mySize, NULL); dataspace = H5Screate_simple (rank, mySize, NULL);

View File

@ -681,7 +681,7 @@ static void putSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self,
eError); eError);
return; return;
} }
status = NXDopenalias(self->fileHandle, self->dictHandle,argv[2]); status = NXDopenalias(self->fileHandle, self->dictHandle,argv[2]);
if(status != NX_OK){ if(status != NX_OK){
SCPrintf(pCon,eError,"ERROR: failed to open alias %s", argv[2]); SCPrintf(pCon,eError,"ERROR: failed to open alias %s", argv[2]);

View File

@ -301,6 +301,12 @@ int ProtocolGet(SConnection* pCon, void* pData, char *pProName, int len)
return 0; return 0;
} }
if(pData == NULL)
{
pCon->iProtocolID = 0;
return 1;
}
/* lazy initialisation of defaultWriter since connection is verified */ /* lazy initialisation of defaultWriter since connection is verified */
if(0==pPro->isDefaultSet) if(0==pPro->isDefaultSet)
{ {

View File

@ -460,7 +460,7 @@ int fixRS232Error(prs232 self, int iCode){
case BADSEND: case BADSEND:
closeRS232(self); closeRS232(self);
status = initRS232(self); status = initRS232(self);
if(status){ if(status > 0){
return 1; return 1;
} else { } else {
return 0; return 0;

View File

@ -4,6 +4,9 @@
copyright: see file COPYRIGHT copyright: see file COPYRIGHT
Mark Koennecke, May 2005 Mark Koennecke, May 2005
In the long run it might be useful to switch all this to the more
general motor list driving code.
--------------------------------------------------------------------*/ --------------------------------------------------------------------*/
#include <assert.h> #include <assert.h>
#include "sics.h" #include "sics.h"
@ -248,6 +251,7 @@ static int startMotors(ptasMot self, tasAngles angles,
int status, silent; int status, silent;
silent = self->math->silent; silent = self->math->silent;
self->math->mustRecalculate = 1;
/* /*
monochromator monochromator
*/ */
@ -472,13 +476,23 @@ static int calculateAndDrive(ptasMot self, SConnection *pCon){
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static int checkMotors(ptasMot self, SConnection *pCon){ static int checkMotors(ptasMot self, SConnection *pCon){
int i, status, length = 12; int i, status, length = 12;
int mask[12];
self->math->mustRecalculate = 1; self->math->mustRecalculate = 1;
if(self->math->tasMode == ELASTIC){ if(self->math->tasMode == ELASTIC){
length = 8; length = 8;
} }
memset(mask,0,12*sizeof(int));
for(i = 0; i < length; i++){
mask[i] = 1;
}
if(self->math->outOfPlaneAllowed != 0){
mask[SGU] = 0;
mask[SGL] = 0;
}
for(i = 0; i < 12; i++){ for(i = 0; i < 12; i++){
if(self->math->motors[i] != NULL){ if(self->math->motors[i] != NULL && mask[i] != 0){
status = self->math->motors[i]->pDrivInt->CheckStatus(self->math->motors[i], status = self->math->motors[i]->pDrivInt->CheckStatus(self->math->motors[i],
pCon); pCon);
if(status != HWIdle && status != OKOK){ if(status != HWIdle && status != OKOK){

30
tasub.c
View File

@ -227,6 +227,13 @@ static int testMotor(ptasUB pNew, SConnection *pCon, char *name, int idx){
return 1; return 1;
} }
} }
/*-------------------------------------------------------------------*/
static void updateTargets(ptasUB pNew, SConnection *pCon){
tasAngles ang;
readTASAngles(pNew,pCon,&ang);
calcTasQEPosition(&pNew->machine, ang, &pNew->target);
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData, int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData,
int argc, char *argv[]){ int argc, char *argv[]){
@ -303,7 +310,7 @@ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: a required motor is mssing, tasub NOT installed",eError); SCWrite(pCon,"ERROR: a required motor is mssing, tasub NOT installed",eError);
return 0; return 0;
} }
status = AddCommand(pSics,argv[1], status = AddCommand(pSics,argv[1],
TasUBWrapper, TasUBWrapper,
KillTasUB, KillTasUB,
@ -1438,6 +1445,21 @@ static int setUB(SConnection *pCon, SicsInterp *pSics, ptasUB self,
return 1; return 1;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
static int getUB(SConnection *pCon, SicsInterp *pSics, ptasUB self,
int argc, char *argv[]){
double value;
char pBueffel[512];
int status;
snprintf(pBueffel,511,"tasub.ub = %f %f %f %f %f %f %f %f %f",
self->machine.UB[0][0], self->machine.UB[0][1], self->machine.UB[0][2],
self->machine.UB[1][0], self->machine.UB[1][1], self->machine.UB[1][2],
self->machine.UB[2][0], self->machine.UB[2][1], self->machine.UB[2][2]);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*------------------------------------------------------------------*/
static int setNormal(SConnection *pCon, SicsInterp *pSics, ptasUB self, static int setNormal(SConnection *pCon, SicsInterp *pSics, ptasUB self,
int argc, char *argv[]){ int argc, char *argv[]){
double value; double value;
@ -1652,6 +1674,8 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
return calcQFromAngles(self,pCon,pSics,argc,argv); return calcQFromAngles(self,pCon,pSics,argc,argv);
} else if(strcmp(argv[1],"setub") == 0){ } else if(strcmp(argv[1],"setub") == 0){
return setUB(pCon,pSics,self,argc,argv); return setUB(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"getub") == 0){
return getUB(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"setnormal") == 0){ } else if(strcmp(argv[1],"setnormal") == 0){
return setNormal(pCon,pSics,self,argc,argv); return setNormal(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"settarget") == 0){ } else if(strcmp(argv[1],"settarget") == 0){
@ -1664,6 +1688,10 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
return readReflection(pCon,pSics,&self->r1,argc,argv); return readReflection(pCon,pSics,&self->r1,argc,argv);
} else if(strcmp(argv[1],"r2") == 0){ } else if(strcmp(argv[1],"r2") == 0){
return readReflection(pCon,pSics,&self->r2,argc,argv); return readReflection(pCon,pSics,&self->r2,argc,argv);
} else if(strcmp(argv[1],"updatetargets") == 0){
updateTargets(self,pCon);
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"const") == 0){ } else if(strcmp(argv[1],"const") == 0){
if(argc > 2){ if(argc > 2){
strtolower(argv[2]); strtolower(argv[2]);