- 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;
|
pIDrivable pDriv;
|
||||||
float value;
|
float value;
|
||||||
int running;
|
int running;
|
||||||
|
long taskID;
|
||||||
} RealMotor, *pRealMotor;
|
} RealMotor, *pRealMotor;
|
||||||
|
|
||||||
/* Data passed by event generating object */
|
/* Data passed by event generating object */
|
||||||
@ -179,9 +180,9 @@ static int startMotorList(pConfigurableVirtualMotor self,
|
|||||||
iRet = LLDnodePtr2First(self->motorList);
|
iRet = LLDnodePtr2First(self->motorList);
|
||||||
while (iRet != 0) {
|
while (iRet != 0) {
|
||||||
LLDnodeDataTo(self->motorList, &tuktuk);
|
LLDnodeDataTo(self->motorList, &tuktuk);
|
||||||
status = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.value);
|
tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.value);
|
||||||
if (status != 1) {
|
if (tuktuk.taskID < 0) {
|
||||||
return status;
|
return HWFault;
|
||||||
}
|
}
|
||||||
tuktuk.running = 1;
|
tuktuk.running = 1;
|
||||||
LLDnodeDataFrom(self->motorList, &tuktuk);
|
LLDnodeDataFrom(self->motorList, &tuktuk);
|
||||||
@ -342,28 +343,12 @@ static int ConfCheckStatus(void *pData, SConnection * pCon)
|
|||||||
while (iRet != 0) {
|
while (iRet != 0) {
|
||||||
LLDnodeDataTo(self->motorList, &tuktuk);
|
LLDnodeDataTo(self->motorList, &tuktuk);
|
||||||
if (tuktuk.running == 1) {
|
if (tuktuk.running == 1) {
|
||||||
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
|
status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
|
||||||
switch (status) {
|
if(status == 1){
|
||||||
case HWIdle:
|
return HWBusy;
|
||||||
tuktuk.running = 0;
|
} else {
|
||||||
|
tuktuk.running = 0;
|
||||||
LLDnodeDataFrom(self->motorList, &tuktuk);
|
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);
|
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) {
|
} else if (strcmp(argv[1], "rights") == 0) {
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
snprintf(pBueffel,511, "Insufficient number of args to %s", argv[0]);
|
snprintf(pBueffel,511, "Insufficient number of args to %s", argv[0]);
|
||||||
SCWrite(pCon, pBueffel, eInError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
i = IsValidUser(argv[2], argv[3]);
|
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);
|
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,
|
static int CountNBCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
{
|
{
|
||||||
@ -587,12 +612,24 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
|||||||
}
|
}
|
||||||
AddHipadabaChild(node, child, NULL);
|
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));
|
child = AddSICSHdbPar(node,"count", usUser, MakeSICSFunc(CountCmd));
|
||||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
||||||
|
|
||||||
child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd));
|
child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd));
|
||||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
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,"stop", usUser, MakeSICSFunc(StopCmd));
|
||||||
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
|
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
|
||||||
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
|
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],
|
lSum = sumWindow(dataNode->value.v.intArray, xstart,xend,dimNode->value.v.intArray[0],
|
||||||
ystart, yend, dimNode->value.v.intArray[1]);
|
ystart, yend, dimNode->value.v.intArray[1]);
|
||||||
SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
|
SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
|
||||||
|
break;
|
||||||
default:
|
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);
|
dimNode->value.arrayLength);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -344,13 +345,13 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
DeleteHipadabaNode(child,pCon);
|
DeleteHipadabaNode(child,pCon);
|
||||||
}
|
}
|
||||||
|
|
||||||
child = MakeSICSHdbPar("rank", usInternal, MakeHdbInt(rank));
|
child = MakeSICSHdbPar("rank", usMugger, MakeHdbInt(rank));
|
||||||
if (child == NULL) {
|
if (child == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
AddHipadabaChild(node, child, NULL);
|
AddHipadabaChild(node, child, NULL);
|
||||||
|
|
||||||
child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTAR,rank));
|
child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTVARAR,rank));
|
||||||
if (child == NULL) {
|
if (child == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
18
macro.c
18
macro.c
@ -171,24 +171,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
|
|||||||
return TCL_ERROR;
|
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 */
|
/* invoke */
|
||||||
pCon->sicsError = 0;
|
pCon->sicsError = 0;
|
||||||
iMacro = SCinMacro(pCon);
|
iMacro = SCinMacro(pCon);
|
||||||
|
79
motorlist.c
79
motorlist.c
@ -6,6 +6,10 @@
|
|||||||
copyright: see file COPYRIGHT
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
Mark Koennecke, September 2005
|
Mark Koennecke, September 2005
|
||||||
|
|
||||||
|
modified to use the task system
|
||||||
|
|
||||||
|
Mark Koennecke, January 2014
|
||||||
-----------------------------------------------------------------------*/
|
-----------------------------------------------------------------------*/
|
||||||
#include "motorlist.h"
|
#include "motorlist.h"
|
||||||
#include "lld.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)
|
static long MOLISetValue(void *data, SConnection * pCon, float val)
|
||||||
{
|
{
|
||||||
int self = 0, iRet, test;
|
int self = 0, iRet;
|
||||||
MotControl tuktuk;
|
MotControl tuktuk;
|
||||||
|
|
||||||
|
|
||||||
self = *(int *) data;
|
self = *(int *) data;
|
||||||
|
|
||||||
iRet = LLDnodePtr2First(self);
|
iRet = LLDnodePtr2First(self);
|
||||||
while (iRet != 0) {
|
while (iRet != 0) {
|
||||||
LLDnodeDataTo(self, &tuktuk);
|
LLDnodeDataTo(self, &tuktuk);
|
||||||
test = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.target);
|
tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.target);
|
||||||
if (test != 1) {
|
if (tuktuk.taskID < 0) {
|
||||||
return test;
|
return HWFault;
|
||||||
} else {
|
} else {
|
||||||
tuktuk.running = 1;
|
tuktuk.running = 1;
|
||||||
LLDnodeDataFrom(self, &tuktuk);
|
LLDnodeDataFrom(self, &tuktuk);
|
||||||
@ -105,7 +110,7 @@ static long MOLISetValue(void *data, SConnection * pCon, float val)
|
|||||||
------------------------------------------------------------------*/
|
------------------------------------------------------------------*/
|
||||||
static int MOLICheckStatus(void *data, SConnection * pCon)
|
static int MOLICheckStatus(void *data, SConnection * pCon)
|
||||||
{
|
{
|
||||||
int self = 0, iRet, status, result = HWIdle;
|
int self = 0, iRet, status;
|
||||||
MotControl tuktuk;
|
MotControl tuktuk;
|
||||||
|
|
||||||
self = *(int *) data;
|
self = *(int *) data;
|
||||||
@ -114,35 +119,17 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
|
|||||||
while (iRet != 0) {
|
while (iRet != 0) {
|
||||||
LLDnodeDataTo(self, &tuktuk);
|
LLDnodeDataTo(self, &tuktuk);
|
||||||
if (tuktuk.running == 1) {
|
if (tuktuk.running == 1) {
|
||||||
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
|
status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
|
||||||
switch (status) {
|
if(status == 1){
|
||||||
case HWIdle:
|
return HWBusy;
|
||||||
tuktuk.running = 0;
|
} else {
|
||||||
|
tuktuk.running = 0;
|
||||||
LLDnodeDataFrom(self, &tuktuk);
|
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);
|
iRet = LLDnodePtr2Next(self);
|
||||||
}
|
}
|
||||||
return result;
|
return HWIdle;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------
|
/*---------------------------------------------------------
|
||||||
A special version for EIGER. I am cautious: I have problems
|
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 MOLIEigerStatus(void *data, SConnection * pCon)
|
||||||
{
|
{
|
||||||
int self = 0, iRet, status, result = HWIdle;
|
return MOLICheckStatus(data,pCon);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------
|
/*----------------------------------------------------------------
|
||||||
|
@ -19,6 +19,7 @@ typedef struct {
|
|||||||
pIDrivable pDriv;
|
pIDrivable pDriv;
|
||||||
void *data;
|
void *data;
|
||||||
int running;
|
int running;
|
||||||
|
long taskID;
|
||||||
} MotControl, *pMotControl;
|
} MotControl, *pMotControl;
|
||||||
|
|
||||||
/*======================================================================*/
|
/*======================================================================*/
|
||||||
|
@ -268,6 +268,9 @@ static int checkPosition(pMotor self, SConnection * pCon)
|
|||||||
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
|
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
|
||||||
|
node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||||
|
assert(node != NULL);
|
||||||
|
SetHipadabaPar(node, MakeHdbFloat(target), pCon);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
return HWIdle;
|
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)
|
static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||||
{
|
{
|
||||||
pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
|
pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
|
||||||
@ -138,6 +150,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
|||||||
if(data != NULL){
|
if(data != NULL){
|
||||||
pCount = GetCountableInterface(data);
|
pCount = GetCountableInterface(data);
|
||||||
if(pCount != NULL){
|
if(pCount != NULL){
|
||||||
|
copyExponent(self,data);
|
||||||
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
||||||
eMode);
|
eMode);
|
||||||
masterID = StartCountTask(data,pCon,name);
|
masterID = StartCountTask(data,pCon,name);
|
||||||
@ -163,6 +176,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
|||||||
if(data != NULL){
|
if(data != NULL){
|
||||||
pCount = GetCountableInterface(data);
|
pCount = GetCountableInterface(data);
|
||||||
if(pCount != NULL){
|
if(pCount != NULL){
|
||||||
|
copyExponent(self,data);
|
||||||
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
||||||
eMode);
|
eMode);
|
||||||
masterID = StartCountTask(data,pCon,master->value.v.text);
|
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.
|
decrement, increment and simple values.
|
||||||
DingsBums pos name - makes the current position a named
|
DingsBums pos name - makes the current position a named
|
||||||
position with name name.
|
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 getpos - gets the current named position
|
||||||
DingsBums drop name - deletes the current named position
|
DingsBums drop name - deletes the current named position
|
||||||
name.
|
name.
|
||||||
@ -841,7 +844,7 @@ int MultiWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
case RECOVERNAMPOS:
|
case RECOVERNAMPOS:
|
||||||
/*
|
/*
|
||||||
This is not meant to be user command but a facility to read
|
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
|
is not happening
|
||||||
*/
|
*/
|
||||||
RecoverNamPos(self, argc - 2, &argv[2]);
|
RecoverNamPos(self, argc - 2, &argv[2]);
|
||||||
|
@ -1460,6 +1460,9 @@ static int GetDefString(void *message, void *userData)
|
|||||||
self->argv[2]);
|
self->argv[2]);
|
||||||
return MPSTOP;
|
return MPSTOP;
|
||||||
}
|
}
|
||||||
|
NXDtextreplace(self->nx->dictHandle,self->defString,
|
||||||
|
self->defString,sizeof(self->defString));
|
||||||
|
|
||||||
|
|
||||||
return MPCONTINUE;
|
return MPCONTINUE;
|
||||||
}
|
}
|
||||||
@ -1556,7 +1559,7 @@ static int SPutWrite(void *message, void *userData)
|
|||||||
case HIPINTAR:
|
case HIPINTAR:
|
||||||
case HIPINTVARAR:
|
case HIPINTVARAR:
|
||||||
status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
|
status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
|
||||||
self->defString, &self->v.v.intArray);
|
self->defString, self->v.v.intArray);
|
||||||
break;
|
break;
|
||||||
case HIPFLOATAR:
|
case HIPFLOATAR:
|
||||||
case HIPFLOATVARAR:
|
case HIPFLOATVARAR:
|
||||||
|
@ -80,7 +80,7 @@ static int OscillationTask(void *data)
|
|||||||
case HWFault:
|
case HWFault:
|
||||||
case HWPosFault:
|
case HWPosFault:
|
||||||
WriteToCommandLog("oscillator>> ",
|
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>> ",
|
WriteToCommandLog("oscillator>> ",
|
||||||
"Trying to run other direction");
|
"Trying to run other direction");
|
||||||
pos = getNextPos(self);
|
pos = getNextPos(self);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
The OutCode's for SICS have to be translated from text at several
|
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
|
This restricts changes to Scommon.h and this file
|
||||||
|
|
||||||
Mark Koennecke, November 1996
|
Mark Koennecke, November 1996
|
||||||
|
@ -48,6 +48,7 @@ typedef struct SctData {
|
|||||||
int inMacro;
|
int inMacro;
|
||||||
Hdb *node;
|
Hdb *node;
|
||||||
long syncid;
|
long syncid;
|
||||||
|
int busy;
|
||||||
} SctData;
|
} SctData;
|
||||||
|
|
||||||
/* data for updatescript */
|
/* data for updatescript */
|
||||||
@ -422,7 +423,10 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
} else {
|
} else {
|
||||||
con = controller->conn;
|
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
|
* 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
|
* property result to the data from the device. Read this now and
|
||||||
* print it if diagnostics is required.
|
* 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
|
* When this is a followup, we use the content of the
|
||||||
* state field as the property storing the next script to
|
* state field as the property storing the next script to
|
||||||
* run. If this is the start of a chain this is set to the
|
* 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);
|
SyncedEnd(data->syncid);
|
||||||
sct->sendNode = NULL;
|
sct->sendNode = NULL;
|
||||||
|
/*
|
||||||
|
* Process the results of the script run
|
||||||
|
*/
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/*
|
/*
|
||||||
* an error occurred in the script: store error message in
|
* an error occurred in the script: store error message in
|
||||||
@ -588,7 +597,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
|||||||
free(script);
|
free(script);
|
||||||
script = NULL;
|
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) {
|
if (sct->sendCalled) {
|
||||||
send = GetProp(node, controller->node, "send");
|
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");
|
SCPrintf(con, eLogError, "ERROR: too many quick scripts chained");
|
||||||
finish:
|
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 (strcmp(data->name, "write") == 0) {
|
||||||
if (GetHdbProp(node, "writestatus") != NULL) {
|
if (GetHdbProp(node, "writestatus") != NULL) {
|
||||||
SetHdbProperty(node, "writestatus", "commandsent");
|
SetHdbProperty(node, "writestatus", "commandsent");
|
||||||
@ -624,6 +638,7 @@ finish:
|
|||||||
SCDeleteConnection(data->conCtx);
|
SCDeleteConnection(data->conCtx);
|
||||||
data->conCtx = NULL;
|
data->conCtx = NULL;
|
||||||
}
|
}
|
||||||
|
data->busy = 0;
|
||||||
return send;
|
return send;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,6 +850,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
|||||||
data->inMacro = SCinMacro(con);
|
data->inMacro = SCinMacro(con);
|
||||||
tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text));
|
tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text));
|
||||||
data->syncid = SyncedIncr(0);
|
data->syncid = SyncedIncr(0);
|
||||||
|
data->busy = 1;
|
||||||
DevQueue(data->controller->devser, data, prio,
|
DevQueue(data->controller->devser, data, prio,
|
||||||
SctWriteHandler, SctMatch, SctEndData, SctDataInfo);
|
SctWriteHandler, SctMatch, SctEndData, SctDataInfo);
|
||||||
/* kill function SctEndData does not kill, data is owned by the node (callback list) */
|
/* 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->answered = 1;
|
||||||
|
|
||||||
data->syncid = SyncedIncr(0);
|
data->syncid = SyncedIncr(0);
|
||||||
|
data->busy = 1;
|
||||||
if (DevQueue(data->controller->devser, data, prio,
|
if (DevQueue(data->controller->devser, data, prio,
|
||||||
SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) {
|
SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) {
|
||||||
if (con != NULL) {
|
if (con != NULL) {
|
||||||
@ -1531,6 +1547,50 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection * con,
|
|||||||
return 1;
|
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,
|
static int SctDisconnect(pSICSOBJ ccmd, SConnection * con,
|
||||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
{
|
{
|
||||||
@ -1857,6 +1917,11 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
|
|||||||
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
|
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
|
||||||
AddSICSHdbPar(cmd, "prio", 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,
|
cmd = AddSICSHdbPar(controller->node,
|
||||||
"disconnect", usMugger, MakeSICSFunc(SctDisconnect));
|
"disconnect", usMugger, MakeSICSFunc(SctDisconnect));
|
||||||
|
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
* - Retrieve reply data
|
* - Retrieve reply data
|
||||||
* - wait for a ComTask to finish.
|
* - 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
|
* Old runs will be deleted periodically. Nevertheless the cache can be listed in order
|
||||||
* to figure out what happened.
|
* to figure out what happened.
|
||||||
*
|
*
|
||||||
* The intended use is for C-code or scripts to interact in a serial manner with
|
* 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
|
* the asynchronous communication system implemented in devser and ascon. As a
|
||||||
* standalone implementation would share tons of code with scriptcontext, this has
|
* standalone implementation this would share tons of code with scriptcontext, thus
|
||||||
* been implemented as an add on module to scriptcontext.
|
* this has been implemented as an add on module to scriptcontext.
|
||||||
*
|
*
|
||||||
* copyright: see file COPYRIGHT
|
* copyright: see file COPYRIGHT
|
||||||
*
|
*
|
||||||
|
@ -113,10 +113,10 @@ pSicsSelector CreateSelector(char *name, pMotor pTheta, pMotor pTwoTheta,
|
|||||||
|
|
||||||
/* create all the parameters */
|
/* create all the parameters */
|
||||||
ObParInit(pRes->pParams, SS, "ss", 1., usUser);
|
ObParInit(pRes->pParams, SS, "ss", 1., usUser);
|
||||||
ObParInit(pRes->pParams, B1C1, "vk1", 1., usInternal);
|
ObParInit(pRes->pParams, B1C1, "vk1", 1., usMugger);
|
||||||
ObParInit(pRes->pParams, B1C2, "vk2", 1., usInternal);
|
ObParInit(pRes->pParams, B1C2, "vk2", 1., usMugger);
|
||||||
ObParInit(pRes->pParams, B2C1, "hk1", 1., usInternal);
|
ObParInit(pRes->pParams, B2C1, "hk1", 1., usMugger);
|
||||||
ObParInit(pRes->pParams, B2C2, "hk2", 1., usInternal);
|
ObParInit(pRes->pParams, B2C2, "hk2", 1., usMugger);
|
||||||
ObParInit(pRes->pParams, LATD, "dd", 2.087, usMugger);
|
ObParInit(pRes->pParams, LATD, "dd", 2.087, usMugger);
|
||||||
ObParInit(pRes->pParams, RIGHTS, "access", usUser, 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){
|
if(status){
|
||||||
data = formatValue(v,NULL);
|
data = formatValue(v,NULL);
|
||||||
if(data != NULL){
|
if(data != NULL){
|
||||||
SCPrintf(pCon,eValue,"%s",GetCharArray(data));
|
SCPrintf(pCon,eValue,"%s",trim(GetCharArray(data)));
|
||||||
DeleteDynString(data);
|
DeleteDynString(data);
|
||||||
} else {
|
} else {
|
||||||
SCPrintf(pCon,eError,"ERROR: formatting value for %s failed", argv[1]);
|
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)
|
static int isNumber(char *txt)
|
||||||
{
|
{
|
||||||
if(*txt == '\0'){
|
if(*txt == '\0' || *txt == ' '){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(isalpha(*txt)){
|
if(isalpha(*txt)){
|
||||||
@ -189,12 +189,14 @@ static int isNumber(char *txt)
|
|||||||
static int countWords(char *txt)
|
static int countWords(char *txt)
|
||||||
{
|
{
|
||||||
char number[80];
|
char number[80];
|
||||||
|
int count = 0;
|
||||||
|
char *pPtr = txt;
|
||||||
|
|
||||||
if(txt == NULL || strlen(txt) < 1){
|
while(pPtr != NULL){
|
||||||
return 0;
|
count++;
|
||||||
} else {
|
pPtr = stptok(pPtr,number,sizeof(number)," ");
|
||||||
return 1 + countWords(stptok(txt,number,sizeof(number)," "));
|
|
||||||
}
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static hdbValue makeArray(char *txt, int type, int count)
|
static hdbValue makeArray(char *txt, int type, int count)
|
||||||
@ -216,6 +218,7 @@ static hdbValue makeArray(char *txt, int type, int count)
|
|||||||
} else {
|
} else {
|
||||||
ar.v.floatArray[i] = atof(number);
|
ar.v.floatArray[i] = atof(number);
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +596,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
|||||||
pHdbPtrMessage cmm = NULL;
|
pHdbPtrMessage cmm = NULL;
|
||||||
pHdbDataMessage mm = NULL;
|
pHdbDataMessage mm = NULL;
|
||||||
SConnection *tstCon;
|
SConnection *tstCon;
|
||||||
|
char updatePath[1024];
|
||||||
|
|
||||||
cbInfo = (HdbCBInfo *) userData;
|
cbInfo = (HdbCBInfo *) userData;
|
||||||
|
|
||||||
@ -657,7 +658,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
|||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPath = GetHipadabaPath(node);
|
GetHdbPath(node,updatePath,sizeof(updatePath));
|
||||||
result = CreateDynString(128, 128);
|
result = CreateDynString(128, 128);
|
||||||
if ((protocol = isJSON(cbInfo->pCon)) == 1)
|
if ((protocol = isJSON(cbInfo->pCon)) == 1)
|
||||||
outCode = eHdbEvent;
|
outCode = eHdbEvent;
|
||||||
@ -671,14 +672,13 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
|||||||
if (GetHdbProperty(node, "transfer", value, 80) == 1) {
|
if (GetHdbProperty(node, "transfer", value, 80) == 1) {
|
||||||
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
|
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
|
||||||
status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon);
|
status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon);
|
||||||
free(pPath);
|
|
||||||
DeleteDynString(result);
|
DeleteDynString(result);
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mm->v->arrayLength < 100) {
|
if (mm->v->arrayLength < 100) {
|
||||||
printedData = formatValue(*(mm->v), node);
|
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",
|
SCWrite(cbInfo->pCon, "ERROR: out of memory formatting data",
|
||||||
eEvent);
|
eEvent);
|
||||||
/*
|
/*
|
||||||
@ -687,7 +687,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
|
|||||||
*/
|
*/
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
formatNameValue(protocol, pPath, GetCharArray(printedData), result,
|
formatNameValue(protocol, updatePath, GetCharArray(printedData), result,
|
||||||
mm->v->dataType);
|
mm->v->dataType);
|
||||||
/* SCWrite(cbInfo->pCon, GetCharArray(result), outCode); */
|
/* SCWrite(cbInfo->pCon, GetCharArray(result), outCode); */
|
||||||
SCPureSockWrite(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);
|
formatNameValue(protocol, pPath, "!!datachange!!", result, HIPTEXT);
|
||||||
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
|
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
|
||||||
}
|
}
|
||||||
free(pPath);
|
|
||||||
DeleteDynString(result);
|
DeleteDynString(result);
|
||||||
|
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
|
@ -950,7 +950,11 @@ static int StandardScriptInvoke(pScanData self, char *function)
|
|||||||
if (command == NULL) {
|
if (command == NULL) {
|
||||||
return 0;
|
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);
|
DeleteDynString(command);
|
||||||
if (status != 1) {
|
if (status != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
|
157
tasdrive.c
157
tasdrive.c
@ -5,12 +5,14 @@
|
|||||||
|
|
||||||
Mark Koennecke, May 2005
|
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
|
Modified to rather use drivables then motors
|
||||||
|
|
||||||
Mark Koennecke, September 2011
|
Mark Koennecke, September 2011
|
||||||
|
|
||||||
|
Modified to use drive tasks
|
||||||
|
|
||||||
|
Mark Koennecke, January 2014
|
||||||
--------------------------------------------------------------------*/
|
--------------------------------------------------------------------*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "sics.h"
|
#include "sics.h"
|
||||||
@ -72,7 +74,12 @@ int readTASMotAngles(ptasUB self, SConnection * pCon,
|
|||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return status;
|
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);
|
status = GetDrivablePosition(self->motors[A2], pCon, &val);
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return status;
|
return status;
|
||||||
@ -274,7 +281,7 @@ static float getMotorValue(pMotor mot, SConnection * pCon)
|
|||||||
void InvokeNewTarget(pExeList self, char *name, float target);
|
void InvokeNewTarget(pExeList self, char *name, float target);
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
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;
|
float val, fixed, precision = MOTPREC;
|
||||||
int status = OKOK;
|
int status = OKOK;
|
||||||
@ -282,6 +289,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
|||||||
pIDrivable pDriv = NULL;
|
pIDrivable pDriv = NULL;
|
||||||
pDummy dum = NULL;
|
pDummy dum = NULL;
|
||||||
pDynString mes = NULL;
|
pDynString mes = NULL;
|
||||||
|
long taskID;
|
||||||
|
|
||||||
dum = (pDummy)mot;
|
dum = (pDummy)mot;
|
||||||
val = getMotorValue(mot, pCon);
|
val = getMotorValue(mot, pCon);
|
||||||
@ -298,10 +306,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
|||||||
}
|
}
|
||||||
mot->stopped = 0;
|
mot->stopped = 0;
|
||||||
if (ABS(val - target) > precision) {
|
if (ABS(val - target) > precision) {
|
||||||
pDriv = GetDrivableInterface(mot);
|
taskID = StartDriveTask(mot,pCon,name,target);
|
||||||
status = pDriv->SetValue(mot, pCon, (float) target);
|
if(taskID < 0){
|
||||||
if(status != OKOK){
|
|
||||||
SCPrintf(pCon,eLog,"ERROR: failed to drive %s to %f", name, target);
|
SCPrintf(pCon,eLog,"ERROR: failed to drive %s to %f", name, target);
|
||||||
|
} else {
|
||||||
|
AddTaskToGroup(pServ->pTasker,taskID, groupID);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
to force updates on targets
|
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,
|
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;
|
float val;
|
||||||
int status;
|
int status;
|
||||||
@ -326,14 +336,14 @@ static int StartTASA3(pMotor mot, SConnection *pCon, char *name,
|
|||||||
status = SCPromptTMO(pCon,NULL,buffer,sizeof(buffer),120);
|
status = SCPromptTMO(pCon,NULL,buffer,sizeof(buffer),120);
|
||||||
if(status == 1){
|
if(status == 1){
|
||||||
if(buffer[0] == 'y'){
|
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);
|
SCWrite(pCon,"ERROR: no or wrong reply, aborting scan",eLogError);
|
||||||
SCSetInterrupt(pCon,eAbortScan);
|
SCSetInterrupt(pCon,eAbortScan);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
} else {
|
} 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;
|
silent = self->math->silent;
|
||||||
stopFixed = self->math->stopFixed;
|
stopFixed = self->math->stopFixed;
|
||||||
self->math->mustRecalculate = 1;
|
self->math->mustRecalculate = 1;
|
||||||
|
|
||||||
|
self->math->groupID = GetTaskGroupID(pServ->pTasker);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
monochromator
|
monochromator
|
||||||
*/
|
*/
|
||||||
@ -353,6 +366,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
pCon,angles.monochromator_two_theta);
|
pCon,angles.monochromator_two_theta);
|
||||||
if(status != OKOK){
|
if(status != OKOK){
|
||||||
return status;
|
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) {
|
if (self->math->tasMode != ELASTIC) {
|
||||||
status = startTASMotor(self->math->motors[A5], pCon, "a5",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
status = startTASMotor(self->math->motors[A6], pCon, "a6",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -374,7 +389,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta);
|
||||||
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eLog);
|
SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eLog);
|
||||||
SCSetInterrupt(pCon,eContinue);
|
SCSetInterrupt(pCon,eContinue);
|
||||||
@ -384,7 +399,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta);
|
||||||
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eLog);
|
SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eLog);
|
||||||
SCSetInterrupt(pCon,eContinue);
|
SCSetInterrupt(pCon,eContinue);
|
||||||
@ -400,24 +415,24 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
crystal
|
crystal
|
||||||
*/
|
*/
|
||||||
status = StartTASA3(self->math->motors[A3], pCon, "a3",
|
status = StartTASA3(self->math->motors[A3], pCon, "a3",
|
||||||
angles.a3, silent,stopFixed);
|
angles.a3, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
status = startTASMotor(self->math->motors[A4], pCon, "a4",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driveTilt == 1) {
|
if (driveTilt == 1) {
|
||||||
status = startTASMotor(self->math->motors[SGL], pCon, "sgl",
|
status = startTASMotor(self->math->motors[SGL], pCon, "sgl",
|
||||||
angles.sgl, silent,stopFixed);
|
angles.sgl, silent,stopFixed, self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
status = startTASMotor(self->math->motors[SGU], pCon, "sgu",
|
status = startTASMotor(self->math->motors[SGU], pCon, "sgu",
|
||||||
angles.sgu, silent,stopFixed);
|
angles.sgu, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -566,60 +581,12 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon)
|
|||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
static int checkMotors(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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if(isTaskGroupRunning(pServ->pTasker,self->math->groupID)){
|
||||||
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 {
|
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
|
} else {
|
||||||
|
return HWIdle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,42 +620,18 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
|
|
||||||
silent = self->math->silent;
|
silent = self->math->silent;
|
||||||
stopFixed = self->math->stopFixed;
|
stopFixed = self->math->stopFixed;
|
||||||
|
|
||||||
|
self->math->groupID = GetTaskGroupID(pServ->pTasker);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
monochromator
|
monochromator
|
||||||
*/
|
*/
|
||||||
/* status = startTASMotor(self->math->motors[A1], pCon, "a1", */
|
status = self->math->mono->SetValue(self->math->monoData,
|
||||||
/* angles.monochromator_two_theta / 2., silent,stopFixed); */
|
pCon,angles.monochromator_two_theta);
|
||||||
/* 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);
|
|
||||||
if(status != OKOK){
|
if(status != OKOK){
|
||||||
return status;
|
return status;
|
||||||
|
} else {
|
||||||
|
AddTaskToGroup(pServ->pTasker, self->math->monoTaskID, self->math->groupID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -696,12 +639,12 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
analyzer
|
analyzer
|
||||||
*/
|
*/
|
||||||
status = startTASMotor(self->math->motors[A5], pCon, "a5",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
status = startTASMotor(self->math->motors[A6], pCon, "a6",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -710,7 +653,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta);
|
||||||
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -719,7 +662,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta);
|
||||||
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed,self->math->groupID);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -729,7 +672,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
crystal
|
crystal
|
||||||
*/
|
*/
|
||||||
status = startTASMotor(self->math->motors[A4], pCon, "a4",
|
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) {
|
if (status != OKOK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
1
tasub.h
1
tasub.h
@ -37,6 +37,7 @@
|
|||||||
int silent;
|
int silent;
|
||||||
int stopFixed; /* flag to stop multiple fixed messages in scans*/
|
int stopFixed; /* flag to stop multiple fixed messages in scans*/
|
||||||
char *updater;
|
char *updater;
|
||||||
|
long groupID;
|
||||||
}tasUB, *ptasUB;
|
}tasUB, *ptasUB;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user