SICS-294 anstohttp.c

Histmem now only calls TaskYield after SICS has finished initalising, this stops the statusfile task from being called early and overwriting the status file. Created ANSTO_MakeHistMemory command to install ANSTO_HistAction
Added veto functions.  Mapped the HistDriver interface Pause() and Continue() commands to AnstoHttpVeto and AnstoHttpNoVeto. Implemented an ANSTO_Histaction to call AnstoHttpPause when sent a "pause" subcommand.

hmcontrol_ansto.c
Call AnstoHttpPause() directly when Pause_HM_After_Count is set to preserver current behaviour.

counterdriv.c
Now sends the correct "SICS RESUME" command to resume a paused count.

ansto_sctdriveadapter.c NEW
This lets you create driveable objects from script-context controllers which have one node for setting a parameter and another node for reading the parameter (eg temperature controllers, choppers, velocity selectors)

sctemonadapter.c NEW
This generates an environment monitor interface for script-context controllers so that the emon object in SICS will be able to pause counters if the controller goes out of tolerance.

sct_usbtmcprot.c, usbtmc.h NEW
First attempt at a protocol handler for USB Test and Measurement Class devices

sct_julabo_lh45.tcl NEW
Implements script-context controller for the Julabo LH45 temperature controller.

Makefile
Added ansto_sctdriveadapter and sctemonadapter

hardsup/makefile
Added velocity selector and usbtmc protocol handlers

hardsup/sct_velselprot.c
Simplified, don't worry about trying to implement a login handler for now, just implement a "Reading" handler.

site_ansto.c
Add the velocity selector and USBTMC protocol handlers.
Added the ANSTO_MakeHM command

instrument/config/hipadaba/common_instrument_dictionary.tcl
Added support for auxiliary data, ie extra meta-data entries in the "data" group of the nexus file.
Add new NXvelocity_selector object under /instrument.

instrument/config/hipadaba/hipadaba_configuration_common.tcl
Add the new "sct_object" script-context controller objects to the hdb tree.

instrument/config/hipadaba/instdict_specification.tcl
Define the new sct_object controllers.

instrument/config/hmm/hmm_configuration_common_1.tcl
Use the new ANSTO_MakeHM command to create histmem drivers which support veto.
Define allowed attributes and elements for the BAT_TABLE and FAT_TABLE
Stop between counts instead of pausing because setting pause now sends a veto.

instrument/config/motors/sct_jogmotor_common.tcl
You now need to specify klass when creating a jogmotor.

instrument/config/motors/sct_positmotor_common.tcl
You can now specify an optional function which calculates the instrument parameter (eg attenuation) from a posit table entry when defining a posit motor.

instrument/config/nexus/nxscripts_common_1.tcl
Report file status info in the /experiment section of the hdb tree.  Add auxiliary data to data file.
Handle saving data from script-context controller objects.

instrument/util/script_context_util.tcl
Added procedure to set required properties  for saving script-context object data.

instrument/util/utility.tcl
Added set_sct_object_attributes proc to automatically set required attributes on SCT_OBJECTs
Fixed hlistplainprop to deal with empty property fields on hdb nodes.

instrument/server_config.tcl
Call the new nexus initialisation command and set attributes on sct objects.

hrpd/config/motors/motor_configuration.tcl
New absenc home readings for mchi and mphi. New absenc home and range for mf1

hipd/config/commands/commands.tcl
Exported and published the new ajscmds so that they can be used in batch files.

hipd/config/motors/motor_configuration.tcl
New mchi absenc home

rsd/config/hmm/hmm_configuration.tcl
Provide support for saving corrected hmm data

rsd/config/motors/motor_configuration.tcl
Use simple names for motors.

SICS-329

sans/config/INSTCFCOMMON.TXT
Added julabo and lakeshore configuration files to list.

sans/config/optics/guide_configuration.tcl
Added entrance aperture positions to the configuration table and the cn_maps which map the index to the component ID.

sans/commands/commands.tcl
The "guide" command now set EApPosYmm after driving the guides in place.
The indexed position to component maps (cn_map) have been moved to the guide_configuration.tcl file.

sans/motors/motor_configuration.tcl
Set samy home to 56.1mm

sans/config/velsel/sct_velsel.tc NEW
Implements script-context controller object for the NVS40 velocity selector. TODO tilt-angle control, driveable interface.

sans/config/hmm/hmm_configuration.tcl
Set 5.08mm spacing on detector width. Use pixel-offset for vertical and horizontal detector axes.

sans/config/motors/motor_configuration.tcl
Swap directions of beamstops 4 and 5 (the two smallest)
New config parameters for samx, samthet, apx, det, detoff, bsz,

sans/config/motors/positmotor_configuration.tcl
Added descriptive headers to positmotor configuration tables and new synstax for the make positmotor command.

sans/config/nexus/nxscripts.tcl
Implemented initialisation command.

sans/config/parameters/parameters.tcl
Added SampleThickness and TransmissionFlag.  Calculate SamplePosYmm from samy and SamyOffsetmm.
Added beamstops to hdb tree.

reflectometer/config/nexus/nxscripts.tcl
Implement the initialisation procedure.

r2767 | ffr | 2009-03-31 10:16:54 +1100 (Tue, 31 Mar 2009) | 123 lines
This commit is contained in:
Ferdi Franceschini
2009-03-31 10:16:54 +11:00
committed by Douglas Clowes
parent eec824f98a
commit d2f57e4615
39 changed files with 2026 additions and 557 deletions

View File

@@ -77,6 +77,8 @@ GHTTP_LIBS = \
OBJ= site_ansto.o anstoutil.o\
ansto_sctdriveadapter.o\
sctemonadapter.o\
motor_asim.o motor_dmc2280.o\
lh45.o lh45driv.o \
lakeshore340.o lakeshore340driv.o \

View File

