- Fixed a singlex death when there was no lambda. Was a problem during

shutdown when nothing works as it should
- Made an attempt to have all error message printed on demand
- Added a tricsswap feature to sinqhttp which swaps the data right for SICS
- Edited speed for phytron driver
- First attack on adding a misalignment calculation to tasub
- Added a test protocol for scriptcontext which can be configured.


SKIPPED:
	psi/sinqhttp.c
This commit is contained in:
koennecke
2010-03-09 13:12:01 +00:00
parent 09cc25ec5b
commit 40ff36d142
13 changed files with 282 additions and 19 deletions

View File

@ -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:

View File

@ -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)
{

View File

@ -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\

1
ofac.c
View File

@ -40,6 +40,7 @@ static void InitGeneral(void)
INIT(CommandLogInit);
INIT(UdpInit);
INIT(HelpInit);
INIT(AddTestProt);
INIT(SiteInit); /* site specific initializations */
}

View File

@ -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);

View File

@ -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;
}
}
/*---------------------------------------------------------------------------*/

11
tasub.c
View File

@ -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]);

View File

@ -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.
*/

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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
@ -687,3 +688,15 @@ if {${dc-804} == 1} {
makesctcontroller dc804sct std localhost:8080 "\r" 10 "\x03" "\x03"
pimotor::makepimotor dc1 1 dc804sct -10000 10000
}
proc testprot {input} {
return "${input}_hugo_appended_by_Tcl"
}
proc testerr {input} {
error "$input is SO abyssimally wrong!"
}
makesctcontroller echo testprot testprot.dat

169
testprot.c Normal file
View File

@ -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 <stdio.h>
#include <tcl.h>
#include <sics.h>
#include <ascon.h>
#include <ascon.i>
#include <stringdict.h>
/*--------------------------------------------------------------------------*/
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);
}