- Switched motor to hdb

- Changes to Hipadaba
- Added project to histogram memory code
- Started regression testing code
- Added hill climbing as optimization method to optimise
This commit is contained in:
koennecke
2006-08-16 14:13:05 +00:00
parent 47e38eba5a
commit a5c2da6acf
32 changed files with 1689 additions and 693 deletions

View File

@ -3,7 +3,13 @@
<cdtproject id="org.eclipse.cdt.make.core.make">
<extension point="org.eclipse.cdt.core.BinaryParser" id="org.eclipse.cdt.core.ELF"/>
<extension point="org.eclipse.cdt.core.CIndexer" id="org.eclipse.cdt.core.domsourceindexer"/>
<extension point="org.eclipse.cdt.core.CIndexer" id="org.eclipse.cdt.core.ctagsindexer">
<attribute key="ctagslocation" value=""/>
<attribute key="ctagfiletype" value="ctags_internal"/>
<attribute key="ctagsindexincludes" value="false"/>
<attribute key="ctagfilelocation" value=""/>
<attribute key="ctagslocationtype" value="ctags_path_default"/>
</extension>
<data>
<item id="org.eclipse.cdt.core.pathentry">
<pathentry kind="src" path=""/>

View File

@ -1,5 +1,5 @@
#line 462 "histogram.w"
#line 465 "histogram.w"
/*---------------------------------------------------------------------------
H I S T D R I V
@ -58,6 +58,9 @@
SConnection *pCon);
float (*GetTime)(pHistDriver self,
SConnection *pCon);
HistInt *(*SubSample)(pHistDriver self,
SConnection *pCon,int bank,
char *command);
int (*Preset)(pHistDriver self,
SConnection *pCon,
HistInt iVal);
@ -69,17 +72,17 @@
void *pPriv;
} HistDriver;
#line 474 "histogram.w"
#line 477 "histogram.w"
#line 229 "histogram.w"
#line 232 "histogram.w"
pHistDriver CreateHistDriver(pStringDict pDict);
void DeleteHistDriver(pHistDriver self);
int HistDriverConfig(pHistDriver self, pStringDict pOpt,
SConnection *pCon);
#line 475 "histogram.w"
#line 478 "histogram.w"
#endif

View File

@ -1,5 +1,5 @@
#line 435 "histogram.w"
#line 438 "histogram.w"
/*--------------------------------------------------------------------------
H I S T M E M
@ -42,22 +42,22 @@
eReflect
} OverFlowMode;
#line 455 "histogram.w"
#line 458 "histogram.w"
/*--------------------------------------------------------------------------*/
#line 287 "histogram.w"
#line 290 "histogram.w"
pHistMem CreateHistMemory(char *drivername);
void DeleteHistMemory(void *self);
#line 303 "histogram.w"
#line 306 "histogram.w"
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
int HistSetOption(pHistMem self, char *name, char *value);
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
#line 331 "histogram.w"
#line 334 "histogram.w"
float GetHistPreset(pHistMem self);
int SetHistPreset(pHistMem self, float fVal);
@ -73,7 +73,7 @@
void HistDirty(pHistMem self);
#line 361 "histogram.w"
#line 364 "histogram.w"
int SetHistogram(pHistMem self, SConnection *pCon,
int i,int iStart, int iEnd, HistInt *lData);
@ -85,7 +85,7 @@
HistInt *lData, int iDataLen);
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
#line 404 "histogram.w"
#line 407 "histogram.w"
int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
@ -94,7 +94,7 @@
int argc, char *argv[]);
#line 457 "histogram.w"
#line 460 "histogram.w"
#endif

View File

