FEDRA emulsion software from the OPERA Collaboration
AcqPlateChanger Class Reference

#include <AcqPlateChanger.h>

Inheritance diagram for AcqPlateChanger:
Collaboration diagram for AcqPlateChanger:

Public Member Functions

 AcqPlateChanger ()
 
void AddToBank (int bnk, TPlate *plate)
 
int ArmVacuumControl (bool VacOn, int timeout)
 
int FindEmulsion (Identifier id, int Bank)
 
int GoOnHAxis (int position, int timeout)
 
int GoOnVAxis (int position, int timeout)
 
int Initialize (AcqStage1 *Stage=NULL)
 
void LoadBrick (int Brick, int Nemulsions=57, int SrcBank=1, int DestBank=2, bool Separators=true, bool FirstIsSeparator=true)
 
int LoadPlate (Identifier id)
 
int LoadPlate (int id0, int id1, int id2=0, int id3=0)
 
int MoveEmulsion (int isrc, int idst)
 
void OnReset ()
 
int Park (int idst)
 
void PowerOFF ()
 
int PowerON ()
 
virtual void Print ()
 
int ReadStatusFile ()
 
void ResetBanks ()
 
int TableVacuumControl (bool VacOn, int timeout)
 
TPlateTakeFromBank (int bnk)
 
void UnloadBrick ()
 
int UnloadPlate (bool TurnPowerOff=true)
 
void UpdateStatusFile ()
 
virtual ~AcqPlateChanger ()
 

Public Attributes

int DestinationBank
 
bool InitDone
 
bool LiftCorners
 
int NumberOfAttempt
 
int NumberOfBanks
 
int PositionTimeout
 
bool Ready
 
int SeparationAttempts
 
int SourceBank
 
AcqStage1ST
 
bool StageError
 
int VacuumTimeout
 
float XLoadPosition
 
float YLoadPosition
 
float ZLoadPosition
 

Private Attributes

float StX
 
float StY
 
float StZ
 

Constructor & Destructor Documentation

◆ AcqPlateChanger()

AcqPlateChanger::AcqPlateChanger ( )
26 {
27  InitDone=false;
28  Ready=false;
29  PositionTimeout=50;
30  NumberOfBanks=3;
31  VacuumTimeout=10;
32  LiftCorners=false;
33  NumberOfAttempt=20;
35  ST=NULL;
36  XLoadPosition=-84000;
37  YLoadPosition=5000;
38  ZLoadPosition=5000;
39  SourceBank=1;
41  StageError=false;
42 
43 
44 
45 }
int NumberOfAttempt
Definition: AcqPlateChanger.h:106
bool LiftCorners
Definition: AcqPlateChanger.h:104
int VacuumTimeout
Definition: AcqPlateChanger.h:102
bool StageError
Definition: AcqPlateChanger.h:96
AcqStage1 * ST
Definition: AcqPlateChanger.h:114
int DestinationBank
Definition: AcqPlateChanger.h:100
bool InitDone
Definition: AcqPlateChanger.h:94
bool Ready
Definition: AcqPlateChanger.h:95
int PositionTimeout
Definition: AcqPlateChanger.h:101
float YLoadPosition
Definition: AcqPlateChanger.h:111
float XLoadPosition
Definition: AcqPlateChanger.h:110
float ZLoadPosition
Definition: AcqPlateChanger.h:112
int SourceBank
Definition: AcqPlateChanger.h:99
int SeparationAttempts
Definition: AcqPlateChanger.h:107
int NumberOfBanks
Definition: AcqPlateChanger.h:103
#define NULL
Definition: nidaqmx.h:84

◆ ~AcqPlateChanger()

AcqPlateChanger::~AcqPlateChanger ( )
virtual
72 {
73  OnReset();
74 }
void OnReset()
Definition: AcqPlateChanger.cxx:77

Member Function Documentation

◆ AddToBank()

void AcqPlateChanger::AddToBank ( int  bnk,
TPlate plate 
)
837 {
838  // puts the info on plate to the container (nothing is done physically)
839  // to keep track of real world situation
840  for(int i=Bank[bnk].NEmulsions+Bank[bnk].NSeparators;i>0;i--) {
841  Bank[bnk].Plates[i]=Bank[bnk].Plates[i-1];
842  }
843  plate->InBank=bnk;
844  plate->SeqNumber=0;
845  Bank[bnk].Plates[0]=plate;
846  if(plate->IsSeparator) Bank[bnk].NSeparators++;
847  else Bank[bnk].NEmulsions++;
849 
850 }
TBank Bank[5]
Definition: AcqPlateChanger.cxx:15
void UpdateStatusFile()
Definition: AcqPlateChanger.cxx:406
Int_t plate
Definition: merge_Energy_SytematicSources_Electron.C:1
TPlate * Plates[MAX_NUMBER_OF_PLATES *2]
Definition: AcqPlateChanger.h:51
int NEmulsions
Definition: AcqPlateChanger.h:49
int NSeparators
Definition: AcqPlateChanger.h:50

◆ ArmVacuumControl()

