From bae18e86868a715faf77e1f61ecac26379e08d0e Mon Sep 17 00:00:00 2001 From: cvs Date: Fri, 16 Mar 2001 16:09:33 +0000 Subject: [PATCH] - Various little fixes to the TAS software - Added a sync command for synchronizing a simulation server with the master server. --- Makefile | 15 ++-- countdriv.h | 2 +- counter.c | 4 +- danu.dat | 2 +- histsim.c | 2 +- macro.c | 27 ++++++ macro.h | 2 + nserver.c | 41 ++++----- nserver.h | 1 + nserver.tex | 3 + nserver.w | 3 + ofac.c | 8 ++ scan.c | 10 ++- sicsstat.tcl | 24 +++--- sicsstatus.tcl | 10 +-- simcter.c | 20 ++++- simsync.w | 45 ++++++++++ synchronize.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ synchronize.h | 19 +++++ tas.h | 1 + tascom.tcl | 64 ++++++++++---- tasdrive.c | 38 +++++++-- tasscan.c | 4 +- test.tcl | 2 +- 24 files changed, 494 insertions(+), 78 deletions(-) create mode 100644 simsync.w create mode 100644 synchronize.c create mode 100644 synchronize.h diff --git a/Makefile b/Makefile index 2c383f58..1f9148cf 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ #---------------------------------------------------------------------------- # Makefile for SICS # -# Mark Koennecke 1996-2000 +# Mark Koennecke 1996-2001 # Markus Zolliker March 2000: add tecs #--------------------------------------------------------------------------- @@ -16,12 +16,15 @@ FORTIFYOBJ = #----- comment or uncomment if a difrac version is required -#DIFOBJ= -#DIFIL= +# Do not forget to remove or add comments to ofac.c as well if changes +# were made here. + +DIFOBJ= +DIFIL= #DIFOBJ=difrac.o -Ldifrac -ldif -lfor #---- -DIFOBJ=difrac.o -Ldifrac -ldif -DIFIL= difrac.o +#DIFOBJ=difrac.o -Ldifrac -ldif +#DIFIL= difrac.o #--------------------------------------------------------------------------- @@ -44,7 +47,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ hklscan.o xytable.o amor2t.o nxamor.o amorscan.o amorstat.o \ circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o \ tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \ - tasdrive.o tasscan.o + tasdrive.o tasscan.o synchronize.o MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/countdriv.h b/countdriv.h index d988428b..95c703ff 100644 --- a/countdriv.h +++ b/countdriv.h @@ -83,6 +83,6 @@ /* PSI Simulation counter, if you have no hardware */ /* simcter.c */ - pCounterDriver NewSIMCounter(char *name); + pCounterDriver NewSIMCounter(char *name, float fVal); void KillSIMCounter(pCounterDriver self); #endif diff --git a/counter.c b/counter.c index 8358c834..3d8d7a60 100644 --- a/counter.c +++ b/counter.c @@ -485,7 +485,7 @@ FuPaResult pParse; FuncTemplate MakeTemplate[] = { {"el737",3,{FUPATEXT,FUPAINT,FUPAINT}}, - {"sim",0,{0.0}} + {"sim",1,{FUPAFLOAT}} }; assert(pCon); @@ -510,7 +510,7 @@ pParse.Arg[1].iVal,pParse.Arg[2].iVal); break; case 1: /* SIM */ - pDriv = NewSIMCounter(argv[1]); + pDriv = NewSIMCounter(argv[1],pParse.Arg[0].fVal); break; default: assert(0); /* internal error */ diff --git a/danu.dat b/danu.dat index 3f540b0f..2ac72590 100644 --- a/danu.dat +++ b/danu.dat @@ -1,3 +1,3 @@ - 7665 + 7671 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!|n \ No newline at end of file diff --git a/histsim.c b/histsim.c index 15ebf433..eb0d0939 100644 --- a/histsim.c +++ b/histsim.c @@ -242,7 +242,7 @@ } /* put a SIMcounter in */ - pNew->pPriv = (void *)NewSIMCounter("HistoSim"); + pNew->pPriv = (void *)NewSIMCounter("HistoSim",-1.); if(!pNew->pPriv) { DeleteHistDriver(pNew); diff --git a/macro.c b/macro.c index f08a6d9d..692e6b3e 100644 --- a/macro.c +++ b/macro.c @@ -648,6 +648,33 @@ extern Tcl_Interp *InterpGetTcl(SicsInterp *pSics); } return 1; } +/*----------------------------------------------------------------------*/ + int Broadcast(SConnection *pCon, SicsInterp *pInter, void *pData, + int argc, char *argv[]) + { + int iMacro; + char pBueffel[256]; + + assert(pCon); + assert(pInter); + + if(argc < 2) + { + SCWrite(pCon,"Insufficient arguments to Broadcast",eError); + return 0; + } + + + /* now write, thereby tunneling macro flag in order to get proper + write to client and not into interpreter + */ + Arg2Text(argc-1, &argv[1],pBueffel,255); + iMacro = SCinMacro(pCon); + SCsetMacro(pCon,0); + ServerWriteGlobal(pBueffel,eWarning); + SCsetMacro(pCon,iMacro); + return 1; + } /*--------------------------------------------------------------------------- This implements a scheme to provide Tcl commands to Tcl. The Tcl commands (either procedures or objects) must be defined in a separate file. Than diff --git a/macro.h b/macro.h index 47309177..b69e2103 100644 --- a/macro.h +++ b/macro.h @@ -30,6 +30,8 @@ int argc, char *argv[]); int ClientPut(SConnection *pCon, SicsInterp *pInter, void *pData, int argc, char *argv[]); + int Broadcast(SConnection *pCon, SicsInterp *pInter, void *pData, + int argc, char *argv[]); int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); diff --git a/nserver.c b/nserver.c index fb283ff5..b6f77a8f 100644 --- a/nserver.c +++ b/nserver.c @@ -304,25 +304,28 @@ TaskerDelete(&self->pTasker); /* save status */ - strcpy(pBueffel,"Backup "); - pText = IFindOption(pSICSOptions,"statusfile"); - if(pText) - { - strcat(pBueffel,pText); - } - else - { - strcat(pBueffel,DEFAULTSTATUSFILE); - } - pCon = SCCreateDummyConnection(self->pSics); - if(pCon) - { - InterpExecute(self->pSics,pCon,pBueffel); - SCDeleteConnection(pCon); - } - else - { - printf("ERROR: Cannot allocate dummy connection, status NOT saved"); + if(!self->simMode) + { + strcpy(pBueffel,"Backup "); + pText = IFindOption(pSICSOptions,"statusfile"); + if(pText) + { + strcat(pBueffel,pText); + } + else + { + strcat(pBueffel,DEFAULTSTATUSFILE); + } + pCon = SCCreateDummyConnection(self->pSics); + if(pCon) + { + InterpExecute(self->pSics,pCon,pBueffel); + SCDeleteConnection(pCon); + } + else + { + printf("ERROR: Cannot allocate dummy connection, status NOT saved"); + } } /* close redirection file if present */ diff --git a/nserver.h b/nserver.h index c3224d21..24b130d8 100644 --- a/nserver.h +++ b/nserver.h @@ -31,6 +31,7 @@ pEnvMon pMonitor; mkChannel *pServerPort; pNetRead pReader; + int simMode; } SicsServer; diff --git a/nserver.tex b/nserver.tex index 74dfcac8..20fe70a3 100644 --- a/nserver.tex +++ b/nserver.tex @@ -18,6 +18,7 @@ $\langle$servdat {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ pEnvMon pMonitor;@\\ \mbox{}\verb@ mkChannel *pServerPort;@\\ \mbox{}\verb@ pNetRead pReader;@\\ +\mbox{}\verb@ int simMode;@\\ \mbox{}\verb@ } SicsServer;@\\ \mbox{}\verb@@$\diamond$ \end{list} @@ -40,6 +41,8 @@ This module monitors sample environment controllers. the SICS server is listening for connections. \item[pReader] points to a data structure which defines the network communication object. +\item[simMode] a flag which is true when the SICS server is a simulation + server. \end{description} diff --git a/nserver.w b/nserver.w index cdabff63..84bcbef2 100644 --- a/nserver.w +++ b/nserver.w @@ -13,6 +13,7 @@ the system: pEnvMon pMonitor; mkChannel *pServerPort; pNetRead pReader; + int simMode; } SicsServer; @} @@ -28,6 +29,8 @@ This module monitors sample environment controllers. the SICS server is listening for connections. \item[pReader] points to a data structure which defines the network communication object. +\item[simMode] a flag which is true when the SICS server is a simulation + server. \end{description} diff --git a/ofac.c b/ofac.c index 6cfa058e..0d073bb1 100644 --- a/ofac.c +++ b/ofac.c @@ -103,6 +103,7 @@ #include "sicscron.h" #include "lin2ang.h" #include "tas.h" +#include "synchronize.h" /*----------------------- Server options creation -------------------------*/ static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -197,6 +198,7 @@ AddCommand(pInter,"InternEval",InternalFileEval,NULL,NULL); AddCommand(pInter,"FileWhere",MacroWhere,WhereKill,NULL); AddCommand(pInter,"ClientPut",ClientPut,NULL,NULL); + AddCommand(pInter,"broadcast",Broadcast,NULL,NULL); AddCommand(pInter,"transact",TransactAction,NULL,NULL); AddCommand(pInter,"sicsprompt", SicsPrompt,NULL,NULL); AddCommand(pInter,"Publish",TclPublish,NULL,NULL); @@ -272,9 +274,12 @@ AddCommand(pInter,"MakeStoreAmor",AmorStoreMake,NULL,NULL); AddCommand(pInter,"MakeAmorStatus",AmorStatusFactory,NULL,NULL); AddCommand(pInter,"MakeMaximize",MaximizeFactory,NULL,NULL); +/* AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL); +*/ AddCommand(pInter,"MakeLin2Ang",MakeLin2Ang,NULL,NULL); AddCommand(pInter,"MakeTAS",TASFactory,NULL,NULL); + AddCommand(pInter,"MakeSync",MakeSync,NULL,NULL); } /*---------------------------------------------------------------------------*/ static void KillIniCommands(SicsInterp *pSics) @@ -323,9 +328,12 @@ RemoveCommand(pSics,"MakeStoreAmor"); RemoveCommand(pSics,"MakeAmorStatus"); RemoveCommand(pSics,"MakeMaximize"); +/* RemoveCommand(pSics,"MakeDifrac"); +*/ RemoveCommand(pSics,"MakeLin2Ang"); RemoveCommand(pSics,"MakeTAS"); + RemoveCommand(pSics,"MakeSync"); } diff --git a/scan.c b/scan.c index 782df5b8..8ea70b6e 100644 --- a/scan.c +++ b/scan.c @@ -41,6 +41,13 @@ extern void SNXFormatTime(char *pBuffer, int iLen); char pNumText[10]; CommandList *pCom = NULL; + /* + make a simulated filename if in simulation mode + */ + if(pServ->simMode) + return strdup("sim001001901.sim"); + + /* Try, get all the Variables */ pPath = FindVariable(pSics,"sicsdatapath"); pPref = FindVariable(pSics,"sicsdataprefix"); @@ -1256,7 +1263,8 @@ extern void SNXFormatTime(char *pBuffer, int iLen); pPtr = ScanMakeFileName(self->pSics,self->pCon,self->ext); if(!pPtr) { - SCWrite(self->pCon,"ERROR: cannot allocate new data filename, Scan aborted", + SCWrite(self->pCon, + "ERROR: cannot allocate new data filename, Scan aborted", eError); self->pCon = NULL; self->pSics = NULL; diff --git a/sicsstat.tcl b/sicsstat.tcl index d4a155c5..499edb7f 100644 --- a/sicsstat.tcl +++ b/sicsstat.tcl @@ -1,4 +1,4 @@ -scaninfo 9,en,2.800000,0.050000 +scaninfo 7,en,-0.300000,0.100000 scaninfo setAccess 0 sicsdatapath /data/koenneck/src/sics/tmp/ sicsdatapath setAccess 1 @@ -26,7 +26,7 @@ etam 0.000000 etam setAccess 2 wav 0.000000 wav setAccess 2 -den 0.050000 +den 0.100000 den setAccess 2 dql 0.000000 dql setAccess 2 @@ -98,9 +98,9 @@ alf1 11.000000 alf1 setAccess 2 local Mordahl Schlawadini local setAccess 2 -output a1,a2,a3,a4 +output a4 output setAccess 2 -lastcommand sc qh 2 0 0 3 dqh 0 0 0 .05 ti 2 np 9 +lastcommand sc en 0 den .1 np 7 ti 2 lastcommand setAccess 2 user Billy Looser user setAccess 2 @@ -132,7 +132,7 @@ mn 700 mn setAccess 2 ti 2.000000 ti setAccess 2 -np 9 +np 7 np setAccess 2 fx 2 fx setAccess 2 @@ -146,7 +146,7 @@ da 3.354000 da setAccess 1 dm 3.354000 dm setAccess 1 -en 3.000000 +en 0.300000 en setAccess 2 ql 0.000000 ql setAccess 2 @@ -158,9 +158,9 @@ kf 1.964944 kf setAccess 2 ef 8.000000 ef setAccess 2 -ki 2.304101 +ki 2.001447 ki setAccess 2 -ei 11.000000 +ei 8.300000 ei setAccess 2 bz 1.000000 bz setAccess 2 @@ -176,11 +176,11 @@ ax 1.000000 ax setAccess 2 cc 90.000000 cc setAccess 2 -bb 67.889999 +bb 90.000000 bb setAccess 2 aa 90.000000 aa setAccess 2 -cs 7.000000 +cs 5.000000 cs setAccess 2 bs 5.000000 bs setAccess 2 @@ -303,8 +303,8 @@ a6 InterruptMode 0.000000 a6 AccessCode 2.000000 # Motor a5 a5 SoftZero 176.479996 -a5 SoftLowerLim -376.479980 -a5 SoftUpperLim 23.520004 +a5 SoftLowerLim -200.000000 +a5 SoftUpperLim 380.000000 a5 Fixed -1.000000 a5 sign 1.000000 a5 InterruptMode 0.000000 diff --git a/sicsstatus.tcl b/sicsstatus.tcl index e73c4b81..1a9eb239 100644 --- a/sicsstatus.tcl +++ b/sicsstatus.tcl @@ -12,9 +12,9 @@ hm init datafile focus-1001848.hdf datafile setAccess 3 hm2 CountMode timer -hm2 preset 2.000000 +hm2 preset 100.000000 hm1 CountMode timer -hm1 preset 2.000000 +hm1 preset 100.000000 dbfile UNKNOWN dbfile setAccess 2 # Motor th @@ -150,8 +150,6 @@ lastscancommand UNKNOWN lastscancommand setAccess 2 banana CountMode timer banana preset 2.000000 -banana genbin 100.000000 13.000000 64 -banana init sample_mur 0.000000 sample_mur setAccess 2 email UNKNOWN @@ -163,7 +161,7 @@ phone setAccess 2 adress UNKNOWN adress setAccess 2 # Counter counter -counter SetPreset 100.000000 +counter SetPreset 10.000000 counter SetMode Timer # Motor som som SoftZero 0.000000 @@ -435,5 +433,5 @@ sample DanielOxid sample setAccess 2 title TopsiTupsiTapsi title setAccess 2 -starttime 2001-01-29 16:18:12 +starttime 2001-03-12 14:55:05 starttime setAccess 2 diff --git a/simcter.c b/simcter.c index 6b7950a4..72fc3d73 100644 --- a/simcter.c +++ b/simcter.c @@ -50,7 +50,7 @@ A SIMCOUNTER HAS a BUILT IN FAILURE RATE OF 10% FOR TESTING ERROR HANDLING CODE. A negative failure rate means absolute success. */ -#define FAILRATE 0.05 +static float FAILRATE; /*----------------------------------------------------------------------------*/ static float SimRandom(void) { @@ -147,6 +147,11 @@ pSim->lEnd = 0; } + if(FAILRATE < .0) + { + return OKOK; + } + if(SimRandom() < FAILRATE) { return HWFault; @@ -195,6 +200,11 @@ pSim->iPause = 0; + if(FAILRATE < .0) + { + return OKOK; + } + if(SimRandom() < FAILRATE) { return HWFault; @@ -212,6 +222,11 @@ pSim = (SimSt *)self->pData; assert(pSim); + if(FAILRATE < .0) + { + return OKOK; + } + if(SimRandom() < FAILRATE) { return HWFault; @@ -295,7 +310,7 @@ return 1; } /*---------------------------------------------------------------------------*/ - pCounterDriver NewSIMCounter(char *name) + pCounterDriver NewSIMCounter(char *name, float fFail) { pCounterDriver pRes = NULL; SimSt *pData = NULL; @@ -335,6 +350,7 @@ pRes->Get = SIMGet; pRes->Send = SIMSend; + FAILRATE = fFail; return pRes; } /*--------------------------------------------------------------------------*/ diff --git a/simsync.w b/simsync.w new file mode 100644 index 00000000..ea52a60d --- /dev/null +++ b/simsync.w @@ -0,0 +1,45 @@ +\subsection{Synchronizing with other SICS server} +A common demand is to have a simulation server for testing command files or +checking complex instrument movements. For such uses the simulation SICS +server must be synchrnized at times with the actual SICS server running the + instrument. This is the purpose of this module. It works by sending a + backup command to to the actual SICS server and then runs the restore + command. In order for this scheme to work properly, both the simulation + and the real SICS server must be configured to read the same status file. + The installation of this module also sets a flag in the SICS servers + general data structure which can be used by other system components in order + to modify behaviour in simulation mode. For instance the writing of data + files can be inhibited. + + As the simulation server must be able to run independently from the actual + SICS server, it was considered sufficient to update the state of the + simulation server manually. As this may break other simulations currently + running a broadcast message about the action is sent to all connected + clients. + + The interface to this module is just the interpreter function doing + the sync and the object creation function. + +@d syncint @{ + int MakeSync(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + int Synchronize(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + +@} + +@o synchronize.h @{ +/* + S y n c h r o n i z e + + Synchronize parameters in this server with parameters from another + SICS server. + + Mark Koennecke, March 2001 +*/ +#ifndef SICSSYNC +#define SICSSYNC +@ +#endif +@} + diff --git a/synchronize.c b/synchronize.c new file mode 100644 index 00000000..2d66421a --- /dev/null +++ b/synchronize.c @@ -0,0 +1,225 @@ +/* + S y n c h r o n i z e + + Synchronize parameters in this server with parameters from another + SICS server. + + Mark Koennecke, March 2001 +*/ +#include "sics.h" +#include "network.h" +#include "synchronize.h" + +/*----------------------------------------------------------------------- + Some file statics which hold the connection parameters + ------------------------------------------------------------------------*/ +static char *hostname, *looser, *password; +static int port; +static mkChannel *connection = NULL; +/*-----------------------------------------------------------------------*/ +static void syncLogin() +{ + int test, i; + char pBueffel[1024], pRead[80]; + + /* + connect + */ + connection = NETConnect(hostname, port); + NETRead(connection,pBueffel,1020,10*1000); + if(connection != NULL) + { + /* + try a login + */ + sprintf(pBueffel,"%s %s\n", looser, password); + test = NETWrite(connection,pBueffel,strlen(pBueffel)); + if(test != 1) + { + printf("Failed at writing user/password\n"); + NETClosePort(connection); + free(connection); + connection = NULL; + } + + pBueffel[0] = '\0'; + for(i = 0; i < 10; i++) + { + test = NETRead(connection,pRead,70,10*1000); + if(test < 0) + { + NETClosePort(connection); + free(connection); + connection = NULL; + } + else + { + strcat(pBueffel,pRead); + } + if(strstr(pBueffel,"Login OK") == NULL) + { + test = 0; + } + else + { + test = 1; + } + SicsWait(1); + } + if(!test) + { + printf("Bad reply to login: %s\n",pBueffel); + NETClosePort(connection); + free(connection); + connection = NULL; + } + } +} +/*---------------------------------------------------------------------*/ +static void killSync(void *pData) +{ + if(connection) + { + NETClosePort(connection); + free(connection); + } + if(hostname) + free(hostname); + if(looser) + free(looser); + if(password) + free(password); +} +/*----------------------------------------------------------------------*/ +int MakeSync(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]) +{ + char pBueffel[256]; + int iRet; + + /* + check arguments: we need host, port, user and passwd + */ + if(argc < 5) + { + SCWrite(pCon, + "ERROR: need parameters: host port user passwd : for sync creation", + eError); + return 0; + } + /* + copy parameters + */ + hostname = strdup(argv[1]); + port = atof(argv[2]); + looser = strdup(argv[3]); + password = strdup(argv[4]); + pServ->simMode = 1; + + /* + add the command to the Interpreter + */ + iRet = AddCommand(pSics,"sync",Synchronize,killSync,NULL); + if(!iRet) + { + sprintf(pBueffel,"ERROR: duplicate command sync not created"); + killSync(NULL); + SCWrite(pCon,pBueffel,eError); + return 0; + } + + return 1; +} +/*----------------------------------------------------------------------*/ +int Synchronize(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]) +{ + char pBueffel[1024]; + char pRead[80]; + int test,i; + + /* + check for connection + */ + if(connection == NULL) + { + syncLogin(); + if(connection == NULL) + { + sprintf(pBueffel,"ERROR: failed to connect to %s, %d for sync 'ing", + hostname, port); + SCWrite(pCon,pBueffel, eError); + return 0; + } + } + + /* + first tell the remote server to backup + */ + strcpy(pBueffel,"transact backup\n"); + test = NETWrite(connection,pBueffel,strlen(pBueffel)); + if(test != 1) + { + NETClosePort(connection); + free(connection); + connection = NULL; + SCWrite(pCon,"ERROR: Failed to contact sync server",eError); + SCWrite(pCon,"Try again in order to reconnect before giving up",eWarning); + return 0; + } + /* + wait 10 seconds for correct message + */ + pBueffel[0] = '\0'; + for(i = 0; i < 10; i++) + { + test = NETRead(connection,pRead,75,20*1000); + if(test < 0) + { + NETClosePort(connection); + free(connection); + connection = NULL; + SCWrite(pCon,"ERROR: Failed to contact sync server",eError); + SCWrite(pCon, + "Try again in order to reconnect before giving up",eWarning); + return 0; + } + else + { + strcat(pBueffel,pRead); + } + if(strstr(pBueffel,"TRANSACTIONFINISHED") == NULL) + { + test = 1; + break; + } + else + { + test = 0; + } + SicsWait(1); + } + if(!test) + { + SCWrite(pCon,"WARNING: sync server may not have exectued backup", + eWarning); + } + + /* + now read the backup file and we are done + */ + test = InterpExecute(pSics,pCon,"restore"); + if(test != 1) + { + SCWrite(pCon,"ERROR: Failed to read sync information",eError); + return 0; + } + + /* + tell everybody that we have sync'ed + */ + ServerWriteGlobal("Simulation Server has SYNCHRONIZED!",eWarning); + + return 1; +} + diff --git a/synchronize.h b/synchronize.h new file mode 100644 index 00000000..02018cc2 --- /dev/null +++ b/synchronize.h @@ -0,0 +1,19 @@ + +/* + S y n c h r o n i z e + + Synchronize parameters in this server with parameters from another + SICS server. + + Mark Koennecke, March 2001 +*/ +#ifndef SICSSYNC +#define SICSSYNC + + int MakeSync(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + int Synchronize(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + + +#endif diff --git a/tas.h b/tas.h index d94c0125..535a1266 100644 --- a/tas.h +++ b/tas.h @@ -110,6 +110,7 @@ #define MAXPAR 94 #define MAXADD 20 +#define MAXEVAR 10 /* --------------------- data structure -------------------------------*/ diff --git a/tascom.tcl b/tascom.tcl index 74df4bef..4d858e55 100644 --- a/tascom.tcl +++ b/tascom.tcl @@ -1,11 +1,11 @@ #--------------------------------------------------------------------------- # In order to run a triple axis spectrometer, SICS has to be made to behave -# like the ancinet MAD program from ILL. Some of the MAD commands had to +# like the ancient MAD program from ILL. Some of the MAD commands had to # be implemented in C (see tas*.c) but others can be implemented in Tcl. # This file contains the procedures and command definitions for this syntax # adaption from SICS to MAD. # -# Mark Koennecke, December 2000 +# Mark Koennecke, December 2000, March 2001 #-------------------------------------------------------------------------- @@ -16,8 +16,11 @@ if { [info exists tasinit] == 0 } { set tasinit 1 SicsAlias fileeval do User Publish ou User + Publish out User Publish fi User + SicsAlias fi fix User Publish cl User + SicsAlias cl clear Publish co User Publish fm User Publish fz User @@ -33,7 +36,6 @@ if { [info exists tasinit] == 0 } { Publish log User Publish sz User Publish sw User - Publish scaninfo Spy } #-------------------------------------------------------------------------- @@ -41,7 +43,6 @@ if { [info exists tasinit] == 0 } { set tasmot { a1 a2 a3 a4 a5 a6 mcv sro ach mtl mtu stl stu atu mgl sgl \ sgu agl} - #------------------------------------------------------------------------- # some MAD variables can be directly mapped to internal SICS variables. # Some others require special functions to be called for them to be set. @@ -106,7 +107,10 @@ proc madZero args { #-------------------------------------------------------------------------- # This routine throws an error if a bad value for fx is given -proc fxi {val} { +proc fxi { {val -1000} } { + if {$val == -1000} { + return [format " fx = %d " [tasSplit [fx]] ] + } if { $val != 1 && $val != 2} { error "ERROR: Invalid value $val for parameter FX" } else { @@ -115,11 +119,17 @@ proc fxi {val} { } #------------------------------------------------------------------------- -# Changing the scattering sense implies a change of the corresponding -# motors softzero as well: it is rotated by 180 degree. This is done -# by this function +# Changing the scattering sense has various consequences: +# for SM it is rejected as this requires a major rebuild of the guide hall. +# for SS only the parameter is changed. +# for SA - the parameter is changed +# - the A5 zero point is rotated by 180 degree +# - the lower software limit is set to the new zero point proc scatSense {par {val -1000} } { + if { [tasSplit $par] == $val } { + return + } switch $par { ss { set mot a3 @@ -141,18 +151,40 @@ proc scatSense {par {val -1000} } { if {$val != 1 && $val != -1 } { error "ERROR: invalid scattering sense $val" } - set oldzero [tasSplit [madZero $mot]] - madZero $mot [expr 180 + $oldzero] - $par $val + switch $par { + sm { + error \ + "REJECTED: Pay 100 mil. swiss francs for a redesign of SINQ first" + } + ss { + $par $val + clientput [format " SS = %d" $val] + } + sa { + set oldzero [tasSplit [madZero $mot]] + set newZero [expr $val*180 + $oldzero] + madZero $mot $newZero + a5 softlowerlim $newZero + $par $val + } + } } #-------------------------------------------------------------------------- # The output command + +proc out args { + if {[llength $args] == 0 } { + output "" + } else { + output [join $args] + } +} proc ou args { if {[llength $args] == 0 } { output "" - }else { + } else { output [join $args] } } @@ -395,7 +427,7 @@ proc varSet { command } { if { [info exists tasmap($token)] == 1} { set ret [catch {eval $tasmap($token) $value} msg] if { $ret != 0} { - error [format "ERROR: error %s while setting %s" $msg $token] + error [format "ERROR: > %s < while setting %s" $msg $token] } else { clientput [format " %s = %s" $token $value] } @@ -824,7 +856,7 @@ proc log args { proc sz args { global tasmot - set usage "\n Usage: \n\t sz motor newzero\n" + set usage "\n Usage: \n\t sz motor newval \n" set line [string tolower [join $args]] set pos 0 set mot [varToken $line $pos] @@ -851,7 +883,8 @@ proc sz args { "%-8sOld: %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f\n" \ $mot $loh $los $pos $targ $his $hih $zero] #-------action - madZero $mot $val + set newZero [expr $zero + ($val - $pos)] + madZero $mot $newZero #-------- more output set zero [tasSplit [madZero $mot]] set loh [tasSplit [eval $mot hardlowerlim]] @@ -981,4 +1014,3 @@ proc sw args { clientput [prsw] } } - diff --git a/tasdrive.c b/tasdrive.c index ec8a4316..a5aed3a1 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -65,13 +65,14 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, { pTASdata self = NULL; int iTAS = 0; - float tasTargets[20]; - unsigned char tasTargetMask[20], tasMask[10]; + float tasTargets[20], oldPos, oldEnergy[MAXEVAR]; + unsigned char tasTargetMask[20], tasMask[MAXEVAR]; char *pPtr, pToken[20], pLine[256]; int varPointer, i, motorPointer, status, rStatus, lastToken; char pBueffel[256]; unsigned char motorMask[MAXMOT]; float newPositions[MAXMOT]; + pMotor pMot; @@ -99,6 +100,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, motorMask[10+i] = 0; tasTargets[i] = .0; tasTargets[i+10] = .0; + oldEnergy[i] = .0; } for(i = 0; i < MAXMOT; i++) { @@ -144,6 +146,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, else if(varPointer >= 0 ) { tasMask[varPointer] = 1; + oldEnergy[varPointer] = self->tasPar[EMIN+varPointer]->fVal; self->tasPar[EMIN + varPointer]->fVal = atof(pToken); } else @@ -186,8 +189,17 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, { if(motorMask[i] > 0) { - sprintf(pBueffel,"Driving %s to %f", - tasMotorOrder[i],newPositions[i]); + pMot = FindMotor(pSics, tasMotorOrder[i]); + if(pMot) + { + MotorGetSoftPosition(pMot, pCon, &oldPos); + } + else + { + oldPos = -9999.; + } + sprintf(pBueffel,"Driving %s from %f to %f", + tasMotorOrder[i],oldPos,newPositions[i]); SCWrite(pCon,pBueffel,eWarning); status = StartMotor(pServ->pExecutor,pSics,pCon, tasMotorOrder[i],newPositions[i]); @@ -215,8 +227,9 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, { if(tasMask[i]) { - sprintf(pBueffel,"Driving %s to %f", tasVariableOrder[EI+i], - self->tasPar[EI+i]->fVal); + sprintf(pBueffel,"Driving %s from %f to %f", tasVariableOrder[EI+i], + oldEnergy[i], + self->tasPar[EI+i]->fVal); SCWrite(pCon,pBueffel,eWarning); } } @@ -227,8 +240,17 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, { if(tasTargetMask[i]) { - sprintf(pBueffel,"Driving %s to %f",tasMotorOrder[i], - tasTargets[i]); + pMot = FindMotor(pSics, tasMotorOrder[i]); + if(pMot) + { + MotorGetSoftPosition(pMot, pCon, &oldPos); + } + else + { + oldPos = -9999.; + } + sprintf(pBueffel,"Driving %s from %f to %f",tasMotorOrder[i], + oldPos, tasTargets[i]); SCWrite(pCon,pBueffel,eWarning); } } diff --git a/tasscan.c b/tasscan.c index 06c0126d..3e6cf19c 100644 --- a/tasscan.c +++ b/tasscan.c @@ -424,11 +424,11 @@ static int TASScanPoint(pScanData self, int iPoint) */ if(pTAS->iPOL > 0) { - sprintf(pBueffel,"%3d.%1d",iPoint,pTAS->iPOL); + sprintf(pBueffel,"%3d.%1d",iPoint+1,pTAS->iPOL); } else { - sprintf(pBueffel,"%4d ", iPoint); + sprintf(pBueffel,"%4d ", iPoint+1); } /* diff --git a/test.tcl b/test.tcl index cbea9fec..d6ebba17 100644 --- a/test.tcl +++ b/test.tcl @@ -177,7 +177,7 @@ SicsAlias MTL sax SicsAlias A3 som #-------------------------------------------------------------------------- # C O U N T E R S -MakeCounter counter SIM +MakeCounter counter SIM .05 #MakeCounter counter EL737 lnsp19.psi.ch 4000 4 #--------------------------------------------------------------------------