- Adding first working version of new AMOR settings module
- Improved sls magnet driver
This commit is contained in:
110
amorcomp.c
Normal file
110
amorcomp.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*---------------------------------------------------------------------
|
||||||
|
AMOR component handling module. For the new (2005) calculation of the
|
||||||
|
positions using the beam height as zero.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
#include "amorcomp.h"
|
||||||
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||||
|
|
||||||
|
double calcCompPosition(pamorComp comp){
|
||||||
|
return ABS(comp->scaleOffset - comp->markOffset - comp->readPosition);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
int handleCompCommand(pamorComp comp, SConnection *pCon,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
char pBueffel[512];
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
SCWrite(pCon,"ERROR: not enough arguments",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strtolower(argv[2]);
|
||||||
|
if(strcmp(argv[2],"list") == 0){
|
||||||
|
snprintf(pBueffel,511,
|
||||||
|
"%s %s active = %d\n%s %s offset = %f\n%s %s scaleoffset = %f\n%s %s read = %f\n%s %s calc = %f\n",
|
||||||
|
argv[0], argv[1], comp->activeFlag,
|
||||||
|
argv[0], argv[1], comp->markOffset,
|
||||||
|
argv[0], argv[1], comp->scaleOffset,
|
||||||
|
argv[0], argv[1], comp->readPosition,
|
||||||
|
argv[0], argv[1], calcCompPosition(comp));
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
} else if (strcmp(argv[2], "active") == 0) {
|
||||||
|
if(argc > 3) {
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCparChange(pCon);
|
||||||
|
comp->activeFlag = atoi(argv[3]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511," %s %s active = %d",
|
||||||
|
argv[0], argv[1], comp->activeFlag);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[2], "offset") == 0) {
|
||||||
|
if(argc > 3) {
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCparChange(pCon);
|
||||||
|
comp->markOffset = atof(argv[3]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511," %s %s offset = %f",
|
||||||
|
argv[0], argv[1], comp->markOffset);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[2], "scaleoffset") == 0) {
|
||||||
|
if(argc > 3) {
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
comp->scaleOffset = atof(argv[3]);
|
||||||
|
SCparChange(pCon);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511," %s %s scaleoffset = %f",
|
||||||
|
argv[0], argv[1], comp->scaleOffset);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[2], "read") == 0) {
|
||||||
|
if(argc > 3) {
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
comp->readPosition = atof(argv[3]);
|
||||||
|
SCparChange(pCon);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511," %s %s read = %f",
|
||||||
|
argv[0], argv[1], comp->readPosition);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,511,"ERROR: subcommand %s to %s %s not understood",
|
||||||
|
argv[2], argv[0], argv[1]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int saveAmorComp(FILE *fd, char *name, char *compname, pamorComp comp){
|
||||||
|
fprintf(fd,"%s %s active %d\n", name, compname, comp->activeFlag);
|
||||||
|
fprintf(fd,"%s %s offset %f\n", name, compname, comp->markOffset);
|
||||||
|
fprintf(fd,"%s %s scaleoffset %f\n", name, compname, comp->scaleOffset);
|
||||||
|
fprintf(fd,"%s %s read %f\n", name, compname, comp->readPosition);
|
||||||
|
return 1;
|
||||||
|
}
|
28
amorcomp.h
Normal file
28
amorcomp.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
AMOR component handling module. For the new (2005) calculation of the
|
||||||
|
positions using the beam height as zero.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORCOMP
|
||||||
|
#define AMORCOMP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sics.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int activeFlag; /* component present */
|
||||||
|
double markOffset; /* offset mark to real */
|
||||||
|
double scaleOffset; /* offset of the scale */
|
||||||
|
double readPosition; /* the position as read */
|
||||||
|
} amorComp, *pamorComp;
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
double calcCompPosition(pamorComp comp);
|
||||||
|
int handleCompCommand(pamorComp comp, SConnection *pCon,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int saveAmorComp(FILE *fd, char *name, char *compname, pamorComp comp);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
170
amordrive.c
Normal file
170
amordrive.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Part of the AMOR position calculation module.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
#include "amorset.h"
|
||||||
|
#include "amordrive.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------*/
|
||||||
|
static void *AMODRIVGetInterface(void *data, int iD){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
|
||||||
|
if(iD == DRIVEID && self != NULL){
|
||||||
|
return self->pDriv;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
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 AMODRIVHalt(void *data) {
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
|
||||||
|
return self->mama->pDriv->Halt(self->mama);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
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
|
||||||
|
Due to the complex nauture of the calculation: no check here
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
static int AMODRIVCheckLimits(void *data, float val,
|
||||||
|
char *error, int errlen){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
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 AMODRIVSetValue(void *data, SConnection *pCon, float val){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
|
||||||
|
amorSetMotor(self->mama, self->type, val);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
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 AMODRIVCheckStatus(void *data, SConnection *pCon){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
|
||||||
|
return self->mama->pDriv->CheckStatus(self->mama, pCon);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
GetValue is supposed to read a motor position
|
||||||
|
On errors, -99999999.99 is returned and messages printed to pCon
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
static float AMODRIVGetValue(void *data, SConnection *pCon){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
float val = -99999999.99;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
return amorGetMotor(self->mama,pCon,self->type);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
returns NULL on failure, a new datastrcuture else
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
static pamorDrive AMODRIVMakeObject(){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)malloc(sizeof(amorDrive));
|
||||||
|
if(self == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(self,0,sizeof(amorDrive));
|
||||||
|
self->pDes = CreateDescriptor("AmorDrive");
|
||||||
|
self->pDriv = CreateDrivableInterface();
|
||||||
|
if(self->pDes == NULL || self->pDriv == NULL){
|
||||||
|
free(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pDes->GetInterface = AMODRIVGetInterface;
|
||||||
|
self->pDriv->Halt = AMODRIVHalt;
|
||||||
|
self->pDriv->CheckLimits = AMODRIVCheckLimits;
|
||||||
|
self->pDriv->SetValue = AMODRIVSetValue;
|
||||||
|
self->pDriv->CheckStatus = AMODRIVCheckStatus;
|
||||||
|
self->pDriv->GetValue = AMODRIVGetValue;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
void killAmorDrive(void *data){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = (pamorDrive)data;
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(self->pDes != NULL){
|
||||||
|
DeleteDescriptor(self->pDes);
|
||||||
|
}
|
||||||
|
if(self->pDriv != NULL){
|
||||||
|
free(self->pDriv);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
pamorDrive makeAmorDrive(pamorSet papa, int type){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
|
||||||
|
self = AMODRIVMakeObject();
|
||||||
|
if(self == NULL){
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
self->mama = papa;
|
||||||
|
self->type = type;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
int AmorDriveAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pamorDrive self = NULL;
|
||||||
|
float val;
|
||||||
|
char pBueffel[132];
|
||||||
|
|
||||||
|
self = (pamorDrive)pData;
|
||||||
|
assert(self);
|
||||||
|
val = amorGetMotor(self->mama, pCon,self->type);
|
||||||
|
if(val > -999999) {
|
||||||
|
snprintf(pBueffel,131, " %s = %f", argv[0], val);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
25
amordrive.h
Normal file
25
amordrive.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Part of the AMOR position calculation module.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORDRIVE
|
||||||
|
#define AMORDRIVE
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
pamorSet mama;
|
||||||
|
int type;
|
||||||
|
} amorDrive, *pamorDrive;
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
pamorDrive makeAmorDrive(pamorSet papa, int type);
|
||||||
|
void killAmorDrive(void *data);
|
||||||
|
int AmorDriveAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
600
amorset.c
Normal file
600
amorset.c
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
/*-------------------------------------------------------------------
|
||||||
|
AMORSET together with amorcomp and amordrive implement the position
|
||||||
|
control facility for the reflectometer AMOR. This uses the algorithm
|
||||||
|
with the beam height as the baseline.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "amorset.h"
|
||||||
|
#include <motorlist.h>
|
||||||
|
#include "amorcomp.h"
|
||||||
|
#include "amordrive.h"
|
||||||
|
#include <trigd.h>
|
||||||
|
#include <lld.h>
|
||||||
|
#include "motor.h"
|
||||||
|
/*--------------------- type defines ------------------------------*/
|
||||||
|
#define TYM2T 1
|
||||||
|
#define TYS2T 2
|
||||||
|
#define TYATH 3
|
||||||
|
|
||||||
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||||
|
/*------------ The meat of it all: The settings calculation --------*/
|
||||||
|
static int readMotors(pamorSet self, SConnection *pCon){
|
||||||
|
int result, status;
|
||||||
|
float val;
|
||||||
|
|
||||||
|
result = LLDcreate(sizeof(MotControl));
|
||||||
|
status = addMotorToList(result,"d2t",.0);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: configuration error: d2t not found", eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
status = addMotorToList(result,"d3t",.0);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: configuration error: d3t not found", eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
status = addMotorToList(result,"d4t",.0);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: configuration error: d4t not found", eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
status = addMotorToList(result,"d5t",.0);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: configuration error: d5t not found", eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val = self->listDrive->GetValue(&result,pCon);
|
||||||
|
if(val < -99999){
|
||||||
|
LLDdelete(result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
static int calcAmorSettings(pamorSet self,SConnection *pCon){
|
||||||
|
int readList;
|
||||||
|
double val, dist, com = .0, soz, mot;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read motors
|
||||||
|
*/
|
||||||
|
readList = readMotors(self,pCon);
|
||||||
|
if(readList < 0){
|
||||||
|
SCWrite(pCon,
|
||||||
|
"ERROR: failed to read motors for amor settings",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* initialize drive list
|
||||||
|
*/
|
||||||
|
LLDdelete(self->driveList);
|
||||||
|
self->driveList = LLDcreate(sizeof(MotControl));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* soz
|
||||||
|
*/
|
||||||
|
dist = calcCompPosition(&self->S) - calcCompPosition(&self->M);
|
||||||
|
soz = dist*Tand(self->targetm2t);
|
||||||
|
addMotorToList(self->driveList,"soz",soz);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* monochromator slit
|
||||||
|
*/
|
||||||
|
if(self->DS.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->DS) - calcCompPosition(&self->M);
|
||||||
|
val = dist*Tand(self->targetm2t) - self->dspar;
|
||||||
|
addMotorToList(self->driveList,"dbs",val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slit 2
|
||||||
|
*/
|
||||||
|
if(self->D2.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->D2) - calcCompPosition(&self->M);
|
||||||
|
mot = getListMotorPosition(readList,"d2t");
|
||||||
|
if(mot < -99999){
|
||||||
|
SCWrite(pCon,"WARNING: skipping d2 because of bad read on d2t",
|
||||||
|
eWarning);
|
||||||
|
} else {
|
||||||
|
val = dist*Tand(self->targetm2t) - .5 * mot;
|
||||||
|
addMotorToList(self->driveList,"d2b",val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slit 3
|
||||||
|
*/
|
||||||
|
if(self->D3.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->D3) - calcCompPosition(&self->M);
|
||||||
|
mot = getListMotorPosition(readList,"d3t");
|
||||||
|
if(mot < -99999){
|
||||||
|
SCWrite(pCon,"WARNING: skipping d3 because of bad read on d3t",
|
||||||
|
eWarning);
|
||||||
|
} else {
|
||||||
|
val = dist*Tand(self->targetm2t) - .5 * mot;
|
||||||
|
addMotorToList(self->driveList,"d3b",val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* detector
|
||||||
|
*/
|
||||||
|
com = self->targetm2t + self->targets2t;
|
||||||
|
if(self->D.activeFlag == 1){
|
||||||
|
addMotorToList(self->driveList,"com",com);
|
||||||
|
dist = calcCompPosition(&self->D) - calcCompPosition(&self->S);
|
||||||
|
val = dist*(Cosd(com) - 1.);
|
||||||
|
addMotorToList(self->driveList,"cox",val);
|
||||||
|
val = dist*Sind(com) + soz;
|
||||||
|
addMotorToList(self->driveList,"coz",val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slit 4
|
||||||
|
*/
|
||||||
|
if(self->D4.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->D4) - calcCompPosition(&self->S);
|
||||||
|
mot = getListMotorPosition(readList,"d4t");
|
||||||
|
if(mot < -99999){
|
||||||
|
SCWrite(pCon,"WARNING: skipping d4 because of bad read on d4t",
|
||||||
|
eWarning);
|
||||||
|
} else {
|
||||||
|
val = soz + dist*Tand(com) - .5 * mot;
|
||||||
|
addMotorToList(self->driveList,"d4b",val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* slit 5
|
||||||
|
*/
|
||||||
|
if(self->D5.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->D5) - calcCompPosition(&self->S);
|
||||||
|
mot = getListMotorPosition(readList,"d5t");
|
||||||
|
if(mot < -99999){
|
||||||
|
SCWrite(pCon,"WARNING: skipping d5 because of bad read on d5t",
|
||||||
|
eWarning);
|
||||||
|
} else {
|
||||||
|
val = soz + dist*Tand(com) - .5 * mot;
|
||||||
|
addMotorToList(self->driveList,"d5b",val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analyzer
|
||||||
|
*/
|
||||||
|
if(self->A.activeFlag == 1){
|
||||||
|
dist = calcCompPosition(&self->A) - calcCompPosition(&self->S);
|
||||||
|
val = soz + dist*Tand(com);
|
||||||
|
addMotorToList(self->driveList,"aoz",val);
|
||||||
|
addMotorToList(self->driveList,"aom",com + self->targetath);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLDdelete(readList);
|
||||||
|
self->mustDrive = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
static int updateActualPositions(pamorSet self, SConnection *pCon){
|
||||||
|
int readList, status;
|
||||||
|
float val, dist, tmp, com;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read some motors
|
||||||
|
*/
|
||||||
|
readList = LLDcreate(sizeof(MotControl));
|
||||||
|
addMotorToList(readList,"soz",125);
|
||||||
|
addMotorToList(readList,"com",125);
|
||||||
|
addMotorToList(readList,"aom",125);
|
||||||
|
val = self->listDrive->GetValue(&readList,pCon);
|
||||||
|
if(val < -99999.){
|
||||||
|
SCWrite(pCon,
|
||||||
|
"ERROR: failed to read motors, values for m2t,s2t,ath invalid",
|
||||||
|
eError);
|
||||||
|
LLDdelete(readList);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val = getListMotorPosition(readList,"soz");
|
||||||
|
dist = calcCompPosition(&self->S) - calcCompPosition(&self->M);
|
||||||
|
tmp = val/dist;
|
||||||
|
if(ABS(tmp) > .0001){
|
||||||
|
self->actualm2t = Atand(tmp);
|
||||||
|
} else {
|
||||||
|
self->actualm2t = .0;
|
||||||
|
}
|
||||||
|
com = getListMotorPosition(readList,"com");
|
||||||
|
self->actuals2t = com - self->actualm2t;
|
||||||
|
|
||||||
|
val = getListMotorPosition(readList,"aom");
|
||||||
|
self->actualath = val - com;
|
||||||
|
|
||||||
|
LLDdelete(readList);
|
||||||
|
self->mustRecalculate = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=================== SICS internal interface functions============*/
|
||||||
|
static void *AMOSETGetInterface(void *data, int iD){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this object shall never be driven directly
|
||||||
|
*/
|
||||||
|
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 AMOSETHalt(void *data) {
|
||||||
|
pamorSet self = NULL;
|
||||||
|
|
||||||
|
self = (pamorSet)data;
|
||||||
|
|
||||||
|
self->listDrive->Halt(&self->driveList);
|
||||||
|
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 AMOSETCheckLimits(void *data, float val,
|
||||||
|
char *error, int errlen){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
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 AMOSETSetValue(void *data, SConnection *pCon, float val){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
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 AMOSETCheckStatus(void *data, SConnection *pCon){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
self = (pamorSet)data;
|
||||||
|
|
||||||
|
if(self->mustDrive == 1){
|
||||||
|
status = calcAmorSettings(self,pCon);
|
||||||
|
if(status <= 0){
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
if(self->verbose == 1){
|
||||||
|
printMotorList(self->driveList,pCon);
|
||||||
|
}
|
||||||
|
return self->listDrive->SetValue(&self->driveList,pCon,.37);
|
||||||
|
} else {
|
||||||
|
self->mustRecalculate = 1;
|
||||||
|
return self->listDrive->CheckStatus(&self->driveList,pCon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
GetValue is supposed to read a motor position
|
||||||
|
On errors, -99999999.99 is returned and messages printed to pCon
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
static float AMOSETGetValue(void *data, SConnection *pCon){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
float val = -99999999.99;
|
||||||
|
|
||||||
|
self = (pamorSet)data;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
/*================ external functions for amordrive ============*/
|
||||||
|
void amorSetMotor(pamorSet amor, int type, double value){
|
||||||
|
switch(type){
|
||||||
|
case TYM2T:
|
||||||
|
amor->targetm2t = value;
|
||||||
|
break;
|
||||||
|
case TYS2T:
|
||||||
|
amor->targets2t = value;
|
||||||
|
break;
|
||||||
|
case TYATH:
|
||||||
|
amor->targetath = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
amor->mustDrive = 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
double amorGetMotor(pamorSet amor, SConnection *pCon, int type){
|
||||||
|
if(amor->mustRecalculate == 1){
|
||||||
|
updateActualPositions(amor,pCon);
|
||||||
|
}
|
||||||
|
switch(type){
|
||||||
|
case TYM2T:
|
||||||
|
return amor->actualm2t;
|
||||||
|
break;
|
||||||
|
case TYS2T:
|
||||||
|
return amor->actuals2t;
|
||||||
|
break;
|
||||||
|
case TYATH:
|
||||||
|
return amor->actualath;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -99999.999;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
Live and Deatch of objects.........
|
||||||
|
returns NULL on failure, a new datastructure else
|
||||||
|
------------------------------------------------------------------*/
|
||||||
|
static int amorSetSave(void *data, char *name,FILE *fd){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
|
||||||
|
self = (pamorSet)data;
|
||||||
|
if(self == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fprintf(fd,"%s dspar %f\n", name, self->dspar);
|
||||||
|
fprintf(fd,"%s verbose %d\n", name, self->verbose);
|
||||||
|
saveAmorComp(fd,name,"mono",&self->M);
|
||||||
|
saveAmorComp(fd,name,"ds",&self->DS);
|
||||||
|
saveAmorComp(fd,name,"slit2",&self->D2);
|
||||||
|
saveAmorComp(fd,name,"slit3",&self->D3);
|
||||||
|
saveAmorComp(fd,name,"sample",&self->S);
|
||||||
|
saveAmorComp(fd,name,"slit4",&self->D4);
|
||||||
|
saveAmorComp(fd,name,"slit5",&self->D5);
|
||||||
|
saveAmorComp(fd,name,"ana",&self->A);
|
||||||
|
saveAmorComp(fd,name,"detector",&self->D);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------*/
|
||||||
|
static pamorSet AMOSETMakeObject(){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
|
||||||
|
self = (pamorSet)malloc(sizeof(amorSet));
|
||||||
|
if(self == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(self,0,sizeof(amorSet));
|
||||||
|
self->pDes = CreateDescriptor("AmorSet");
|
||||||
|
self->pDriv = CreateDrivableInterface();
|
||||||
|
self->listDrive = makeMotListInterface();
|
||||||
|
self->driveList = LLDcreate(sizeof(MotControl));
|
||||||
|
if(self->pDes == NULL || self->pDriv == NULL ||
|
||||||
|
self->listDrive == NULL || self->driveList < 0){
|
||||||
|
free(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pDes->GetInterface = AMOSETGetInterface;
|
||||||
|
self->pDes->SaveStatus = amorSetSave;
|
||||||
|
self->pDriv->Halt = AMOSETHalt;
|
||||||
|
self->pDriv->CheckLimits = AMOSETCheckLimits;
|
||||||
|
self->pDriv->SetValue = AMOSETSetValue;
|
||||||
|
self->pDriv->CheckStatus = AMOSETCheckStatus;
|
||||||
|
self->pDriv->GetValue = AMOSETGetValue;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static void killAmorSet(void *data){
|
||||||
|
pamorSet self = (pamorSet)data;
|
||||||
|
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self->pDes != NULL) {
|
||||||
|
DeleteDescriptor(self->pDes);
|
||||||
|
}
|
||||||
|
if(self->pDriv != NULL){
|
||||||
|
free(self->pDriv);
|
||||||
|
}
|
||||||
|
if(self->listDrive != NULL){
|
||||||
|
free(self->listDrive);
|
||||||
|
}
|
||||||
|
LLDdelete(self->driveList);
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int testRequiredMotors(SConnection *pCon){
|
||||||
|
char motList[][20] = {"soz", "com",
|
||||||
|
"cox","coz","dbs","d2b","d2t",
|
||||||
|
"d3b", "d3t", "d4b","d4t",
|
||||||
|
"d5t", "d5b","aoz", "aom"};
|
||||||
|
int i = 0, status = 1;
|
||||||
|
pMotor pMot = NULL;
|
||||||
|
char pBueffel[132];
|
||||||
|
|
||||||
|
|
||||||
|
for(i = 0; i < 15; i++){
|
||||||
|
pMot = NULL;
|
||||||
|
pMot = FindMotor(pServ->pSics,motList[i]);
|
||||||
|
if(pMot == NULL){
|
||||||
|
snprintf(pBueffel,131,"ERROR: motor %s for amorset not found",
|
||||||
|
motList[i]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*======================= interpreter interface section ============*/
|
||||||
|
int AmorSetFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
int status;
|
||||||
|
pamorSet pNew = NULL;
|
||||||
|
pamorDrive pTuk = NULL;
|
||||||
|
|
||||||
|
if(testRequiredMotors(pCon) == 0){
|
||||||
|
SCWrite(pCon,
|
||||||
|
"ERROR: aborting initialization of amorset due to missing motors",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew = AMOSETMakeObject();
|
||||||
|
if(pNew == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating amorset",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,"amorset",AmorSetAction,killAmorSet,pNew);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: duplicate command amorset NOT created",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pTuk = makeAmorDrive(pNew,TYM2T);
|
||||||
|
if(pTuk == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: failed to allocate data fro m2t",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,"m2t",AmorDriveAction,killAmorDrive,pTuk);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: duplicate command amorset m2t reated",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pTuk = makeAmorDrive(pNew,TYATH);
|
||||||
|
if(pTuk == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: failed to allocate data for ath",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,"ath",AmorDriveAction,killAmorDrive,pTuk);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: duplicate command amorset ath reated",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pTuk = makeAmorDrive(pNew,TYS2T);
|
||||||
|
if(pTuk == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: failed to allocate data for s2t",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,"s2t",AmorDriveAction,killAmorDrive,pTuk);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: duplicate command amorset s2t reated",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static pamorComp locateComponent(pamorSet self, char *name){
|
||||||
|
if(strcmp(name,"mono") == 0){
|
||||||
|
return &self->M;
|
||||||
|
} else if(strcmp(name,"ds") == 0){
|
||||||
|
return &self->DS;
|
||||||
|
}else if(strcmp(name,"slit2") == 0){
|
||||||
|
return &self->D2;
|
||||||
|
}else if(strcmp(name,"slit3") == 0){
|
||||||
|
return &self->D3;
|
||||||
|
}else if(strcmp(name,"sample") == 0){
|
||||||
|
return &self->S;
|
||||||
|
} else if(strcmp(name,"slit4") == 0){
|
||||||
|
return &self->D4;
|
||||||
|
}else if(strcmp(name,"slit5") == 0){
|
||||||
|
return &self->D5;
|
||||||
|
}else if(strcmp(name,"detector") == 0){
|
||||||
|
return &self->D;
|
||||||
|
}else if(strcmp(name,"ana") == 0){
|
||||||
|
return &self->A;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static double calcCD(pamorSet self){
|
||||||
|
double soz, cmh, smh, sdh, cd, dist;
|
||||||
|
|
||||||
|
soz = dist*Cotd(self->targetm2t);
|
||||||
|
cmh = calcCompPosition(&self->M);
|
||||||
|
smh = calcCompPosition(&self->S) - calcCompPosition(&self->M);
|
||||||
|
sdh = calcCompPosition(&self->D) - calcCompPosition(&self->M);
|
||||||
|
cd = cmh + sqrt(smh*smh + soz*soz) + sdh;
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int AmorSetAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pamorSet self = NULL;
|
||||||
|
pamorComp comp = NULL;
|
||||||
|
char pBueffel[132];
|
||||||
|
|
||||||
|
self = (pamorSet)pData;
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if(argc < 2){
|
||||||
|
SCWrite(pCon,"ERROR: not enough arguments to amorset",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* catch component commands
|
||||||
|
*/
|
||||||
|
strtolower(argv[1]);
|
||||||
|
comp = locateComponent(self,argv[1]);
|
||||||
|
if(comp != NULL){
|
||||||
|
return handleCompCommand(comp,pCon,argc,argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now it is for us ....
|
||||||
|
*/
|
||||||
|
if(strcmp(argv[1],"dspar") == 0){
|
||||||
|
if(argc > 2){
|
||||||
|
if(!SCMatchRights(pCon,usMugger)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->dspar = atof(argv[2]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,131,"%s dspar = %f", argv[0], self->dspar);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}else if(strcmp(argv[1],"verbose") == 0){
|
||||||
|
if(argc > 2){
|
||||||
|
if(!SCMatchRights(pCon,usMugger)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->verbose = atoi(argv[2]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,131,"%s verbose = %d", argv[0], self->verbose);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if(strcmp(argv[1],"cd") == 0){
|
||||||
|
snprintf(pBueffel,131,"%s cd = %f", argv[0], calcCD(self));
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon,"ERROR: unknown subcommand to amorset",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
50
amorset.h
Normal file
50
amorset.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
AMORSET together with amorcomp and amordrive implement the position
|
||||||
|
control facility for the reflectometer AMOR. This uses the algorithm
|
||||||
|
with the beam height as the baseline.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORSET
|
||||||
|
#define AMORSET
|
||||||
|
#include "amorcomp.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
pIDrivable listDrive;
|
||||||
|
amorComp M;
|
||||||
|
amorComp DS;
|
||||||
|
amorComp D2;
|
||||||
|
amorComp D3;
|
||||||
|
amorComp S;
|
||||||
|
amorComp D4;
|
||||||
|
amorComp A;
|
||||||
|
amorComp D5;
|
||||||
|
amorComp D;
|
||||||
|
double targetm2t;
|
||||||
|
double targets2t;
|
||||||
|
double targetath;
|
||||||
|
double actualm2t;
|
||||||
|
double actuals2t;
|
||||||
|
double actualath;
|
||||||
|
int mustDrive;
|
||||||
|
int mustRecalculate;
|
||||||
|
int driveList;
|
||||||
|
double dspar;
|
||||||
|
int verbose;
|
||||||
|
}amorSet, *pamorSet;
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int AmorSetFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int AmorSetAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
/*============ helper functions for the virtual motors ===============*/
|
||||||
|
void amorSetMotor(pamorSet amor, int type, double value);
|
||||||
|
double amorGetMotor(pamorSet amor, SConnection *pCon, int type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
209
amorset.tex
Normal file
209
amorset.tex
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
\subsection{AMOR Reflectometer Settings}
|
||||||
|
This is yet another module for calculating the settings for the AMOR
|
||||||
|
spectrometer. This version is of 2005 and implements the new calculation
|
||||||
|
scheme as devised by the Jochen where the base line and height zero point
|
||||||
|
is the beam height at the chop, chop, chopper.
|
||||||
|
|
||||||
|
Again a lot of parameters have to be maintained. For each optical bench
|
||||||
|
component an active flag, a fixed offset for correcting the scale reading to
|
||||||
|
the actual position and an offset regarding the zero point of the scale need
|
||||||
|
to be kept. And of course the value as read. This is offloaded into a
|
||||||
|
separate module, amorcomp. Beamline components to be controlled are:
|
||||||
|
\begin{description}
|
||||||
|
\item[DS] The slit at the monochromator bunker
|
||||||
|
\item[M] The monochromator
|
||||||
|
\item[Dx] various slits
|
||||||
|
\item[A] the analyzer
|
||||||
|
\item[D] the detector.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
A master module encloses all those beamline components and performs the
|
||||||
|
actual calculation. The calculation is controlled through three virtual
|
||||||
|
motors: m2t (monochromator 2 theta), s2t (sample 2 theta) and ath, the
|
||||||
|
analyzer angle. For the formula used for the exact calculation, see the
|
||||||
|
paper from the Jochen.
|
||||||
|
|
||||||
|
|
||||||
|
The amorcomp module provides the following interface:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap1}
|
||||||
|
$\langle$amorcompint {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ typedef struct {@\\
|
||||||
|
\mbox{}\verb@ int activeFlag; /* component present */@\\
|
||||||
|
\mbox{}\verb@ double markOffset; /* offset mark to real */@\\
|
||||||
|
\mbox{}\verb@ double scaleOffset; /* offset of the scale */@\\
|
||||||
|
\mbox{}\verb@ double readPosition; /* the position as read */@\\
|
||||||
|
\mbox{}\verb@} amorComp, *pamorComp;@\\
|
||||||
|
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@double calcCompPosition(pamorComp comp); @\\
|
||||||
|
\mbox{}\verb@int handleCompCommand(pamorComp comp, SConnection *pCon, @\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@int saveAmorComp(FILE *fd, char *name, char *compname, pamorComp comp); @\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
The amorset module implements the container for all the data and the actual
|
||||||
|
calculation. Most of the interesting stuff is in the functions relating to
|
||||||
|
the interpreter interface and the drivable interface. Again the virtual
|
||||||
|
motors only set values in the amorset data structure and amorset then takes
|
||||||
|
control off the driving operation.
|
||||||
|
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap2}
|
||||||
|
$\langle$amorsetint {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@typedef struct {@\\
|
||||||
|
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||||
|
\mbox{}\verb@ pIDrivable pDriv;@\\
|
||||||
|
\mbox{}\verb@ pIDrivable listDrive;@\\
|
||||||
|
\mbox{}\verb@ amorComp M;@\\
|
||||||
|
\mbox{}\verb@ amorComp DS;@\\
|
||||||
|
\mbox{}\verb@ amorComp D2;@\\
|
||||||
|
\mbox{}\verb@ amorComp D3;@\\
|
||||||
|
\mbox{}\verb@ amorComp S;@\\
|
||||||
|
\mbox{}\verb@ amorComp D4;@\\
|
||||||
|
\mbox{}\verb@ amorComp A;@\\
|
||||||
|
\mbox{}\verb@ amorComp D5;@\\
|
||||||
|
\mbox{}\verb@ amorComp D;@\\
|
||||||
|
\mbox{}\verb@ double targetm2t;@\\
|
||||||
|
\mbox{}\verb@ double targets2t;@\\
|
||||||
|
\mbox{}\verb@ double targetath;@\\
|
||||||
|
\mbox{}\verb@ double actualm2t;@\\
|
||||||
|
\mbox{}\verb@ double actuals2t;@\\
|
||||||
|
\mbox{}\verb@ double actualath;@\\
|
||||||
|
\mbox{}\verb@ int mustDrive;@\\
|
||||||
|
\mbox{}\verb@ int mustRecalculate;@\\
|
||||||
|
\mbox{}\verb@ int driveList;@\\
|
||||||
|
\mbox{}\verb@ double dspar;@\\
|
||||||
|
\mbox{}\verb@ int verbose;@\\
|
||||||
|
\mbox{}\verb@}amorSet, *pamorSet;@\\
|
||||||
|
\mbox{}\verb@/*--------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@int AmorSetFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@int AmorSetAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@/*============ helper functions for the virtual motors ===============*/ @\\
|
||||||
|
\mbox{}\verb@void amorSetMotor(pamorSet amor, int type, double value);@\\
|
||||||
|
\mbox{}\verb@double amorGetMotor(pamorSet amor, SConnection *pCon, int type);@\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
The virtual motors just implement the bare minimum:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap3}
|
||||||
|
$\langle$amordriveint {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@typedef struct{@\\
|
||||||
|
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||||
|
\mbox{}\verb@ pIDrivable pDriv;@\\
|
||||||
|
\mbox{}\verb@ pamorSet mama;@\\
|
||||||
|
\mbox{}\verb@ int type;@\\
|
||||||
|
\mbox{}\verb@} amorDrive, *pamorDrive;@\\
|
||||||
|
\mbox{}\verb@/*-----------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@pamorDrive makeAmorDrive(pamorSet papa, int type);@\\
|
||||||
|
\mbox{}\verb@void killAmorDrive(void *data);@\\
|
||||||
|
\mbox{}\verb@int AmorDriveAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap4}
|
||||||
|
\verb@"amorset.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*-------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ AMORSET together with amorcomp and amordrive implement the position@\\
|
||||||
|
\mbox{}\verb@ control facility for the reflectometer AMOR. This uses the algorithm@\\
|
||||||
|
\mbox{}\verb@ with the beam height as the baseline.@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ Mark Koennecke, October 2005@\\
|
||||||
|
\mbox{}\verb@--------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@#ifndef AMORSET@\\
|
||||||
|
\mbox{}\verb@#define AMORSET@\\
|
||||||
|
\mbox{}\verb@#include "amorcomp.h"@\\
|
||||||
|
\mbox{}\verb@@$\langle$amorsetint {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@#endif@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-2ex}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap5}
|
||||||
|
\verb@"amorcomp.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*---------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ AMOR component handling module. For the new (2005) calculation of the@\\
|
||||||
|
\mbox{}\verb@ positions using the beam height as zero.@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ Mark Koennecke, October 2005@\\
|
||||||
|
\mbox{}\verb@-----------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@ #ifndef AMORCOMP@\\
|
||||||
|
\mbox{}\verb@ #define AMORCOMP@\\
|
||||||
|
\mbox{}\verb@ #include <stdio.h>@\\
|
||||||
|
\mbox{}\verb@ #include <sics.h>@\\
|
||||||
|
\mbox{}\verb@ @$\langle$amorcompint {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@ #endif@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-2ex}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap6}
|
||||||
|
\verb@"amordrive.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ /*--------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ Part of the AMOR position calculation module.@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Mark Koennecke, October 2005@\\
|
||||||
|
\mbox{}\verb@----------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@#ifndef AMORDRIVE@\\
|
||||||
|
\mbox{}\verb@#define AMORDRIVE@\\
|
||||||
|
\mbox{}\verb@@$\langle$amordriveint {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@#endif@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ @$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-2ex}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
152
amorset.w
Normal file
152
amorset.w
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
\subsection{AMOR Reflectometer Settings}
|
||||||
|
This is yet another module for calculating the settings for the AMOR
|
||||||
|
spectrometer. This version is of 2005 and implements the new calculation
|
||||||
|
scheme as devised by the Jochen where the base line and height zero point
|
||||||
|
is the beam height at the chop, chop, chopper.
|
||||||
|
|
||||||
|
Again a lot of parameters have to be maintained. For each optical bench
|
||||||
|
component an active flag, a fixed offset for correcting the scale reading to
|
||||||
|
the actual position and an offset regarding the zero point of the scale need
|
||||||
|
to be kept. And of course the value as read. This is offloaded into a
|
||||||
|
separate module, amorcomp. Beamline components to be controlled are:
|
||||||
|
\begin{description}
|
||||||
|
\item[DS] The slit at the monochromator bunker
|
||||||
|
\item[M] The monochromator
|
||||||
|
\item[Dx] various slits
|
||||||
|
\item[A] the analyzer
|
||||||
|
\item[D] the detector.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
A master module encloses all those beamline components and performs the
|
||||||
|
actual calculation. The calculation is controlled through three virtual
|
||||||
|
motors: m2t (monochromator 2 theta), s2t (sample 2 theta) and ath, the
|
||||||
|
analyzer angle. For the formula used for the exact calculation, see the
|
||||||
|
paper from the Jochen.
|
||||||
|
|
||||||
|
|
||||||
|
The amorcomp module provides the following interface:
|
||||||
|
@d amorcompint @{
|
||||||
|
typedef struct {
|
||||||
|
int activeFlag; /* component present */
|
||||||
|
double markOffset; /* offset mark to real */
|
||||||
|
double scaleOffset; /* offset of the scale */
|
||||||
|
double readPosition; /* the position as read */
|
||||||
|
} amorComp, *pamorComp;
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
double calcCompPosition(pamorComp comp);
|
||||||
|
int handleCompCommand(pamorComp comp, SConnection *pCon,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int saveAmorComp(FILE *fd, char *name, char *compname, pamorComp comp);
|
||||||
|
@}
|
||||||
|
|
||||||
|
The amorset module implements the container for all the data and the actual
|
||||||
|
calculation. Most of the interesting stuff is in the functions relating to
|
||||||
|
the interpreter interface and the drivable interface. Again the virtual
|
||||||
|
motors only set values in the amorset data structure and amorset then takes
|
||||||
|
control off the driving operation.
|
||||||
|
|
||||||
|
@d amorsetint @{
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
pIDrivable listDrive;
|
||||||
|
amorComp M;
|
||||||
|
amorComp DS;
|
||||||
|
amorComp D2;
|
||||||
|
amorComp D3;
|
||||||
|
amorComp S;
|
||||||
|
amorComp D4;
|
||||||
|
amorComp A;
|
||||||
|
amorComp D5;
|
||||||
|
amorComp D;
|
||||||
|
double targetm2t;
|
||||||
|
double targets2t;
|
||||||
|
double targetath;
|
||||||
|
double actualm2t;
|
||||||
|
double actuals2t;
|
||||||
|
double actualath;
|
||||||
|
int mustDrive;
|
||||||
|
int mustRecalculate;
|
||||||
|
int driveList;
|
||||||
|
double dspar;
|
||||||
|
int verbose;
|
||||||
|
}amorSet, *pamorSet;
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int AmorSetFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int AmorSetAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
/*============ helper functions for the virtual motors ===============*/
|
||||||
|
void amorSetMotor(pamorSet amor, int type, double value);
|
||||||
|
double amorGetMotor(pamorSet amor, SConnection *pCon, int type);
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
The virtual motors just implement the bare minimum:
|
||||||
|
@d amordriveint @{
|
||||||
|
typedef struct{
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
pamorSet mama;
|
||||||
|
int type;
|
||||||
|
} amorDrive, *pamorDrive;
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
pamorDrive makeAmorDrive(pamorSet papa, int type);
|
||||||
|
void killAmorDrive(void *data);
|
||||||
|
int AmorDriveAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
@o amorset.h @{
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
AMORSET together with amorcomp and amordrive implement the position
|
||||||
|
control facility for the reflectometer AMOR. This uses the algorithm
|
||||||
|
with the beam height as the baseline.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
--------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORSET
|
||||||
|
#define AMORSET
|
||||||
|
#include "amorcomp.h"
|
||||||
|
@<amorsetint@>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@}
|
||||||
|
|
||||||
|
@o amorcomp.h @{
|
||||||
|
/*---------------------------------------------------------------------
|
||||||
|
AMOR component handling module. For the new (2005) calculation of the
|
||||||
|
positions using the beam height as zero.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORCOMP
|
||||||
|
#define AMORCOMP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sics.h>
|
||||||
|
@<amorcompint@>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
@o amordrive.h @{
|
||||||
|
/*--------------------------------------------------------------------
|
||||||
|
Part of the AMOR position calculation module.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, October 2005
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
#ifndef AMORDRIVE
|
||||||
|
#define AMORDRIVE
|
||||||
|
@<amordriveint@>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@}
|
||||||
|
|
418
dspcode.c
Normal file
418
dspcode.c
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
void slsdspCodeToText(int code, char *text, int textlen){
|
||||||
|
switch(code){
|
||||||
|
case 0x0:
|
||||||
|
strncpy(text,"NO",textlen);
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
strncpy(text,"DEVICE_STATE_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
strncpy(text,"DEVICE_SUPERVISOR_DISABLED",textlen);
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
strncpy(text,"COMMAND_ABORT",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
strncpy(text,"DATA_NOT_STORED",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5:
|
||||||
|
strncpy(text,"ERROR_ERASING_FLASH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6:
|
||||||
|
strncpy(text,"COMMUNICATION_BREAK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7:
|
||||||
|
strncpy(text,"INTERNAL_COMMUNICATION_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8:
|
||||||
|
strncpy(text,"MASTER_CARD_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
strncpy(text,"INTERNAL_BUFFER_FULL",textlen);
|
||||||
|
break;
|
||||||
|
case 0xa:
|
||||||
|
strncpy(text,"WRONG_SECTOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb:
|
||||||
|
strncpy(text,"DATA_NOT_COPIED",textlen);
|
||||||
|
break;
|
||||||
|
case 0xc:
|
||||||
|
strncpy(text,"WRONG_DOWNLOAD_PARAMETERS",textlen);
|
||||||
|
break;
|
||||||
|
case 0xd:
|
||||||
|
strncpy(text,"DEVICE_PARAMETRIZATION_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE",textlen);
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
strncpy(text,"TIMEOUT_DATA_DOWNLOAD",textlen);
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
strncpy(text,"INTERLOCK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
strncpy(text,"MASTER_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x22:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x23:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x24:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x25:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x26:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x27:
|
||||||
|
strncpy(text,"TEMPERATURE_POLARITY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x28:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x29:
|
||||||
|
strncpy(text,"MAIN_RELAY",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2a:
|
||||||
|
strncpy(text,"AD_CONVERTER_CARD",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2b:
|
||||||
|
strncpy(text,"POLARITY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2c:
|
||||||
|
strncpy(text,"AUXILIARY_RELAY",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2d:
|
||||||
|
strncpy(text,"MASTER_SWITCH_T1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2e:
|
||||||
|
strncpy(text,"MASTER_SWITCH_T2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2f:
|
||||||
|
strncpy(text,"TEMPERATURE_MAGNET",textlen);
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
strncpy(text,"WATER_MAGNET",textlen);
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
strncpy(text,"WATER_RACK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
strncpy(text,"LOAD_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x41:
|
||||||
|
strncpy(text,"DC_LINK_VOLTAGE_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x42:
|
||||||
|
strncpy(text,"DC_LINK_VOLTAGE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x43:
|
||||||
|
strncpy(text,"LOAD_VOLTAGE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x44:
|
||||||
|
strncpy(text,"LOAD_CURRENT_RIPPLE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x45:
|
||||||
|
strncpy(text,"DC_LINK_ISOLATION_NOT_OK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x46:
|
||||||
|
strncpy(text,"LOAD_ISOLATION_NOT_OK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x47:
|
||||||
|
strncpy(text,"LOAD_IMPEDANCE_OUT_OF_RANGE",textlen);
|
||||||
|
break;
|
||||||
|
case 0x48:
|
||||||
|
strncpy(text,"SHUT_OFF_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x49:
|
||||||
|
strncpy(text,"LOAD_DC_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4a:
|
||||||
|
strncpy(text,"CURRENT_I1A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4b:
|
||||||
|
strncpy(text,"CURRENT_I1B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4c:
|
||||||
|
strncpy(text,"CURRENT_I1A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4d:
|
||||||
|
strncpy(text,"CURRENT_I1B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4e:
|
||||||
|
strncpy(text,"CURRENT_I2A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4f:
|
||||||
|
strncpy(text,"CURRENT_I2B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x50:
|
||||||
|
strncpy(text,"CURRENT_I2A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x51:
|
||||||
|
strncpy(text,"CURRENT_I2B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x52:
|
||||||
|
strncpy(text,"CURRENT_I3P_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x53:
|
||||||
|
strncpy(text,"CURRENT_I3N_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x54:
|
||||||
|
strncpy(text,"CURRENT_IE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x55:
|
||||||
|
strncpy(text,"VOLTAGE_U1A_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x56:
|
||||||
|
strncpy(text,"VOLTAGE_U1B_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x57:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I1A1_I1A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x58:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I1B1_I1B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x59:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I2A1_I2A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5a:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I2B1_I2B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5b:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3P_I3N_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5c:
|
||||||
|
strncpy(text,"CURRENT_I1A_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5d:
|
||||||
|
strncpy(text,"CURRENT_I1B_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5e:
|
||||||
|
strncpy(text,"CURRENT_I3A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5f:
|
||||||
|
strncpy(text,"CURRENT_I3B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x60:
|
||||||
|
strncpy(text,"CURRENT_I3A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x61:
|
||||||
|
strncpy(text,"CURRENT_I3B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x62:
|
||||||
|
strncpy(text,"CURRENT_I4_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x63:
|
||||||
|
strncpy(text,"CURRENT_I5_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x64:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3A1_I3A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x65:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3B1_I3B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x66:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I4_I5_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x67:
|
||||||
|
strncpy(text,"VOLTAGE_U3A_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x68:
|
||||||
|
strncpy(text,"VOLTAGE_U3B_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x69:
|
||||||
|
strncpy(text,"VOLTAGE_U1_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6a:
|
||||||
|
strncpy(text,"VOLTAGE_U3A_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6b:
|
||||||
|
strncpy(text,"VOLTAGE_U3B_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6c:
|
||||||
|
strncpy(text,"SPEED_ERROR_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x70:
|
||||||
|
strncpy(text,"MAIN_RELAY_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x71:
|
||||||
|
strncpy(text,"MAIN_RELAY_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x72:
|
||||||
|
strncpy(text,"POWER_SWITCH_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x73:
|
||||||
|
strncpy(text,"POWER_SWITCH_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x74:
|
||||||
|
strncpy(text,"MONITOR_TRAFO_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x75:
|
||||||
|
strncpy(text,"MONITOR_TRAFO_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x76:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x77:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x78:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x79:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7a:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7b:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7c:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7d:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7e:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7f:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
strncpy(text,"WATER_RECTIFIER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
strncpy(text,"WATER_RECTIFIER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x82:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x83:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x84:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x85:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x86:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x87:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x88:
|
||||||
|
strncpy(text,"WATER_TRANSFORMER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x89:
|
||||||
|
strncpy(text,"WATER_TRANSFORMER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8a:
|
||||||
|
strncpy(text,"DOOR_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8b:
|
||||||
|
strncpy(text,"DOOR_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8c:
|
||||||
|
strncpy(text,"DOOR_C",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8d:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8e:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8f:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x90:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x91:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x92:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x93:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I3P",textlen);
|
||||||
|
break;
|
||||||
|
case 0x94:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I3N",textlen);
|
||||||
|
break;
|
||||||
|
case 0x95:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK_1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x96:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK_2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x97:
|
||||||
|
strncpy(text,"VENTILATOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x98:
|
||||||
|
strncpy(text,"EMERGENCY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x99:
|
||||||
|
strncpy(text,"CAPACITOR_DISCHARGE_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9a:
|
||||||
|
strncpy(text,"CAPACITOR_DISCHARGE_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9b:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I4",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9c:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I5",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb0:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb1:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb2:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb3:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb4:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb5:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb6:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb7:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb8:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_A_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb9:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_B_OFF",textlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@ -843,7 +843,7 @@ static void ECBGetError(void *pData, int *iCode, char *buffer, int bufferlen){
|
|||||||
strncpy(buffer,"failed to start motor",bufferlen);
|
strncpy(buffer,"failed to start motor",bufferlen);
|
||||||
break;
|
break;
|
||||||
case ECBLIMIT:
|
case ECBLIMIT:
|
||||||
strncpy(buffer,"hit limit switch",bufferlen);
|
strncpy(buffer,"hit limit switch or amplifier error",bufferlen);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strncpy(buffer,"unidentified error code",bufferlen);
|
strncpy(buffer,"unidentified error code",bufferlen);
|
||||||
|
5
make_gen
5
make_gen
@ -15,8 +15,9 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
|||||||
bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \
|
bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \
|
||||||
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
||||||
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
||||||
el737hpv2driv.o swmotor2.o tricssupport.o \
|
el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \
|
||||||
fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o \
|
fsm.o logger.o sugar.o pardef.o amordrive.o\
|
||||||
|
ease.o strobj.o oxinst.o amorset.o\
|
||||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o \
|
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o \
|
||||||
dgrambroadcast.o sinq.o tabledrive.o
|
dgrambroadcast.o sinq.o tabledrive.o
|
||||||
|
|
||||||
|
32
makedspcodes
Executable file
32
makedspcodes
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/tclsh
|
||||||
|
#----- little script which converts ukas Tanners error code header file into a
|
||||||
|
#------ subroutine which converts into text
|
||||||
|
|
||||||
|
set f [open MessagesCodes.h r]
|
||||||
|
|
||||||
|
puts stdout "void slsdspCodeToText(int code, char *text, int textlen){"
|
||||||
|
puts stdout " switch(code){"
|
||||||
|
|
||||||
|
proc tokenize {txt} {
|
||||||
|
set l [split $txt]
|
||||||
|
foreach w $l {
|
||||||
|
if {[string length $w] > 1} {
|
||||||
|
lappend result $w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
while {[gets $f line] >= 0} {
|
||||||
|
if {[string first "#define" $line] >= 0} {
|
||||||
|
set l [tokenize $line]
|
||||||
|
puts stdout " case [lindex $l 2]:"
|
||||||
|
puts stdout " strncpy(text,\"[lindex $l 1]\",textlen);"
|
||||||
|
puts stdout " break;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts stdout " }"
|
||||||
|
puts stdout "}"
|
||||||
|
close $f
|
||||||
|
exit 0
|
7
nxamor.c
7
nxamor.c
@ -119,6 +119,13 @@ static int psdSave = 1;
|
|||||||
|
|
||||||
/* chopper */
|
/* chopper */
|
||||||
NXDputalias(hfil,hdict,"cname",CHOPPERNAME);
|
NXDputalias(hfil,hdict,"cname",CHOPPERNAME);
|
||||||
|
SNXSPutDrivable(pServ->pSics, pCon,hfil,hdict, "chopperspeed",
|
||||||
|
"crot");
|
||||||
|
SNXSPutDrivable(pServ->pSics, pCon,hfil,hdict,"chopper1phase",
|
||||||
|
"cphase1");
|
||||||
|
SNXSPutDrivable(pServ->pSics, pCon,hfil,hdict, "chopper2phase",
|
||||||
|
"cphase2");
|
||||||
|
|
||||||
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"crot",
|
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"crot",
|
||||||
"chopperrotation");
|
"chopperrotation");
|
||||||
|
|
||||||
|
4
psi.c
4
psi.c
@ -53,7 +53,7 @@
|
|||||||
#include "tricssupport.h"
|
#include "tricssupport.h"
|
||||||
#include "sinq.h"
|
#include "sinq.h"
|
||||||
#include "tabledrive.h"
|
#include "tabledrive.h"
|
||||||
|
#include "amorset.h"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void SiteInit(void) {
|
void SiteInit(void) {
|
||||||
@ -101,6 +101,7 @@ static void AddPsiCommands(SicsInterp *pInter){
|
|||||||
AddCommand(pInter,"Remob",RemobCreate,NULL,NULL);
|
AddCommand(pInter,"Remob",RemobCreate,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeSinq",SinqFactory,NULL,NULL);
|
AddCommand(pInter,"MakeSinq",SinqFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeTableDrive",TableDriveFactory,NULL,NULL);
|
AddCommand(pInter,"MakeTableDrive",TableDriveFactory,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeAmorSet",AmorSetFactory,NULL,NULL);
|
||||||
/*
|
/*
|
||||||
AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL);
|
AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL);
|
||||||
*/
|
*/
|
||||||
@ -131,6 +132,7 @@ static void RemovePsiCommands(SicsInterp *pSics){
|
|||||||
RemoveCommand(pSics,"SerialInit");
|
RemoveCommand(pSics,"SerialInit");
|
||||||
RemoveCommand(pSics,"MakeSinq");
|
RemoveCommand(pSics,"MakeSinq");
|
||||||
RemoveCommand(pSics,"MakeTableDrive");
|
RemoveCommand(pSics,"MakeTableDrive");
|
||||||
|
RemoveCommand(pSics,"MakeAmorSet");
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
MotorDriver *CreateEL734(SConnection *pCon, int argc, char *argv[]);
|
MotorDriver *CreateEL734(SConnection *pCon, int argc, char *argv[]);
|
||||||
|
527
slsmagnet.c
527
slsmagnet.c
@ -45,7 +45,9 @@
|
|||||||
before doing a timeout. 100 corresponds to one second
|
before doing a timeout. 100 corresponds to one second
|
||||||
*/
|
*/
|
||||||
#define MAXLOOP 100
|
#define MAXLOOP 100
|
||||||
|
#define BADLOWLIM -5301
|
||||||
|
#define BADHIGHLIM -5302
|
||||||
|
#define DEVICERROR -5304
|
||||||
/*
|
/*
|
||||||
packet header codes
|
packet header codes
|
||||||
*/
|
*/
|
||||||
@ -153,7 +155,7 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
static int GetSLSPos(pEVDriver self, float *fPos)
|
static int GetSLSPos(pEVDriver self, float *fPos)
|
||||||
{
|
{
|
||||||
pSLSDriv pMe = NULL;
|
pSLSDriv pMe = NULL;
|
||||||
int iRet, ival;
|
int iRet, ival, err;
|
||||||
double dval;
|
double dval;
|
||||||
char msg[6], reply[6];
|
char msg[6], reply[6];
|
||||||
long lVal;
|
long lVal;
|
||||||
@ -178,6 +180,22 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
*fPos = (float)dval;
|
*fPos = (float)dval;
|
||||||
pMe->iError = 0;
|
pMe->iError = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try read error codes
|
||||||
|
*/
|
||||||
|
msg[1] = 0x29;
|
||||||
|
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||||
|
if(iRet < 0)
|
||||||
|
{
|
||||||
|
pMe->iError = iRet;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
err = (int)reply[5];
|
||||||
|
if(err != 0){
|
||||||
|
pMe->iError = -7000 - err;
|
||||||
|
return pMe->iError;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -186,11 +204,51 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
pSLSDriv pMe = NULL;
|
pSLSDriv pMe = NULL;
|
||||||
int iRet, ival, i;
|
int iRet, ival, i;
|
||||||
char msg[6], reply[6];
|
char msg[6], reply[6];
|
||||||
|
double min, max;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
pMe = (pSLSDriv )self->pPrivate;
|
pMe = (pSLSDriv )self->pPrivate;
|
||||||
assert(pMe);
|
assert(pMe);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* test high limit
|
||||||
|
*/
|
||||||
|
msg[0] = DSPREAD;
|
||||||
|
msg[1] = 0x76;
|
||||||
|
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||||
|
if(iRet <= 0)
|
||||||
|
{
|
||||||
|
pMe->iError = iRet;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
memcpy(&ival,reply+2,4);
|
||||||
|
max = DSPfloat2double(ival);
|
||||||
|
if(fVal > max){
|
||||||
|
pMe->iError = BADHIGHLIM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* test low limit
|
||||||
|
*/
|
||||||
|
msg[0] = DSPREAD;
|
||||||
|
msg[1] = 0x77;
|
||||||
|
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||||
|
if(iRet <= 0)
|
||||||
|
{
|
||||||
|
pMe->iError = iRet;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
memcpy(&ival,reply+2,4);
|
||||||
|
min = DSPfloat2double(ival);
|
||||||
|
if(fVal < min){
|
||||||
|
pMe->iError = BADLOWLIM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* actual set the new value
|
||||||
|
*/
|
||||||
msg[0] = DSPWRITE;
|
msg[0] = DSPWRITE;
|
||||||
msg[1] = 0x90;
|
msg[1] = 0x90;
|
||||||
ival = double2DSPfloat((double)fVal);
|
ival = double2DSPfloat((double)fVal);
|
||||||
@ -199,18 +257,438 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
if(iRet <= 0)
|
if(iRet <= 0)
|
||||||
{
|
{
|
||||||
pMe->iError = iRet;
|
pMe->iError = iRet;
|
||||||
return iRet;
|
return 0;
|
||||||
}
|
}
|
||||||
for(i = 1; i < 6; i++)
|
for(i = 1; i < 6; i++)
|
||||||
{
|
{
|
||||||
if(msg[i] != reply[i])
|
if(msg[i] != reply[i])
|
||||||
{
|
{
|
||||||
pMe->iError = BADECHO;
|
pMe->iError = BADECHO;
|
||||||
return BADECHO;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static void slsdspCodeToText(int code, char *text, int textlen){
|
||||||
|
switch(code){
|
||||||
|
case 0x0:
|
||||||
|
strncpy(text,"NO",textlen);
|
||||||
|
break;
|
||||||
|
case 0x1:
|
||||||
|
strncpy(text,"DEVICE_STATE_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
strncpy(text,"DEVICE_SUPERVISOR_DISABLED",textlen);
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
strncpy(text,"COMMAND_ABORT",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
strncpy(text,"DATA_NOT_STORED",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5:
|
||||||
|
strncpy(text,"ERROR_ERASING_FLASH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6:
|
||||||
|
strncpy(text,"COMMUNICATION_BREAK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7:
|
||||||
|
strncpy(text,"INTERNAL_COMMUNICATION_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8:
|
||||||
|
strncpy(text,"MASTER_CARD_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
strncpy(text,"INTERNAL_BUFFER_FULL",textlen);
|
||||||
|
break;
|
||||||
|
case 0xa:
|
||||||
|
strncpy(text,"WRONG_SECTOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb:
|
||||||
|
strncpy(text,"DATA_NOT_COPIED",textlen);
|
||||||
|
break;
|
||||||
|
case 0xc:
|
||||||
|
strncpy(text,"WRONG_DOWNLOAD_PARAMETERS",textlen);
|
||||||
|
break;
|
||||||
|
case 0xd:
|
||||||
|
strncpy(text,"DEVICE_PARAMETRIZATION_ERROR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE",textlen);
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
strncpy(text,"TIMEOUT_DATA_DOWNLOAD",textlen);
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
strncpy(text,"INTERLOCK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
strncpy(text,"MASTER_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x22:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x23:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x24:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x25:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x26:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER",textlen);
|
||||||
|
break;
|
||||||
|
case 0x27:
|
||||||
|
strncpy(text,"TEMPERATURE_POLARITY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x28:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x29:
|
||||||
|
strncpy(text,"MAIN_RELAY",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2a:
|
||||||
|
strncpy(text,"AD_CONVERTER_CARD",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2b:
|
||||||
|
strncpy(text,"POLARITY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2c:
|
||||||
|
strncpy(text,"AUXILIARY_RELAY",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2d:
|
||||||
|
strncpy(text,"MASTER_SWITCH_T1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2e:
|
||||||
|
strncpy(text,"MASTER_SWITCH_T2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x2f:
|
||||||
|
strncpy(text,"TEMPERATURE_MAGNET",textlen);
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
strncpy(text,"WATER_MAGNET",textlen);
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
strncpy(text,"WATER_RACK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
strncpy(text,"LOAD_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x41:
|
||||||
|
strncpy(text,"DC_LINK_VOLTAGE_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x42:
|
||||||
|
strncpy(text,"DC_LINK_VOLTAGE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x43:
|
||||||
|
strncpy(text,"LOAD_VOLTAGE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x44:
|
||||||
|
strncpy(text,"LOAD_CURRENT_RIPPLE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x45:
|
||||||
|
strncpy(text,"DC_LINK_ISOLATION_NOT_OK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x46:
|
||||||
|
strncpy(text,"LOAD_ISOLATION_NOT_OK",textlen);
|
||||||
|
break;
|
||||||
|
case 0x47:
|
||||||
|
strncpy(text,"LOAD_IMPEDANCE_OUT_OF_RANGE",textlen);
|
||||||
|
break;
|
||||||
|
case 0x48:
|
||||||
|
strncpy(text,"SHUT_OFF_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x49:
|
||||||
|
strncpy(text,"LOAD_DC_CURRENT_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4a:
|
||||||
|
strncpy(text,"CURRENT_I1A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4b:
|
||||||
|
strncpy(text,"CURRENT_I1B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4c:
|
||||||
|
strncpy(text,"CURRENT_I1A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4d:
|
||||||
|
strncpy(text,"CURRENT_I1B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4e:
|
||||||
|
strncpy(text,"CURRENT_I2A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x4f:
|
||||||
|
strncpy(text,"CURRENT_I2B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x50:
|
||||||
|
strncpy(text,"CURRENT_I2A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x51:
|
||||||
|
strncpy(text,"CURRENT_I2B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x52:
|
||||||
|
strncpy(text,"CURRENT_I3P_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x53:
|
||||||
|
strncpy(text,"CURRENT_I3N_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x54:
|
||||||
|
strncpy(text,"CURRENT_IE_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x55:
|
||||||
|
strncpy(text,"VOLTAGE_U1A_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x56:
|
||||||
|
strncpy(text,"VOLTAGE_U1B_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x57:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I1A1_I1A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x58:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I1B1_I1B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x59:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I2A1_I2A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5a:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I2B1_I2B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5b:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3P_I3N_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5c:
|
||||||
|
strncpy(text,"CURRENT_I1A_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5d:
|
||||||
|
strncpy(text,"CURRENT_I1B_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5e:
|
||||||
|
strncpy(text,"CURRENT_I3A1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x5f:
|
||||||
|
strncpy(text,"CURRENT_I3B1_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x60:
|
||||||
|
strncpy(text,"CURRENT_I3A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x61:
|
||||||
|
strncpy(text,"CURRENT_I3B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x62:
|
||||||
|
strncpy(text,"CURRENT_I4_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x63:
|
||||||
|
strncpy(text,"CURRENT_I5_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x64:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3A1_I3A2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x65:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I3B1_I3B2_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x66:
|
||||||
|
strncpy(text,"DIFF_CURRENT_I4_I5_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x67:
|
||||||
|
strncpy(text,"VOLTAGE_U3A_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x68:
|
||||||
|
strncpy(text,"VOLTAGE_U3B_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x69:
|
||||||
|
strncpy(text,"VOLTAGE_U1_TOO_LOW",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6a:
|
||||||
|
strncpy(text,"VOLTAGE_U3A_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6b:
|
||||||
|
strncpy(text,"VOLTAGE_U3B_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x6c:
|
||||||
|
strncpy(text,"SPEED_ERROR_TOO_HIGH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x70:
|
||||||
|
strncpy(text,"MAIN_RELAY_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x71:
|
||||||
|
strncpy(text,"MAIN_RELAY_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x72:
|
||||||
|
strncpy(text,"POWER_SWITCH_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x73:
|
||||||
|
strncpy(text,"POWER_SWITCH_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x74:
|
||||||
|
strncpy(text,"MONITOR_TRAFO_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x75:
|
||||||
|
strncpy(text,"MONITOR_TRAFO_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x76:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x77:
|
||||||
|
strncpy(text,"TEMPERATURE_RECTIFIER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x78:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x79:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7a:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7b:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7c:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7d:
|
||||||
|
strncpy(text,"TEMPERATURE_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7e:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x7f:
|
||||||
|
strncpy(text,"TEMPERATURE_TRANSFORMER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
strncpy(text,"WATER_RECTIFIER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
strncpy(text,"WATER_RECTIFIER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x82:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x83:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x84:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x85:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x86:
|
||||||
|
strncpy(text,"WATER_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x87:
|
||||||
|
strncpy(text,"WATER_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x88:
|
||||||
|
strncpy(text,"WATER_TRANSFORMER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x89:
|
||||||
|
strncpy(text,"WATER_TRANSFORMER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8a:
|
||||||
|
strncpy(text,"DOOR_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8b:
|
||||||
|
strncpy(text,"DOOR_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8c:
|
||||||
|
strncpy(text,"DOOR_C",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8d:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8e:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0x8f:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x90:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x91:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_A2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x92:
|
||||||
|
strncpy(text,"POWER_SEMICONDUCTOR_CONVERTER_B2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x93:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I3P",textlen);
|
||||||
|
break;
|
||||||
|
case 0x94:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I3N",textlen);
|
||||||
|
break;
|
||||||
|
case 0x95:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK_1",textlen);
|
||||||
|
break;
|
||||||
|
case 0x96:
|
||||||
|
strncpy(text,"MAGNET_INTERLOCK_2",textlen);
|
||||||
|
break;
|
||||||
|
case 0x97:
|
||||||
|
strncpy(text,"VENTILATOR",textlen);
|
||||||
|
break;
|
||||||
|
case 0x98:
|
||||||
|
strncpy(text,"EMERGENCY_SWITCH",textlen);
|
||||||
|
break;
|
||||||
|
case 0x99:
|
||||||
|
strncpy(text,"CAPACITOR_DISCHARGE_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9a:
|
||||||
|
strncpy(text,"CAPACITOR_DISCHARGE_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9b:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I4",textlen);
|
||||||
|
break;
|
||||||
|
case 0x9c:
|
||||||
|
strncpy(text,"CURRENT_TRANSDUCER_I5",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb0:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_A",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb1:
|
||||||
|
strncpy(text,"TIMEOUT_DC_LINK_VOLTAGE_PART_B",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb2:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb3:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb4:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_A_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb5:
|
||||||
|
strncpy(text,"TIMEOUT_AUXILIARY_RELAY_B_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb6:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_A_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb7:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_B_ON",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb8:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_A_OFF",textlen);
|
||||||
|
break;
|
||||||
|
case 0xb9:
|
||||||
|
strncpy(text,"TIMEOUT_MAIN_RELAY_B_OFF",textlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int SLSError(pEVDriver self, int *iCode, char *error, int iErrLen)
|
static int SLSError(pEVDriver self, int *iCode, char *error, int iErrLen)
|
||||||
{
|
{
|
||||||
@ -224,6 +702,12 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
assert(pMe);
|
assert(pMe);
|
||||||
|
|
||||||
*iCode = pMe->iError;
|
*iCode = pMe->iError;
|
||||||
|
if(*iCode < -7000){
|
||||||
|
slsdspCodeToText(-(pMe->iError + 7000),error,iErrLen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch(*iCode)
|
switch(*iCode)
|
||||||
{
|
{
|
||||||
case BADECHO:
|
case BADECHO:
|
||||||
@ -235,6 +719,12 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
case TIMEOUT:
|
case TIMEOUT:
|
||||||
strncpy(error,"Timeout waiting for response", iErrLen);
|
strncpy(error,"Timeout waiting for response", iErrLen);
|
||||||
break;
|
break;
|
||||||
|
case BADHIGHLIM:
|
||||||
|
strncpy(error,"Device internal upper limit violated",iErrLen);
|
||||||
|
break;
|
||||||
|
case BADLOWLIM:
|
||||||
|
strncpy(error,"Device internal lower limit violated",iErrLen);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
getRS232Error(*iCode,error,iErrLen);
|
getRS232Error(*iCode,error,iErrLen);
|
||||||
break;
|
break;
|
||||||
@ -276,6 +766,9 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
msg[1] = 0x31;
|
msg[1] = 0x31;
|
||||||
*/
|
*/
|
||||||
msg[1] = 0x3c;
|
msg[1] = 0x3c;
|
||||||
|
/*
|
||||||
|
* ival = 0: ausschalten
|
||||||
|
*/
|
||||||
ival = 1;
|
ival = 1;
|
||||||
memcpy(msg+2, &ival,4);
|
memcpy(msg+2, &ival,4);
|
||||||
iRet = communicateSLS(pMe->pSock,msg,reply);
|
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||||
@ -299,12 +792,28 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
static int SLSClose(pEVDriver self)
|
static int SLSClose(pEVDriver self)
|
||||||
{
|
{
|
||||||
pSLSDriv pMe = NULL;
|
pSLSDriv pMe = NULL;
|
||||||
int iRet;
|
int iRet, ival;
|
||||||
|
char msg[6], reply[6];
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
pMe = (pSLSDriv )self->pPrivate;
|
pMe = (pSLSDriv )self->pPrivate;
|
||||||
assert(pMe);
|
assert(pMe);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* switch the thing off
|
||||||
|
*/
|
||||||
|
msg[0] = DSPWRITE;
|
||||||
|
msg[1] = 0x3c;
|
||||||
|
/*
|
||||||
|
* ival = 0: ausschalten
|
||||||
|
*/
|
||||||
|
ival = 0;
|
||||||
|
memcpy(msg+2, &ival,4);
|
||||||
|
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||||
|
/*
|
||||||
|
* we are on our way out: ignore errors
|
||||||
|
*/
|
||||||
|
|
||||||
NETClosePort(pMe->pSock);
|
NETClosePort(pMe->pSock);
|
||||||
pMe->pSock = NULL;
|
pMe->pSock = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
@ -319,8 +828,16 @@ static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
|||||||
pMe = (pSLSDriv )self->pPrivate;
|
pMe = (pSLSDriv )self->pPrivate;
|
||||||
assert(pMe);
|
assert(pMe);
|
||||||
|
|
||||||
|
if(iError < -7000){
|
||||||
|
return DEVFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
switch(iError)
|
switch(iError)
|
||||||
{
|
{
|
||||||
|
case BADHIGHLIM:
|
||||||
|
case BADLOWLIM:
|
||||||
|
return DEVFAULT;
|
||||||
|
break;
|
||||||
case BADECHO:
|
case BADECHO:
|
||||||
case TIMEOUT:
|
case TIMEOUT:
|
||||||
return DEVREDO;
|
return DEVREDO;
|
||||||
|
175
tabledrive.tex
Normal file
175
tabledrive.tex
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
\subsection{Tabled Driving}
|
||||||
|
This object implements driving several motors along a predefined path. The definition
|
||||||
|
of the path happens through a table. Positions between tabulated positions are
|
||||||
|
interpolated by linear interpolation. Additionally, each motor may be driven a
|
||||||
|
bit from the tabulated positions for fine adjustments. Of course the limits are
|
||||||
|
variable from position to position. Thus this object also sets the software limits of the
|
||||||
|
motors accordingly. This object assumes that motors can be driven between positions
|
||||||
|
without watching for collisions. The original use of this module is to coordinate the
|
||||||
|
movements of the MARS triffids or girafs.
|
||||||
|
|
||||||
|
The table lives in a separate file. The format of the file is very simple:
|
||||||
|
Each block starts with a line containing:
|
||||||
|
\begin{verbatim}
|
||||||
|
# motorname
|
||||||
|
\end{verbatim}
|
||||||
|
This is a hash and the name of the motor.
|
||||||
|
These lines are followed by n lines of:
|
||||||
|
\begin{verbatim}
|
||||||
|
lower position upper
|
||||||
|
\end{verbatim}
|
||||||
|
These are three numbers giving the lower and upper limit for this position in the table
|
||||||
|
and, as the middle value, the target position for this entry.
|
||||||
|
|
||||||
|
|
||||||
|
In order to achieve all this, we need a data structure per table entry:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap1}
|
||||||
|
$\langle$tdentry {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@typedef struct{@\\
|
||||||
|
\mbox{}\verb@ double lower, position, upper;@\\
|
||||||
|
\mbox{}\verb@ int tablePos;@\\
|
||||||
|
\mbox{}\verb@ }tdEntry, *ptdEntry;@\\
|
||||||
|
\mbox{}\verb@ @$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
The fields are the lower and upper limits, the position for this table entry and the
|
||||||
|
number of the entry.
|
||||||
|
|
||||||
|
|
||||||
|
For each motor we need another data structure:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap2}
|
||||||
|
$\langle$tdmotor {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@typedef struct {@\\
|
||||||
|
\mbox{}\verb@ char motorName[132];@\\
|
||||||
|
\mbox{}\verb@ int table;@\\
|
||||||
|
\mbox{}\verb@ pMotor pMot;@\\
|
||||||
|
\mbox{}\verb@ }tdMotor, *ptdMotor; @\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
The fields:
|
||||||
|
\begin{description}
|
||||||
|
\item[motorName] The name of the motor
|
||||||
|
\item[table] A list of tabulated positions in the form of tdEntry
|
||||||
|
\item[pMot] A pointer to the motor data structure.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
|
The tabledrive object itself needs a data structure too:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap3}
|
||||||
|
$\langle$tdobj {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@typedef struct{@\\
|
||||||
|
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||||
|
\mbox{}\verb@ pIDrivable pDriv;@\\
|
||||||
|
\mbox{}\verb@ int motorTable;@\\
|
||||||
|
\mbox{}\verb@ int tableLength;@\\
|
||||||
|
\mbox{}\verb@ float targetPosition;@\\
|
||||||
|
\mbox{}\verb@ float currentPosition;@\\
|
||||||
|
\mbox{}\verb@ int state;@\\
|
||||||
|
\mbox{}\verb@ char orientMotor[80];@\\
|
||||||
|
\mbox{}\verb@ int debug;@\\
|
||||||
|
\mbox{}\verb@ }TableDrive, *pTableDrive;@\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
The fields:
|
||||||
|
\begin{description}
|
||||||
|
\item[pDes] The standard SICS object descriptor
|
||||||
|
\item[pDriv] The drivable interface which encapsulates most of the magic of this module.
|
||||||
|
\item[motorTable] A list of tdMotor entries.
|
||||||
|
\item[tableLength] The length of the path of positions.
|
||||||
|
\item[targetPosition] The target position we have to drive to.
|
||||||
|
\item[currentPosition] where we are now.
|
||||||
|
\item[state] A state variable used during driving the path.
|
||||||
|
\item[orientMotor] is the name of the orienting motor, i.e. the one used to determine
|
||||||
|
the position.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
|
In terms of an interface, this object implements the drivable interface which has to
|
||||||
|
deal with most of the work. There is just an interpreter interface which allows to
|
||||||
|
configure and query the object.
|
||||||
|
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap4}
|
||||||
|
$\langle$tdint {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@int TableDriveFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@int TableDriveAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ @$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-1ex}
|
||||||
|
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||||
|
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||||
|
\item Macro referenced in scrap ?.
|
||||||
|
\end{list}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap5}
|
||||||
|
\verb@"tabledrive.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ /*---------------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ SICS object for driving a couple of motors along a tabulated given path.@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Mark Koennecke, July 2005@\\
|
||||||
|
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@#ifndef SICSTABLEDRIVE@\\
|
||||||
|
\mbox{}\verb@#define SICSTABLEDRIVE@\\
|
||||||
|
\mbox{}\verb@#include <sics.h>@\\
|
||||||
|
\mbox{}\verb@#include "../motor.h"@\\
|
||||||
|
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@@$\langle$tdentry {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@@$\langle$tdmotor {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@@$\langle$tdobj {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@@$\langle$tdint {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@#endif@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ @$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-2ex}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
8
tas.h
8
tas.h
@ -146,8 +146,14 @@
|
|||||||
#define HCONV3 127
|
#define HCONV3 127
|
||||||
#define HCONV4 128
|
#define HCONV4 128
|
||||||
#define POLFIL 129
|
#define POLFIL 129
|
||||||
|
#define PIX 130
|
||||||
|
#define PIY 131
|
||||||
|
#define PIZ 132
|
||||||
|
#define PFX 133
|
||||||
|
#define PFY 134
|
||||||
|
#define PFZ 135
|
||||||
|
|
||||||
#define MAXPAR 130
|
#define MAXPAR 136
|
||||||
#define MAXADD 20
|
#define MAXADD 20
|
||||||
#define MAXEVAR 12
|
#define MAXEVAR 12
|
||||||
|
|
||||||
|
@ -201,6 +201,12 @@ char *tasVariableOrder[] = {
|
|||||||
"hconv3",
|
"hconv3",
|
||||||
"hconv4",
|
"hconv4",
|
||||||
"polfile",
|
"polfile",
|
||||||
|
"pix",
|
||||||
|
"piy",
|
||||||
|
"piz",
|
||||||
|
"pfx",
|
||||||
|
"pfy",
|
||||||
|
"pfz",
|
||||||
NULL};
|
NULL};
|
||||||
/*-------------------------------------------------------------------
|
/*-------------------------------------------------------------------
|
||||||
Normally SICS does not store motor hardware limits into status files as
|
Normally SICS does not store motor hardware limits into status files as
|
||||||
|
@ -755,6 +755,7 @@ int TASUpdate(pTASdata self, SConnection *pCon)
|
|||||||
self->tasPar[HX]->fVal = hx;
|
self->tasPar[HX]->fVal = hx;
|
||||||
self->tasPar[HY]->fVal = hy;
|
self->tasPar[HY]->fVal = hy;
|
||||||
self->tasPar[HZ]->fVal = hz;
|
self->tasPar[HZ]->fVal = hz;
|
||||||
|
SCparChange(pCon);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
now check the analyzer or monochromator angles
|
now check the analyzer or monochromator angles
|
||||||
|
Reference in New Issue
Block a user