From 4f43bd159f003db3d61d1061785bbde34eb341fb Mon Sep 17 00:00:00 2001 From: MarkRivers Date: Mon, 12 Sep 2005 19:47:53 +0000 Subject: [PATCH] New files for XPS --- motorApp/NewportSrc/XPSGathering.cc | 205 ++++++++++++++ motorApp/NewportSrc/asynOctetSocket.cpp | 342 ++++++++++++++++++++++++ motorApp/NewportSrc/tclCall.cc | 50 ++++ 3 files changed, 597 insertions(+) create mode 100644 motorApp/NewportSrc/XPSGathering.cc create mode 100644 motorApp/NewportSrc/asynOctetSocket.cpp create mode 100644 motorApp/NewportSrc/tclCall.cc diff --git a/motorApp/NewportSrc/XPSGathering.cc b/motorApp/NewportSrc/XPSGathering.cc new file mode 100644 index 00000000..0a62b52c --- /dev/null +++ b/motorApp/NewportSrc/XPSGathering.cc @@ -0,0 +1,205 @@ +/* Prog to test the XPS position gathering and trigger during a trajectory scan*/ +/**/ +#include +/*#include */ +#include "xps_c8_driver.h" +#include "Socket.h" +#include +#include +#include +#define TIMEOUT 1 +#define pline printf("-Debug line %i\n",__LINE__); +#define BUFFER_SIZE 500; + + +/* require xps_c8_driver.cpp with 23rd May bug fix for the + GatheringExternalConfigurationSet command*/ + + +/* Function to ask the XPS for a socket */ +int getsocket(void) +{ + char ipchar[] = "164.54.160.124"; + int socket = 0; + int port = 5001; + + socket = TCP_ConnectToServer(ipchar,port,TIMEOUT); + if (socket < 0) + printf(" Error TCP_ConnectToServer\n"); + return (socket); +} + +void xpsgathering(int inttrajelementperiod) +{ + int status,socket,end =0; + char *gatheringdata= "GROUP1.PHI.ExternalLatchPosition," + "GROUP1.KAPPA.ExternalLatchPosition," + "GROUP1.OMEGA.ExternalLatchPosition," + "GROUP1.PSI.ExternalLatchPosition," + "GROUP1.2THETA.ExternalLatchPosition," + "GROUP1.NU.ExternalLatchPosition"; + + + char positioner[] = "GROUP1.PHI"; + char group[] = "GROUP1"; + char nullchar[] = ""; + char GPIOname[] = "GPIO4.DO"; /* DB15 Connector */ + char pulsemask[] = "63"; /* Defines which pins are pulsed, 63 in base 2 ->111111 */ + /* The trigger pin6 is connected to GPIO4.DO pin 27 (output 1) */ +/* char element[250];*/ + char inputfilename[] = "testtrajectory"; + char outputfilename[500]; + char timer1[250] = "Timer1"; + double maxp,minp,maxv,maxa; + char trajelementperiod[250] ; +/* int inttrajelementperiod = 20000;*/ /* Time defined in trajectory file between moves *1e4 */ + char numtrajelements[] = "10"; /* Number of elements in traj scan*/ + char eventlist[260]; + + printf("You Input %g Seconds For The Period\n",(double) inttrajelementperiod/10000); + + sprintf(trajelementperiod,"%i",inttrajelementperiod); /* Convert to a string */ + + socket = getsocket(); + + /*************************** Verfy trajectory **********************/ + status = MultipleAxesPVTVerification(socket,group,inputfilename); + if (status != 0){ + printf(" Error performing MultipleAxesPVTVerification%i\n Return\n",status); + end = 1; /* Don't Verify */ + } + + /*printf("xpsgathering, socket=%d, timer=%s, period=%d\n", + socket, timer1, inttrajelementperiod);*/ + + status = MultipleAxesPVTVerificationResultGet(socket,positioner,outputfilename, + &minp, &maxp, &maxv, &maxa); + printf(" MultipleAxesPVTVerificationResultGet\n"); + printf(" status %i, ptrmaxp %g, ptrminp %g, ptrmaxv %g, ptrmaxa %g\n outputfilename=%s\n", + status,maxp, minp, maxv, maxa,outputfilename); + + /*printf("xpsgathering, socket=%d, timer=%s, period=%d \n", + socket, timer1, inttrajelementperiod);*/ + if (end == 1) + return; + /***********************Configure Gathering and Timer******************/ + + /* The "1" signifies one type of data collected */ + +printf(" socket=%i, gathering=%s\n",socket,gatheringdata); + + status = GatheringExternalConfigurationSet(socket,1,gatheringdata); + + if (status != 0) + printf(" Error performing GatheringConfigurationSet%i\n",status); + + + status = TimerSet(socket,timer1,inttrajelementperiod); + + if (status != 0) + printf(" Error performing TimerSet %i\n",status); + + /**************************Add Events *****************************/ + + status = EventAdd(socket,positioner,timer1,nullchar, + "DOPulse",GPIOname,pulsemask,nullchar); + if (status != 0) + printf(" Error performing EventAdd(socket,positioner,Timer1=%i\n",status); + + status = EventAdd(socket,positioner,"PVT.TrajectoryStart",nullchar, + "ExternalGatheringRun",numtrajelements,"1",nullchar); + if (status != 0) + printf(" Error performing EventAdd(socket,positioner,PVT.TrajectoryStart %i\n",status); + + status = EventGet(socket,positioner,eventlist); + printf(" EventGet: status=%i list=%s\n",status,eventlist); + + /********************* Run traj ****************************/ + printf("socket=%i group=%s file=%s\n",socket,group,inputfilename); + + status = MultipleAxesPVTExecution(socket,group,inputfilename,1); + if (status != 0) + printf(" Error performing MultipleAxesPVTExecution\%i\n",status); + + /***********************Save the gathered data ***************/ + status = GatheringExternalStopAndSave(socket); + if (status != 0) + printf(" Error performing GatheringExternalStopAndSave\%i\n",status); + + /*******************Tidy-up the Event List and stop timer1 **************/ + status = EventRemove(socket,positioner,timer1,"0"); + if (status != 0) + printf(" Error performing EventRemove(socket,positioner,Timer1)=%i\n",status); + + status = EventRemove(socket,positioner,"PVT.TrajectoryStart",nullchar); + if (status != 0) + printf(" Error performing EventRemove(socket,positioner,PVT.TrajectoryStart)=%i\n",status); + + +/********************************************************************/ + + FILE *trajFile; + FILE *gatheringFile; + char buffer[100]; + double motorReadbacks[6][20]; + double motorError[6][20]; + double trajTime = 0,trajStep = 0; + int numAxes = 6; + int i,j,npoints = 10; + double posTheory[8]; + hostAdd ("XPS1","164.54.160.124"); + netDevCreate ("XPS1:", "XPS1", 1); + remCurIdSet("Administrator", "Administrator"); + trajFile = fopen ("XPS1:/Admin/Public/Trajectories/testtrajectory", "r"); + gatheringFile = fopen ("XPS1:/Admin/Public/GatheringExternal.dat", "r"); + + for (i=0; i 0 && j < (numAxes-1)){ + if(fscanf(trajFile," %lf,%*lf,",&trajStep) != 1) printf("trajerror\n");} + + if(i == 0) { + posTheory[j] = motorReadbacks[j][i]; + printf("posTheory = %lf ",posTheory[j]);} + else{ + posTheory[j]+= trajStep;} + + motorError[j][i] = posTheory[j] - motorReadbacks[j][i]; + printf("i=%i J=%i ReadBack=%f motorError=%f trajStep%f\n", + i,j,motorReadbacks[j][i],motorError[j][i],trajStep); + } + } + + + + fclose (trajFile); /* This is where the ftp actualy takes place */ + fclose (gatheringFile); /* This is where the ftp actualy takes place */ +/**********************************************************************/ + + return; +} diff --git a/motorApp/NewportSrc/asynOctetSocket.cpp b/motorApp/NewportSrc/asynOctetSocket.cpp new file mode 100644 index 00000000..f4f25fd4 --- /dev/null +++ b/motorApp/NewportSrc/asynOctetSocket.cpp @@ -0,0 +1,342 @@ +/* This script was addapted from the Newport Socket.cpp code + to provide TCP/IP sockets for the XPSC8 motion controller + using EPICS asynOctetSyncIO.cc + + By Jon Kelly July 2005 +*/ + +/* includes */ + +#ifdef vxWorks +#else +#define TRUE 1 +#define FALSE 0 +typedef int BOOL; +#endif + +#include +#include +#include +#include +#include "asynDriver.h" +#include "asynOctetSyncIO.h" +#include +#include +#include +#include + + +/* defines */ + +#define MAX_MSG_SIZE 256 +#define TIMEOUT 0.2 +#define MAX_RETRY 5 +#define CONNREFUSED -1 +#define CREATESOCKETFAILED -2 +#define OPTREFUSED -3 + +#define MAX_NB_SOCKETS 50 + +/* global variables */ + +BOOL UsedSocket[MAX_NB_SOCKETS] = { FALSE }; +double TimeoutSocket[MAX_NB_SOCKETS]; +int ErrorSocket[MAX_NB_SOCKETS]; + +/* Pointer to the connection info for each socket + the asynUser structure is defined in asynDriver.h */ +static struct asynUser *pasynUserArray[MAX_NB_SOCKETS]; + +asynStatus status; + +/***************************************************************************************/ +#define DEBUG + +#ifdef __GNUG__ + #ifdef DEBUG + volatile int asynXPSC8Debug = 10; + #define Debug(l, f, args...) { if(l<=asynXPSC8Debug) printf(f,## args); } + epicsExportAddress(int, asynXPSC8Debug); + #else + #define Debug(l, f, args...) + #endif +#else + #define Debug() +#endif + + +/***************************************************************************************/ +/* The drvXPSC8.cc must assign the aysn port string to the IP field + and replace the xps port int with the asyn addr int */ +int ConnectToServer(char *Ip_Address, int Ip_Port, double TimeOut) +{ + + int SocketIndex = 0; + const char *asynPort = (const char *)Ip_Address; + int asynAddr; + asynAddr = Ip_Port; + + /* Select a free socket */ + while ((UsedSocket[SocketIndex] == TRUE) && (SocketIndex < MAX_NB_SOCKETS)) + { + SocketIndex++; + } + + if (SocketIndex == MAX_NB_SOCKETS) + return -1; + + ErrorSocket[SocketIndex] = 0; + + + /* These asyn functions are defined in asynOctetSyncIO.c */ + status = pasynOctetSyncIO->connect(asynPort,asynAddr,&pasynUserArray[SocketIndex],NULL); + + if (status != asynSuccess ) + { + ErrorSocket[SocketIndex] = CREATESOCKETFAILED; + printf("Error Socket connect failed asynStatus=%i \n",status); + return -1; + } + + + /* Use default timeout macro if one is not given + if (TimeOut > 0) TimeoutSocket[SocketIndex] = TimeOut; + else TimeoutSocket[SocketIndex] = TIMEOUT;*/ + + UsedSocket[SocketIndex] = TRUE; + TimeoutSocket[SocketIndex] = TIMEOUT; /* Ignore the requested timeout */ + return SocketIndex; +} + +/***************************************************************************************/ +void SetTCPTimeout(int SocketIndex, double TimeOut) +{ + if ((SocketIndex >= 0) && (SocketIndex < MAX_NB_SOCKETS) && (UsedSocket[SocketIndex] == TRUE)) + { + if (TimeOut > 0) TimeoutSocket[SocketIndex] = TimeOut; + } +} + +/***************************************************************************************/ +void SendAndReceive (int SocketIndex, char *buffer, char *valueRtrn) +{ + int nbytesOut = 0; + int nbytesIn = 0; + int eomReason; + /*clock_t start, finish; + double timeEllapse = 0.0;*/ + char *output, *input; + int writeReadStatus = -99; + int loop = 0, bufferLength; + + /* Check to see if the Socket is valid! */ + + bufferLength = strlen(buffer); + if ((SocketIndex >= 0) && (SocketIndex < MAX_NB_SOCKETS) && (UsedSocket[SocketIndex] == TRUE)) + { + if (bufferLength > MAX_MSG_SIZE) + { + /* Error string too long */ + printf("Error buffer>Max SendAndRecieve Out=%s In=%s\n",valueRtrn,buffer); + printf("asynStatus=%i ",status); + strcpy(valueRtrn,"-3"); + return; + } + + while ((writeReadStatus < 0) && (loop < MAX_RETRY)) + { + status = pasynOctetSyncIO->writeRead(pasynUserArray[SocketIndex], + (char const *)buffer, + bufferLength, + valueRtrn, + MAX_MSG_SIZE, + TimeoutSocket[SocketIndex], + &nbytesOut, + &nbytesIn, + &eomReason); + + Debug(12,"buffer %s\n bufferlen %i\n valueRtrn %s\n",buffer,bufferLength,valueRtrn); + Debug(12,"nbytesOut %i nbytesIn %i eomReason %i\n",nbytesOut,nbytesIn,eomReason); + output = valueRtrn; + if (output != NULL) sscanf (output, "%i", &writeReadStatus); + + /* If the XPS returns a status <0 it is probably still confused from a + * sendOnly so re-send the command */ + + if (writeReadStatus < 0){ + Debug(10,"Address %x\n",pasynUserArray[SocketIndex]); + Debug(1,"Error WriteReadStatus = %i Retry ",writeReadStatus); + Debug(2,"Sock=%i Tout=%g In=%s Out=%s \n Command sent again! loop %i\n",SocketIndex, + TimeoutSocket[SocketIndex],valueRtrn,buffer,loop); + } else { + + /* If the XPS returns a non error status check to see if the data + * is what you expected because it frequently returns the answere + * to the previous call! */ + + output = valueRtrn; + input = buffer; + strchr (output, ','); + while ( (input=strchr (input, '*')) != NULL ) { /* Number required */ + input++; /* Move ptr past * */ + if ((output=strchr (output, ',')) == NULL) { /* No comma after number */ + Debug(2,"Error Not enough numbers in=%s out=%s\n",valueRtrn,buffer); + writeReadStatus = -98; + } + output++; /* move ptr past , */ + Debug(15,"Look for number in return string %s\n",output); + } + } + loop++; + } + + if ( status != asynSuccess ) + { + /* Asyn command error */ + Debug(5,"Error buffer %s\n bufferlen %i\n valueRtrn %s\n",buffer,bufferLength,valueRtrn); + Debug(5,"Error nbytesOut %i nbytesIn %i eomReason %i\n",nbytesOut,nbytesIn,eomReason); + + printf("Error SendAndRecieve read In=%s Out=%s nbytesOut=%i",valueRtrn,buffer,nbytesOut); + printf(" asynStatus=%i \n",status); + return; + } + + } else { + /* Not allowed action socket was not created */ + printf("Error Socket Invalid SendAndRecieve In=%s Out=%s\n",valueRtrn,buffer); + printf("asynStatus=%i ",status); + strcpy(valueRtrn,"-22"); + return; + } + return; +} +/***************************************************************************************/ +void SendOnly (int SocketIndex, char *buffer, char *valueRtrn) +{ + char dummyReturn[MAX_MSG_SIZE]; + int nbytesOut = 0; + int nbytesIn = 0; + int eomReason; + char const dummyBuffer[40] = "FirmwareVersionGet (char *)"; + char *output; + int writeReadStatus = -99; + int loop = 0; + + /* Valid Socket? */ + if ((SocketIndex >= 0) && (SocketIndex < MAX_NB_SOCKETS) && (UsedSocket[SocketIndex] == TRUE)) + { + if (strlen(buffer) > MAX_MSG_SIZE) + { + /* Error string too long */ + strcpy(valueRtrn,"-3"); + return; + } + +Above_Write: + status = pasynOctetSyncIO->write(pasynUserArray[SocketIndex],(char const *)buffer, + strlen(buffer),TimeoutSocket[SocketIndex], &nbytesIn); + + if ((status != asynSuccess) || (nbytesIn <= 0)) + { + printf("****Error SendOnly status=%i",status); + /* Error during write message */ + strcpy(valueRtrn,"-72"); + return; + } + +/* When a send only is performed but the XPS is expecting to give a response it + * becomes confused for a period of time. A writeRead is sent and the readback + * checked until the XPS returns a sensible value */ + +Above_Dummy_writeRead: + status = pasynOctetSyncIO->writeRead(pasynUserArray[SocketIndex], + (char const *)dummyBuffer, + strlen(dummyBuffer), + dummyReturn, + MAX_MSG_SIZE, + TimeoutSocket[SocketIndex], + &nbytesOut, + &nbytesIn, + &eomReason); + + output = dummyReturn; + if (output != NULL) sscanf (output, "%i", &writeReadStatus); + else Debug(5,"SendOnly Dummywriteread Output Null\n"); + + if (writeReadStatus < 0 && output != NULL){ + Debug(2,"SendOnly DumyWriteReadStatus = %i Retry ",writeReadStatus); + Debug(3,"Sock=%i Timeout=%g DumyReturn=%s \n DummyIn=%s OrigCommand=%s\n"\ + " Dummy sent again\n",SocketIndex,TimeoutSocket[SocketIndex], + dummyReturn,dummyBuffer,buffer); + } + loop++; + if (writeReadStatus == -3 && loop < MAX_RETRY) /* Command Not executed by XPS so retry */ + goto Above_Write; + if (writeReadStatus < 0 && loop < MAX_RETRY) /* The XPS is still confused so re-send*/ + goto Above_Dummy_writeRead; + + } else { + /* Not allowed action */ + strcpy(valueRtrn,"-22"); + return; + } + strcpy(valueRtrn,"0"); + return; +} + +/***************************************************************************************/ +void CloseSocket(int SocketIndex) +{ + if ((SocketIndex >= 0) && (SocketIndex < MAX_NB_SOCKETS) && (UsedSocket[SocketIndex] == TRUE)) + { + status = pasynOctetSyncIO->disconnect(pasynUserArray[SocketIndex]); + + TimeoutSocket[SocketIndex] = TIMEOUT; + ErrorSocket[SocketIndex] = 0; + UsedSocket[SocketIndex] = FALSE; + } +} + +/***************************************************************************************/ +void CloseAllSockets(void) +{ + int i; + for (i = 0; i < MAX_NB_SOCKETS; i++) + { + if (UsedSocket[i] == TRUE) + { + status = pasynOctetSyncIO->disconnect(pasynUserArray[i]); + + TimeoutSocket[i] = TIMEOUT; + ErrorSocket[i] = 0; + UsedSocket[i] = FALSE; + } + } +} + +/***************************************************************************************/ +void ResetAllSockets(void) +{ + int i; + for (i = 0; i < MAX_NB_SOCKETS; i++) + { + if (UsedSocket[i] == TRUE) + UsedSocket[i] = FALSE; + } +} + + +/***************************************************************************************/ +char * GetError(int SocketIndex) +{ + if ((SocketIndex >= 0) && (SocketIndex < MAX_NB_SOCKETS) && (UsedSocket[SocketIndex] == TRUE)) + { + switch (ErrorSocket[SocketIndex]) + { + case CONNREFUSED: return("The attempt to connect was rejected."); + case CREATESOCKETFAILED: return("Create Socket failed."); + case OPTREFUSED: return("SetSockOption() Refused."); + } + } + return(""); +} diff --git a/motorApp/NewportSrc/tclCall.cc b/motorApp/NewportSrc/tclCall.cc new file mode 100644 index 00000000..58a88428 --- /dev/null +++ b/motorApp/NewportSrc/tclCall.cc @@ -0,0 +1,50 @@ +/* This function alows you to run a tcl script from within the + Public/Scripts directory of the Newport XPS with the ip + address contained in the string below. + + ->tclcall(tclScriptName.tcl,arbProcessName,tclScriptArgs) + + + + By Jon Kelly 2005 */ + + +#include +#include "xps_c8_driver.h" +#include "Socket.h" + +#define TIMEOUT 1 + +static int getsocket(void); + +void tclcall(char const *name,char const *taskName,char const *args){ + + int status = 0; + int socket; + + socket = getsocket(); + status = TCLScriptExecute(socket,(char *)name, + (char*)taskName,(char *)args); + + printf("TCL Call Status %i\n",status); + if (status < 0) { + printf("Error Name called %s, Task Name %s, Args %s\n",\ + name,taskName,args); + } + + return; +} + +static int getsocket(void) +{ + char ipchar[] = "164.54.160.124"; + int socket = 0; + int port = 5001; + + printf("XPS ip = %s\n",ipchar); + + socket = TCP_ConnectToServer(ipchar,port,TIMEOUT); + if (socket < 0) + printf(" Error TCP_ConnectToServer\n"); + return (socket); +}