@ -1,5 +1,5 @@
#line 480 "histogram.w"
#line 483 "histogram.w"
/*---------------------------------------------------------------------------
H I S T M E M -- Internal
@ -11,7 +11,7 @@
#ifndef SICSHISTMEMINT
#define SICSHISTMEMINT
#line 251 "histogram.w"
#line 254 "histogram.w"
typedef struct __HistMem {
pObjectDescriptor pDes;
@ -23,7 +23,7 @@
pICallBack pCall;
} HistMem;
#line 490 "histogram.w"
#line 493 "histogram.w"
#endif

View File

@ -39,6 +39,8 @@
fields.
Mark Koennecke, December 2004
Aded buffering support, Mark Koennecke, July 2006
Copyright: see copyright.h
-----------------------------------------------------------------------------*/
#include "fortify.h"
@ -457,6 +459,11 @@ extern pServer pServ;
DeleteCommandStack(pVictim->pStack);
}
/* remove possible buffers */
if(pVictim->data != NULL)
{
DeleteDynString(pVictim->data);
}
pVictim->lMagic=0; /* make a write to a freed connection harmless */
/* finally free pVictim*/
@ -809,6 +816,52 @@ static void writeToLogFiles(SConnection *self, char *buffer)
free(bufPtr);
return 1;
}
/*-------------------------------------------------------------------------*/
static int SCBufferWrite(SConnection *self, char *buffer, int iOut)
{
if(!VerifyConnection(self))
{
return 0;
}
assert(self->data != NULL);
DynStringConcat(self->data,buffer);
if(strchr(buffer,'\n') == NULL){
DynStringConcat(self->data,"\n");
}
return 1;
}
/*-------------------------------------------------------------------------*/
int SCStartBuffering(SConnection *pCon)
{
if(!VerifyConnection(pCon))
{
return 0;
}
if(pCon->data != NULL)
{
DeleteDynString(pCon->data);
}
pCon->data = CreateDynString(128,128);
if(pCon->data == NULL)
{
return 0;
}
pCon->oldWriteFunc = pCon->write;
pCon->write = SCBufferWrite;
return 1;
}
/*-------------------------------------------------------------------------*/
pDynString SCEndBuffering(SConnection *pCon)
{
if(!VerifyConnection(pCon))
{
return 0;
}
assert(pCon->oldWriteFunc != NULL);
pCon->write = pCon->oldWriteFunc;
pCon->oldWriteFunc = NULL;
return pCon->data;
}
/*--------------------------------------------------------------------------*/
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut)
{

View File

@ -24,6 +24,7 @@
#include "network.h"
#include "obdes.h"
#include "commandcontext.h"
#include "dynstring.h"
#define MAXLOGFILES 10
@ -60,6 +61,12 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int parameterChange;
int sicsError;
/*
* for I/O Buffering
*/
pDynString data;
writeFunc oldWriteFunc;
/*
stuff supporting the sycamore protocol and a
command context
@ -116,6 +123,9 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCNotWrite(SConnection *self, char *buffer, int iOut);
int SCNormalWrite(SConnection *self, char *buffer, int iOut);
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut);
/*********************** I/O Buffering ***********************************/
int SCStartBuffering(SConnection *pCon);
pDynString SCEndBuffering(SConnection *pCon);
/************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);

View File

@ -200,6 +200,7 @@ typedef struct {
pRes->lTask = -1;
pRes->iLock = 0;
pRes->drivePrint = 0;
pRes->paused = 0;
pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL);
return pRes;

View File

@ -118,6 +118,8 @@
#line 259 "devexec.w"
/*-------------------------- Commands ------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
@ -161,7 +163,7 @@
void UnlockDeviceExecutor(pExeList self);
#line 297 "devexec.w"
#line 299 "devexec.w"
/* -------------------------- Executor management -------------------------*/

View File

@ -312,6 +312,8 @@ to the global SICS device executor.
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$devstop {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*-------------------------- Commands ------------------------------------*/@\\
\mbox{}\verb@ int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ /*@\\

View File

@ -258,6 +258,8 @@ to the global SICS device executor.
/*-------------------------------------------------------------------------*/
@<devstop@>
/*-------------------------- Commands ------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*

View File

@ -270,9 +270,9 @@ hdbValue makeHdbValue(int datatype, int length){
case HIPINTAR:
case HIPINTVARAR:
val.arrayLength = length;
val.v.intArray = malloc(length*sizeof(long));
val.v.intArray = malloc(length*sizeof(int));
if(val.v.intArray != NULL){
memset(val.v.intArray,0,length*sizeof(long));
memset(val.v.intArray,0,length*sizeof(int));
}
break;
case HIPFLOATAR:
@ -285,6 +285,7 @@ hdbValue makeHdbValue(int datatype, int length){
break;
case HIPTEXT:
val.v.text = strdup("UNKNOWN");
val.arrayLength = length;
break;
}
return val;
@ -311,10 +312,11 @@ hdbValue MakeHdbText(char *initText){
result.dataType = HIPTEXT;
result.v.text = initText;
result.arrayLength = strlen(initText);
return result;
}
/*-------------------------------------------------------------------------*/
hdbValue MakeHdbIntArray(int length, long *data){
hdbValue MakeHdbIntArray(int length, int *data){
hdbValue result;
result.dataType = HIPINTAR;
@ -438,11 +440,11 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length){
case HIPINTAR:
case HIPINTVARAR:
pNew->value.arrayLength = length;
pNew->value.v.intArray = malloc(length*sizeof(long));
pNew->value.v.intArray = malloc(length*sizeof(int));
if(pNew->value.v.intArray == NULL){
return NULL;
}
memset(pNew->value.v.intArray,0,length*sizeof(long));
memset(pNew->value.v.intArray,0,length*sizeof(int));
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
@ -454,6 +456,7 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length){
memset(pNew->value.v.floatArray,0,length*sizeof(double));
break;
case HIPTEXT:
pNew->value.arrayLength = length;
pNew->value.v.text = strdup("UNKNOWN");
break;
}
@ -463,7 +466,10 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length){
void AddHipadabaChild(pHdb parent, pHdb child){
pHdb current = NULL, prev = NULL;
assert(parent != NULL && child != NULL);
assert(parent != NULL);
if(child == NULL){
return;
}
current = parent->child;
child->mama = parent;
@ -745,11 +751,11 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
if(target->v.intArray != NULL){
free(target->v.intArray);
}
target->v.intArray = malloc(source->arrayLength * sizeof(long));
target->v.intArray = malloc(source->arrayLength * sizeof(int));
if(target->v.intArray == NULL){
return 0;
}
memset(target->v.intArray,0,source->arrayLength * sizeof(long));
memset(target->v.intArray,0,source->arrayLength * sizeof(int));
target->arrayLength = source->arrayLength;
}
for(i = 0; i < source->arrayLength; i++){
@ -812,4 +818,3 @@ int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
copyHdbValue(&node->value,v);
return 1;
}

View File

@ -42,10 +42,10 @@ typedef struct __hdbValue {
int dataType;
int arrayLength;
union __value {
long intValue;
int intValue;
double doubleValue;
char *text;
long *intArray;
int *intArray;
double *floatArray;
}v;
}hdbValue;
@ -107,7 +107,7 @@ hdbValue MakeHdbText(char *initText);
* data points to dynamically allocated memory.
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbIntArray(int length, long *data);
hdbValue MakeHdbIntArray(int length, int *data);
/**
* wrap a float array as an hdbValue
* @param length The length of the int array

View File

@ -1379,6 +1379,11 @@ static int checkHMEnd(pHistMem self, char *text){
iEnd = checkHMEnd(self,NULL);
}
if(iNum != 0 && argc > 4)
{
iEnd = atoi(argv[4]);
}
/* allocate data storage and get it */
lData = (HistInt *)malloc(iEnd*sizeof(HistInt));
if(!lData)
@ -1387,8 +1392,14 @@ static int checkHMEnd(pHistMem self, char *text){
return 0;
}
memset(lData,0,iEnd*sizeof(HistInt));
if(iNum == 0)
{
iRet = GetHistogram(self,pCon,iNum,iStart,iEnd,
lData,iEnd*sizeof(long));
} else {
iRet = GetHistogramDirect(self,pCon,iNum,iStart, iEnd,
lData, iEnd*sizeof(long));
}
if(!iRet)
{
sprintf(pBueffel,"ERROR: cannot retrieve histogram %d",iNum);

View File

@ -163,6 +163,9 @@ $\langle$HistType {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ float (*GetTime)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon);@\\
\mbox{}\verb@ HistInt *(*SubSample)(pHistDriver self, @\\
\mbox{}\verb@ SConnection *pCon,int bank,@\\
\mbox{}\verb@ char *command); @\\
\mbox{}\verb@ int (*Preset)(pHistDriver self,@\\
\mbox{}\verb@ SConnection *pCon,@\\
\mbox{}\verb@ HistInt iVal);@\\

View File

@ -130,6 +130,9 @@ definition:
SConnection *pCon);
float (*GetTime)(pHistDriver self,
SConnection *pCon);
HistInt *(*SubSample)(pHistDriver self,
SConnection *pCon,int bank,
char *command);
int (*Preset)(pHistDriver self,
SConnection *pCon,
HistInt iVal);

View File

@ -46,7 +46,7 @@ void clearHMData(pHMdata self){
size *= self->iDim[i];
}
if(self->tofMode){
size *= self->nTimeChan;
size *= getNoOfTimebins(self);
}
memset(self->localBuffer,0,size*sizeof(HistInt));
}
@ -60,7 +60,7 @@ static int resizeBuffer(pHMdata self){
size *= self->iDim[i];
}
if(self->tofMode){
size *= self->nTimeChan;
size *= getNoOfTimebins(self);
}
if(self->localBuffer != NULL){
free(self->localBuffer);
@ -80,6 +80,7 @@ int configureHMdata(pHMdata self, pStringDict pOpt,
int status, i;
float fVal;
char pValue[80];
pHistMem master = NULL;
if(self->nTimeChan > 2) {
self->tofMode = 1;
@ -111,6 +112,18 @@ int configureHMdata(pHMdata self, pStringDict pOpt,
self->updateIntervall = (int)rint(fVal);
}
status = StringDictGet(pOpt,"timeslave",pValue, 79);
if(status == 1) {
master = (pHistMem)FindCommandData(pServ->pSics,pValue,"HistMem");
if(master == NULL){
SCWrite(pCon,"ERROR: timeslave requested, but master HM not found",
eError);
} else {
self->timeslave = master->pDriv->data;
self->tofMode = 1;
}
}
/*
invalidate buffer
*/
@ -138,7 +151,7 @@ int configureHMdata(pHMdata self, pStringDict pOpt,
int genTimeBinning(pHMdata self, float start, float step, int noSteps){
int i;
if(noSteps >= MAXCHAN){
if(noSteps >= MAXCHAN || self->timeslave != NULL){
return 0;
}
for(i = 0; i < noSteps; i++){
@ -150,6 +163,10 @@ int genTimeBinning(pHMdata self, float start, float step, int noSteps){
}
/*----------------------------------------------------------------------*/
int setTimeBin(pHMdata self, int index, float value){
if(self->timeslave != NULL){
return 0;
}
if(index >= 0 && index < MAXCHAN){
self->timeBinning[index] = value;
} else {
@ -157,7 +174,7 @@ int setTimeBin(pHMdata self, int index, float value){
}
self->tofMode = 1;
if(index > self->nTimeChan){
self->nTimeChan = index;
self->nTimeChan = index+1;
return resizeBuffer(self);
}
return 1;
@ -168,17 +185,27 @@ int isInTOFMode(pHMdata self){
}
/*---------------------------------------------------------------------*/
int getNoOfTimebins(pHMdata self){
if(self->timeslave != NULL){
return getNoOfTimebins(self->timeslave);
} else {
return self->nTimeChan;
}
}
/*---------------------------------------------------------------------*/
float *getTimeBinning(pHMdata self){
if(self->timeslave != NULL){
return getTimeBinning(self->timeslave);
} else {
return self->timeBinning;
}
}
/*-------------------------------------------------------------------*/
void clearTimeBinning(pHMdata self){
if(self->timeslave == NULL){
self->nTimeChan = 1;
self->tofMode = 0;
resizeBuffer(self);
}
}
/*--------------------------------------------------------------------*/
void getHMDataDim(pHMdata self, int iDim[MAXDIM], int *rank){
@ -193,7 +220,7 @@ long getHMDataLength(pHMdata self){
length *= self->iDim[i];
}
if(self->tofMode){
length *= self->nTimeChan;
length *= getNoOfTimebins(self);
}
return length;
}
@ -227,6 +254,10 @@ static int updateHMbuffer(pHistMem hist, int bank, SConnection *pCon){
assert(self);
if(self->timeslave != NULL){
resizeBuffer(self);
}
for(i = 0; i < 3; i++){
status = hist->pDriv->GetHistogram(hist->pDriv,pCon,
bank,0,getHMDataLength(self),
@ -292,7 +323,7 @@ HistInt *getHMDataBufferPointer(pHistMem hist,SConnection *pCon){
assert(self);
if(self->localBuffer == NULL){
if(self->localBuffer == NULL || self->timeslave != NULL){
resizeBuffer(self);
}
/*

View File

@ -16,7 +16,7 @@
#define MAXDIM 3
typedef struct {
typedef struct __hmdata{
int rank;
int iDim[MAXDIM];
int nTimeChan;
@ -26,6 +26,7 @@
int updateIntervall;
int updateFlag;
HistInt *localBuffer;
struct __hmdata *timeslave;
} HMdata, *pHMdata;

View File

@ -11,7 +11,7 @@ display clients gone mad. This task is also handled through this class.
In order to do this, the following data structure is needed:
@d hmdatadat @{
typedef struct {
typedef struct __hmdata{
int rank;
int iDim[MAXDIM];
int nTimeChan;
@ -21,6 +21,7 @@ In order to do this, the following data structure is needed:
int updateIntervall;
int updateFlag;
HistInt *localBuffer;
struct __hmdata *timeslave;
} HMdata, *pHMdata;
@}

View File

@ -30,7 +30,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
moregress.o
MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -73,5 +73,6 @@
/* ----------------------- Simulation -----------------------------------*/
MotorDriver *CreateSIM(SConnection *pCon, int argc, char *argv[]);
void KillSIM(void *pData);
MotorDriver *RGMakeMotorDriver(void);
#endif

258
moregress.c Normal file
View File

@ -0,0 +1,258 @@
/**
* This is a regression testing motor driver for SICS.
* A parameter can be set which makes this driver cause
* various error conditions. This can then be used to
* verify and debug the working of upper level code
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, July 2007
*/
#include <stdlib.h>
#include <sics.h>
#include <modriv.h>
/*===================== supported errors ======================*/
#define NONE 0
#define STARTFAIL 1
#define BADPOS 2 /* positioning problem */
#define FAIL 3 /* failure */
#define OFFPOS 4 /* off pos by .2 */
#define READFAIL 5
#define RUN 6 /* keep running; for interrupt testing */
/*=============================================================*/
typedef struct __RGMoDriv{
/* general motor driver interface
fields. REQUIRED!
*/
float fUpper; /* upper limit */
float fLower; /* lower limit */
char *name;
int (*GetPosition)(void *self, float *fPos);
int (*RunTo)(void *self,float fNewVal);
int (*GetStatus)(void *self);
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
int (*TryAndFixIt)(void *self, int iError,float fNew);
int (*Halt)(void *self);
int (*GetDriverPar)(void *self, char *name,
float *value);
int (*SetDriverPar)(void *self,SConnection *pCon,
char *name, float newValue);
void (*ListDriverPar)(void *self, char *motorName,
SConnection *pCon);
void (*KillPrivate)(void *self);
/* your drivers private fields follow below */
float target;
int errorType;
int recover;
int counter;
} RGMotorDriver;
/*================================================================
GetPos returns OKOK on success, HWFault on failure
------------------------------------------------------------------*/
static int RGGetPos(void *data, float *fPos){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
if(self->errorType == READFAIL){
return HWFault;
}
if(self->errorType > 1 && self->errorType < 6){
*fPos = self->target - .2;
} else {
*fPos = self->target;
}
return OKOK;
}
/*----------------------------------------------------------------
RunTo starts the motor running. Returns OKOK on success, HWfault
on Errors
------------------------------------------------------------------*/
static int RGRunTo(void *data, float newValue){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
self->target = newValue;
if(self->errorType == STARTFAIL){
return HWFault;
}
return OKOK;
}
/*-----------------------------------------------------------------
CheckStatus queries the sattus of a running motor. Possible return
values can be:
HWBusy : motor still running
HWFault : motor error detected
HWPosFault : motor finished, but position not reached
HWIdle : motor finished OK
HWWarn : motor issued warning
--------------------------------------------------------------------*/
static int RGCheckStatus(void *data){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
switch(self->errorType){
case BADPOS:
return HWPosFault;
break;
case FAIL:
return HWFault;
break;
case RUN:
return HWBusy;
break;
}
return HWIdle;
}
/*------------------------------------------------------------------
GetError gets more information about error which occurred
*iCode is an integer error code to be used in TryFixIt as indicator
buffer is a buffer for a text description of the problem
iBufLen is the length of buffer
--------------------------------------------------------------------*/
static void RGGetError(void *data, int *iCode, char *buffer,
int iBufLen){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
*iCode = self->errorType;
switch(self->errorType){
case NONE:
strncpy(buffer,"No error found",iBufLen);
break;
case BADPOS:
strncpy(buffer,"Position not reached",iBufLen);
break;
case FAIL:
strncpy(buffer,"Hardware is mad",iBufLen);
break;
case STARTFAIL:
strncpy(buffer,"Failed to start motor",iBufLen);
break;
case READFAIL:
strncpy(buffer,"Failed to read motor",iBufLen);
break;
}
}
/*------------------------------------------------------------------
TryAndFixIt tries everything which is possible in software to fix
a problem. iError is the error code from GetError, newValue is
the target value for the motor
Possible retrun values are:
MOTOK : everything fixed
MOTREDO : try again
MOTFAIL : cannot fix this
--------------------------------------------------------------------*/
static int RGFixIt(void *data, int iError, float newValue){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
if(self->recover == 1){
self->errorType = NONE;
return MOTREDO;
}
return MOTFAIL;
}
/*-------------------------------------------------------------------
Halt tries to stop the motor. Halt errors are ignored
---------------------------------------------------------------------*/
static int RGHalt(void *data){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
self->errorType = NONE;
return 1;
}
/*--------------------------------------------------------------------
GetDriverPar retrieves the value of a driver parameter.
Name is the name of the parameter, fValue the value when found.
Returns 0 on success, 0 else
-----------------------------------------------------------------------*/
static int RGGetDriverPar(void *data, char *name, float *value){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
if(strcmp(name,"errortype") == 0){
*value = (float)self->errorType;
return 1;
} else if (strcmp(name,"recover") == 0){
*value = self->recover;
return 1;
}
return 0;
}
/*----------------------------------------------------------------------
SetDriverPar sets a driver parameter. Returns 0 on failure, 1 on
success. Name is the parameter name, pCon the connection to report
errors too, value the new value
------------------------------------------------------------------------*/
static int RGSetDriverPar(void *data, SConnection *pCon,
char *name, float value){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
if(strcmp(name,"errortype") == 0){
self->errorType = (int)value;
return 1;
} else if (strcmp(name,"recover") == 0){
self->recover = (int)value;
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------
ListDriverPar lists the names and values of driver parameters to
pCon. Motorname is the name of the motor ro prefix to the listing.
-------------------------------------------------------------------------*/
static void RGListDriverPar(void *data, char *motorname,
SConnection *pCon){
RGMotorDriver *self = NULL;
char buffer[256];
self = (RGMotorDriver *)data;
snprintf(buffer,255,"%s errortype = %d", motorname,
self->errorType);
SCWrite(pCon,buffer,eValue);
snprintf(buffer,255,"%s recover = %d", motorname,
self->recover);
SCWrite(pCon,buffer,eValue);
}
/*-----------------------------------------------------------------------
KillPrivate has the task to delete possibly dynamically allocated
memory in the private part of the driver structure
------------------------------------------------------------------------*/
static void RGKillPrivate(void *data){
RGMotorDriver *self = NULL;
self = (RGMotorDriver *)data;
}
/*=======================================================================*/
MotorDriver *RGMakeMotorDriver(void) {
RGMotorDriver *pNew = NULL;
pNew = malloc(sizeof(RGMotorDriver));
if(pNew == NULL){
return NULL;
}
memset(pNew,0,sizeof(RGMotorDriver));
pNew->GetPosition = RGGetPos;
pNew->RunTo = RGRunTo;
pNew->GetStatus = RGCheckStatus;
pNew->GetError = RGGetError;
pNew->TryAndFixIt = RGFixIt;
pNew->Halt = RGHalt;
pNew->GetDriverPar = RGGetDriverPar;
pNew->SetDriverPar = RGSetDriverPar;
pNew->ListDriverPar = RGListDriverPar;
pNew->KillPrivate = RGKillPrivate;
pNew->fLower = -180.;
pNew->fUpper = 180.;
return (MotorDriver *)pNew;
}

1032
motor.c

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,6 @@
typedef struct __Motor {
pObjectDescriptor pDescriptor;
ObPar *ParArray;
pIDrivable pDrivInt;
pICallBack pCall;
char *drivername;

View File

@ -373,6 +373,31 @@ static void putSicsData(SConnection *pCon, SicsInterp *pSics,
}
}
/*----------------------------------------------------------------------*/
static void putAttribute(SConnection *pCon, SicsInterp *pSics,
pNXScript self, int argc, char *argv[]){
int status, type = NX_CHAR;
char buffer[256];
if(argc < 5){
SCWrite(pCon,"ERROR: insufficient number of arguments to putAttribute",
eError);
return;
}
status = NXDopenalias(self->fileHandle,self->dictHandle,argv[2]);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to open alias %s", argv[2]);
SCWrite(pCon,buffer,eError);
return;
}
status = NXputattr(self->fileHandle,argv[3],(void *)argv[4],
strlen(argv[4])+1, type);
if(status != NX_OK){
sprintf(buffer,"ERROR: failed to write attribute %s", argv[3]);
SCWrite(pCon,buffer,eError);
}
}
/*----------------------------------------------------------------------*/
static void updateHMDim(NXScript *self, pHistMem mem){
int iDim[MAXDIM];
int i, rank, timeLength, status;
@ -412,7 +437,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
pNXScript self,
int argc, char *argv[]){
pHistMem mem = NULL;
int status, start, length, i, subset = 0;
int status, start, length, i, subset = 0, bank = 0;
HistInt *iData = NULL;
char buffer[256];
@ -461,6 +486,19 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
}
}
/*
* check for additional bank number
*/
if(argc > 6){
status = Tcl_GetInt(InterpGetTcl(pSics),argv[6],&bank);
if(status != TCL_OK){
sprintf(buffer,"ERROR: failed to convert %s to integer",
argv[6]);
SCWrite(pCon,buffer,eError);
return;
}
}
/*
read HM
*/
@ -472,7 +510,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
return;
}
memset(iData,0,length*sizeof(HistInt));
status = GetHistogramDirect(mem,pCon,0,start,start+length,iData,
status = GetHistogramDirect(mem,pCon,bank,start,start+length,iData,
length*sizeof(HistInt));
}else{
/*
@ -980,6 +1018,9 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
}else if(strcmp(argv[1],"putsicsdata") == 0){
/*===============*/
putSicsData(pCon,pSics,self,argc,argv);
}else if(strcmp(argv[1],"putattribute") == 0){
/*===============*/
putAttribute(pCon,pSics,self,argc,argv);
} else {
SCWrite(pCon,"ERROR: put command not recognised",eError);
}

View File

@ -28,8 +28,9 @@
int iRet;
/* Find the motor */
strtolower(pName);
pMot = FindMotor(pSics,pName);
strncpy(pBueffel,pName,511);
strtolower(pBueffel);
pMot = FindMotor(pSics,pBueffel);
if(!pMot)
{
sprintf(pBueffel,"WARNING: cannot find motor %s",pName);
@ -58,8 +59,9 @@
int iRet;
/* Find the motor */
strtolower(pName);
pMot = FindMotor(pSics,pName);
strncpy(pBueffel,pName,511);
strtolower(pBueffel);
pMot = FindMotor(pSics,pBueffel);
if(!pMot)
{
sprintf(pBueffel,"WARNING: cannot find motor %s",pName);
@ -95,8 +97,9 @@
char *pText = NULL;
/* find it */
strtolower(pName);
pVar = FindVariable(pSics,pName);
strncpy(pBueffel,pName,511);
strtolower(pBueffel);
pVar = FindVariable(pSics,pBueffel);
if(!pVar)
{
sprintf(pBueffel,"WARNING: cannot find variable %s",pName);

View File

@ -519,38 +519,13 @@ static int ClimbDrive(SConnection *pCon,char *name, float value)
}
return 1;
}
/*-------------------------------------------------------------------------*/
static int ClimbVariable(pOptimise self, SConnection *pCon, int i)
{
pOVarEntry pOvar;
void *pData;
int status, direction = 1;
long oneCount, twoCount, lastCount, currentCount;
float varValue, startValue;
char buffer[256];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
/*------------------------------------------------------------------------*/
static int findDirection(pOptimise self, pOVarEntry pOvar, SConnection *pCon)
{
int status, direction;
float varValue;
long oneCount, twoCount;
assert(self);
assert( (i >= 0) && (i < self->iVar));
assert(pCon);
/* get variable data */
DynarGet(self->pVariables,i,&pData);
pOvar = (pOVarEntry)pData;
startValue = pOvar->fCenter;
/*
* prepare scan object
*/
self->pScanner->pCon = pCon;
self->pScanner->pSics = pServ->pSics;
self->pScanner->iNP = 1;
self->pScanner->iMode = self->eCount;
self->pScanner->fPreset = self->fPreset;
/*
* test for upwards direction
*/
varValue = pOvar->fCenter + pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
@ -584,14 +559,46 @@ static int ClimbDrive(SConnection *pCon,char *name, float value)
if(oneCount > twoCount)
{
direction = 1;
lastCount = oneCount;
}
else
{
direction = -1;
lastCount = twoCount;
}
return direction;
}
/*-------------------------------------------------------------------------*/
static int ClimbVariable(pOptimise self, SConnection *pCon, int i)
{
pOVarEntry pOvar;
void *pData;
int status, direction = 1;
long oneCount, twoCount, lastCount, currentCount;
float varValue, startValue;
char buffer[256];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
assert(self);
assert( (i >= 0) && (i < self->iVar));
assert(pCon);
/* get variable data */
DynarGet(self->pVariables,i,&pData);
pOvar = (pOVarEntry)pData;
startValue = pOvar->fCenter;
/*
* prepare scan object
*/
self->pScanner->pCon = pCon;
self->pScanner->pSics = pServ->pSics;
self->pScanner->iNP = 1;
self->pScanner->iMode = self->eCount;
self->pScanner->fPreset = self->fPreset;
direction = findDirection(self,pOvar, pCon);
if(direction < 0){
return direction;
}
/*
* drive to the last best position
*/
@ -601,6 +608,11 @@ static int ClimbDrive(SConnection *pCon,char *name, float value)
{
return DRIVEERROR;
}
lastCount = ClimbCount(self,pCon);
if(lastCount < 0)
{
return SCANERROR;
}
currentCount = lastCount;
/*

2
scan.c
View File

@ -1540,7 +1540,7 @@ static int PrintCountsOrMonitors(pScanData self, SConnection *pCon,
if(iWhich < 0)
{
GetScanCounts(self,lData,self->iNP);
snprintf(pBueffel,59,"%s.counts = {", name);
snprintf(pBueffel,59,"%s.Counts = {", name);
}
else
{

View File

@ -17,7 +17,7 @@
#include "scan.h"
#include "HistMem.h"
#include "sicsdata.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*--------------------------------------------------------------------*/
static void KillSICSData(void *pData){
pSICSData self = NULL;
@ -236,6 +236,74 @@ static int putFloat(pSICSData self, int argc, char *argv[],
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------*/
static int getPos(pSICSData self, char *name,
SConnection *pCon, int pos){
char pBueffel[512];
float value;
if(pos >= self->dataUsed){
SCWrite(pCon,"ERROR: requested position out of range",eError);
return 0;
}
if(self->dataType[pos] == FLOATTYPE){
memcpy(&value,&self->data[pos],sizeof(float));
snprintf(pBueffel,511,"%s = %f", name, value);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
if(self->dataType[pos] == INTTYPE){
snprintf(pBueffel,511,"%s = %d", name, self->data[pos]);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
return 0;
}
/*------------------------------------------------------------------*/
static float getDataPos(pSICSData self, int pos){
float value;
assert(pos < self->dataUsed);
if(self->dataType[pos] == FLOATTYPE){
memcpy(&value,&self->data[pos],sizeof(float));
} else {
value = (float)self->data[pos];
}
return value;
}
/*------------------------------------------------------------------*/
static int divideSicsData(pSICSData self, SicsInterp *pSics,
SConnection *pCon, char *name){
int i;
pSICSData other = NULL;
float val, div;
other = (pSICSData)FindCommandData(pSics,name,"SICSData");
if(other == NULL){
SCWrite(pCon,"ERROR: requested SICSData object to divide not found",
eError);
return 0;
}
if(other->dataUsed < self->dataUsed){
SCWrite(pCon,"ERROR: not enough data in SICSData for division",
eError);
return 0;
}
for(i = 0; i < self->dataUsed; i++){
div = getDataPos(other,i);
if(ABS(div) > .00001){
val = getDataPos(self,i)/div;
} else {
val = .0;
}
if(self->dataType[i] == INTTYPE){
self->data[i] = (int)val;
} else {
memcpy(&self->data[i],&val,sizeof(float));
}
}
return 1;
}
/*-------------------------------------------------------------------*/
static int copyScanCounts(pSICSData self, int argc, char *argv[],
SConnection *pCon, SicsInterp *pSics){
@ -482,6 +550,7 @@ int SICSDataAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pSICSData self = NULL;
char pBueffel[132];
int pos;
self = (pSICSData)pData;
assert(self);
@ -509,6 +578,19 @@ int SICSDataAction(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
return dumpSICSData(self,argv[2],pCon);
} else if(strcmp(argv[1],"get") == 0){
if(argc < 3){
SCWrite(pCon,"ERROR: need a position to read",eError);
return 0;
}
pos = atoi(argv[2]);
return getPos(self,argv[0],pCon,pos);
} else if(strcmp(argv[1],"divideby") == 0){
if(argc < 3){
SCWrite(pCon,"ERROR: need a SICSdata to divide by",eError);
return 0;
}
return divideSicsData(self,pSics,pCon,argv[2]);
} else if(strcmp(argv[1],"putint") == 0){
/*---------- putint */
return putInt(self,argc-2,&argv[2],pCon, pSics);

View File

@ -54,6 +54,7 @@ pHdbCallback MakeCheckPermissionCallback(int priv){
if(testPriv == NULL){
return NULL;
}
*testPriv = priv;
return MakeHipadabaCallback(SICSCheckPermissionCallback, testPriv,free,-1,-1);
}
/*-------------------------------------------------------------------------------------*/
@ -352,6 +353,117 @@ pHdbCallback MakeFloatRangeCallback(double min, double max){
return MakeHipadabaCallback(SICSFloatRangeCallback, range,
free,-1,-1);
}
/*-------------------------------------------------------------------------*/
static int MemReadCallback(void *userData, void *callData, pHdb node,
hdbValue v){
float *value = NULL;
value = (float *)userData;
if(value != NULL){
v.dataType = HIPFLOAT;
v.v.doubleValue = (float) *value;
node->value.v.doubleValue = (double)*value;
}
return 1;
}
/*------------------------------------------------------------------------*/
static int MemGenReadCallback(void *userData, void *callData, pHdb node,
hdbValue v){
switch(node->value.dataType){
case HIPINT:
node->value.v.intValue = *(int *)userData;
break;
case HIPFLOAT:
node->value.v.doubleValue = *(double *)userData;
break;
case HIPTEXT:
if(node->value.v.text != NULL){
free(node->value.v.text);
}
node->value.v.text = strdup((char *)userData);
break;
case HIPINTAR:
memcpy(&node->value.v.intArray,userData,
node->value.arrayLength *sizeof(int));
break;
case HIPFLOATAR:
memcpy(&node->value.v.floatArray,userData,
node->value.arrayLength *sizeof(double));
break;
default:
assert(0);
break;
}
return 1;
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeMemGenReadCallback(void *address){
return MakeHipadabaCallback(MemReadCallback, address,
NULL,-1,-1);
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeMemReadCallback(float *address){
return MakeHipadabaCallback(MemReadCallback, address,
NULL,-1,-1);
}
/*-------------------------------------------------------------------------*/
static int MemSetCallback(void *userData, void *callData, pHdb node,
hdbValue v){
float *value = NULL;
value = (float *)userData;
if(value != NULL){
*value = (float)v.v.doubleValue;
}
UpdateHipadabaPar(node,v,callData);
return 1;
}
/*-------------------------------------------------------------------------*/
static int MemGenSetCallback(void *userData, void *callData, pHdb node,
hdbValue v){
const char *pPtr = NULL;
if(v.dataType != node->value.dataType){
assert(0);
return 0;
}
switch(node->value.dataType){
case HIPINT:
memcpy(userData,&v.v.intValue,sizeof(int));
break;
case HIPFLOAT:
memcpy(userData,&v.v.doubleValue,sizeof(double));
break;
case HIPTEXT:
strncpy((char *)userData,(const char *)v.v.text,
node->value.arrayLength);
break;
case HIPINTAR:
memcpy(userData,&v.v.intArray,node->value.arrayLength*sizeof(int));
break;
case HIPFLOATAR:
memcpy(userData,&v.v.floatArray,
node->value.arrayLength*sizeof(double));
break;
default:
assert(0);
return 0;
break;
}
UpdateHipadabaPar(node,v,callData);
return 1;
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeMemSetCallback(float *address){
return MakeHipadabaCallback(MemSetCallback, address,
NULL,-1,-1);
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeMemGenSetCallback(void *address){
return MakeHipadabaCallback(MemSetCallback, address,
NULL,-1,-1);
}
/*--------------------------------------------------------------------------*/
static void killHdbValue(void *pData){
hdbValue *v = NULL;
@ -384,7 +496,7 @@ static int SICSIntFixedCallback(void *userData, void *callData, pHdb node,
return SICSCBBADFIXED;
}
/*---------------------------------------------------------------------------*/
pHdbCallback MakeIntFixedCallback(long *data, int length){
pHdbCallback MakeIntFixedCallback(int *data, int length){
pHdbCallback result = NULL;
hdbValue *v = NULL;
@ -394,11 +506,11 @@ pHdbCallback MakeIntFixedCallback(long *data, int length){
}
v->dataType = HIPINTAR;
v->arrayLength = length;
v->v.intArray = malloc(length*sizeof(long));
v->v.intArray = malloc(length*sizeof(int));
if(v->v.intArray == NULL){
return NULL;
}
memcpy(v->v.intArray,data,length*sizeof(long));
memcpy(v->v.intArray,data,length*sizeof(int));
return MakeHipadabaCallback(SICSIntFixedCallback, v,
killHdbValue,-1,-1);
}
@ -462,6 +574,39 @@ pHdb MakeSICSHdbDriv(char *name, int priv, void *sicsObject, int dataType){
return result;
}
/*---------------------------------------------------------------------------*/
pHdb MakeSICSMemPar(char *name, int priv, float *address){
pHdb result = NULL;
pHdbCallback pHcb = NULL;
result = MakeHipadabaNode(name,HIPFLOAT,1);
if(result == NULL){
return NULL;
}
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(result);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeMemSetCallback(address);
if(pHcb == NULL){
DeleteHipadabaNode(result);
return NULL;
}
AppendHipadabaCallback(result,HCBSET,pHcb);
pHcb = MakeMemReadCallback(address);
if(pHcb == NULL){
DeleteHipadabaNode(result);
return NULL;
}
AppendHipadabaCallback(result,HCBREAD,pHcb);
return result;
}
/*----------------------------------------------------------------------------*/
pHdb MakeSICSROPar(char *name, hdbValue v){
pHdb result = NULL;
@ -566,6 +711,68 @@ void RemoveSICSPar(pHdb node){
SICSDeleteNodeData(node);
}
/*===================== add functions =======================================*/
int AddSICSHdbPar(pHdb node, char *name, int priv, hdbValue v){
pHdb child = NULL;
child = MakeSICSHdbPar(name,priv,v);
if(child == NULL){
return 0;
}
AddHipadabaChild(node,child);
return 1;
}
/*---------------------------------------------------------------------------*/
int AddSICSHdbROPar(pHdb node, char *name, hdbValue v){
pHdb child = NULL;
child = MakeSICSROPar(name,v);
if(child == NULL){
return 0;
}
AddHipadabaChild(node,child);
return 1;
}
/*--------------------------------------------------------------------------*/
int AddSICSHdbMemPar(pHdb node, char *name, int priv,
void *data, int datalength, int type, int length){
pHdb child = NULL;
pHdbCallback pHcb = NULL;
if(type == HIPINTVARAR || type == HIPFLOATVARAR){
assert(0);
return 0;
}
child = MakeHipadabaNode(name,type,length);
if(child == NULL){
return 0;
}
pHcb = MakeCheckPermissionCallback(priv);
if(pHcb == NULL){
DeleteHipadabaNode(child);
return 0;
}
AppendHipadabaCallback(child,HCBSET,pHcb);
pHcb = MakeMemGenSetCallback(data);
if(pHcb == NULL){
DeleteHipadabaNode(child);
return 0;
}
AppendHipadabaCallback(child,HCBSET,pHcb);
pHcb = MakeMemGenReadCallback(data);
if(pHcb == NULL){
DeleteHipadabaNode(child);
return 0;
}
AppendHipadabaCallback(child,HCBREAD,pHcb);
AddHipadabaChild(node,child);
return 1;
}
/*==================== access suport functions ==============================*/
int SICSHdbGetFloat(pHdb parent, SConnection *pCon,
char *path, float *value){
@ -620,7 +827,7 @@ int SICSHdbSetFloat(pHdb parent, SConnection *pCon,
if(v.dataType == HIPFLOAT){
v.v.doubleValue = (double)value;
} else if(v.dataType == HIPINT){
v.v.intValue = (long)value;
v.v.intValue = (int)value;
} else {
/*
* it is an error to call this for array dada types
@ -668,7 +875,7 @@ int ProcessSICSHdbPar(pHdb root, SConnection *pCon,
assert(root != NULL && pCon != NULL);
if(argc < 1){
SCWrite(pCon,"ERROR: nor parameter to treat specified",eError);
SCWrite(pCon,"ERROR: no parameter to treat specified",eError);
return -1;
}
@ -705,6 +912,10 @@ int ProcessSICSHdbPar(pHdb root, SConnection *pCon,
DeleteDynString(parData);
status = SetHipadabaPar(parNode,input,pCon);
ReleaseHdbValue(&input);
if(status == 1){
SCSendOK(pCon);
SCparChange(pCon);
}
return status;
} else {
/*
@ -730,6 +941,65 @@ int ProcessSICSHdbPar(pHdb root, SConnection *pCon,
return 1;
}
}
/*--------------------------------------------------------------------------*/
void PrintSICSParList(pHdb node, SConnection *pCon, char *prefix){
char childPrefix[1024];
pHdb child = NULL;
pDynString value = NULL;
hdbValue v;
child = node->child;
while(child != NULL){
if(child->value.dataType != HIPNONE){
GetHipadabaPar(child,&v,pCon);
value = formatValue(child->value);
if(value != NULL){
SCPrintf(pCon,eValue,"%s%s = %s", prefix, child->name,
GetCharArray(value));
DeleteDynString(value);
}
}
if(child->child != NULL){
strncpy(childPrefix,prefix,1024);
strncat(childPrefix,child->name, 1024);
strncat(childPrefix,"/",1024);
PrintSICSParList(child, pCon,prefix);
}
child = child->next;
}
}
/*---------------------------------------------------------------------------*/
void SaveSICSHipadaba(FILE *fd, pHdb node, char *prefix){
pHdb currentChild = NULL;
pDynString data = NULL;
hdbValue v;
currentChild = node->child;
while(currentChild != NULL){
if(currentChild->value.dataType != HIPNONE && !isSICSHdbRO(currentChild)){
GetHipadabaPar(currentChild,&v,NULL);
data = formatValue(currentChild->value);
if(data != NULL){
fprintf(fd,"%s%s %s\n", prefix, currentChild->name, GetCharArray(data));
DeleteDynString(data);
}
}
if(currentChild->child != NULL){
/*
* build a new prefix string and recurse
*/
data = CreateDynString(64,64);
if(data != NULL){
DynStringCopy(data,prefix);
DynStringConcat(data,currentChild->name);
DynStringConcat(data,"/");
SaveSICSHipadaba(fd,currentChild,GetCharArray(data));
DeleteDynString(data);
}
}
currentChild = currentChild->next;
}
}
/*---------------------------------------------------------------------------*/
int SICSHipadabaTask(void *pData){
pHdbUpdateTask self = NULL;
@ -798,7 +1068,7 @@ pDynString formatValue(hdbValue v){
case HIPNONE:
break;
case HIPINT:
snprintf(number,30,"%ld", v.v.intValue);
snprintf(number,30,"%d", v.v.intValue);
DynStringCopy(result,number);
break;
case HIPFLOAT:
@ -811,7 +1081,7 @@ pDynString formatValue(hdbValue v){
case HIPINTAR:
case HIPINTVARAR:
for(i = 0; i < v.arrayLength; i++){
snprintf(number,30," %ld", v.v.intArray[i]);
snprintf(number,30," %d", v.v.intArray[i]);
DynStringConcat(result,number);
}
break;
@ -861,11 +1131,11 @@ static int adjustDataLength(hdbValue *v, char *data){
if(v->v.intArray != NULL){
free(v->v.intArray);
}
v->v.intArray = malloc(count*sizeof(long));
v->v.intArray = malloc(count*sizeof(int));
if(v->v.intArray == NULL){
return 0;
}
memset(v->v.intArray,0,count*sizeof(long));
memset(v->v.intArray,0,count*sizeof(int));
}
if(v->dataType == HIPFLOATVARAR){
if(v->v.floatArray != NULL){
@ -883,7 +1153,7 @@ static int adjustDataLength(hdbValue *v, char *data){
/*---------------------------------------------------------------------------------*/
int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
int i, status;
long lValue;
int lValue;
double dValue;
char number[80];
char *pPtr = NULL;
@ -893,7 +1163,7 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
break;
case HIPINT:
getNextHdbNumber(data,number);
status = sscanf(number,"%ld", &v->v.intValue);
status = sscanf(number,"%d", &v->v.intValue);
if(status != 1){
snprintf(error,errlen,"Failed to convert %s to integer",
data);
@ -928,7 +1198,7 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
i);
return 0;
}
status = sscanf(number,"%ld", &lValue);
status = sscanf(number,"%d", &lValue);
if(status != 1){
snprintf(error,errlen,"Failed to convert %s to integer",
data);
@ -1286,6 +1556,90 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 1;
}
/*--------------------------------------------------------------------------*/
static int countChildren(pHdb node){
pHdb current = NULL;
int count = 0;
current = node->child;
while(current != NULL){
count++;
current = current->next;
}
return count;
}
/*---------------------------------------------------------------------------*/
static int HdbNodeInfo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb targetNode = NULL;
char error[512], oriPath[512], info[512];
int i, status, length;
if(argc < 2) {
SCWrite(pCon,"ERROR: need path to node to get info",eError);
return 0;
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
if(targetNode == NULL){
return 0;
}
length = targetNode->value.arrayLength;
if(length == 0){
length = 1;
}
snprintf(info,511,"%s,%d,%d",hdbTypeToText(targetNode->value.dataType),
countChildren(targetNode), length);
SCWrite(pCon,info,eValue);
return 1;
}
/*---------------------------------------------------------------------------*/
static int HdbNodeVal(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb targetNode = NULL;
hdbValue newValue;
pDynString parData = NULL;
char error[512];
int i, status;
if(argc < 2) {
SCWrite(pCon,"ERROR: need path to node to print",eError);
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
if(targetNode == NULL){
return 0;
}
memset(&newValue,0,sizeof(hdbValue));
GetHipadabaPar(targetNode, &newValue, pCon);
parData = formatValue(newValue);
if(parData == NULL){
SCWrite(pCon,"ERROR: out of memory formatting data",eError);
return 0;
}
SCWrite(pCon,GetCharArray(parData),eValue);
DeleteDynString(parData);
ReleaseHdbValue(&newValue);
return 1;
}
/*---------------------------------------------------------------------------*/
int isSICSHdbRO(pHdb node){
pHdbCallback current = NULL;
current = node->writeCallbacks;
while(current != NULL){
if(current->userCallback == SICSReadOnlyCallback) {
return 1;
}
current = current->next;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static pDynString formatPlainList(pHdb node){
pHdb current;
@ -1317,6 +1671,7 @@ static pDynString formatListWithVal(pHdb node){
current = node->child;
while(current != NULL){
if(current->value.dataType != HIPNONE){
DynStringConcat(result,current->name);
data = formatValue(current->value);
if(data != NULL){
@ -1325,22 +1680,11 @@ static pDynString formatListWithVal(pHdb node){
DeleteDynString(data);
}
DynStringConcat(result,"\n");
}
current = current->next;
}
return result;
}
/*--------------------------------------------------------------------------*/
static int countChildren(pHdb node){
pHdb current = NULL;
int count = 0;
current = node->child;
while(current != NULL){
count++;
current = current->next;
}
return count;
}
/*---------------------------------------------------------------------------*/
static pDynString formatClientList(pHdb node){
pHdb current;
@ -1375,7 +1719,7 @@ static pDynString formatClientList(pHdb node){
case HIPNONE:
break;
case HIPINT:
snprintf(number,50,"%ld",current->value.v.intValue);
snprintf(number,50,"%d",current->value.v.intValue);
DynStringConcat(result,number);
break;
case HIPFLOAT:
@ -1388,7 +1732,7 @@ static pDynString formatClientList(pHdb node){
case HIPINTAR:
case HIPINTVARAR:
for(i = 0; i < length; i++){
snprintf(number,50,"%ld",current->value.v.intArray[i]);
snprintf(number,50,"%d",current->value.v.intArray[i]);
DynStringConcat(result,number);
if(i > length -1){
DynStringConcat(result,",");
@ -1495,6 +1839,66 @@ static int RemoveHdbCallback(SConnection *pCon, SicsInterp *pSics, void *pData,
return 1;
}
/*---------------------------------------------------------------------------*/
static int LinkHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb node = NULL;
char buffer[256];
CommandList *pCom = NULL;
pDummy pDum = NULL;
if(argc < 3) {
SCWrite(pCon,"ERROR: need path and object name to link",
eError);
return 0;
}
if(!SCMatchRights(pCon,usMugger)){
return 0;
}
node = GetHipadabaNode(root,argv[1]);
if(node == NULL){
snprintf(buffer,255,"ERROR: path %s NOT found!", argv[1]);
SCWrite(pCon,buffer,eError);
return 0;
}
pCom = FindCommand(pSics,argv[2]);
if(pCom == NULL){
snprintf(buffer,255,"ERROR: failed to find object %s", argv[2]);
SCWrite(pCon,buffer,eError);
return 0;
}
pDum = pCom->pData;
if(pDum == NULL || pDum->pDescriptor->parNode == NULL){
snprintf(buffer,255,
"ERROR: Object %s does not use Hipadaba natively and thus cannot be linked",
argv[2]);
SCWrite(pCon,buffer,eError);
return 0;
}
if(pDum->pDescriptor->parNode->mama != NULL){
snprintf(buffer,255,
"ERROR: Object %s is already linked somewhere else",
argv[2]);
SCWrite(pCon,buffer,eError);
return 0;
}
AddHipadabaChild(node,pDum->pDescriptor->parNode);
if(argc > 3){
if(pDum->pDescriptor->parNode->name != NULL){
free(pDum->pDescriptor->parNode->name);
}
pDum->pDescriptor->parNode->name = strdup(argv[3]);
}
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------------*/
void killSICSHipadaba(){
if(root != NULL){
DeleteHipadabaNode(root);
@ -1535,6 +1939,9 @@ int InstallSICSHipadaba(SConnection *pCon, SicsInterp *pSics, void *pData,
AddCommand(pSics,"hlist", ListHdbNode, NULL, NULL);
AddCommand(pSics,"hnotify", AutoNotifyHdbNode, NULL, NULL);
AddCommand(pSics,"hdelcb", RemoveHdbCallback, NULL, NULL);
AddCommand(pSics,"hlink", LinkHdbNode, NULL, NULL);
AddCommand(pSics,"hinfo", HdbNodeInfo, NULL, NULL);
AddCommand(pSics,"hval", HdbNodeVal, NULL, NULL);
return 1;
}

View File

@ -81,7 +81,7 @@ pHdbCallback MakeIntRangeCallback(int min, int max);
* @return a suitably configured callback or NULL
* when out of memory
*/
pHdbCallback MakeIntFixedCallback(long *data, int length);
pHdbCallback MakeIntFixedCallback(int *data, int length);
/**
* make a callback for checking if a parameter is within a given
* range of floats
@ -91,6 +91,22 @@ pHdbCallback MakeIntFixedCallback(long *data, int length);
* when out of memory
*/
pHdbCallback MakeFloatRangeCallback(double min, double max);
/**
* make a callback which reads a memory address (perhaps in a
* data structure) which is a float value
* @param address The address of the parameter
* @return a suitable callback for reading this parameter.
*/
pHdbCallback MakeMemReadCallback(float *address);
/**
* make a callback which sets a memory address (perhaps in a
* data structure) which is a float value. It is assumed that
* this is a direct parameter, i.e, UpdateHipadabaPar is
* automatically called.
* @param address The address of the parameter
* @return a suitable callback for setting this parameter.
*/
pHdbCallback MakeMemSetCallback(float *address);
/*======================== parameter creation ===================================*/
/**
* make a simple SICS hdb parameter. Setting it will call update immediately. Use
@ -111,8 +127,15 @@ pHdb MakeSICSHdbPar(char *name, int priv, hdbValue v);
* @param dataType The datatype of this variable
* @return A new suitably configured Hdb parameter or NULL when out of memory.
*/
pHdb MakeSICSHdbDriv(char *name, int priv,void *sicsObject, int datatype);
/**
* make SICS hdb variable which is connected to a memory location, perhaps in
* an objects data structure.
* @param name The name of the variable
* @param priv The privilege required to set this parameter
* @param address A pointer to the memory location of the variable.
*/
pHdb MakeSICSMemPar(char *name, int priv, float *address);
/**
* makes a SICS Hdb read only parameter. Setting such a parameter causes an error.
* @param name The name of the parameter
@ -137,6 +160,38 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v
* @param node The node to delete
*/
void RemoveSICSPar(pHdb node);
/*=============== Add par functions =======================================*/
/**
* add a new simple hdb parameter as child to node
* @param node The node to add the new node too.
* @param priv The privilege required to change that parameter
* @param v The initial value and datatype of this parameter
* @return 1 on success, 0 else
*/
int AddSICSHdbPar(pHdb node, char *name, int priv, hdbValue v);
/**
* add a new read only hdb parameter as child to node
* @param node The node to add the new node too.
* @param v The initial value and datatype of this parameter
* @return 1 on success, 0 else
*/
int AddSICSHdbROPar(pHdb node, char *name, hdbValue v);
/**
* Add a new hdb parameter as child to node. Updates are synced
* to the memory location data. This works for simple variables, fixed size
* arrays and fixed sized strings. This does not work for dynamically sized
* arrays or strings.
* @param node The node to add the new node too.
* @param priv The privilege required to change that parameter
* @param data The pointer to map this parameter too. This must be in
* dynamically allocated memory.
* @param datalength The length of the data area pointed to by data.
* @param type The data type of the parameter
* @param length The length of the type. Used for array types.
* @return 1 on success, 0 else
*/
int AddSICSHdbMemPar(pHdb node, char *name, int priv,
void *data, int datalength, int type, int length);
/*============== access support functions =================================*/
/**
* SICSHdbGetFloat returns the float value of a parameter. Integers are
@ -160,6 +215,12 @@ int SICSHdbGetFloat(pHdb parent, SConnection *pCon,
*/
int SICSHdbSetFloat(pHdb parent, SConnection *pCon,
char *path, float value);
/**
* query function if a parameter is read only.
* @param node The ndoe to query
* @return 1 when RO, 0 else
*/
int isSICSHdbRO(pHdb node);
/*============= common SICS Interactions ===================================*/
/**
* Install a SICS automatic notification callback on the node. This is
@ -187,6 +248,23 @@ int InstallSICSNotify(pHdb node, SConnection *pCon, int id, int recurse);
*/
int ProcessSICSHdbPar(pHdb root, SConnection *pCon, char *printPrefix,
int argc, char *argv[]);
/**
* print a listing of the parameters of node to pCon, using the
* specified prefix.
* @param The node to print
* @pCon The connection to print too
* @prefix The prefix to use for printing
*/
void PrintSICSParList(pHdb node, SConnection *pCon, char *prefix);
/**
* save the content of the Hipadaba starting at node into a file. This can
* be used to save the configuration of an instrument. This routine is
* recursive.
* @param fd The file to write to
* @param node The node to print from
* @param prefix A prefix to use for printing.
*/
void SaveSICSHipadaba(FILE *fd, pHdb node, char *prefix);
/**
* A SICS task which scans a Hipadaba and reads and updates all parameters,
* one per invocation. TODO: how to distinguish between automatic pars which

View File

@ -1,7 +1,19 @@
# Counter counter
counter SetPreset 10.000000
counter SetMode Timer
hm CountMode timer
hm preset 10.000000
hm genbin 0.000000 10.000000 10000
hm init
exe batchpath ./
exe syspath ./
# Motor brumm
brumm sign 1.0000
brumm hardlowerlim -180.0000
brumm hardupperlim 180.0000
brumm softlowerlim -180.0000
brumm softupperlim 180.0000
brumm softzero 0.0000
brumm fixed -1.0000
brumm interruptmode 0.0000
brumm precision 0.2000
brumm accesscode 2.0000
brumm failafter 3.0000
brumm maxretry 3.0000
brumm ignorefault 0.0000
brumm movecount 10.0000
brumm errortype 0.0000
brumm recover 1.0000

8
velo.c
View File

@ -326,6 +326,7 @@ static void VSListForbidden(pVelSel self, SConnection *pCon){
pVelSel VSCreate(pMotor pTilt, pVelSelDriv pDriv)
{
pVelSel pNew = NULL;
SConnection *pCon = NULL;
assert(pTilt);
assert(pDriv);
@ -389,7 +390,12 @@ static void VSListForbidden(pVelSel self, SConnection *pCon){
/* deal with that motor, have him AccessCode Internal */
pNew->pTilt = pTilt;
ObParInit(pTilt->ParArray,8,"accesscode",(float)usInternal,usInternal);
pCon = SCCreateDummyConnection(pServ->pSics);
if(pCon != NULL)
{
MotorSetPar(pTilt,pCon,"accesscode",(float)usInternal);
SCDeleteConnection(pCon);
}
/* enter driver */
pNew->pDriv = pDriv;