Files
sics/motorlist.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
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
2015-04-23 20:49:26 +10:00

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