int AcqPlateChanger::ArmVacuumControl ( bool  VacOn,
int  timeout 
)
220 {
221  // Switches the vacuum on/off at arm holder, if vacuum is not reached within given timeout returns -timeout,
222  // otherwise returns actual time spent to reach vacuum
223  int32 tme=0;
224  int32 read;
225  int32 bytesPerSamp;
226  uInt8 datain[8];
227  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
228  //Read whatever is set on Output Port X
229  DAQmxReadDigitalLines (writehandle, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
232  // Toggle Vacuum valve bit (Bit7 on X )
233  if(VacOn) dataout[7]=1; else dataout[7]=0;
234  //Write back to port
235  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
238  gSystem->Sleep(100);
239  //Wait for vacuum sensor (Bit 7)
240  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
243  while(datain[7]==0 && tme<timeout)
244  {
245  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
248  gSystem->Sleep(100);tme++;
249  }
250  if(tme>=timeout)
251  {
252  return -tme;
253  }
254  return tme;
255 
256 
257 }
TaskHandle readhandle
Definition: AcqPlateChanger.cxx:17
TaskHandle writehandle
Definition: AcqPlateChanger.cxx:16
int32 DllExport __CFUNC DAQmxStopTask(TaskHandle taskHandle)
#define DAQmx_Val_GroupByChannel
Definition: nidaqmx.h:516
unsigned char uInt8
Definition: nidaqmx.h:39
signed long int32
Definition: nidaqmx.h:51
int32 DllExport __CFUNC DAQmxWaitUntilTaskDone(TaskHandle taskHandle, float64 timeToWait)
int32 DllExport __CFUNC DAQmxWriteDigitalLines(TaskHandle taskHandle, int32 numSampsPerChan, bool32 autoStart, float64 timeout, bool32 dataLayout, uInt8 writeArray[], int32 *sampsPerChanWritten, bool32 *reserved)
int32 DllExport __CFUNC DAQmxReadDigitalLines(TaskHandle taskHandle, int32 numSampsPerChan, float64 timeout, bool32 fillMode, uInt8 readArray[], uInt32 arraySizeInBytes, int32 *sampsPerChanRead, int32 *numBytesPerSamp, bool32 *reserved)

◆ FindEmulsion()

int AcqPlateChanger::FindEmulsion ( Identifier  id,
int  Bank 
)
1000 {
1001  // returns the sequence number of the given emulsion in the bank
1002  // if not found, returns -1
1003  for(int i=0;i<Bank[bnk].NEmulsions+Bank[bnk].NSeparators;i++) {
1004  if(Bank[bnk].Plates[i]->IsSeparator==false)
1005  if(Bank[bnk].Plates[i]->id.Part[0]==id.Part[0])
1006  if(Bank[bnk].Plates[i]->id.Part[1]==id.Part[1])
1007  if(Bank[bnk].Plates[i]->id.Part[2]==id.Part[2])
1008  if(Bank[bnk].Plates[i]->id.Part[3]==id.Part[3])
1009  return i;
1010  }
1011 
1012  return -1;
1013 }

◆ GoOnHAxis()

int AcqPlateChanger::GoOnHAxis ( int  position,
int  timeout 
)
300 {
301  // Moves arm horisontally to position <position>, if not reached within given timeout returns -timeout,
302  // otherwise returns actual time spent to reach position
303  // ************ WARNING!!!!!!! This low level function is not mechanically safe!!
304  // ************ It may damage the plate changer
305  // ************ if used without caution to set the arm into UPMOST POSITION!
306 
307  int32 tme=0;
308  int32 read;
309  int32 bytesPerSamp;
310  uInt8 datain[8];
311  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
312 // if(PowerON()==-1) return -timeout;
313  //Read whatever is set on Output Port X
314  DAQmxReadDigitalLines (writehandle, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
317  //Move to position on Axis
318  if(position & 1) dataout[1]=1; else dataout[1]=0;//Bank mask bit 1
319  if(position & 2) dataout[2]=1; else dataout[2]=0;//Bank mask bit 2
320  if(position & 4) dataout[3]=1; else dataout[3]=0;//Bank mask bit 3
321  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
324  gSystem->Sleep(10);
325  dataout[6]=abs(1-dataout[6]);
326  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
329  gSystem->Sleep(100);
330  dataout[6]=abs(1-dataout[6]);
331  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
334  //Check if position is reached
335  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
338  tme=0;
339 // while(datain[0]*datain[1]*datain[2]==0 && tme<timeout)
340  while(datain[0]*datain[2]==0 && tme<timeout)
341  {
342  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
345  gSystem->Sleep(100);tme++;
346  }
347  if(tme==timeout)
348  {
349  return -tme;
350  }
351  return tme;
352 
353 }
MFTYPE32 long position
Definition: Milproto.h:644

◆ GoOnVAxis()

int AcqPlateChanger::GoOnVAxis ( int  position,
int  timeout 
)
355 {
356  // Moves arm vertically to position <position>, if not reached within given timeout returns -timeout,
357  // otherwise returns actual time spent to reach position
358  int32 tme=0;
359  int32 read;
360  int32 bytesPerSamp;
361  uInt8 datain[8];
362  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
363  //Read whatever is set on Output Port Z
364  DAQmxReadDigitalLines (writehandlez, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
367  //Move to position on Axis
368  if(position & 1) dataout[1]=1; else dataout[1]=0;//Bank mask bit 1
369  if(position & 2) dataout[2]=1; else dataout[2]=0;//Bank mask bit 2
370  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
373  gSystem->Sleep(10);
374  dataout[6]=abs(1-dataout[6]);
375  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
378  gSystem->Sleep(100);
379  dataout[6]=abs(1-dataout[6]);
380  // dataout[6]=0;
381  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
384  //Check if position is reached
385  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
388  tme=0;
389 // while(datain[0]*datain[1]*datain[2]==0 && tme<timeout)
390  while(datain[0]*datain[2]==0 && tme<timeout)
391  {
392  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
395  gSystem->Sleep(100);tme++;
396  }
397  if(tme==timeout)
398  {
399  return -tme;
400  }
401  return tme;
402 
403 }
TaskHandle writehandlez
Definition: AcqPlateChanger.cxx:18
TaskHandle readhandlez
Definition: AcqPlateChanger.cxx:19

◆ Initialize()

int AcqPlateChanger::Initialize ( AcqStage1 Stage = NULL)
95 {
96  // initializes the arm drives, vacuum generators,
97  // moves the arm to position 1 up,
98  // reads the status file and sets flags InitDone, Ready
99  ST=Stage;
100  int32 tme=0;
101  int32 read;
102  int32 bytesPerSamp;
103  uInt8 datain[8];
104  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
105  printf("Initializing Plate changer..\n");
106 
107  DAQmxSetDigitalPowerUpStates ("Dev1", "Dev1/port0/line0:7", DAQmx_Val_Low, NULL);
108  DAQmxSetDigitalPowerUpStates ("Dev1", "Dev1/port1/line0:7", DAQmx_Val_Low, NULL);
109 
110  readhandle = 0;
111  readhandlez = 0;
112  writehandle = 0;
113  writehandlez = 0;
114  //Initialisation of reading X coord.
115 // printf("readhandle "); fflush(stdout);
116  DAQmxCreateTask ("read", &readhandle);
117  DAQmxCreateDIChan (readhandle, "Dev1/port1/line0:7", "", DAQmx_Val_ChanForAllLines);
118  //Initialisation of reading Z coord.
119 // printf("readhandlez "); fflush(stdout);
120  DAQmxCreateTask ("readz", &readhandlez);
121  DAQmxCreateDIChan (readhandlez, "Dev1/port0/line0:7", "", DAQmx_Val_ChanForAllLines);
122  //Initialisation of writing X coord.
123 // printf("writehandle "); fflush(stdout);
124  DAQmxCreateTask ("write", &writehandle);
125  DAQmxCreateDOChan (writehandle, "Dev1/port5/line0:7", "", DAQmx_Val_ChanForAllLines);
126  //Initialisation of writing Z coord.
127 // printf("writehandlez "); fflush(stdout);
128  DAQmxCreateTask ("writez", &writehandlez);
129  DAQmxCreateDOChan (writehandlez, "Dev1/port4/line0:7", "", DAQmx_Val_ChanForAllLines);
130  //printf("ok. \n"); fflush(stdout);
131  InitDone=false;
132  ResetBanks();
133 
134 printf("Resetting ports.. "); fflush(stdout);
135  //reset ports 4 & 5
136  //Writing to P5
137  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
140  //Writing to P4
141  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
144 
145 /* //checking 24 V
146  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
147  DAQmxWaitUntilTaskDone (readhandlez, 10.0);
148  DAQmxStopTask (readhandlez);
149  if (datain[7] == 0)//checking 24 V
150  {
151  printf("Please check 24V on drive\n");
152  return;
153  }
154  */
155  //Set AH on both drives
156  printf("Setting AH.. "); fflush(stdout);
157  dataout[0]=1;
158  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
161  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
164  gSystem->Sleep(20);
165  //Check RDY signal
166  printf("Checking H RDY.."); fflush(stdout);
167  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
170  if(datain[0]==0)
171  {
172  printf("Vertical drive controller error!\n");
173  OnReset();
174  return 0;
175  }
176  printf("OK..Checking H RDY.."); fflush(stdout);
177 
178  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
181  if(datain[0]==0)
182  {
183  printf("Horizontal drive controller error!\n");
184  OnReset();
185  return 0;
186  }
187  printf("OK.."); fflush(stdout);
188 
189  gSystem->Sleep(500);
190  printf("Arm up.."); fflush(stdout);
191 
193  {
194  printf("Vertical drive position is not reached!\n");
195  OnReset();
196  return 0;
197  }
198  printf("Arm to pos 2.."); fflush(stdout);
199  if(GoOnHAxis(2,PositionTimeout)<0)
200  {
201  printf("Horizontal drive position is not reached!\n");
202  OnReset();
203  return 0;
204  }
205  InitDone=true;
206  Ready=false;
207  printf("Reading status file.."); fflush(stdout);
208 
209  ReadStatusFile();
210 
212  printf("Done!"); fflush(stdout);
213  Dump();
214  PowerOFF();
215  return 1;
216 }
TPlate * EmulsionOnTable
Definition: AcqPlateChanger.cxx:14
#define VPOS_UP
Definition: AcqPlateChanger.h:25
FILE * stdout
int TableVacuumControl(bool VacOn, int timeout)
Definition: AcqPlateChanger.cxx:259
void PowerOFF()
Definition: AcqPlateChanger.cxx:676
int ReadStatusFile()
Definition: AcqPlateChanger.cxx:439
void ResetBanks()
Definition: AcqPlateChanger.cxx:606
int GoOnVAxis(int position, int timeout)
Definition: AcqPlateChanger.cxx:354
int GoOnHAxis(int position, int timeout)
Definition: AcqPlateChanger.cxx:299
#define DAQmx_Val_Low
Definition: nidaqmx.h:866
#define DAQmx_Val_ChanForAllLines
Definition: nidaqmx.h:512
int32 DllExport __CFUNC DAQmxCreateDIChan(TaskHandle taskHandle, const char lines[], const char nameToAssignToLines[], int32 lineGrouping)
int32 DllExport __CFUNC DAQmxCreateDOChan(TaskHandle taskHandle, const char lines[], const char nameToAssignToLines[], int32 lineGrouping)
int32 DllExport __CFUNC_C DAQmxSetDigitalPowerUpStates(const char deviceName[], const char channelNames[], int32 state,...)
int32 DllExport __CFUNC DAQmxCreateTask(const char taskName[], TaskHandle *taskHandle)

◆ LoadBrick()

void AcqPlateChanger::LoadBrick ( int  Brick,
int  Nemulsions = 57,
int  SrcBank = 1,
int  DestBank = 2,
bool  Separators = true,
bool  FirstIsSeparator = true 
)
516 {
517  // Lets user load the emulsion pile into <isrc> bank, updates StatusFile.
518  int res,inumem,ibrick;
519  ibrick=Brick;
520  inumem=Nemulsions;
521  if(isrc<1 || isrc>3 || idest<1 || idest>3 || isrc==idest || inumem<=0) {
522  printf("Wrong bank assignements!\n");
523  return;
524  }
525 if(!InitDone) Initialize();
526  PowerON();
527 Park(idest);
528 printf("Load source bank, top sheet must be ");
529 if( FirstIsSeparator) printf("the separator sheet ");
530 else printf("the first emulsion ");
531 printf(", then press any key :"); fflush(stdout);
532 getchar();
533 printf("\n");
534 
536 while(res>=0){
537  printf("Please remove emulsion from the stage, then press any key :");
538  getchar();
539  printf("\n");
541 }
542 //for(int bnk=0; bnk<NumberOfBanks+1;bnk++){
543 // Bank[bnk].NEmulsions=0;
544 // Bank[bnk].NSeparators=0;
545 // }
546 ResetBanks();
547 SourceBank=isrc;
548 DestinationBank=idest;
549 
550 Bank[isrc].NEmulsions=inumem;
551 if( Separators ) Bank[isrc].NSeparators=inumem;
552 if( FirstIsSeparator ) {
553  (Bank[isrc].NSeparators)++;
554  Bank[isrc].Plates[0]=new TPlate; //add sep
555  Bank[isrc].Plates[0]->SeqNumber=0;
556  Bank[isrc].Plates[0]->InBank=isrc;
557  Bank[isrc].Plates[0]->IsSeparator=true;
558  Bank[isrc].Plates[0]->id.Part[0]=ibrick;
559  Bank[isrc].Plates[0]->id.Part[1]=0;
560  Bank[isrc].Plates[0]->id.Part[2]=0;
561  Bank[isrc].Plates[0]->id.Part[3]=0;
562 
563 }
564 int Fsep;
565 Fsep=FirstIsSeparator?1:0;
566 if( Separators ) for(int i=0;i<inumem;i++) {
567  Bank[isrc].Plates[i*2+Fsep]=new TPlate; //add plate
568  Bank[isrc].Plates[i*2+Fsep]->SeqNumber=i*2+Fsep;
569  Bank[isrc].Plates[i*2+Fsep]->InBank=isrc;
570  Bank[isrc].Plates[i*2+Fsep]->IsSeparator=false;
571  Bank[isrc].Plates[i*2+Fsep]->id.Part[0]=ibrick;
572  Bank[isrc].Plates[i*2+Fsep]->id.Part[1]=i+1;
573  Bank[isrc].Plates[i*2+Fsep]->id.Part[2]=0;
574  Bank[isrc].Plates[i*2+Fsep]->id.Part[3]=0;
575 
576  Bank[isrc].Plates[i*2+1+Fsep]=new TPlate; //add sep
577  Bank[isrc].Plates[i*2+1+Fsep]->SeqNumber=i*2+1+Fsep;
578  Bank[isrc].Plates[i*2+1+Fsep]->InBank=isrc;
579  Bank[isrc].Plates[i*2+1+Fsep]->IsSeparator=true;
580  Bank[isrc].Plates[i*2+1+Fsep]->id.Part[0]=ibrick;
581  Bank[isrc].Plates[i*2+1+Fsep]->id.Part[1]=i+1;
582  Bank[isrc].Plates[i*2+1+Fsep]->id.Part[2]=0;
583  Bank[isrc].Plates[i*2+1+Fsep]->id.Part[3]=0;
584 
585 }
586 else for(int i=0;i<inumem;i++) {
587  Bank[isrc].Plates[i]=new TPlate; //add emulsion
588  Bank[isrc].Plates[i]->SeqNumber=i;
589  Bank[isrc].Plates[i]->InBank=isrc;
590  Bank[isrc].Plates[i]->IsSeparator=false;
591  Bank[isrc].Plates[i]->id.Part[0]=ibrick;
592  Bank[isrc].Plates[i]->id.Part[1]=i+1;
593  Bank[isrc].Plates[i]->id.Part[2]=0;
594  Bank[isrc].Plates[i]->id.Part[3]=0;
595 
596 }
597 
598 
599 Ready=true;
600 
602 PowerOFF();
603 }
int Park(int idst)
Definition: AcqPlateChanger.cxx:1014
int PowerON()
Definition: AcqPlateChanger.cxx:622
int Initialize(AcqStage1 *Stage=NULL)
Definition: AcqPlateChanger.cxx:94
int Part[4]
Definition: AcqPlateChanger.h:32
Definition: AcqPlateChanger.h:38
int SeqNumber
Definition: AcqPlateChanger.h:40
Identifier id
Definition: AcqPlateChanger.h:39
int InBank
Definition: AcqPlateChanger.h:41
bool IsSeparator
Definition: AcqPlateChanger.h:42

◆ LoadPlate() [1/2]

int AcqPlateChanger::LoadPlate ( Identifier  id)
887 {
888  // Loads the plate with given Id
889  // returns 0 if failed,
890  // 1 if succeeded,
891  // 2 if plate is already on the table
892  printf("LoadPlate is in progress...\n"); fflush(stdout);
893  int SeqN=-1,sn,BankN;
894  int Mfrom, Mto;
895  int res;
896  if(FindEmulsion(id,0)>=0) {printf("Load Plate is complete (plate was already on the stage).\n"); return 2; }//Already loaded
897  for(int bnk=1; bnk<NumberOfBanks+1;bnk++) {
898  sn=FindEmulsion(id,bnk);
899  if(sn>=0){ SeqN=sn; BankN=bnk; break;}
900  }
901  if(SeqN<0) {printf("Load Plate is failed. Emulsion is not found in banks!\n"); return 0; }//Emulsion is not found anywhere
902  printf("Required emulsion is found in bank #%d at position %d\n",BankN,SeqN+1);
903  // Emulsion is in bank BankN at the position SeqN, SeqN=0 means at the top
904  //Now put it onto the table
905  if(ST)
906  { //Move stage to exchange position
907  ST->Z->PosMove(ZLoadPosition,1e9,1e9);
908  ST->X->PosMove(XLoadPosition,1e9,1e9);
909  ST->Y->PosMove(YLoadPosition,1e9,1e9);
910  printf("Waiting for stage to reach exchange position..\n"); fflush(stdout);
911  res=ST->X->WaitForMoveComplete(5e3);
912  res*=ST->Y->WaitForMoveComplete(5e3);
913  res*=ST->Z->WaitForMoveComplete(3e3);
914  if(res==0) {printf("Stage didn't reach exchange position! Unload Plate is failed. \n"); return 0; }
915  }
916  else { printf("No connection with the stage (stage pointer is not set)!!! Unload Plate is failed. \n"); return 0; }
917  printf("OK.\n"); //reached position;
918 
919  if(BankN==SourceBank) { Mfrom=BankN; Mto=DestinationBank;}
920  else { Mto=SourceBank; Mfrom=BankN;}
921  PowerON();
922  if(EmulsionOnTable!=NULL) {
923  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
924  printf("OK..\nMoving emulsion from the stage..\n"); fflush(stdout);
925  if(MoveEmulsion(0,Mto)!=1) { Park(Mto); return 0;};
928  printf("Done.\n"); fflush(stdout);
929  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
930 
931  }
932  if(SeqN>0) printf("Moving emulsions from bank #%d to #%d\n", Mfrom,Mto); fflush(stdout);
933  for(int num=0;num<SeqN;num++){ //move from one bank to another all unnecessary plates
934  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
935  AddToBank(Mto,TakeFromBank(Mfrom));
936  if(MoveEmulsion(Mfrom,Mto)!=1) { Park(Mto); return 0;};
937  }
938  printf("Done.\n"); fflush(stdout);
939  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
940 
941  //Now top in Mfrom bank must be emulsion that we search for
942  if(FindEmulsion(id,Mfrom)!=0) {
943  printf("Brick structure incosistent!!! Reload the brick!\n");
944  return 0; //Inconsistency!!!!!
945  }
946  printf("OK..moving emulsion to the stage.."); fflush(stdout);
947  EmulsionOnTable=TakeFromBank(Mfrom); //if movement is OK update database
949  if(MoveEmulsion(Mfrom,0)!=1) { Park(Mto); return 0;};
950  printf("Done.\n"); fflush(stdout);
951  Park(Mfrom);
952 
953  printf("Load Plate is complete.\n");
955  PowerOFF();
956  return 1;
957 }
void PosMove(float Pos, float Speed, float Acc)
Definition: AcqStage1.cxx:524
int WaitForMoveComplete(u32 Timeout)
Definition: AcqStage1.cxx:514
void AddToBank(int bnk, TPlate *plate)
Definition: AcqPlateChanger.cxx:836
int FindEmulsion(Identifier id, int Bank)
Definition: AcqPlateChanger.cxx:999
TPlate * TakeFromBank(int bnk)
Definition: AcqPlateChanger.cxx:853
int MoveEmulsion(int isrc, int idst)
Definition: AcqPlateChanger.cxx:706
AcqAxis * Y
Definition: AcqStage1.h:146
AcqAxis * Z
Definition: AcqStage1.h:147
AcqAxis * X
Definition: AcqStage1.h:145

◆ LoadPlate() [2/2]

int AcqPlateChanger::LoadPlate ( int  id0,
int  id1,
int  id2 = 0,
int  id3 = 0 
)
873 {
874  // Loads the plate with given indices (id0 is brick number, id1 is plate number)
875  // returns 0 if failed,
876  // 1 if succeeded,
877  // 2 if plate is already on the table
878 Identifier id;
879 id.Part[0]=id0;
880 id.Part[1]=id1;
881 id.Part[2]=id2;
882 id.Part[3]=id3;
883 return LoadPlate(id);
884 }
int LoadPlate(Identifier id)
Definition: AcqPlateChanger.cxx:886
UInt_t id
Definition: tlg2pattern.C:118
Definition: AcqPlateChanger.h:31

◆ MoveEmulsion()

int AcqPlateChanger::MoveEmulsion ( int  isrc,
int  idst 
)
707 {
708  // Moves one sheet from bank to bank, whatever it is : emulsion or separator
709  int res,attempt=0;
710  int cornpos;
711  if((isrc<0) || (isrc>3)) {printf("Wring Source Position assignement!\n");return 0;}
712  if((idest<0) || (idest>3)) {printf("Wring Scanned Position assignement!\n");return 0;}
713  if(isrc==idest) {printf("Same Source and Scanned Position assignement!\n");return 0;}
714 // if(!PowerON()) return -1;
715  printf("\n%d > %d",isrc,idest); fflush(stdout);
716  if(isrc==0) {
717  if(!LiftCorners) {
718  res=GoOnHAxis(isrc,PositionTimeout);
719  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
721  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
722  TableVacuumControl(false,1);
724  if(res<0) {printf("ArmVacuum is not reached in 2 seconds!\n");}
725  if(res<0) { GoOnVAxis(VPOS_UP,PositionTimeout); return 0;} //error
726  }
727  TableVacuumControl(false,1);
728  attempt=0;
729  while(attempt<NumberOfAttempt){
730  attempt++;
731  if((!LiftCorners) || (attempt>1)) {
733  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
734 // res=GoOnVAxis(VPOS_UP,PositionTimeout);
736  if(res>=0) break; //The emulsion is taken succesfully
737  }
738 //if not: try to lift up corners
739  res=ArmVacuumControl(false,1); // leave emulsion
740 // if((attempt/2.)==int(attempt/2.)) cornpos=4; else cornpos=5; //try to lift the corner = pos #4 or #5
741  cornpos=4; //try to lift the corner = pos #4 or #5
742  res=GoOnHAxis(cornpos,PositionTimeout); //try to lift the corner = pos #4 or #5
743  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
745  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
746  res=ArmVacuumControl(true,VacuumTimeout); //vacuum ON
747  res=GoOnVAxis(VPOS_ABOVE_STAGE,2*PositionTimeout); //lift the corner
748  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
749 
751  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
752  res=ArmVacuumControl(false,1); //Vacuum OFF
753  res=GoOnVAxis(VPOS_UP,PositionTimeout); // Go UP
754  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
755  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
756 
757  cornpos=5; //try to lift the corner = pos #4 or #5
758  res=GoOnHAxis(cornpos,PositionTimeout); //try to lift the corner = pos #4 or #5
759  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
761  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
762  res=ArmVacuumControl(true,VacuumTimeout); //vacuum ON
763  res=GoOnVAxis(VPOS_ABOVE_STAGE,2*PositionTimeout); //lift the corner
764  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
765 
767  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
768  res=ArmVacuumControl(false,1); //Vacuum OFF
769  res=GoOnVAxis(VPOS_UP,PositionTimeout); // Go UP
770  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
771  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return 0; else printf(" Continue.\n");}
772  // res=ArmVacuumControl(true,VacuumTimeout); //Vacuum ON
773 
774 
775  res=GoOnHAxis(isrc,PositionTimeout); //go back to 0 position
776  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
777 // res=ArmVacuumControl(true,VacuumTimeout); //Vacuum ON
778  res=GoOnVAxis(VPOS_DOWN_TO_STAGE,PositionTimeout); //and DOWN again, ready for the next attempt
779  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
780  res=ArmVacuumControl(true,VacuumTimeout); //Vacuum ON
781  }
782 
783  if(attempt==NumberOfAttempt) {
784  ArmVacuumControl(false,1);
786  printf("Robot can't take plate from the stage!\n");
787  return 0;}
788  }
789  else { //taking from the bank - perform attempts to separate top emulsion from the rest
790  res=GoOnHAxis(isrc,PositionTimeout);
791  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
793  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
794  if(isrc==0) TableVacuumControl(false,1);
796  if(res<0 && isrc==0) {printf("ArmVacuum is not reached in 2 seconds!\n");}
797  if(res<0) { GoOnVAxis(VPOS_UP,PositionTimeout); return 0;} //no more emulsion in the bank
798  for(int att=0;att<SeparationAttempts;att++){
799  res=GoOnVAxis(VPOS_UP,PositionTimeout); // Go UP
800  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
802  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
803  }
804  }
805  printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%d > %d",isrc,idest); fflush(stdout);
806 
808  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
809  res=GoOnHAxis(idest,PositionTimeout);
810  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
812  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
813  printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%d > %d",isrc,idest); fflush(stdout);
814  res=ArmVacuumControl(false,1);
815  if(idest==0) {
817  if(res<0)
818  {
819  printf("TableVacuum is not reached in 5 seconds!\n");
821  if(res<0) printf("Vpos is not reached in 5 seconds!\n");
822  return 0;
823 
824  }
825 
826  }
828  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
829  printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout);
830 
831  return 1;
832 
833 }
#define VPOS_ABOVE_STAGE
Definition: AcqPlateChanger.h:28
#define VPOS_DOWN_TO_STAGE
Definition: AcqPlateChanger.h:27
#define VPOS_DOWN
Definition: AcqPlateChanger.h:26
int ArmVacuumControl(bool VacOn, int timeout)
Definition: AcqPlateChanger.cxx:219

◆ OnReset()

void AcqPlateChanger::OnReset ( )
78 {
79  // resets the power on platechanger arm, turns off the vacuums
80  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
81  int32 read;
82  //Writing to P5
83  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
86  //Writing to P4
87  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
90  InitDone=false;
91  Ready=false;
92 }

◆ Park()

int AcqPlateChanger::Park ( int  idst)
1015 {
1016  // Moves the arm up and to the idest position
1017  PowerON();
1018  int res;
1019  if((idest<0) || (idest>3)) {printf("Wrong Scanned Position assignement!\n");return 0;}
1021  if(res<0) {printf("Vpos is not reached in 5 seconds!\n");return 0;}
1022  res=GoOnHAxis(idest,PositionTimeout);
1023  if(res<0) {printf("Hpos is not reached in 5 seconds!\n");return 0;}
1024  PowerOFF();
1025  return 1;
1026 }

◆ PowerOFF()

void AcqPlateChanger::PowerOFF ( )
677 {
678  // Turns arm drives power OFF.
679  int32 tme=0;
680  int32 read;
681  int32 bytesPerSamp;
682  uInt8 data[8];
683  //reset ports 4 & 5 bit 0
684  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , data, 8, &read, &bytesPerSamp, NULL);
687  data[0]=0;
688  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , data, &read, NULL);
691  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , data, 8, &read, &bytesPerSamp, NULL);
694  data[0]=0;
698  // chack if stage coordinate changed during arm movements and rise StageError
699  if(fabs(StX - ST->X->GetPos()) >10.) StageError=true;
700  if(fabs(StY - ST->Y->GetPos()) >10.) StageError=true;
701  if(fabs(StZ - ST->Z->GetPos()) >5.) StageError=true;
702 
703 }
Expr< UnaryOp< Fabs< T >, Expr< A, T, D >, T >, T, D > fabs(const Expr< A, T, D > &rhs)
Definition: UnaryOperators.hh:96
float GetPos()
Definition: AcqStage1.cxx:599
float StX
Definition: AcqPlateChanger.h:60
float StZ
Definition: AcqPlateChanger.h:60
float StY
Definition: AcqPlateChanger.h:60