@@ -0,0 +1,320 @@
/**
* This is an adapter to a node under the control of the new
* scriptcontext generic device model. This is a wrapper around
* such a node which implements the drivable interface.
*
* Some cooperation from the node is required: It has to provide
* certain properties the value of which define scripts which
* have to be called at various stages. These are:
*
* checklimits, for limits checking
* checkstatus, for evaluating progress
* halt , for halting things
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, June 2008
* --------------------------------------------------------------*/
#include <sics.h>
#include <sicshipadaba.h>
#include <devser.h>
#include <tcl.h>
#include <macro.h>
#include <sicsobj.h>
#include "scriptcontext.h"
/*---------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pIDrivable pDriv;
pHdb write_node;
pHdb read_node;
SctController *c;
}SctDrive, *pSctDrive;
/*---------------------------------------------------------------*/
static void *SCTDRIVGetInterface(void *data, int iD){
pSctDrive self = NULL;
self = (pSctDrive)data;
if(self != NULL && iD == DRIVEID){
if (self->write_node == NULL) return 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 SCTDRIVHalt(void *data) {
pSctDrive self = NULL;
char dummy[16];
self = (pSctDrive)data;
if (GetHdbProperty(self->write_node,"halt", dummy, sizeof dummy)) {
SctQueueNode(self->c, self->write_node, HaltPRIO, "halt", NULL);
} else if (GetHdbProperty(self->write_node, "status", dummy, sizeof dummy)) {
SetHdbProperty(self->write_node, "status", "idle");
}
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 SCTDRIVCheckLimits(void *data, float val,
char *error, int errlen){
pSctDrive self = NULL;
char script[1024];
int status;
Tcl_Interp *pTcl = NULL;
char *result;
self = (pSctDrive)data;
snprintf(script,1024,"%f", val);
SetHdbProperty(self->write_node,"target", script);
if(GetHdbProperty(self->write_node,"checklimits",script,1024)){
status = SctCallInContext(pServ->dummyCon, script,
self->write_node, self->c, &result);
if(SctVerbose(self->c)){
SCPrintf(pServ->dummyCon, eWarning, "script %s called with result %s\n ",
script, result);
}
if(status == 0){
strncpy(error,result,errlen);
return 0;
}
}
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 SCTDRIVSetValue(void *data, SConnection *pCon, float val){
pSctDrive self = NULL;
int status;
hdbValue v;
self = (pSctDrive)data;
v.dataType = HIPFLOAT;
v.v.doubleValue = (double)val;
SetHdbProperty(self->write_node,"writestatus", "start");
status = SetHipadabaPar(self->write_node, v, pCon);
if(status == 1){
return OKOK;
} else {
return HWFault;
}
}
/*----------------------------------------------------------------
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 SCTDRIVCheckStatus(void *data, SConnection *pCon){
pSctDrive self = NULL;
char script[1024];
int status;
Tcl_Interp *pTcl = NULL;
char *result;
SConnection *con;
self = (pSctDrive)data;
/*
* check if the write command has gone through
*/
if(GetHdbProperty(self->write_node,"writestatus", script,1024)){
if(strcmp(script,"start") == 0){
return HWBusy;
}
}
/*
* run the checkstatus script
*/
if(!GetHdbProperty(self->write_node,"checkstatus",script,1024)){
if (!GetHdbProperty(self->write_node,"status",script,1024)){
SCWrite(pCon,
"ERROR: configuration problem: no checkstatus script!", eError);
return HWFault;
}
result = script;
} else {
status = SctCallInContext(pCon,script, self->write_node,
self->c, &result);
if (status == 0) {
SCPrintf(pCon,eError," script %s returned %s",
script, result);
return HWFault;
}
if(SctVerbose(self->c)){
SCPrintf(pCon,eError," script %s returned %s",
script, result);
}
}
if(strstr(result,"busy") != NULL){
return HWBusy;
} else if(strstr(result,"posfault") != NULL){
return HWPosFault;
} else if(strstr(result,"fault") != NULL){
return HWFault;
} else if(strstr(result,"idle") != NULL){
return HWIdle;
} else {
SCPrintf(pCon,eError,
"ERROR: invalid status code %s returned from checkstatus script",
result);
return HWFault;
}
return HWFault;
}
/*----------------------------------------------------------------
GetValue is supposed to read a motor position
On errors, -99999999.99 is returned and messages printed to pCon
------------------------------------------------------------------*/
static float SCTDRIVGetValue(void *data, SConnection *pCon){
pSctDrive self = NULL;
float val = -99999999.99;
int status;
char error[256];
hdbValue v;
self = (pSctDrive)data;
if(GetHdbProperty(self->read_node,"geterror", error, 256)){
SCWrite(pCon,error, eError);
return val;
}
return (float)self->read_node->value.v.doubleValue;
}
/*----------------------------------------------------------------
returns NULL on failure, a new datastructure else
------------------------------------------------------------------*/
static pSctDrive SCTDRIVMakeObject(){
pSctDrive self = NULL;
self = calloc(sizeof(SctDrive),1);
if(self == NULL){
return NULL;
}
self->pDes = CreateDescriptor("SctDriveAdapter");
self->pDriv = CreateDrivableInterface();
if(self->pDes == NULL || self->pDriv == NULL){
free(self);
return NULL;
}
self->pDes->GetInterface = SCTDRIVGetInterface;
self->pDriv->Halt = SCTDRIVHalt;
self->pDriv->CheckLimits = SCTDRIVCheckLimits;
self->pDriv->SetValue = SCTDRIVSetValue;
self->pDriv->CheckStatus = SCTDRIVCheckStatus;
self->pDriv->GetValue = SCTDRIVGetValue;
return self;
}
/*-----------------------------------------------------------------*/
static int SctDriveCommand(SConnection *pCon, SicsInterp *sics, void *object,
int argc, char *argv[]) {
pSctDrive self = (pSctDrive)object;
float val;
assert(self != NULL);
if (self->write_node == NULL) {
SCWrite(pCon, "ERROR: defunct object", eError);
return 0;
}
/*
* only action: print value
*/
val = self->pDriv->GetValue(self,pCon);
SCPrintf(pCon,eValue,"%s = %f", argv[0], val);
return 1;
}
/*----------------------------------------------------------------*/
static void SctDriveKill(void *data){
pSctDrive self = (pSctDrive)data;
if(self == NULL){
return;
}
if(self->pDriv != NULL){
free(self->pDriv);
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
free(self);
}
/*----------------------------------------------------------------*/
static hdbCallbackReturn SctDummyCallback(Hdb *node, void *userData,
hdbMessage *msg) {
return hdbContinue;
}
/*----------------------------------------------------------------*/
static void SctDriveDeleteNode(void *data) {
pSctDrive self = (pSctDrive)data;
self->write_node = NULL;
}
/*---------------------------------------------------------------*/
int ANSTO_SctMakeDriveAdapter(SConnection *pCon, SicsInterp *pSics, void *object,
int argc, char *argv[]) {
pSctDrive pNew = NULL;
pSICSOBJ obj = NULL;
hdbCallback *cb;
pNew = SCTDRIVMakeObject();
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory in ANSTO_SctMakeDriveAdapter",
eError);
return 0;
}
if(argc < 4){
SCWrite(pCon,"ERROR: not enough arguments for ANSTO_SctMakeDriveAdapter", eError);
return 0;
}
pNew->write_node = FindHdbNode(NULL,argv[2], pCon);
pNew->read_node = FindHdbNode(NULL,argv[3], pCon);
obj = FindCommandData(pSics,argv[4], "SctController");
if(pNew->write_node == NULL || obj == NULL){
SCWrite(pCon,"ERROR: node or controller not found", eError);
SctDriveKill(pNew);
return 0;
}
pNew->c =(SctController *)obj->pPrivate;
if (strcasecmp(argv[0],"dynsctdrive") == 0) {
/* make object dynamic by defining a descriptor command */
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
}
AddCommand(pSics, argv[1], SctDriveCommand, SctDriveKill, pNew);
SetHdbProperty(pNew->write_node,"sicsdev",argv[1]);
cb = MakeHipadabaCallback(SctDummyCallback, pNew, SctDriveDeleteNode);
assert(cb);
AppendHipadabaCallback(pNew->write_node, cb);
return 1;
}
/*---------------------------------------------------------------*/
void ANSTO_SctDriveInit(void) {
AddCmd("ansto_makesctdrive", ANSTO_SctMakeDriveAdapter);
}

View File

@@ -23,6 +23,7 @@
#include <countdriv.h>
#include <nserver.h>
#include <sys/time.h>
#include <HistMem.i>
extern char *trim(char *);
/*===================================================================
@@ -32,6 +33,8 @@ static char startdaq[] = {"/admin/startdaq.egi"};
static char stopdaq[] = {"/admin/stopdaq.egi"};
static char pausedaq[] = {"/admin/pausedaq.egi"};
static char continuedaq[] = {"/admin/continuedaq.egi"};
static char vetodaq[] = {"/admin/guienablesoftveto.egi"};
static char novetodaq[] = {"/admin/guidisablesoftveto.egi"};
static char statusdaq[] = {"/admin/textstatus.egi"};
static char gethm[] = {"/admin/readhmdata.egi"};
static char configure[] = {"/admin/configure.egi"};
@@ -110,6 +113,11 @@ static int anstoHttpCheckResponse(pAnstoHttp self){
len = 510;
}
if(strstr(pPtr,"ERROR") != NULL){
if(strstr(pPtr,"unknown caller") != NULL){
//ffr Ignore this error so we can use the guienablesoftveto
// and guidisablesoftveto controls.
return 1;
}
memset(self->hmError,0,512*sizeof(char));
strncpy(self->hmError,pPtr, len);
self->errorCode = HTTPERROR;
@@ -568,9 +576,55 @@ static int AnstoHttpHalt(pHistDriver self){ // hmm, why isn't there a pCon like
return OKOK;
}
/*---------------------------------------------------------------------*/
static int AnstoHttpPause(pHistDriver self,SConnection *pCon){
static int AnstoHttpVeto(pHistDriver self,SConnection *pCon)
{
pAnstoHttp pPriv = NULL;
int status;
char daqStatus[20];
StringDictGet(self->pOption,"daq",daqStatus,20);
if(strstr(daqStatus,"Stopped") != NULL){
return OKOK;
}
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,vetodaq);
if(status != 1){
return HWFault;
}
pPriv->pause = 1;
AnstoHttpStatusWithRetries(self,ANSTO_HS_STATUS_PAUSED,pCon);
return OKOK;
}
static int AnstoHttpNoVeto(pHistDriver self,SConnection *pCon)
{
pAnstoHttp pPriv = NULL;
int status;
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
status = anstoHttpGet(pPriv,novetodaq); // which is the same as restarting
if(status != 1){
return HWFault;
}
pPriv->pause = 0;
AnstoHttpStatusWithRetries(self,ANSTO_HS_STATUS_STARTED,pCon);
return OKOK;
}
int AnstoHttpPause(pHistDriver self,SConnection *pCon){
pAnstoHttp pPriv = NULL;
int status;
char daqStatus[20];
StringDictGet(self->pOption,"daq",daqStatus,20);
if(strstr(daqStatus,"Stopped") != NULL){
return OKOK;
}
pPriv = (pAnstoHttp)self->pPriv;
assert(pPriv != NULL);
@@ -805,6 +859,7 @@ static int AnstoHttpFreePrivate(pHistDriver self){
free(pPriv);
return 1;
}
/*-------------------------------------------------------------------*/
pHistDriver CreateAnstoHttpDriver(pStringDict pOption){
pHistDriver pNew = NULL;
@@ -855,8 +910,65 @@ pHistDriver CreateAnstoHttpDriver(pStringDict pOption){
pNew->GetTime = AnstoHttpGetTime;
pNew->Preset = AnstoHttpPreset;
pNew->FreePrivate = AnstoHttpFreePrivate;
pNew->Pause = AnstoHttpPause;
pNew->Continue = AnstoHttpContinue;
pNew->Pause = AnstoHttpVeto;
pNew->Continue = AnstoHttpNoVeto;
return pNew;
}
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
int ANSTO_HistAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
{
pHistMem self = NULL;
self = (pHistMem)pData;
if(strcmp(argv[1],"pause") == 0) {
if(!SCMatchRights(pCon,usUser)) {
return 0;
}
AnstoHttpPause(self->pDriv,pCon);
SCSendOK(pCon);
return 1;
}
return HistAction(pCon, pSics, pData, argc, argv);
}
int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pHistMem pNew = NULL;
char pBueffel[512];
int iRet;
/* check no of arguments */
if(argc < 3)
{
sprintf(pBueffel,"ERROR: insufficient no of arguments to %s",argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* make new HM */
strtolower(argv[2]);
pNew = CreateHistMemory(argv[2]);
if(!pNew)
{
sprintf(pBueffel,"ERROR: failed to create Histogram Memory %s, driver %s may be invalid or no memory",
argv[1], argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
StringDictAddPair(pNew->pDriv->pOption,"name",argv[1]);
/* install HM as command */
iRet = AddCommand(pSics,argv[1],ANSTO_HistAction,DeleteHistMemory,(void *)pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s not created",argv[1]);
SCWrite(pCon,pBueffel,eError);
DeleteHistMemory((void *)pNew);
return 0;
}
return 1;
}

View File

@@ -640,7 +640,7 @@ static int MonContinue(CounterDriver *cntrData) {
int status;
self = (BeamMon *) cntrData->pData;
status = MonSendBuffer(cntrData, "SICS CONTINUE", &self->buffer);
status = MonSendBuffer(cntrData, "SICS RESUME", &self->buffer);
if (status == SUCCESS) {
self->state = HWBusy;
return SUCCESS;

View File

@@ -10,7 +10,7 @@ SRC = .
CC = gcc
CFLAGS = -g -DLINUX $(DFORTIFY) -I$(SRC) -I../.. -Wall -Wno-unused -Wextra
HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_orhvpsprot.o
HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o
libhlib.a: $(HOBJ)
rm -f libhlib.a

View File

@@ -0,0 +1,53 @@
/** @file USBTMC protocol handler for script-context based controllers.
*
*/
#include <stropts.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <ascon.h>
#include <ascon.i>
#include <dynstring.h>
#include "usbtmc.h"
static void USBTMC_Connect(Ascon *a) {
struct usbtmc_instrument inst;
struct usbtmc_attribute attr;
a->fd = open(a->hostport, O_RDWR);
if (a->fd == -1) exit(1);
// Tell the driver we are using read(2), not fread(2)
attr.attribute=USBTMC_ATTRIB_READ_MODE;
attr.value=USBTMC_ATTRIB_VAL_READ;
ioctl(a->fd,USBTMC_IOCTL_SET_ATTRIBUTE,&attr);
attr.attribute=USBTMC_ATTRIB_NUM_INSTRUMENTS;
ioctl(a->fd,USBTMC_IOCTL_GET_ATTRIBUTE,&attr);
return;
}
/**
* @brief USBTMC protocol handler.
*/
int USBTMC_ProtHandler(Ascon *a) {
switch(a->state){
case AsconConnectStart:
USBTMC_Connect(a);
break;
default:
return AsconStdHandler(a);
}
return 1;
}
void AddUSBTMCProtocoll(){
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("usbtmc");
prot->init = AsconStdInit;
prot->handler = USBTMC_ProtHandler;
AsconInsertProtocol(prot);
}

View File

@@ -1,204 +1,50 @@
/**
* @file Astrium Velocity Selector protocol
* @Author Ferdi Franceschini
*/
#include <errno.h>
#include <ascon.h>
#include <ascon.i>
#include <dynstring.h>
#define MAXRETRIES 3
static char *UIDPROMPT="#SES#Fill in your user ID";
static char *PWDPROMPT="#SES#Fill in your password";
static char *CMDOK="#SOS#ACCEPT";
static char *CMDERR="#SOS#NCCEPT";
typedef enum {
Unknown,
sendUID,
sendPWD,
Established
} VelSelState;
typedef struct {
VelSelState subState;
char *user;
char *password;
char *expect;
int retries;
} VelSelProt, *pVelSelProt;
void VelSelAuthUID(Ascon *a) {
char chr;
int VelSelReading(Ascon *a)
{
int ret;
}
void VelSelAuthPwd(Ascon *a) {
}
void VelSelAuthenticate(Ascon *a) {
char chr;
int ret;
pVelSelProt pVelSel = (pVelSelProt)a->private;
switch (pVelSel->authProg) {
case start:
break;
case readingUIDPrompt:
break;
case readingPWDPrompt:
break;
}
char chr=0;
ret = AsconReadChar(a->fd, &chr);
if (ret > 0 && chr == '#') {
while (AsconReadChar(a->fd, &chr) > 0) {
if (chr == 0) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
return 1;
}
if (a->state != AsconReadDone) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
return 1;
} else {
return 1;
}
}
DynStringConcatChar(a->rdBuffer, chr);
while ((ret = AsconReadChar(a->fd, &chr)) > 0) {
DynStringConcatChar(a->rdBuffer, chr);
}
}
int VelSelWriteStart(Ascon *a) {
DynStringConcatChar(a->wrBuffer, '\r');
a->state = AsconWriting;
a->wrPos = 0;
return 1;
a->state = AsconReadDone;
DynStringConcatChar(a->rdBuffer, '\0');
}
int VelSelReading(Ascon *a) {
int VelSelProtHandler(Ascon *a)
{
int ret;
char chr;
pVelSelProt pVelSel = (pVelSelProt)a->private;
switch (pVelSel->subState) {
case sendUID:
ret = AsconReadChar(a->fd, &chr);
if (ret > 0) {
if (*pVelSel->expect == '\0') {
pVelSel->substate = sendPWD;
pVelSel->expect = PWDPROMPT;
} else if (chr == *pVelSel->expect) {
pVelSel->expect++;
} else if (pVelSel->retries-- > 0) {
a->state = AsconConnectStart;
pVelSel->retries = MAXRETRIES;
AsconError(a, "Did not get UID request", 0);
return 1;
}
}
pVelSel->retries = MAXRETRIES;
break;
case sendPWD:
break;
case Established:
break;
default:
}
switch(event) {
case UIDReq:
// wrBuffer = user:NVS
a->state = AsconWriteStart;
return 1;
break;
case PWDReq:
// wrBuffer = password:NVS
a->state = AsconWriteStart;
return 1;
break;
case
}
}
int VelSelProtHandler(Ascon *a) {
int ret;
pVelSelProt pVelSel = (pVelSelProt)a->private;
switch (a->state) {
case AsconConnecting:
ret = AsconConnectSuccess(a->fd);
if (ret == 0) {
/* in progress */
} else if (ret > 0) {
pVelSelProt->subState = sendUID;
a->state = AsconReading;
} else if (ret < 0) {
AsconError(a, "AsconConnectSuccess failed:", errno);
}
break;
case AsconWriteStart:
ret = VelSelWriteStart(a);
return ret;
break;
switch(a->state){
case AsconReading:
ret = VelSelReading(a);
return ret;
return VelSelReading(a);
break;
default:
return AsconStdHandler(a);
}
}
static void VelSelKill(void *data) {
pVelSelProt pVelSel = (pVelSelProt)data;
if (pVelSel == NULL)
return;
if (pVelSel->user != NULL)
free(pVelSel->user);
if (pVelSel->password != NULL)
free(pVelSel->password);
free(pVelSel);
}
static int VelSelProtInit(Ascon *a, SConnection *con, int argc, char *argv[]) {
pVelSelProt *pVelSel = NULL;
Tcl_Interp *tcl_interp;
pVelSel = (pVelSelProt) malloc(sizeof(VelSelProt));
if (VelSel == NULL) {
SCWrite(con, "ERROR: malloc for pVelSel failed in VelSelProtInit",eError);
return 0;
}
if (argc < 4) {
SCWrite(con, "ERROR: You must provide host, user, password parameters",eError);
return 0;
}
a->hostport = strdup(argv[1]);
pVelSel->user = strdup(argv[2]);
pVelSel->password = strdup(argv[3]);
if (argc == 5) {
tcl_interp = InterpGetTcl(pServ->pSics);
if (TCL_ERROR == Tcl_GetDobule(tcl_interp,argv[4],&a->timeout)) {
SCWrite(con, Tcl_GetStringResult(tcl_interp), eError);
return 0;
}
} else {
a->timeout = 10;
}
pVelSel->subState = Unknown;
pVelSel->expect = UIDPROMPT;
pVelSel->retries = MAXRETRIES;
a->private = pVelSel;
a->killPrivate = VelSelKill;
a->state = AsconConnectStart;
return 1;
}
void AddVelSelProtocol() {
void AddVelSelProtocol()
{
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("astvelsel");
prot->init = VelSelProtInit;
prot->init = AsconStdInit;
prot->handler = VelSelProtHandler;
AsconInsertProtocol(prot);
}

131
site_ansto/hardsup/usbtmc.h Normal file
View File

@@ -0,0 +1,131 @@
// usbtmc.h
// This file is part of a Linux kernel module for USBTMC (USB Test and
// Measurement Class) devices
// Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
// See usbtmc.c source file for license details
#include <linux/ioctl.h> // For _IO macro
// Driver parameters that you might want to tune...
// Maximum number of USBTMC devices to be concurrently serviced by this module
#define USBTMC_MINOR_NUMBERS 16
// Size of driver internal IO buffer. Must be multiple of 4 and at least as
// large as wMaxPacketSize (which is usually 512 bytes).
#define USBTMC_SIZE_IOBUFFER 4096
// Default USB timeout (in jiffies)
#define USBTMC_DEFAULT_TIMEOUT 10*HZ
// Maximum number of read cycles to empty bulk in endpoint during CLEAR and
// ABORT_BULK_IN requests. Ends the loop if (for whatever reason) a short
// packet is never read.
#define USBTMC_MAX_READS_TO_CLEAR_BULK_IN 100
// Other definitions
// Request values for USBTMC driver's ioctl entry point
#define USBTMC_IOC_NR 91
#define USBTMC_IOCTL_GET_CAPABILITIES _IO(USBTMC_IOC_NR,0)
#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR,1)
#define USBTMC_IOCTL_CLEAR _IO(USBTMC_IOC_NR,2)
#define USBTMC_IOCTL_ABORT_BULK_OUT _IO(USBTMC_IOC_NR,3)
#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR,4)
#define USBTMC_IOCTL_SET_ATTRIBUTE _IO(USBTMC_IOC_NR,5)
#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR,6)
#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR,7)
//#define USBTMC_IOCTL_TIMEOUT _IO(USBTMC_IOC_NR,8)
#define USBTMC_IOCTL_GET_ATTRIBUTE _IO(USBTMC_IOC_NR,9)
#define USBTMC_IOCTL_INSTRUMENT_DATA _IO(USBTMC_IOC_NR,10)
#define USBTMC_IOCTL_RESET_CONF _IO(USBTMC_IOC_NR,11)
// Request names for usbtmc_ioctl command line utility
#define USBTMC_IOCTL_NAME_GET_CAPABILITIES "getcaps"
#define USBTMC_IOCTL_NAME_INDICATOR_PULSE "indpulse"
#define USBTMC_IOCTL_NAME_CLEAR "clear"
#define USBTMC_IOCTL_NAME_ABORT_BULK_OUT "abortout"
#define USBTMC_IOCTL_NAME_ABORT_BULK_IN "abortin"
#define USBTMC_IOCTL_NAME_SET_ATTRIBUTE "setattr"
#define USBTMC_IOCTL_NAME_CLEAR_OUT_HALT "clearouthalt"
#define USBTMC_IOCTL_NAME_CLEAR_IN_HALT "clearinhalt"
#define USBTMC_IOCTL_NAME_GET_ATTRIBUTE "getattr"
#define USBTMC_IOCTL_NAME_RESET_CONF "reset"
// This structure is used with USBTMC_IOCTL_GET_CAPABILITIES.
// See section 4.2.1.8 of the USBTMC specification for details.
struct usbtmc_dev_capabilities {
char interface_capabilities;
char device_capabilities;
char usb488_interface_capabilities;
char usb488_device_capabilities;
};
// This structure is used with USBTMC_IOCTL_SET_ATTRIBUTE and
// USBTMC_IOCTL_GET_ATTRIBUTE.
struct usbtmc_attribute {
int attribute;
int value;
};
// Defines for attributes and their values
#define USBTMC_ATTRIB_AUTO_ABORT_ON_ERROR 0
#define USBTMC_ATTRIB_NAME_AUTO_ABORT_ON_ERROR "autoabort"
#define USBTMC_ATTRIB_READ_MODE 1
#define USBTMC_ATTRIB_NAME_READ_MODE "readmode"
#define USBTMC_ATTRIB_TIMEOUT 2
#define USBTMC_ATTRIB_NAME_TIMEOUT "timeout"
#define USBTMC_ATTRIB_NUM_INSTRUMENTS 3
#define USBTMC_ATTRIB_NAME_NUM_INSTRUMENTS "numinst"
#define USBTMC_ATTRIB_MINOR_NUMBERS 4
#define USBTMC_ATTRIB_NAME_MINOR_NUMBERS "numminor"
#define USBTMC_ATTRIB_SIZE_IO_BUFFER 5
#define USBTMC_ATTRIB_NAME_SIZE_IO_BUFFER "buffsize"
#define USBTMC_ATTRIB_DEFAULT_TIMEOUT 6
#define USBTMC_ATTRIB_NAME_DEFAULT_TIMEOUT "deftimeout"
#define USBTMC_ATTRIB_DEBUG_MODE 7
#define USBTMC_ATTRIB_NAME_DEBUG_MODE "debug"
#define USBTMC_ATTRIB_VERSION 8
#define USBTMC_ATTRIB_NAME_VERSION "version"
#define USBTMC_ATTRIB_TERM_CHAR_ENABLED 9
#define USBTMC_ATTRIB_NAME_TERM_CHAR_ENABLED "termcharenab"
#define USBTMC_ATTRIB_TERM_CHAR 10
#define USBTMC_ATTRIB_NAME_TERM_CHAR "termchar"
#define USBTMC_ATTRIB_ADD_NL_ON_READ 11
#define USBTMC_ATTRIB_NAME_ADD_NL_ON_READ "addnlread"
#define USBTMC_ATTRIB_REM_NL_ON_WRITE 12
#define USBTMC_ATTRIB_NAME_REM_NL_ON_WRITE "remnlwrite"
#define USBTMC_ATTRIB_VAL_OFF 0
#define USBTMC_ATTRIB_NAME_VAL_OFF "off"
#define USBTMC_ATTRIB_VAL_ON 1
#define USBTMC_ATTRIB_NAME_VAL_ON "on"
#define USBTMC_ATTRIB_VAL_FREAD 0
#define USBTMC_ATTRIB_NAME_VAL_FREAD "fread"
#define USBTMC_ATTRIB_VAL_READ 1
#define USBTMC_ATTRIB_NAME_VAL_READ "read"
// This structure is used with USBTMC_IOCTL_INSTRUMENT_DATA.
struct usbtmc_instrument {
int minor_number;
char manufacturer[200];
char product[200];
char serial_number[200];
};
// USBTMC status values
#define USBTMC_STATUS_SUCCESS 0x01
#define USBTMC_STATUS_PENDING 0x02
#define USBTMC_STATUS_FAILED 0x80
#define USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81
#define USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82
#define USBTMC_STATUS_SPLIT_IN_PROGRESS 0x83
// USBTMC requests values
#define USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT 1
#define USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS 2
#define USBTMC_REQUEST_INITIATE_ABORT_BULK_IN 3
#define USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS 4
#define USBTMC_REQUEST_INITIATE_CLEAR 5
#define USBTMC_REQUEST_CHECK_CLEAR_STATUS 6
#define USBTMC_REQUEST_GET_CAPABILITIES 7
#define USBTMC_REQUEST_INDICATOR_PULSE 64

View File

@@ -45,6 +45,8 @@ static int HMCStatus_ANSTO(void *pData, SConnection *pCon)
// If required, pause all objects when hm/count terminates
// instead of stopping them. Use the existing interface
// functions to do this.
// ffr: NOTE: Pause() is now mapped to AnstoHttpVeto()
// we need to call AnstoHttpPause() via the histmem Pause
if (((pHMcontrol_ANSTO)pData)->Pause_HM_After_Count==1)
self->pCount->Pause(self,pCon);
else

View File

@@ -0,0 +1,347 @@
# Define procs in ::scobj::xxx namespace
# MakeSICSObj $obj SCT_<class>
# The MakeSICSObj cmd adds a /sics/$obj node. NOTE the /sics node is not browsable.
namespace eval ::scobj::lh45 {
# Temperature controllers must have at least the following nodes
# /tempcont/setpoint
# /tempcont/sensor/value
proc getValue {nextState cmd} {
sct send $cmd
return $nextState
}
proc setValue {nextState cmd} {
set par [sct target]
sct send "$cmd $par"
return $nextState
}
proc setPoint {tc_root nextState cmd} {
set par [sct target]
if [hval $tc_root/apply_tolerance] {
set tol [hval $tc_root/tolerance]
hset $tc_root/subtemp_warnlimit [expr $par - $tol]
hset $tc_root/overtemp_warnlimit [expr $par + $tol]
}
hset $tc_root/power 1
hset $tc_root/status "busy"
if {[sct writestatus] == "start"} {
# Called by drive adapter
hsetprop $tc_root/setpoint driving 1
}
sct send "$cmd $par"
return $nextState
}
proc rdValue {} {
set data [sct result]
switch -glob -- $data {
"ASCERR:*" {
sct geterror $data
}
default {
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
}
}
}
return idle
}
##
# @brief Check if temperature controller is on or off
#
# Julabo LH45 Manual pg41
# If a time of 00:00 is set for a profile, the profile is continued with
# the next section only after the setpoint temperature (±0.2 °C) is
# reached.
# That's good enough for me.
#
# When the power is off no temp is outside of any range, therefore we
# report that the T.C. is in tolerance. This implies that counters
# can continue running if the T.C. is off, also lets you acquire data
# while allowing a sample to cool to ambient temperature.
proc rdPower {tc_root} {
set power [sct result]
sct utime readtime
switch -glob -- $power {
"ASCERR:*" {
sct geterror $power
}
default {
set oldval [sct oldval]
if {$oldval == "UNKNOWN"} { sct utime timecheck }
if {$power != $oldval} {
sct oldval $power
sct update $power
}
if {$power==1} {
set intol [::scobj::lh45::checktol $tc_root [sct readtime] [sct timecheck]]
if {$intol==0} { sct utime timecheck }
set setpt [hval $tc_root/setpoint]
set temp [hval $tc_root/sensor/value]
if {[expr abs($setpt - $temp)] > 0.2} {
hset $tc_root/emon/monmode "drive"
hset $tc_root/status "busy"
} else {
hsetprop $tc_root/setpoint driving 0
hset $tc_root/emon/monmode "monitor"
hset $tc_root/status "idle"
}
} else {
hset $tc_root/emon/monmode "idle"
hset $tc_root/emon/isintol 1
hset $tc_root/status "idle"
}
}
}
return idle
}
proc getState {tc_root nextState cmd} {
# Apply tolerance
if [hval $tc_root/apply_tolerance] {
set tol [hval $tc_root/tolerance]
set setpt [hval $tc_root/setpoint]
hset $tc_root/subtemp_warnlimit [expr $setpt - $tol]
hset $tc_root/overtemp_warnlimit [expr $setpt + $tol]
}
sct send $cmd
return $nextState
}
proc checktol {tc_root currtime timecheck} {
set temp [hval $tc_root/sensor/value]
set lotemp [hval $tc_root/subtemp_warnlimit]
set hitemp [hval $tc_root/overtemp_warnlimit]
if { $temp < $lotemp || $temp > $hitemp} {
hset $tc_root/emon/isintol 0
return 0
} else {
set timeout [hval $tc_root/tolerance/settletime]
if {[expr $currtime - $timecheck] > $timeout} {
hset $tc_root/emon/isintol 1
}
return 1
}
}
##
# @brief Reads the current lh45 state and error messages.
proc rdState {tc_root} {
set data [sct result]
if {[string first "ASCERR:" $data] >=0} {
sct geterror $data
} elseif {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
switch -- [lindex $data 0] {
"00" {
hset $tc_root/remote_ctrl False
}
"01" {
hset $tc_root/remote_ctrl False
}
"02" {
hset $tc_root/remote_ctrl True
}
"03" {
hset $tc_root/remote_ctrl True
}
default {
hset $tc_root/remote_ctrl UNKNOWN
hset $tc_root/lh45_lasterror $data
}
}
}
return idle
}
proc noResponse {} {
return idle
}
proc wrtValue {wcmd args} {
}
proc check {tc_root} {
set setpoint [sct target]
set lolimit [hval $tc_root/lowerlimit]
set hilimit [hval $tc_root/upperlimit]
if {$setpoint < $lolimit || $setpoint > $hilimit} {
error "setpoint violates limits"
}
return OK
}
##
# @brief Implement the checkstatus command for the drivable interface
#
# NOTE: The drive adapter initially sets the writestatus to "start" and will
# only call this when writestatus!="start"
proc drivestatus {tc_root} {
if [sct driving] {
return busy
} else {
return idle
}
}
proc halt {tc_root} {
hset $tc_root/setpoint [hval $tc_root/sensor/value]
hsetprop $tc_root/setpoint driving 0
return idle
}
proc mk_sct_julabo_lh45 {sct_controller klass tempobj tol} {
if [ catch {
set ns ::scobj::lh45
MakeSICSObj $tempobj SCT_OBJECT
sicslist setatt $tempobj klass $klass
sicslist setatt $tempobj long_name $tempobj
set scobj_hpath /sics/$tempobj
hfactory $scobj_hpath/setpoint plain user float
hsetprop $scobj_hpath/setpoint read ${ns}::getValue rdValue "in_sp_00"
hsetprop $scobj_hpath/setpoint write ${ns}::setPoint $scobj_hpath noResponse "out_sp_00"
hsetprop $scobj_hpath/setpoint check ${ns}::check $scobj_hpath
hsetprop $scobj_hpath/setpoint rdValue ${ns}::rdValue
hsetprop $scobj_hpath/setpoint noResponse ${ns}::noResponse
hsetprop $scobj_hpath/setpoint oldval UNKNOWN
hsetprop $scobj_hpath/setpoint driving 0
hsetprop $scobj_hpath/setpoint writestatus UNKNOWN
# Drive adapter interface
hsetprop $scobj_hpath/setpoint checklimits ${ns}::check $scobj_hpath
hsetprop $scobj_hpath/setpoint checkstatus ${ns}::drivestatus $scobj_hpath
hsetprop $scobj_hpath/setpoint halt ${ns}::halt $scobj_hpath
hfactory $scobj_hpath/overtemp_warnlimit plain user float
hsetprop $scobj_hpath/overtemp_warnlimit read ${ns}::getValue rdValue "in_sp_03"
hsetprop $scobj_hpath/overtemp_warnlimit write ${ns}::setValue noResponse "out_sp_03"
hsetprop $scobj_hpath/overtemp_warnlimit rdValue ${ns}::rdValue
hsetprop $scobj_hpath/overtemp_warnlimit noResponse ${ns}::noResponse
hsetprop $scobj_hpath/overtemp_warnlimit oldval UNKNOWN
hfactory $scobj_hpath/subtemp_warnlimit plain user float
hsetprop $scobj_hpath/subtemp_warnlimit read ${ns}::getValue rdValue "in_sp_04"
hsetprop $scobj_hpath/subtemp_warnlimit write ${ns}::setValue noResponse "out_sp_04"
hsetprop $scobj_hpath/subtemp_warnlimit rdValue ${ns}::rdValue
hsetprop $scobj_hpath/subtemp_warnlimit noResponse ${ns}::noResponse
hsetprop $scobj_hpath/subtemp_warnlimit oldval UNKNOWN
hfactory $scobj_hpath/sensor plain spy none
hfactory $scobj_hpath/sensor/value plain internal float
hsetprop $scobj_hpath/sensor/value read ${ns}::getValue rdValue "in_pv_00"
hsetprop $scobj_hpath/sensor/value rdValue ${ns}::rdValue
hsetprop $scobj_hpath/sensor/value oldval UNKNOWN
hsetprop $scobj_hpath/sensor/value units "C"
hfactory $scobj_hpath/heating_power_percent plain internal float
hsetprop $scobj_hpath/heating_power_percent read ${ns}::getValue rdValue "in_pv_01"
hsetprop $scobj_hpath/heating_power_percent rdValue ${ns}::rdValue
hsetprop $scobj_hpath/heating_power_percent oldval UNKNOWN
hfactory $scobj_hpath/power plain user int
hsetprop $scobj_hpath/power read ${ns}::getValue rdValue "in_mode_05"
hsetprop $scobj_hpath/power write ${ns}::setValue noResponse "out_mode_05"
hsetprop $scobj_hpath/power rdValue ${ns}::rdPower $scobj_hpath
hsetprop $scobj_hpath/power noResponse ${ns}::noResponse
hsetprop $scobj_hpath/power oldval UNKNOWN
hsetprop $scobj_hpath/power values 0,1
hfactory $scobj_hpath/apply_tolerance plain user int
hsetprop $scobj_hpath/apply_tolerance values 0,1
hset $scobj_hpath/apply_tolerance 1
hfactory $scobj_hpath/tolerance plain user float
hsetprop $scobj_hpath/tolerance units "C"
hfactory $scobj_hpath/tolerance/settletime plain user float
hset $scobj_hpath/tolerance/settletime 5.0
hsetprop $scobj_hpath/tolerance/settletime units "s"
hset $scobj_hpath/tolerance $tol
hfactory $scobj_hpath/status plain spy text
hset $scobj_hpath/status "idle"
hsetprop $scobj_hpath/status values busy,idle
hfactory $scobj_hpath/lh45_state plain spy text
hsetprop $scobj_hpath/lh45_state read ${ns}::getState $scobj_hpath rdState "status"
hsetprop $scobj_hpath/lh45_state rdState ${ns}::rdState $scobj_hpath
hsetprop $scobj_hpath/lh45_state oldval UNKNOWN
hfactory $scobj_hpath/remote_ctrl plain spy text
hset $scobj_hpath/remote_ctrl UNKNOWN
hfactory $scobj_hpath/lh45_lasterror plain user text
hset $scobj_hpath/lh45_lasterror ""
hfactory $scobj_hpath/lowerlimit plain mugger float
hsetprop $scobj_hpath/lowerlimit units "C"
hset $scobj_hpath/lowerlimit -45
hfactory $scobj_hpath/upperlimit plain mugger float
hsetprop $scobj_hpath/upperlimit units "C"
hset $scobj_hpath/upperlimit 130
hfactory $scobj_hpath/emon plain spy none
hfactory $scobj_hpath/emon/monmode plain user text
hsetprop $scobj_hpath/emon/monmode values idle,drive,monitor,error
hset $scobj_hpath/emon/monmode "idle"
hfactory $scobj_hpath/emon/isintol plain user int
hset $scobj_hpath/emon/isintol 1
hfactory $scobj_hpath/emon/errhandler plain user text
hset $scobj_hpath/emon/errhandler "pause"
$sct_controller poll $scobj_hpath/setpoint
$sct_controller write $scobj_hpath/setpoint
$sct_controller poll $scobj_hpath/subtemp_warnlimit
$sct_controller write $scobj_hpath/subtemp_warnlimit
$sct_controller poll $scobj_hpath/overtemp_warnlimit
$sct_controller write $scobj_hpath/overtemp_warnlimit
$sct_controller poll $scobj_hpath/heating_power_percent
$sct_controller poll $scobj_hpath/power
$sct_controller write $scobj_hpath/power
$sct_controller poll $scobj_hpath/sensor/value
$sct_controller poll $scobj_hpath/lh45_state 5 halt read
::scobj::hinitprops $tempobj
hsetprop $scobj_hpath klass NXenvironment
::scobj::set_required_props $scobj_hpath
foreach {rootpath hpath klass priv} "
$scobj_hpath sensor NXsensor spy
$scobj_hpath sensor/value sensor user
" {
hsetprop $rootpath/$hpath klass $klass
hsetprop $rootpath/$hpath privilege $priv
hsetprop $rootpath/$hpath control true
hsetprop $rootpath/$hpath data true
hsetprop $rootpath/$hpath nxsave true
}
hsetprop $scobj_hpath type part
hsetprop $scobj_hpath/sensor type part
hsetprop $scobj_hpath/sensor/value nxalias tc1_sensor_value
hsetprop $scobj_hpath/sensor/value mutable true
hsetprop $scobj_hpath/sensor/value sdsinfo ::nexus::scobj::sdsinfo
hsetprop $scobj_hpath privilege spy
::scobj::hinitprops $tempobj setpoint
ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/sensor/value $sct_controller
} message ] {
return -code error $message
}
}
namespace export mk_sct_julabo_lh45
}
# Julabo 137.157.202.85:4003
proc add_lh45 {name IP port {_tol 5.0}} {
makesctcontroller sct_lh45 std ${IP}:$port "\r"
mk_sct_julabo_lh45 sct_lh45 environment $name $_tol
makesctemon $name /sics/$name/emon/monmode /sics/$name/emon/isintol /sics/$name/emon/errhandler
}
namespace import ::scobj::lh45::*

View File

@@ -27,7 +27,7 @@ set instrument_dictionary [subst {
property {data true control true nxsave false klass @none type graphset}
}
instrument {
sobj {@any instrument}
sobj {@any instrument @any NXvelocity_selector}
privilege spy
datatype @none
property {data true control true nxsave false klass NXinstrument type instrument}
@@ -250,4 +250,49 @@ set instrument_dictionary [subst {
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias axis_4 link @none}
}
data/aux_data_1 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_1 link @none}
}
data/aux_data_2 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_2 link @none}
}
data/aux_data_3 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_3 link @none}
}
data/aux_data_4 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_4 link @none}
}
data/aux_data_5 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_5 link @none}
}
data/aux_data_6 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_6 link @none}
}
data/aux_data_7 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_7 link @none}
}
data/aux_data_8 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_8 link @none}
}
data/aux_data_9 {
privilege spy
datatype @none
property {data true control false nxsave false klass @none type nxvgroup nxalias aux_data_9 link @none}
}
}]

