DUTs
E_DPaddle_States
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE E_DPaddle_States :
(
parked := 0,
diode,
L1,
L2,
L3,
L4,
R1,
R2,
R3,
R4
);
END_TYPE
- Related:
ENUM_DiagPaddle
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE ENUM_DiagPaddle :
(
UNKNOWN := 0,
PARK :=1,
UP := 2,
CENTER := 3,
PINHOLE := 4,
DIODE := 5,
YAG1 := 6,
YAG2 := 7,
YAG3 := 8,
KNIFE := 9
);
END_TYPE
ENUM_DPX
{attribute 'qualified_only'}
// EPICS states enum for use in FB_DPX (diagnostic paddle X)
// Remove strict attribute for easier handling
TYPE ENUM_DPX :
(
UNKNOWN := 0, // UNKNOWN must be in slot 0 or the FB breaks
PARK := 1, // The parked position for the diagnostic paddle
CENTER := 2, // center positon for the diagnostic paddle. This should be
KNIFE := 3 // Knife edge position for the diagnostic paddle. Should be the same nominal X positon as the "CENTER"
// position, but will use a different set of soft limits to allow scanning of the knife edge.
);
END_TYPE
- Related:
ENUM_DPY
{attribute 'qualified_only'}
// EPICS states enum for use in FB_DPY (diagnostic paddle Y)
// Remove strict attribute for easier handling
TYPE ENUM_DPY :
(
UNKNOWN := 0, // UNKNOWN must be in slot 0 or the FB breaks
PARK := 1, // The parked position for the diagnostic paddle
CENTER := 2, // center positon for the diagnostic paddle. This should be
PINHOLE := 3, // Pinhole position for WFS
DIODE :=4, // Diode position
YAG1 := 5, // Yag 1 position
YAG2 := 6, // Yag 2 position
YAG3 := 7, // Yag 3 position
KNIFE := 8 // Knife edge position for the diagnostic paddle. Should be the same nominal X positon as the "CENTER"
// position, but will use a different set of soft limits to allow scanning of the knife edge.
);
END_TYPE
ENUM_DPZ
{attribute 'qualified_only'}
// EPICS states enum for use in FB_DPX (diagnostic paddle X)
// Remove strict attribute for easier handling
TYPE ENUM_DPZ :
(
UNKNOWN := 0, // UNKNOWN must be in slot 0 or the FB breaks
PARK := 1, // The parked position for the diagnostic paddle
CENTER := 2 // center positon for the diagnostic paddle. This should be
);
END_TYPE
- Related:
ST_BFSAssemblyState
TYPE ST_BFSAssemblyState :
STRUCT
iState : DINT; // state index
bDiscovered : BOOL; // BFS search discovery status
iParent : DINT; // BFS parent state
END_STRUCT
END_TYPE
ST_DiagPaddleOutputs
TYPE ST_DiagPaddleOutputs :
STRUCT
PARK : ARRAY [1..3] OF DUT_PositionState;
UP : ARRAY [1..3] OF DUT_PositionState;
CENTER : ARRAY [1..3] OF DUT_PositionState;
PINHOLE : ARRAY [1..3] OF DUT_PositionState;
DIODE : ARRAY [1..3] OF DUT_PositionState;
YAG1 : ARRAY [1..3] OF DUT_PositionState;
YAG2 : ARRAY [1..3] OF DUT_PositionState;
YAG3 : ARRAY [1..3] OF DUT_PositionState;
KNIFE : ARRAY [1..3] OF DUT_PositionState;
END_STRUCT
END_TYPE
ST_EPSLimits
TYPE ST_EPSLimits :
// Defines the PLC limits and EPS structure where these limits are valid
STRUCT
{attribute 'pytmc' := 'pv: FwdLimit'}
// Forward Limit
fFwd_Limits : LREAL;
{attribute 'pytmc' := 'pv: BwdLimit'}
// Backward Limit
fBwd_Limits : LREAL;
{attribute 'pytmc' := 'pv: ST'}
// EPS_OK - TRUE, Use limits as 'plc limits'; EPS_OK - FALSE, DO not use limits
stEPS : DUT_EPS;
END_STRUCT
END_TYPE
ST_Queue
TYPE ST_Queue :
STRUCT
iLength : DINT := 100; // max number of elements in the queue
iFront : DINT := 0; // oldest item index
iBack : DINT := -1; // newest item index
iCount : DINT := 0; // current item count
arrQueue: ARRAY[0..100] OF ST_BFSAssemblyState; // array to hold queued items
END_STRUCT
END_TYPE
- Related:
GVLs
GVL
{attribute 'qualified_only'}
VAR_GLOBAL
xOverride : BOOL := FALSE; // Global override of motion safety settings.
END_VAR
GVL_DiagnosticPaddle
VAR_GLOBAL
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// X axis position states
stDPXPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPXPosCenter : DUT_PositionState := (sName:= 'CENTER',
fPosition := 10.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPXPosKnife : DUT_PositionState := (sName:= 'KNIFE',
fPosition := 15.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stDPYPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosCenter : DUT_PositionState := (sName:= 'CENTER',
fPosition := 10.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosDiode : DUT_PositionState := (sName:= 'DIODE',
fPosition := 15.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosPinhole : DUT_PositionState := (sName:= 'PINHOLE',
fPosition := 20.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosYAG1 : DUT_PositionState := (sName:= 'YAG1',
fPosition := 25.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosYAG2 : DUT_PositionState := (sName:= 'YAG2',
fPosition := 30.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosYAG3 : DUT_PositionState := (sName:= 'YAG3',
fPosition := 35.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPYPosKnife : DUT_PositionState := (sName:= 'KNIFE',
fPosition := 40.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Z axis position states
stDPZPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPZPosCenter : DUT_PositionState := (sName:= 'CENTER',
fPosition := 10.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
stDPPark : ST_BFSAssemblyState := (iState:=1, bDiscovered:=FALSE, iParent:=0);
stDPUp : ST_BFSAssemblyState := (iState:=2, bDiscovered:=FALSE, iParent:=0);
stDPCenter : ST_BFSAssemblyState := (iState:=3, bDiscovered:=FALSE, iParent:=0);
stDPPinhole : ST_BFSAssemblyState := (iState:=4, bDiscovered:=FALSE, iParent:=0);
stDPDiode : ST_BFSAssemblyState := (iState:=5, bDiscovered:=FALSE, iParent:=0);
stDPYag1 : ST_BFSAssemblyState := (iState:=6, bDiscovered:=FALSE, iParent:=0);
stDPYag2 : ST_BFSAssemblyState := (iState:=7, bDiscovered:=FALSE, iParent:=0);
stDPYag3 : ST_BFSAssemblyState := (iState:=8, bDiscovered:=FALSE, iParent:=0);
stDPKnife : ST_BFSAssemblyState := (iState:=9, bDiscovered:=FALSE, iParent:=0);
arrDPStates : ARRAY [1..9] OF ST_BFSAssemblyState := [stDPPark, stDPUp, stDPCenter, stDPPinhole, stDPDiode,
stDPYag1, stDPYag2, stDPYag3, stDPKnife];
END_VAR
- Related:
GVL_FiberLite
//{attribute 'qualified_only'}
VAR_GLOBAL
//Fiber-Lite Control
{attribute 'TcLinkTo' := '.iIlluminatorINT := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Term 158 (EL4004)^AO Outputs Channel 1^Analog output'}
{attribute 'pytmc' := '
pv: RIX:CRIX:LED:01
io: io
'}
bLedOutput1 : FB_LED;
{attribute 'TcLinkTo' := '.iIlluminatorINT := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^FiberLite (EL4004)^AO Outputs Channel 2^Analog output'}
{attribute 'pytmc' := '
pv: RIX:CRIX:LED:02
io: io
'}
bLedOutput2 : FB_LED;
END_VAR
GVL_Illumination
//{attribute 'qualified_only'}
VAR_GLOBAL
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// X axis position states
stILMXPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stILMYPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Z axis position states
stILMZPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
fbILMXStage : FB_MotionStage;
fbILMYStage : FB_MotionStage;
fbILMZStage : FB_MotionStage;
END_VAR
GVL_MotorEPS
VAR_GLOBAL
fDPL_X : LREAL;
fDPL_Z : LREAL;
fDPL_Y : LREAL;
fSDS_RX : LREAL;
fSDS_Y : LREAL;
fSDS_Z_ENC : LREAL;
fRCC_Z : LREAL;
fRCC_Y : LREAL;
tEPS_OVRD_RESET_TIME : TIME := T#5m; // Resets overide after this amount of time.
{attribute 'pytmc' := '
pv: RIX:CRIX:EPS:fNozzleCatcherOffset
io: io
'}
fNozzleCatcherOffset : LREAL := 20;
END_VAR
GVL_PMPS
{attribute 'qualified_only'}
VAR_GLOBAL
//MPS
{attribute 'pytmc' := '
pv: PLC:CRIX:MOT:FFO:01
'}
{attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 1^Output'}
g_FastFaultOutput1 : FB_HardwareFFOutput :=(i_sNetID:='172.21.42.126.1.1');
{attribute 'pytmc' := '
pv: PLC:CRIX:MOT:FFO:02
'}
{attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 2^Output'}
g_FastFaultOutput2 : FB_HardwareFFOutput :=(i_sNetID:='172.21.42.126.1.1');
{attribute 'pytmc' := '
pv: PLC:CRIX:MOT:ARB:01
'}
fbArbiter1 : FB_Arbiter(1);
END_VAR
GVL_PointDetector
{attribute 'qualified_only'}
VAR_GLOBAL
// Motor axes
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// Rotation axis position states
stPDRotPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 10.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stPDYPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 21.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
END_VAR
GVL_Questar
{attribute 'qualified_only'}
VAR_GLOBAL
// Motor axes
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// X axis position states
stQSTXPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stQSTYPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
END_VAR
GVL_SampleDelivery
{attribute 'qualified_only'}
VAR_GLOBAL
// Motor axes
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// X axis position states
stSDSXPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stSDSYPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Z axis position states
stSDSZPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Rotation axis position states
stSDSRotPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Shroud axis position states
stSDSShroudPosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 5.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
END_VAR
Main
//{attribute 'qualified_only'}
VAR_GLOBAL
// Motor axes
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E1 (EL7031)^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E1 (EL7031)^STM Status^Status^Digital input 1'}
M1 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stDPXMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E3 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E3 (EL7031)^STM Status^Status^Digital input 2'}
M2 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stDPYMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E4 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E4 (EL7031)^STM Status^Status^Digital input 2'}
M3 : DUT_MotionStage :=(bPowerSelf:=TRUE,nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stDPZMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:OBJ:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E6 (EL7031)^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E6 (EL7031)^STM Status^Status^Digital input 1'}
M4: DUT_MotionStage :=(bPowerSelf:=TRUE ,nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stOBJXMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:OBJ:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E7 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E7 (EL7031)^STM Status^Status^Digital input 2'}
M5 : DUT_MotionStage :=(bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stOBJYMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:OBJ:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E9 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E9 (EL7031)^STM Status^Status^Digital input 2'}
M6 : DUT_MotionStage :=(bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stOBJZMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:PDET:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E11 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E11 (EL7031)^STM Status^Status^Digital input 2'}
M7 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stPDYMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:PDET:MMS:THETA'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E13 (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E13 (EL7041)^STM Status^Status^Digital input 2'}
M8 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stPDRotMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:ILM:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 65 (EL1084)^Channel 1^Input;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 65 (EL1084)^Channel 2^Input'}
M9 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stILMXMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:ILM:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 65 (EL1084)^Channel 3^Input;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 65 (EL1084)^Channel 4^Input'}
M10 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stILMYMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:ILM:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 68 (EL1084)^Channel 1^Input;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 68 (EL1084)^Channel 2^Input'}
M11 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stILMZMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:QSTR:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E17 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E17 (EL7031)^STM Status^Status^Digital input 2'}
M12 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stQSTXMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:QSTR:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E19 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E19 (EL7031)^STM Status^Status^Digital input 2'}
M13 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION);
//stQSTYMotor : DUT_MotionStage;
M14 : DUT_MotionStage; // SPARE 1
M15 : DUT_MotionStage; // SPARE 2
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:X'}
M16 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stSDSXMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E26 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E26 (EL7031)^STM Status^Status^Digital input 2'}
M17 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stSDSYMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E27 (EL7031)^STM Status^Status^Digital input 1'}
M18 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stSDSZMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:RX'}
(* {attribute 'TcLinkTo' := '.bLimitForwardEnable := ; // There are currently no limits on this stage
.bLimitBackwardEnable := '} *)
M19 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stSDSRotMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:RJET'}
(* {attribute 'TcLinkTo' := '.bLimitForwardEnable := ; // There are currently no limits on this stage
.bLimitBackwardEnable := '} *)
M20 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //stSDSShroudMotor : DUT_MotionStage;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:ZENCODER'}
M36 : DUT_MotionStage; // SDS Z Encoder Axis
{attribute 'pytmc' := 'pv: CRIX:CRYO:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo X (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo X (EL7041)^STM Status^Status^Digital input 2'}
M22 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CryoStat X
{attribute 'pytmc' := 'pv: CRIX:CRYO:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo Y (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo Y (EL7041)^STM Status^Status^Digital input 2'}
M23 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CryoStat Y
{attribute 'pytmc' := 'pv: CRIX:CRYO:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo Z (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ1 (EK1122)^CryoStat (EK1101)^Cryo Z (EL7041)^STM Status^Status^Digital input 2'}
M24 : DUT_MotionStage:= (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CryoStat Z
{attribute 'pytmc' := 'pv: CRIX:CRYO:MMS:RY'}
M25 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CryoStat rY
{attribute 'pytmc' := 'pv: CRIX:RCI:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI X (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI X (EL7041)^STM Status^Status^Digital input 2'}
M26 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCI X
{attribute 'pytmc' := 'pv: CRIX:RCI:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI Y (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI Y (EL7041)^STM Status^Status^Digital input 2'}
M27 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCI Y
{attribute 'pytmc' := 'pv: CRIX:RCI:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI Z (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^RCI (EK1101-0080)^RCI Z (EL7041)^STM Status^Status^Digital input 2'}
M28 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCI Z
{attribute 'pytmc' := 'pv: CRIX:RCI:MMS:RX'}
M29 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCI rX
{attribute 'pytmc' := 'pv: CRIX:BEAM:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock X (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock X (EL7041)^STM Status^Status^Digital input 2'}
M30 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //BEAM X
{attribute 'pytmc' := 'pv: CRIX:BEAM:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock Y (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock Y (EL7041)^STM Status^Status^Digital input 2'}
M31 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //BEAM Y
{attribute 'pytmc' := 'pv: CRIX:BEAM:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock Z (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 113 (EK1101-0080)^Beamblock Z (EL7041)^STM Status^Status^Digital input 2'}
M32 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //BEAM Z
{attribute 'pytmc' := 'pv: CRIX:CAM:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 109 (EK1101-0080)^Camera X (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 109 (EK1101-0080)^Camera X (EL7041)^STM Status^Status^Digital input 2'}
M33 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CAM X
{attribute 'pytmc' := 'pv: CRIX:CAM:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 109 (EK1101-0080)^Camera Y (EL7041)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-ECJ0 (EK1122-0080)^Term 109 (EK1101-0080)^Camera Y (EL7041)^STM Status^Status^Digital input 2'}
M34 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //CAM Z
{attribute 'pytmc' := 'pv: CRIX:OUTCOUP:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E31 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E31 (EL7031)^STM Status^Status^Digital input 2'}
M35 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //OUTCOUP LENS Y
(*
M21 : DUT_MotionStage; // Out-coupling y
*)
(* not needed for now; it has a manual knob
// NOTE: Questar is M21, even though Outcoupling Y stage is before it on the DIN rail
{attribute 'pytmc' := 'pv: CRIX:QSTR:MMS:FOCUS'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E33 (EL7031)^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E33 (EL7031)^STM Status^Status^Digital input 2'}
M21 : DUT_MotionStage; // Questar Focus
*)
//Catcher Axes
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:X'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[Catcher_E1_EL7041]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIIB[Catcher_E1_EL7041]^STM Status^Status^Digital input 1'}
M37 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCC X
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Y'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[Catcher_E3_EL7041]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIIB[Catcher_E3_EL7041]^STM Status^Status^Digital input 2'}
M38 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCC Y
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Z'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[Catcher_E4_EL7041]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIIB[Catcher_E4_EL7041]^STM Status^Status^Digital input 1'}
M39 : DUT_MotionStage := (bPowerSelf:=TRUE, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION); //RCC Z
// VLS SLIT TOP
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP6_EP7041-1002]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable:=TIIB[VLS_EP6_EP7041-1002]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:SLTOP
field: DESC VLS Slit TOP Blade
'}
M40: DUT_MotionStage;
// VLS SLIT BOTTOM
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP7_EP7041-1002]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable:=TIIB[VLS_EP7_EP7041-1002]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:SLBOTTOM
field: DESC VLS Slit BOTTOM Blade
'}
M41: DUT_MotionStage;
// VLS SLIT RIGHT
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP8_EP7041-1002]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable:=TIIB[VLS_EP8_EP7041-1002]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:SLRIGHT
field: DESC VLS Slit RIGHT Blade
'}
M42: DUT_MotionStage;
// VLS SLIT LEFT
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP9_EP7041-1002]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable:=TIIB[VLS_EP9_EP7041-1002]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:SLLEFT
field: DESC VLS Slit LEFT Blade
'}
M43: DUT_MotionStage;
// VLS focusing mirror pitch
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP10_EP7041-3102]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable:=TIIB[VLS_EP10_EP7041-3102]^STM Status^Status^Digital input 1;
.nRawEncoderUINT:=TIIB[VLS_EP10_EP7041-3102]^ENC Status compact^Counter value;
.bHome:=TIIB[VLS_EP10_EP7041-3102]^ENC Status compact^Status^Status of input C'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:MP
field: DESC VLS Focus Mirror
'}
M44: DUT_MotionStage;
// VLS grating pitch
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP11_EP7041-3102]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable:=TIIB[VLS_EP11_EP7041-3102]^STM Status^Status^Digital input 1;
.nRawEncoderUINT:=TIIB[VLS_EP11_EP7041-3102]^ENC Status compact^Counter value;
.bHome:=TIIB[VLS_EP11_EP7041-3102]^ENC Status compact^Status^Status of input C'}
{attribute 'pytmc' := '
pv: CRIX:VLS:MMS:GP
field: DESC VLS Grating
'}
M45: DUT_MotionStage;
// VLS camera Pitch
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP12_EP7041-3102]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable:=TIIB[VLS_EP12_EP7041-3102]^STM Status^Status^Digital input 2;
.bHome:=TIIB[VLS_EP12_EP7041-3102]^ENC Status compact^Status^Status of input C'}
{attribute 'pytmc' := '
pv: CRIX:VLS:CAM:MMS:PITCH
field: DESC VLS Camera Pitch
'}
M46: DUT_MotionStage;
// VLS camera Distance
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[VLS_EP13_EP7041-3102]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable:=TIIB[VLS_EP13_EP7041-3102]^STM Status^Status^Digital input 1;
.bHome:=TIIB[VLS_EP13_EP7041-3102]^ENC Status compact^Status^Status of input C'}
{attribute 'pytmc' := '
pv: CRIX:VLS:CAM:MMS:DIST
field: DESC VLS Camera Translation
'}
M47: DUT_MotionStage;
//Cryo pump
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[DRL02-E23 (EL7041)]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:PTC:Y:MMS:10
field:Cryo Pump Y stage 10
'}
M48: DUT_MotionStage;
{attribute 'TcLinkTo' := ' .bLimitForwardEnable:=TIIB[DRL02-E21 (EL7041)]^STM Status^Status^Digital input 2'}
{attribute 'pytmc' := '
pv: CRIX:PTC:Y:MMS:11
field:Cryo Pump Y stage 11
'}
M49: DUT_MotionStage;
// SL2K2-SCATTER: 4 Axes
{attribute 'pytmc' := 'pv: SL2K2:SCATTER:MMS:BOTTOM'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K2-EL7031-E1]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIIB[SL2K2-EL7031-E1]^STM Status^Status^Digital input 1;
.nRawEncoderUINT := TIIB[SL2K2-EL5101-E2]^ENC Status compact^Counter value'}
M50: DUT_MotionStage := (sName := 'SL2K2:SCATTER:MMS:BOTTOM');
{attribute 'pytmc' := 'pv: SL2K2:SCATTER:MMS:TOP'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K2-EL7031-E3]^STM Status^Status^Digital input 2;
.bLimitBackwardEnable := TIIB[SL2K2-EL7031-E3]^STM Status^Status^Digital input 1;
.nRawEncoderUINT := TIIB[SL2K2-EL5101-E4]^ENC Status compact^Counter value'}
M51: DUT_MotionStage := (sName := 'SL2K2:SCATTER:MMS:TOP');
{attribute 'pytmc' := 'pv: SL2K2:SCATTER:MMS:NORTH'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K2-EL7031-E5]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIIB[SL2K2-EL7031-E5]^STM Status^Status^Digital input 2;
.nRawEncoderUINT := TIIB[SL2K2-EL5101-E6]^ENC Status compact^Counter value'}
M52: DUT_MotionStage := (sName := 'SL2K2:SCATTER:MMS:NORTH');
{attribute 'pytmc' := 'pv: SL2K2:SCATTER:MMS:SOUTH'}
{attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K2-EL7031-E7]^STM Status^Status^Digital input 1;
.bLimitBackwardEnable := TIIB[SL2K2-EL7031-E7]^STM Status^Status^Digital input 2;
.nRawEncoderUINT := TIIB[SL2K2-EL5101-E8]^ENC Status compact^Counter value'}
M53: DUT_MotionStage := (sName := 'SL2K2:SCATTER:MMS:SOUTH');
END_VAR
POUs
F_InRange
FUNCTION F_InRange : BOOL
// Determine if value is between the lower and upper limit
VAR_INPUT
value : LREAL;
lower_limit : LREAL;
upper_limit : LREAL;
END_VAR
VAR
END_VAR
F_InRange := (lower_limit < value) AND (value < upper_limit);
END_FUNCTION
FB_AdjacentStates
FUNCTION_BLOCK FB_AdjacentStates
VAR_IN_OUT
arrTransitionMatrix : ARRAY [*, *] OF BOOL; // adjacency matrix of allowed transitions
arrAdjacentStates : ARRAY [*] OF ST_BFSAssemblyState; // output array of found adjacent states
arrStates : ARRAY [*] OF ST_BFSAssemblyState; // array of assembly states
END_VAR
VAR_INPUT
iRootState : DINT;
END_VAR
VAR_OUTPUT
nAdjacentStates : DINT;
END_VAR
VAR
nStates : DINT;
iCounter : INT;
iState : DINT;
iTransition : DINT;
END_VAR
iCounter := 0;
nStates := UPPER_BOUND(arrStates, 1);
FOR iTransition := 1 TO nStates DO
iState := arrStates[iTransition].iState; // pick out the state index of the state in question
IF iState <> iRootState THEN // only look at transitions away from root state
IF arrTransitionMatrix[iRootState, iTransition] THEN // the transition is allowed
iCounter := iCounter + 1;
arrAdjacentStates[iCounter] := arrStates[iTransition]; // save this adjacent state
END_IF
END_IF
END_FOR
nAdjacentStates := iCounter;
END_FUNCTION_BLOCK
- Related:
FB_AssemblyPositionStateManager
FUNCTION_BLOCK FB_AssemblyPositionStateManager
(*
Handles EPICS moves between multiple states for multiple axes.
See FB_XXXX for an example.
*)
VAR_IN_OUT
// Array of bMoveEnables to, well, enable based on the assembly state.
arrOutputs: ARRAY [*, *] OF DUT_PositionState;
// Array of allowed position state transitions. This is the adjacency matrix
arrTransitions : ARRAY [*, *] OF BOOL;
// Array of all axes in the assembly
arrAxes : ARRAY [*] OF DUT_MotionStage;
// Array of all assembly states
arrAssemblyStates : ARRAY [*] OF STRING;
END_VAR
VAR
nAssemblyStates : DINT;
nAxes :DINT;
nOutputs :DINT;
bInit : BOOL := FALSE;
bAtState : BOOL;
iAxis : DINT;
stAxis : DUT_MotionStage;
stState : DUT_PositionState;
currState : DINT;
nextState : DINT;
END_VAR
IF NOT bInit THEN
bInit := TRUE;
//nAssemblyStates := UPPER_BOUND(arrAssemblyStates, 1);
nAssemblyStates := UPPER_BOUND(arrTransitions, 2); // take from # of columns in transition matrix
nAxes := UPPER_BOUND(arrAxes, 1);
nOutputs := UPPER_BOUND(arrOutputs, 1);
END_IF
// Determine current assembly state
currState := 0; // Start in the unknown state
FOR nextState := 1 TO nOutputs DO // For each defined output state
bAtState := TRUE;
FOR iAxis := 1 TO UPPER_BOUND(arrAxes,1) DO // check each axis for a match with the assembly position state
bAtState := (bAtState AND F_AtPositionState(stMotionStage:=arrAxes[iAxis], stPositionState:=arrOutputs[nextState, iAxis]));
END_FOR
IF bAtState THEN
currState := nextState;
END_IF
END_FOR
// Reset logic before determining allowed moves
FOR nextState := 1 TO UPPER_BOUND(arrAssemblyStates, 1) DO
FOR iAxis := 1 TO UPPER_BOUND(arrAxes, 1) DO
arrOutputs[nextState, iAxis].bMoveOk := FALSE;
END_FOR
END_FOR
// Update motion logic for next state based on current state
FOR nextState := 1 TO nAssemblyStates DO
IF arrTransitions[currState, nextState] THEN
FOR iAxis :=1 TO UPPER_BOUND(arrAxes, 1) DO
arrOutputs[nextState, iAxis].bMoveOk := TRUE;
END_FOR
END_IF
END_FOR
END_FUNCTION_BLOCK
FB_BFS
FUNCTION_BLOCK FB_BFS
VAR_IN_OUT
fbAdjacent : FB_AdjacentStates;
arrTransitions: ARRAY [*, *] OF BOOL;
arrAdjStates: ARRAY [*] OF ST_BFSAssemblyState;
//arrAdjStates : ARRAY [*] OF DINT;
nAdjacentStates : DINT;
arrStates : ARRAY [*] OF ST_BFSAssemblyState;
arrPath : ARRAY [*] OF ST_BFSAssemblyState;
stQueue : ST_Queue;
fbQueue : FB_Queue;
END_VAR
VAR_INPUT
RootState : ST_BFSAssemblyState;
Target : ST_BFSAssemblyState;
END_VAR
VAR_OUTPUT
bError : BOOL; // an error occured, e.g. we didn't find the requested state
END_VAR
VAR
Current : ST_BFSAssemblyState;
Root : ST_BFSAssemblyState;
Adjacent : ST_BFSAssemblyState;
iCounter : DINT;
nStates : DINT;
//
iState : DINT;
iTransition : DINT;
bFound : BOOL := FALSE;
Next : ST_BFSAssemblyState;
iLower : DINT;
iUpper : DINT;
bFirst : BOOL;
END_VAR
THIS^.ClearStates();
Root := THIS^.GetState(iState:=RootState.iState, bDiscover:=TRUE);
fbQueue.Enqueue(Root);
WHILE NOT fbQueue.Queue_Is_Empty() DO
Current := fbQueue.Dequeue();
IF Current.iState = Target.iState THEN // found destination
bFound := TRUE;
EXIT;
ELSE
// Put adjacent states into arrAdjStates, count # of adjacent states
THIS^.GetAdjacentStates(Current.iState);
// Mark any undiscovered states in arrAdjStates, add them to the queue, and label their parent state
THIS^.DiscoverStates();
END_IF
END_WHILE
// Stuff the target in first
//arrPath[1] := arrStates[Target.iState];
arrPath[1] := THIS^.GetState(iState:=Target.iState, bDiscover:=FALSE);
// Get the next state before starting loop
Current := THIS^.GetNextState(PrevState:=Target);
iCounter := 2;
WHILE Current.iParent <> 0 DO
// Stuff state into path array
arrPath[iCounter] := arrStates[Current.iState];
// Locate the next child state
Current := THIS^.GetNextState(PrevState:=Current);
iCounter := iCounter + 1;
IF iCounter >= nStates THEN
EXIT; // Something bad happened. We exceeded the number of possible states.
END_IF
END_WHILE
END_FUNCTION_BLOCK
METHOD ClearStates : BOOL
VAR_INPUT
END_VAR
VAR
Counter : DINT;
END_VAR
FOR Counter := LOWER_BOUND(arrStates,1) TO UPPER_BOUND(arrStates,1) DO // set all states to undiscovered, clear parent states
arrStates[Counter].bDiscovered := FALSE;
arrStates[Counter].iParent := 0;
END_FOR
END_METHOD
METHOD DiscoverStates : BOOL
VAR_INPUT
END_VAR
VAR
Counter : DINT;
END_VAR
FOR Counter := LOWER_BOUND(arrAdjStates,1) TO nAdjacentStates DO // for all adjacent states
Adjacent := arrAdjStates[Counter];
IF NOT arrStates[Adjacent.iState].bDiscovered THEN // check that we haven't visited this one yet
arrStates[Adjacent.iState].bDiscovered := TRUE; // mark state as discovered
arrStates[Adjacent.iState].iParent := Current.iState;
fbQueue.Enqueue(arrStates[Adjacent.iState]); // add state to queue to continue search
END_IF
END_FOR
END_METHOD
METHOD GetAdjacentStates : BOOL
VAR_INPUT
iStartState : DINT; // Node to expand find adjacent nodes from
END_VAR
VAR
stateCounter : DINT;
transitionCounter : DINT;
END_VAR
transitionCounter := 0;
// Loop over all states to find states adjacent to the current state
FOR stateCounter := LOWER_BOUND(arrStates, 1) TO UPPER_BOUND(arrStates,1) DO // start at zero due to arrStates index
iState := arrStates[stateCounter].iState; // pick out the state index of the state in question
IF iState <> iStartState THEN // only look at transitions away from root state
IF arrTransitions[iStartState, stateCounter] THEN // the transition is allowed
transitionCounter := transitionCounter + 1;
arrAdjStates[transitionCounter] := arrStates[stateCounter]; // save this adjacent state
END_IF
END_IF
END_FOR
nAdjacentStates := transitionCounter;
END_METHOD
METHOD GetNextState : ST_BFSAssemblyState
VAR_INPUT
PrevState : ST_BFSAssemblyState;
END_VAR
VAR
Counter : DINT;
END_VAR
// Find next state in path by following parent attribute
FOR Counter := LOWER_BOUND(arrStates, 1) TO UPPER_BOUND(arrStates, 1) DO
IF PrevState.iParent = arrStates[Counter].iState THEN
GetNextState := arrStates[Counter];
EXIT;
END_IF
END_FOR
END_METHOD
METHOD GetState : ST_BFSAssemblyState
VAR_INPUT
iState : DINT;
bDiscover : BOOL := FALSE;
END_VAR
VAR
Counter : DINT;
END_VAR
FOR Counter := LOWER_BOUND(arrStates,1) TO UPPER_BOUND(arrStates,1) DO
IF arrStates[Counter].iState = iState THEN
arrStates[Counter].bDiscovered := bDiscover; // set state to discovered
GetState := arrStates[Counter];
END_IF
END_FOR
END_METHOD
FB_CheckEPS
FUNCTION_BLOCK FB_CheckEPS
VAR_IN_OUT
stMotor : ST_MotionStage;
aEPSLimits : ARRAY [*] OF ST_EPSLimits;
// Allows for user to define what is 'forward' and what is 'backward'. In most cases, use the in_out stMotor as default.
stForwardMotorEPS : DUT_EPS;
stBackwardMotorEPS: DUT_EPS;
END_VAR
VAR_INPUT
// Encoder Position, Current position of motor. Needed for the case where the motor and encoders are seperate. Default use stMotor Position
fPosition : LREAL;
// Ignores EPS
bEPS_Override : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR
nPreviousState : DINT;
nIndex: DINT;
nEPSIndex: DINT;
bUnknownState: BOOL;
fbBwdEPS: FB_EPS;
fbFwdEPS: FB_EPS;
END_VAR
fbBwdEps(eps:=stBackwardMotorEPS);
fbFwdEPS(eps:=stForwardMotorEPS);
// Look through possible states to see which state we are in
bUnknownState := TRUE;
FOR nIndex := LOWER_BOUND(aEPSLimits, 1) TO UPPER_BOUND(aEPSLimits, 1) BY 1 DO
IF aEPSLimits[nIndex].stEPS.bEPS_OK THEN
nEPSIndex := nIndex;
bUnknownState := FALSE; // Known State
exit; // stop when found state
END_IF
END_FOR
IF (nPreviousState <> nEPSIndex) THEN
// only clear stMotor eps from previous state.
fbBwdEPS.setBit(DINT_TO_BYTE(0), TRUE);
fbFwdEPS.setBit(DINT_TO_BYTE(0), TRUE);
END_IF
// Check if position is in plc limit rage, Stop motor if out of Upper/Lower bounds
IF fPosition > aEPSLimits[nEPSIndex].fBwd_Limits THEN
fbBwdEPS.setBit(DINT_TO_BYTE(0), TRUE);
ELSE
fbBwdEPS.setBit(DINT_TO_BYTE(0), FALSE);
END_IF
IF fPosition < aEPSLimits[nEPSIndex].fFwd_Limits THEN
fbFwdEPS.setBit(DINT_TO_BYTE(0), TRUE);
ELSE
fbFwdEPS.setBit(DINT_TO_BYTE(0), FALSE);
END_IF
IF bUnknownState THEN
stBackwardMotorEPS.bEPS_OK := FALSE;
stForwardMotorEPS.bEPS_OK := FALSE;
stBackwardMotorEPS.sMessage := 'UNKNOWN STATE';
stForwardMotorEPS.sMessage := 'UNKNOWN STATE';
ELSE
// Update Labels
stBackwardMotorEPS.sMessage := aEPSLimits[nEPSIndex].stEPS.sMessage;
stForwardMotorEPS.sMessage := aEPSLimits[nEPSIndex].stEPS.sMessage;
END_IF
IF bEPS_Override THEN
stBackwardMotorEPS.bEPS_OK := TRUE;
stForwardMotorEPS.bEPS_OK := TRUE;
END_IF
nPreviousState := nEPSIndex; // Update Previous State
END_FUNCTION_BLOCK
- Related:
FB_DPX
FUNCTION_BLOCK FB_DPX
VAR_IN_OUT
// Motor to apply states to
stMotionStage: DUT_MotionStage;
// Information about the park position
stPark: DUT_PositionState;
// Information about the center parameter
stCenter: DUT_PositionState;
// Information about the knife edge parameter
stKnife: DUT_PositionState;
END_VAR
VAR_INPUT
// If TRUE, the motor will be moved when enumSet is changed
bEnable: BOOL;
// When changed, sets the destination and starts a move
{attribute 'pytmc' := '
pv: SET
io: io
'}
enumSet: ENUM_DPX;
bOverride: BOOL; // Override for state locking. If TRUE, do not lock states.
END_VAR
VAR_OUTPUT
// If TRUE, we are in an error state
bError: BOOL; // NOTE: do not pragma these, already has pragma in manager
// Error code
nErrorId: UDINT;
// Message associated with bError = TRUE
sErrorMessage: STRING;
// If TRUE, we are currently moving between states
bBusy: BOOL;
// If TRUE, we asked for a move between states, it completed successfully, and there is no ongoing move
bDone: BOOL;
// The current state readback
{attribute 'pytmc' := '
pv: GET
io: i
'}
enumGet: ENUM_DPX; // NOTE: Please copy this pragma exactly on your enumGet
END_VAR
VAR
bInit: BOOL;
arrStates: ARRAY[1..15] OF DUT_PositionState;
{attribute 'pytmc' := '
pv:
io: io
'}
fbStateManager: FB_PositionStateManager; // NOTE: Please copy this pragma exactly to pick up the standard PVs
fbLockPark: FB_PositionStateLock;
fbLockCenter: FB_PositionStateLock;
fbLockKnife: FB_PositionStateLock;
END_VAR
// Fist cycle setup
IF NOT bInit THEN
stPark.sName := 'PARK';
stCenter.sName := 'CENTER';
stKnife.sName := 'KNIFE';
bInit := TRUE;
END_IF
// If any of these have bLocked = TRUE, do not allow user to change them
IF NOT bOverride THEN
fbLockPark(stPositionState:=stPark);
fbLockCenter(stPositionState:=stCenter);
fbLockKnife(stPositionState:=stKnife);
END_IF
// Stuff values into the 15 element array for the manager
arrStates[1] := stPark;
arrStates[2] := stCenter;
arrStates[3] := stKnife;
// Call the function block every cycle
fbStateManager(
stMotionStage := stMotionStage,
arrStates := arrStates,
setState := enumSet,
bEnable := bEnable,
bError => bError,
nErrorId => nErrorId,
sErrorMessage => sErrorMessage,
bBusy => bBusy,
bDone => bDone,
getState => enumGet); // Cannot do this assignment if enumGet has attribute strict
END_FUNCTION_BLOCK
- Related:
FB_Queue
FUNCTION_BLOCK FB_Queue
VAR_INPUT
stQ : ST_Queue;
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR
END_FUNCTION_BLOCK
METHOD PUBLIC Dequeue : ST_BFSAssemblyState
VAR_INPUT
END_VAR
IF NOT THIS^.Queue_Is_Empty() THEN
Dequeue := stQ.arrQueue[stQ.iFront];
stQ.iFront := stQ.iFront + 1;
stQ.iCount := stQ.iCount - 1;
END_IF
END_METHOD
METHOD Empty_Queue : BOOL
VAR_INPUT
END_VAR
// Reset queue to ST_Queue initial values
stQ.iCount := 0;
stQ.iBack := -1;
stQ.iFront := 0;
END_METHOD
METHOD PUBLIC Enqueue : BOOL
VAR_INPUT
element : ST_BFSAssemblyState;
END_VAR
IF NOT THIS^.Queue_Is_Full() THEN
IF stQ.iBack = stQ.iLength THEN
stQ.iBack := -1;
END_IF
stQ.iBack := stQ.iBack + 1;
stQ.arrQueue[stQ.iBack] := element;
stQ.iCount := stQ.iCount + 1;
Enqueue := TRUE;
ELSE
Enqueue := FALSE;
END_IF
END_METHOD
METHOD Queue_Is_Empty : BOOL
VAR_INPUT
END_VAR
IF stQ.iCount = 0 THEN
Queue_Is_Empty := TRUE;
ELSE
Queue_Is_Empty := FALSE;
END_IF
END_METHOD
METHOD Queue_Is_Full : BOOL
VAR_INPUT
END_VAR
IF stQ.iCount = stQ.iLength THEN
Queue_Is_Full := TRUE;
ELSE
Queue_Is_Full := FALSE;
END_IF
END_METHOD
- Related:
FB_RCI_Analog_Input
FUNCTION_BLOCK FB_RCI_Analog_Input
VAR_INPUT
// Connect this input to the terminal
iRaw AT %I*: INT;
// The number of bits correlated with the terminal's max value. This is not necessarily the resolution parameter.
iTermBits: UINT;
// The fReal value correlated with the terminal's max value
fTermMax: LREAL;
// The fReal value correlated with the terminal's min value
fTermMin: LREAL;
END_VAR
VAR_OUTPUT
// The real value read from the output
fReal: LREAL;
END_VAR
VAR
fScale: LREAL;
END_VAR
IF fScale = 0 AND fTermMax > fTermMin THEN
fScale := (EXPT(2, iTermBits) - 1) / (fTermMax - fTermMin);
END_IF
IF fScale <> 0 THEN
fReal := iRaw / (fScale/2);
END_IF
END_FUNCTION_BLOCK
FB_RCI_Analog_Output
FUNCTION_BLOCK FB_RCI_Analog_Output
VAR_INPUT
// The real value to send to the output
fReal: LREAL;
// The maximum allowed real value for the connected hardware
fSafeMax: LREAL;
// The minimum allowed real value for the connected hardware
fSafeMin: LREAL;
// The number of bits correlated with the terminal's max output. This is not necessarily the resolution parameter.
iTermBits: UINT;
// The fReal value correlated with the terminal's max output
fTermMax: LREAL;
// The fReal value correlated with the terminal's min output
fTermMin: LREAL;
END_VAR
VAR_OUTPUT
// Connect this output to the terminal
iRaw AT %Q*: INT;
END_VAR
VAR
fScale: LREAL;
END_VAR
// Set the scaling from real to raw
IF fScale = 0 AND fTermMax > fTermMin THEN
fScale := (EXPT(2, iTermBits) - 1) / (fTermMax - fTermMin);
END_IF
// Adjust real value to be within the limits
fReal := MIN(fReal, fSafeMax, fTermMax);
fReal := MAX(fReal, fSafeMin, fTermMin);
// Scale the output accordingly
iRaw := LREAL_TO_INT((fReal) * fScale);
END_FUNCTION_BLOCK
FB_RestTimer
FUNCTION_BLOCK FB_RestTimer
// Resets value of input after some time
// bInput : Value that will reset when set to true after some time passes
// tCountdown : count down when input will be rest
// tElapseTime : Time before input is reset
VAR_IN_OUT
bInput : BOOL;
tCountDown : STRING;
END_VAR
VAR_INPUT
tElapseTime : TIME;
END_VAR
VAR
fbTimer : TON;
END_VAR
fbTimer(IN := bInput, PT:= tElapseTime);
IF bInput THEN
tCountDown := TIME_TO_STRING(tElapseTime - fbTimer.ET);
END_IF
IF fbTimer.Q THEN
bInput := FALSE;
tCountDown := TIME_TO_STRING(T#0s);
END_IF
END_FUNCTION_BLOCK
FB_SLITS
FUNCTION_BLOCK FB_SLITS
VAR_IN_OUT
stTopBlade: DUT_MotionStage;
stBottomBlade: DUT_MotionStage;
stNorthBlade: DUT_MotionStage;
stSouthBlade: DUT_MotionStage;
bExecuteMotion:BOOL ;
io_fbFFHWO : FB_HardwareFFOutput;
fbArbiter: FB_Arbiter();
END_VAR
VAR_INPUT
{attribute 'pytmc' := '
pv: PMPS_OK;
io: i;
field: ZNAM False
field: ONAM True
'}
bMoveOk:BOOL;
(*Offsets*)
{attribute 'pytmc' := '
pv: Offset_Top;
io: io;
'}
rEncoderOffsetTop: REAL;
{attribute 'pytmc' := '
pv: ZeroOffset_Bottom;
io: io;
'}
rEncoderOffsetBottom: REAL;
{attribute 'pytmc' := '
pv: ZeroOffset_North;
io: io;
'}
rEncoderOffsetNorth: REAL;
{attribute 'pytmc' := '
pv: ZeroOffset_South;
io: io;
'}
rEncoderOffsetSouth: REAL;
i_DevName : STRING; //device name for FFO and PMPS diagnostics
{attribute 'pytmc' := '
pv: Home;
io: i;
field: ZNAM False
field: ONAM True
'}
bHome:BOOL:=FALSE;
END_VAR
VAR
fbTopBlade: FB_MotionStage;
fbBottomBlade: FB_MotionStage;
fbNorthBlade: FB_MotionStage;
fbSouthBlade: FB_MotionStage;
fPosTopBlade: LREAL;
fPosBottomBlade: LREAL;
fPosNorthBlade: LREAL;
fPosSouthBlade: LREAL;
(*Motion Parameters*)
fSmallDelta: LREAL := 0.01;
fBigDelta: LREAL := 10;
fMaxVelocity: LREAL := 0.2;
fHighAccel: LREAL := 0.8;
fLowAccel: LREAL := 0.1;
stTop: DUT_PositionState;
stBOTTOM: DUT_PositionState;
stNorth: DUT_PositionState;
stSouth: DUT_PositionState;
{attribute 'pytmc' := 'pv: TOP'}
fbTop: FB_StatePTPMove;
{attribute 'pytmc' := 'pv: BOTTOM'}
fbBottom: FB_StatePTPMove;
{attribute 'pytmc' := 'pv: NORTH'}
fbNorth: FB_StatePTPMove;
{attribute 'pytmc' := 'pv: SOUTH'}
fbSouth: FB_StatePTPMove;
(*EPICS pvs*)
{attribute 'pytmc' := '
pv: XWID_REQ;
io: io;
'}
rReqApertureSizeX : REAL;
{attribute 'pytmc' := '
pv: YWID_REQ;
io: io;
'}
rReqApertureSizeY : REAL;
{attribute 'pytmc' := '
pv: XCEN_REQ;
io: io;
'}
rReqCenterX: REAL;
{attribute 'pytmc' := '
pv: YCEN_REQ;
io: io;
'}
rReqCenterY: REAL;
{attribute 'pytmc' := '
pv: ACTUAL_XWIDTH;
io: io;
'}
rActApertureSizeX : REAL;
{attribute 'pytmc' := '
pv: ACTUAL_YWIDTH;
io: io;
'}
rActApertureSizeY : REAL;
{attribute 'pytmc' := '
pv: ACTUAL_XCENTER;
io: io;
'}
rActCenterX: REAL;
{attribute 'pytmc' := '
pv: ACTUAL_YCENTER;
io: io;
'}
rActCenterY: REAL;
{attribute 'pytmc' := '
pv: XCEN_SETZERO;
io: io;
'}
rSetCenterX: BOOL;
{attribute 'pytmc' := '
pv: YCEN_SETZERO;
io: io;
'}
rSetCenterY: BOOL;
{attribute 'pytmc' := '
pv: OPEN;
io: io;
field: ZNAM False
field: ONAM True
'}
bOpen: BOOL;
{attribute 'pytmc' := '
pv: CLOSE;
io: io;
field: ZNAM False
field: ONAM True
'}
bClose: BOOL;
{attribute 'pytmc' := '
pv: BLOCK;
io: io;
field: ZNAM False
field: ONAM True
'}
bBlock: BOOL;
{attribute 'pytmc' := '
pv: HOME_READY;
io: i;
field: ZNAM False
field: ONAM True
'}
bHomeReady:BOOL:=FALSE;
//Local variables
bInit: BOOL :=true;
rTrig_Block: R_TRIG;
rTrig_Open: R_TRIG;
rTrig_Close: R_TRIG;
//old values
rOldReqApertureSizeX : REAL;
rOldReqApertureSizeY : REAL;
rOldReqCenterX: REAL;
rOldReqCenterY: REAL;
bExecuteMotionX: BOOL;
bExecuteMotionY: BOOL;
fPosBlock: LREAL;
fPosClose: LREAL;
fPosOpen: LREAL;
stSetPositionOptions:ST_SetPositionOptions;
fbSetPosition_TOP: MC_SetPosition;
fbSetPosition_Bottom: MC_SetPosition;
fbSetPosition_North: MC_SetPosition;
fbSetPosition_South: MC_SetPosition;
// For logging
fbLogger : FB_LogMessage := (eSubsystem:=E_SubSystem.MOTION);
tErrorPresent : R_TRIG;
tAction : R_TRIG;
tOverrideActivated : R_TRIG;
FFO : FB_FastFault :=(
i_DevName := 'Slits',
i_Desc := 'Fault occurs when center is greated than that requested',
i_TypeCode := 16#1010);
bTest: BOOL;
AptArrayStatus AT %Q* : ST_PMPS_Aperture_IO;
AptArrayReq AT %I* : ST_PMPS_Aperture_IO;
END_VAR
ACT_init();
// Instantiate Function block for all the blades
ACT_Motion();
//SET and GET the requested and Actual values
ACT_CalculatePositions();
//ACT_BLOCK();
END_FUNCTION_BLOCK
ACTION ACT_BLOCK:
rTrig_Block (CLK:= bBlock);
rTrig_Open (CLK:= bOpen);
rTrig_Close (CLK:= bClose);
if (rTrig_Block.Q) THEN
//BLOCK
bBlock := false;
END_IF
if (rTrig_Open.Q) THEN
bOpen := false;
END_IF
if (rTrig_Close.Q) THEN
bClose := false;
END_IF
END_ACTION
ACTION ACT_CalculatePositions:
//check if requested center or gap has changed
//check that the requested values are within acceptable motion range
IF (rOldReqApertureSizeX <> rReqApertureSizeX) THEN
rOldReqApertureSizeX := rReqApertureSizeX;
bExecuteMotionX := TRUE;
fbLogger(sMsg:='Requested new X gap.', eSevr:=TcEventSeverity.Verbose);
END_IF
IF (rOldReqCenterX <> rReqCenterX) THEN
rOldReqCenterX := rReqCenterX;
bExecuteMotionX := TRUE;
fbLogger(sMsg:='Requested new X center', eSevr:=TcEventSeverity.Verbose);
// ELSE
// rReqCenterX := rActCenterX;
END_IF
IF (rOldReqApertureSizeY <> rReqApertureSizeY) THEN
rOldReqApertureSizeY := rReqApertureSizeY;
bExecuteMotionY := TRUE;
fbLogger(sMsg:='Requested new Y gap.', eSevr:=TcEventSeverity.Verbose);
END_IF
IF (rOldReqCenterY <> rReqCenterY) THEN
rOldReqCenterY := rReqCenterY;
bExecuteMotionY := TRUE;
fbLogger(sMsg:='Requested new Y center.', eSevr:=TcEventSeverity.Verbose);
// ELSE
// rReqCenterY := rActCenterY;
END_IF
//Calculate requested target positions from requested gap and center
fPosTopBlade := (rReqApertureSizeY/2) + (rReqCenterY + rEncoderOffsetTop) ;
fPosBottomBlade := (-1*rReqApertureSizeY/2) + (rReqCenterY+rEncoderOffsetBottom);
fPosNorthBlade := (rReqApertureSizeX/2) + (rReqCenterX + rEncoderOffsetNorth);
fPosSouthBlade := (-1*rReqApertureSizeX/2) + (rReqCenterX + rEncoderOffsetSouth);
//Calculate actual gap and center from actual stages positions
rActApertureSizeX := LREAL_TO_REAL((stNorthBlade.stAxisStatus.fActPosition - rEncoderOffsetNorth) - (stSouthBlade.stAxisStatus.fActPosition- rEncoderOffsetSouth));
rActApertureSizeY := LREAL_TO_REAL((stTopBlade.stAxisStatus.fActPosition - rEncoderOffsetTop) - (stBottomBlade.stAxisStatus.fActPosition - rEncoderOffsetBottom));
rActCenterX := LREAL_TO_REAL((((stNorthBlade.stAxisStatus.fActPosition - rEncoderOffsetNorth) + (stSouthBlade.stAxisStatus.fActPosition - rEncoderOffsetSouth ))/2));
rActCenterY := LREAL_TO_REAL((((stTopBlade.stAxisStatus.fActPosition - rEncoderOffsetTop) + (stBottomBlade.stAxisStatus.fActPosition - rEncoderOffsetBottom))/2));
//Update PMPS Arbiter with the Actual Size and Center of the Aperture
END_ACTION
ACTION ACT_Home:
END_ACTION
ACTION ACT_Init:
// init the motion stages parameters
IF ( bInit) THEN
stTopBlade.bHardwareEnable := TRUE;
stBottomBlade.bHardwareEnable := TRUE;
stNorthBlade.bHardwareEnable := TRUE;
stSouthBlade.bHardwareEnable := TRUE;
stTopBlade.bPowerSelf :=TRUE;
stBottomBlade.bPowerSelf :=TRUE;
stNorthBlade.bPowerSelf :=TRUE;
stSouthBlade.bPowerSelf :=TRUE;
stTopBlade.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
stBottomBlade.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
stNorthBlade.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
stSouthBlade.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
FFO.i_DevName := i_DevName;
END_IF
END_ACTION
ACTION ACT_Motion:
// Instantiate Function block for all the blades
fbTopBlade(stMotionStage:=stTopBlade);
fbBottomBlade(stMotionStage:=stBottomBlade);
fbNorthBlade(stMotionStage:=stNorthBlade);
fbSouthBlade(stMotionStage:=stSouthBlade);
// PTP Motion for each blade
stTop.sName := 'Top';
stTop.fPosition := fPosTopBlade;
stTop.fDelta := fSmallDelta;
stTop.fVelocity := fMaxVelocity;
stTop.fAccel := fHighAccel;
stTop.fDecel := fHighAccel;
stBOTTOM.sName := 'Bottom';
stBOTTOM.fPosition := fPosBottomBlade;
stBOTTOM.fDelta := fSmallDelta;
stBOTTOM.fVelocity := fMaxVelocity;
stBOTTOM.fAccel := fHighAccel;
stBOTTOM.fDecel := fHighAccel;
stNorth.sName := 'North';
stNorth.fPosition := fPosNorthBlade;
stNorth.fDelta := fSmallDelta;
stNorth.fVelocity := fMaxVelocity;
stNorth.fAccel := fHighAccel;
stNorth.fDecel := fHighAccel;
stSouth.sName := 'South';
stSouth.fPosition := fPosSouthBlade;
stSouth.fDelta := fSmallDelta;
stSouth.fVelocity := fMaxVelocity;
stSouth.fAccel := fHighAccel;
stSouth.fDecel := fHighAccel;
IF (bExecuteMotionY) THEN
fbTop.bExecute := fbBottom.bExecute := bExecuteMotionY;
bExecuteMotionY:= FALSE;
END_IF
IF (bExecuteMotionX) THEN
fbNorth.bExecute := fbSouth.bExecute := bExecuteMotionX;
bExecuteMotionX:= FALSE;
END_IF
fbTop(
stPositionState:=stTop,
bMoveOk:=bMoveOk,
stMotionStage:=stTopBlade);
fbBottom(
stPositionState:=stBOTTOM,
bMoveOk:=bMoveOk,
stMotionStage:=stBottomBlade);
fbNorth(
stPositionState:=stNorth,
bMoveOk:=bMoveOk,
stMotionStage:=stNorthBlade);
fbSouth(
stPositionState:=stSouth,
bMoveOk:=bMoveOk,
stMotionStage:=stSouthBlade);
END_ACTION
ACTION ACT_Zero:
//ZERO BIAS
// Set Y center to zero
// Set X center to zero
(*
if (rSetCenterY)THEN
rSetCenterY := false;
// Set Current Position
fbSetPosition_TOP.Position := stTopBlade.stAxisStatus.fActPosition - rActCenterY ;
fbSetPosition_TOP.Execute := TRUE;
fbSetPosition_Bottom.Position := stBottomBlade.stAxisStatus.fActPosition - rActCenterY;
fbSetPosition_Bottom.Execute := TRUE;
END_IF
if (rSetCenterX)THEN
rSetCenterX := false;
// Set Current Position
fbSetPosition_North.Position := stNorthBlade.stAxisStatus.fActPosition - rActCenterX ;
fbSetPosition_North.Execute := TRUE;
fbSetPosition_South.Position := stSouthBlade.stAxisStatus.fActPosition - rActCenterX ; ;
fbSetPosition_South.Execute := TRUE;
END_IF
//Reset
if (fbSetPosition_TOP.Done ) THEN
fbSetPosition_TOP.Execute := FALSE;
END_IF
if (fbSetPosition_Bottom.Done ) THEN
fbSetPosition_Bottom.Execute := FALSE;
END_IF
if (fbSetPosition_North.Done ) THEN
fbSetPosition_North.Execute := FALSE;
END_IF
if (fbSetPosition_South.Done ) THEN
fbSetPosition_South.Execute := FALSE;
END_IF
// Set Encoder Position
//Clear position lag error
stSetPositionOptions.ClearPositionLag := TRUE;
fbSetPosition_TOP(
Axis:= stTopBlade.Axis ,
Execute:= ,
Position:= 0 ,
Mode:= FALSE,
Options:= stSetPositionOptions,
Done=> ,
Busy=> ,
Error=> ,
ErrorID=> );
fbSetPosition_Bottom(
Axis:= stBottomBlade.Axis ,
Execute:= ,
Position:= 0 ,
Mode:= FALSE,
Options:= stSetPositionOptions,
Done=> ,
Busy=> ,
Error=> ,
ErrorID=> );
fbSetPosition_North(
Axis:= stNorthBlade.Axis ,
Execute:= ,
Position:= 0 ,
Mode:= FALSE,
Options:= stSetPositionOptions,
Done=> ,
Busy=> ,
Error=> ,
ErrorID=> );
fbSetPosition_South(
Axis:= stSouthBlade.Axis ,
Execute:= ,
Position:= 0 ,
Mode:= FALSE,
Options:= stSetPositionOptions,
Done=> ,
Busy=> ,
Error=> ,
ErrorID=> );
*)
END_ACTION
METHOD M_CheckPMPS : BOOL
VAR_INPUT
index: int;
END_VAR
IF(rActApertureSizeX < (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Width)+0.001)
OR (rActApertureSizeY < (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Height)+0.001) THEN
FFO.i_xOK := FALSE;
ELSE
FFO.i_xOK := TRUE;
END_IF
(*FAST FAULT*)
FFO(i_xOK := ,
i_xReset := ,
i_xAutoReset :=TRUE,
io_fbFFHWO := this^.io_fbFFHWO);
END_METHOD
METHOD M_UpdatePMPS : BOOL
VAR_INPUT
index: int;
END_VAR
//Keep updating the status of the apertures PMPS
This^.AptArrayStatus.Height := This^.rActApertureSizeY;
This^.AptArrayStatus.Width := This^.rActApertureSizeX;
This^.AptArrayStatus.xOK := NOT (This^.stTopBlade.bError) AND NOT (This^.stBottomBlade.bError)
AND NOT (This^.stNorthBlade.bError) AND NOT (This^.stNorthBlade.bError);
//Evaluate that the current center on the X and the y direction didn't exceed limits
//Fast fault when it does.
IF(rActCenterX > (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Width/2))
OR (rActCenterY > (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Height/2)) THEN
FFO.i_xOK := FALSE;
ELSE
FFO.i_xOK := TRUE;
END_IF
//Evaluate that the requested gaps on the X and the y direction is not larger than the current gap
// narrow the gap if the requested is larger
IF(bTest) THEN
IF (This^.rActApertureSizeX > AptArrayReq.Width) THEN
rReqApertureSizeX := AptArrayReq.Width;
END_IF
IF (This^.rActApertureSizeY > AptArrayReq.Height) THEN
rReqApertureSizeY := AptArrayReq.Height;
END_IF
END_IF
(*FAST FAULT*)
FFO(i_xOK := ,
i_xReset := ,
i_xAutoReset :=TRUE,
io_fbFFHWO := io_fbFFHWO);
END_METHOD
FB_SLITS_POWER
FUNCTION_BLOCK FB_SLITS_POWER EXTENDS FB_SLITS
VAR_INPUT
END_VAR
VAR
{attribute 'pytmc' := '
pv: FSW
'}
fbFlowSwitch: FB_XTES_Flowswitch;
//RTDs
{attribute 'pytmc' := '
pv: TOP:RTD:01
'}
RTD_TOP_1: FB_TempSensor;
{attribute 'pytmc' := '
pv: TOP:RTD:02
'}
RTD_TOP_2: FB_TempSensor;
{attribute 'pytmc' := '
pv: BOTTOM:RTD:01
'}
RTD_Bottom_1: FB_TempSensor;
{attribute 'pytmc' := '
pv: BOTTOM:RTD:02
'}
RTD_Bottom_2: FB_TempSensor;
{attribute 'pytmc' := '
pv: NORTH:RTD:01
'}
RTD_North_1: FB_TempSensor;
{attribute 'pytmc' := '
pv: NORTH:RTD:02
'}
RTD_North_2: FB_TempSensor;
{attribute 'pytmc' := '
pv: SOUTH:RTD:01
'}
RTD_South_1: FB_TempSensor;
{attribute 'pytmc' := '
pv: SOUTH:RTD:02
'}
RTD_South_2: FB_TempSensor;
END_VAR
ACT_RTDs();
END_FUNCTION_BLOCK
ACTION ACT_CalculatePositions:
//check if requested center or gap has changed
//check that the requested values are within acceptable motion range
IF (rOldReqApertureSizeX <> rReqApertureSizeX) THEN
IF (rReqApertureSizeX <= AptArrayReq.Width) THEN
rOldReqApertureSizeX := rReqApertureSizeX;
bExecuteMotionX := TRUE;
fbLogger(sMsg:='Requested new X gap.', eSevr:=TcEventSeverity.Verbose);
ELSE
fbLogger(sMsg:='Requested new X gap is larger than PMPS request.', eSevr:=TcEventSeverity.Verbose);
END_IF
// ELSE
// rReqApertureSizeX := rActApertureSizeX;
END_IF
IF (rOldReqCenterX <> rReqCenterX) THEN
rOldReqCenterX := rReqCenterX;
bExecuteMotionX := TRUE;
fbLogger(sMsg:='Requested new X center', eSevr:=TcEventSeverity.Verbose);
// ELSE
// rReqCenterX := rActCenterX;
END_IF
IF (rOldReqApertureSizeY <> rReqApertureSizeY) THEN
IF rReqApertureSizeY <= AptArrayReq.Height THEN
rOldReqApertureSizeY := rReqApertureSizeY;
bExecuteMotionY := TRUE;
fbLogger(sMsg:='Requested new Y gap.', eSevr:=TcEventSeverity.Verbose);
ELSE
fbLogger(sMsg:='Requested new Y gap is larger than PMPS request.', eSevr:=TcEventSeverity.Verbose);
END_IF
// ELSE
// rReqApertureSizeY := rActApertureSizeY;
END_IF
IF (rOldReqCenterY <> rReqCenterY) THEN
rOldReqCenterY := rReqCenterY;
bExecuteMotionY := TRUE;
fbLogger(sMsg:='Requested new Y center.', eSevr:=TcEventSeverity.Verbose);
// ELSE
// rReqCenterY := rActCenterY;
END_IF
//Calculate requested target positions from requested gap and center
fPosTopBlade := (rReqApertureSizeY/2) + (rReqCenterY + rEncoderOffsetTop) ;
fPosBottomBlade := (-1*rReqApertureSizeY/2) + (rReqCenterY+rEncoderOffsetBottom);
fPosNorthBlade := (rReqApertureSizeX/2) + (rReqCenterX + rEncoderOffsetNorth);
fPosSouthBlade := (-1*rReqApertureSizeX/2) + (rReqCenterX + rEncoderOffsetSouth);
//Calculate actual gap and center from actual stages positions
rActApertureSizeX := LREAL_TO_REAL((stNorthBlade.stAxisStatus.fActPosition - rEncoderOffsetNorth) - (stSouthBlade.stAxisStatus.fActPosition- rEncoderOffsetSouth));
rActApertureSizeY := LREAL_TO_REAL((stTopBlade.stAxisStatus.fActPosition - rEncoderOffsetTop) - (stBottomBlade.stAxisStatus.fActPosition - rEncoderOffsetBottom));
rActCenterX := LREAL_TO_REAL((((stNorthBlade.stAxisStatus.fActPosition - rEncoderOffsetNorth) + (stSouthBlade.stAxisStatus.fActPosition - rEncoderOffsetSouth ))/2));
rActCenterY := LREAL_TO_REAL((((stTopBlade.stAxisStatus.fActPosition - rEncoderOffsetTop) + (stBottomBlade.stAxisStatus.fActPosition - rEncoderOffsetBottom))/2));
//Update PMPS Arbiter with the Actual Size and Center of the Aperture
END_ACTION
ACTION ACT_RTDs:
////RTDs
RTD_TOP_1();
RTD_TOP_2();
RTD_Bottom_1();
RTD_Bottom_2();
RTD_North_1();
RTD_North_2();
RTD_South_1();
RTD_South_2();
//Flow Switch
fbFlowSwitch();
END_ACTION
- Related:
FB_SLITS_SCATTER
FUNCTION_BLOCK FB_SLITS_SCATTER EXTENDS FB_SLITS
VAR_INPUT
END_VAR
VAR
END_VAR
END_FUNCTION_BLOCK
- Related:
PRG_Beamblock
PROGRAM PRG_Beamblock
VAR
fbBEAM_Motor_X : FB_MotionStage;
fbBEAM_Motor_Y : FB_MotionStage;
fbBEAM_Motor_Z : FB_MotionStage;
fbOUTCOUP_Motor_Y : FB_MotionStage;
END_VAR
Main.M30.bHardwareEnable := TRUE;
fbBEAM_Motor_X(stMotionStage:=Main.M30);
Main.M31.bHardwareEnable := TRUE;
fbBEAM_Motor_Y(stMotionStage:=Main.M31);
Main.M32.bHardwareEnable := TRUE;
fbBEAM_Motor_Z(stMotionStage:=Main.M32);
Main.M35.bHardwareEnable := TRUE;
fbOUTCOUP_Motor_Y(stMotionStage:=Main.M35);
END_PROGRAM
- Related:
PRG_BFS
PROGRAM PRG_BFS
VAR
arrDPTransitions : ARRAY [0..9, 1..9] OF BOOL := // Note one more row than columns (Unknown state)
//Park Up Center Pinh. Diode Yag1 Yag2 Yag3 Knife
[FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Unknown (This should always be included)
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Park
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Up
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Center
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Pinhole
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Diode
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag1
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag2
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag3
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE]; // Knife
arrAdjStates : ARRAY [1..9] OF ST_BFSAssemblyState;
nStates : DINT := 9;
iRootState : DINT := 8;
fbAdjacent : FB_AdjacentStates;
iAdjacentStates : DINT;
stQueue : ST_Queue;
fbQueue : FB_Queue;
bInit : BOOL := FALSE;
iResult : DINT;
bResult : BOOL;
arrDiscovered : ARRAY [1..9] OF BOOL := [9(FALSE)];
arrPath : ARRAY [1..9] OF ST_BFSAssemblyState;
iCurrent : DINT;
iTarget : DINT;
Target : ST_BFSAssemblyState;
Root : ST_BFSAssemblyState;
iCounter : DINT;
fbBFS : FB_BFS;
arrStates : ARRAY [1..9] OF ST_BFSAssemblyState;
END_VAR
arrStates[1] := stDPPark;
arrStates[2] := stDPUp;
arrStates[3] := stDPCenter;
arrStates[4] := stDPPinhole;
arrStates[5] := stDPDiode;
arrStates[6] := stDPYag1;
arrStates[7] := stDPYag2;
arrStates[8] := stDPYag3;
arrStates[9] := stDPKnife;
Target := stDPYag3;
Root := stDPPark;
fbBFS(fbAdjacent:=fbAdjacent,
arrTransitions:=arrDPTransitions,
arrAdjStates:=arrAdjStates,
nAdjacentStates:=iAdjacentStates,
arrStates:=arrStates,
stQueue:=stQueue,
fbQueue:=fbQueue,
RootState:=Root,
arrPath:=arrPath,
Target:=Target);
END_PROGRAM
PRG_Camera
PROGRAM PRG_Camera
VAR
fbCAM_Motor_X : FB_MotionStage;
fbCAM_Motor_Y : FB_MotionStage;
END_VAR
Main.M33.bHardwareEnable := TRUE;
fbCAM_Motor_X(stMotionStage:=Main.M33);
Main.M34.bHardwareEnable := TRUE;
fbCAM_Motor_Y(stMotionStage:=Main.M34);
END_PROGRAM
- Related:
PRG_CryoPump
PROGRAM PRG_CryoPump
VAR
fbCryoPump_Motor_Y_10 : FB_MotionStage;
fbCryoPump_Motor_Y_11 : FB_MotionStage;
bEPS_OK_Y_10: BOOL; //Valve is in the Open State And communication ok
bEPS_OK_Y_11: BOOL; //Valve is in the Open State And communication ok
bInit : BOOl := TRUE;
(*Limit switches*)
{attribute 'TcLinkTo' := 'TIIB[DRL02-E23 (EL7041)]^STM Status^Status^Digital input 1'}
bLimitBackwardEnable_Y_10 AT %I* :BOOL;
{attribute 'TcLinkTo' := 'TIIB[DRL02-E21 (EL7041)]^STM Status^Status^Digital input 1'}
bLimitBackwardEnable_Y_11 AT %I* :BOOL;
(*ETHERCAT BRRIDGE COM STATUS*)
//0: Other side is in OP state, >0: Error
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^SYNC Inputs^TxPDO state
'}
xEcatBridge_TxPDO_state AT %I* :BOOL;
//0: External device connectd, 1: External device not connected
{attribute := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^SYNC Inputs^External device not connected
'}
xEcatBridge_External_device_not_connected AT %I* : BOOL;
//0 = Data valid, 1 = Data invalid
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^WcState^WcState
'}
xEcatBridge_WcState AT %I* : BOOL;
//Inputs
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bCRYO_VGC_01_CLS'}
bCRYO_VGC_01_CLS AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bCRYO_VGC_01_OPN'}
bCRYO_VGC_01_OPN AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bCRYO_VGC_02_CLS'}
bCRYO_VGC_02_CLS AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bCRYO_VGC_02_OPN'}
bCRYO_VGC_02_OPN AT %I* : BOOL;
//Outputs
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTY10_IN'}
bMOTY10_IN AT %Q* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTY10_OUT'}
bMOTY10_OUT AT %Q* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTY11_IN'}
bMOTY11_IN AT %Q* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTY11_OUT'}
bMOTY11_OUT AT %Q* : BOOL;
END_VAR
IF ( bInit) THEN
bInit := FALSE;
Main.M48.bHardwareEnable := TRUE; //Linked to valve state
Main.M48.bPowerSelf := TRUE;
Main.M48.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M48.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M49.bHardwareEnable := TRUE; //Linked to valve state
Main.M49.bPowerSelf := TRUE;
Main.M49.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M49.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
//Homing routine parameters
Main.M48.fHomePosition:= 0;
Main.M48.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT;
Main.M49.fHomePosition:= 0;
Main.M49.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT;
END_IF
fbCryoPump_Motor_Y_10(stMotionStage:=Main.M48);
fbCryoPump_Motor_Y_11(stMotionStage:=Main.M49);
//Interface
bMOTY10_IN := NOT bLimitBackwardEnable_Y_10;
bMOTY10_OUT := NOT Main.M48.bLimitForwardEnable;
bMOTY11_IN := NOT bLimitBackwardEnable_Y_11;
bMOTY11_OUT := NOT Main.M49.bLimitForwardEnable;
bEPS_OK_Y_10 := (NOT bCRYO_VGC_01_CLS) AND bCRYO_VGC_01_OPN AND NOT (xEcatBridge_External_device_not_connected) AND NOT (xEcatBridge_WcState) AND NOT (xEcatBridge_TxPDO_state);
bEPS_OK_Y_11 := (NOT bCRYO_VGC_02_CLS) AND bCRYO_VGC_02_OPN AND NOT (xEcatBridge_External_device_not_connected) AND NOT (xEcatBridge_WcState) AND NOT (xEcatBridge_TxPDO_state);
//Handle EPS
Main.M48.bLimitBackwardEnable := bEPS_OK_Y_10 AND bLimitBackwardEnable_Y_10;
Main.M49.bLimitBackwardEnable := bEPS_OK_Y_11 AND bLimitBackwardEnable_Y_11;
END_PROGRAM
- Related:
PRG_Cryopumps
PROGRAM PRG_Cryopumps
VAR
// Motor axes
stCP1Motor : DUT_MotionStage;
stCP2Motor : DUT_MotionStage;
// Define axis states for each axis. These are fed to a FB_PositionState manager for each axis
// Rotation axis position states
stCP1PosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
// Y axis position states
stCP2PosPark : DUT_PositionState := (sName:= 'PARK',
fPosition := 0.0,
fDelta:=1.0,
fVelocity:=5.0,
fAccel:=1.0,
fDecel:=1.0,
bMoveOk:=FALSE,
bLocked:=TRUE,
bValid:=TRUE);
END_VAR
END_PROGRAM
PRG_CryoStat
PROGRAM PRG_CryoStat
VAR
fbCRYO_Motor_X : FB_MotionStage;
fbCRYO_Motor_Y : FB_MotionStage;
fbCRYO_Motor_Z : FB_MotionStage;
fbCRYO_Motor_rY : FB_MotionStage;
END_VAR
Main.M22.bHardwareEnable := TRUE;
fbCRYO_Motor_X(stMotionStage:=Main.M22);
Main.M23.bHardwareEnable := TRUE;
fbCRYO_Motor_Y(stMotionStage:=Main.M23);
Main.M24.bHardwareEnable := TRUE;
fbCRYO_Motor_Z(stMotionStage:=Main.M24);
Main.M25.bHardwareEnable := TRUE;
fbCRYO_Motor_rY(stMotionStage:=Main.M25);
Main.M25.bLimitBackwardEnable:=TRUE;
Main.M25.bLimitForwardEnable:=TRUE;
END_PROGRAM
- Related:
PRG_DiagnosticPaddle
PROGRAM PRG_DiagnosticPaddle
(* Program for the ChemRIXS diagnostic paddle. This program sets up a series of PositionStateManagers to implement
the necessary logic to protect the assembly from running into the recirculation system tube and catcher. *)
// TODO: Setup position state locks?
VAR_INPUT
xMoveOK : BOOL := FALSE; // External interlock. Applied to bEnable of all PositionStateManagers.
END_VAR
VAR
bInit : BOOL := FALSE; // Initialization variable
//iCounter : UDINT; // loop counter
// Setup Assembly manager to set bMoveOK for appropriate states
fbDPAssemblyManager : FB_AssemblyPositionStatemanager;
// Array of axes for protection FB
arrDPAxes : ARRAY [1..3] OF DUT_MotionStage := [stDPXMotor, stDPYMotor, stDPZMotor];
// Setup diagnostic paddle adjacency matrix
arrDPTransitions : ARRAY [0..9, 1..9] OF BOOL :=
//Park Up Center Pinh. Diode Yag1 Yag2 Yag3 Knife
[FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Unknown (This should always be included)
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Park
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Up
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Center
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Pinhole
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Diode
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag1
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag2
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag3
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE]; // Knife
// Setup diagnostic paddle output matrix
arrDPOutputs : ARRAY [1..9, 1..3] OF DUT_PositionState :=
//X axis Y axis Z axis Assembly state
[stDPXPosPark, stDPYPosPark, stDPZPosPark, // Park
stDPXPosPark, stDPYPosCenter, stDPZPosPark, // Up
stDPXPosCenter, stDPYPosCenter, stDPZPosCenter, // Center
stDPXPosCenter, stDPYPosPinhole, stDPZPosCenter, // Pinhole
stDPXPosCenter, stDPYPosDiode, stDPZPosCenter, // Diode
stDPXPosCenter, stDPYPosYag1, stDPZPosCenter, // Yag1
stDPXPosCenter, stDPYPosYag2, stDPZPosCenter, // Yag2
stDPXPosCenter, stDPYPosYag3, stDPZPosCenter, // Yag3
stDPXPosCenter, stDPYPosKnife, stDPZPosCenter]; // Knife
// TODO: Figure out a way to make this more useful, or remove it.
arrDPStates : ARRAY[0..9] OF STRING := ['UNKNOWN', 'PARK', 'UP', 'CENTER',
'PINHOLE', 'DIODE', 'YAG1', 'YAG2',
'YAG3', 'KNIFE'];
// Array of position states for PositionStateManagers (initialize later)
arrDPXStates : ARRAY [1..15] OF DUT_PositionState := [stDPXPosPark,stDPXPosCenter,stDPXPosKnife];
arrDPYStates : ARRAY [1..15] OF DUT_PositionState := [stDPYPosPark,stDPYPosCenter,stDPYPosPinhole,stDPYPosDiode,stDPYPosYag1,
stDPYPosYag2,stDPYPosYag3,stDPYPosKnife];
arrDPZStates : ARRAY [1..15] OF DUT_PositionState := [stDPZPosPark,stDPZPosCenter];
// Setup PositionStateManagers and set variables for each axis
// X Axis
// When changed, sets the destination and starts a move
{attribute 'pytmc' := '
pv: SET
io: io
'}
enumDPXSet: ENUM_DPX; // NOTE: Please copy this pragma exactly on your enumSet
{attribute 'pytmc' := '
pv:
io: io
'}
fbXStateManager: FB_PositionStateManager;
// Y axis
// When changed, sets the destination and starts a move
{attribute 'pytmc' := '
pv: SET
io: io
'}
enumDPYSet: ENUM_DPY; // NOTE: Please copy this pragma exactly on your enumSet
{attribute 'pytmc' := '
pv:
io: io
'}
fbYStateManager: FB_PositionStateManager;
// Z axis
// When changed, sets the destination and starts a move
{attribute 'pytmc' := '
pv: SET
io: io
'}
enumDPZSet: ENUM_DPZ; // NOTE: Please copy this pragma exactly on your enumSet
{attribute 'pytmc' := '
pv:
io: io
'}
fbZStateManager: FB_PositionStateManager;
arrPosLocks : ARRAY [1..13] OF FB_PositionStateLock;
END_VAR
VAR_OUTPUT
// Setup PositionStateManager Outputs
// X Axis
// If TRUE, we are in an error state
bDPXError: BOOL; // NOTE: do not pragma these, already has pragma in manager
// Error code
nDPXErrorId: UDINT;
// Message associated with bError = TRUE
sDPXErrorMessage: STRING;
// If TRUE, we are currently moving between states
bDPXBusy: BOOL;
// If TRUE, we asked for a move between states, it completed successfully, and there is no ongoing move
bDPXDone: BOOL;
// The current state readback
{attribute 'pytmc' := '
pv: GET
io: i
'}
enumDPXGet: ENUM_DPX; // NOTE: Please copy this pragma exactly on your enumGet
// Y Axis
// If TRUE, we are in an error state
bDPYError: BOOL; // NOTE: do not pragma these, already has pragma in manager
// Error code
nDPYErrorId: UDINT;
// Message associated with bError = TRUE
sDPYErrorMessage: STRING;
// If TRUE, we are currently moving between states
bDPYBusy: BOOL;
// If TRUE, we asked for a move between states, it completed successfully, and there is no ongoing move
bDPYDone: BOOL;
// The current state readback
{attribute 'pytmc' := '
pv: GET
io: i
'}
enumDPYGet: ENUM_DPY; // NOTE: Please copy this pragma exactly on your enumGet
// Z Axis
// If TRUE, we are in an error state
bDPZError: BOOL; // NOTE: do not pragma these, already has pragma in manager
// Error code
nDPZErrorId: UDINT;
// Message associated with bError = TRUE
sDPZErrorMessage: STRING;
// If TRUE, we are currently moving between states
bDPZBusy: BOOL;
// If TRUE, we asked for a move between states, it completed successfully, and there is no ongoing move
bDPZDone: BOOL;
// The current state readback
{attribute 'pytmc' := '
pv: GET
io: i
'}
enumDPZGet: ENUM_DPZ; // NOTE: Please copy this pragma exactly on your enumGet
END_VAR
IF NOT bInit THEN
bInit := TRUE;
END_IF
// Manage the logic between the Diagnostic Paddle axes
fbDPAssemblyManager(arrOutputs:=arrDPOutputs,
arrTransitions:=arrDPTransitions,
arrAxes:=arrDPAxes,
arrAssemblyStates:=arrDPStates);
// Update positions based on motion requests
fbXStateManager(
stMotionStage := stDPXMotor,
arrStates := arrDPXStates,
setState := enumDPXSet,
bEnable := xMoveOK,
bError => bDPXError,
nErrorId => nDPXErrorId,
sErrorMessage => sDPXErrorMessage,
bBusy => bDPXBusy,
bDone => bDPXDone,
getState => enumDPXGet);
fbYStateManager(
stMotionStage := stDPYMotor,
arrStates := arrDPYStates,
setState := enumDPYSet,
bEnable := xMoveOK,
bError => bDPYError,
nErrorId => nDPYErrorId,
sErrorMessage => sDPYErrorMessage,
bBusy => bDPYBusy,
bDone => bDPYDone,
getState => enumDPYGet);
fbZStateManager(
stMotionStage := stDPZMotor,
arrStates := arrDPZStates,
setState := enumDPZSet,
bEnable := xMoveOK,
bError => bDPZError,
nErrorId => nDPZErrorId,
sErrorMessage => sDPZErrorMessage,
bBusy => bDPZBusy,
bDone => bDPZDone,
getState => enumDPZGet);
END_PROGRAM
PRG_DiagnosticPaddleMotors
PROGRAM PRG_DiagnosticPaddleMotors
VAR
fbDPX_Motor : FB_MotionStage;
fbDPY_Motor : FB_MotionStage;
fbDPZ_Motor : FB_MotionStage;
END_VAR
Main.M1.bHardwareEnable := TRUE;
fbDPX_Motor(stMotionStage:=Main.M1);
//// Deal with bad limit switch on Y stage
//Main.M2.bLimitBackwardEnable := TRUE;
//Main.M2.bLimitForwardEnable := TRUE;
Main.M2.bHardwareEnable := TRUE;
fbDPY_Motor(stMotionStage:=Main.M2);
Main.M3.bHardwareEnable := TRUE;
fbDPZ_Motor(stMotionStage:=Main.M3);
END_PROGRAM
- Related:
PRG_DPL_X_EPS
PROGRAM PRG_DPL_X_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:X:EPS'}
aDPL_X_EPS : ARRAY [1 .. 3] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:X:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:X:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aDPL_X_EPS[1].fBwd_Limits := 10;
aDPL_X_EPS[1].fFwd_Limits := 80;
aDPL_X_EPS[2].fBwd_Limits := 10;
aDPL_X_EPS[2].fFwd_Limits := 30;
aDPL_X_EPS[3].fBwd_Limits := 60;
aDPL_X_EPS[3].fFwd_Limits := 80;
bInit := FALSE;
END_IF
fbEPS(eps:=aDPL_X_EPS[2].stEPS);
fbEPS.setMessage('SDS_RX in [124, 215');
fbEPS.setBit(0, F_InRange(fSDS_RX, 124, 215));
fbEPS(eps:=aDPL_X_EPS[3].stEPS);
fbEPS.setMessage('DPL_Z in [-10, 30]');
fbEPS.setBit(0, F_InRange(fDPL_Z, -10, 30));
bFullRange := (NOT aDPL_X_EPS[2].stEPS.bEPS_OK) AND (NOT aDPL_X_EPS[3].stEPS.bEPS_OK);
fbEPS(eps:=aDPL_X_EPS[1].stEPS);
fbEPS.setMessage('Full Range');
fbEPS.setBit(0, bFullRange);
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:= M1, fPosition:=fDPL_X, aEPSLimits:= aDPL_X_EPS, stForwardMotorEPS:=M1.stEPSForwardEnable, stBackwardMotorEPS:= M1.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_DPL_Y_EPS
PROGRAM PRG_DPL_Y_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Y:EPS'}
aDPL_Y_EPS : ARRAY [1 .. 2] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Y:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Y:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aDPL_Y_EPS[1].fBwd_Limits := -1;
aDPL_Y_EPS[1].fFwd_Limits := 80;
aDPL_Y_EPS[2].fBwd_Limits := 40;
aDPL_Y_EPS[2].fFwd_Limits := 80;
bInit := FALSE;
END_IF
fbEPS(eps:=aDPL_Y_EPS[2].stEPS);
fbEPS.setMessage('DPL_Z in [-10,30];RCC in [-15,11]');
fbEPS.setBit(0, F_InRange(fDPL_Z, -10, 30));
fbEPS.setBit(1, F_InRange(fRCC_Z, -15, 11));
bFullRange := NOT aDPL_Y_EPS[2].stEPS.bEPS_OK;
fbEPS(eps:=aDPL_Y_EPS[1].stEPS);
fbEPS.setMessage('Full Range');
fbEPS.setBit(0, bFullRange);
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M2, fPosition:=M2.stAxisStatus.fActPosition, aEPSLimits:=aDPL_Y_EPS, stForwardMotorEPS:=M2.stEPSForwardEnable, stBackwardMotorEPS:= M2.stEPSBackwardEnable, bEPS_Override:= bEPS_Override);
END_PROGRAM
- Related:
PRG_DPL_Z_EPS
PROGRAM PRG_DPL_Z_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Z:EPS'}
aDPL_Z_EPS : ARRAY [1 .. 4] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Z:EPS:OVRD_MODE'}
bEPS_Override: BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:DPL:MMS:Z:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aDPL_Z_EPS[1].fBwd_Limits := -10;
aDPL_Z_EPS[1].fFwd_Limits := 100;
aDPL_Z_EPS[2].fBwd_Limits := 30;
aDPL_Z_EPS[2].fFwd_Limits := 100;
aDPL_Z_EPS[3].fBwd_Limits := 30;
aDPL_Z_EPS[3].fFwd_Limits := 100;
aDPL_Z_EPS[4].fBwd_Limits := 30;
aDPL_Z_EPS[4].fFwd_Limits := 100;
bInit := FALSE;
END_IF
fbEPS(eps:=aDPL_Z_EPS[2].stEPS);
fbEPS.setMessage('DPL X in [10,30]');
fbEPS.setBit(0, F_InRange(fDPL_X, 10, 60));
fbEPS(eps:=aDPL_Z_EPS[3].stEPS);
fbEPS.setMessage('RCC Y in [-34,10];RCC_Z in [-15,11]');
fbEPS.setBit(0, F_InRange(fRCC_Y, -34, 10));
fbEPS.setBit(1, F_InRange(fRCC_Z, -15, 11));
fbEPS(eps:=aDPL_Z_EPS[4].stEPS);
fbEPS.setMessage('RCC_Y in [-38,-34];RCC_Z in [-15,11];DPL_Y in [-1,40]');
fbEPS.setBit(0, F_InRange(fRCC_Y, -38, -34));
fbEPS.setBit(1, F_InRange(fRCC_Z, -15, 11));
fbEPS.setBit(2, F_InRange(fDPL_Y, -1, 40));
bFullRange := (NOT aDPL_Z_EPS[2].stEPS.bEPS_OK) AND (NOT aDPL_Z_EPS[3].stEPS.bEPS_OK) AND (NOT aDPL_Z_EPS[4].stEPS.bEPS_OK);
fbEPS(eps:=aDPL_Z_EPS[1].stEPS);
fbEPS.setMessage('Full Range');
fbEPS.setBit(0, bFullRange);
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M3, fPosition:=fDPL_Z, aEPSLimits:= aDPL_Z_EPS, stForwardMotorEPS:=M3.stEPSForwardEnable, stBackwardMotorEPS:= M3.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_EPS
PROGRAM PRG_EPS
VAR
END_VAR
// Update Motor Positions before Using them in EPS Checks
fDPL_X := M1.stAxisStatus.fActPosition;
fSDS_RX := M19.stAxisStatus.fActPosition;
fSDS_Y := M17.stAxisStatus.fActPosition;
fSDS_Z_ENC := M36.stAxisStatus.fActPosition;
fDPL_Z := M3.stAxisStatus.fActPosition;
fDPL_Y := M2.stAxisStatus.fActPosition;
fRCC_Z := M39.stAxisStatus.fActPosition;
fRCC_Y := M38.stAxisStatus.fActPosition;
PRG_SDS_Y_EPS();
PRG_SDS_RX_EPS();
PRG_SDS_ZENCODER_EPS();
PRG_DPL_X_EPS();
PRG_DPL_Y_EPS();
PRG_DPL_Z_EPS();
PRG_RCC_Y_EPS();
PRG_RCC_Z_EPS();
END_PROGRAM
PRG_FiberLite
PROGRAM PRG_FiberLite
VAR
END_VAR
// Set LED output scaling (Fiber-Lite)
bLedOutput1.iTermBits := 14;
bLedOutput1(fbSetIllPercent=>);
bLedOutput2.iTermBits := 14;
bLedOutput2();
END_PROGRAM
PRG_Illumination
PROGRAM PRG_Illumination
(* Program for the ChemRIXS illumination system. *)
VAR_INPUT
xMoveOK : BOOL := FALSE; // External interlock. Applied to bEnable of all PositionStateManagers.
END_VAR
VAR
bInit : BOOL := TRUE; // Initialization variable
END_VAR
IF ( bInit) THEN
bInit := FALSE;
Main.M9.bHardwareEnable := TRUE;
Main.M10.bHardwareEnable := TRUE;
Main.M11.bHardwareEnable := TRUE;
END_IF
fbILMXStage(stMotionStage := Main.M9);
fbILMYStage(stMotionStage := Main.M10);
fbILMZStage(stMotionStage := Main.M11);
END_PROGRAM
- Related:
PRG_InjectorMotors
PROGRAM PRG_InjectorMotors
VAR
fbSDSX_Motor : FB_MotionStage;
fbSDSY_Motor : FB_MotionStage;
fbSDSZ_Motor : FB_MotionStage;
fbSDSRY_Motor : FB_MotionStage;
fbSDSShroud_Motor : FB_MotionStage;
fbSDSZEncoder: FB_MotionStage;
bEPS_OK_SDSZ_18: BOOL; //Valve is in the Open State And communication ok
bInit : BOOL := TRUE;
//Limit Switch
{attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^DRL02-E27 (EL7031)^STM Status^Status^Digital input 2'}
bLimitBackwardEnable_SDSZ_18 AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bSDS_VGC_01_CLS'}
bSDS_VGC_01_CLS AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Inputs^bSDS_VGC_01_OPN'}
bSDS_VGC_01_OPN AT %I* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTSDSZ18_IN'}
bMOTSDSZ18_IN AT %Q* : BOOL;
{attribute 'TcLinkTo' := 'TIIB[CRIX_VAC_INTF (EL6695-0002)]^IO Outputs^bMOTSDSZ18_OUT'}
bMOTSDSZ18_OUT AT %Q* : BOOL;
// Hall Effect Limits for SDS X Stage
{attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 173 (EL1124)^Channel 3^Input'}
bHall_Forward AT %I* : BOOL;
nHall_Forward_Cycles: UINT;
{attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 5 (EK1200)^Term 6 (EK1122-0080)^DRL02-EK0 (EK1101-0080)^Term 173 (EL1124)^Channel 4^Input'}
bHall_Backward AT %I*: BOOL;
nHall_Backward_Cycles: UINT;
nNumCyclesNeeded: UINT := 10;
END_VAR
if (bInit) THEN
// X Motor
Main.M16.bHardwareEnable := TRUE;
Main.M16.nHomingMode := ENUM_EpicsHomeCmd.ABSOLUTE_SET;
// Y motor
Main.M17.bHardwareEnable := TRUE;
// Z Motor
Main.M18.bHardwareEnable := TRUE;
// Y Rotation Motor
Main.M19.bHardwareEnable := TRUE;
Main.M19.bLimitForwardEnable := TRUE;
Main.M19.bLimitBackwardEnable := TRUE;
// Shroud Motor
Main.M20.bHardwareEnable := TRUE;
Main.M20.bLimitForwardEnable := TRUE;
Main.M20.bLimitBackwardEnable := TRUE;
END_IF
fbSDSX_Motor(stMotionStage:=Main.M16);
fbSDSY_Motor(stMotionStage:=Main.M17);
fbSDSZ_Motor(stMotionStage:=Main.M18);
fbSDSRY_Motor(stMotionStage:=Main.M19);
fbSDSShroud_Motor(stMotionStage:=Main.M20);
fbSDSZEncoder(stMotionStage:=Main.M36);
bMOTSDSZ18_OUT := NOT Main.M18.bLimitForwardEnable;
bMOTSDSZ18_IN := NOT bLimitBackwardEnable_SDSZ_18;
bEPS_OK_SDSZ_18 := (NOT bSDS_VGC_01_CLS) AND bSDS_VGC_01_OPN AND NOT (PRG_CryoPump.xEcatBridge_External_device_not_connected) AND NOT (PRG_CryoPump.xEcatBridge_WcState) AND NOT (PRG_CryoPump.xEcatBridge_TxPDO_state);
Main.M18.bLimitBackwardEnable := bEPS_OK_SDSZ_18 AND bLimitBackwardEnable_SDSZ_18;
// X Stage Groundswitching Limits Logic
//Cycle counting code for dealing with interference
IF bHall_Forward THEN
nHall_Forward_Cycles := MIN(nHall_Forward_Cycles + 1, nNumCyclesNeeded);
ELSE
nHall_Forward_Cycles := 0;
END_IF
IF bHall_Backward THEN
nHall_Backward_Cycles := MIN(nHall_Backward_Cycles + 1, nNumCyclesNeeded);
ELSE
nHall_Backward_Cycles := 0;
END_IF
Main.M16.bLimitForwardEnable := nHall_Forward_Cycles < nNumCyclesNeeded;
Main.M16.bLimitBackwardEnable := nHall_Backward_Cycles < nNumCyclesNeeded;
END_PROGRAM
- Related:
PRG_Main
PROGRAM PRG_Main
VAR
//stTestMotor1 : DUT_SimMotor;
//fbTestMotor : FB_SIM_MOTOR;
bInit : BOOL := FALSE;
DPState : INT;
arrStates : ARRAY [1..9] OF ENUM_DiagPaddle;
bDPaddleOK : BOOL;
END_VAR
IF NOT bInit THEN
bInit := TRUE;
END_IF
// Add interlock logic to this later
bDPaddleOK := TRUE;
//PRG_DiagnosticPaddle(xMoveOK:=bDPaddleOK);
//PRG_QueueTest();
//PRG_Test_AdjacentStates();
//PRG_BFS();
PRG_EPS();
PRG_DiagnosticPaddleMotors();
PRG_QuestarMotors();
PRG_PointDetectorMotors();
PRG_CryoStat();
PRG_RCI();
PRG_Camera();
PRG_Beamblock();
PRG_ObjectivesMotors();
PRG_RCC();
PRG_VLS();
PRG_InjectorMotors();
PRG_Illumination();
PRG_CryoPump();
PRG_FiberLite();
PRG_PMPS();
END_PROGRAM
- Related:
PRG_ObjectivesMotors
PROGRAM PRG_ObjectivesMotors
VAR
fbOBJX_Motor : FB_MotionStage;
fbOBJY_Motor : FB_MotionStage;
fbOBJZ_Motor : FB_MotionStage;
END_VAR
Main.M4.bHardwareEnable := TRUE;
fbOBJX_Motor(stMotionStage:=Main.M4);
Main.M5.bHardwareEnable := TRUE;
fbOBJY_Motor(stMotionStage:=Main.M5);
Main.M6.bHardwareEnable := TRUE;
fbOBJZ_Motor(stMotionStage:=Main.M6);
END_PROGRAM
- Related:
PRG_PMPS
PROGRAM PRG_PMPS
VAR
fbArbiterIO : FB_SubSysToArbiter_IO;
ff2_ff1_link: FB_FastFault := (i_xAutoReset := TRUE, i_DevName := 'FF2 to FF1 Link', i_Desc := 'This is virtual FF2 fault, Please check the faulting device below', i_TypeCode := 16#9999);
END_VAR
(*Fast Fault instantiation*)
GVL_PMPS.g_FastFaultOutput1.bAutoReset :=TRUE;
GVL_PMPS.g_FastFaultOutput2.bAutoReset :=TRUE;
GVL_PMPS.g_FastFaultOutput1.Execute(i_xVeto := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]
AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN])
OR PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2]);
GVL_PMPS.g_FastFaultOutput2.Execute(i_xVeto := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]
AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN])
OR PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2]);
(* Arbiter Instantiation*)
fbArbiterIO(Arbiter := GVL_PMPS.fbArbiter1, fbFFHWO := GVL_PMPS.g_FastFaultOutput1, i_bVeto := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]
AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN])
OR PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2]);
//routed to the arbiter
ff2_ff1_link(
io_fbFFHWO := GVL_PMPS.g_FastFaultOutput2,
i_xOK := GVL_PMPS.g_FastFaultOutput1.q_xFastFaultOut);
GVL_PMPS.fbArbiter1.AddRequest(nReqID := 16#FAFA, stReqBp := PMPS_GVL.cstFullBeam, sDevName :='plc-crix-mot');
END_PROGRAM
- Related:
PRG_PointDetectorMotors
PROGRAM PRG_PointDetectorMotors
VAR
fbPDETY_Motor : FB_MotionStage;
fbPDETTheta_Motor : FB_MotionStage;
END_VAR
Main.M7.bHardwareEnable := TRUE;
fbPDETY_Motor(stMotionStage:=Main.M7);
Main.M8.bHardwareEnable := TRUE;
fbPDETTheta_Motor(stMotionStage:=Main.M8);
END_PROGRAM
- Related:
PRG_QuestarMotors
PROGRAM PRG_QuestarMotors
VAR
fbQSTX_Motor : FB_MotionStage;
fbQSTY_Motor : FB_MotionStage;
END_VAR
Main.M12.bHardwareEnable := TRUE;
fbQSTX_Motor(stMotionStage:=Main.M12);
Main.M13.bHardwareEnable := TRUE;
fbQSTY_Motor(stMotionStage:=Main.M13);
END_PROGRAM
- Related:
PRG_QueueTest
PROGRAM PRG_QueueTest
VAR
stQueue : ST_Queue;
fbQueue : FB_Queue;
bInit : BOOL := FALSE;
iResult : DINT;
bResult : BOOL;
END_VAR
fbQueue.Enqueue(1);
fbQueue.Enqueue(2);
fbQueue.Enqueue(3);
fbQueue.Enqueue(4);
fbQueue.Enqueue(5);
fbQueue.Enqueue(6);
fbQueue.Enqueue(7);
fbQueue.Enqueue(8);
fbQueue.Enqueue(9);
fbQueue.Enqueue(10);
fbQueue.Enqueue(11);
iResult := fbQueue.Dequeue(); // 1
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue(); // 5
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue();
iResult := fbQueue.Dequeue(); // 10
iResult := fbQueue.Dequeue(); // element 11; should fail
END_PROGRAM
PRG_RCC
PROGRAM PRG_RCC
VAR
fbRCC_Motor_X : FB_MotionStage;
fbRCC_Motor_Y : FB_MotionStage;
fbRCC_Motor_Z : FB_MotionStage;
bInit : BOOl := TRUE;
END_VAR
IF ( bInit) THEN
bInit := FALSE;
Main.M37.bHardwareEnable := TRUE;
Main.M37.bPowerSelf := TRUE;
Main.M37.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M37.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M38.bHardwareEnable := TRUE;
Main.M38.bPowerSelf := TRUE;
Main.M38.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M38.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M39.bHardwareEnable := TRUE;
Main.M39.bPowerSelf := TRUE;
Main.M39.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M39.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
END_IF
fbRCC_Motor_X(stMotionStage:=Main.M37);
fbRCC_Motor_Y(stMotionStage:=Main.M38);
fbRCC_Motor_Z(stMotionStage:=Main.M39);
END_PROGRAM
- Related:
PRG_RCC_Y_EPS
PROGRAM PRG_RCC_Y_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Y:EPS'}
aRCC_Y_EPS : ARRAY [1 .. 4] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Y:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Y:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aRCC_Y_EPS[1].fBwd_Limits := -38;
aRCC_Y_EPS[1].fFwd_Limits := 10;
aRCC_Y_EPS[2].fBwd_Limits := -38;
aRCC_Y_EPS[2].fFwd_Limits := -34;
aRCC_Y_EPS[3].fBwd_Limits := -38;
aRCC_Y_EPS[3].fFwd_Limits := -34;
aRCC_Y_EPS[4].fBwd_Limits := -38;
aRCC_Y_EPS[4].fFwd_Limits := 0; // VARIBLE
bInit := FALSE;
END_IF
fbEPS(eps:=aRCC_Y_EPS[2].stEPS);
fbEPS.setMessage('SDS_RX in [124, 215];SDS_Z_ENC in [3.05, 3.8]');
fbEPS.setBit(0, F_InRange(fSDS_RX, 124, 215));
fbEPS.setBit(1, F_InRange(fSDS_Z_ENC, 3.05, 3.8));
fbEPS(eps:=aRCC_Y_EPS[3].stEPS);
fbEPS.setMessage('DPL_Z in [-10,30];RCC_Z in [-15,11]');
fbEPS.setBit(0, F_InRange(fDPL_Z, -10, 30));
fbEPS.setBit(1, F_InRange(fRCC_Z, -15, 11));
fbEPS(eps:=aRCC_Y_EPS[4].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.8, 4];SDS_Y - RCC_Y <= nozzle_catcher_offset');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.8, 4));
fbEPS.setBit(1, (fSDS_Y - fRCC_Y) <= fNozzleCatcherOffset);
aRCC_Y_EPS[4].fFwd_Limits := fSDS_Y - fNozzleCatcherOffset; // Variable Limits
bFullRange := (NOT aRCC_Y_EPS[2].stEPS.bEPS_OK) AND (NOT aRCC_Y_EPS[3].stEPS.bEPS_OK) AND (NOT aRCC_Y_EPS[4].stEPS.bEPS_OK);
fbEPS(eps:=aRCC_Y_EPS[1].stEPS);
fbEPS.setMessage('Full Range');
fbEPS.setBit(0, bFullRange);
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M38, fPosition:=fRCC_Y, aEPSLimits:=aRCC_Y_EPS, stForwardMotorEPS:=M38.stEPSForwardEnable, stBackwardMotorEPS:= M38.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_RCC_Z_EPS
PROGRAM PRG_RCC_Z_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Z:EPS'}
aRCC_Z_EPS : ARRAY [1 .. 3] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Z:EPS:OVRD_MODE'}
bEPS_Override: BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:RCC:MMS:Z:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aRCC_Z_EPS[1].fBwd_Limits := -18;
aRCC_Z_EPS[1].fFwd_Limits := 11;
aRCC_Z_EPS[2].fBwd_Limits := -18;
aRCC_Z_EPS[2].fFwd_Limits := -15;
aRCC_Z_EPS[3].fBwd_Limits := -18;
aRCC_Z_EPS[3].fFwd_Limits := -15;
bInit := FALSE;
END_IF
fbEPS(eps:=aRCC_Z_EPS[2].stEPS);
fbEPS.setMessage('DPL_Z in [-10,30];DPL_Y in [-1,40]');
fbEPS.setBit(0, F_InRange(fDPL_Z, -10, 30));
fbEPS.setBit(1, F_InRange(fDPL_Y, -1, 40));
fbEPS(eps:=aRCC_Z_EPS[3].stEPS);
fbEPS.setMessage('DPL_Z in [-10, 30];RCC_Y in [-34,10]');
fbEPS.setBit(0, F_InRange(fDPL_Z, -10, 30));
fbEPS.setBit(1, F_InRange(fRCC_Y, -34, 10));
bFullRange := (NOT aRCC_Z_EPS[2].stEPS.bEPS_OK) AND (NOT aRCC_Z_EPS[3].stEPS.bEPS_OK);
fbEPS(eps:=aRCC_Z_EPS[1].stEPS);
fbEPS.setMessage('Full Range');
fbEPS.setBit(0, bFullRange);
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:= tEPS_TimerCountDown);
fbCheckEPS(stMotor:= M39, fPosition:=fRCC_Z, aEPSLimits:=aRCC_Z_EPS, stForwardMotorEPS:=M39.stEPSForwardEnable, stBackwardMotorEPS:= M39.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_RCI
PROGRAM PRG_RCI
VAR
fbRCI_Motor_X : FB_MotionStage;
fbRCI_Motor_Y : FB_MotionStage;
fbRCI_Motor_Z : FB_MotionStage;
fbRCI_Motor_rX : FB_MotionStage;
iMagnetOutINT AT %Q*: INT;
iMagnetInINT AT %I*: INT;
{attribute 'pytmc' := '
pv: CRIX:RCI:MAG_SET
EGU: V
'}
fMagnetSet: LREAL;
{attribute 'pytmc' := '
pv: CRIX:RCI:MAG_GET
EGU: V
'}
fMagnetGet: LREAL;
fbGetMagnetVoltage: FB_RCI_Analog_Input; // FB_AnalogInput;
fbSetMagnetVoltage: FB_RCI_Analog_Output; // FB_AnalogOutput;
END_VAR
Main.M26.bHardwareEnable := TRUE;
fbRCI_Motor_X(stMotionStage:=Main.M26);
Main.M27.bHardwareEnable := TRUE;
fbRCI_Motor_Y(stMotionStage:=Main.M27);
Main.M28.bHardwareEnable := TRUE;
fbRCI_Motor_Z(stMotionStage:=Main.M28);
Main.M29.bHardwareEnable := TRUE;
fbRCI_Motor_rX(stMotionStage:=Main.M29);
Main.M29.bLimitBackwardEnable:=TRUE;
Main.M29.bLimitForwardEnable:=TRUE;
fbSetMagnetVoltage(
fReal:=fMagnetSet,
fSafeMax:=9.999,
fSafeMin:=-10,
iTermBits:=16,
fTermMax:=10,
fTermMin:=-10,
iRaw=>iMagnetOutINT);
fbGetMagnetVoltage(
iRaw:=iMagnetInINT,
iTermBits:=16,
fTermMax:=10,
fTermMin:=0,
fReal=>fMagnetGet);
END_PROGRAM
- Related:
PRG_SDS_RX_EPS
PROGRAM PRG_SDS_RX_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:RX:EPS'}
aSDS_RX_EPS : ARRAY [1 .. 5] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:RX:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:RX:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bSDS_RX_FullRange : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
// Set Inital Values
aSDS_RX_EPS[1].fBwd_Limits := 124;
aSDS_RX_EPS[1].fFwd_Limits := 218;
aSDS_RX_EPS[2].fBwd_Limits := 215;
aSDS_RX_EPS[2].fFwd_Limits := 218;
aSDS_RX_EPS[3].fBwd_Limits := 215;
aSDS_RX_EPS[3].fFwd_Limits := 218;
aSDS_RX_EPS[4].fBwd_Limits := 124;
aSDS_RX_EPS[4].fFwd_Limits := 134;
aSDS_RX_EPS[5].fBwd_Limits := 124;
aSDS_RX_EPS[5].fFwd_Limits := 134;
bInit := FALSE;
END_IF
// Set EPS conditions
fbEPS(eps:=aSDS_RX_EPS[1].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.05,3.4];SDS_Y in [30,38.5];RCC_Y in [-38,-34];DPL_X in [10,30]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, -1 , 3.4));
fbEPS.setBit(1, F_InRange(fSDS_Y, 30, 38.5));
fbEPS.setBit(2, F_InRange(fRCC_Y, -38, -34));
fbEPS.setBit(3, F_InRange(fDPL_X, 10, 30));
bSDS_RX_FullRange := aSDS_RX_EPS[1].stEPS.bEPS_OK; // FULL RANGE CONDITION
fbEPS(eps:=aSDS_RX_EPS[2].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [-1, 3.05]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, -1.0, 3.05));
fbEPS.setBit(1, NOT bSDS_RX_FullRange); // NOT FULL RANGE COND.
fbEPS(eps:=aSDS_RX_EPS[3].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.05, 3.4];SDS_RX in [215, 220];Not Full Range');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.05, 3.4));
fbEPS.setBit(1, F_InRange(fSDS_RX, 215, 220));
fbEPS.setBit(2, NOT bSDS_RX_FullRange); // NOT FULL RANGE COND.
fbEPS(eps:=aSDS_RX_EPS[4].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.4, 4]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.4, 4));
fbEPS(eps:=aSDS_RX_EPS[5].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.05,3.4];SDS_RX in [124, 134];Not Full Range');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.05, 3.4));
fbEPS.setBit(1, F_InRange(fSDS_RX, 124, 134));
fbEPS.setBit(2, NOT bSDS_RX_FullRange); // NOT FULL RANGE COND.
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M19, fPosition:= fSDS_RX, aEPSLimits:= aSDS_RX_EPS, stForwardMotorEPS:=M19.stEPSForwardEnable, stBackwardMotorEPS:= M19.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_SDS_Y_EPS
PROGRAM PRG_SDS_Y_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:Y:EPS'}
aSDS_Y_EPS : ARRAY [1 .. 5] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:Y:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:Y:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bFullRange : BOOL;
nIndex : uint;
nEPSIndex : uint;
fbEPS : FB_EPS;;
fbCheckEPS : FB_CheckEPS;
END_VAR
// SDS Y EPS
IF bInit THEN
// Set Inital Values
aSDS_Y_EPS[1].fBwd_Limits := 20;
aSDS_Y_EPS[1].fFwd_Limits := 45;
aSDS_Y_EPS[2].fBwd_Limits := 37.5;
aSDS_Y_EPS[2].fFwd_Limits := 38.5;
aSDS_Y_EPS[3].fBwd_Limits := 30;
aSDS_Y_EPS[3].fFwd_Limits := 38.5;
aSDS_Y_EPS[4].fBwd_Limits := 30;
aSDS_Y_EPS[4].fFwd_Limits := 38.5;
aSDS_Y_EPS[5].fBwd_Limits := 30;
aSDS_Y_EPS[5].fFwd_Limits := 45;
bInit := FALSE;
END_IF
// Set EPS conditions
fbEPS(eps:= aSDS_Y_EPS[2].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [-1,3.05]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, -1, 3.05));
fbEPS(eps:= aSDS_Y_EPS[3].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.05, 3.4];SDS_RX in [215, 220]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.05, 3.4));
fbEPS.setBit(1, F_InRange(fSDS_RX, 215, 220));
fbEPS(eps:= aSDS_Y_EPS[4].stEPS);
fbEPS.setMessage('SDS_Z_ENC in [3.05, 3.8];SDS_RX in [124, 215]');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.05, 3.8));
fbEPS.setBit(1, F_InRange(fSDS_RX, 124, 215));
fbEPS(eps:= aSDS_Y_EPS[5].stEPS);
fbEPS.setDescription('SDS_Z_ENC in [3.8, 4];(SDS_Y - RCC) <= nozzle_catcher_offset');
fbEPS.setBit(0, F_InRange(fSDS_Z_ENC, 3.8, 4));
fbEPS.setBit(1, (fSDS_Y - fRCC_Y) <= fNozzleCatcherOffset);
aSDS_Y_EPS[5].fBwd_Limits := fNozzleCatcherOffset + fRCC_Y;
bFullRange := (NOT aSDS_Y_EPS[2].stEPS.bEPS_OK) AND (NOT aSDS_Y_EPS[3].stEPS.bEPS_OK) AND(NOT aSDS_Y_EPS[4].stEPS.bEPS_OK) AND (NOT aSDS_Y_EPS[5].stEPS.bEPS_OK);
fbEPS(eps:= aSDS_Y_EPS[1].stEPS);
fbEPS.setDescription('Full Range');
fbEPS.setBit(0, bFullRange); // FULL RANGE
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M17, fPosition:=fSDS_Y, aEPSLimits:=aSDS_Y_EPS, stForwardMotorEPS:=M17.stEPSForwardEnable, stBackwardMotorEPS:= M17.stEPSBackwardEnable, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_SDS_ZENCODER_EPS
PROGRAM PRG_SDS_ZENCODER_EPS
VAR
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:ZENC:EPS'}
aSDS_Z_ENC_EPS : ARRAY [1 .. 5] OF ST_EPSLimits;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:ZENC:EPS:OVRD_MODE'}
bEPS_Override : BOOL := FALSE;
{attribute 'pytmc' := 'pv: CRIX:SDS:MMS:ZENC:EPS:OVRD_COUNTDOWN'}
tEPS_TimerCountDown : STRING := TIME_TO_STRING(T#0s);
fbResetTimer : FB_RestTimer;
bInit : BOOL := TRUE;
bSDS_vert_transport_state : BOOL;
bFullRange : BOOL;
bUnknownState : BOOL;
fbEPS : FB_EPS;
fbCheckEPS : FB_CheckEPS;
END_VAR
IF bInit THEN
aSDS_Z_ENC_EPS[1].fBwd_Limits := -1;
aSDS_Z_ENC_EPS[1].fFwd_Limits := 3.4;
aSDS_Z_ENC_EPS[2].fBwd_Limits := 3.05;
aSDS_Z_ENC_EPS[2].fFwd_Limits := 3.4;
aSDS_Z_ENC_EPS[3].fBwd_Limits := 3.05;
aSDS_Z_ENC_EPS[3].fFwd_Limits := 3.4;
aSDS_Z_ENC_EPS[4].fBwd_Limits := 3.05;
aSDS_Z_ENC_EPS[4].fFwd_Limits := 4;
aSDS_Z_ENC_EPS[5].fBwd_Limits := 3.8;
aSDS_Z_ENC_EPS[5].fFwd_Limits := 4;
bInit := FALSE;
END_IF
bSDS_vert_transport_state := F_InRange(fSDS_Y, 30, 38.5) AND F_InRange(fSDS_RX, 124, 134) AND (fDPL_X < 30) AND (fRCC_Y < -34);
fbEPS(eps:=aSDS_Z_ENC_EPS[1].stEPS);
fbEPS.setMessage('SDS_RX in [215, 220];SDS_Y in [37.5, 38.5]');
fbEPS.setBit(0, F_InRange(fSDS_RX, 215, 220));
fbEPS.setBit(1, F_InRange(fSDS_Y, 37.5, 38.5));
fbEPS(eps:=aSDS_Z_ENC_EPS[2].stEPS);
fbEPS.setMessage('SDS_RX in [134, 220];SDS_Y in [30, 38.5]');
fbEPS.setBit(0, F_InRange(fSDS_RX, 134, 220));
fbEPS.setBit(1, F_InRange(fSDS_Y, 30, 37.5));
fbEPS(eps:=aSDS_Z_ENC_EPS[3].stEPS);
fbEPS.setMessage('SDS_RX in [124, 134];SDS_Z_ENC in [3.05, 3.45];NOT SDS VERT. TRANSPORT STATE');
fbEPS.setBit(0, F_InRange(fSDS_RX, 124, 134));
fbEPS.setBit(1, F_InRange(fSDS_Z_ENC, 3.05, 3.45));
fbEPS.setBit(2, NOT bSDS_vert_transport_state); // NOT INJECTOR Vertical Tansport Condition
fbEPS(eps:=aSDS_Z_ENC_EPS[4].stEPS);
fbEPS.setMessage('SDS_RX in [124, 134];SDS_Y in [30, 38.5];RCC_Y in [-38,-34];DPL_X in [10,30]');
fbEPS.setBit(0, F_InRange(fSDS_RX, 124, 134));
fbEPS.setBit(1, F_InRange(fSDS_Y, 30, 38.5));
fbEPS.setBit(2, F_InRange(fRCC_Y, -38, -34));
fbEPS.setBit(3, F_InRange(fDPL_X, 10, 30));
fbEPS(eps:=aSDS_Z_ENC_EPS[5].stEPS);
fbEPS.setMessage('SDS_RX in [124, 134];SDS_Z_ENC in [3.75, 4]; NOT SDS VERT. TRANSPORT State');
fbEPS.setBit(0, F_InRange(fSDS_RX, 124, 134));
fbEPS.setBit(1, F_InRange(fSDS_Z_ENC, 3.75, 4));
fbEPS.setBit(2, NOT bSDS_vert_transport_state); // NOT INJECTOR Vertical Transport Condition
fbResetTimer(bInput:=bEPS_Override, tElapseTime:=tEPS_OVRD_RESET_TIME, tCountDown:=tEPS_TimerCountDown);
fbCheckEPS(stMotor:=M18, fPosition:=fSDS_Z_ENC, stForwardMotorEPS:= M18.stEPSBackwardEnable, stBackwardMotorEPS:=M18.stEPSForwardEnable, aEPSLimits:=aSDS_Z_ENC_EPS, bEPS_Override:=bEPS_Override);
END_PROGRAM
- Related:
PRG_SL2K2_SCATTER
PROGRAM PRG_SL2K2_SCATTER
VAR
{attribute 'pytmc' := '
pv: SL2K2:SCATTER
io: io
'}
fbSL2K2: FB_SLITS;
//GET PMPS Move Ok bit
// Default True until it is properly linked to PMPS bit
bMoveOk:BOOL :=TRUE;
{attribute 'pytmc' := '
pv: SL2K2:SCATTER:GO;
io: io;
field: ZNAM False;
field: ONAM True;
'}
bExecuteMotion :BOOL :=FALSE;
bTest:BOOL:=FALSE;
//for testing purposes only. comment-out/delete once done.
mcPower : ARRAY [1..4] OF MC_POWER;
(*Offsets*)
(* Absolute encoder value at the HLS + Absolure eoncoder value at the centered beam *)
rEncoderOffsetTop: REAL := -15; (* 0+(-15)*)
rEncoderOffsetBottom: REAL := -15; (* 0+(-15)*)
rEncoderOffsetNorth: REAL := -15;(* 0+(-15)*)
rEncoderOffsetSouth: REAL := -15;(* 0+(-15)*)
END_VAR
fbSL2K2.bMoveOk := bMoveOk;
//for testing purposes only. comment-out/delete once done.
If (bTest) THEN
mcPower[1](axis:=Main.M50.Axis, Enable:=bTest, enable_positive:=Main.M50.bLimitForwardEnable, enable_negative:=Main.M50.bLimitBackwardEnable);
mcPower[2](axis:=Main.M51.Axis, Enable:=bTest, enable_positive:=Main.M51.bLimitForwardEnable, enable_negative:=Main.M51.bLimitBackwardEnable);
mcPower[3](axis:=Main.M52.Axis, Enable:=bTest, enable_positive:=Main.M52.bLimitForwardEnable, enable_negative:=Main.M52.bLimitBackwardEnable);
mcPower[4](axis:=Main.M53.Axis, Enable:=bTest, enable_positive:=Main.M53.bLimitForwardEnable, enable_negative:=Main.M53.bLimitBackwardEnable);
ELSE
//Homing routine parameters
Main.M51.fHomePosition:= 0;
Main.M50.fHomePosition:= -30.6;
Main.M52.fHomePosition:= 0;
Main.M53.fHomePosition:= -30.51;
Main.M51.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT;
Main.M50.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
Main.M52.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT;
Main.M53.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
fbSL2K2.rEncoderOffsetTop := rEncoderOffsetTop;
fbSL2K2.rEncoderOffsetBottom := rEncoderOffsetBottom;
fbSL2K2.rEncoderOffsetNorth := rEncoderOffsetNorth;
fbSL2K2.rEncoderOffsetSouth := rEncoderOffsetSouth;
fbSL2K2(stTopBlade:= Main.M51,
stBottomBlade:= Main.M50,
stNorthBlade:= Main.M52,
stSouthBlade:= Main.M53,
bExecuteMotion:=bExecuteMotion,
io_fbFFHWO := GVL_PMPS.g_FastFaultOutput2,
fbArbiter := GVL_PMPS.fbArbiter1);
//fbSL2K2.M_CheckPMPS(2);
END_IF
END_PROGRAM
PRG_Test_AdjacentStates
PROGRAM PRG_Test_AdjacentStates
VAR
arrDPTransitions : ARRAY [0..9, 1..9] OF BOOL :=
//Park Up Center Pinh. Diode Yag1 Yag2 Yag3 Knife
[FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Unknown (This should always be included)
TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Park
TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // Up
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Center
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Pinhole
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Diode
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag1
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag2
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, // Yag3
FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE]; // Knife
arrAdjStates : ARRAY [1..9] OF ST_BFSAssemblyState;
nStates : DINT := 9;
iRootState : DINT := 8;
fbAdjacent : FB_AdjacentStates;
nAdjacentStates : DINT;
END_VAR
fbAdjacent(arrTransitionMatrix:=arrDPTransitions,
arrAdjacentStates:=arrAdjStates,
arrStates:=arrDPStates,
iRootState:=iRootState,
nAdjacentStates=>nAdjacentStates);
END_PROGRAM
- Related:
PRG_VLS
PROGRAM PRG_VLS
VAR
fbVLS_SLITS_TOP : FB_MotionStage;
fbVLS_SLITS_BOTTOM : FB_MotionStage;
fbVLS_SLITS_RIGHT : FB_MotionStage;
fbVLS_SLITS_LEFT: FB_MotionStage;
fbVLS_Mirror_P : FB_MotionStage;
fbVLS_Grating_P : FB_MotionStage;
fbVLS_CAM_P : FB_MotionStage;
fbVLS_CAM_D : FB_MotionStage;
bInit :BOOL:=TRUE;
rGrating_Pitch :LREAL;
rMirror_Pitch :LREAL;
END_VAR
IF ( bInit) THEN
bInit := FALSE;
//SLITS
Main.M40.bHardwareEnable := TRUE;
Main.M40.bPowerSelf :=TRUE;
Main.M40.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M40.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M41.bHardwareEnable := TRUE;
Main.M41.bPowerSelf :=TRUE;
Main.M41.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M41.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M42.bHardwareEnable := TRUE;
Main.M42.bPowerSelf :=TRUE;
Main.M42.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M42.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M43.bHardwareEnable := TRUE;
Main.M43.bPowerSelf :=TRUE;
Main.M43.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M43.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
//Homing routine parameters
Main.M40.fHomePosition:= 0;
Main.M40.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
Main.M41.fHomePosition:= 0;
Main.M41.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
Main.M42.fHomePosition:= 0;
Main.M42.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
Main.M43.fHomePosition:= 0;
Main.M43.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
//Focusing Mirror Pitch
Main.M44.bHardwareEnable := TRUE;
Main.M44.bPowerSelf :=TRUE;
Main.M44.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M44.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
//Homing routine parameters
Main.M44.fHomePosition:= -0.2288; // old homing position: -3.473;
Main.M44.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
//Grating Pitch
Main.M45.bHardwareEnable := TRUE;
Main.M45.bPowerSelf :=TRUE;
Main.M45.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M45.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
//Homing routine parameters
Main.M45.fHomePosition:= -1.74;
Main.M45.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
//Cam
Main.M46.bHardwareEnable := TRUE;
Main.M46.bPowerSelf :=TRUE;
Main.M46.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M46.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
Main.M47.bHardwareEnable := TRUE;
Main.M47.bPowerSelf :=TRUE;
Main.M47.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE;
Main.M47.nEnableMode := ENUM_StageEnableMode.DURING_MOTION;
//Homing routine parameters
Main.M46.fHomePosition:= 0.8923;
Main.M46.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT;//0 where it is horizontal
Main.M47.fHomePosition:= -15.5;
Main.M47.nHomingMode := ENUM_EpicsHomeCmd.LOW_LIMIT;
END_IF
//Calculate the mirror and grating pitch values
//OLD EQUATION:
//Mirror Pitch (x) = 33.85 + 18.09x - 0.2479x2
//rMirror_Pitch :=33.85 + (18.09*Main.M44.stAxisStatus.fActPosition(*mm*) )- (0.2479 * EXPT(Main.M44.stAxisStatus.fActPosition,2));
//NEW EQUATION:
rMirror_Pitch :=27.667 + (18.1*Main.M44.stAxisStatus.fActPosition(*mm*) )+ (-0.7569 * EXPT(Main.M44.stAxisStatus.fActPosition,2));
//Grating Pitch (x) = 22.56 - 16.25x + 0.334x2
rGrating_Pitch := 22.56 - (16.25*Main.M45.stAxisStatus.fActPosition(*mm*) )+ (0.334 * EXPT(Main.M45.stAxisStatus.fActPosition,2));
fbVLS_SLITS_TOP(stMotionStage:=Main.M40);
fbVLS_SLITS_BOTTOM(stMotionStage:=Main.M41);
fbVLS_SLITS_RIGHT(stMotionStage:=Main.M42);
fbVLS_SLITS_LEFT(stMotionStage:=Main.M43);
fbVLS_Mirror_P(stMotionStage:=Main.M44);
fbVLS_Grating_P(stMotionStage:=Main.M45);
fbVLS_CAM_P(stMotionStage:=Main.M46);
fbVLS_CAM_D(stMotionStage:=Main.M47);
END_PROGRAM
- Related: