- Added separate drivable motors for four circle H, K, L

- Added a listen mode to commandlog in order to support the batchEditor
- Some small fixes to exe* for BatchEditor
This commit is contained in:
koennecke
2005-02-23 10:11:18 +00:00
parent ef1de4589c
commit 28ddbc420d
39 changed files with 1274 additions and 130 deletions

247
hklmot.c Normal file
View File

@ -0,0 +1,247 @@
/*------------------------------------------------------------------------------------------------------
Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.
Requires a HKL object for calculations.
copyright: see file COPYRIGHT
Mark Koennecke, February 2005
--------------------------------------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "sics.h"
#include "fortify.h"
#include "motor.h"
#include "matrix/matrix.h"
#include "hkl.h"
#include "hkl.i"
#include "hklmot.h"
/*=================== Object Descriptor Interface ===================================================*/
static void *HKLGetInterface(void *pData, int iID){
pHKLMot self = NULL;
self = (pHKLMot)pData;
if(self == NULL){
return NULL;
}
if(iID == DRIVEID){
return self->pDriv;
}
return NULL;
}
/*=================== Drivable Interface ============================================================*/
static int HKLHalt(void *pData){
pHKLMot self = NULL;
self = (pHKLMot)pData;
assert(self != NULL);
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
if(self->pHkl->iNOR == 1){
self->pHkl->pNu->pDrivInt->Halt(self->pHkl->pNu);
} else {
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
}
return 1;
}
/*-----------------------------------------------------------------------------------------------------*/
static int HKLCheckLimits(void *self, float fVal, char *error, int errLen){
/*
There is no meaningful implementation here. This gets called when starting the motor.
At that stage not all other values may be known. If the calculation failes, this will die
at status check time.
*/
return 1;
}
/*----------------------------------------------------------------------------------------------------*/
static long HKLSetValue(void *pData, SConnection *pCon, float fVal){
pHKLMot self = NULL;
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self = (pHKLMot)pData;
assert(self != NULL);
self->pHkl->targetHKL[self->index] = fVal;
self->pHkl->targetDirty = 1;
return OKOK;
}
/*---------------------------------------------------------------------------------------------------*/
static int checkMotors(pHKLMot self, SConnection *pCon){
int status;
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
if(self->pHkl->iNOR == 1){
status = self->pHkl->pNu->pDrivInt->CheckStatus(self->pHkl->pNu, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
} else {
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
}
return HWIdle;
}
/*-----------------------------------------------------------------------------------------------------*/
static int HKLCheckStatus(void *pData, SConnection *pCon){
pHKLMot self = NULL;
int status;
self = (pHKLMot)pData;
assert(self != NULL);
if(self->pHkl->targetDirty == 1){
status = RunHKL(self->pHkl,self->pHkl->targetHKL,.0,0,pCon);
if(status != 1){
return HWFault;
}
self->pHkl->targetDirty = 0;
return HWBusy;
} else {
return checkMotors(self,pCon);
}
}
/*-----------------------------------------------------------------------------------------------------*/
static float HKLGetValue(void *pData, SConnection *pCon){
pHKLMot self = NULL;
float fVal[3];
int status;
self = (pHKLMot)pData;
assert(self != NULL);
status = GetHKLFromAngles(self->pHkl,pCon,fVal);
if(status != 1){
SCWrite(pCon,"ERROR: failed to read positions or convert to HKL",eError);
return -9999.99;
}
return fVal[self->index];
}
/*=============================== Live and Death ====================================*/
static pHKLMot MakeHKLMot(pHKL pHkl, int index){
pHKLMot self = NULL;
assert(pHkl != NULL);
assert(index >= 0 && index < 3);
self = (pHKLMot)malloc(sizeof(HKLMot));
if(self == NULL){
return NULL;
}
memset(self,0,sizeof(HKLMot));
self->pDes = CreateDescriptor("HKLMot");
self->pDriv = CreateDrivableInterface();
if(self->pDes == NULL || self->pDriv == NULL){
free(self);
return NULL;
}
self->pDes->GetInterface = HKLGetInterface;
self->pDriv->Halt = HKLHalt;
self->pDriv->CheckLimits = HKLCheckLimits;
self->pDriv->SetValue = HKLSetValue;
self->pDriv->CheckStatus = HKLCheckStatus;
self->pDriv->GetValue = HKLGetValue;
self->pHkl = pHkl;
self->index = index;
return self;
}
/*----------------------------------------------------------------------------------*/
static void KillHklMot(void *pData){
pHKLMot self = NULL;
self = (pHKLMot)pData;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->pDriv){
free(self->pDriv);
}
free(self);
}
/*=============================== Interpreter Interface ============================*/
int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pHKLMot self = NULL;
float value;
char pBuffer[132];
self = (pHKLMot)pData;
assert(self != NULL);
value = self->pDriv->GetValue(self,pCon);
if(value < -9000.){
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
snprintf(pBuffer,131,"%s = %f", argv[0], value);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
/*------------------------------------------------------------------------------------------*/
int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pHKL pHkl;
pHKLMot pMot = NULL;
char pBuffer[131];
if(argc < 2){
SCWrite(pCon,"ERROR: Insifficient number of arguments to HKLMotInstall",eError);
return 0;
}
strtolower(argv[1]);
pHkl = (pHKL)FindCommandData(pSics,argv[1],"4-Circle-Calculus");
if(pHkl == NULL){
snprintf(pBuffer,131,"ERROR: %s is not present or no HKL object",argv[1]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
pMot = MakeHKLMot(pHkl, 0);
if(pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating H Motor",eError);
return 0;
}
if(!AddCommand(pSics,"H",HKLMotAction,KillHklMot,pMot)){
SCWrite(pCon,"ERROR: duplicate command H not created",eError);
return 0;
}
pMot = MakeHKLMot(pHkl, 1);
if(pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating K Motor",eError);
return 0;
}
if(!AddCommand(pSics,"K",HKLMotAction,KillHklMot,pMot)){
SCWrite(pCon,"ERROR: duplicate command K not created",eError);
return 0;
}
pMot = MakeHKLMot(pHkl, 2);
if(pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating L Motor",eError);
return 0;
}
if(!AddCommand(pSics,"L",HKLMotAction,KillHklMot,pMot)){
SCWrite(pCon,"ERROR: duplicate command L not created",eError);
return 0;
}
return 1;
}