View File

@@ -790,7 +790,7 @@ proc ::hdb::sobjadd {hpath sobj args} {
todo_msg "$sobjatt(type) case, add $sobj to $hpath"
}
# TODO Can this be replaced with a sct_* glob?
sct_posit_motor {
sct_object {
set sobjName [normalgetatt $sobj long_name]
add_node $hpath node $sobjName long_name $sobjName kind scobj
}

View File

@@ -12,7 +12,7 @@ set boolean {true false}
# SICS OBJECTS MUST PROVIDE THE FOLLOWING INFORMATION
set sobj_klass_list {@none aperture attenuator collimator command crystal data detector disk_chopper entry environment experiment graphics instrument slits monitor monochromator parameter derived_parameter plc sample scan sensor source user}
set sobj_sicstype_list {chopperadapter environment_controller sicsvariable macro motor configurablevirtualmotor singlecounter histmem nxscript sicsdata scanobject sct_posit_motor}
set sobj_sicstype_list {chopperadapter environment_controller sicsvariable macro motor configurablevirtualmotor singlecounter histmem nxscript sicsdata scanobject sct_object}
# Different kinds of things are added to the hdb in different ways.
# command: This is something a client can run with hset /a/b/c start, it may have parameters and feedback.
# Parameters and feedback should be made available in 'ilists' named after the command.
@@ -86,7 +86,7 @@ set scanobject_attlist [subst {
$sobj_attlist
}]
set sct_posit_motor_attlist [subst {
set sct_object_attlist [subst {
$sobj_attlist
}]

View File

@@ -1,5 +1,5 @@
# $Revision: 1.44 $
# $Date: 2008-12-12 06:53:49 $
# $Revision: 1.45 $
# $Date: 2009-03-30 23:16:52 $
# Author: Ferdi Franceschini
# Based on the examples in the hs_test.tcl sample configuration by Mark Lesha.
# http://gumtree.ansto.gov.au:9080/nbicms/bragg-systems/histogram-server/hs_test.tcl/view
@@ -41,13 +41,13 @@ namespace eval histogram_memory {
set ic_fsrce_values [ list INTERNAL EXTERNAL ]
set ic_count_methods [concat [list time unlimited period count frame] $::counter::isc_beam_monitor_list ]
if {$histmem_simulation == "true"} {
MakeHM hmm SIM
MakeHM hmm_xy SIM
MakeHM hmm_xt SIM
MakeHM hmm_yt SIM
MakeHM hmm_x SIM
MakeHM hmm_y SIM
MakeHM hmm_t SIM
ANSTO_MakeHM hmm SIM
ANSTO_MakeHM hmm_xy SIM
ANSTO_MakeHM hmm_xt SIM
ANSTO_MakeHM hmm_yt SIM
ANSTO_MakeHM hmm_x SIM
ANSTO_MakeHM hmm_y SIM
ANSTO_MakeHM hmm_t SIM
hmm configure daq Stopped
hmm configure statuscheck false
hmm configure num_events_filled_to_histo 12345
@@ -73,13 +73,13 @@ namespace eval histogram_memory {
}
}
} else {
MakeHM hmm anstohttp
MakeHM hmm_xy anstohttp
MakeHM hmm_xt anstohttp
MakeHM hmm_yt anstohttp
MakeHM hmm_x anstohttp
MakeHM hmm_y anstohttp
MakeHM hmm_t anstohttp
ANSTO_MakeHM hmm anstohttp
ANSTO_MakeHM hmm_xy anstohttp
ANSTO_MakeHM hmm_xt anstohttp
ANSTO_MakeHM hmm_yt anstohttp
ANSTO_MakeHM hmm_x anstohttp
ANSTO_MakeHM hmm_y anstohttp
ANSTO_MakeHM hmm_t anstohttp
MakeHMControl_ANSTO hmc bm hmm;
}
@@ -753,8 +753,8 @@ proc HISTMEM_TABLE {tpath args} {
#
proc BAT_TABLE {args} {
if [ catch {
set attributes { NO_BAT_ENTRIES NO_BAT_PERIODS NO_REPEAT_ENTRY NO_REPEAT_TABLE NO_EXECUTE_TABLE }
set elements {{ PERIOD_INDICES }}
set attributes { FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE }
set elements {{ }}
set tag BAT
foreach {opt arglist} [::utility::get_opt_arglist $args] {}
@@ -929,7 +929,7 @@ proc CAT_TABLE {args} {
#
proc FAT_TABLE {args} {
if [ catch {
set attributes { FRAME_FREQUENCY SIZE_PERIOD NOS_PERIODS COUNT_METHOD COUNT_SIZE READ_DATA_TYPE VIEW_MAG_X VIEW_MAG_Y HISTO_STREAMING }
set attributes { FRAME_FREQUENCY SIZE_PERIOD COUNT_METHOD COUNT_SIZE READ_DATA_TYPE VIEW_MAG_X VIEW_MAG_Y}
set elements {{ }}
set tag FAT
@@ -1412,17 +1412,17 @@ proc ::histogram_memory::configure_dims {} {
foreach hm_obj [sicslist type histmem] {
set rank [SplitReply [$hm_obj configure rank]]
set hmm_length 1
foreach elmt $dim_map($hm_obj) {
set [lindex $elmt 0] [hmmdictitemval hmm [lindex $elmt 1]]
}
$hm_obj configure READ_DATA_TYPE $dim_map($hm_obj,read_data_type)
# ffr:SICS-330 UNCALIBRATED stops "hmm get 1" commands from getting data
# $hm_obj configure READ_DATA_UNCAL_CAL UNCALIBRATED
$hm_obj stop
$hm_obj configure init 0
$hm_obj init
for {set i 0} {$i < $rank} {incr i} {
set hmm_length [expr {$hmm_length * [set hmm_dim$i]} ]
$hm_obj configure dim$i [set hmm_dim$i]
}
}
@@ -1567,6 +1567,7 @@ proc ::histogram_memory::t_max {} {
sicslist setatt ::histogram_memory::total_counts klass detector
sicslist setatt ::histogram_memory::total_counts long_name total_counts
sicslist setatt ::histogram_memory::total_counts mutable true
sicslist setatt ::histogram_memory::total_counts units count
##
# @brief Histogram memory acquisition time
@@ -1707,7 +1708,11 @@ proc ::histogram_memory::post_count {} {}
if {$oscmd_controlled == "true"} {
hmm count
} else {
hmc start 1000000000 timer pause 1
#hmc start 1000000000 timer pause 1
# ffr: Can't set pause because this now calls the
# new AnstoHttpVeto function. hmcontrol_ansto.c needs
# to be fixed so it calls AnstoHttpPause()
hmc start 1000000000 timer stop 1
}
}
set reply [SplitReply [hmm configure daq]]
@@ -1717,7 +1722,6 @@ proc ::histogram_memory::post_count {} {}
clientput "histmem started" value
if {$blocking == "block"} {
blockctr count 0
::histogram_memory::pause
}
} message ] {
if {$::errorCode=="NONE"} {return $message}

View File

@@ -127,7 +127,7 @@ proc updatestatus {} {
# middle n2 "inbetween"
# lower n3 "down"
#}
proc mk_sct_jogmotor {sct_controller axis jogmotor jogspeed {initcmd_table {UP "up" DOWN "down"}}} {
proc mk_sct_jogmotor {sct_controller klass axis jogmotor jogspeed {initcmd_table {UP "up" DOWN "down"}}} {
variable cmd_table
foreach {cmd name} $initcmd_table {
set cmd_table($cmd) [string tolower $name]
@@ -135,7 +135,8 @@ proc updatestatus {} {
if [ catch {
set ns ::scobj::jogmotor
MakeSICSObj $jogmotor SCT_JOG_MOTOR
MakeSICSObj $jogmotor SCT_OBJECT
sicslist setatt $jogmotor klass $klass
set jog_hpath /sics/${jogmotor}
hfactory $jog_hpath/speed plain spy float
hsetprop $jog_hpath/speed read ${ns}::getSpeed $axis

View File

@@ -1,3 +1,8 @@
# You define a two column lookup table, the first column may be a simple
# index number or some instrument parameter which depends on the motor
# position. The second column is the motor position.
# The lookup table must have a header which names the two columns.
namespace eval ::scobj::positmotor {
variable posit_table
variable posit_indices
@@ -102,10 +107,21 @@ namespace eval ::scobj::positmotor {
return state_reading_index
}
proc state_reading_index {path par motor} {
##
# @brief Updates the position index and sets the associated instrument
# parameter
#
# @param path, Script context object path
# @param par, Control parameter for the positional motor
# @param motor, The name of the motor which does the actual driving
# @param staticpar, The static parameter defined in the lookup table.
# @param calc_instpar, Name of an optional function which calculates
# the instrument parameter from the staticpar. Eg attenuation
proc state_reading_index {path par motor staticpar calc_instpar} {
variable posit_table
variable posit_label
sct writestatus replyreceived
set rply [val2pos [sct result] [hval $path/motprecision] $motor]
set rply [val2pos [sct result] [hval $path/$par/motprecision] $motor]
set data $rply
# broadcast state_reading_index update parameter $par $data
if {$data != [sct oldval] || [sct force_update] } {
@@ -114,6 +130,13 @@ namespace eval ::scobj::positmotor {
# }
sct oldval $data
sct update $data
if {$data > 0} {
if {$calc_instpar == "@none"} {
hset $path/$staticpar $posit_label($motor,$data)
} else {
hset $path/$staticpar [$calc_instpar $posit_label($motor,$data)]
}
}
sct force_update False
sct utime readtime
}
@@ -155,15 +178,29 @@ namespace eval ::scobj::positmotor {
set posit_table($motor,$posindex) $val
}
proc mk_sct_positmotor {sct_controller motor scobjNode param table_ID posit_list} {
##
# @brief Create a positional motor control object which lets you
# drive to an indexed position defined in a lookup table.
#
# @param sct_controller, Name of controller created with mk_sct_positmotor
# @param klass, Controls place in hdb and nexus file hierarchy.
# @param motor, Name of motor which handles the actual driving.
# @param scobjName, Name of script-context object which we are creating.
# @param pindex, Position index, selects the position to drive to.
# @param table_ID, Tag which identifies the lookup table used for this controller.
# @param posit_list, Lookup table which maps the index set on the control parameter to a position.
# @param calc_instpar, Optional command which returns ????
proc mk_sct_positmotor {sct_controller klass motor scobjName pindex table_ID posit_list {calc_instpar @none}} {
variable posit_table
variable posit_indices
variable posit_label
set index 1
foreach {label position} $posit_list {
set staticpar [lindex $posit_list 0]
foreach {label position} [lrange $posit_list 2 end] {
lappend posit_indices($motor) $index
set posit_table($motor,$index) $position
set posit_label($index) $label
set posit_label($motor,$index) $label
incr index
}
# set posit_indices [lsort -integer [array names posit_table]]
@@ -172,48 +209,52 @@ namespace eval ::scobj::positmotor {
if [ catch {
set ns ::scobj::positmotor
MakeSICSObj $scobjNode SCT_POSIT_MOTOR
MakeSICSObj $scobjName SCT_OBJECT
sicslist setatt $scobjName klass $klass
# Make setable position parameter and poll it.
set posindex_node /sics/${scobjNode}/${param}
hfactory $posindex_node plain user float
hsetprop $posindex_node read ${ns}::rd_index $param $motor
hsetprop $posindex_node state_reading_index ${ns}::state_reading_index $posindex_node $param $motor
hsetprop $posindex_node write ${ns}::w_index $sct_controller $posindex_node $param $motor
hsetprop $posindex_node check ${ns}::check_motor
set scobjPath /sics/$scobjName
hfactory $scobjPath/$pindex plain user float
hsetprop $scobjPath/$pindex read ${ns}::rd_index $pindex $motor
hsetprop $scobjPath/$pindex state_reading_index ${ns}::state_reading_index $scobjPath $pindex $motor $staticpar $calc_instpar
hsetprop $scobjPath/$pindex write ${ns}::w_index $sct_controller $scobjPath $pindex $motor
hsetprop $scobjPath/$pindex check ${ns}::check_motor
hsetprop $posindex_node oldval UNKNOWN
hsetprop $posindex_node force_update True
# hsetprop $posindex_node motprecision [SplitReply [samx precision]]
hfactory $posindex_node/motprecision script "getmotpar $motor precision" "$motor precision " float 1
hsetprop $scobjPath/$pindex oldval UNKNOWN
hsetprop $scobjPath/$pindex force_update True
# hsetprop $scobjPath/$pindex motprecision [SplitReply [samx precision]]
hfactory $scobjPath/$pindex/motprecision script "getmotpar $motor precision" "$motor precision " float 1
hfactory $posindex_node/lookup_table plain spy none
hsetprop $posindex_node/lookup_table ID $table_ID
hsetprop $posindex_node/lookup_table numpos [llength $posit_indices($motor)]
hfactory $scobjPath/$pindex/lookup_table plain spy none
hsetprop $scobjPath/$pindex/lookup_table ID $table_ID
hsetprop $scobjPath/$pindex/lookup_table numpos [llength $posit_indices($motor)]
foreach posindex $posit_indices($motor) {
hfactory $posindex_node/lookup_table/$posindex script "${ns}::pos2val $posindex $motor" "${ns}::setposindex $posindex $motor " float 1
hsetprop $posindex_node/lookup_table/$posindex ID $posit_label($posindex)
hfactory $scobjPath/$pindex/lookup_table/$posindex script "${ns}::pos2val $posindex $motor" "${ns}::setposindex $posindex $motor " float 1
hsetprop $scobjPath/$pindex/lookup_table/$posindex $staticpar $posit_label($motor,$posindex)
}
hfactory $posindex_node/status plain spy text
hset $posindex_node/status IDLE
hfactory $scobjPath/$staticpar plain user float
hfactory $scobjPath/status plain spy text
hset $scobjPath/status IDLE
proc ${motor}_MOTEND {} [subst -nocommands {
if { [hval $posindex_node/status] == "BUSY"} {
$sct_controller poll $posindex_node 5
hset $posindex_node/status STOPPING
if { [hval $scobjPath/status] == "BUSY"} {
$sct_controller poll $scobjPath/$pindex 5
hset $scobjPath/status STOPPING
}
}]
publish ${ns}::${motor}_MOTEND user
scriptcallback connect $motor MOTEND ${ns}::${motor}_MOTEND
$sct_controller poll $posindex_node
$sct_controller write $posindex_node
$sct_controller poll $scobjPath/$pindex
$sct_controller write $scobjPath/$pindex
sicslist setatt $scobjNode long_name $scobjNode
sicslist setatt $scobjName long_name $scobjName
hinitprops $scobjNode
hinitprops $scobjNode $param
::scobj::hinitprops $scobjName
::scobj::hinitprops $scobjName $pindex
::scobj::hinitprops $scobjName $staticpar
} message ] {
return -code error $message
}

View File

@@ -10,7 +10,10 @@ sicsdatafactory new nxscript_data
::utility::mkVar eend Text user end_time true entry false true
::utility::mkVar timestamp int user time_stamp true entry false true
::utility::mkVar data_run_number int user run_number true instrument false true
::utility::mkVar save_count int user save_count true experiment true true
::utility::mkVar currpoint int user currpoint true experiment true true
::utility::mkVar nexus_datatype text user DataType true data false true
::utility::mkVar file_status text user file_status true experiment true true
::utility::mkVar file_set_list Text user file_set true experiment true true
sicslist setatt data_run_number mutable true
sicslist setatt timestamp mutable true
@@ -56,6 +59,8 @@ namespace eval nexus {
link {axis 2 ::histogram_memory::time_channel}
link {axis 3 ::histogram_memory::vertical_axis}
link {axis 4 ::histogram_memory::horizontal_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm}
save_policy {include @all exclude {hmm_xy hmm_xt hmm_yt hmm_x hmm_y hmm_t}}
}
@@ -63,6 +68,8 @@ namespace eval nexus {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::vertical_axis}
link {axis 3 ::histogram_memory::horizontal_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_xy}
save_policy {include @all exclude {hmm hmm_xt hmm_yt hmm_x hmm_y hmm_t}}
}
@@ -70,6 +77,8 @@ namespace eval nexus {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::time_channel}
link {axis 3 ::histogram_memory::horizontal_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_xt}
save_policy {include @all exclude {hmm_xy hmm hmm_yt hmm_x hmm_y hmm_t}}
}
@@ -77,30 +86,36 @@ namespace eval nexus {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::time_channel}
link {axis 3 ::histogram_memory::vertical_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_yt}
save_policy {include @all exclude {hmm_xy hmm_xt hmm hmm_x hmm_y hmm_t}}
}
HISTOGRAM_X {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::horizontal_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_x}
save_policy {include @all exclude {hmm_xy hmm_xt hmm_yt hmm hmm_y hmm_t}}
}
HISTOGRAM_Y {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::vertical_axis}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_y}
save_policy {include @all exclude {hmm_xy hmm_xt hmm_yt hmm_x hmm hmm_t}}
}
HISTOGRAM_T {
link {axis 1 data_run_number}
link {axis 2 ::histogram_memory::time_channel}
link {aux_data 1 ::histogram_memory::time}
link {aux_data 2 ::histogram_memory::total_counts}
link {data_set hmm_t}
save_policy {include @all exclude {hmm_xy hmm_xt hmm_yt hmm_x hmm_y hmm}}
}
}
variable filetype_spec [concat [array get bmon_filetype_spec] [array get histmem_filetype_spec] ]
}
##
@@ -191,7 +206,9 @@ proc newFileName {idNum postfix} {
variable state
variable nexusdic
variable currFilename
variable save_count_arr
variable start_seconds_array
variable file_states
array set state {
file,open "false"
@@ -204,7 +221,18 @@ proc newFileName {idNum postfix} {
set nexusdic "nexus.dic"
array set currFilename ""
array set save_count_arr ""
array set start_seconds_array ""
array set file_states {U "UNKNOWN" O "OPEN" C "CLOSED" S "SAVING"}
save_count 0
currpoint 0
file_status UNKNOWN
}
proc ::nexus::ic_initialize {} {
variable bmon_filetype_spec
variable histmem_filetype_spec
variable filetype_spec [concat [array get bmon_filetype_spec] [array get histmem_filetype_spec] ]
}
##
@@ -282,6 +310,8 @@ proc ::nexus::newfile_collection {args} {
variable state
variable data_gp_path
variable currFilename
variable save_count_arr
variable file_states
set valid_options [list "-labels" "-filetype" "-savetype"]
set required_options [list "-filetype" "-savetype"]
@@ -296,7 +326,8 @@ proc ::nexus::newfile_collection {args} {
default { error "ERROR: Invalid file suffix $file_suffix" }
}
set state(file,namestyle) $param(-savetype)
file_set_list "UNKNOWN"
array unset save_count_arr
array unset currFilename
if {$param(-savetype) == "scratch"} {
set state(file,isNewScratchFile) true
set state(file,incr_datnum) false
@@ -310,11 +341,13 @@ proc ::nexus::newfile_collection {args} {
set state(file,labels) $param(-labels)
if {$param(-savetype) == "scratch"} {
foreach fid $state(file,labels) {
set save_count_arr($fid) 0
set currFilename($fid) [format "%s/scratch_%s.%s" [::nexus::datapath] $fid $file_suffix]
lappend files $currFilename($fid)
}
} else {
foreach fid $state(file,labels) {
set save_count_arr($fid) 0
set currFilename($fid) [newFileName $idNum $file_suffix]
incr idNum
lappend files $currFilename($fid)
@@ -324,12 +357,16 @@ proc ::nexus::newfile_collection {args} {
} else {
set state(file,fileset) "false"
set state(file,labels) @singlefile
set save_count_arr(@singlefile) 0
if {$param(-savetype) == "scratch"} {
set currFilename(@singlefile) [format "%s/scratch.%s" [::nexus::datapath] $file_suffix]
} else {
set currFilename(@singlefile) [newFileName $idNum $file_suffix]
}
}
save_count 0
currpoint 0
file_status $file_states(U)
hsetprop $data_gp_path currentfiletype UNKNOWN
if {$param(-filetype) == "clear"} {
::nexus::data clear
@@ -337,6 +374,8 @@ proc ::nexus::newfile_collection {args} {
hsetprop $data_gp_path currentfiletype UNKNOWN
hsetprop $data_gp_path datatype UNKNOWN
nexus_datatype "UNKNOWN"
file_set_list "UNKNOWN"
# dataFileName "UNKNOWN"
} else {
::nexus::process_filetype_policy $param(-filetype) filetype_spec
nexus_datatype $param(-filetype)
@@ -407,6 +446,8 @@ proc ::nexus::save {{point 0}} {
variable start_seconds
variable start_seconds_array
variable currFilename
variable save_count_arr
variable file_states
set valid_options [list "-index" "-label"]
set required_options [list "-index"]
@@ -456,20 +497,32 @@ proc ::nexus::save {{point 0}} {
set start_seconds [clock seconds]
# set start_seconds_array($data_label) $start_seconds
timestamp 0
file_status $file_states(O)
::nexus::nxreopenfile $currFilename($data_label)
file_status $file_states(S)
::nexus::save_data $point
::nexus::makelinks
::nexus::set_plotdata_info
::nexus::nxclosefile $currFilename($data_label)
file_status $file_states(C)
incr save_count_arr($data_label)
save_count $save_count_arr($data_label)
currpoint $point
set state(file,isNewScratchFile) false
} else {
eend [lindex [sicstime] 1]
# timestamp [expr {[clock seconds] - $start_seconds_array($data_label)}]
timestamp [expr {[clock seconds] - $start_seconds}]
dataFileName $currFilename($data_label)
file_status $file_states(O)
::nexus::nxreopenfile $currFilename($data_label)
file_status $file_states(S)
::nexus::save_data $point
::nexus::nxclosefile $currFilename($data_label)
file_status $file_states(C)
incr save_count_arr($data_label)
currpoint $point
save_count $save_count_arr($data_label)
}
} message ] {
::nexus::nxclosefile $currFilename($data_label)
@@ -552,6 +605,8 @@ proc ::nexus::save {{point 0}} {
# Records that /data/data_set should be linked to datsource and sets a data type identifier
# data axis 1|2|3|4 datsource
# Records that /data/axisn should be linked to datsource
# data aux_data 1|2|3|4|5|6|7|8|9 datsource
# Records that /data/aux_datan should be linked to datsource
# data clear
# Clears all link targets and sets the data type identifier to unknown
# data alias <name>, remove alias <name>
@@ -571,7 +626,7 @@ proc ::nexus::save {{point 0}} {
set arglist [lrange $arguments 1 end]
switch $opt {
"axis" {
"axis" - "aux_data" {
debug_msg "'axis' case of switch"
set link_target [lindex $arguments 2]
if {[getatt $link_target privilege] == "internal"} {
@@ -584,7 +639,7 @@ proc ::nexus::save {{point 0}} {
if {[getatt $link_target type] == ""} {
error "Unknown link target $link_target"
}
set hp $dpath/axis_$axnum
set hp $dpath/${opt}_$axnum
# if {[::utility::hgetplainprop $hp link] == "@none"} {
hsetprop $hp link [getatt [lindex $arguments 2] id]
hsetprop $hp long_name [getatt [lindex $arguments 2] long_name]
@@ -689,6 +744,9 @@ proc ::nexus::save {{point 0}} {
nxscript putattribute $p_arr(link) signal 1
set data_set_alias $p_arr(link)
}
"aux_data_*" {
continue
}
default {error "ERROR: [info level -1]->set_plotdata_info, Unsupported data path $hpath/$child"}
}
}
@@ -730,7 +788,7 @@ proc ::nexus::save {{point 0}} {
if {[info exists p_arr(mutable)] && $p_arr(mutable) == "true" } {
nxscript puthdb /$hpath/$child point $pt
} else {
nxscript puthdb /$hpath/$child
nxscript puthdb /$hpath/$child point 0
}
}
::nexus::savetree $hpath/$child $pt
@@ -776,18 +834,27 @@ proc ::nexus::save {{point 0}} {
}
array set p_arr [::utility::hlistplainprop /$hpath]
set data_type [lindex [split [hinfo /$hpath] , ] 0]
if {$data_type == "none"} {
if {$data_type == "none" && $p_arr(type) != "nxvgroup"} {
#XXX Do we need to check data_type here. This would skip NXVGROUP nodes
return;
}
if {$p_arr(data) == "true" && $p_arr(nxsave) == "true" && [info exists p_arr(nxalias)]} {
set alias $p_arr(nxalias)
if {[info exists p_arr(sdsinfo)]} {
if {[info exists p_arr(mutable)] && $p_arr(mutable) == "true"} {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $p_arr(sicsdev) $data_type mutable true]"
} else {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $p_arr(sicsdev) $data_type mutable false]"
}
} elseif {[info exists p_arr(type)] && $p_arr(type) == "nxvgroup"} {
if {[info exists p_arr(sdsinfo)]} {
if {[info exists p_arr(mutable)] && $p_arr(mutable) == "true"} {
if {[info exists p_arr(savecmd)]} {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $p_arr(sicsdev) $data_type mutable true]"
} else {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $data_type mutable true]"
}
} else {
if {[info exists p_arr(savecmd)]} {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $p_arr(sicsdev) $data_type mutable false]"
} else {
set nxdictionary($alias) "$dictPath/SDS $name [$p_arr(sdsinfo) $data_type mutable false]"
}
}
} elseif {[info exists p_arr(type)] && $p_arr(type) == "nxvgroup"} {
set nxdictionary($alias) "$dictPath/NXVGROUP"
}
}
@@ -971,12 +1038,12 @@ proc ::nexus::motor::save {motor nxalias data_type args} {
proc ::nexus::motor::sdsinfo {motor data_type args} {
array set param $args
array set attribute [::utility::normalattlist $motor]
set dtype [::nexus::hdb2nx_type $data_type]
if {[info exists attribute(units)]} {
set units_att " -attr {units,$attribute(units)} "
} else {
set units_att " "
}
set dtype [::nexus::hdb2nx_type $data_type]
set name_att " -attr {long_name,$attribute(long_name)} "
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1} $units_att $name_att"
@@ -1067,7 +1134,6 @@ namespace eval ::nexus {
proc ::nexus::sicsvariable::save {svar nxalias data_type args} {
if [ catch {
array set attribute [attlist $svar]
set val [SplitReply [$svar]]
if {[lindex $args 0] == "point"} {
set index [lindex $args 1]
@@ -1086,9 +1152,6 @@ proc ::nexus::sicsvariable::save {svar nxalias data_type args} {
default {error "ERROR: [info level -1]->::nexus::sicsvariable::save, unknown type $data_type"}
}
}
if {[info exists attribute(units)]} {
nxscript putattribute $nxalias units $attribute(units)
}
} message ] {
if {$::errorCode=="NONE"} {return $message}
return -code error "::nexus::sicsvariable::save, $message"
@@ -1096,18 +1159,24 @@ proc ::nexus::sicsvariable::save {svar nxalias data_type args} {
}
# TODO Add optional units to sicsvariables
proc ::nexus::sicsvariable::sdsinfo {svar data_type args} {
proc ::nexus::sicsvariable::sdsinfo {sobj data_type args} {
array set param $args
set dtype [::nexus::hdb2nx_type $data_type]
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1}"
} else {
return " -type $dtype"
}
set dtype [::nexus::hdb2nx_type $data_type]
array set attribute [::utility::normalattlist $sobj]
if {[info exists attribute(units)]} {
set units_att " -attr {units,$attribute(units)} "
} else {
set units_att " "
}
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1} $units_att"
} else {
return " -type $dtype $units_att"
}
}
namespace eval ::nexus::scobj {}
proc ::nexus::scobj::sdsinfo {svar data_type args} {
proc ::nexus::scobj::sdsinfo {data_type args} {
array set param $args
set dtype [::nexus::hdb2nx_type $data_type]
if {$param(mutable) == true} {
@@ -1138,19 +1207,22 @@ proc ::nexus::chopperadapter::save {sobj nxalias data_type args} {
default {error "ERROR: [info level -1]->::nexus::chopperadapter::save, unknown type $data_type"}
}
}
if {[info exists attribute(units)]} {
nxscript putattribute $nxalias units $attribute(units)
}
}
proc ::nexus::chopperadapter::sdsinfo {sobj data_type args} {
array set param $args
set dtype [::nexus::hdb2nx_type $data_type]
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1}"
} else {
return " -type $dtype"
}
set dtype [::nexus::hdb2nx_type $data_type]
array set attribute [::utility::normalattlist $sobj]
if {[info exists attribute(units)]} {
set units_att " -attr {units,$attribute(units)} "
} else {
set units_att " "
}
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1} $units_att"
} else {
return " -type $dtype $units_att"
}
}
proc ::nexus::singlecounter::save {counter nxalias data_type args} {
todo_msg "Save counter: $counter"
@@ -1185,9 +1257,6 @@ proc ::nexus::script::save {script nxalias data_type args} {
} else {
nxscript putslab $nxalias [list 0] [list $size] $darray
}
if {[info exists attribute(units)]} {
nxscript putattribute $nxalias units $attribute(units)
}
}
} message ] {
if {$::errorCode=="NONE"} {return $message}
@@ -1195,18 +1264,24 @@ proc ::nexus::script::save {script nxalias data_type args} {
}
}
proc ::nexus::script::sdsinfo {script data_type args} {
proc ::nexus::script::sdsinfo {sobj data_type args} {
if [ catch {
array set param $args
set dtype [::nexus::hdb2nx_type $data_type]
if {[getatt $script klass] == "sensor"} {
array set attribute [::utility::normalattlist $sobj]
if {[info exists attribute(units)]} {
set units_att " -attr {units,$attribute(units)} "
} else {
set units_att " "
}
if {[getatt $sobj klass] == "sensor"} {
if {$param(mutable) == true} {
return " -type $dtype -rank 1 -dim {-1}"
return " -type $dtype -rank 1 -dim {-1} $units_att"
} else {
return " -type $dtype"
return " -type $dtype $units_att"
}
} else {
set darray [$script -arrayname]
set darray [$sobj -arrayname]
set size [SplitReply [$darray used]]
if {$param(mutable) == true} {
return " -type $dtype -rank 2 -dim {-1,$size}"
@@ -1237,7 +1312,7 @@ foreach expt $::nexus::exports {
set tmpstr [string map {"$" ""} {$Name: not supported by cvs2svn $}]
set nx_content_release_tag [lindex $tmpstr [expr [llength $tmpstr] - 1]]
set tmpstr [string map {"$" ""} {$Revision: 1.46 $}]
set tmpstr [string map {"$" ""} {$Revision: 1.47 $}]
set nx_content_revision_num [lindex $tmpstr [expr [llength $tmpstr] - 1]]
#namespace eval data {

View File

@@ -6,6 +6,8 @@ namespace eval motor {
}
namespace eval ajscmds {
namespace export SetRadColl SimpleRun SimpleScan RadCollRun RadCollTimed RadCollScan
# SetRadColl
command SetRadColl {
float time
@@ -114,6 +116,13 @@ int=1:inf oscno
RadCollOff
}
}
namespace import ::ajscmds::*
publish SetRadColl user
publish SimpleRun user
publish SimpleScan user
publish RadCollRun user
publish RadCollTimed user
publish RadCollScan user
proc ::commands::isc_initialize {} {
::commands::ic_initialize

View File

@@ -36,7 +36,7 @@ set mx_Home 7464891
set mom_Home 9274794
set mtth_Home 19927837
set mphi_Home 7613516
set mchi_Home 7503905
set mchi_Home 9050090
set my_Home 6767221
set som_Home 17214054
set stth_Home 2896180

View File

@@ -1 +1,4 @@
source $cfPath(nexus)/nxscripts_common_1.tcl
proc ::nexus::isc_initialize {} {
::nexus::ic_initialize
}

View File

@@ -1,5 +1,5 @@
# $Revision: 1.33 $
# $Date: 2008-12-12 06:53:51 $
# $Revision: 1.34 $
# $Date: 2009-03-30 23:16:53 $
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Last revision by: $Author: ffr $
@@ -32,8 +32,8 @@ if {$sim_mode == "true"} {
}
#Measured absolute encoder reading at home position
set mphi_Home 7413209
set mchi_Home 7818834
set mphi_Home 11839906
set mchi_Home 8417936
set my_Home 7781389
set mx_Home 7580366
set mom_Home 13442930
@@ -488,8 +488,8 @@ Motor mf1 $motor_driver_type [params \
maxDecel 1\
stepsPerX 20000\
absEnc 1\
absEncHome 350\
cntsPerX 14000]
absEncHome 1311\
cntsPerX 15593]
setHomeandRange -motor mf1 -home 0 -lowrange 0 -uprange 1
mf1 speed 0.1
mf1 movecount $move_count

View File

@@ -1 +1,4 @@
source $cfPath(nexus)/nxscripts_common_1.tcl
proc ::nexus::isc_initialize {} {
::nexus::ic_initialize
}

View File

@@ -17,10 +17,36 @@ proc ::histogram_memory::init_OAT_TABLE {} {
proc ::histogram_memory::pre_count {} {}
proc ::histogram_memory::post_count {} {}
proc ::histogram_memory::mk_hmm_corrected {} {
if {$::sim_mode == "true"} {
MakeHM hmm_xy_corrected SIM
MakeHM hmm_x_corrected SIM
} else {
MakeHM hmm_xy_corrected anstohttp
MakeHM hmm_x_corrected anstohttp
}
hmm_xy_corrected configure rank 2
hmm_xy_corrected configure READ_DATA_UNCAL_CAL CALIBRATED
hmm_xy_corrected configure READ_DATA_TYPE TOTAL_HISTOGRAM_XY
hmm_xy_corrected configure dim0 421
hmm_xy_corrected configure dim1 421
hmm_xy_corrected configure init 0
hmm_xy_corrected init
hmm_x_corrected configure rank 1
hmm_x_corrected configure READ_DATA_UNCAL_CAL CALIBRATED
hmm_x_corrected configure READ_DATA_TYPE TOTAL_HISTOGRAM_X
hmm_x_corrected configure dim0 421
hmm_x_corrected configure init 0
hmm_x_corrected init
}
proc ::histogram_memory::isc_initialize {} {
if [ catch {
::histogram_memory::init_hmm_objs
::histogram_memory::mk_hmm_corrected
if {$::sim_mode == "true"} {
hmm configure oat_ntc_eff 1
hmm configure oat_nyc_eff 421

View File

@@ -161,7 +161,7 @@ mphi speed 1
mphi movecount $move_count
mphi precision 0.01
mphi part crystal
mphi long_name phi
mphi long_name mphi
# Monochromator chi, Tilt 2, lower
Motor mchi $motor_driver_type [params \
@@ -182,7 +182,7 @@ mchi speed 1
mchi movecount $move_count
mchi precision 0.01
mchi part crystal
mchi long_name chi
mchi long_name mchi
# Monochromator Trans 1, upper
Motor mx $motor_driver_type [params \
@@ -203,7 +203,7 @@ mx speed 1
mx movecount $move_count
mx precision 0.01
mx part crystal
mx long_name translate_y
mx long_name mx
# Monochromator Trans 2, lower
Motor my $motor_driver_type [params \
@@ -224,7 +224,7 @@ my speed 1
my movecount $move_count
my precision 0.01
my part crystal
my long_name translate_x
my long_name my
# Monochromator omega, rotate
# Ref pos has lower tilt dial facing mono drum door for mom=0
@@ -246,7 +246,7 @@ mom speed 1
mom movecount $move_count
mom precision 0.01
mom part crystal
mom long_name rotate
mom long_name mom
# Monochromator two-theta, flight-tube rotate
Motor mtth $motor_driver_type [params \
@@ -280,7 +280,7 @@ mtth blockage_check_interval 5
mtth blockage_thresh 0.10
mtth blockage_ratio 400
mtth part crystal
mtth long_name takeoff_angle
mtth long_name mtth
############################
# Motor Controller 2
@@ -315,7 +315,7 @@ sz blockage_ratio 5
sz Precision 0.1
sz Creep_Offset 1
sz Creep_Precision 0.01
sz long_name translate_z
sz long_name sz
# Sample Trans, vertical, second stage
#Motor sz2 $motor_driver_type [params \
@@ -332,7 +332,7 @@ sz long_name translate_z
#sz2 speed 1
#sz2 precision 0.01
#sz2 part sample.second
#sz2 long_name vertical_translation
#sz2 long_name sz2
} else {
# Temporary Tiny Translation Thingy
set sz_home 800000
@@ -359,7 +359,7 @@ sz backlash_offset -1
sz blockage_ratio 5
sz precision 0.025
sz creep_offset 0.1
sz long_name translate_z
sz long_name sz
}
# Sample Trans 1, upper, x
@@ -392,7 +392,7 @@ sx decel 1.0
sx movecount $move_count
sx precision 0.01
sx part sample
sx long_name translate_x
sx long_name sx
sx backlash_offset -5
sx creep_offset 0.5
@@ -432,7 +432,7 @@ sy decel 1.0
sy movecount $move_count
sy precision 0.01
sy part sample
sy long_name translate_y
sy long_name sy
sy backlash_offset -5
sy creep_offset 0.5
@@ -457,7 +457,7 @@ som accel 0.1
som decel 0.1
som precision 0.01
som part sample
som long_name rotate
som long_name som
# Sample two-theta, detector rotate
Motor stth $motor_driver_type [params \
@@ -482,7 +482,7 @@ stth movecount $move_count
stth precision 0.005
stth maxretry 6
stth part sample
stth long_name azimuthal_angle
stth long_name stth
stth Backlash_offset 0.3
@@ -517,7 +517,7 @@ mf1 speed 0.1
mf1 movecount $move_count
mf1 precision 0.01
mf1 part monochromator.focus
mf1 long_name horizontal
mf1 long_name mf1
mf1 creep_offset 1
mf1 Backlash_offset -0.03
@@ -542,7 +542,7 @@ mf2 speed 0.1
mf2 movecount $move_count
mf2 precision 0.01
mf2 part monochromator.focus
mf2 long_name vertical
mf2 long_name mf2
mf2 creep_offset 1
## Eulerian-chi
@@ -595,7 +595,7 @@ Motor psho $motor_driver_type [params \
psho speed 4
psho Backlash_offset -0.3
psho part slits.primary
psho long_name horizontal_offset
psho long_name psho
setHomeandRange -motor psho -home 0 -lowrange 0 -uprange 30
# Primary Slit, position 0-150mm (Y-axis)
@@ -615,7 +615,7 @@ Motor psp $motor_driver_type [params \
psp speed 4
psp Backlash_offset -0.3
psp part slits.primary
psp long_name position
psp long_name psp
setHomeandRange -motor psp -home 0 -lowrange 0 -uprange 150
# Primary Slit, width, 0-30mm
@@ -635,7 +635,7 @@ Motor psw $motor_driver_type [params \
psw speed 4
psw Backlash_offset 0.3
psw part slits.primary
psw long_name width
psw long_name psw
setHomeandRange -motor psw -home 0 -lowrange 0 -uprange 30
#--------------------------------------------------------
@@ -662,7 +662,7 @@ setHomeandRange -motor psw -home 0 -lowrange 0 -uprange 30
#eom movecount $move_count
#eom precision 0.01
#eom part sample
#eom long_name euler_omega
#eom long_name eom
# Sample Tilt 2, euler chi stage
#Motor echi $motor_driver_type [params \
@@ -686,7 +686,7 @@ setHomeandRange -motor psw -home 0 -lowrange 0 -uprange 30
#echi movecount $move_count
#echi precision 0.01
#echi part sample
#echi long_name euler_chi
#echi long_name echi
# Sample Tilt 2, euler phi stage
#Motor ephi $motor_driver_type [params \
@@ -710,7 +710,7 @@ setHomeandRange -motor psw -home 0 -lowrange 0 -uprange 30
#ephi movecount $move_count
#ephi precision 0.01
#ephi part sample
#ephi long_name euler_phi
#ephi long_name ephi
@@ -731,7 +731,7 @@ Motor ssho $motor_driver_type [params \
ssho speed 4
ssho Backlash_offset -0.3
ssho part slits.secondary
ssho long_name horizontal_offset
ssho long_name ssho
setHomeandRange -motor ssho -home 0 -lowrange 0 -uprange 30
# Secondary Slit, position
@@ -751,7 +751,7 @@ Motor ssp $motor_driver_type [params \
ssp speed 4
ssp Backlash_offset -0.3
ssp part slits.secondary
ssp long_name position
ssp long_name ssp
setHomeandRange -motor ssp -home 0 -lowrange 0 -uprange 150
# Secondary Slit, width
@@ -771,7 +771,7 @@ Motor ssw $motor_driver_type [params \
ssw speed 4
ssw Backlash_offset 0.3
ssw part slits.secondary
ssw long_name width
ssw long_name ssw
setHomeandRange -motor ssw -home 0 -lowrange 0 -uprange 30
## Primary Slit, height, 0-30mm
@@ -789,7 +789,7 @@ setHomeandRange -motor ssw -home 0 -lowrange 0 -uprange 30
# absenchome 542093\
# cntsPerX 8192]
#psh part slits.primary
#psh part long_name height
#psh long_name psh
#setHomeandRange -motor psh -home 0 -lowrange 0 -uprange 30
## Secondary Slit, height
@@ -807,7 +807,7 @@ setHomeandRange -motor ssw -home 0 -lowrange 0 -uprange 30
# absenchome 500000\
# cntsPerX 8192]
#ssh part slits.secondary
#ssh long_name height
#ssh long_name ssh
#setHomeandRange -motor ssh -home 0 -lowrange 0 -uprange 30
#--------------------------------------------------------
@@ -821,7 +821,7 @@ mth readscript mthGet
mth drivescript mthSet
sicslist setatt mth klass crystal
sicslist setatt mth units degrees
sicslist setatt mth long_name half_takeoff_angle
sicslist setatt mth long_name mth
proc sthGet {} { return [expr [SplitReply [stth]]/2.0]}
proc sthSet {val} { return "stth=[SplitReply [stth]]"}
@@ -832,7 +832,7 @@ sth readscript sthGet
sth drivescript sthSet
sicslist setatt sth klass sample
sicslist setatt sth units degrees
sicslist setatt sth long_name half_azimuthal_angle
sicslist setatt sth long_name sth
#--------------------------------------------------------

View File

@@ -1 +1,7 @@
source $cfPath(nexus)/nxscripts_common_1.tcl
proc ::nexus::isc_initialize {} {
variable histmem_filetype_spec
lappend histmem_filetype_spec(HISTOGRAM_XY) link {aux_data 3 hmm_xy_corrected}
lappend histmem_filetype_spec(HISTOGRAM_X) link {aux_data 3 hmm_x_corrected}
::nexus::ic_initialize
}

View File

@@ -12,3 +12,5 @@ config/scan/scan_common_1.tcl
config/nexus/nxscripts_common_1.tcl
config/commands/commands_common.tcl
config/motors/sct_positmotor_common.tcl
config/environment/temperature/sct_julabo_lh45.tcl
config/environment/temperature/config/lakeshore340_common.tcl

View File

@@ -39,11 +39,11 @@ namespace eval optics {
##############################
##
# @brief set_guide uses a lookup table to setup the collimation system
# @brief The "guide" command uses a lookup table to setup the collimation system
# @param row, selects a row from the guide configuration table
#
# eg\n
# set_guide HIRES
# guide ga
command guide "
text=[join [array names ::optics::guide_configuration] , ] configuration
" {
@@ -51,22 +51,16 @@ namespace eval optics {
variable guide_configuration
variable guide_configuration_columns
if [ catch {
array set c1_map {G 1 MT 2 P 3}
array set c2_map {MT 1 G 2 A 3}
array set c3_map {MT 1 G 2 A 3}
array set c4_map {MT 1 G 2 A 3}
array set c5_map {MT 1 G 2 A 3}
array set c6_map {MT 1 G 2 A 3}
array set c7_map {MT 1 G 2 A 3}
array set c8_map {MT 1 G 2 A 3}
array set c9_map {LP 1 MT 2 G 3 A 4 L 5}
foreach el $guide_configuration($configuration) guide $guide_configuration_columns {
lappend to_config $guide
lappend to_config [set ${guide}_map($el)]
foreach {compselection position} $guide_configuration($configuration) {
foreach el $compselection guide $guide_configuration_columns {
lappend to_config $guide
lappend to_config [set ::optics::${guide}_map($el)]
}
::optics::guide -set feedback status BUSY
set msg [eval "drive $to_config"]
EApPosYmm $position
}
::optics::guide -set feedback status BUSY
eval "drive $to_config"
} message ] {
::optics::guide -set feedback status IDLE
if {$::errorCode=="NONE"} {return $message}

View File

@@ -38,7 +38,9 @@ proc ::histogram_memory::isc_initialize {} {
::histogram_memory::ic_initialize
detector_active_height_mm 980
detector_active_width_mm 980
detector_active_width_mm [expr 5.08 * 192]
detector_active_height_mm lock
detector_active_width_mm lock
# hmm configure FAT_SIMULATED_EVENT_Y0 $y_bb0
# hmm configure FAT_SIMULATED_EVENT_Y1 $ybbmax
@@ -47,8 +49,8 @@ proc ::histogram_memory::isc_initialize {} {
::histogram_memory::init_OAT_TABLE
::histogram_memory::upload_config Filler_defaults
::nexus::data alias ::histogram_memory::vertical_axis ::histogram_memory::y_bin
::nexus::data alias ::histogram_memory::horizontal_axis ::histogram_memory::x_bin
::nexus::data alias ::histogram_memory::vertical_axis ::histogram_memory::y_pixel_offset
::nexus::data alias ::histogram_memory::horizontal_axis ::histogram_memory::x_pixel_offset
} message ] {
if {$::errorCode=="NONE"} {return $message}
return -code error $message

View File

@@ -1,5 +1,5 @@
# $Revision: 1.26 $
# $Date: 2008-11-03 08:59:56 $
# $Revision: 1.27 $
# $Date: 2009-03-30 23:16:53 $
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Last revision by: $Author: ffr $
@@ -47,16 +47,16 @@ set bs45_gear 110.0
set bs123_gear 160.0
#set bs45_gear 160.0
#set bs123_gear 110.0
set bs124sign -1
set bs35sign 1
set bs125sign -1
set bs34sign 1
#Measured absolute encoder reading at home position
set samchi_Home 7808328
set samphi_Home 7675008
set samx_Home 7414223
set samx_Home 7420441
set samy_Home 7101486
set samz_Home 9944901
set samthet_Home 22997883
set samthet_Home 23004075
set det_Home 7055209
set detoff_Home 6932100
@@ -67,7 +67,7 @@ set pent_Home 8123563
#set srce_Home 7826986
#set srce_Home 7518434
set srce_Home 7518652
set apx_Home 7500000
set apx_Home 12965422
set apz_Home 7500000
set att_Home 24782942
@@ -374,8 +374,8 @@ Motor det $motor_driver_type [params \
action MC1\
axis G\
units mm\
hardlowerlim 350\
hardupperlim 19000\
hardlowerlim 320\
hardupperlim 19345\
maxSpeed 40\
maxAccel 5\
maxDecel 10\
@@ -386,8 +386,8 @@ Motor det $motor_driver_type [params \
det part detector
det long_name detector_y
det precision 1
det softlowerlim 400
det softupperlim 18900
det softlowerlim 350
det softupperlim 19330
det home 350.5
det speed 20
det Blockage_Fail 0
@@ -401,7 +401,7 @@ Motor detoff $motor_driver_type [params \
axis H\
units mm\
hardlowerlim -50\
hardupperlim 450\
hardupperlim 420\
maxSpeed 10\
maxAccel 1\
maxDecel 10\
@@ -412,7 +412,7 @@ Motor detoff $motor_driver_type [params \
detoff part detector
detoff long_name detector_x
detoff softlowerlim -50
detoff softupperlim 450
detoff softupperlim 410
detoff home 0
############################
@@ -754,19 +754,21 @@ Motor apx $motor_driver_type [params \
port pmc3-quokka\
axis E\
units mm\
hardlowerlim -10\
hardupperlim 360\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX 25000\
hardlowerlim -260\
hardupperlim 5\
maxSpeed 5\
maxAccel 5\
maxDecel 5\
stepsPerX 2500\
absEnc 1\
absEncHome $apx_Home\
cntsPerX -8192]
cntsPerX -819.2]
apx part collimator
apx long_name apx
setHomeandRange -motor apx -home 0 -lowrange -10 -uprange 360
apx speed 1
apx home 0
apx softlowerlim -255
apx softupperlim 5
apx speed 5
# Sample aperture y
Motor apz $motor_driver_type [params \
@@ -848,7 +850,7 @@ Motor bsz $motor_driver_type [params \
axis B\
units mm\
hardlowerlim -240\
hardupperlim 100\
hardupperlim 85\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
@@ -859,118 +861,18 @@ Motor bsz $motor_driver_type [params \
bsz part detector
bsz long_name bsz
bsz softlowerlim -240
bsz softupperlim 100
bsz softupperlim 80
bsz home 0
if {1} {
# largest to smallest
# MakeActionObject obj aQ JG-speed upsw downsw axis
MakeActionObject bs1 mc4 [expr $bs124sign*$bs_steps_per_rev*$bs1gear/360.0] 8 4 C
MakeActionObject bs2 mc4 [expr $bs124sign*$bs_steps_per_rev*$bs2gear/360.0] 8 4 D
MakeActionObject bs3 mc4 [expr $bs35sign*$bs_steps_per_rev*$bs3gear/360.0] 4 8 E
MakeActionObject bs4 mc4 [expr $bs124sign*$bs_steps_per_rev*$bs4gear/360.0] 8 4 F
MakeActionObject bs5 mc4 [expr $bs35sign*$bs_steps_per_rev*$bs5gear/360.0] 4 8 G
MakeActionObject bs1 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs1gear/360.0] 8 4 C
MakeActionObject bs2 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs2gear/360.0] 8 4 D
MakeActionObject bs3 mc4 [expr $bs34sign*$bs_steps_per_rev*$bs3gear/360.0] 4 8 E
MakeActionObject bs4 mc4 [expr $bs34sign*$bs_steps_per_rev*$bs4gear/360.0] 4 8 F
MakeActionObject bs5 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs5gear/360.0] 8 4 G
} else {
# beam stop disk 5 (smallest)
Motor bs5 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis G\
units mm\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX [expr $bs35sign*$bs_steps_per_rev*$bs5gear/360.0]\
motorHome $bs5_Home]
bs5 part detector
bs5 long_name bs5
bs5 softlowerlim 0
bs5 softupperlim 90
bs5 home 0
# beam stop disk 4
Motor bs4 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis F\
units mm\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX [expr $bs124sign*$bs_steps_per_rev*$bs4gear/360.0]\
motorHome $bs4_Home]
bs4 part detector
bs4 long_name bs4
bs4 softlowerlim 0
bs4 softupperlim 90
bs4 home 0
# beam stop disk 3
Motor bs3 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis E\
units mm\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX [expr $bs35sign*$bs_steps_per_rev*$bs3gear/360.0]\
motorHome $bs3_Home]
bs3 part detector
bs3 long_name bs3
bs3 softlowerlim 0
bs3 softupperlim 90
bs3 home 0
# beam stop disk 2
Motor bs2 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis D\
units mm\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX [expr $bs124sign*$bs_steps_per_rev*$bs2gear/360.0]\
motorHome $bs2_Home]
bs2 part detector
bs2 long_name bs2
bs2 softlowerlim 0
bs2 softupperlim 90
bs2 home 0
# beam stop disk 1 (largest)
Motor bs1 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis C\
units mm\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX [expr $bs124sign*$bs_steps_per_rev*$bs1gear/360.0]\
motorHome $bs1_Home]
bs1 part detector
bs1 long_name bs1
bs1 softlowerlim 0
bs1 softupperlim 90
bs1 home 0
}
# Polarizer Rotation

View File

@@ -11,41 +11,43 @@ makesctcontroller sct_mc4 std mc4:$port4
# label pos
set 20sample_table {
1 453.7
2 411.7
3 369.7
4 327.7
5 285.7
6 203.7
7 161.7
8 119.7
9 77.7
10 35.7
11 -46.3
12 -88.3
13 -130.3
14 -172.3
15 -214.3
16 -296.3
17 -338.3
18 -380.3
19 -422.3
20 -464.3
index position
1 453.7
2 411.7
3 369.7
4 327.7
5 285.7
6 203.7
7 161.7
8 119.7
9 77.7
10 35.7
11 -46.3
12 -88.3
13 -130.3
14 -172.3
15 -214.3
16 -296.3
17 -338.3
18 -380.3
19 -422.3
20 -464.3
}
mk_sct_positmotor sct_mc1 samx changer_position samplenum 20SAMPLES $20sample_table
mk_sct_positmotor sct_mc1 parameter samx changer_position samplenum 20SAMPLES $20sample_table
set auto_ap_table {
2.5 0
5.0 23
7.5 47
10.0 72
12.5 98
15.0 125
17.5 153
20.0 183
25.0 215
30.0 250
thickness_mm position
2.5 0
5.0 -23
7.5 -47
10.0 -72
12.5 -98
15.0 -125
17.5 -153
20.0 -183
25.0 -215
30.0 -250
}
mk_sct_positmotor sct_mc3 apx autoSampleAp aperture auto_ap $auto_ap_table
mk_sct_positmotor sct_mc3 parameter apx autoSampleAp aperture auto_ap $auto_ap_table

View File

@@ -1 +1,11 @@
source $cfPath(nexus)/nxscripts_common_1.tcl
proc ::nexus::isc_initialize {} {
variable histmem_filetype_spec
foreach spec [array names histmem_filetype_spec] {
lappend histmem_filetype_spec($spec) link {aux_data 3 LambdaA}
lappend histmem_filetype_spec($spec) link {aux_data 4 Transmission}
lappend histmem_filetype_spec($spec) link {aux_data 5 ::histogram_memory::x_bin}
lappend histmem_filetype_spec($spec) link {aux_data 6 ::histogram_memory::y_bin}
}
::nexus::ic_initialize
}

View File

@@ -6,40 +6,56 @@
# commands to setup the instrument.
namespace eval optics {
# A configuration table is made up of a set of named rows which provide
# configuration parameters
# Rows can be of mixed type
##
# @brief These arrays map the component identifiers (G, MT, etc) to the
# position index for each guide motor (c1, c2 ... c9)
array set c1_map {G 1 MT 2 P 3}
array set c2_map {MT 1 G 2 A 3}
array set c3_map {MT 1 G 2 A 3}
array set c4_map {MT 1 G 2 A 3}
array set c5_map {MT 1 G 2 A 3}
array set c6_map {MT 1 G 2 A 3}
array set c7_map {MT 1 G 2 A 3}
array set c8_map {MT 1 G 2 A 3}
array set c9_map {L 1 MT 2 G 3 A 4 LP 5}
# The guide configuration table is indexed by a configuration
# identifier (ga, mt, lp, etc). Each row has two elements,
# 1. A list of components selected for each guide (MT A ... etc)
# 2. The entrance aperature position in mm
# Eg $guide_configuration(p2) returns the following list
# {{P G A A A A A A A } 6934}
array set guide_configuration {
ga {MT A A A A A A A A }
mt {MT MT MT MT MT MT MT MT MT }
lp {MT MT MT MT MT MT MT MT LP }
lens {MT MT MT MT MT MT MT MT L }
p1 {P A MT MT MT MT MT MT MT }
p1lp {P A MT MT MT MT MT MT LP }
p1lens {P A MT MT MT MT MT MT L }
g1 {G A A A A A A A A }
p2 {P G A A A A A A A }
g2 {G G A A A A A A A }
p3 {P G G A A A A A A }
g3 {G G G A A A A A A }
p4 {P G G G A A A A A }
g4 {G G G G A A A A A }
p5 {P G G G G A A A A }
g5 {G G G G G A A A A }
p6 {P G G G G G A A A }
g6 {G G G G G G A A A }
p7 {P G G G G G G A A }
g7 {G G G G G G G A A }
p8 {P G G G G G G G A }
g8 {G G G G G G G G A }
p9 {P G G G G G G G G }
g9 {G G G G G G G G G }
ga {{MT A A A A A A A A } 675}
mt {{MT MT MT MT MT MT MT MT MT} 675}
lp {{MT MT MT MT MT MT MT MT LP} 675}
lens {{MT MT MT MT MT MT MT MT L } 675}
p1 {{P A MT MT MT MT MT MT MT} 675}
p1lp {{P A MT MT MT MT MT MT LP} 675}
p1lens {{P A MT MT MT MT MT MT L } 675}
g1 {{G A A A A A A A A } 4929}
p2 {{P G A A A A A A A } 6934}
g2 {{G G A A A A A A A } 6934}
p3 {{P G G A A A A A A } 8949}
g3 {{G G G A A A A A A } 8949}
p4 {{P G G G A A A A A } 10955}
g4 {{G G G G A A A A A } 10955}
p5 {{P G G G G A A A A } 12943}
g5 {{G G G G G A A A A } 12943}
p6 {{P G G G G G A A A } 14970}
g6 {{G G G G G G A A A } 14970}
p7 {{P G G G G G G A A } 16971}
g7 {{G G G G G G G A A } 16971}
p8 {{P G G G G G G G A } 18937}
g8 {{G G G G G G G G A } 18937}
p9 {{P G G G G G G G G } 19925}
g9 {{G G G G G G G G G } 19925}
}
# This list maps the motor names to columns of the
# guide_configuration table.
set guide_configuration_columns {
c1 c2 c3 c4 c5 c6 c7 c8 c9
c1 c2 c3 c4 c5 c6 c7 c8 c9
}
}
@@ -47,5 +63,4 @@ set guide_configuration_columns {
namespace eval optics {
variable guide_configuration
variable guide_configuration_columns
namespace export set_guide
}

View File

@@ -18,11 +18,16 @@ foreach {var lname nxname} {
##
# @brief User privilege text variables
#
foreach {var lname nxname priv klass} {
SApShape SApShape shape user parameter
BSShape BSShape shape user parameter
foreach {var lname type nxname priv units klass} {
SApShape SApShape text shape user none parameter
BSShape BSShape text shape user none parameter
SampleThickness thickness float thickness user mm sample
TransmissionFlag transmission_flag int transmission user none sample
} {
::utility::mkVar $var text $priv $lname true $klass true true
::utility::mkVar $var $type $priv $lname true $klass true true
if {$units != "none"} {
sicslist setatt $var units $units
}
}
##
@@ -46,7 +51,7 @@ foreach {var lname nxname units klass} {
##
# @brief Parameter SicsVariables
foreach {var lname nxname units priv } {
LambdaA LambdaA wavelength nm user
LambdaA LambdaA wavelength Ao user
LambdaResFWHM_percent LambdaResFWHM_percent wavelength_spread 1 user
VSdeg VSdeg twist degrees user
VSrpm VSrpm rotation_speed rpm user
@@ -58,7 +63,7 @@ foreach {var lname nxname units priv } {
SApPosYmm SApPosYmm y mm user
SApPosZmm SApPosZmm z mm user
SamplePosXmm SamplePosXmm x mm user
SamplePosYmm SamplePosYmm y mm user
SamYOffsetmm SamYOffsetmm y mm user
SamplePosZmm SamplePosZmm z mm user
DetPosYOffsetmm DetPosYOffsetmm detposyoffset mm user
BSXmm BSXmm x mm user
@@ -91,11 +96,21 @@ foreach {var type lname units depends} {
}
}
proc sicsmsgfmt {args} {return "[info level -1] = $args"}
::utility::macro::getset float SamplePosYmm {} {
set sy [SplitReply [samy]]
set syo [SplitReply [SamYOffsetmm]]
return [sicsmsgfmt [expr {$sy+$syo}]]
}
sicslist setatt SamplePosYmm long_name SamplePosYmm
sicslist setatt SamplePosYmm klass derived_parameter
sicslist setatt SamplePosYmm units mm
sicslist setatt SamplePosYmm depends samy,SamYOffsetmm
::utility::macro::getset float L1mm {} {
set efpy [SplitReply [EndFacePosYmm]]
set sapy [SplitReply [SApPosYmm]]
set samposy [SplitReply [SamplePosYmm]]
set eapy [SplitReply [EApPosYmm]]
return [sicsmsgfmt [expr {$efpy + $sapy - $eapy}]]
return [sicsmsgfmt [expr {$efpy + $samposy - $eapy}]]
}
sicslist setatt L1mm long_name L1mm
sicslist setatt L1mm klass derived_parameter
@@ -210,12 +225,12 @@ foreach {pname motor units} {
##
# @brief This is the position of the velocity selector bunker face. It is used
# as the reference for other positions. x=y=z=0.
::hdb::MakeVelocity_Selector velocity_selector {
wavelength LambdaA
wavelength_spread LambdaResFWHM_percent
coordinate_scheme VelSelCoordScheme
position {VelSelPosXmm VelSelPosYmm VelSelPosZmm}
}
#::hdb::MakeVelocity_Selector velocity_selector {
# wavelength LambdaA
# wavelength_spread LambdaResFWHM_percent
# coordinate_scheme VelSelCoordScheme
# position {VelSelPosXmm VelSelPosYmm VelSelPosZmm}
#}
::hdb::MakeAperture sample_aperture {
shape SApShape
@@ -340,7 +355,6 @@ namespace eval parameters {
SampleNum
SamplePosXmm
SamplePosYmm
SamplePosYmm
SamplePosZmm
SampleRotDeg
SampleTiltXDeg
@@ -348,7 +362,6 @@ namespace eval parameters {
SampleTitle
SApPosXmm
SApPosYmm
SApPosYmm
SApPosZmm
SApShape
SApXmm
@@ -385,3 +398,18 @@ proc check {args} {
}
}
publish check user
foreach {pname bsname} {
beamstop110 bs1
beamstop88 bs2
beamstop66 bs3
beamstop44 bs4
beamstop22 bs5
} {
::utility::macro::getset text $pname {} [subst -nocommands {
return [$bsname status]
}]
sicslist setatt $pname long_name $pname
sicslist setatt $pname mutable false
sicslist setatt $pname klass derived_parameter
}

View File

@@ -0,0 +1,191 @@
##
# @file
# The velocity selector control is split into two objects,
# 1. velsel_poller: This object polls the velocity selector to get its
# current state.
# 2. velsel: This object provides manages a set of status nodes which
# correspond to the state parameters read by the velsel_poller object.
# It also provides commands to set the speed and angle for the velocity
# selector.
# Test by adding the following to barebones.tcl
# InstallHdb
# source config/velsel/sct_velsel.tcl
# hfactory /velsel link velsel
# The velocity selector doesn't close client connections
# if the connection is broken. It only closes the connection
# when a client logs off with "#SES#bye", NOTE bye must be lowercase.
makesctcontroller sct_velsel astvelsel 137.157.202.73:10000 "" 10
sct_velsel transact "NVS"
sct_velsel transact "NVS"
namespace eval ::scobj::velsel {
variable paramindex
variable paramtype
variable pollrate
set pollrate 7
array set paramindex {
state 0
rspeed 1
aspeed 2
sspeed 3
aveto 4
ploss 5
splos 6
ttang 7
rtemp 8
wflow 9
winlt 10
woutt 11
vacum 12
wvalv 13
vvalv 14
vibrt 15
bcuun 16
}
array set paramtype {
state text
rspeed float
aspeed float
sspeed float
aveto text
ploss float
splos float
ttang float
rtemp float
wflow float
winlt float
woutt float
vacum float
wvalv text
vvalv text
vibrt float
bcuun float
}
MakeSICSObj velsel_poller SCT_OBJECT
MakeSICSObj velsel SCT_OBJECT
sicslist setatt velsel klass NXvelocity_selector
sicslist setatt velsel long_name velsel
##
# @brief Request a state report from the velocity selector
proc getStatus {} {
sct send "#SOS#STATE "
return rdStatus
}
##
# @brief Read the current state report from the velocity selector.
proc rdStatus {} {
set data [sct result]
if {$data != [sct oldval]} {
sct oldval $data
set status [lrange [split $data "#"] 3 end-1]
sct update $status
sct utime readtime
}
return idle
}
##
# @brief This dummy read command forces a transition to a state which
# will update a parameter from the current status.
proc getpar {nextstate} {
return $nextstate
}
proc noResponse {} {
sct result
return idle
}
##
# @brief Looks up a parameter in the current status and updates the
# parameter node.
# @param statuspath, path to the poller object's status node.
# @param parindex, index of the required parameter
proc updatepar {statuspath parindex} {
set data [lindex [hval $statuspath] $parindex end]
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
}
return idle
}
proc setSpeed {nextState} {
set speed [format "%5d" [sct target]]
sct send "#SOS#SPEED $speed"
return $nextState
}
proc setState {nextState} {
set state [string tolower [sct target]]
switch $state {
"idle" {
sct send "#SOS#IDLE "
}
"brake" {
sct send "#SOS#BRAKE "
}
default {
return idle
}
}
return $nextState
}
hfactory /sics/velsel_poller/status plain internal text
hsetprop /sics/velsel_poller/status read ::scobj::velsel::getStatus
hsetprop /sics/velsel_poller/status rdStatus ::scobj::velsel::rdStatus
hsetprop /sics/velsel_poller/status oldval UNKNOWN
sct_velsel poll /sics/velsel_poller/status $pollrate halt read
hfactory /sics/velsel/LambdaA plain user float
hfactory /sics/velsel/LambdaResFWHM_percent plain user float
foreach par [lsort [array names paramindex]] {
hfactory /sics/velsel/$par plain spy $paramtype($par)
hsetprop /sics/velsel/$par read ::scobj::velsel::getpar rdpar
hsetprop /sics/velsel/$par rdpar ::scobj::velsel::updatepar /sics/velsel_poller/status $paramindex($par)
hsetprop /sics/velsel/$par oldval UNKNOWN
sct_velsel poll /sics/velsel/$par $pollrate
}
hfactory /sics/velsel/setspeed plain spy $paramtype($par)
hsetprop /sics/velsel/setspeed write ::scobj::velsel::setSpeed ignore
hsetprop /sics/velsel/setspeed ignore ::scobj::velsel::noResponse
sct_velsel write /sics/velsel/setspeed
hfactory /sics/velsel/setstate plain spy $paramtype($par)
hsetprop /sics/velsel/setstate write ::scobj::velsel::setState ignore
hsetprop /sics/velsel/setstate ignore ::scobj::velsel::noResponse
sct_velsel write /sics/velsel/setstate
::scobj::hinitprops velsel
hsetprop /sics/velsel klass NXvelocity_selector
hsetprop /sics/velsel privilege spy
hsetprop /sics/velsel type part
::scobj::set_required_props /sics/velsel
foreach {hpath klass priv alias} {
LambdaA parameter user velsel_lambdaa
LambdaResFWHM_percent parameter user velsel_lambdaresfwhm_percent
rspeed parameter user velsel_rspeed
aspeed parameter user velsel_aspeed
ttang parameter user velsel_ttang
} {
hsetprop /sics/velsel/$hpath nxalias $alias
hsetprop /sics/velsel/$hpath klass $klass
hsetprop /sics/velsel/$hpath privilege $priv
hsetprop /sics/velsel/$hpath control true
hsetprop /sics/velsel/$hpath data true
hsetprop /sics/velsel/$hpath nxsave true
hsetprop /sics/velsel/$hpath mutable true
hsetprop /sics/velsel/$hpath sdsinfo ::nexus::scobj::sdsinfo
}
}

View File

@@ -1,7 +1,7 @@
# SICS common configuration
# $Revision: 1.46 $
# $Date: 2008-12-12 06:53:47 $
# $Revision: 1.47 $
# $Date: 2009-03-30 23:16:52 $
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Last revision by $Author: ffr $
# RELEASE_NUMBER: $Name: not supported by cvs2svn $
@@ -141,7 +141,7 @@ sics_release [lindex $tmpstr [expr [llength $tmpstr] - 1]]
sics_release lock
::utility::mkVar sics_revision_num Text internal
set tmpstr [string map {"$" ""} {$Revision: 1.46 $}]
set tmpstr [string map {"$" ""} {$Revision: 1.47 $}]
sics_revision_num [lindex $tmpstr [expr [llength $tmpstr] - 1]]
sics_revision_num lock
@@ -219,7 +219,7 @@ proc server_set_sobj_attributes {} {
::histogram_memory::set_sobj_attributes
::utility::set_chopper_attributes
::utility::set_sctobj_attributes
::utility::set_sct_posit_motor_attributes
::utility::set_sct_object_attributes
## TODO move the following to the new ansto gumxml.tcl
sicslist setatt getgumtreexml privilege internal
clientput "serverport [get_portnum $::serverport]"
@@ -237,6 +237,7 @@ proc server_init {} {
::scan::isc_initialize
::anticollider::init
::commands::isc_initialize
::nexus::isc_initialize
########
# Parameters set above the restore command will be clobbered by
# the values in the status.tcl file

View File

@@ -1,4 +1,10 @@
namespace eval ::scobj { }
proc ::scobj::set_required_props {hpath} {
foreach child [hlist $hpath] {
hsetprop $hpath/$child data false
::scobj::set_required_props $hpath/$child
}
}
##
# @brief Initialise the hdb properties required for generating the GumTree interface and
# saving data for script context objects
@@ -17,6 +23,6 @@ proc ::scobj::hinitprops {scobj {par "@none"}} {
hsetprop $hpath nxsave true
hsetprop $hpath mutable true
hsetprop $hpath klass parameter
hsetprop $hpath sicsdev $scobj
# hsetprop $hpath sicsdev $scobj
hsetprop $hpath sdsinfo ::nexus::scobj::sdsinfo
}

View File

@@ -1,7 +1,7 @@
# Some useful functions for SICS configuration.
# $Revision: 1.20 $
# $Date: 2008-12-12 06:53:53 $
# $Revision: 1.21 $
# $Date: 2009-03-30 23:16:54 $
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Last revision by $Author: ffr $
@@ -441,14 +441,14 @@ proc ::utility::set_sctobj_attributes {} {
hsetprop /$sobj data false
}
}
proc ::utility::set_sct_posit_motor_attributes {} {
foreach sobj [sicslist type SCT_POSIT_MOTOR] {
sicslist setatt $sobj klass parameter
proc ::utility::set_sct_object_attributes {} {
foreach sobj [sicslist type SCT_OBJECT] {
sicslist setatt $sobj data true
sicslist setatt $sobj control true
sicslist setatt $sobj nxsave true
sicslist setatt $sobj mutable true
sicslist setatt $sobj privilege user
sicslist setatt $sobj kind scobj
}
}
proc ::utility::set_motor_attributes {} {
@@ -534,7 +534,7 @@ proc ::utility::hgetplainprop {hpath prop} {
}
proc ::utility::hlistplainprop {hpath} {
if [ catch {
return [string trim [join [split [string map {" " _} [hlistprop $hpath]] =] ]]
return [string trim [join [split [string map {" " _} [regsub {[^
]*= *
} [hlistprop $hpath] {} ]] =] ]]
} message ] {

282
site_ansto/sctemonadapter.c Normal file
View File

@@ -0,0 +1,282 @@
/**
* --------------------------------------------------------------*/
#include <sics.h>
#include <sicshipadaba.h>
#include <devser.h>
#include <tcl.h>
#include <macro.h>
#include <sicsobj.h>
#include "scriptcontext.h"
/*---------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pIDrivable pDrivInt; /* Need a drivable interface for "emon list" */
pEVInterface pEVI;
EVMode eMode;
int iPaused;
char *pName;
pHdb modeNode, tolNode, errNode;
}SctEmon, *pSctEmon;
/* emon will monitor when mode is "monitor" or "paused" */
/* XXX nopause
static char *modestr[5] = {"idle", "drive", "monitor", "error", "paused"};
static int EVPaused=4;*/
/*---------------------------------------------------------------*/
/**
@brief a dummy getvalue command to prevent "emon list" from aborting SICS
*/
static float SCTEmonGetValue(void *pData, SConnection *pCon)
{
return -999.666;
}
/* XXX nopause
static void SetModeNode(pSctEmon self, EVMode mode)
{
if (self->modeNode->value.v.text != NULL)
free(self->modeNode->value.v.text);
self->modeNode->value.v.text = strdup(modestr[mode]);
}
*/
static void *SCTEmonGetInterface(void *pData, int ID){
pSctEmon self = NULL;
self = (pSctEmon)pData;
assert(self);
if (self->modeNode == NULL || self->tolNode == NULL || self->errNode == NULL)
return NULL;
switch (ID) {
case DRIVEID:
return self->pDrivInt;
case ENVIRINTERFACE:
return self->pEVI;
default:
return NULL;
}
}
/*----------------------------------------------------------------
Reads node value and returns EVMode
Convert mode string from the evmode textnode value to
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
"idle", "drive", "monitor", "error"
------------------------------------------------------------------*/
static EVMode SCTEmonGetMode(void *pData)
{
pSctEmon self = NULL;
self = (pSctEmon)pData;
assert(self);
switch(self->modeNode->value.v.text[0]) {
case 'I':
case 'i':
return EVIdle;
break;
case 'D':
case 'd':
return EVDrive;
break;
case 'M':
case 'm':
/*XXX nopause case 'P':
case 'p':*/
return EVMonitor;
break;
case 'E':
case 'e':
return EVError;
break;
default:
return EVIdle;
//TODO Handle error
}
}
/*----------------------------------------------------------------
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
Reads value from the "isintolerance" node (1 or 0)
------------------------------------------------------------------*/
static int SCTEmonIsInTolerance(void *pData)
{
pSctEmon self = NULL;
pExeList pExe;
char pBueffel[512];
char monMode;
self = (pSctEmon)pData;
assert(self);
if(self->tolNode->value.v.intValue == 1) {
monMode = self->modeNode->value.v.text[0];
if (self->iPaused) {
pExe = GetExecutor();
ContinueExecution(pExe);
self->iPaused = 0;
sprintf(pBueffel,"Device %s back in tolerances again", self->pName);
SCWrite(GetExeOwner(pExe), pBueffel, eWarning);
}
//XXX nopause SetModeNode(self, EVMonitor);
return 1;
} else {
return 0;
}
}
/*----------------------------------------------------------------
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
The HandleError node value can be one of Lazy, Pause, Interrupt, Safe
NOTE: emon ignores the returned iStatus value
------------------------------------------------------------------*/
static int SCTEmonHandleError(void *pData)
{
pSctEmon self = NULL;
pExeList pExe;
int iRet, iHandler, iStatus;
char monMode;
self = (pSctEmon)pData;
assert(self);
monMode = self->modeNode->value.v.text[0];
//XXX nopause SetModeNode(self, EVError);
switch(self->errNode->value.v.text[0]) {
case 'l':
case 'L': /* Lazy */
iStatus = 1;
break;
case 'p':
case 'P': /* Pause */
pExe = GetExecutor();
if(IsCounting(pExe)) {
if (!self->iPaused) {
SCWrite(GetExeOwner(pExe),"Pausing till OK",eError);
}
PauseExecution(pExe);
self->iPaused = 1;
//XXX nopause SetModeNode(self, EVPaused);
iStatus = 1;
}
break;
case 'i':
case 'I': /* Interrupt */
/* TODO How is this supposed to work?
SetInterrupt((int)ObVal(self->pParam,INTERRUPT));*/
iStatus = 1;
break;
case 's':
case 'S': /* Safe, run to a safe place, put him into idle afterwards */
/*TODO Drive environment to a safevalue */
break;
default:
return 0;
}
/* NOTE: emon ignores the return value */
return iStatus;
}
/*----------------------------------------------------------------
returns NULL on failure, a new datastructure else
------------------------------------------------------------------*/
static pSctEmon SCTEMONMakeObject(){
pSctEmon self = NULL;
self = calloc(sizeof(SctEmon),1);
if(self == NULL){
return NULL;
}
self->pDes = CreateDescriptor("SctEmonAdapter");
if(self->pDes == NULL) {
free(self);
return NULL;
}
self->pEVI = CreateEVInterface();
if(self->pEVI == NULL) {
DeleteDescriptor(self->pDes);
free(self);
return NULL;
}
self->pDrivInt = CreateDrivableInterface();
if(self->pDrivInt == NULL) {
DeleteDescriptor(self->pDes);
free(self->pEVI);
free(self);
return NULL;
}
self->pDes->GetInterface = SCTEmonGetInterface;
self->pEVI->GetMode = SCTEmonGetMode;
self->pEVI->IsInTolerance = SCTEmonIsInTolerance;
self->pEVI->HandleError = SCTEmonHandleError;
self->pDrivInt->Halt = NULL;
self->pDrivInt->CheckLimits = NULL;
self->pDrivInt->SetValue = NULL;
self->pDrivInt->CheckStatus = NULL;
self->pDrivInt->GetValue = SCTEmonGetValue;
return self;
}
/*----------------------------------------------------------------*/
static hdbCallbackReturn SctDummyCallback(Hdb *node, void *userData,
hdbMessage *msg) {
return hdbContinue;
}
/*----------------------------------------------------------------*/
static void SctEmonDeleteNode(void *pData) {
pSctEmon self = (pSctEmon)pData;
self->modeNode = NULL;
self->tolNode = NULL;
self->errNode = NULL;
}
/*--------------------------------------------------------------
args: name, modepath, tolpath, errpath
*/
int SctMakeEmonAdapter(SConnection *pCon, SicsInterp *pSics, void *object,
int argc, char *argv[]) {
pSctEmon pNew = NULL;
hdbCallback *cb;
if(argc < 5){
SCWrite(pCon,"ERROR: not enough arguments for SctMakeEmonAdapter", eError);
return 0;
}
pNew = SCTEMONMakeObject();
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory in SctMakeEmonAdapter",
eError);
return 0;
}
pNew->pName = strdup(argv[1]);
pNew->modeNode = FindHdbNode(NULL,argv[2], pCon);
pNew->tolNode = FindHdbNode(NULL,argv[3], pCon);
pNew->errNode = FindHdbNode(NULL,argv[4], pCon);
pNew->iPaused = 0;
/*XXX I'm guessing that SctEmonDeleteNode will be called when the
script context object is deleted. So the emon functions should check
if node == NULL before trying to do something */
cb = MakeHipadabaCallback(SctDummyCallback, pNew, SctEmonDeleteNode);
assert(cb);
AppendHipadabaCallback(pNew->modeNode, cb);
EVRegisterController(FindEMON(pSics),argv[1],pNew, pCon);
return 1;
}
/*---------------------------------------------------------------*/
void SctEmonInit(void) {
AddCmd("makesctemon", SctMakeEmonAdapter);
}

View File

@@ -55,6 +55,9 @@ extern int VelSelTcpFactory(SConnection *pCon, SicsInterp *pSics, void *pData, i
extern pCodri MakeTcpDoChoDriver(char *tclArray, SConnection *pCon);
extern void AddGalilProtocoll();
extern void AddOrdHVPSProtocoll();
extern void AddVelSelProtocol();
extern void AddUSBTMCProtocoll();
extern int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
void SiteInit(void) {
@@ -62,8 +65,12 @@ void SiteInit(void) {
NetWatchInit();
#define INIT(F) { void F(void); F(); }
/* insert here initialization routines ... */
INIT(SctEmonInit);
INIT(ANSTO_SctDriveInit);
AddGalilProtocoll();
AddOrdHVPSProtocoll();
AddVelSelProtocol();
AddUSBTMCProtocoll();
}
static pSite /*@null@*/ siteANSTO = NULL;
@@ -88,6 +95,7 @@ static void AddCommands(SicsInterp *pInter)
AddCommand(pInter,"MakeSafetyPLC",SafetyPLCFactory,NULL,NULL);
AddCommand(pInter,"MakeLSSMonitor",LSSFactory,NULL,NULL);
AddCommand(pInter,"MakeActionObject",ActionObjectFactory,NULL,NULL);
AddCommand(pInter,"ANSTO_MakeHM",ANSTO_MakeHistMemory,NULL,NULL);
}
/*---------------------------------------------------------------------*/
static void RemoveCommands(SicsInterp *pSics){