
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
280 lines
7.6 KiB
C
280 lines
7.6 KiB
C
/*----------------------------------------------------------------------
|
|
Support module which manages a list of motors and their target values
|
|
when running complex movements. See accompanying tex file for
|
|
more info.
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, September 2005
|
|
|
|
modified to use the task system
|
|
|
|
Mark Koennecke, January 2014
|
|
-----------------------------------------------------------------------*/
|
|
#include "motorlist.h"
|
|
#include "lld.h"
|
|
#include "motor.h"
|
|
/*---------------------------------------------------------------*/
|
|
static void *MOLIGetInterface(void *data, int iD)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/*----------------------------------------------------------------
|
|
This routine can return either OKOK or HWFault when thing
|
|
go wrong. However, the return value of Halt is usually ignored!
|
|
------------------------------------------------------------------*/
|
|
static int MOLIHalt(void *data)
|
|
{
|
|
int self = 0, iRet;
|
|
MotControl tuktuk;
|
|
|
|
self = *(int *) data;
|
|
|
|
iRet = LLDnodePtr2First(self);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(self, &tuktuk);
|
|
tuktuk.pDriv->Halt(tuktuk.data);
|
|
iRet = LLDnodePtr2Next(self);
|
|
}
|
|
return OKOK;
|
|
}
|
|
|
|
/*----------------------------------------------------------------
|
|
This routine can return either 1 or 0. 1 means the position can
|
|
be reached, 0 NOT
|
|
If 0, error shall contain up to errlen characters of information
|
|
about which limit was violated
|
|
------------------------------------------------------------------*/
|
|
static int MOLICheckLimits(void *data, float val, char *error, int errlen)
|
|
{
|
|
int self = 0, iRet, test, retVal = 1;
|
|
MotControl tuktuk;
|
|
|
|
self = *(int *) data;
|
|
|
|
iRet = LLDnodePtr2First(self);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(self, &tuktuk);
|
|
test = tuktuk.pDriv->CheckLimits(tuktuk.data, tuktuk.target, error, errlen);
|
|
if (test == 0) {
|
|
retVal = 0;
|
|
}
|
|
iRet = LLDnodePtr2Next(self);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*----------------------------------------------------------------
|
|
This routine can return 0 when a limit problem occurred
|
|
OKOK when the motor was successfully started
|
|
HWFault when a problem occured starting the device
|
|
Possible errors shall be printed to pCon
|
|
For real motors, this is supposed to try at least three times
|
|
to start the motor in question
|
|
val is the value to drive the motor too
|
|
------------------------------------------------------------------*/
|
|
static long MOLISetValue(void *data, SConnection * pCon, float val)
|
|
{
|
|
int self = 0, iRet;
|
|
MotControl tuktuk;
|
|
|
|
|
|
self = *(int *) data;
|
|
|
|
iRet = LLDnodePtr2First(self);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(self, &tuktuk);
|
|
tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.target);
|
|
if (tuktuk.taskID < 0) {
|
|
return HWFault;
|
|
} else {
|
|
tuktuk.running = 1;
|
|
LLDnodeDataFrom(self, &tuktuk);
|
|
}
|
|
iRet = LLDnodePtr2Next(self);
|
|
}
|
|
return OKOK;
|
|
}
|
|
|
|
/*----------------------------------------------------------------
|
|
Checks the status of a running motor. Possible return values
|
|
HWBusy The motor is still running
|
|
OKOK or HWIdle when the motor finished driving
|
|
HWFault when a hardware problem ocurred
|
|
HWPosFault when the hardware cannot reach a position
|
|
Errors are duly to be printed to pCon
|
|
For real motors CheckStatus again shall try hard to fix any
|
|
issues with the motor
|
|
------------------------------------------------------------------*/
|
|
static int MOLICheckStatus(void *data, SConnection * pCon)
|
|
{
|
|
int self = 0, iRet, status;
|
|
MotControl tuktuk;
|
|
|
|
self = *(int *) data;
|
|
|
|
iRet = LLDnodePtr2First(self);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(self, &tuktuk);
|
|
if (tuktuk.running == 1) {
|
|
status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
|
|
if(status == 1){
|
|
return HWBusy;
|
|
} else {
|
|
tuktuk.running = 0;
|
|
LLDnodeDataFrom(self, &tuktuk);
|
|
}
|
|
}
|
|
iRet = LLDnodePtr2Next(self);
|
|
}
|
|
return HWIdle;
|
|
}
|
|
/*---------------------------------------------------------
|
|
A special version for EIGER. I am cautious: I have problems
|
|
with this at EIGER but I do not want to propagate the fix
|
|
elsewhere even if it may be the right thing to do.
|
|
-----------------------------------------------------------*/
|
|
int MOLIEigerStatus(void *data, SConnection * pCon)
|
|
{
|
|
return MOLICheckStatus(data,pCon);
|
|
}
|
|
|
|
/*----------------------------------------------------------------
|
|
GetValue is supposed to read a motor position
|
|
On errors, -99999999.99 is returned and messages printed to pCon
|
|
------------------------------------------------------------------*/
|
|
static float MOLIGetValue(void *data, SConnection * pCon)
|
|
{
|
|
int self = 0, iRet;
|
|
MotControl tuktuk;
|
|
float value, result = 1;
|
|
|
|
self = *(int *) data;
|
|
|
|
iRet = LLDnodePtr2First(self);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(self, &tuktuk);
|
|
if (MotorGetSoftPosition(tuktuk.data, pCon, &value) == 1) {
|
|
tuktuk.position = value;
|
|
} else {
|
|
tuktuk.position = -9999999.99;
|
|
}
|
|
LLDnodeDataFrom(self, &tuktuk);
|
|
iRet = LLDnodePtr2Next(self);
|
|
}
|
|
return OKOK;
|
|
}
|
|
|
|
/*======================== interface functions ========================*/
|
|
pIDrivable makeMotListInterface()
|
|
{
|
|
pIDrivable pDriv = NULL;
|
|
pDriv = CreateDrivableInterface();
|
|
if (pDriv == NULL) {
|
|
return NULL;
|
|
}
|
|
pDriv->Halt = MOLIHalt;
|
|
pDriv->CheckLimits = MOLICheckLimits;
|
|
pDriv->SetValue = MOLISetValue;
|
|
pDriv->CheckStatus = MOLICheckStatus;
|
|
pDriv->GetValue = MOLIGetValue;
|
|
|
|
return pDriv;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
int addMotorToList(int listHandle, char *name, float targetValue)
|
|
{
|
|
pMotor pMot = NULL;
|
|
MotControl tuktuk;
|
|
|
|
pMot = FindMotor(pServ->pSics, name);
|
|
if (pMot == NULL) {
|
|
return 0;
|
|
}
|
|
tuktuk.data = pMot;
|
|
strlcpy(tuktuk.name, name, 79);
|
|
tuktuk.pDriv = pMot->pDrivInt;
|
|
tuktuk.target = targetValue;
|
|
tuktuk.running = 0;
|
|
tuktuk.position = -9999999.999;
|
|
LLDnodeAppendFrom(listHandle, &tuktuk);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
int setNewMotorTarget(int listHandle, char *name, float value)
|
|
{
|
|
int iRet;
|
|
MotControl tuktuk;
|
|
|
|
iRet = LLDnodePtr2First(listHandle);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(listHandle, &tuktuk);
|
|
if (strcmp(tuktuk.name, name) == 0) {
|
|
tuktuk.target = value;
|
|
tuktuk.running = 0;
|
|
LLDnodeDataFrom(listHandle, &tuktuk);
|
|
return 1;
|
|
}
|
|
iRet = LLDnodePtr2Next(listHandle);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------*/
|
|
int getMotorFromList(int listHandle, char *name, pMotControl tuk)
|
|
{
|
|
int iRet;
|
|
MotControl tuktuk;
|
|
|
|
iRet = LLDnodePtr2First(listHandle);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(listHandle, &tuktuk);
|
|
if (strcmp(tuktuk.name, name) == 0) {
|
|
memcpy(tuk, &tuktuk, sizeof(MotControl));
|
|
return 1;
|
|
}
|
|
iRet = LLDnodePtr2Next(listHandle);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------*/
|
|
float getListMotorPosition(int listHandle, char *name)
|
|
{
|
|
int iRet;
|
|
MotControl tuktuk;
|
|
|
|
iRet = LLDnodePtr2First(listHandle);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(listHandle, &tuktuk);
|
|
if (strcmp(tuktuk.name, name) == 0) {
|
|
return tuktuk.position;
|
|
}
|
|
iRet = LLDnodePtr2Next(listHandle);
|
|
}
|
|
return -999999.99;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
void printMotorList(int listHandle, SConnection * pCon)
|
|
{
|
|
int iRet;
|
|
MotControl tuktuk;
|
|
char pBueffel[132];
|
|
|
|
MOLIGetValue(&listHandle, pCon);
|
|
|
|
iRet = LLDnodePtr2First(listHandle);
|
|
while (iRet != 0) {
|
|
LLDnodeDataTo(listHandle, &tuktuk);
|
|
snprintf(pBueffel, 131, "Driving %20s from %8.3f to %8.3f",
|
|
tuktuk.name, tuktuk.position, tuktuk.target);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
iRet = LLDnodePtr2Next(listHandle);
|
|
}
|
|
}
|