- Modified collective drive operations to run motors in individual tasks
- Added a processnode methos to scriptcontext. processnode waits for the scriptchain of a node to finish. - Fixed a bug in sicsget - Made histmemsec dim and rank manager privilege. To allow chnage at runtime. Is required for SANS - Fixed some issues with multicountersec, mostly relating to passing things through in a sensible way. - Updated motorsec.c to work with a client based driver SKIPPED: psi/polterwrite.c psi/tabledrive.c psi/tabledrive.h
This commit is contained in:
@ -47,6 +47,7 @@ typedef struct {
|
||||
pIDrivable pDriv;
|
||||
float value;
|
||||
int running;
|
||||
long taskID;
|
||||
} RealMotor, *pRealMotor;
|
||||
|
||||
/* Data passed by event generating object */
|
||||
@ -179,9 +180,9 @@ static int startMotorList(pConfigurableVirtualMotor self,
|
||||
iRet = LLDnodePtr2First(self->motorList);
|
||||
while (iRet != 0) {
|
||||
LLDnodeDataTo(self->motorList, &tuktuk);
|
||||
status = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.value);
|
||||
if (status != 1) {
|
||||
return status;
|
||||
tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.value);
|
||||
if (tuktuk.taskID < 0) {
|
||||
return HWFault;
|
||||
}
|
||||
tuktuk.running = 1;
|
||||
LLDnodeDataFrom(self->motorList, &tuktuk);
|
||||
@ -342,28 +343,12 @@ static int ConfCheckStatus(void *pData, SConnection * pCon)
|
||||
while (iRet != 0) {
|
||||
LLDnodeDataTo(self->motorList, &tuktuk);
|
||||
if (tuktuk.running == 1) {
|
||||
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
|
||||
switch (status) {
|
||||
case HWIdle:
|
||||
tuktuk.running = 0;
|
||||
status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
|
||||
if(status == 1){
|
||||
return HWBusy;
|
||||
} else {
|
||||
tuktuk.running = 0;
|
||||
LLDnodeDataFrom(self->motorList, &tuktuk);
|
||||
break;
|
||||
case HWBusy:
|
||||
result = HWBusy;
|
||||
break;
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
if(self->state != NULL){
|
||||
free(self->state);
|
||||
self->state = strdup("idle");
|
||||
}
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
this is a programming error and has to be fixed
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->motorList);
|
||||
|
2
conman.c
2
conman.c
@ -1846,7 +1846,7 @@ int ConfigCon(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
} else if (strcmp(argv[1], "rights") == 0) {
|
||||
if (argc < 4) {
|
||||
snprintf(pBueffel,511, "Insufficient number of args to %s", argv[0]);
|
||||
SCWrite(pCon, pBueffel, eInError);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
i = IsValidUser(argv[2], argv[3]);
|
||||
|
37
countersec.c
37
countersec.c
@ -425,6 +425,31 @@ static int CountCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
return DoCount((pCounter)ccmd, preset, con, 1);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int GetMonitorCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
long counts;
|
||||
pCounter self = (pCounter)ccmd;
|
||||
if(nPar < 1) {
|
||||
SCWrite(con,"ERROR: missing monitor no in getmonitor",eError);
|
||||
return 0;
|
||||
}
|
||||
counts = self->getMonitor(self,par[0]->value.v.intValue,con);
|
||||
SCPrintf(con,eValue,"%s.monitor.%d = %ld", self->name,
|
||||
par[0]->value.v.intValue,counts);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int GetCountsCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
long counts;
|
||||
pCounter self = (pCounter)ccmd;
|
||||
counts = self->getCounts(self,con);
|
||||
SCPrintf(con,eValue,"%s.counts = %ld", self->name,counts);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int CountNBCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
@ -587,12 +612,24 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
}
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("exponent", usUser,
|
||||
MakeHdbInt(0));
|
||||
if (child == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SetHdbProperty(child, "__save", "true");
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = AddSICSHdbPar(node,"count", usUser, MakeSICSFunc(CountCmd));
|
||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
||||
|
||||
child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd));
|
||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
||||
|
||||
child = AddSICSHdbPar(node,"getmonitor", usSpy, MakeSICSFunc(GetMonitorCmd));
|
||||
AddSICSHdbPar(child, "no", usSpy, MakeHdbInt(1));
|
||||
child = AddSICSHdbPar(node,"getcounts", usUser, MakeSICSFunc(GetCountsCmd));
|
||||
|
||||
child = AddSICSHdbPar(node,"stop", usUser, MakeSICSFunc(StopCmd));
|
||||
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
|
||||
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
|
||||
|
@ -254,8 +254,9 @@ static int SumCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||
lSum = sumWindow(dataNode->value.v.intArray, xstart,xend,dimNode->value.v.intArray[0],
|
||||
ystart, yend, dimNode->value.v.intArray[1]);
|
||||
SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
|
||||
break;
|
||||
default:
|
||||
SCPrintf(pCon,eError, "ERROR: summing not supported for %s dimensional data",
|
||||
SCPrintf(pCon, eError, "ERROR: summing not supported for %d dimensional data",
|
||||
dimNode->value.arrayLength);
|
||||
return 0;
|
||||
}
|
||||
@ -344,13 +345,13 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
DeleteHipadabaNode(child,pCon);
|
||||
}
|
||||
|
||||
child = MakeSICSHdbPar("rank", usInternal, MakeHdbInt(rank));
|
||||
child = MakeSICSHdbPar("rank", usMugger, MakeHdbInt(rank));
|
||||
if (child == NULL) {
|
||||
return 0;
|
||||
}
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTAR,rank));
|
||||
child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTVARAR,rank));
|
||||
if (child == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
18
macro.c
18
macro.c
@ -171,24 +171,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* check for endless loop */
|
||||
/* Arg2Text(margc, myarg, comBuffer, 131); */
|
||||
/* if (lastCommand != NULL) { */
|
||||
/* if (strcmp(lastCommand, comBuffer) == 0) { */
|
||||
/* Tcl_AppendResult(pInter, "ERROR: Never ending loop in unknown\n", */
|
||||
/* "Offending command: ", comBuffer, */
|
||||
/* " Probably Tcl command not found", NULL); */
|
||||
/* /\* SCSetInterrupt(pCon, eAbortBatch); */
|
||||
/* The interrupt cause me a problem in a race condition at BOA. */
|
||||
/* Try to understand why this check is necessary in the first place. */
|
||||
/* *\/ */
|
||||
/* return TCL_ERROR; */
|
||||
/* } */
|
||||
/* } */
|
||||
/* if (pSics->lastUnknown[pSics->iStack]) */
|
||||
/* free(pSics->lastUnknown[pSics->iStack]); */
|
||||
/* pSics->lastUnknown[pSics->iStack] = strdup(comBuffer); */
|
||||
|
||||
/* invoke */
|
||||
pCon->sicsError = 0;
|
||||
iMacro = SCinMacro(pCon);
|
||||
|
79
motorlist.c
79
motorlist.c
@ -6,6 +6,10 @@
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, September 2005
|
||||
|
||||
modified to use the task system
|
||||
|
||||
Mark Koennecke, January 2014
|
||||
-----------------------------------------------------------------------*/
|
||||
#include "motorlist.h"
|
||||
#include "lld.h"
|
||||
@ -73,17 +77,18 @@ static int MOLICheckLimits(void *data, float val, char *error, int errlen)
|
||||
------------------------------------------------------------------*/
|
||||
static long MOLISetValue(void *data, SConnection * pCon, float val)
|
||||
{
|
||||
int self = 0, iRet, test;
|
||||
int self = 0, iRet;
|
||||
MotControl tuktuk;
|
||||
|
||||
|
||||
self = *(int *) data;
|
||||
|
||||
iRet = LLDnodePtr2First(self);
|
||||
while (iRet != 0) {
|
||||
LLDnodeDataTo(self, &tuktuk);
|
||||
test = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.target);
|
||||
if (test != 1) {
|
||||
return test;
|
||||
tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.target);
|
||||
if (tuktuk.taskID < 0) {
|
||||
return HWFault;
|
||||
} else {
|
||||
tuktuk.running = 1;
|
||||
LLDnodeDataFrom(self, &tuktuk);
|
||||
@ -105,7 +110,7 @@ static long MOLISetValue(void *data, SConnection * pCon, float val)
|
||||
------------------------------------------------------------------*/
|
||||
static int MOLICheckStatus(void *data, SConnection * pCon)
|
||||
{
|
||||
int self = 0, iRet, status, result = HWIdle;
|
||||
int self = 0, iRet, status;
|
||||
MotControl tuktuk;
|
||||
|
||||
self = *(int *) data;
|
||||
@ -114,35 +119,17 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
|
||||
while (iRet != 0) {
|
||||
LLDnodeDataTo(self, &tuktuk);
|
||||
if (tuktuk.running == 1) {
|
||||
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
|
||||
switch (status) {
|
||||
case HWIdle:
|
||||
tuktuk.running = 0;
|
||||
status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
|
||||
if(status == 1){
|
||||
return HWBusy;
|
||||
} else {
|
||||
tuktuk.running = 0;
|
||||
LLDnodeDataFrom(self, &tuktuk);
|
||||
break;
|
||||
case HWBusy:
|
||||
result = HWBusy;
|
||||
break;
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
/**
|
||||
* It is questionable if one should not set a flag here
|
||||
* and keep polling: it is not clear if this error is a
|
||||
* communication problem or that the motor really
|
||||
* has stopped.
|
||||
*/
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
this is a programming error and has to be fixed
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self);
|
||||
}
|
||||
return result;
|
||||
return HWIdle;
|
||||
}
|
||||
/*---------------------------------------------------------
|
||||
A special version for EIGER. I am cautious: I have problems
|
||||
@ -151,39 +138,7 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
|
||||
-----------------------------------------------------------*/
|
||||
int MOLIEigerStatus(void *data, SConnection * pCon)
|
||||
{
|
||||
int self = 0, iRet, status, result = HWIdle;
|
||||
MotControl tuktuk;
|
||||
|
||||
self = *(int *) data;
|
||||
|
||||
iRet = LLDnodePtr2First(self);
|
||||
while (iRet != 0) {
|
||||
LLDnodeDataTo(self, &tuktuk);
|
||||
if (tuktuk.running == 1) {
|
||||
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
|
||||
switch (status) {
|
||||
case HWIdle:
|
||||
tuktuk.running = 0;
|
||||
LLDnodeDataFrom(self, &tuktuk);
|
||||
break;
|
||||
case HWBusy:
|
||||
result = HWBusy;
|
||||
break;
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
tuktuk.running = 0;
|
||||
LLDnodeDataFrom(self, &tuktuk);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
this is a programming error and has to be fixed
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self);
|
||||
}
|
||||
return result;
|
||||
return MOLICheckStatus(data,pCon);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
|
@ -19,6 +19,7 @@ typedef struct {
|
||||
pIDrivable pDriv;
|
||||
void *data;
|
||||
int running;
|
||||
long taskID;
|
||||
} MotControl, *pMotControl;
|
||||
|
||||
/*======================================================================*/
|
||||
|
@ -268,6 +268,9 @@ static int checkPosition(pMotor self, SConnection * pCon)
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||
assert(node != NULL);
|
||||
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||
assert(node != NULL);
|
||||
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
|
||||
return HWBusy;
|
||||
}
|
||||
return HWIdle;
|
||||
|
@ -98,6 +98,18 @@ static void doCountCommand(pHdb self, SConnection *pCon, int command)
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void copyExponent(pHdb self, void *data)
|
||||
{
|
||||
pHdb source = NULL, target = NULL;
|
||||
|
||||
pCounter count = (pCounter)data;
|
||||
source = GetHipadabaNode(self,"exponent");
|
||||
target = GetHipadabaNode(count->pDes->parNode,"exponent");
|
||||
if(source != NULL && target != NULL){
|
||||
UpdateHipadabaPar(target,MakeHdbInt(source->value.v.intValue), NULL);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
{
|
||||
pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
|
||||
@ -138,6 +150,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
if(data != NULL){
|
||||
pCount = GetCountableInterface(data);
|
||||
if(pCount != NULL){
|
||||
copyExponent(self,data);
|
||||
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
||||
eMode);
|
||||
masterID = StartCountTask(data,pCon,name);
|
||||
@ -163,6 +176,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
if(data != NULL){
|
||||
pCount = GetCountableInterface(data);
|
||||
if(pCount != NULL){
|
||||
copyExponent(self,data);
|
||||
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
||||
eMode);
|
||||
masterID = StartCountTask(data,pCon,master->value.v.text);
|
||||
|
5
mumo.c
5
mumo.c
@ -683,6 +683,9 @@ static void RecoverNamPos(pMulMot self, int argc, char *argv[])
|
||||
decrement, increment and simple values.
|
||||
DingsBums pos name - makes the current position a named
|
||||
position with name name.
|
||||
DingsBums defpos name [alias value..] - makes a named
|
||||
position with name name. The par is a list of alias value
|
||||
pairs with the appropriate positions for name.
|
||||
DingsBums getpos - gets the current named position
|
||||
DingsBums drop name - deletes the current named position
|
||||
name.
|
||||
@ -841,7 +844,7 @@ int MultiWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
case RECOVERNAMPOS:
|
||||
/*
|
||||
This is not meant to be user command but a facility to read
|
||||
back data from sattus file. This is why the error checking
|
||||
back data from status file. This is why the error checking
|
||||
is not happening
|
||||
*/
|
||||
RecoverNamPos(self, argc - 2, &argv[2]);
|
||||
|
@ -1460,6 +1460,9 @@ static int GetDefString(void *message, void *userData)
|
||||
self->argv[2]);
|
||||
return MPSTOP;
|
||||
}
|
||||
NXDtextreplace(self->nx->dictHandle,self->defString,
|
||||
self->defString,sizeof(self->defString));
|
||||
|
||||
|
||||
return MPCONTINUE;
|
||||
}
|
||||
@ -1556,7 +1559,7 @@ static int SPutWrite(void *message, void *userData)
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
|
||||
self->defString, &self->v.v.intArray);
|
||||
self->defString, self->v.v.intArray);
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
case HIPFLOATVARAR:
|
||||
|
@ -80,7 +80,7 @@ static int OscillationTask(void *data)
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
WriteToCommandLog("oscillator>> ",
|
||||
"ERROR occurred in oscialltion, try running motor manually to find out more");
|
||||
"ERROR occurred in oscillation, try running motor manually to find out more");
|
||||
WriteToCommandLog("oscillator>> ",
|
||||
"Trying to run other direction");
|
||||
pos = getNextPos(self);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ------------------------------------------------------------------------
|
||||
The OutCode's for SICS have to be translated from text at several
|
||||
places in SICS. Wherever necessary sich code should include this file.
|
||||
places in SICS. Wherever necessary such code should include this file.
|
||||
This restricts changes to Scommon.h and this file
|
||||
|
||||
Mark Koennecke, November 1996
|
||||
|
@ -48,6 +48,7 @@ typedef struct SctData {
|
||||
int inMacro;
|
||||
Hdb *node;
|
||||
long syncid;
|
||||
int busy;
|
||||
} SctData;
|
||||
|
||||
/* data for updatescript */
|
||||
@ -422,7 +423,10 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
} else {
|
||||
con = controller->conn;
|
||||
}
|
||||
data->busy = 1;
|
||||
|
||||
/*
|
||||
* Check if this is a followup call.
|
||||
* If this is a followup call, the I/O system will have set the
|
||||
* property result to the data from the device. Read this now and
|
||||
* print it if diagnostics is required.
|
||||
@ -445,6 +449,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the state property is set to the name of the property
|
||||
* which holds the name of the script to run at this stage.
|
||||
* When this is a followup, we use the content of the
|
||||
* state field as the property storing the next script to
|
||||
* run. If this is the start of a chain this is set to the
|
||||
@ -491,6 +497,9 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
}
|
||||
SyncedEnd(data->syncid);
|
||||
sct->sendNode = NULL;
|
||||
/*
|
||||
* Process the results of the script run
|
||||
*/
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* an error occurred in the script: store error message in
|
||||
@ -588,7 +597,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
free(script);
|
||||
script = NULL;
|
||||
/*
|
||||
* If there is data to send, check it and do so
|
||||
* If there is data to send, check it and do so. This also exits the
|
||||
* quick script loop by returning the data to send to Devser.
|
||||
*/
|
||||
if (sct->sendCalled) {
|
||||
send = GetProp(node, controller->node, "send");
|
||||
@ -610,6 +620,10 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
}
|
||||
SCPrintf(con, eLogError, "ERROR: too many quick scripts chained");
|
||||
finish:
|
||||
/*
|
||||
* This section is always called when the script chain ends: either due to
|
||||
* error or by successfull termination.
|
||||
*/
|
||||
if (strcmp(data->name, "write") == 0) {
|
||||
if (GetHdbProp(node, "writestatus") != NULL) {
|
||||
SetHdbProperty(node, "writestatus", "commandsent");
|
||||
@ -624,6 +638,7 @@ finish:
|
||||
SCDeleteConnection(data->conCtx);
|
||||
data->conCtx = NULL;
|
||||
}
|
||||
data->busy = 0;
|
||||
return send;
|
||||
}
|
||||
|
||||
@ -835,6 +850,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
||||
data->inMacro = SCinMacro(con);
|
||||
tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text));
|
||||
data->syncid = SyncedIncr(0);
|
||||
data->busy = 1;
|
||||
DevQueue(data->controller->devser, data, prio,
|
||||
SctWriteHandler, SctMatch, SctEndData, SctDataInfo);
|
||||
/* kill function SctEndData does not kill, data is owned by the node (callback list) */
|
||||
@ -1149,7 +1165,7 @@ void SctQueueNode(SctController * controller, Hdb * node,
|
||||
data->answered = 1;
|
||||
|
||||
data->syncid = SyncedIncr(0);
|
||||
|
||||
data->busy = 1;
|
||||
if (DevQueue(data->controller->devser, data, prio,
|
||||
SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) {
|
||||
if (con != NULL) {
|
||||
@ -1531,6 +1547,50 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SctProcessCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
SctData *data = NULL;
|
||||
SctController *c;
|
||||
|
||||
c = (SctController *) ccmd->pPrivate;
|
||||
|
||||
if(nPar < 1 || par[0] == NULL){
|
||||
SCWrite(con,"ERROR: no node to process found", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = calloc(sizeof(SctData), 1);
|
||||
if (data == NULL) {
|
||||
SCWrite(con, "ERROR: out of memory in SctProcessCommand", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->node = FindHdbNode(NULL,par[0]->value.v.text, con);
|
||||
if(data->node == NULL){
|
||||
SCPrintf(con,eError,"ERROR: node %s to process not found", par[0]->value.v.text);
|
||||
return 0;
|
||||
}
|
||||
if(nPar > 1) {
|
||||
data->name = strdup(par[1]->value.v.text);
|
||||
} else {
|
||||
data->name = strdup("read");
|
||||
}
|
||||
data->controller = c;
|
||||
data->conCtx = SCCopyConnection(con);
|
||||
data->busy = 1;
|
||||
data->inMacro = SCinMacro(con);
|
||||
|
||||
DevQueue(c->devser, data, WritePRIO,
|
||||
SctWriteHandler, SctMatch, NULL, SctDataInfo);
|
||||
while (data->busy == 1) {
|
||||
TaskYield(pServ->pTasker);
|
||||
}
|
||||
SctKillData(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SctDisconnect(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
@ -1857,6 +1917,11 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
|
||||
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
|
||||
AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText(""));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"processnode", usUser, MakeSICSFunc(SctProcessCmd));
|
||||
AddSICSHdbPar(cmd, "node", usUser, MakeHdbText(""));
|
||||
AddSICSHdbPar(cmd, "command", usUser, MakeHdbText("read"));
|
||||
|
||||
cmd = AddSICSHdbPar(controller->node,
|
||||
"disconnect", usMugger, MakeSICSFunc(SctDisconnect));
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
||||
* - Retrieve reply data
|
||||
* - wait for a ComTask to finish.
|
||||
*
|
||||
* The the purpose sctcomtask will keep a cache of pending and finished communications.
|
||||
* The purpose sctcomtask will keep a cache of pending and finished communications.
|
||||
* Old runs will be deleted periodically. Nevertheless the cache can be listed in order
|
||||
* to figure out what happened.
|
||||
*
|
||||
* The intended use is for C-code or scripts to interact in a serial manner with
|
||||
* the asynchronous communication system implemented in devser and ascon. As a
|
||||
* standalone implementation would share tons of code with scriptcontext, this has
|
||||
* been implemented as an add on module to scriptcontext.
|
||||
* standalone implementation this would share tons of code with scriptcontext, thus
|
||||
* this has been implemented as an add on module to scriptcontext.
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
|
@ -113,10 +113,10 @@ pSicsSelector CreateSelector(char *name, pMotor pTheta, pMotor pTwoTheta,
|
||||
|
||||
/* create all the parameters */
|
||||
ObParInit(pRes->pParams, SS, "ss", 1., usUser);
|
||||
ObParInit(pRes->pParams, B1C1, "vk1", 1., usInternal);
|
||||
ObParInit(pRes->pParams, B1C2, "vk2", 1., usInternal);
|
||||
ObParInit(pRes->pParams, B2C1, "hk1", 1., usInternal);
|
||||
ObParInit(pRes->pParams, B2C2, "hk2", 1., usInternal);
|
||||
ObParInit(pRes->pParams, B1C1, "vk1", 1., usMugger);
|
||||
ObParInit(pRes->pParams, B1C2, "vk2", 1., usMugger);
|
||||
ObParInit(pRes->pParams, B2C1, "hk1", 1., usMugger);
|
||||
ObParInit(pRes->pParams, B2C2, "hk2", 1., usMugger);
|
||||
ObParInit(pRes->pParams, LATD, "dd", 2.087, usMugger);
|
||||
ObParInit(pRes->pParams, RIGHTS, "access", usUser, usMugger);
|
||||
|
||||
|
15
sicsget.c
15
sicsget.c
@ -81,7 +81,7 @@ static int SICSGetCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
if(status){
|
||||
data = formatValue(v,NULL);
|
||||
if(data != NULL){
|
||||
SCPrintf(pCon,eValue,"%s",GetCharArray(data));
|
||||
SCPrintf(pCon,eValue,"%s",trim(GetCharArray(data)));
|
||||
DeleteDynString(data);
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]);
|
||||
@ -176,7 +176,7 @@ static int SplitOffEqual(void *ms, void *userData)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int isNumber(char *txt)
|
||||
{
|
||||
if(*txt == '\0'){
|
||||
if(*txt == '\0' || *txt == ' '){
|
||||
return 1;
|
||||
}
|
||||
if(isalpha(*txt)){
|
||||
@ -189,12 +189,14 @@ static int isNumber(char *txt)
|
||||
static int countWords(char *txt)
|
||||
{
|
||||
char number[80];
|
||||
int count = 0;
|
||||
char *pPtr = txt;
|
||||
|
||||
if(txt == NULL || strlen(txt) < 1){
|
||||
return 0;
|
||||
} else {
|
||||
return 1 + countWords(stptok(txt,number,sizeof(number)," "));
|
||||
while(pPtr != NULL){
|
||||
count++;
|
||||
pPtr = stptok(pPtr,number,sizeof(number)," ");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static hdbValue makeArray(char *txt, int type, int count)
|
||||
@ -216,6 +218,7 @@ static hdbValue makeArray(char *txt, int type, int count)
|
||||
} else {
|
||||
ar.v.floatArray[i] = atof(number);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
|
@ -596,6 +596,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
||||
pHdbPtrMessage cmm = NULL;
|
||||
pHdbDataMessage mm = NULL;
|
||||
SConnection *tstCon;
|
||||
char updatePath[1024];
|
||||
|
||||
cbInfo = (HdbCBInfo *) userData;
|
||||
|
||||
@ -657,7 +658,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
pPath = GetHipadabaPath(node);
|
||||
GetHdbPath(node,updatePath,sizeof(updatePath));
|
||||
result = CreateDynString(128, 128);
|
||||
if ((protocol = isJSON(cbInfo->pCon)) == 1)
|
||||
outCode = eHdbEvent;
|
||||
@ -671,14 +672,13 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
||||
if (GetHdbProperty(node, "transfer", value, 80) == 1) {
|
||||
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
|
||||
status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon);
|
||||
free(pPath);
|
||||
DeleteDynString(result);
|
||||
return hdbContinue;
|
||||
}
|
||||
}
|
||||
if (mm->v->arrayLength < 100) {
|
||||
printedData = formatValue(*(mm->v), node);
|
||||
if (pPath == NULL || printedData == NULL || result == NULL) {
|
||||
if (printedData == NULL || result == NULL) {
|
||||
SCWrite(cbInfo->pCon, "ERROR: out of memory formatting data",
|
||||
eEvent);
|
||||
/*
|
||||
@ -687,7 +687,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
||||
*/
|
||||
return hdbContinue;
|
||||
}
|
||||
formatNameValue(protocol, pPath, GetCharArray(printedData), result,
|
||||
formatNameValue(protocol, updatePath, GetCharArray(printedData), result,
|
||||
mm->v->dataType);
|
||||
/* SCWrite(cbInfo->pCon, GetCharArray(result), outCode); */
|
||||
SCPureSockWrite(cbInfo->pCon, GetCharArray(result), outCode);
|
||||
@ -696,7 +696,6 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
||||
formatNameValue(protocol, pPath, "!!datachange!!", result, HIPTEXT);
|
||||
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
|
||||
}
|
||||
free(pPath);
|
||||
DeleteDynString(result);
|
||||
|
||||
return hdbContinue;
|
||||
|
@ -950,7 +950,11 @@ static int StandardScriptInvoke(pScanData self, char *function)
|
||||
if (command == NULL) {
|
||||
return 0;
|
||||
}
|
||||
status = InterpExecute(self->pSics, self->pCon, GetCharArray(command));
|
||||
if(self->pCon != NULL){
|
||||
status = InterpExecute(pServ->pSics, self->pCon, GetCharArray(command));
|
||||
} else {
|
||||
status = InterpExecute(pServ->pSics, pServ->dummyCon, GetCharArray(command));
|
||||
}
|
||||
DeleteDynString(command);
|
||||
if (status != 1) {
|
||||
return 0;
|
||||
|
157
tasdrive.c
157
tasdrive.c
@ -5,12 +5,14 @@
|
||||
|
||||
Mark Koennecke, May 2005
|
||||
|
||||
In the long run it might be useful to switch all this to the more
|
||||
general motor list driving code.
|
||||
|
||||
Modified to rather use drivables then motors
|
||||
|
||||
Mark Koennecke, September 2011
|
||||
|
||||
Modified to use drive tasks
|
||||
|
||||
Mark Koennecke, January 2014
|
||||
--------------------------------------------------------------------*/
|
||||
#include <assert.h>
|
||||
#include "sics.h"
|
||||
@ -72,7 +74,12 @@ int readTASMotAngles(ptasUB self, SConnection * pCon,
|
||||
if (status == 0) {
|
||||
return status;
|
||||
}
|
||||
theta = val;
|
||||
theta = val;/* $Id: tasdrive.c,v 1.39 2014/02/18 13:25:32 koennecke Exp $ */
|
||||
|
||||
#ifndef lint
|
||||
static char vcid[] = "$Id: tasdrive.c,v 1.39 2014/02/18 13:25:32 koennecke Exp $";
|
||||
#endif /* lint */
|
||||
|
||||
status = GetDrivablePosition(self->motors[A2], pCon, &val);
|
||||
if (status == 0) {
|
||||
return status;
|
||||
@ -274,7 +281,7 @@ static float getMotorValue(pMotor mot, SConnection * pCon)
|
||||
void InvokeNewTarget(pExeList self, char *name, float target);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
||||
double target, int silent, int stopFixed)
|
||||
double target, int silent, int stopFixed, long groupID)
|
||||
{
|
||||
float val, fixed, precision = MOTPREC;
|
||||
int status = OKOK;
|
||||
@ -282,6 +289,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
||||
pIDrivable pDriv = NULL;
|
||||
pDummy dum = NULL;
|
||||
pDynString mes = NULL;
|
||||
long taskID;
|
||||
|
||||
dum = (pDummy)mot;
|
||||
val = getMotorValue(mot, pCon);
|
||||
@ -298,10 +306,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
||||
}
|
||||
mot->stopped = 0;
|
||||
if (ABS(val - target) > precision) {
|
||||
pDriv = GetDrivableInterface(mot);
|
||||
status = pDriv->SetValue(mot, pCon, (float) target);
|
||||
if(status != OKOK){
|
||||
taskID = StartDriveTask(mot,pCon,name,target);
|
||||
if(taskID < 0){
|
||||
SCPrintf(pCon,eLog,"ERROR: failed to drive %s to %f", name, target);
|
||||
} else {
|
||||
AddTaskToGroup(pServ->pTasker,taskID, groupID);
|
||||
}
|
||||
/*
|
||||
to force updates on targets
|
||||
@ -313,7 +322,8 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int StartTASA3(pMotor mot, SConnection *pCon, char *name,
|
||||
double target, int silent, int stopFixed)
|
||||
double target, int silent, int stopFixed,
|
||||
long groupID)
|
||||
{
|
||||
float val;
|
||||
int status;
|
||||
@ -326,14 +336,14 @@ static int StartTASA3(pMotor mot, SConnection *pCon, char *name,
|
||||
status = SCPromptTMO(pCon,NULL,buffer,sizeof(buffer),120);
|
||||
if(status == 1){
|
||||
if(buffer[0] == 'y'){
|
||||
return startTASMotor(mot,pCon,name,target,silent,stopFixed);
|
||||
return startTASMotor(mot,pCon,name,target,silent,stopFixed,groupID);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,"ERROR: no or wrong reply, aborting scan",eLogError);
|
||||
SCSetInterrupt(pCon,eAbortScan);
|
||||
return HWFault;
|
||||
} else {
|
||||
return startTASMotor(mot,pCon,name,target,silent,stopFixed);
|
||||
return startTASMotor(mot,pCon,name,target,silent,stopFixed,groupID);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -346,6 +356,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
silent = self->math->silent;
|
||||
stopFixed = self->math->stopFixed;
|
||||
self->math->mustRecalculate = 1;
|
||||
|
||||
self->math->groupID = GetTaskGroupID(pServ->pTasker);
|
||||
|
||||
/*
|
||||
monochromator
|
||||
*/
|
||||
@ -353,6 +366,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
pCon,angles.monochromator_two_theta);
|
||||
if(status != OKOK){
|
||||
return status;
|
||||
} else {
|
||||
AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -360,12 +375,12 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
*/
|
||||
if (self->math->tasMode != ELASTIC) {
|
||||
status = startTASMotor(self->math->motors[A5], pCon, "a5",
|
||||
angles.analyzer_two_theta / 2.0, silent,stopFixed);
|
||||
angles.analyzer_two_theta / 2.0, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
status = startTASMotor(self->math->motors[A6], pCon, "a6",
|
||||
angles.analyzer_two_theta, silent,stopFixed);
|
||||
angles.analyzer_two_theta, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
@ -374,7 +389,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||
angles.analyzer_two_theta);
|
||||
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
||||
curve, silent,stopFixed);
|
||||
curve, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eLog);
|
||||
SCSetInterrupt(pCon,eContinue);
|
||||
@ -384,7 +399,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||
angles.analyzer_two_theta);
|
||||
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
||||
curve, silent,stopFixed);
|
||||
curve, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eLog);
|
||||
SCSetInterrupt(pCon,eContinue);
|
||||
@ -400,24 +415,24 @@ static int startMotors(ptasMot self, tasAngles angles,
|
||||
crystal
|
||||
*/
|
||||
status = StartTASA3(self->math->motors[A3], pCon, "a3",
|
||||
angles.a3, silent,stopFixed);
|
||||
angles.a3, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
status = startTASMotor(self->math->motors[A4], pCon, "a4",
|
||||
angles.sample_two_theta, silent,stopFixed);
|
||||
angles.sample_two_theta, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (driveTilt == 1) {
|
||||
status = startTASMotor(self->math->motors[SGL], pCon, "sgl",
|
||||
angles.sgl, silent,stopFixed);
|
||||
angles.sgl, silent,stopFixed, self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
status = startTASMotor(self->math->motors[SGU], pCon, "sgu",
|
||||
angles.sgu, silent,stopFixed);
|
||||
angles.sgu, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
@ -566,60 +581,12 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon)
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static int checkMotors(ptasMot self, SConnection * pCon)
|
||||
{
|
||||
int i, status, length = 12, count;
|
||||
int mask[12], busy[12];
|
||||
pIDrivable pDrivInt = NULL;
|
||||
|
||||
self->math->mustRecalculate = 1;
|
||||
if (self->math->tasMode == ELASTIC) {
|
||||
length = 8;
|
||||
}
|
||||
memset(mask, 0, 12 * sizeof(int));
|
||||
memset(busy, 0, 12 * sizeof(int));
|
||||
for (i = 0; i < length; i++) {
|
||||
mask[i] = 1;
|
||||
busy[i] = 1;
|
||||
}
|
||||
if (self->math->outOfPlaneAllowed == 0) {
|
||||
mask[SGU] = 0;
|
||||
mask[SGL] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
check monochromator
|
||||
*/
|
||||
status = self->math->mono->CheckStatus(self->math->monoData,pCon);
|
||||
if(status == HWIdle){
|
||||
for(i = 0; i < 4; i++){
|
||||
busy[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
check the rest
|
||||
*/
|
||||
for (i = 4; i < 12; i++) {
|
||||
if(self->math->motors[i] == NULL){
|
||||
busy[i] = 0;
|
||||
} else {
|
||||
if(mask[i] != 0) {
|
||||
pDrivInt = GetDrivableInterface(self->math->motors[i]);
|
||||
status = pDrivInt->CheckStatus(self->math->motors[i], pCon);
|
||||
if(status == HWIdle || status == OKOK || status == HWFault || status == HWPosFault){
|
||||
busy[i] = 0;
|
||||
}
|
||||
} else {
|
||||
busy[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i = 0, count = 0; i < 12; i++){
|
||||
count += busy[i];
|
||||
}
|
||||
if(count == 0) {
|
||||
return HWIdle;
|
||||
} else {
|
||||
if(isTaskGroupRunning(pServ->pTasker,self->math->groupID)){
|
||||
return HWBusy;
|
||||
} else {
|
||||
return HWIdle;
|
||||
}
|
||||
}
|
||||
|
||||
@ -653,42 +620,18 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
||||
|
||||
silent = self->math->silent;
|
||||
stopFixed = self->math->stopFixed;
|
||||
|
||||
self->math->groupID = GetTaskGroupID(pServ->pTasker);
|
||||
|
||||
/*
|
||||
monochromator
|
||||
*/
|
||||
/* status = startTASMotor(self->math->motors[A1], pCon, "a1", */
|
||||
/* angles.monochromator_two_theta / 2., silent,stopFixed); */
|
||||
/* if (status != OKOK) { */
|
||||
/* return status; */
|
||||
/* } */
|
||||
/* status = startTASMotor(self->math->motors[A2], pCon, "a2", */
|
||||
/* angles.monochromator_two_theta, silent,stopFixed); */
|
||||
/* if (status != OKOK) { */
|
||||
/* return status; */
|
||||
/* } */
|
||||
|
||||
/* if (self->math->motors[MCV] != NULL) { */
|
||||
/* curve = maCalcVerticalCurvature(self->math->machine.monochromator, */
|
||||
/* angles.monochromator_two_theta); */
|
||||
/* status = startTASMotor(self->math->motors[MCV], pCon, "mcv", */
|
||||
/* curve, silent,stopFixed); */
|
||||
/* if (status != OKOK) { */
|
||||
/* return status; */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
/* if (self->math->motors[MCH] != NULL) { */
|
||||
/* curve = maCalcHorizontalCurvature(self->math->machine.monochromator, */
|
||||
/* angles.monochromator_two_theta); */
|
||||
/* status = startTASMotor(self->math->motors[MCH], pCon, "mch", */
|
||||
/* curve, silent,stopFixed); */
|
||||
/* if (status != OKOK) { */
|
||||
/* return status; */
|
||||
/* } */
|
||||
/* } */
|
||||
status = self->math->mono->SetValue(self->math->monoData,pCon,angles.analyzer_two_theta);
|
||||
monochromator
|
||||
*/
|
||||
status = self->math->mono->SetValue(self->math->monoData,
|
||||
pCon,angles.monochromator_two_theta);
|
||||
if(status != OKOK){
|
||||
return status;
|
||||
} else {
|
||||
AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID);
|
||||
}
|
||||
|
||||
|
||||
@ -696,12 +639,12 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
||||
analyzer
|
||||
*/
|
||||
status = startTASMotor(self->math->motors[A5], pCon, "a5",
|
||||
angles.analyzer_two_theta / 2.0, silent,stopFixed);
|
||||
angles.analyzer_two_theta / 2.0, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
status = startTASMotor(self->math->motors[A6], pCon, "a6",
|
||||
angles.analyzer_two_theta, silent,stopFixed);
|
||||
angles.analyzer_two_theta, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
@ -710,7 +653,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||
angles.analyzer_two_theta);
|
||||
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
||||
curve, silent,stopFixed);
|
||||
curve, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
@ -719,7 +662,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||
angles.analyzer_two_theta);
|
||||
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
||||
curve, silent,stopFixed);
|
||||
curve, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
@ -729,7 +672,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
||||
crystal
|
||||
*/
|
||||
status = startTASMotor(self->math->motors[A4], pCon, "a4",
|
||||
angles.sample_two_theta, silent,stopFixed);
|
||||
angles.sample_two_theta, silent,stopFixed,self->math->groupID);
|
||||
if (status != OKOK) {
|
||||
return status;
|
||||
}
|
||||
|
1
tasub.h
1
tasub.h
@ -37,6 +37,7 @@
|
||||
int silent;
|
||||
int stopFixed; /* flag to stop multiple fixed messages in scans*/
|
||||
char *updater;
|
||||
long groupID;
|
||||
}tasUB, *ptasUB;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user