DUTs ---- E_PositionState ^^^^^^^^^^^^^^^ :: TYPE E_PositionState : ( RETRACTED := 0, INSERTED := 1, MOVING := 2, INVALID :=3 ); END_TYPE Related: * `E_PositionState`_ ST_MPA ^^^^^^ :: TYPE ST_MPA : STRUCT // i_xInsertLS AT %I*: BOOL; // i_xRetractLS AT %I*: BOOL; // _xInsertSW : BOOL; // _xRetractSW : BOOL; // q_xInsertDO AT %Q*: BOOL; // q_xRetractDO AT %Q*: BOOL; // eState : DUT_PneumaticActuator_Position; //Readbacks {attribute 'pytmc' := ' pv: IN io: i '} i_bInLS : BOOL; {attribute 'pytmc' := ' pv: OUT io: i '} i_bOutLS : BOOL; //Controls {attribute 'pytmc' := ' pv: INSERT_DO io: i '} q_bRetract : BOOL; {attribute 'pytmc' := ' pv: RETRACT_DO io: i '} q_bInsert : BOOL; //Logic and supervisory {attribute 'pytmc' := ' pv: ILKOK io: i '} bILK_OK: BOOL; {attribute 'pytmc' := ' pv: INSERT_OK io: i '} bInsertOK : BOOL; {attribute 'pytmc' := ' pv: RETRACT_OK io: i '} bRetractOK : BOOL; {attribute 'pytmc' := ' pv: IN_CMD io: io '} bInsert_SW : BOOL; {attribute 'pytmc' := ' pv: OUT_CMD io: io '} bRetract_SW : BOOL; {attribute 'pytmc' := ' pv: ERROR io: io '} bErrorPresent : BOOL; {attribute 'pytmc' := ' pv: POS_STATE type: mbbi field: ZRST RETRACTED field: ONST INSERTED field: TWST MOVING field: THST INVALID io: i '} eState : E_PositionState := INVALID; END_STRUCT END_TYPE Related: * `E_PositionState`_ GVLs ---- Global_Version ^^^^^^^^^^^^^^ :: {attribute 'TcGenerated'} // This function has been automatically generated from the project information. VAR_GLOBAL CONSTANT {attribute 'const_non_replaced'} {attribute 'linkalways'} stLibVersion_kfe_motion : ST_LibVersion := (iMajor := 4, iMinor := 0, iBuild := 1, iRevision := 0, sVersion := '4.0.1'); END_VAR GVL ^^^ :: {attribute 'qualified_only'} VAR_GLOBAL {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:ARB:01'} fbArbiter: FB_Arbiter(1); {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:ARB:02'} fbArbiter2: FB_Arbiter(2); {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:FFO:01'} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 1^Output'} fbFastFaultOutput1: FB_HardwareFFOutput := (bAutoReset := TRUE, i_sNetID:='172.21.92.73.1.1'); {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:FFO:02'} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 2^Output'} fbFastFaultOutput2: FB_HardwareFFOutput := (bAutoReset := TRUE, i_sNetID:='172.21.92.73.1.1'); {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:PMPS:ReqTrans'} rReqTrans AT %I* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; {attribute 'pytmc' := 'pv: PLC:KFE:MOTION:PMPS:CurTrans'} rCurTrans AT %Q* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; ePF1K0State: E_WFS_States; END_VAR VAR_GLOBAL CONSTANT iFiltersPerSATTBlade : INT := 8; END_VAR Main ^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL (* Only includes motor definitions for the IOC These are hard-coded to be Main.M#, but are very convenient to store in a GVL, hence the confusing namespace here This should be refactored once the IOC supports arbitrary ads paths for motors *) // IM1K0-XTES: 3 Axes {attribute 'pytmc' := 'pv: IM1K0:XTES:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM1K0-EL7041]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[IM1K0-EL2004]^Channel 1^Output; .nRawEncoderINT := TIIB[IM1K0-EL3054]^AI Standard Channel 1^Value'} M1: ST_MotionStage := (sName := 'IM1K0:XTES:MMS'); {attribute 'pytmc' := 'pv: IM1K0:XTES:CLZ'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM1K0-EL1088]^Channel 2^Input; .nRawEncoderUINT := TIIB[IM1K0-EL5101-01]^ENC Status compact^Counter value'} M2: ST_MotionStage := (sName := 'IM1K0:XTES:CLZ'); {attribute 'pytmc' := 'pv: IM1K0:XTES:CLF'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM1K0-EL1088]^Channel 4^Input; .nRawEncoderUINT := TIIB[IM1K0-EL5101-01]^ENC Status compact^Counter value'} M3: ST_MotionStage := (sName := 'IM1K0:XTES:CLF'); // IM1K3-PPM: 1 Axis {attribute 'pytmc' := 'pv: IM1K3:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM1K3-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM1K3-EL7041]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM1K3-EL2004]^Channel 1^Output; .nRawEncoderULINT := TIIB[IM1K3-EL5042]^FB Inputs Channel 1^Position'} M4: ST_MotionStage := (sName := 'IM1K3:PPM:MMS'); // IM2K0-XTES: 1 Axis, previously 3 but the zoom/focus have been removed {attribute 'pytmc' := 'pv: IM2K0:XTES:MMS'} {attribute 'TcLinkTo' := '.bBrakeRelease := TIIB[IM2K0-EL2004]^Channel 1^Output; .nRawEncoderULINT := TIIB[IM2K0-EL5042]^FB Inputs Channel 1^Position'} M5: ST_MotionStage := (sName := 'IM2K0:XTES:MMS'); {attribute 'pytmc' := 'pv: IM2K0:XTES:CLZ'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM2K0-EL1088]^Channel 2^Input; .nRawEncoderUINT := TIIB[IM2K0-EL7342]^ENC Status compact Channel 1^Counter value'} M6: ST_MotionStage := (sName := 'IM2K0:XTES:CLZ'); {attribute 'pytmc' := 'pv: IM2K0:XTES:CLF'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM2K0-EL1088]^Channel 4^Input; .nRawEncoderUINT := TIIB[IM2K0-EL7342]^ENC Status compact Channel 2^Counter value'} M7: ST_MotionStage := (sName := 'IM2K0:XTES:CLF'); // PF1K0-WFS: 2 Axes {attribute 'pytmc' := 'pv: PF1K0:WFS:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PF1K0-EL7041-01]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PF1K0-EL7041-01]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[PF1K0-EL2004]^Channel 1^Output; .nRawEncoderULINT := TIIB[PF1K0-EL5042]^FB Inputs Channel 2^Position'} M8: ST_MotionStage := (sName := 'PF1K0:WFS:MMS:Y'); {attribute 'pytmc' := 'pv: PF1K0:WFS:MMS:Z'} {attribute 'TcLinkTo' := '.nRawEncoderULINT := TIIB[PF1K0-EL5042]^FB Inputs Channel 1^Position'} M9: ST_MotionStage := (sName := 'PF1K0:WFS:MMS:Z'); // RTDSK0: 8 Axes M10: ST_MotionStage; {attribute 'pytmc' := 'pv: RTDSK0:SCRP:MMS:Z'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[RTDSK0-M2-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[RTDSK0-M2-EL7041]^STM Status^Status^Digital input 2'} M11: ST_MotionStage:= (sName := 'RTDSK0:SCRP:MMS:Z'); {attribute 'pytmc' := 'pv: RTDSK0:SCRP:MMS:X'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[RTDSK0-M3-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[RTDSK0-M3-EL7041]^STM Status^Status^Digital input 2'} M12: ST_MotionStage:= (sName := 'RTDSK0:SCRP:MMS:X'); {attribute 'pytmc' := 'pv: RTDSK0:SCRP:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[RTDSK0-M4-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[RTDSK0-M4-EL7041]^STM Status^Status^Digital input 2'} M13: ST_MotionStage:= (sName := 'RTDSK0:SCRP:MMS:Y'); M14: ST_MotionStage; M15: ST_MotionStage; M16: ST_MotionStage; M17: ST_MotionStage; // SL1K0-POWER: 4 Axes {attribute 'pytmc' := 'pv: SL1K0:POWER:MMS:SOUTH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL1K0-EL7041-E1]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL1K0-EL7041-E1]^STM Status^Status^Digital input 1; .nRawEncoderINT := TIIB[SL1K0-EL3054-E12]^AI Standard Channel 1^Value'} M18: ST_MotionStage := (sName := 'SL1K0:POWER:MMS:SOUTH'); {attribute 'pytmc' := 'pv: SL1K0:POWER:MMS:TOP'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL1K0-EL7041-E2]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL1K0-EL7041-E2]^STM Status^Status^Digital input 1; .nRawEncoderINT := TIIB[SL1K0-EL3054-E12]^AI Standard Channel 2^Value'} M19: ST_MotionStage := (sName := 'SL1K0:POWER:MMS:TOP'); {attribute 'pytmc' := 'pv: SL1K0:POWER:MMS:NORTH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL1K0-EL7041-E4]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL1K0-EL7041-E4]^STM Status^Status^Digital input 1; .nRawEncoderINT := TIIB[SL1K0-EL3054-E12]^AI Standard Channel 3^Value'} M20: ST_MotionStage := (sName := 'SL1K0:POWER:MMS:NORTH'); {attribute 'pytmc' := 'pv: SL1K0:POWER:MMS:BOTTOM'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL1K0-EL7041-E5]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL1K0-EL7041-E5]^STM Status^Status^Digital input 1; .nRawEncoderINT := TIIB[SL1K0-EL3054-E12]^AI Standard Channel 4^Value'} M21: ST_MotionStage := (sName := 'SL1K0:POWER:MMS:BOTTOM'); // SL2K0-POWER: 4 Axes {attribute 'pytmc' := 'pv: SL2K0:POWER:MMS:SOUTH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K0-EL7041-E1]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL2K0-EL7041-E1]^STM Status^Status^Digital input 1; .nRawEncoderUINT := TIIB[SL2K0-EL5042-E2]^FB Inputs Channel 1^Position'} M22: ST_MotionStage := (sName := 'SL2K0:POWER:MMS:SOUTH'); {attribute 'pytmc' := 'pv: SL2K0:POWER:MMS:TOP'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K0-EL7041-E3]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL2K0-EL7041-E3]^STM Status^Status^Digital input 1; .nRawEncoderUINT := TIIB[SL2K0-EL5042-E2]^FB Inputs Channel 2^Position'} M23: ST_MotionStage := (sName := 'SL2K0:POWER:MMS:TOP'); {attribute 'pytmc' := 'pv: SL2K0:POWER:MMS:NORTH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K0-EL7041-E5]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL2K0-EL7041-E5]^STM Status^Status^Digital input 1; .nRawEncoderUINT := TIIB[SL2K0-EL5042-E6]^FB Inputs Channel 1^Position'} M24: ST_MotionStage := (sName := 'SL2K0:POWER:MMS:NORTH'); {attribute 'pytmc' := 'pv: SL2K0:POWER:MMS:BOTTOM'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[SL2K0-EL7041-E7]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[SL2K0-EL7041-E7]^STM Status^Status^Digital input 1; .nRawEncoderUINT := TIIB[SL2K0-EL5042-E6]^FB Inputs Channel 2^Position'} M25: ST_MotionStage := (sName := 'SL2K0:POWER:MMS:BOTTOM'); // AT1K4-SOLID: 4 axes (Z=748) (* Important note AT1K4 axes were mistakenly wired opposite to other solid attenuators. The intended convention is: MMS:01 should be the most upstream blade, MMS:04 should be the most downstream blade. The fix applied here is that the NC axes and temperature sensors are *linked* in reverse. In summary: Traveler EPICS Stage NC Location Axis 4 MMS:01 fbStage1 26 Upstream Axis 3 MMS:02 fbStage2 27 Axis 2 MMS:03 fbStage3 28 Axis 1 MMS:04 fbStage4 29 Downstream *) {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:01'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K4-EL7047-04]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K4-EL7047-04]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K4-EL5042-02]^FB Inputs Channel 2^Position; '} M26: ST_MotionStage := (sName := 'AT1K4:L2SI:MMS:01'); {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K4-EL7047-03]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K4-EL7047-03]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K4-EL5042-02]^FB Inputs Channel 1^Position; '} M27: ST_MotionStage := (sName := 'AT1K4:L2SI:MMS:02'); {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:03'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K4-EL7047-02]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K4-EL7047-02]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K4-EL5042-01]^FB Inputs Channel 2^Position; '} M28: ST_MotionStage := (sName := 'AT1K4:L2SI:MMS:03'); {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:04'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K4-EL7047-01]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K4-EL7047-01]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K4-EL5042-01]^FB Inputs Channel 1^Position; '} M29: ST_MotionStage := (sName := 'AT1K4:L2SI:MMS:04'); // IM1K4-XTES: 3 Axes {attribute 'pytmc' := 'pv: IM1K4:XTES:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM1K4-EL7041-E1]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[IM1K4-EL2004-E2]^Channel 1^Output; .nRawEncoderULINT := TIIB[IM1K4-EL5042-E3]^FB Inputs Channel 1^Position'} M30: ST_MotionStage := (sName := 'IM1K4:XTES:MMS'); {attribute 'pytmc' := 'pv: IM1K4:XTES:CLZ'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM1K4-EL1088-E5]^Channel 2^Input; .nRawEncoderUINT := TIIB[IM1K4-EL7342-E4]^ENC Status compact Channel 1^Counter value'} M31: ST_MotionStage := (sName := 'IM1K4:XTES:CLZ'); {attribute 'pytmc' := 'pv: IM1K4:XTES:CLF'} {attribute 'TcLinkTo' := '.bHome := TIIB[IM1K4-EL1088-E5]^Channel 4^Input; .nRawEncoderUINT := TIIB[IM1K4-EL7342-E4]^ENC Status compact Channel 2^Counter value'} M32: ST_MotionStage := (sName := 'IM1K4:XTES:CLF'); // ST1K4-TEST: 1 Axis {attribute 'pytmc' := 'pv: ST1K4:TEST:MMS:01'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[ST1K4-EL7041-E4]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[ST1K4-EL7041-E4]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[ST1K4-EL2202-E3]^Channel 1^Output; .nRawEncoderULINT := TIIB[ST1K4-EL5042-E5A]^FB Inputs Channel 1^Position'} M33: ST_MotionStage := (sName := 'ST1K4:TEST:MMS:01'); END_VAR Related: * `GVL`_ POUs ---- FB_MPA ^^^^^^ :: FUNCTION_BLOCK FB_MPA VAR_INPUT (*EPS Interlock Bits*) ibInsertOK: BOOL; ibRetractOK: BOOL; ibPMPS_OK:BOOL; ibOverrideInterlock:BOOL; (*if true interlocks are ignored*) // Reset fault {attribute 'pytmc' := ' pv: FF_Reset '} i_xReset: BOOL; sName: STRING; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: '} q_stAct : ST_MPA; {attribute 'pytmc' := ' pv: MPS_FAULT '} xMPS_OK:BOOL; {attribute 'pytmc' := ' pv: MOT_DONE '} xDone:Bool; // Motion is Done END_VAR VAR_IN_OUT io_fbFFHWO : FB_HardwareFFOutput; END_VAR VAR // PMPS fbFF : FB_FastFault :=( i_xAutoReset := TRUE, i_Desc := 'Device is moving', i_TypeCode := 16#1010); (*Init*) xFirstPass : BOOL; fbFSInit : R_TRIG; (* Timeouts*) tTimeOutDuration: TIME:= T#5S; tInserttimeout: TON; tRetracttimeout:TON; (*IO*) i_xInsertedLS AT%I*: BOOL; i_xRetractedLS AT%I*: BOOL; q_xInsert_DO AT%Q*: BOOL; q_xRetract_DO AT%Q*: BOOL; (* Reset Triggers *) rtInsert: R_TRIG; rtRemove: R_TRIG; END_VAR (*Initialize*) fbFSInit( CLK := TRUE, Q => xFirstPass); (*IO Mapping*) ACT_IO(); IF xFirstPass THEN q_stAct.eState := INVALID; q_stAct.bRetract_SW := FALSE; q_stAct.bInsert_SW := FALSE; END_IF (* Manage States*) IF q_stAct.i_bInLS AND q_stAct.i_bOutLS THEN q_stAct.eState:=INVALID; ELSIF NOT q_stAct.i_bInLS AND q_stAct.i_bOutLS THEN q_stAct.eState:=RETRACTED; ELSIF q_stAct.i_bInLS AND NOT q_stAct.i_bOutLS THEN q_stAct.eState:=INSERTED; ELSIF NOT q_stAct.i_bInLS AND NOT q_stAct.i_bOutLS THEN q_stAct.eState:=MOVING; ELSE q_stAct.eState:=INVALID; END_IF (*Set the Done signal*) xDone := (q_stAct.bRetract_SW AND q_stAct.eState=RETRACTED) OR (q_stAct.eState=INSERTED AND q_stAct.bInsert_SW); (*MPS FAULT*) (**) xMPS_OK := (q_stAct.bRetract_SW AND i_xRetractedLS) XOR (i_xInsertedLS AND q_stAct.bInsert_SW); //xMPS_OK := i_xRetractedLS XOR i_xInsertedLS; //xMPS_OK := (q_stAct.eState=RETRACTED) OR (q_stAct.eState=INSERTED); //xMPS_OK := (q_stAct.eState=RETRACTED) ; (*PMPS PERMISSION*) (* Reset the other command bit when one goes high *) rtInsert(CLK:=q_stAct.bInsert_SW); IF rtInsert.Q THEN q_stAct.bRetract_SW := FALSE; END_IF rtRemove(CLK:=q_stAct.bRetract_SW); IF rtRemove.Q THEN q_stAct.bInsert_SW := FALSE; END_IF (* Can't have bRetract_SW and bInsert_SW both be true*) If (q_stAct.bRetract_SW) and (q_stAct.bInsert_SW) THEN q_stAct.bRetract_SW := FALSE; q_stAct.bInsert_SW := FALSE; END_IF (* Make the state consistent if we can *) IF NOT (q_stAct.bRetract_SW OR q_stAct.bInsert_SW) THEN IF q_stAct.eState = RETRACTED THEN q_stAct.bRetract_SW := TRUE; ELSIF q_stAct.eState = INSERTED THEN q_stAct.bInsert_SW := TRUE; END_IF END_IF q_stAct.bRetractOK := ibRetractOK; q_stAct.bInsertOK := ibInsertOK; (*Actuate the device*) q_stAct.q_bRetract := q_stAct.bRetractOK AND q_stAct.bRetract_SW; q_stAct.q_bInsert := q_stAct.bInsertOK AND q_stAct.bInsert_SW; IF q_stAct.q_bInsert THEN q_stAct.q_bRetract := FALSE; q_stAct.bRetract_SW:= FALSE; ELSIF q_stAct.q_bRetract THEN q_stAct.q_bInsert := FALSE; q_stAct.bInsert_SW:= FALSE; END_IF; (*Timers*) tInserttimeout(IN:= q_stAct.q_bInsert, PT := tTimeOutDuration ); tRetracttimeout(IN:= q_stAct.q_bRetract, PT := tTimeOutDuration); ///Check moving postion timout IF NOT q_stAct.i_bInLS AND tInserttimeout.Q THEN q_stAct.bErrorPresent := TRUE; ELSIF NOT q_stAct.i_bOutLS AND tRetracttimeout.Q THEN q_stAct.bErrorPresent := TRUE; END_IF (*FAST FAULT*) fbFF(i_DevName := sName, i_xOK := xMPS_OK, i_xReset := i_xReset, io_fbFFHWO := io_fbFFHWO); (*Soft IO Mapping*) ACT_IO(); END_FUNCTION_BLOCK ACTION ACT_IO: (*Inputs*) q_stAct.i_bInLS := i_xInsertedLS; q_stAct.i_bOutLS := i_xRetractedLS; (*outputs*) q_xInsert_DO:=q_stAct.q_bInsert; q_xRetract_DO:=q_stAct.q_bRetract; END_ACTION Related: * `ST_MPA`_ FB_SLITS ^^^^^^^^ :: FUNCTION_BLOCK FB_SLITS VAR_IN_OUT stTopBlade: ST_MotionStage; stBottomBlade: ST_MotionStage; stNorthBlade: ST_MotionStage; stSouthBlade: ST_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 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; //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 gaps and/or centers are not within safe margins, or PMPS mode is switched OFF', i_TypeCode := 16#FAA); AptArrayStatus AT %Q* : ST_PMPS_Aperture_IO; AptArrayReq AT %I* : ST_PMPS_Aperture_IO; bTest: BOOL; END_VAR 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 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_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 FB_SLITS_POWER ^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_SLITS_POWER EXTENDS FB_SLITS VAR_INPUT END_VAR VAR {attribute 'pytmc' := ' pv: MODE ; field: ZNAM Local; field: ONAM PMPS; io: io; '} xPMPSMode :BOOL :=TRUE; {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_init(); // Instantiate Function block for all the blades ACT_Motion(); //SET and GET the requested and Actual values ACT_CalculatePositions(); //ACT_BLOCK(); ACT_RTDs(); END_FUNCTION_BLOCK 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 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, // Gap should be reduced when center is moved, gap < Maximum permessible gap - 2|Center deviation from nominal| //Fast fault when it does. IF(This^.rActApertureSizeX > (AptArrayReq.Width - (2*ABS(rActCenterX))) //(rActCenterX > (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Width/2)) AND (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Width >0 )) OR (This^.rActApertureSizeY > (AptArrayReq.Height - (2*ABS(rActCenterY))) //((rActCenterY > (PMPS_GVL.stCurrentBeamParameters.astApertures[index].Height/2)) AND(PMPS_GVL.stCurrentBeamParameters.astApertures[index].Height>0 )) 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(xPMPSMode) THEN IF (This^.rActApertureSizeX > AptArrayReq.Width) THEN rReqApertureSizeX := AptArrayReq.Width - 0.01; END_IF IF (This^.rActApertureSizeY > AptArrayReq.Height) THEN rReqApertureSizeY := AptArrayReq.Height - 0.01; END_IF ELSE FFO.i_xOK := FALSE; END_IF (*FAST FAULT*) FFO(i_xOK := , i_xReset := , i_xAutoReset :=TRUE, io_fbFFHWO := io_fbFFHWO); END_METHOD Related: * `FB_SLITS`_ FB_XPIM_IM2K0 ^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_XPIM_IM2K0 (* Function block for the IM2K0 imager. This used to be a standard XPIM, but IM2K0 has been modified to replace the lens, illuminator, and camera with the PPM versions. This function block therefore controls: - Y motion (XPIM style) - Y scintillator states (XPIM style) - camera power (PPM style) - camera illuminator (PPM style but with XPIM style on/off only) - flowswitch (XPIM style, not fully implemented) *) VAR_IN_OUT // Y motor (state select). stYStage: ST_MotionStage; // The fast fault output to fault to. fbFFHWO: FB_HardwareFFOutput; // The arbiter to request beam conditions from. fbArbiter: FB_Arbiter; END_VAR VAR_INPUT // Settings for the OUT state. stOut: DUT_PositionState; // Settings for the YAG state. stYag: DUT_PositionState; // Settings for the DIAMOND state. stDiamond: DUT_PositionState; // Settings for the RETICLE state. stReticle: DUT_PositionState; // Set this to a non-unknown value to request a new move. {attribute 'pytmc' := ' pv: MMS:STATE:SET io: io '} eEnumSet: E_XPIM_States; // Set this to TRUE to enable input state moves, or FALSE to disable them. bEnableMotion: BOOL; // Set this to TRUE to enable beam parameter checks, or FALSE to disable them. bEnableBeamParams: BOOL; // Set this to TRUE to enable position limit checks, or FALSE to disable them. bEnablePositionLimits: BOOL; // The name of the device for use in the PMPS DB lookup and diagnostic screens. sDeviceName: STRING; // The name of the transition state in the PMPS database. sTransitionKey: STRING; // Set this to TRUE to re-read the loaded database immediately (useful for debug). bReadDBNow: BOOL; END_VAR VAR_OUTPUT // The current position state as an enum. {attribute 'pytmc' := ' pv: MMS:STATE:GET io: i '} eEnumGet: E_XPIM_States; // The PMPS database lookup associated with the current position state. stDbStateParams: ST_DbStateParams; END_VAR VAR bInit: BOOL; fbYStage: FB_MotionStage; fbStateDefaults: FB_PositionState_Defaults; {attribute 'pytmc' := ' pv: MMS astPositionState.array: 1..4 '} fbStates: FB_PositionStatePMPS1D; astPositionState: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; fbArrCheckWrite: FB_CheckPositionStateWrite; {attribute 'pytmc' := ' pv: CAM '} fbGige: FB_PPM_Gige; {attribute 'pytmc' := ' pv: CIL '} fbLED: FB_XPIM_LED; {attribute 'pytmc' := ' pv: SFW '} fbFlowSwitch: FB_XTES_Flowswitch; END_VAR VAR CONSTANT // State defaults if not provided fDelta: LREAL := 2; fAccel: LREAL := 200; fOutDecel: LREAL := 25; END_VAR IF NOT bInit THEN bInit := TRUE; stYStage.bHardwareEnable := TRUE; stYStage.bPowerSelf := FALSE; // No limit switch at the bottom stYStage.bLimitBackwardEnable := TRUE; // Partial backcompat, this used to set fVelocity too but this should be set per install fbStateDefaults(stPositionState:=stOut, sNameDefault:='OUT', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fOutDecel); fbStateDefaults(stPositionState:=stYag, sNameDefault:='YAG', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stDiamond, sNameDefault:='DIAMOND', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stReticle, sNameDefault:='RETICLE', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); END_IF fbYStage(stMotionStage:=stYStage); // We need to update from PLC or from EPICS, but not both fbArrCheckWrite( astPositionState:=astPositionState, bCheck:=TRUE, bSave:=FALSE, ); IF NOT fbArrCheckWrite.bHadWrite THEN astPositionState[E_XPIM_States.OUT] := stOut; astPositionState[E_XPIM_States.YAG] := stYag; astPositionState[E_XPIM_States.DIAMOND] := stDiamond; astPositionState[E_XPIM_States.RETICLE] := stReticle; END_IF fbStates( stMotionStage:=stYStage, astPositionState:=astPositionState, eEnumSet:=eEnumSet, eEnumGet:=eEnumGet, fbFFHWO:=fbFFHWO, fbArbiter:=fbArbiter, bEnableMotion:=bEnableMotion, bEnableBeamParams:=bEnableBeamParams, bEnablePositionLimits:=bEnablePositionLimits, sDeviceName:=sDeviceName, sTransitionKey:=sTransitionKey, bReadDBNow:=bReadDBNow, stDbStateParams=>stDbStateParams, ); fbArrCheckWrite( astPositionState:=astPositionState, bCheck:=FALSE, bSave:=TRUE, ); stOut := astPositionState[E_XPIM_States.OUT]; stYag := astPositionState[E_XPIM_States.YAG]; stDiamond := astPositionState[E_XPIM_States.DIAMOND]; stReticle := astPositionState[E_XPIM_States.RETICLE]; fbGige(); fbLED(enumXPIM:=eEnumGet); fbFlowSwitch(); END_FUNCTION_BLOCK PRG_1_PlcTask ^^^^^^^^^^^^^ :: PROGRAM PRG_1_PlcTask VAR END_VAR PRG_2_PMPS_PRE(); PRG_IM1K0_XTES(); PRG_IM1K3_PPM(); PRG_IM2K0_XTES(); PRG_PF1K0_WFS(); PRG_RTDSK0(); PRG_SL1K0_POWER(); PRG_SL2K0_POWER(); PRG_AT1K4_SOLID(); PRG_IM1K4_XTES(); PRG_ST1K4_TEST(); PRG_3_PMPS_POST(); PRG_4_LOG(); END_PROGRAM Related: * `PRG_2_PMPS_PRE`_ * `PRG_3_PMPS_POST`_ * `PRG_4_LOG`_ * `PRG_AT1K4_SOLID`_ * `PRG_IM1K0_XTES`_ * `PRG_IM1K3_PPM`_ * `PRG_IM1K4_XTES`_ * `PRG_IM2K0_XTES`_ * `PRG_PF1K0_WFS`_ * `PRG_RTDSK0`_ * `PRG_SL1K0_POWER`_ * `PRG_SL2K0_POWER`_ * `PRG_ST1K4_TEST`_ PRG_2_PMPS_PRE ^^^^^^^^^^^^^^ :: PROGRAM PRG_2_PMPS_PRE VAR END_VAR MOTION_GVL.fbStandardPMPSDB( io_fbFFHWO:=GVL.fbFastFaultOutput1, bEnable:=TRUE, sPLCName:='plc-kfe-motion', ); END_PROGRAM Related: * `GVL`_ PRG_3_PMPS_POST ^^^^^^^^^^^^^^^ :: PROGRAM PRG_3_PMPS_POST VAR fbArbiterIO: FB_SubSysToArbiter_IO; fb_vetoArbiter: FB_VetoArbiter; bM1K1_Veto_IN: BOOL; END_VAR // create MR1K1 as veto for K4 lines bM1K1_Veto_IN := NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT] AND PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN]; //create a preemptive request from Arbiter 2 in Arbiter 1 fb_vetoArbiter(bVeto:=bM1K1_Veto_IN, HigherAuthority := GVL.fbArbiter, LowerAuthority := GVL.fbArbiter2, FFO := GVL.fbFastFaultOutput2); GVL.fbFastFaultOutput1.Execute(); GVL.fbFastFaultOutput2.Execute(i_xVeto:=bM1K1_Veto_IN); fbArbiterIO( Arbiter:=GVL.fbArbiter, fbFFHWO:=GVL.fbFastFaultOutput1); END_PROGRAM Related: * `GVL`_ PRG_4_LOG ^^^^^^^^^ :: PROGRAM PRG_4_LOG VAR fbLogHandler: FB_LogHandler; END_VAR fbLogHandler(); END_PROGRAM PRG_AT1K4_SOLID ^^^^^^^^^^^^^^^ :: PROGRAM PRG_AT1K4_SOLID VAR (* TODO: use FALSE for simulation and production *) (* TODO: use TRUE when relying on visualization + actual hardware *) bDebug : BOOL := FALSE; nEnableMode : ENUM_StageEnableMode; {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:01'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K4-EL3202-04]^RTD Inputs Channel 2^Status^Overrange; '} fbStage1: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K4-EL3202-03]^RTD Inputs Channel 2^Status^Overrange; '} fbStage2: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:03'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K4-EL3202-02]^RTD Inputs Channel 2^Status^Overrange; '} fbStage3: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT1K4:L2SI:MMS:04'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K4-EL3202-01]^RTD Inputs Channel 2^Status^Overrange; '} fbStage4: FB_SXR_SATT_Stage; fbStateSetup: FB_StateSetupHelper; stDefaultGood: ST_PositionState := ( fDelta := 0.2, fVelocity := 10, bMoveOk := TRUE, bValid := TRUE ); fbBadStateSetup: FB_StateSetupHelper; stDefaultBad: ST_PositionState := ( fPosition := 500, fDelta := 0.2, fVelocity := 10, bMoveOk := FALSE, bValid := FALSE ); END_VAR // M26, Axis 26 // M27, Axis 27 // M28, Axis 28 // M29, Axis 29 IF bDebug THEN // NEVER: checkouts with the TwinCAT NC GUI. nEnableMode := ENUM_StageEnableMode.NEVER; ELSE // ALWAYS: want active position correction at all times nEnableMode := ENUM_StageEnableMode.ALWAYS; END_IF (* Important note Traveler EPICS Stage NC Location Axis 4 MMS:01 fbStage1 26 Downstream Axis 3 MMS:02 fbStage2 27 Axis 2 MMS:03 fbStage3 28 Axis 1 MMS:04 fbStage4 29 Upstream *) fbStateSetup(stPositionState:=stDefaultGood, bSetDefault:=TRUE); fbBadStateSetup(stPositionState:=stDefaultBad, bSetDefault:=TRUE); (* State setup - stage 1 *) (* Downstream-most MMS:01 - TRAVELER AXIS 4 *) fbStateSetup(stPositionState:=fbStage1.stOut, sName:='Out', fPosition:=22.70); fbStateSetup(stPositionState:=fbStage1.stFilter1, sName:='(1) 25 um C', fPosition:=40.5); fbStage1.arrFilters[1].fFilterThickness_um := 25; fbStage1.arrFilters[1].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage1.stFilter2, sName:='(2) 50 um C', fPosition:=56.0); fbStage1.arrFilters[2].fFilterThickness_um := 50; fbStage1.arrFilters[2].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage1.stFilter3, sName:='(3) 100 um C', fPosition:=72.0); fbStage1.arrFilters[3].fFilterThickness_um := 100; fbStage1.arrFilters[3].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage1.stFilter4, sName:='(4) 320 um Si', fPosition:=87.5); fbStage1.arrFilters[4].fFilterThickness_um := 320; fbStage1.arrFilters[4].sFilterMaterial := 'Si'; fbStateSetup(stPositionState:=fbStage1.stFilter5, sName:='(5) 160 um Si', fPosition:=102.5); fbStage1.arrFilters[5].fFilterThickness_um := 160; fbStage1.arrFilters[5].sFilterMaterial := 'Si'; fbStateSetup(stPositionState:=fbStage1.stFilter6, sName:='(6) 80 um Si', fPosition:=117.5); fbStage1.arrFilters[6].fFilterThickness_um := 80; fbStage1.arrFilters[6].sFilterMaterial := 'Si'; fbStateSetup(stPositionState:=fbStage1.stFilter7, sName:='(7) 40 um Si', fPosition:=135.5); fbStage1.arrFilters[7].fFilterThickness_um := 40; fbStage1.arrFilters[7].sFilterMaterial := 'Si'; fbStateSetup(stPositionState:=fbStage1.stFilter8, sName:='(8) 20 um Si', fPosition:=150.5); fbStage1.arrFilters[8].fFilterThickness_um := 20; fbStage1.arrFilters[8].sFilterMaterial := 'Si'; fbStage1(stAxis:=Main.M26, nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 2 *) (* MMS:02 - 2nd downstream-most - TRAVELER AXIS 3 *) fbStateSetup(stPositionState:=fbStage2.stOut, sName:='Out', fPosition:=24.00); fbBadStateSetup(stPositionState:=fbStage2.stFilter1, sName:='Filter 1'); fbStage2.arrFilters[1].fFilterThickness_um := 0; fbStage2.arrFilters[1].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage2.stFilter2, sName:='Filter 2'); fbStage2.arrFilters[2].fFilterThickness_um := 0; fbStage2.arrFilters[2].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage2.stFilter3, sName:='Filter 3'); fbStage2.arrFilters[3].fFilterThickness_um := 0; fbStage2.arrFilters[3].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage2.stFilter4, sName:='Filter 4'); fbStage2.arrFilters[4].fFilterThickness_um := 0; fbStage2.arrFilters[4].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage2.stFilter5, sName:='(5) 50 um C', fPosition:=103.0); fbStage2.arrFilters[5].fFilterThickness_um := 50; fbStage2.arrFilters[5].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage2.stFilter6, sName:='(6) 25 um C', fPosition:=118.75); fbStage2.arrFilters[6].fFilterThickness_um := 25; fbStage2.arrFilters[6].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage2.stFilter7, sName:='(7) 12 um C', fPosition:=133.0); fbStage2.arrFilters[7].fFilterThickness_um := 12; fbStage2.arrFilters[7].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage2.stFilter8, sName:='(8) 10 um Si', fPosition:=147.0); fbStage2.arrFilters[8].fFilterThickness_um := 10; fbStage2.arrFilters[8].sFilterMaterial := 'Si'; fbStage2(stAxis:=Main.M27, nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 3 *) (* MMS:03 - 2nd upstream-most - TRAVELER AXIS 2 *) fbStateSetup(stPositionState:=fbStage3.stOut, sName:='Out', fPosition:=23.24); fbBadStateSetup(stPositionState:=fbStage3.stFilter1, sName:='Filter 1'); fbStage3.arrFilters[1].fFilterThickness_um := 0; fbStage3.arrFilters[1].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage3.stFilter2, sName:='Filter 2'); fbStage3.arrFilters[2].fFilterThickness_um := 0; fbStage3.arrFilters[2].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage3.stFilter3, sName:='Filter 3'); fbStage3.arrFilters[3].fFilterThickness_um := 0; fbStage3.arrFilters[3].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage3.stFilter4, sName:='Filter 4'); fbStage3.arrFilters[4].fFilterThickness_um := 0; fbStage3.arrFilters[4].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage3.stFilter5, sName:='Filter 5'); fbStage3.arrFilters[5].fFilterThickness_um := 0; fbStage3.arrFilters[5].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage3.stFilter6, sName:='(6) 25 um C', fPosition:=119.5); fbStage3.arrFilters[6].fFilterThickness_um := 25; fbStage3.arrFilters[6].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage3.stFilter7, sName:='(7) 12 um C', fPosition:=135.0); fbStage3.arrFilters[7].fFilterThickness_um := 12; fbStage3.arrFilters[7].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage3.stFilter8, sName:='(8) 6 um C', fPosition:=147.5); fbStage3.arrFilters[8].fFilterThickness_um := 6; fbStage3.arrFilters[8].sFilterMaterial := 'C'; fbStage3(stAxis:=Main.M28, nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 4 *) (* MMS:04 - upstream-most - TRAVELER AXIS 1 *) fbStateSetup(stPositionState:=fbStage4.stOut, sName:='Out', fPosition:=23.44); fbBadStateSetup(stPositionState:=fbStage4.stFilter1, sName:='Filter 1'); fbStage4.arrFilters[1].fFilterThickness_um := 0; fbStage4.arrFilters[1].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage4.stFilter2, sName:='Filter 2'); fbStage4.arrFilters[2].fFilterThickness_um := 0; fbStage4.arrFilters[2].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage4.stFilter3, sName:='Filter 3'); fbStage4.arrFilters[3].fFilterThickness_um := 0; fbStage4.arrFilters[3].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage4.stFilter4, sName:='(4) 12 um C', fPosition:=85.5); fbStage4.arrFilters[4].fFilterThickness_um := 12; fbStage4.arrFilters[4].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage4.stFilter5, sName:='(5) 6 um C', fPosition:=100.5); fbStage4.arrFilters[5].fFilterThickness_um := 6; fbStage4.arrFilters[5].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage4.stFilter6, sName:='(6) 3 um C', fPosition:=116.0); fbStage4.arrFilters[6].fFilterThickness_um := 3; fbStage4.arrFilters[6].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage4.stFilter7, sName:='(7) 3 um C', fPosition:=132.0); fbStage4.arrFilters[7].fFilterThickness_um := 3; fbStage4.arrFilters[7].sFilterMaterial := 'C'; fbStateSetup(stPositionState:=fbStage4.stFilter8, sName:='(8) 0.2 um Al', fPosition:=147.0); fbStage4.arrFilters[8].fFilterThickness_um := 0.2; fbStage4.arrFilters[8].sFilterMaterial := 'Al'; fbStage4(stAxis:=Main.M29, nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); GVL.rCurTrans[PMPS.K_Attenuators.AT1K4].nTran := LREAL_TO_REAL( fbStage1.fTransmission * fbStage2.fTransmission * fbStage3.fTransmission * fbStage4.fTransmission ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM1K0_XTES ^^^^^^^^^^^^^^ :: PROGRAM PRG_IM1K0_XTES VAR {attribute 'pytmc' := 'pv: IM1K0:XTES'} {attribute 'TcLinkTo' := '.bZoomEndFwd := TIIB[IM1K0-EL1088]^Channel 1^Input; .bZoomEndBwd := TIIB[IM1K0-EL1088]^Channel 2^Input; .bFocusEndFwd := TIIB[IM1K0-EL1088]^Channel 3^Input; .bFocusEndBwd := TIIB[IM1K0-EL1088]^Channel 4^Input; .fbOpal.bOpalPower := TIIB[IM1K0-EL2004]^Channel 2^Output; .fbLED.bLedPower := TIIB[IM1K0-EL2004]^Channel 3^Output'} fbIM1K0: FB_XPIM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); {attribute 'TcLinkTo' := '.Status := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Status; .D[0] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 0; .D[1] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 1; .D[2] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 2; .D[3] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 3; .D[4] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 4; .D[5] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 5; .D[6] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 6; .D[7] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 7; .D[8] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 8; .D[9] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 9; .D[10] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 10; .D[11] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 11; .D[12] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 12; .D[13] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 13; .D[14] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 14; .D[15] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 15; .D[16] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 16; .D[17] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 17; .D[18] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 18; .D[19] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 19; .D[20] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 20; .D[21] := TIIB[IM1K0-EL6002]^COM TxPDO-Map Inputs Channel 1^Data In 21'} stEL6In AT %I*: EL6InData22b; {attribute 'TcLinkTo' := '.Ctrl := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Ctrl; .D[0] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 0; .D[1] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 1; .D[2] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 2; .D[3] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 3; .D[4] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 4; .D[5] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 5; .D[6] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 6; .D[7] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 7; .D[8] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 8; .D[9] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 9; .D[10] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 10; .D[11] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 11; .D[12] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 12; .D[13] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 13; .D[14] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 14; .D[15] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 15; .D[16] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 16; .D[17] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 17; .D[18] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 18; .D[19] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 19; .D[20] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 20; .D[21] := TIIB[IM1K0-EL6002]^COM RxPDO-Map Outputs Channel 1^Data Out 21'} stEL6Out AT %Q*: EL6OutData22b; END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM1K0.stOut, fPosition:=0, sPmpsState:='IM1K0:XTES-OUT'); fbStateSetup(stPositionState:=fbIM1K0.stYag, fPosition:=-27.65, sPmpsState:='IM1K0:XTES-YAG'); fbStateSetup(stPositionState:=fbIM1K0.stDiamond, fPosition:=-57.65, sPmpsState:='IM1K0:XTES-DIAMOND'); fbStateSetup(stPositionState:=fbIM1K0.stReticle, fPosition:=-87.65, sPmpsState:='IM1K0:XTES-RETICLE'); fbIM1K0( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter, stYStage := Main.M1, stZoomStage := Main.M2, stFocusStage := Main.M3, stEl6In := stEL6In, stEl6Out := stEl6Out, sDeviceName := 'IM1K0:XTES', sTransitionKey := 'IM1K0:XTES-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM1K3_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM1K3_PPM VAR {attribute 'pytmc' := 'pv: IM1K3:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM1K3-EL4004]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM1K3-EL2004]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM1K3-EL3062]^AI Standard Channel 1^Value; .fbPowerMeter.fbThermoCouple.bError := TIIB[IM1K3-EL3314]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbThermoCouple.bUnderrange := TIIB[IM1K3-EL3314]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbThermoCouple.bOverrange := TIIB[IM1K3-EL3314]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbThermoCouple.iRaw := TIIB[IM1K3-EL3314]^TC Inputs Channel 1^Value; .fbYagThermoCouple.bError := TIIB[IM1K3-EL3314]^TC Inputs Channel 2^Status^Error; .fbYagThermoCouple.bUnderrange := TIIB[IM1K3-EL3314]^TC Inputs Channel 2^Status^Underrange; .fbYagThermoCouple.bOverrange := TIIB[IM1K3-EL3314]^TC Inputs Channel 2^Status^Overrange; .fbYagThermoCouple.iRaw := TIIB[IM1K3-EL3314]^TC Inputs Channel 2^Value'} fbIM1K3: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 15, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM1K3.stOut, fPosition:=-9.1, sPmpsState:='IM1K3:PPM-OUT'); fbStateSetup(stPositionState:=fbIM1K3.stPower, fPosition:=-48.2, sPmpsState:='IM1K3:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM1K3.stYag1, fPosition:=-72.2, sPmpsState:='IM1K3:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM1K3.stYag2, fPosition:=-98.21, sPmpsState:='IM1K3:PPM-YAG2'); fbIM1K3( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M4, sDeviceName := 'IM1K3:PPM', sTransitionKey := 'IM1K3:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM1K4_XTES ^^^^^^^^^^^^^^ :: PROGRAM PRG_IM1K4_XTES VAR {attribute 'pytmc' := 'pv: IM1K4:XTES'} {attribute 'TcLinkTo' := '.bZoomEndFwd := TIIB[IM1K4-EL1088-E5]^Channel 1^Input; .bZoomEndBwd := TIIB[IM1K4-EL1088-E5]^Channel 2^Input; .bFocusEndFwd := TIIB[IM1K4-EL1088-E5]^Channel 3^Input; .bFocusEndBwd := TIIB[IM1K4-EL1088-E5]^Channel 4^Input; .fbOpal.bOpalPower := TIIB[IM1K4-EL2004-E2]^Channel 2^Output; .fbLED.bLedPower := TIIB[IM1K4-EL2004-E2]^Channel 3^Output'} fbIM1K4: FB_XPIM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); {attribute 'TcLinkTo' := '.Status := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Status; .D[0] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 0; .D[1] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 1; .D[2] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 2; .D[3] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 3; .D[4] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 4; .D[5] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 5; .D[6] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 6; .D[7] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 7; .D[8] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 8; .D[9] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 9; .D[10] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 10; .D[11] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 11; .D[12] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 12; .D[13] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 13; .D[14] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 14; .D[15] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 15; .D[16] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 16; .D[17] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 17; .D[18] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 18; .D[19] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 19; .D[20] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 20; .D[21] := TIIB[IM1K4-EL6002-E6]^COM TxPDO-Map Inputs Channel 1^Data In 21'} stEL6In AT %I*: EL6InData22b; {attribute 'TcLinkTo' := '.Ctrl := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Ctrl; .D[0] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 0; .D[1] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 1; .D[2] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 2; .D[3] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 3; .D[4] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 4; .D[5] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 5; .D[6] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 6; .D[7] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 7; .D[8] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 8; .D[9] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 9; .D[10] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 10; .D[11] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 11; .D[12] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 12; .D[13] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 13; .D[14] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 14; .D[15] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 15; .D[16] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 16; .D[17] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 17; .D[18] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 18; .D[19] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 19; .D[20] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 20; .D[21] := TIIB[IM1K4-EL6002-E6]^COM RxPDO-Map Outputs Channel 1^Data Out 21'} stEL6Out AT %Q*: EL6OutData22b; {attribute 'pytmc' := ' pv: IM1K4:SCRP:LED:01:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[IM1K4-EL2004-E2]^Channel 4^Output'} bIM1K4_SCRP_LED_01 AT %Q*: BOOL; END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM1K4.stOut, fPosition:=0, sPmpsState:='IM1K4:XTES-OUT'); fbStateSetup(stPositionState:=fbIM1K4.stYag, fPosition:=-88.87, sPmpsState:='IM1K4:XTES-YAG'); fbStateSetup(stPositionState:=fbIM1K4.stDiamond, fPosition:=-58.87, sPmpsState:='IM1K4:XTES-DIAMOND'); fbStateSetup(stPositionState:=fbIM1K4.stReticle, fPosition:=-28.87, sPmpsState:='IM1K4:XTES-RETICLE'); fbIM1K4( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M30, stZoomStage := Main.M31, stFocusStage := Main.M32, stEl6In := stEL6In, stEl6Out := stEl6Out, sDeviceName := 'IM1K4:XTES', sTransitionKey := 'IM1K4:XTES-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM2K0_XTES ^^^^^^^^^^^^^^ :: PROGRAM PRG_IM2K0_XTES VAR {attribute 'pytmc' := 'pv: IM2K0:XTES'} {attribute 'TcLinkTo' := '.fbLED.bLedPower := TIIB[IM2K0-EL2004]^Channel 3^Output; .fbGige.bGigePower := TIIB[IM2K0-EL2004]^Channel 4^Output'} fbIM2K0: FB_XPIM_IM2K0; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); {attribute 'TcLinkTo' := 'TIIB[IM2K0-EL7041]^STM Status^Status^Digital input 1'} bDefectiveLimitSwitch AT %I*: BOOL; END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM2K0.stOut, fPosition:=0, sPmpsState:='IM2K0:XTES-OUT'); fbStateSetup(stPositionState:=fbIM2K0.stYag, fPosition:=-87.65); fbStateSetup(stPositionState:=fbIM2K0.stDiamond, fPosition:=-57.65, sPmpsState:='IM2K0:XTES-DIAMOND'); fbStateSetup(stPositionState:=fbIM2K0.stReticle, fPosition:=-27.65, sPmpsState:='IM2K0:XTES-RETICLE'); CASE GVL.ePF1K0State OF E_WFS_STATES.TARGET1, E_WFS_STATES.TARGET2, E_WFS_STATES.TARGET3, E_WFS_STATES.TARGET4, E_WFS_STATES.TARGET5 : // Known state targets: allow less strict pmps fbIM2K0.stYag.stPMPS.sPmpsState := 'IM2K0:XTES-YAG_WFS_IN'; ELSE // Out, Unknown, or an unexpected state: full pmps fbIM2K0.stYag.stPMPS.sPmpsState := 'IM2K0:XTES-YAG'; END_CASE fbIM2K0( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter, stYStage := Main.M5, sDeviceName := 'IM2K0:XTES', sTransitionKey := 'IM2K0:XTES-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); Main.M5.bLimitForwardEnable := bDefectiveLimitSwitch OR (Main.M5.stAxisStatus.fActPosition < 0); END_PROGRAM Related: * `FB_XPIM_IM2K0`_ * `GVL`_ * `Main`_ PRG_PF1K0_WFS ^^^^^^^^^^^^^ :: PROGRAM PRG_PF1K0_WFS VAR {attribute 'pytmc' := 'pv: PF1K0:WFS'} {attribute 'TcLinkTo' := '.fbThermoCouple1.bError := TIIB[PF1K0-EL3314]^TC Inputs Channel 1^Status^Error; .fbThermoCouple1.bUnderrange := TIIB[PF1K0-EL3314]^TC Inputs Channel 1^Status^Underrange; .fbThermoCouple1.bOverrange := TIIB[PF1K0-EL3314]^TC Inputs Channel 1^Status^Overrange; .fbThermoCouple1.iRaw := TIIB[PF1K0-EL3314]^TC Inputs Channel 1^Value; .fbThermoCouple2.bError := TIIB[PF1K0-EL3314]^TC Inputs Channel 2^Status^Error; .fbThermoCouple2.bUnderrange := TIIB[PF1K0-EL3314]^TC Inputs Channel 2^Status^Underrange; .fbThermoCouple2.bOverrange := TIIB[PF1K0-EL3314]^TC Inputs Channel 2^Status^Overrange; .fbThermoCouple2.iRaw := TIIB[PF1K0-EL3314]^TC Inputs Channel 2^Value'} fbPF1K0: FB_WFS; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbPF1K0.stOut, fPosition:=-15, sPmpsState:='PF1K0:WFS-OUT'); fbStateSetup(stPositionState:=fbPF1K0.stTarget1, fPosition:=-96.623, sPmpsState:='PF1K0:WFS-TARGET1'); fbStateSetup(stPositionState:=fbPF1K0.stTarget2, fPosition:=-82.25, sPmpsState:='PF1K0:WFS-TARGET2'); fbStateSetup(stPositionState:=fbPF1K0.stTarget3, fPosition:=-67.874, sPmpsState:='PF1K0:WFS-TARGET3'); fbStateSetup(stPositionState:=fbPF1K0.stTarget4, fPosition:=-53.5, sPmpsState:='PF1K0:WFS-TARGET4'); fbStateSetup(stPositionState:=fbPF1K0.stTarget5, fPosition:=-39.124, sPmpsState:='PF1K0:WFS-TARGET5'); fbPF1K0( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter, stYStage := Main.M8, stZStage := Main.M9, sDeviceName := 'PF1K0:WFS', sTransitionKey := 'PF1K0:WFS-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, eEnumGet => GVL.ePF1K0State, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_RTDSK0 ^^^^^^^^^^ :: PROGRAM PRG_RTDSK0 VAR {attribute 'TcLinkTo' := '.i_xInsertedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 1^Input; .i_xRetractedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 2^Input; .q_xInsert_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 1^Output; .q_xRetract_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 2^Output '} {attribute 'pytmc' :=' pv: RTDSK0:MPA:01 '} RTDSK0_MPA_01: FB_MPA := (sName := 'RTDSK0:MPA:01'); {attribute 'TcLinkTo' := '.i_xInsertedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 3^Input; .i_xRetractedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 4^Input; .q_xInsert_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 3^Output; .q_xRetract_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 4^Output '} {attribute 'pytmc' :=' pv: RTDSK0:MPA:02 '} RTDSK0_MPA_02: FB_MPA := (sName := 'RTDSK0:MPA:02'); {attribute 'TcLinkTo' := '.i_xInsertedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 5^Input; .i_xRetractedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 6^Input; .q_xInsert_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 5^Output; .q_xRetract_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 6^Output '} {attribute 'pytmc' :=' pv: RTDSK0:MPA:03 '} RTDSK0_MPA_03: FB_MPA := (sName := 'RTDSK0:MPA:03'); {attribute 'TcLinkTo' := '.i_xInsertedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 7^Input; .i_xRetractedLS := TIIB[RTDSK0-MPA-EL1008]^Channel 8^Input; .q_xInsert_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 7^Output; .q_xRetract_DO := TIIB[RTDSK0-MPA-EL2008]^Channel 8^Output '} {attribute 'pytmc' :=' pv: RTDSK0:MPA:04 '} RTDSK0_MPA_04: FB_MPA := (sName := 'RTDSK0:MPA:04'); fbRTDSK0_SCRP_MMS_Z: FB_MotionStage; fbRTDSK0_SCRP_MMS_X: FB_MotionStage; fbRTDSK0_SCRP_MMS_Y: FB_MotionStage; {attribute 'pytmc' := 'pv: RTDSK0:SCRP:LED:01:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[RTDSK0-EL2004]^Channel 3^Output'} bRTDSK0_SCRP_LED_01 AT %Q*: BOOL; FFO : FB_FastFault :=( i_Desc := 'fault occurs when Y motor is not activating upper limit switch', i_TypeCode := 16#FAF, i_DevName := 'RTDSK0:SCRP:MMS:Y'); bInit: BOOL := TRUE; END_VAR //Pneumatic actuators - OTR filters RTDSK0_MPA_01( ibInsertOK:= TRUE, ibRetractOK:= TRUE , ibPMPS_OK:= TRUE , ibOverrideInterlock:= , q_stAct=> , xMPS_OK=> , xDone=> , i_xReset := , io_fbFFHWO := GVL.fbFastFaultOutput1, ); RTDSK0_MPA_02( ibInsertOK:= TRUE, ibRetractOK:= TRUE , ibPMPS_OK:= TRUE , ibOverrideInterlock:= , q_stAct=> , xMPS_OK=> , xDone=> , i_xReset := , io_fbFFHWO := GVL.fbFastFaultOutput1, ); (* Disable MPA_03 and MPA_04, no actuator installed RTDSK0_MPA_03( ibInsertOK:= TRUE, ibRetractOK:= TRUE , ibPMPS_OK:= TRUE , ibOverrideInterlock:= , q_stAct=> , xMPS_OK=> , xDone=> , i_xReset := , io_fbFFHWO := GVL.fbFastFaultOutput1, ); RTDSK0_MPA_04( ibInsertOK:= TRUE, ibRetractOK:= TRUE , ibPMPS_OK:= TRUE , ibOverrideInterlock:= , q_stAct=> , xMPS_OK=> , xDone=> , i_xReset := , io_fbFFHWO := GVL.fbFastFaultOutput1, ); *) //initialize RTDSK0 stages IF bInit THEN Main.M11.bHardwareEnable := TRUE; Main.M11.bPowerSelf :=TRUE; Main.M11.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M11.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; Main.M11.fHomePosition := 0; Main.M12.bHardwareEnable := TRUE; Main.M12.bPowerSelf :=TRUE; Main.M12.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M12.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; Main.M12.fHomePosition := 0; Main.M13.bHardwareEnable := TRUE; Main.M13.bPowerSelf :=TRUE; Main.M13.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M13.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; Main.M13.fHomePosition := 0; Main.M11.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT; Main.M12.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT; Main.M13.nHomingMode := ENUM_EpicsHomeCmd.HIGH_LIMIT; bInit := FALSE; END_IF fbRTDSK0_SCRP_MMS_Z (stMotionStage := Main.M11); fbRTDSK0_SCRP_MMS_X (stMotionStage := Main.M12); fbRTDSK0_SCRP_MMS_Y (stMotionStage := Main.M13); FFO(i_xOK := NOT(Main.M13.bLimitForwardEnable) AND Main.M13.bLimitBackwardEnable, io_fbFFHWO := GVL.fbFastFaultOutput1); END_PROGRAM Related: * `FB_MPA`_ * `GVL`_ * `Main`_ PRG_SL1K0_POWER ^^^^^^^^^^^^^^^ :: PROGRAM PRG_SL1K0_POWER VAR {attribute 'pytmc' := ' pv: SL1K0:POWER io: io '} {attribute 'TcLinkTo' := '.RTD_South_1.iRaw := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 1^Value; .RTD_South_1.bError := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 1^Status^Error; .RTD_South_1.bUnderrange := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 1^Status^Underrange; .RTD_South_1.bOverrange := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 1^Status^Overrange; .RTD_South_2.iRaw := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 2^Value; .RTD_South_2.bError := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 2^Status^Error; .RTD_South_2.bUnderrange := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 2^Status^Underrange; .RTD_South_2.bOverrange := TIIB[SL1K0-EL3202-E6]^RTD Inputs Channel 2^Status^Overrange; .RTD_TOP_1.iRaw := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 1^Value; .RTD_TOP_1.bError := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 1^Status^Error; .RTD_TOP_1.bUnderrange := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 1^Status^Underrange; .RTD_TOP_1.bOverrange := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 1^Status^Overrange; .RTD_TOP_2.iRaw := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 2^Value; .RTD_TOP_2.bError := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 2^Status^Error; .RTD_TOP_2.bUnderrange := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 2^Status^Underrange; .RTD_TOP_2.bOverrange := TIIB[SL1K0-EL3202-E7]^RTD Inputs Channel 2^Status^Overrange; .RTD_North_1.iRaw := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 1^Value; .RTD_North_1.bError := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 1^Status^Error; .RTD_North_1.bUnderrange := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 1^Status^Underrange; .RTD_North_1.bOverrange := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 1^Status^Overrange; .RTD_North_2.iRaw := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 2^Value; .RTD_North_2.bError := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 2^Status^Error; .RTD_North_2.bUnderrange := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 2^Status^Underrange; .RTD_North_2.bOverrange := TIIB[SL1K0-EL3202-E8]^RTD Inputs Channel 2^Status^Overrange; .RTD_Bottom_1.iRaw := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 1^Value; .RTD_Bottom_1.bError := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 1^Status^Error; .RTD_Bottom_1.bUnderrange := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 1^Status^Underrange; .RTD_Bottom_1.bOverrange := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 1^Status^Overrange; .RTD_Bottom_2.iRaw := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 2^Value; .RTD_Bottom_2.bError := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 2^Status^Error; .RTD_Bottom_2.bUnderrange := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 2^Status^Underrange; .RTD_Bottom_2.bOverrange := TIIB[SL1K0-EL3202-E9]^RTD Inputs Channel 2^Status^Overrange; .AptArrayStatus := 'TIIB[PMPS_PRE]^IO Outputs^AptArrayStatus^AptArrayStatus[1]; .AptArrayReq := 'TIIB[PMPS_PRE]^IO Inputs^AptArrayReq^AptArrayReq[1]'} fbSL1K0: FB_SLITS_POWER; //{attribute 'TcLinkTo' := 'TIIB[PMPS_PRE]^IO Outputs^AptArrayStatus'} {attribute 'pytmc' := ' pv: SL1K0:POWER:GO; io: io; field: ZNAM False; field: ONAM True; '} bExecuteMotion:BOOL ; //GET PMPS Move Ok bit // Default True until it is properly linked to PMPS bit bMoveOk:BOOL :=TRUE; //for testing purposes only. comment-out/delete once done. mcPower : ARRAY [1..4] OF MC_POWER; bTest:BOOL:=FALSE; (*Offsets*) (* Absolute encoder value at the HLS + Absolure eoncoder value at the centered beam *) rEncoderOffsetTop: REAL := -11.2; (* 0+(-15)*) rEncoderOffsetBottom: REAL := -11.9; (* 0+(-15)*) rEncoderOffsetNorth: REAL := -11.4;//-4.6;(* 0+(-15)*) rEncoderOffsetSouth: REAL := -13;(* 0+(-15)*) END_VAR fbSL1K0.bMoveOk := bMoveOk; Main.M18.bLimitBackwardEnable := True; //for testing purposes only. comment-out/delete once done. If bTest THEN mcPower[1](axis:=Main.M18.Axis, Enable:=TRUE, enable_positive:=Main.M18.bLimitForwardEnable, enable_negative:=Main.M18.bLimitBackwardEnable); mcPower[2](axis:=Main.M19.Axis, Enable:=TRUE, enable_positive:=Main.M19.bLimitForwardEnable, enable_negative:=Main.M19.bLimitBackwardEnable); mcPower[3](axis:=Main.M20.Axis, Enable:=TRUE, enable_positive:=Main.M20.bLimitForwardEnable, enable_negative:=Main.M20.bLimitBackwardEnable); mcPower[4](axis:=Main.M21.Axis, Enable:=TRUE, enable_positive:=Main.M21.bLimitForwardEnable, enable_negative:=Main.M21.bLimitBackwardEnable); else //force that inner limit switch on south motor is not depressed. need to debug further in winter down. //Main.M18.bLimitForwardEnable := TRUE; fbSL1K0.rEncoderOffsetTop := rEncoderOffsetTop; fbSL1K0.rEncoderOffsetBottom := rEncoderOffsetBottom; fbSL1K0.rEncoderOffsetNorth := rEncoderOffsetNorth; fbSL1K0.rEncoderOffsetSouth := rEncoderOffsetSouth; fbSL1K0(stTopBlade:= Main.M19, stBottomBlade:= Main.M21, stNorthBlade:= Main.M20, stSouthBlade:= Main.M18, bExecuteMotion:=bExecuteMotion, io_fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter); fbSL1K0.M_UpdatePMPS(1); END_IF END_PROGRAM Related: * `FB_SLITS_POWER`_ * `GVL`_ * `Main`_ PRG_SL2K0_POWER ^^^^^^^^^^^^^^^ :: PROGRAM PRG_SL2K0_POWER VAR {attribute 'pytmc' := ' pv: SL2K0:POWER io: io '} {attribute 'TcLinkTo' := '.RTD_South_1.iRaw := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 1^Value; .RTD_South_1.bError := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 1^Status^Error; .RTD_South_1.bUnderrange := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 1^Status^Underrange; .RTD_South_1.bOverrange := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 1^Status^Overrange; .RTD_South_2.iRaw := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 2^Value; .RTD_South_2.bError := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 2^Status^Error; .RTD_South_2.bUnderrange := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 2^Status^Underrange; .RTD_South_2.bOverrange := TIIB[SL2K0-EL3202-E8]^RTD Inputs Channel 2^Status^Overrange; .RTD_TOP_1.iRaw := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 1^Value; .RTD_TOP_1.bError := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 1^Status^Error; .RTD_TOP_1.bUnderrange := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 1^Status^Underrange; .RTD_TOP_1.bOverrange := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 1^Status^Overrange; .RTD_TOP_2.iRaw := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 2^Value; .RTD_TOP_2.bError := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 2^Status^Error; .RTD_TOP_2.bUnderrange := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 2^Status^Underrange; .RTD_TOP_2.bOverrange := TIIB[SL2K0-EL3202-E9]^RTD Inputs Channel 2^Status^Overrange; .RTD_North_1.iRaw := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Value; .RTD_North_1.bError := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Status^Error; .RTD_North_1.bUnderrange := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Status^Underrange; .RTD_North_1.bOverrange := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Status^Overrange; .RTD_North_2.iRaw := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 2^Value; .RTD_North_2.bError := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 2^Status^Error; .RTD_North_2.bUnderrange := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 2^Status^Underrange; .RTD_North_2.bOverrange := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 2^Status^Overrange; .RTD_Bottom_1.iRaw := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Value; .RTD_Bottom_1.bError := TIIB[SL2K0-EL3202-E10]^RTD Inputs Channel 1^Status^Error; .RTD_Bottom_1.bUnderrange := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 1^Status^Underrange; .RTD_Bottom_1.bOverrange := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 1^Status^Overrange; .RTD_Bottom_2.iRaw := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 2^Value; .RTD_Bottom_2.bError := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 2^Status^Error; .RTD_Bottom_2.bUnderrange := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 2^Status^Underrange; .RTD_Bottom_2.bOverrange := TIIB[SL2K0-EL3202-E11]^RTD Inputs Channel 2^Status^Overrange; .AptArrayStatus := 'TIIB[PMPS_PRE]^IO Outputs^AptArrayStatus^AptArrayStatus[2]; .AptArrayReq := 'TIIB[PMPS_PRE]^IO Inputs^AptArrayReq^AptArrayReq[2]'} fbSL2K0: FB_SLITS_POWER; //GET PMP Move Ok bit // Default True until it is properly linked to PMPS bit bMoveOk:BOOL :=TRUE; {attribute 'pytmc' := ' pv: SL2K0:POWER:GO; io: io; field: ZNAM False; field: ONAM True; '} bExecuteMotion:BOOL ; //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.1; rEncoderOffsetBottom: REAL := -12.2; rEncoderOffsetNorth: REAL := 15.4; rEncoderOffsetSouth: REAL := -13.4; END_VAR fbSL2K0.bMoveOk := bMoveOk; fbSL2K0.rEncoderOffsetTop := rEncoderOffsetTop; fbSL2K0.rEncoderOffsetBottom := rEncoderOffsetBottom; fbSL2K0.rEncoderOffsetNorth := rEncoderOffsetNorth; fbSL2K0.rEncoderOffsetSouth := rEncoderOffsetSouth; fbSL2K0(stTopBlade:= Main.M23, stBottomBlade:= Main.M25, stNorthBlade:= Main.M24, stSouthBlade:= Main.M22, bExecuteMotion:=bExecuteMotion, io_fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter); fbSL2K0.M_UpdatePMPS(2); //for testing purposes only. comment-out/delete once done. (*mcPower[1](axis:=Main.M22.Axis, Enable:=TRUE, enable_positive:=Main.M22.bLimitForwardEnable, enable_negative:=Main.M22.bLimitBackwardEnable); mcPower[2](axis:=Main.M23.Axis, Enable:=TRUE, enable_positive:=Main.M23.bLimitForwardEnable, enable_negative:=Main.M23.bLimitBackwardEnable); mcPower[3](axis:=Main.M24.Axis, Enable:=TRUE, enable_positive:=Main.M24.bLimitForwardEnable, enable_negative:=Main.M24.bLimitBackwardEnable); mcPower[4](axis:=Main.M25.Axis, Enable:=TRUE, enable_positive:=Main.M25.bLimitForwardEnable, enable_negative:=Main.M25.bLimitBackwardEnable);*) END_PROGRAM Related: * `FB_SLITS_POWER`_ * `GVL`_ * `Main`_ PRG_ST1K4_TEST ^^^^^^^^^^^^^^ :: PROGRAM PRG_ST1K4_TEST VAR fbMotion: FB_MotionStage; {attribute 'pytmc' := ' pv: ST1K4:TEST:MMS astPositionState.array: 1..2 '} fbStates: FB_PositionState1D; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fDelta := 1, fVelocity := 5, bMoveOk := TRUE, bValid := TRUE ); astPositionState: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; {attribute 'pytmc' := ' pv: ST1K4:TEST:MMS:STATE:GET io: i '} eEnumGet: E_EpicsInOut; {attribute 'pytmc' := ' pv: ST1K4:TEST:MMS:STATE:SET io: io '} eEnumSet: E_EpicsInOut; bST3K4_in: BOOL; {attribute 'pytmc' := ' pv: ST1K4:TEST:MMS:STATE:ST3K4_AUTO io: io '} bST3K4_auto: BOOL := TRUE; END_VAR // M33, Axis 33 Main.M33.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; Main.M33.bHardwareEnable:= TRUE; Main.M33.bPowerSelf := TRUE; Main.M33.nBrakeMode := ENUM_StageBrakeMode.IF_ENABLED; fbMotion(stMotionStage:=Main.M33); // States fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=astPositionState[E_EpicsInOut.IN], sName:='IN', fPosition:=2); fbStateSetup(stPositionState:=astPositionState[E_EpicsInOut.OUT], sName:='OUT', fPosition:=40); fbStates( stMotionStage:=Main.M33, astPositionState:=astPositionState, eEnumSet:=eEnumSet, eEnumGet:=eEnumGet, bEnable:=TRUE, ); bST3K4_in := PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST3K4]; IF bST3K4_auto THEN IF bST3K4_in AND eEnumGet <> E_EpicsInOut.IN THEN eEnumSet := ENUM_EpicsInOut.IN; ELSIF NOT bST3K4_in AND eEnumGet <> E_EpicsInOut.OUT THEN eEnumSet := ENUM_EpicsInOut.OUT; END_IF END_IF END_PROGRAM Related: * `Main`_