◆ PowerON()

int AcqPlateChanger::PowerON ( )
623 {
624  // Turns arm drives power ON.
625  StX=ST->X->GetPos();
626  StY=ST->Y->GetPos();
627  StZ=ST->Z->GetPos(); //save current stage positions
628  StageError=false;
629  int32 tme=0;
630  int32 read;
631  int32 bytesPerSamp;
632  uInt8 datain[8];
633  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
634 
635  //Set AH on both drives
636  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
639  dataout[0]=1;
640  DAQmxWriteDigitalLines (writehandle, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
643  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
646  dataout[0]=1;
647  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
650  gSystem->Sleep(20);
651  //Check RDY signal
652  DAQmxReadDigitalLines (readhandle, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
655  if(datain[0]==0)
656  {
657  printf("Vertical drive controller error!\n");
658  OnReset();
659  return 0;
660  }
661 
662  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
665  if(datain[0]==0)
666  {
667  printf("Horizontal drive controller error!\n");
668  OnReset();
669  return 0;
670  }
671  gSystem->Sleep(500);
672  return 1;
673 
674 }

◆ Print()

void AcqPlateChanger::Print ( )
virtual
48 {
49  // prints the content of emulsion banks
50  for(int bnk=0;bnk<NumberOfBanks+1;bnk++)
51  {
52  if(bnk==0) printf("\nTable:",Bank[bnk].Number);
53  else printf("\nBank #%d content:",Bank[bnk].Number);
54  if(Bank[bnk].NEmulsions==0 && Bank[bnk].NSeparators==0) printf(" Empty.\n\n");
55  else printf("\n\n");
56 
57  for(int i=0;i<Bank[bnk].NEmulsions+Bank[bnk].NSeparators;i++)
58  {
59  if(Bank[bnk].Plates[i]->IsSeparator) printf("---Separator---\n");
60  else printf("Emulsion %d %d %d %d\n",Bank[bnk].Plates[i]->id.Part[0],
61  Bank[bnk].Plates[i]->id.Part[1],
62  Bank[bnk].Plates[i]->id.Part[2],
63  Bank[bnk].Plates[i]->id.Part[3]);
64  }
65  }
66 
67 
68 }

◆ ReadStatusFile()

int AcqPlateChanger::ReadStatusFile ( )

UpdateBanksView();

440 {
441  //restores the banks content from the status file
442  char line[128];
443  char key[32];
444  int I,bnk,seps,plts,a,b,c,d,ip;
445  FILE *fp=fopen("c:\\ChangerStatus.txt","r");
446  if(fp==NULL) return 0;
447  if(fgets(line,128,fp)==NULL) return 0; //date/time line is gisregarded
448  ResetBanks();
449 
450  while(fgets(line,128,fp)!=NULL){
451  sscanf(line,"%s %d",key,&I);
452  if(strcmp(key,"Bank")==0) bnk=I;
453  if(strcmp(key,"SEPARATORS")==0) seps=I;
454  if(strcmp(key,"PLATES")==0) plts=I;
455  if(strcmp(key,"PLATE")==0){
456  sscanf(line,"%s %d %d %d %d",key,&a,&b,&c,&d);
457  ip=Bank[bnk].NEmulsions+Bank[bnk].NSeparators;
458  Bank[bnk].Plates[ip]=new TPlate; //add plate
459  Bank[bnk].Plates[ip]->SeqNumber=ip;
460  Bank[bnk].Plates[ip]->InBank=bnk;
461  Bank[bnk].Plates[ip]->IsSeparator=false;
462  Bank[bnk].Plates[ip]->id.Part[0]=a;
463  Bank[bnk].Plates[ip]->id.Part[1]=b;
464  Bank[bnk].Plates[ip]->id.Part[2]=c;
465  Bank[bnk].Plates[ip]->id.Part[3]=d;
466  Bank[bnk].NEmulsions++;
467  }
468  if(strcmp(key,"SEPARATOR")==0){
469  ip=Bank[bnk].NEmulsions+Bank[bnk].NSeparators;
470  Bank[bnk].Plates[ip]=new TPlate; //add separator
471  Bank[bnk].Plates[ip]->SeqNumber=ip;
472  Bank[bnk].Plates[ip]->InBank=bnk;
473  Bank[bnk].Plates[ip]->IsSeparator=true;
474  Bank[bnk].Plates[ip]->id.Part[0]=0;
475  Bank[bnk].Plates[ip]->id.Part[1]=0;
476  Bank[bnk].Plates[ip]->id.Part[2]=0;
477  Bank[bnk].Plates[ip]->id.Part[3]=0;
478  Bank[bnk].NSeparators++;
479  }
480  if(strcmp(key,"EndBank")==0){
481  if((bnk!=I) || (Bank[bnk].NSeparators!=seps) || (Bank[bnk].NEmulsions!=plts))
482  {
483  printf("Plate Changer Error: ChangerStatus.txt file is corrupted!!! Resetting banks.\n");
484  ResetBanks();
486  return 0;
487  }
488  }
489 
490  }
491  fclose(fp);
493  Ready=true;
495  return 1;
496 }
void d()
Definition: RecDispEX.C:381
void a()
Definition: check_aligned.C:59
fclose(pFile)

◆ ResetBanks()

void AcqPlateChanger::ResetBanks ( )
607 {
608  //resets the banks content
609  if(EmulsionOnTable) delete EmulsionOnTable;
611  for(int i=0;i<NumberOfBanks+1;i++) {
612  Bank[i].Number=i; //0- microscope, 1-3 banks
613  Bank[i].NEmulsions=0; //not known how many plates it contains
614  Bank[i].NSeparators=0;
615  for(int j=0;j<MAX_NUMBER_OF_PLATES*2;j++) {if(Bank[i].Plates[j]) delete Bank[i].Plates[j]; Bank[i].Plates[j]=NULL; }
616  }
617  Ready=false;
618 //UpdateStatusFile();
619 }
#define MAX_NUMBER_OF_PLATES
Definition: AcqPlateChanger.h:24
int Number
Definition: AcqPlateChanger.h:48

◆ TableVacuumControl()

int AcqPlateChanger::TableVacuumControl ( bool  VacOn,
int  timeout 
)
260 {
261  // Switches the vacuum on/off at the table, if vacuum is not reached within given timeout returns -timeout,
262  // otherwise returns actual time spent to reach vacuum
263  int32 tme=0;
264  int32 read;
265  int32 bytesPerSamp;
266  uInt8 datain[8];
267  uInt8 dataout[8] = {0,0,0,0,0,0,0,0};
268  //Read whatever is set on Output Port Z
269  DAQmxReadDigitalLines (writehandlez, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, 8, &read, &bytesPerSamp, NULL);
272  // Toggle Vacuum valve bit (Bit7 on Z )
273  if(VacOn) dataout[7]=1; else dataout[7]=0;
274  //Write back to port
275  DAQmxWriteDigitalLines (writehandlez, 1, 1, 10.0, DAQmx_Val_GroupByChannel , dataout, &read, NULL);
278  gSystem->Sleep(100);
279  //Wait for vacuum sensor (Bit 7)
280  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
283  while(datain[7]==0 && tme<timeout)
284  {
285  DAQmxReadDigitalLines (readhandlez, 1, 10.0, DAQmx_Val_GroupByChannel , datain, 8, &read, &bytesPerSamp, NULL);
288  gSystem->Sleep(100);tme++;
289  }
290  if(tme>=timeout)
291  {
292  return -tme;
293  }
294  return tme;
295 
296 
297 }

◆ TakeFromBank()

TPlate * AcqPlateChanger::TakeFromBank ( int  bnk)
854 {
855  // takes info on plate from the container (nothing is done physically)
856  // to keep track of real world situation
857  TPlate* retvalue;
858  if(Bank[bnk].NEmulsions+Bank[bnk].NSeparators<=0) return NULL;
859  retvalue=Bank[bnk].Plates[0];
860  for(int i=0;i<Bank[bnk].NEmulsions+Bank[bnk].NSeparators-1;i++) {
861  Bank[bnk].Plates[i]=Bank[bnk].Plates[i+1];
862 
863  }
864  if(retvalue->IsSeparator) Bank[bnk].NSeparators--;
865  else Bank[bnk].NEmulsions--;
866  //if(bnk==0) EmulsionOnTable=NULL;
868  retvalue->InBank=-1; //unknown
869  return retvalue;
870 }

◆ UnloadBrick()

void AcqPlateChanger::UnloadBrick ( )
499 {
500  // Moves all emulsions and separators back to
501  // the source bank to allow user to withdraw the brick.
502  // Doesnt' reset banks!!!! Make sure to execute LoadBrick if you change the brick!
503  UnloadPlate(false);
504  printf("Moving emulsions from bank %d back to %d..",DestinationBank,SourceBank); fflush(stdout);
505  while( (Bank[DestinationBank].NEmulsions + Bank[DestinationBank].NSeparators) > 0 )
506  {
507  if(kbhit()){getch();printf("Paused. Continue? (y/n)"); if(getchar()=='n') return; else printf(" Continue.\n");}
508  if(MoveEmulsion(DestinationBank,SourceBank)!=1) { printf("MoveEmulsion returned FAILED!\n"); Park(DestinationBank); return;};
510  }
512  printf("Done. \nPlease take the brick from the bank %d\n", SourceBank);
513 }
int UnloadPlate(bool TurnPowerOff=true)
Definition: AcqPlateChanger.cxx:959

◆ UnloadPlate()

int AcqPlateChanger::UnloadPlate ( bool  TurnPowerOff = true)
960 {
961  // Unloads the plate from the stage to the source bank
962  // returns 1 if OK,
963  // 0 in case of error.
964  PowerON();
965 printf("Unload plate is in progress...\n");
966  int isrc,idest;
968  if(!EmulsionOnTable) return 1;
969  isrc=SourceBank;
970  idest=DestinationBank;
971  if(isrc<1 || isrc>3 || idest<1 || idest>3 || isrc==idest) {
972  printf("Wrong bank assignements!\n");
973  printf("Unload Plate is failed.\n");
974  return 0;
975  }
976 //All is ok, now move plate to src bank
977  int res;
978  if(ST){ //Move stage to exchange position
979  ST->Z->PosMove(ZLoadPosition,1e9,1e9);
980  ST->X->PosMove(XLoadPosition,1e9,1e9);
981  ST->Y->PosMove(YLoadPosition,1e9,1e9);
982  res=ST->X->WaitForMoveComplete(5e3);
983  res*=ST->Y->WaitForMoveComplete(5e3);
984  res*=ST->Z->WaitForMoveComplete(3e3);
985  if(res==0) {printf("Stage didn't reach exchange position! Unload Plate is failed. \n"); return 0; }
986  }
989 
990  if(MoveEmulsion(0,isrc)!=1) { printf("Unload Plate is failed. "); Park(idest); return 0;};
991 
992 printf("Unload Plate is complete.\n");
994 if(TurnPowerOff)PowerOFF();
995 return 1;
996 
997 }

◆ UpdateStatusFile()

void AcqPlateChanger::UpdateStatusFile ( )
407 {
408  // Syncronizes the status file with the current banks content
409  char dateStr [9];
410  char timeStr [9];
411  _strdate( dateStr);
412  _strtime( timeStr );
413  FILE *fp=fopen("c:\\ChangerStatus.txt","w");
414  FILE *fpl=fopen("c:\\ChangerLog.txt","a");
415  fprintf(fp,"Plate Changer Status on %s at %s.\n",dateStr,timeStr);
416  fprintf(fpl,"Plate Changer Status on %s at %s.\n",dateStr,timeStr);
417  for(int bnk=0;bnk<NumberOfBanks+1;bnk++){
418  fprintf(fp,"Bank %d\n",bnk);
419  fprintf(fpl,"Bank %d\n",bnk);
420  fprintf(fp,"SEPARATORS %d\n",Bank[bnk].NSeparators);
421  fprintf(fpl,"SEPARATORS %d\n",Bank[bnk].NSeparators);
422  fprintf(fp,"PLATES %d\n",Bank[bnk].NEmulsions);
423  fprintf(fpl,"PLATES %d\n",Bank[bnk].NEmulsions);
424  for(int i=0;i<Bank[bnk].NEmulsions+Bank[bnk].NSeparators;i++)
425  if(Bank[bnk].Plates[i]->IsSeparator){ fprintf(fp,"SEPARATOR\n");fprintf(fpl,"SEPARATOR\n");}
426  else {
427  fprintf(fp,"PLATE %d %d %d %d\n",Bank[bnk].Plates[i]->id.Part[0],Bank[bnk].Plates[i]->id.Part[1],Bank[bnk].Plates[i]->id.Part[2],Bank[bnk].Plates[i]->id.Part[3]);
428  fprintf(fpl,"PLATE %d %d %d %d\n",Bank[bnk].Plates[i]->id.Part[0],Bank[bnk].Plates[i]->id.Part[1],Bank[bnk].Plates[i]->id.Part[2],Bank[bnk].Plates[i]->id.Part[3]);
429  }
430  fprintf(fp,"EndBank %d\n",bnk);
431  fprintf(fpl,"EndBank %d\n",bnk);
432 
433  }
434 
435  fclose(fp);
436  fclose(fpl);
437 }

Member Data Documentation

◆ DestinationBank

int AcqPlateChanger::DestinationBank

◆ InitDone

bool AcqPlateChanger::InitDone

◆ LiftCorners

bool AcqPlateChanger::LiftCorners

◆ NumberOfAttempt

int AcqPlateChanger::NumberOfAttempt

◆ NumberOfBanks

int AcqPlateChanger::NumberOfBanks

◆ PositionTimeout

int AcqPlateChanger::PositionTimeout

◆ Ready

bool AcqPlateChanger::Ready

◆ SeparationAttempts

int AcqPlateChanger::SeparationAttempts

◆ SourceBank

int AcqPlateChanger::SourceBank

◆ ST

AcqStage1* AcqPlateChanger::ST

◆ StageError

bool AcqPlateChanger::StageError

◆ StX

float AcqPlateChanger::StX
private

◆ StY

float AcqPlateChanger::StY
private

◆ StZ

float AcqPlateChanger::StZ
private

◆ VacuumTimeout

int AcqPlateChanger::VacuumTimeout

◆ XLoadPosition

float AcqPlateChanger::XLoadPosition

◆ YLoadPosition

float AcqPlateChanger::YLoadPosition

◆ ZLoadPosition

float AcqPlateChanger::ZLoadPosition

The documentation for this class was generated from the following files: