diff --git a/ascon.c b/ascon.c index fefb8408..59e12eb3 100644 --- a/ascon.c +++ b/ascon.c @@ -313,7 +313,7 @@ int AsconBaseHandler(Ascon * a) } else if (ret > 0) { a->state = AsconConnectDone; /* success */ } else if (ret < 0) { - AsconError(a, "ASC3", errno); + AsconError(a, "ASC3", errno); } break; case AsconWriteStart: diff --git a/conman.c b/conman.c index 958f5a9e..b204c967 100644 --- a/conman.c +++ b/conman.c @@ -5,7 +5,6 @@ below. - Mark Koennecke, October 1996 SMInvoke added. Mark Koennecke, April 1997 @@ -757,7 +756,30 @@ int SCNormalWrite(SConnection * self, char *buffer, int iOut) return 1; } +/*--------------------------------------------------------------------------*/ +int SCAllWrite(SConnection * self, char *buffer, int iOut) +{ + int i, iPtr, iRet; + if (!VerifyConnection(self)) { + return 0; + } + + if (buffer[0] == '\0' && iOut >= eStart && iOut <= eEvent) { + return 1; /* do not write empty line */ + } + + /* log it for any case */ + SICSLogWrite(buffer, iOut); + + testAndWriteCommandLog(self, buffer, iOut); + + testAndStoreInTcl(self, buffer, iOut); + + doSockWrite(self, buffer); + + return 1; +} /*--------------------------------------------------------------------------*/ int SCACTWrite(SConnection * self, char *buffer, int iOut) { diff --git a/make_gen b/make_gen index 35c91b44..8d95a3c0 100644 --- a/make_gen +++ b/make_gen @@ -8,7 +8,7 @@ COBJ = Sclient.o network.o ifile.o intcli.o $(FORTIFYOBJ) SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ servlog.o sicvar.o nserver.o SICSmain.o motorlist.o\ - sicsexit.o costa.o task.o $(FORTIFYOBJ) \ + sicsexit.o costa.o task.o $(FORTIFYOBJ) testprot.o\ macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \ devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \ lld_blob.o strrepl.o lin2ang.o fomerge.o napi5.o napi4.o\ diff --git a/ofac.c b/ofac.c index edfc8b8f..b5bb0ea8 100644 --- a/ofac.c +++ b/ofac.c @@ -40,6 +40,7 @@ static void InitGeneral(void) INIT(CommandLogInit); INIT(UdpInit); INIT(HelpInit); + INIT(AddTestProt); INIT(SiteInit); /* site specific initializations */ } diff --git a/protocol.c b/protocol.c index 95563a4e..569bfbe9 100644 --- a/protocol.c +++ b/protocol.c @@ -21,7 +21,7 @@ #define MAXMSG 1024 #define INIT_STR_SIZE 256 #define STR_RESIZE_LENGTH 256 -#define NUMPROS 6 +#define NUMPROS 7 #define PROLISTLEN 7 typedef struct __Protocol { pObjectDescriptor pDes; /* required as first field */ @@ -97,6 +97,8 @@ static int InitDefaultProtocol(SConnection * pCon, Protocol * pPro); /* Signatures for protocol writers implemented in this file */ int SCWriteSycamore(SConnection * pCon, char *pBuffer, int iOut); int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut); +/* Signatures for ptotocols from conman.c*/ +extern int SCAllWrite(SConnection * self, char *buffer, int iOut); /*--------------------------------------------------------------------------*/ pProtocol CreateProtocol(void) @@ -108,6 +110,7 @@ pProtocol CreateProtocol(void) "sycamore", "json", "act", + "all", NULL }; pProtocol pNew = NULL; @@ -301,6 +304,10 @@ static int ProtocolSet(SConnection * pCon, Protocol * pPro, char *pProName) SCSetWriteFunc(pMaster, SCACTWrite); SCSetWriteFunc(pCon, SCACTWrite); break; + case 6: + SCSetWriteFunc(pMaster, SCAllWrite); + SCSetWriteFunc(pCon, SCAllWrite); + break; case 0: /* default = psi_sics */ default: SCSetWriteFunc(pMaster, pPro->defaultWriter); diff --git a/singlex.c b/singlex.c index e9f8964b..5a9453de 100644 --- a/singlex.c +++ b/singlex.c @@ -732,7 +732,11 @@ const double *SXGetUB() { hdbValue v; pHdb node = NULL; - pSingleX priv = (pSingleX) singlex->pPrivate; + pSingleX priv ; + + assert(singlex != NULL); + + priv= (pSingleX) singlex->pPrivate; node = GetHipadabaNode(singlex->objectNode, "ub"); assert(node != NULL); @@ -833,9 +837,15 @@ double SXGetLambda() return val; } node = GetHipadabaNode(singlex->objectNode, "lambda"); - assert(node != NULL); +/* assert(node != NULL); GetHipadabaPar(node, &v, pServ->dummyCon); - return v.v.doubleValue; + */ + if(node != NULL){ + GetHipadabaPar(node, &v, pServ->dummyCon); + return v.v.doubleValue; + } else { + return 7.7; + } } /*---------------------------------------------------------------------------*/ diff --git a/tasub.c b/tasub.c index 21b83df5..8e8dd87a 100644 --- a/tasub.c +++ b/tasub.c @@ -347,7 +347,7 @@ int TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData, status += testMotor(pNew, pCon, "a5", A5); status += testMotor(pNew, pCon, "a6", A6); if (status != 8) { - SCWrite(pCon, "ERROR: a required motor is mssing, tasub NOT installed", + SCWrite(pCon, "ERROR: a required motor is missing, tasub NOT installed", eError); return 0; } @@ -1857,6 +1857,7 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, ptasUB self = NULL; char pBueffel[131]; int status, newSS; + double misalign = .0; self = (ptasUB) pData; assert(self != NULL); @@ -2008,6 +2009,14 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, pBueffel, eValue); return 1; } + } else if(strcmp(argv[1],"misalign") == 0){ + status = calcTasMisalignment(&self->machine, self->current,&misalign); + if(status != 1){ + SCWrite(pCon,"ERROR: failed to calculate misalignment, fix UB", eError); + return 0; + } + SCPrintf(pCon,eValue,"tasub.misalign = %f", misalign ); + return 1; } else if (strcmp(argv[1], "outofplane") == 0) { if (argc > 2) { strtolower(argv[2]); diff --git a/tasublib.c b/tasublib.c index ac897c69..73795334 100644 --- a/tasublib.c +++ b/tasublib.c @@ -519,6 +519,25 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal, mat_free(TV); return TVINV; } +/*-------------------------------------------------------------------------------*/ +int calcTasMisalignment(ptasMachine machine, tasQEPosition qe, double *misalign) +{ + MATRIX R; + int errorCode = 1; + double om; + + R = buildRMatrix(machine->UB, machine->planeNormal, qe, &errorCode); + if (R == NULL) { + return errorCode; + } + /** + * See below, notes on om + */ + om = Atan2d(R[1][0], R[0][0]); + *misalign = om; + mat_free(R); + return 1; +} /*-------------------------------------------------------------------------------*/ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe, @@ -550,7 +569,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe, om = atan(R[1][0],R[0][0]) where: R[1][0] = sin(om)cos(sgl) R[0][0] = cos(om)cos(sgl) - The definitions of th R components are taken from M. Lumsden + The definitions of the R components are taken from M. Lumsden R-matrix definition. */ diff --git a/tasublib.h b/tasublib.h index 954ec1b3..0915c3e4 100644 --- a/tasublib.h +++ b/tasublib.h @@ -234,6 +234,18 @@ int calcTasPowderAngles(ptasMachine machine, tasQEPosition qe, */ int calcTasPowderPosition(ptasMachine machine, tasAngles angles, ptasQEPosition qe); +/** + * calculate the misalignment of the crystal towards the goniometers. + * This is for people who love to manually adjust their crystal + * until it is paralel with the goniometers which in turn helps them + * understand what they are doing. + * @param machine The spectrometer parameters. + * @param qe The current qe position + * @param misalign An output parameter which then holds the value + * of the misalignment. + * @return 1 on success, a negative error code on errors + */ +int calcTasMisalignment(ptasMachine machine, tasQEPosition qe, double *misalign); /*======================= TAS Logic =====================================*/ /** * set triple axis parameters, thereby taking the tasMode into account diff --git a/tcl/phytron.tcl b/tcl/phytron.tcl index e11a2273..b476bea2 100644 --- a/tcl/phytron.tcl +++ b/tcl/phytron.tcl @@ -256,16 +256,17 @@ proc phytron::make {name axis controller lowlim upperlim} { $controller queue /sics/${name}/hardposition progress read $controller queue /sics/${name}/speed progress read } -#=============================================================================================== -# At MORPHEUS there is a special table where one motor needs a brake. This requires a digital I/O -# to be disabled before driving and enabled after driving. The code below adds this feature to +#====================================================================== +# At MORPHEUS there is a special table where one motor needs a brake. +# This requires a digital I/O to be disabled before driving and +# enabled after driving. The code below adds this feature to # a phytron motor -#----------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------ proc phytron::openset {out} { sct send [format "0A%dS" $out] return openans } -#---------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------ proc phytron::openans {axis name} { after 100 return [phytron::setpos $axis $name] diff --git a/test/sicsstat.tcl b/test/sicsstat.tcl index 23e6ac8e..ff69c514 100644 --- a/test/sicsstat.tcl +++ b/test/sicsstat.tcl @@ -248,5 +248,5 @@ cone qscale 1 cone center unknown simidx sttlim 0.2 simidx anglim 0.5 -simi preset 3 +simi preset 0 simi mode monitor diff --git a/test/testini.tcl b/test/testini.tcl index 09a3d3dc..0dcdb94d 100644 --- a/test/testini.tcl +++ b/test/testini.tcl @@ -641,11 +641,12 @@ set simhm 1 simi init #} -set phytron 0 +set phytron 1 if {$phytron == 1} { -makesctcontroller phyto phytron psts234:3002 5 +#makesctcontroller phyto phytron psts234:3002 5 +makesctcontroller phyto phytron morpheus-ts:3011 5 #makesctcontroller phyto phytron localhost:8080 5 -phyto debug -1 +phyto debug 0 source ../tcl/phytron.tcl @@ -686,4 +687,16 @@ if {${dc-804} == 1} { source ../tcl/pimotor.tcl makesctcontroller dc804sct std localhost:8080 "\r" 10 "\x03" "\x03" pimotor::makepimotor dc1 1 dc804sct -10000 10000 -} \ No newline at end of file +} + +proc testprot {input} { + return "${input}_hugo_appended_by_Tcl" +} + +proc testerr {input} { + error "$input is SO abyssimally wrong!" +} + + +makesctcontroller echo testprot testprot.dat + diff --git a/testprot.c b/testprot.c new file mode 100644 index 00000000..a64e297f --- /dev/null +++ b/testprot.c @@ -0,0 +1,169 @@ +/* + * This is a testing and simulation protocol for use with + * scriptcontext. This protocol does not build a network + * connection. Rather it has two modes of operation: + * - In the simplest mode of operation it just returns an echo of the + * command given. + * - When initialized with a filename it reads that file as a dictionary + * of commands and responses. Thus responses can be programmed. Through + * a special escape, stored as tclescape in the dictionary it executes + * the response as a Tcl function with the command string as a parameter. + * Thus replies can be programmed for software testing. + * + * testprot.c + * + * Created on: Feb 2, 2010 + * Author: Mark Koennecke + */ +#include +#include +#include +#include +#include +#include +/*--------------------------------------------------------------------------*/ +static void killDict(void *data) +{ + pStringDict dict = NULL; + if(data != NULL){ + dict = (pStringDict)data; + DeleteStringDict(dict); + } +} +/*--------------------------------------------------------------------------*/ +static void readDictionary(Ascon *a, SConnection *con, char *filename) +{ + pStringDict dict = NULL; + FILE *fd = NULL; + char pLine[256], *c; + + fd = fopen(filename,"r"); + if(fd == NULL){ + SCPrintf(con,eError,"ERROR: dictionary file %s not found!", filename); + return; + } + dict = CreateStringDict(); + if(dict == NULL){ + SCWrite(con,"ERROR: failed to allocate dictionary", eError); + return; + } + while(fgets(pLine,256,fd) != NULL){ + /* + * get rid of the trailing \n + */ + c = strrchr(pLine,'\n'); + if(c != NULL){ + *c = '\0'; + } + /* split at = */ + c = strchr(pLine,'='); + if(c == NULL){ + SCPrintf(con,eWarning, "WARNING: Invalid line %s in %s", + pLine, filename); + continue; + } + *c = '\0'; + StringDictAddPair(dict,pLine,c+1); + } + fclose(fd); + a->private = dict; + a->killPrivate = killDict; +} +/*--------------------------------------------------------------------------*/ +static int TestProtInit(Ascon *a, SConnection *con, int argc, char *argv[]) +{ + a->hostport = strdup("None"); + a->sendTerminator = strdup("\n"); + a->timeout = 0; + a->reconnectInterval = -1; /* immediate */ + a->replyTerminator = strdup("\n"); + if(argc > 0){ + readDictionary(a,con,argv[1]); + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static void findResponse(Ascon *a) +{ + pStringDict dict = NULL; + char tclEscape[80], response[256], *test = NULL, command[512]; + int status; + + DynStringClear(a->rdBuffer); + DynStringClear(a->errmsg); + /* simple echo operation */ + if(a->private == NULL){ + DynStringConcat(a->rdBuffer,GetCharArray(a->wrBuffer)); + return; + } + /* dictionary operation */ + memset(response,0,sizeof(response)); + memset(tclEscape,0,sizeof(tclEscape)); + + dict = (pStringDict)a->private; + status = StringDictGet(dict,GetCharArray(a->wrBuffer),response, sizeof(response)); + if(status != 1){ + a->state = AsconFailed; + DynStringConcat(a->errmsg,"ERROR: no response found in dictionary for "); + DynStringConcat(a->errmsg,GetCharArray(a->wrBuffer)); + return; + } + status = StringDictGet(dict,"tclescape",tclEscape,sizeof(tclEscape)); + if(status == 1){ + test = strstr(response, tclEscape); + if(test != NULL){ + /* Tcl operation! */ + test += strlen(tclEscape); + snprintf(command,sizeof(command),"%s %s", test, GetCharArray(a->wrBuffer)); + status = Tcl_Eval(InterpGetTcl(pServ->pSics), command); + if(status != TCL_OK){ + DynStringConcat(a->errmsg, "ERROR:"); + DynStringConcat(a->errmsg, (char *)Tcl_GetStringResult(InterpGetTcl(pServ->pSics))); + a->state = AsconFailed; + } else { + DynStringConcat(a->rdBuffer,(char *)Tcl_GetStringResult(InterpGetTcl(pServ->pSics))); + } + } else { + DynStringConcat(a->rdBuffer,response); + } + } else { + DynStringConcat(a->rdBuffer,response); + } +} +/*---------------------------------------------------------------------------*/ +static int TestProtHandler(Ascon * a) +{ + switch (a->state) { + case AsconConnectStart: + case AsconConnecting: + a->state = AsconConnectDone; + break; + case AsconWriteStart: + a->state = AsconWriting; + break; + case AsconWriting: + a->state = AsconWriteDone; + findResponse(a); + break; + case AsconReadStart: + a->state = AsconReading; + break; + case AsconReading: + a->state = AsconReadDone; + break; + default: + break; + } + return 1; +} +/*-------------------------------------------------------------------------*/ +void AddTestProt() +{ + AsconProtocol *prot = NULL; + + prot = calloc(sizeof(AsconProtocol), 1); + prot->name = strdup("testprot"); + prot->init = TestProtInit; + prot->handler = TestProtHandler; + AsconInsertProtocol(prot); +}