DUTs ---- DUT_SATT_Filter ^^^^^^^^^^^^^^^ :: TYPE DUT_SATT_Filter : STRUCT {attribute 'pytmc' := ' pv: MATERIAL io: input field: DESC Filter material name '} sFilterMaterial : STRING; {attribute 'pytmc' := ' pv: THICKNESS io: input field: DESC Filter material thickness field: EGU um '} fFilterThickness_um : LREAL; END_STRUCT END_TYPE Related: * `DUT_SATT_Filter`_ E_TM1K2_States ^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} TYPE E_TM1K2_States : // Adapted from E_ATM_States to add TARGET6 ( Unknown := 0, OUT := 1, TARGET1 := 2, TARGET2 := 3, TARGET3 := 4, TARGET4 := 5, TARGET5 := 6, TARGET6 := 7, TARGET7 := 8, TARGET8 := 9 ) UINT; END_TYPE E_TM2K2_States ^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} TYPE E_TM2K2_States : // Adapted from E_ATM_States to add TARGET6 ( Unknown := 0, OUT := 1, TARGET1 := 2, TARGET2 := 3, TARGET3 := 4, TARGET4 := 5, TARGET5 := 6, TARGET6 := 7 ) UINT; END_TYPE ENUM_SXR_SATT_Position ^^^^^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} TYPE ENUM_SXR_SATT_Position : ( UNKNOWN := 0, // UNKNOWN must be in slot 0 or the FB breaks OUT := 1, // OUT at slot 1 is a convention FILTER1 := 2, FILTER2 := 3, FILTER3 := 4, FILTER4 := 5, FILTER5 := 6, FILTER6 := 7, FILTER7 := 8, FILTER8 := 9 ); END_TYPE GVLs ---- GVL ^^^ :: {attribute 'qualified_only'} VAR_GLOBAL {attribute 'pytmc' := 'pv: PLC:RIX:MOTION:ARB:01'} fbArbiter1: FB_Arbiter(1); {attribute 'pytmc' := 'pv: PLC:RIX:MOTION:ARB:02'} fbArbiter2: FB_Arbiter(2); // For devices between the mirror and the stopper, uses 44 FF slots as of 1/12/2024, load 75 in EPICS (skip 125 for IOC load speed) {attribute 'pytmc' := ' pv: PLC:RIX:MOTION:FFO:01 astFF.array: 1..75 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 1^Output'} fbFastFaultOutput1: FB_HardwareFFOutput := (bAutoReset := TRUE, i_sNetID:='172.21.42.126.1.1'); // For devices after the stopper, uses 165 FF slots as of 1/12/2024, load all in EPICS {attribute 'pytmc' := ' pv: PLC:RIX:MOTION:FFO:02 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 2^Output'} fbFastFaultOutput2: FB_HardwareFFOutput := (bAutoReset := TRUE, i_sNetID:='172.21.42.126.1.1'); fbAtomicMass : FB_AtomicMass; fbAttenuatorElementDensity : FB_AttenuatorElementDensity; {attribute 'pytmc' := 'pv: PLC:RIX:MOTION:PMPS:ReqTrans'} rReqTrans AT %I* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; {attribute 'pytmc' := 'pv: PLC:RIX:MOTION:PMPS:CurTrans'} rCurTrans AT %Q* : ARRAY [1..PMPS_GVL.AUX_ATTENUATORS] OF ST_PMPS_Attenuator_IO; ePF1K2State: E_WFS_States; ePF2K2State: E_WFS_States; END_VAR VAR_GLOBAL CONSTANT iFiltersPerSATTBlade : INT := 8; END_VAR Main ^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL // IM1K1-PPM-MMS {attribute 'pytmc' := 'pv: IM1K1:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM1K1-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM1K1-EL7041]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM1K1-EL2004]^Channel 1^Output'} M1: ST_MotionStage := (sName := 'IM1K1:PPM:MMS'); // IM2K1-PPM-MMS {attribute 'pytmc' := 'pv: IM2K1:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM2K1-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM2K1-EL7041]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM2K1-EL2004]^Channel 1^Output'} M2: ST_MotionStage := (sName := 'IM2K1:PPM:MMS'); // SPARE (Previously ZOS) M3: ST_MotionStage; // IM1K2-PPM-MMS {attribute 'pytmc' := 'pv: IM1K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM1K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM1K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM1K2-EL2004-E3]^Channel 1^Output'} M4: ST_MotionStage := (sName := 'IM1K2:PPM:MMS'); // AL1K2-L2SI: 1 Axis {attribute 'pytmc' := 'pv: AL1K2:L2SI:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[AL1K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AL1K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[AL1K2-EL2004-E3]^Channel 1^Output; .nRawEncoderULINT := TIIB[AL1K2-EL5042-E2]^FB Inputs Channel 1^Position'} M5: ST_MotionStage := (sName := 'AL1K2:L2SI:MMS'); // IM2K2-PPM-MMS {attribute 'pytmc' := 'pv: IM2K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM2K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM2K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM2K2-EL2004-E3]^Channel 1^Output'} M6: ST_MotionStage := (sName := 'IM2K2:PPM:MMS'); // IM3K2-PPM-MMS {attribute 'pytmc' := 'pv: IM3K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM3K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM3K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM3K2-EL2004-E3]^Channel 1^Output'} M7: ST_MotionStage := (sName := 'IM3K2:PPM:MMS'); // IM4K2-PPM-MMS {attribute 'pytmc' := 'pv: IM4K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM4K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM4K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM4K2-EL2004-E3]^Channel 1^Output'} M8: ST_MotionStage := (sName := 'IM4K2:PPM:MMS'); // TM1K2: 2 Axes {attribute 'pytmc' := 'pv: TM1K2:ATM:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[TM1K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[TM1K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[TM1K2-EL2004-E4]^Channel 1^Output; .nRawEncoderULINT := TIIB[TM1K2-EL5042-E3]^FB Inputs Channel 1^Position'} M9: ST_MotionStage := (sName := 'TM1K2:ATM:MMS:Y'); {attribute 'pytmc' := 'pv: TM1K2:ATM:MMS:X'} {attribute 'TcLinkTo' := '.nRawEncoderULINT := TIIB[TM1K2-EL5042-E3]^FB Inputs Channel 2^Position'} M10: ST_MotionStage := (sName := 'TM1K2:ATM:MMS:X'); // LI2K2-K2A_OUT: 1 Axis {attribute 'pytmc' := 'pv: LI2K2:K2A:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[LI2K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[LI2K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[LI2K2-EL2004-E2]^Channel 1^Output; .nRawEncoderULINT := TIIB[LI2K2-EL5042-E3]^FB Inputs Channel 1^Position'} M11: ST_MotionStage := (sName := 'LI2K2:K2A:MMS'); // PF1K2-WFS: 2 Axes {attribute 'pytmc' := 'pv: PF1K2:WFS:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PF1K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PF1K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[PF1K2-EL2004-E4]^Channel 1^Output; .nRawEncoderULINT := TIIB[PF1K2-EL5042-E3]^FB Inputs Channel 2^Position'} M12: ST_MotionStage := (sName := 'PF1K2:WFS:MMS:Y'); {attribute 'pytmc' := 'pv: PF1K2:WFS:MMS:Z'} {attribute 'TcLinkTo' := '.nRawEncoderULINT := TIIB[PF1K2-EL5042-E3]^FB Inputs Channel 1^Position'} M13: ST_MotionStage := (sName := 'PF1K2:WFS:MMS:Z'); // IM5K2-PPM-MMS {attribute 'pytmc' := 'pv: IM5K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM5K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM5K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM5K2-EL2004-E3]^Channel 1^Output'} M14: ST_MotionStage := (sName := 'IM5K2:PPM:MMS'); // TM2K2: 2 Axes {attribute 'pytmc' := 'pv: TM2K2:ATM:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[TM2K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[TM2K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[TM2K2-EL2004-E4]^Channel 1^Output; .nRawEncoderULINT := TIIB[TM2K2-EL5042-E3]^FB Inputs Channel 1^Position'} M15: ST_MotionStage := (sName := 'TM2K2:ATM:MMS:Y'); {attribute 'pytmc' := 'pv: TM2K2:ATM:MMS:X'} {attribute 'TcLinkTo' := '.nRawEncoderULINT := TIIB[TM2K2-EL5042-E3]^FB Inputs Channel 2^Position'} M16: ST_MotionStage := (sName := 'TM2K2:ATM:MMS:X'); //AT2K2: 4 Axes (* AT2K2 Solid Attenuator notes (JJ-xray SN-11343) JJ Label EPICS Stage NC Location 1087 1 MMS:01 fbStage1 M17 Upstream-most 1088 2 MMS:02 fbStage2 M18 1086 3 MMS:03 fbStage3 M19 1089 4 MMS:04 fbStage4 M20 Downstream-most *) {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:01'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT2K2-EL7047-01]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT2K2-EL7047-01]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT2K2-EL5042-01]^FB Inputs Channel 1^Position '} M17: ST_MotionStage := (sName := 'AT2K2:L2SI:MMS:01'); {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT2K2-EL7047-02]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT2K2-EL7047-02]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT2K2-EL5042-01]^FB Inputs Channel 2^Position '} M18: ST_MotionStage := (sName := 'AT2K2:L2SI:MMS:02'); {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:03'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT2K2-EL7047-03]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT2K2-EL7047-03]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT2K2-EL5042-02]^FB Inputs Channel 1^Position '} M19: ST_MotionStage := (sName := 'AT2K2:L2SI:MMS:03'); {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:04'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT2K2-EL7047-04]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT2K2-EL7047-04]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT2K2-EL5042-02]^FB Inputs Channel 2^Position '} M20: ST_MotionStage := (sName := 'AT2K2:L2SI:MMS:04'); //LI3K2-K2B: 1 Axis {attribute 'pytmc' := 'pv: LI3K2:K2B:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[LI3K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[LI3K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[LI3K2-EL2004-E3]^Channel 1^Output; .nRawEncoderULINT := TIIB[LI3K2-EL5042-E2]^FB Inputs Channel 1^Position'} M21: ST_MotionStage := (sName := 'LI3K2:K2B:MMS'); //PF2K2: 2 Axes {attribute 'pytmc' := 'pv: PF2K2:WFS:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PF2K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PF2K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[PF2K2-EL2004-E4]^Channel 1^Output; .nRawEncoderULINT := TIIB[PF2K2-EL5042-E3]^FB Inputs Channel 2^Position'} M22: ST_MotionStage := (sName := 'PF2K2:WFS:MMS:Y'); {attribute 'pytmc' := 'pv: PF2K2:WFS:MMS:Z'} {attribute 'TcLinkTo' := '.nRawEncoderULINT := TIIB[PF2K2-EL5042-E3]^FB Inputs Channel 1^Position'} M23: ST_MotionStage := (sName := 'PF2K2:WFS:MMS:Z'); //IM6K2: 1 Axis {attribute 'pytmc' := 'pv: IM6K2:PPM:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[IM6K2-EL7041-E1]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[IM6K2-EL7041-E1]^STM Status^Status^Digital input 2; .bBrakeRelease := TIIB[IM6K2-EL2004-E3]^Channel 1^Output'} M24: ST_MotionStage := (sName := 'IM6K2:PPM:MMS'); //AT1K2: Blade 1 {attribute 'pytmc' := 'pv: AT1K2:L2SI:MMS:01'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K2-EL7047-01]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K2-EL7047-01]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K2-EL5042-01]^FB Inputs Channel 1^Position'; ;} M25: ST_MotionStage := (sName := 'AT1K2:L2SI:MMS:01'); //AT1K2: Blade 2 {attribute 'pytmc' := 'pv: AT1K2:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .bLimitForwardEnable := TIIB[AT1K2-EL7047-02]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[AT1K2-EL7047-02]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[AT1K2-EL5042-01]^FB Inputs Channel 2^Position'; ;} M26: ST_MotionStage := (sName := 'AT1K2:L2SI:MMS:02'); //AT1K2: Mirror {attribute 'pytmc' := 'pv: AT1K2:L2SI:MMS:03'} {attribute 'TcLinkTo' := ' .nRawEncoderULINT := TIIB[AT1K2-EL5042-02]^FB Inputs Channel 1^Position'; ;} M27: ST_MotionStage := (sName := 'AT1K2:L2SI:MMS:03'); // PAX Motors {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:01'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E01]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E01]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E02]^FB Inputs Channel 1^Position'} M28: ST_MotionStage := (sName := 'SP1K2:PAX:FRAME:Y:01'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:02'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E03]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E03]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E02]^FB Inputs Channel 2^Position'} M29: ST_MotionStage := (sName := 'SP1K2:PAX:FRAME:Y:02'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:03'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E04]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E04]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E05]^FB Inputs Channel 1^Position'} M30: ST_MotionStage := (sName := 'SP1K2:PAX:FRAME:Y:03'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:X:01'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E06]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[PAX-EL7047-E06]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[PAX-EL2004-E07]^Channel 1^Output; .nRawEncoderULINT := TIIB[PAX-EL5042-E05]^FB Inputs Channel 2^Position'} M31: ST_MotionStage := (sName := 'SP1K2:PAX:FRAME:X'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:X:02'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIID^PLC Rail (EtherCAT)^Power (EK1200)^Fiber Coupler (EK1521-0010)^Term 123 (EK1100)^Term 73 (EK1122)^PAX-DRL-02 (EK1100)^PAX-EL7047-E08^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIID^PLC Rail (EtherCAT)^Power (EK1200)^Fiber Coupler (EK1521-0010)^Term 123 (EK1100)^Term 73 (EK1122)^PAX-DRL-02 (EK1100)^PAX-EL7047-E08^STM Status^Status^Digital input 1; .nRawEncoderULINT := TIID^PLC Rail (EtherCAT)^Power (EK1200)^Fiber Coupler (EK1521-0010)^Term 123 (EK1100)^Term 73 (EK1122)^PAX-DRL-02 (EK1100)^PAX-EL5042-E09^FB Inputs Channel 1^Position'} M32: ST_MotionStage := (sName := 'SP1K2:PAX:TAR:X'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:04'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E10]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[PAX-EL7047-E10]^STM Status^Status^Digital input 1; .nRawEncoderULINT := TIIB[PAX-EL5042-E09]^FB Inputs Channel 2^Position'} M33: ST_MotionStage := (sName := 'SP1K2:PAX:TAR:Y'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Z:01'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E12]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E12]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E13]^FB Inputs Channel 1^Position'} M34: ST_MotionStage := (sName := 'SP1K2:PAX:TAR:Z'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:RY:01'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E14]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E14]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E13]^FB Inputs Channel 2^Position'} M35: ST_MotionStage := (sName := 'SP1K2:PAX:MMS:RY:01'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:05'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E15]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E15]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E16]^FB Inputs Channel 1^Position'} M36: ST_MotionStage := (sName := 'SP1K2:PAX:BB:Y:01'); {attribute 'pytmc' := 'pv: SP1K2:PAX:MMS:Y:06'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[PAX-EL7047-E17]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[PAX-EL7047-E17]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[PAX-EL5042-E16]^FB Inputs Channel 2^Position'} M37: ST_MotionStage := (sName := 'SP1K2:PAX:BB:Y:02'); END_VAR POUs ---- FB_AnalogInput_IM4K2 ^^^^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_AnalogInput_IM4K2 (* Converts the integer from an analog input terminal to a real unit value (e.g., volts) 2019-10-09 Zachary Lentz *) VAR_INPUT // Connect this input to the terminal iRaw AT %I*: DINT; // 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; // Value to scale the end result to {attribute 'pytmc' := ' pv: RES io: io '} fResolution : LREAL := 1; {attribute 'pytmc' := ' pv: OFF io: io '} fOffset : LREAL; END_VAR VAR_OUTPUT // The real value read from the output {attribute 'pytmc' := ' pv: VAL io: i '} fReal: LREAL; END_VAR VAR fScale: LREAL; END_VAR fScale := (EXPT(2, iTermBits) - 1); fReal := (iRaw / fScale) * fTermMax; fReal := fReal * fResolution + fOffset; END_FUNCTION_BLOCK FB_PPM_IM4K2 ^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_PPM_IM4K2 (* Function block for Power and Profile Monitor (PPM) controls: - Y motion - Y power and profile states - power meter - camera power - camera illuminator - flow meter - thermocouple The following IO link points are included and should be used: - FB_PPM.fbPowerMeter.iVoltageINT should be linked to the power meter analog input voltage - FB_PPM.fbPowerMeter.fbThermoCouple.bError, bUnderrange, bOverrange, and iRaw should be linked to the corresponding thermocouple terminal inputs. - FB_PPM.fbGige.iIlluminatorINT should be linked to illuminator dimmer analog output voltage - FB_PPM.fbGige.bGigePower should be linked to the camera power digial output channel - FB_PPM.fbFlowMeter.iRaw should be linked to the flow meter current analog input channel - FB_PPM.fbYagThermoCouple.bError, bUnderrange, bOverrange, and iRaw should be linked to the corresponding thermocouple terminal inputs. *) 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: ST_PositionState; // Settings for the POWERMETER state. stPower: ST_PositionState; // Settings for the YAG1 state. stYag1: ST_PositionState; // Settings for the YAG2 state. stYag2: ST_PositionState; // Set this to a non-unknown value to request a new move. {attribute 'pytmc' := ' pv: MMS:STATE:SET io: io '} eEnumSet: E_PPM_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; // Offset for the flow meter in engineering units fFlowOffset: LREAL := 0; // Responsivity for power meter fResponsivity: LREAL; END_VAR VAR_OUTPUT // The current position state as an enum. {attribute 'pytmc' := ' pv: MMS:STATE:GET io: i '} eEnumGet: E_PPM_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: SPM'} fbPowerMeter: FB_PPM_PowerMeter_IM4K2; {attribute 'pytmc' := 'pv: CAM'} fbGige: FB_PPM_Gige; {attribute 'pytmc' :='pv: FWM'} fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); {attribute 'pytmc' := 'pv: YAG'} fbYagThermoCouple: FB_ThermoCouple; {attribute 'pytmc' := 'pv: FSW'} 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.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; // 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:=stPower, sNameDefault:='POWERMETER', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stYag1, sNameDefault:='YAG1', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stYag2, sNameDefault:='YAG2', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); END_IF stYStage.bHardwareEnable := TRUE; stYStage.bPowerSelf := FALSE; 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_PPM_States.OUT] := stOut; astPositionState[E_PPM_States.POWERMETER] := stPower; astPositionState[E_PPM_States.YAG1] := stYag1; astPositionState[E_PPM_States.YAG2] := stYag2; 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_PPM_States.OUT]; stPower := astPositionState[E_PPM_States.POWERMETER]; stYag1 := astPositionState[E_PPM_States.YAG1]; stYag2 := astPositionState[E_PPM_States.YAG2]; fbPowerMeter( fTempSP:=fbStates.stDbStateParams.stReactiveParams.nTempSP, bVetoTempFFO:=eEnumGet = E_PPM_States.OUT, sDeviceName:=sDeviceName, fbFFHWO:=fbFFHWO, eEnumGet:=eEnumGet, stYAxisState:=stYStage.Axis.NcToPlc.AxisState, fResponsivity:=fResponsivity, ); fbGige(); fbFlowMeter(fOffset:=fFlowOffset); fbYagThermoCouple(); fbFlowSwitch(); END_FUNCTION_BLOCK Related: * `FB_PPM_PowerMeter_IM4K2`_ FB_PPM_PowerMeter_IM4K2 ^^^^^^^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_PPM_PowerMeter_IM4K2 VAR_INPUT fTempSP: REAL; bVetoTempFFO: BOOL; sDeviceName: STRING; // Used to know when to stop background auto-collection eEnumGet: E_PPM_States; stYAxisState: DWORD; // Calibrated for each gentec, should be passed as input // If not set, responsive energy will not be calculated {attribute 'pytmc' := ' pv: RESP io: i field: EGU V/W '} fResponsivity: LREAL; END_VAR VAR_IN_OUT fbFFHWO: FB_HardwareFFOutput; END_VAR VAR iVoltageDINT AT %I*: DINT; {attribute 'pytmc' := ' pv: VOLT io: input field: EGU mV '} fVoltage: LREAL; {attribute 'pytmc' := ' pv: VOLT_BUFFER io: input field: EGU mV '} fVoltageBuffer: ARRAY[1..1000] OF LREAL; {attribute 'pytmc' := ' pv: io: input '} fbThermoCouple: FB_ThermoCouple; fFrequency: REAL; // Used to get beam rate {attribute 'pytmc' := ' pv: SXR_NC_BeamRateFromEpics link: EVNT:SYS0:1:NC_SOFTRATE '} fSXR_NC_Frequency: REAL; {attribute 'pytmc' := ' pv: SXR_SC_BeamRateFromEpics link: TPG:SYS0:1:DST04:RATE '} uSXR_SC_Frequency: UINT; {attribute 'pytmc' := ' pv: HXR_NC_BeamRateFromEpics link: EVNT:SYS0:1:NC_HARDRATE '} fHXR_NC_Frequency: REAL; {attribute 'pytmc' := ' pv: HXR_SC_BeamRateFromEpics link: TPG:SYS0:1:DST03:RATE '} uHXR_SC_Frequency: UINT; // Pulse-by-pulse energy and buffer {attribute 'pytmc' := ' pv: MJ io: i field: EGU mJ '} fCalibMJ: LREAL; {attribute 'pytmc' := ' pv: MJ_BUFFER io: i field: EGU mJ '} fCalibMJBuffer: ARRAY[1..1000] OF LREAL; // Wattage and buffer {attribute 'pytmc' := ' pv: WATT io: i field: EGU mW '} fPulseWattage: LREAL; {attribute 'pytmc' := ' pv: WATT_BUFFER io: i field: EGU mW '} fPulseWattageBuffer: ARRAY[1..1000] OF LREAL; // Background voltage {attribute 'pytmc' := ' pv: BACK:VOLT io: io field: EGU mV '} fBackgroundVoltage: LREAL; // Internal variables for background voltage auto-collection fBackgroundVoltageAcc: LREAL; uAccCount: UINT; fBackgroundVoltageSum: LREAL; fBackgroundVoltageStale: LREAL; tonBackgroundAutoCollecting: TON; fBackgroundVoltageBuffer: ARRAY[1..100] OF LREAL; udBackgroundVoltageBufferIndex: UDINT := 1; rTrig_Background : R_TRIG; i: UDINT; // Used to reset auto-collected background buffer, and fBackgroundVoltage if in Auto mode {attribute 'pytmc' := ' pv: BACK:RESET io: io '} bResetAutoBackground: BOOL; // In manual mode, auto-background updates buffer but does not change fBackgroundVoltage {attribute 'pytmc' := ' pv: BACK:MODE io: io '} BACKGROUND_MODE: (Manual, Auto) := Auto; // Boolean to trigger collection of background voltages {attribute 'pytmc' := ' pv: BACK:COLL io: io '} bBackgroundCollect: BOOL; // Time in seconds to collect background voltages for {attribute 'pytmc' := ' pv: BACK:TIME io: io field: EGU s '} uBackgroundCollectionTime: UINT := 60; tofBackgroundCollecting: TOF; udBackgroundManualCount: UDINT; // Boolean indicating when background is being manually collected {attribute 'pytmc' := ' pv: BACK:MANUAL_COLLECTING io: i '} bBackgroundCollecting: BOOL := FALSE; fbGetPMVoltage: FB_AnalogInput_IM4K2; fbVoltageBuffer: FB_LREALBuffer; fbPulseWattageBuffer: FB_LREALBuffer; fbCalibMJBuffer: FB_LREALBuffer; FF: FB_FastFault :=( i_Desc := 'Fault occurs when the per-pulse energy reading is high enough to damage the power meter', i_TypeCode := 16#500); bOverAllowableEnergy: BOOL; uOverCounter: UINT := 1; END_VAR VAR_STAT CONSTANT // Voltage limits for wavelength ranges uSoftWavelengthEdge1: UINT := 300; uSoftWavelengthEdge1L: UINT := 299; uSoftWavelengthEdge2: UINT := 1000; uSoftWavelengthEdge2L: UINT := 999; uSoftWavelengthEdge3: UINT := 1560; uSoftWavelengthEdge3L: UINT := 1559; uSoftWavelengthEdge4: UINT := 2000; uSoftWavelengthEdge4L: UINT := 1999; uHardWavelengthEdge1: UINT := 1000; uHardWavelengthEdge2: UINT := 1500; uHardWavelengthEdge2L: UINT := 1499; uHardWavelengthEdge3: UINT := 4000; uHardWavelengthEdge3L: UINT := 3999; END_VAR fbThermoCouple(); // Convert the terminal's integer into a value in millivolts fbGetPMVoltage( iRaw := iVoltageDINT, iTermBits := 31, fTermMax := 0.2, fTermMin := -0.2, fOffset := 0, // Add Offset based on fResolution (2mV in this case). fResolution := 1000, // Display the output in mV fReal => fVoltage); rTrig_Background(CLK:=(eEnumGet <> E_PPM_States.OUT OR stYAxisState <> 0)); // Reset buffer and related variables IF rTrig_Background.Q OR bResetAutoBackground THEN IF bResetAutoBackground THEN bResetAutoBackground := FALSE; IF BACKGROUND_MODE = Auto THEN fBackgroundVoltage := 0; END_IF ELSE // Dump 5s worth of readings IF udBackgroundVoltageBufferIndex > 6 THEN FOR i := (udBackgroundVoltageBufferIndex - 5) TO (udBackgroundVoltageBufferIndex - 1) DO fBackgroundVoltageSum := fBackgroundVoltageSum - fBackgroundVoltageBuffer[((i-1) MOD 100) + 1]; END_FOR udBackgroundVoltageBufferIndex := udBackgroundVoltageBufferIndex - 5; IF udBackgroundVoltageBufferIndex <> 1 AND BACKGROUND_MODE = Auto THEN fBackgroundVoltage := fBackgroundVoltageSum / MIN((udBackgroundVoltageBufferIndex - 1), 100); END_IF ELSIF BACKGROUND_MODE = Auto THEN fBackgroundVoltage := 0; END_IF END_IF fBackgroundVoltageAcc := 0; fBackgroundVoltageSum := 0; tonBackgroundAutoCollecting(IN := FALSE); udBackgroundVoltageBufferIndex := 1; ELSIF eEnumGet = E_PPM_States.OUT AND stYAxisState = 0 THEN tonBackgroundAutoCollecting( IN := TRUE, PT := T#1000MS); // Every second, move fBackgroundVoltageAcc into buffer and sum IF tonBackgroundAutoCollecting.Q = TRUE THEN tonBackgroundAutoCollecting( IN := FALSE); fBackgroundVoltageStale := fBackgroundVoltageBuffer[((udBackgroundVoltageBufferIndex - 1) MOD 100) + 1]; fBackgroundVoltageBuffer[((udBackgroundVoltageBufferIndex - 1) MOD 100) + 1] := fBackgroundVoltageAcc / uAccCount; // Remove overwritten voltage IF udBackgroundVoltageBufferIndex > 100 THEN fBackgroundVoltageSum := fBackgroundVoltageSum - fBackgroundVoltageStale; END_IF fBackgroundVoltageSum := fBackgroundVoltageSum + fBackgroundVoltageAcc / uAccCount; fBackgroundVoltageAcc := fVoltage; uAccCount := 1; udBackgroundVoltageBufferIndex := udBackgroundVoltageBufferIndex + 1; ELSE uAccCount := uAccCount + 1; fBackgroundVoltageAcc := fBackgroundVoltageAcc + fVoltage; END_IF END_IF IF udBackgroundVoltageBufferIndex <> 1 AND BACKGROUND_MODE = Auto THEN fBackgroundVoltage := fBackgroundVoltageSum / MIN((udBackgroundVoltageBufferIndex - 1), 100); END_IF // Start collecting background in manual mode - 60s by default but can be set with uBackgroundCollectionTime IF bBackgroundCollect = TRUE AND BACKGROUND_MODE = Manual THEN bBackgroundCollect := FALSE; udBackgroundManualCount := 0; fBackgroundVoltage := 0; tofBackgroundCollecting(IN := TRUE); END_IF bBackgroundCollecting := FALSE; tofBackgroundCollecting(IN := FALSE, PT := UINT_TO_TIME(uBackgroundCollectionTime * 1000)); IF tofBackgroundCollecting.Q = TRUE THEN IF BACKGROUND_MODE = Manual THEN bBackgroundCollecting := TRUE; udBackgroundManualCount := udBackgroundManualCount + 1; fBackgroundVoltage := (fBackgroundVoltage * (udBackgroundManualCount - 1) + fVoltage) / udBackgroundManualCount; END_IF END_IF // Getting frequency based on accelerator source {IF defined (K)} IF PMPS_GVL.stCurrentBeamParameters.nMachineMode = 0 THEN fFrequency := fSXR_NC_Frequency; ELSIF PMPS_GVL.stCurrentBeamParameters.nMachineMode = 1 THEN fFrequency := uSXR_SC_Frequency; END_IF {ELSIF defined (L)} IF PMPS_GVL.stCurrentBeamParameters.nMachineMode = 0 THEN fFrequency := fHXR_NC_Frequency; ELSIF PMPS_GVL.stCurrentBeamParameters.nMachineMode = 1 THEN fFrequency := uHXR_SC_Frequency; END_IF {END_IF} // Getting wattage and energy fPulseWattage := SEL(fResponsivity <> 0, 0, (fVoltage - fBackgroundVoltage) / fResponsivity); fCalibMJ := SEL(fFrequency <> 0, -9999, fPulseWattage / fFrequency); // FF in case voltage is high enough to damage power meter based on wavelengths {IF defined (K)} CASE REAL_TO_UINT(PMPS_GVL.stCurrentBeamParameters.neV) OF 0 .. uSoftWavelengthEdge1L: bOverAllowableEnergy := fCalibMJ > 2; uSoftWavelengthEdge1 .. uSoftWavelengthEdge2L : bOverAllowableEnergy := fCalibMJ > 2; uSoftWavelengthEdge2 .. uSoftWavelengthEdge3L: bOverAllowableEnergy := fCalibMJ > 4; uSoftWavelengthEdge3 .. uSoftWavelengthEdge4L: bOverAllowableEnergy := fCalibMJ > 0.5; uSoftWavelengthEdge4 .. 65535: bOverAllowableEnergy := fCalibMJ > 1; END_CASE {ELSIF defined (L)} CASE REAL_TO_UINT(PMPS_GVL.stCurrentBeamParameters.neV) OF uHardWavelengthEdge1 .. uHardWavelengthEdge2L: bOverAllowableEnergy := fCalibMJ > 10; uHardWavelengthEdge2 .. uHardWavelengthEdge3L: bOverAllowableEnergy := fCalibMJ > 4; uHardWavelengthEdge3 .. 65535: bOverAllowableEnergy := fCalibMJ > 10; END_CASE {END_IF} IF eEnumGet = E_PPM_States.POWERMETER AND bOverAllowableEnergy THEN uOverCounter := MIN(uOverCounter + 1, 10); ELSE uOverCounter := 0; END_IF FF(i_xOK := eEnumGet <> E_PPM_States.POWERMETER OR uOverCounter < 10, i_DevName := sDeviceName, io_fbFFHWO := fbFFHWO); // Buffer the full-rate Voltage, Pulse wattage, and calibrated MJ values fbVoltageBuffer( bExecute := TRUE, fInput := fVoltage, arrOutput => fVoltageBuffer); fbPulseWattageBuffer( bExecute := TRUE, fInput := fPulseWattage, arrOutput => fPulseWattageBuffer); fbCalibMJBuffer( bExecute := TRUE, fInput := fCalibMJ, arrOutput => fCalibMJBuffer); END_FUNCTION_BLOCK Related: * `FB_AnalogInput_IM4K2`_ FB_TM1K2 ^^^^^^^^ :: FUNCTION_BLOCK FB_TM1K2 (* Function block for Arrival Time Monitor (ATM) controls: - X, Y motion - Y target states - thermocouple For TM1K2, we make the following adjustments: - Add stTarget6 to the inputs - Change the array pragma from 1..6 to 1..7 (1 out and 6 in states, up from 5 in states) - Use E_TM1K2_States instead of E_ATM_States Add array to 1..9 *) VAR_IN_OUT // Y motor (state select). stYStage: ST_MotionStage; // X motor (align target to beam). stXStage: 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: ST_PositionState; // Settings for the TARGET1 state. stTarget1: ST_PositionState; // Settings for the TARGET2 state. stTarget2: ST_PositionState; // Settings for the TARGET3 state. stTarget3: ST_PositionState; // Settings for the TARGET4 state. stTarget4: ST_PositionState; // Settings for the TARGET5 state. stTarget5: ST_PositionState; // Settings for the TARGET6 state. stTarget6: ST_PositionState; // Settings for the TARGET7 state. stTarget7: ST_PositionState; // Settings for the TARGET8 state. stTarget8: ST_PositionState; // Set this to a non-unknown value to request a new move. {attribute 'pytmc' := ' pv: MMS:STATE:SET io: io '} eEnumSet: E_TM1K2_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_TM1K2_States; // The PMPS database lookup associated with the current position state. stDbStateParams: ST_DbStateParams; END_VAR VAR bInit: BOOL; fbYStage: FB_MotionStage; fbXStage: FB_MotionStage; fbStateDefaults: FB_PositionState_Defaults; {attribute 'pytmc' := ' pv: MMS astPositionState.array: 1..7 '} fbStates: FB_PositionStatePMPS1D; astPositionState: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; fbArrCheckWrite: FB_CheckPositionStateWrite; {attribute 'pytmc' := 'pv: STC:01'} fbThermoCouple1: FB_TempSensor; {attribute 'pytmc' :='pv: FWM'} fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); 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.nEnableMode := E_StageEnableMode.DURING_MOTION; stXStage.nEnableMode := E_StageEnableMode.DURING_MOTION; // 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:=stTarget1, sNameDefault:='TARGET1', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget2, sNameDefault:='TARGET2', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget3, sNameDefault:='TARGET3', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget4, sNameDefault:='TARGET4', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget5, sNameDefault:='TARGET5', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget6, sNameDefault:='TARGET6', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget7, sNameDefault:='TARGET7', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget8, sNameDefault:='TARGET8', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); END_IF stYStage.bHardwareEnable := TRUE; stYStage.bPowerSelf := FALSE; stXStage.bLimitForwardEnable := TRUE; stXStage.bLimitBackwardEnable := TRUE; stXStage.bHardwareEnable := TRUE; stXStage.bPowerSelf := TRUE; fbYStage(stMotionStage:=stYStage); fbXStage(stMotionStage:=stXStage); // 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_TM1K2_States.OUT] := stOut; astPositionState[E_TM1K2_States.TARGET1] := stTarget1; astPositionState[E_TM1K2_States.TARGET2] := stTarget2; astPositionState[E_TM1K2_States.TARGET3] := stTarget3; astPositionState[E_TM1K2_States.TARGET4] := stTarget4; astPositionState[E_TM1K2_States.TARGET5] := stTarget5; astPositionState[E_TM1K2_States.TARGET6] := stTarget6; astPositionState[E_TM1K2_States.TARGET7] := stTarget7; astPositionState[E_TM1K2_States.TARGET8] := stTarget8; 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_TM1K2_States.OUT]; stTarget1 := astPositionState[E_TM1K2_States.TARGET1]; stTarget2 := astPositionState[E_TM1K2_States.TARGET2]; stTarget3 := astPositionState[E_TM1K2_States.TARGET3]; stTarget4 := astPositionState[E_TM1K2_States.TARGET4]; stTarget5 := astPositionState[E_TM1K2_States.TARGET5]; stTarget6 := astPositionState[E_TM1K2_States.TARGET6]; stTarget7 := astPositionState[E_TM1K2_States.TARGET7]; stTarget8 := astPositionState[E_TM1K2_States.TARGET8]; fbThermoCouple1(); fbFlowMeter(); END_FUNCTION_BLOCK Related: * `E_TM1K2_States`_ FB_TM2K2 ^^^^^^^^ :: FUNCTION_BLOCK FB_TM2K2 (* Function block for Arrival Time Monitor (ATM) controls: - X, Y motion - Y target states - thermocouple For TM2K2, we make the following adjustments: - Add stTarget6 to the inputs - Change the array pragma from 1..6 to 1..7 (1 out and 6 in states, up from 5 in states) - Use E_TM2K2_States instead of E_ATM_States *) VAR_IN_OUT // Y motor (state select). stYStage: ST_MotionStage; // X motor (align target to beam). stXStage: 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: ST_PositionState; // Settings for the TARGET1 state. stTarget1: ST_PositionState; // Settings for the TARGET2 state. stTarget2: ST_PositionState; // Settings for the TARGET3 state. stTarget3: ST_PositionState; // Settings for the TARGET4 state. stTarget4: ST_PositionState; // Settings for the TARGET5 state. stTarget5: ST_PositionState; // Settings for the TARGET6 state. stTarget6: ST_PositionState; // Set this to a non-unknown value to request a new move. {attribute 'pytmc' := ' pv: MMS:STATE:SET io: io '} eEnumSet: E_TM2K2_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_TM2K2_States; // The PMPS database lookup associated with the current position state. stDbStateParams: ST_DbStateParams; END_VAR VAR bInit: BOOL; fbYStage: FB_MotionStage; fbXStage: FB_MotionStage; fbStateDefaults: FB_PositionState_Defaults; {attribute 'pytmc' := ' pv: MMS astPositionState.array: 1..7 '} fbStates: FB_PositionStatePMPS1D; astPositionState: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; fbArrCheckWrite: FB_CheckPositionStateWrite; {attribute 'pytmc' := 'pv: STC:01'} fbThermoCouple1: FB_TempSensor; {attribute 'pytmc' :='pv: FWM'} fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); 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.nEnableMode := E_StageEnableMode.DURING_MOTION; stXStage.nEnableMode := E_StageEnableMode.DURING_MOTION; // 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:=stTarget1, sNameDefault:='TARGET1', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget2, sNameDefault:='TARGET2', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget3, sNameDefault:='TARGET3', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget4, sNameDefault:='TARGET4', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget5, sNameDefault:='TARGET5', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); fbStateDefaults(stPositionState:=stTarget6, sNameDefault:='TARGET6', fDeltaDefault:=fDelta, fAccelDefault:=fAccel, fDecelDefault:=fAccel); END_IF stYStage.bHardwareEnable := TRUE; stYStage.bPowerSelf := FALSE; stXStage.bLimitForwardEnable := TRUE; stXStage.bLimitBackwardEnable := TRUE; stXStage.bHardwareEnable := TRUE; stXStage.bPowerSelf := TRUE; fbYStage(stMotionStage:=stYStage); fbXStage(stMotionStage:=stXStage); // 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_TM2K2_States.OUT] := stOut; astPositionState[E_TM2K2_States.TARGET1] := stTarget1; astPositionState[E_TM2K2_States.TARGET2] := stTarget2; astPositionState[E_TM2K2_States.TARGET3] := stTarget3; astPositionState[E_TM2K2_States.TARGET4] := stTarget4; astPositionState[E_TM2K2_States.TARGET5] := stTarget5; astPositionState[E_TM2K2_States.TARGET6] := stTarget6; 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_TM2K2_States.OUT]; stTarget1 := astPositionState[E_TM2K2_States.TARGET1]; stTarget2 := astPositionState[E_TM2K2_States.TARGET2]; stTarget3 := astPositionState[E_TM2K2_States.TARGET3]; stTarget4 := astPositionState[E_TM2K2_States.TARGET4]; stTarget5 := astPositionState[E_TM2K2_States.TARGET5]; stTarget6 := astPositionState[E_TM2K2_States.TARGET6]; fbThermoCouple1(); fbFlowMeter(); END_FUNCTION_BLOCK Related: * `E_TM2K2_States`_ PRG_1_PlcTask ^^^^^^^^^^^^^ :: PROGRAM PRG_1_PlcTask VAR bDebug: BOOL := FALSE; END_VAR PRG_2_PMPS_PRE(); // Temporarily disable motors by setting bHardwareEnable to FALSE prior to running motion FB //Main.M5.bHardwareEnable := bDebug; //Main.M6.bHardwareEnable := bDebug; //Main.M7.bHardwareEnable := bDebug; //Main.M8.bHardwareEnable := bDebug; //Main.M9.bHardwareEnable := bDebug; //Main.M10.bHardwareEnable := bDebug; //Main.M11.bHardwareEnable := bDebug; //Main.M12.bHardwareEnable := bDebug; //Main.M13.bHardwareEnable := bDebug; //Main.M14.bHardwareEnable := bDebug; //Main.M15.bHardwareEnable := bDebug; //Main.M16.bHardwareEnable := bDebug; // Note: AT2K2 has its own built-in debugging interface; see PRG_AT2K2_SOLID // and its ``bDebug`` variable. PRG_IM1K1_PPM(); PRG_IM2K1_PPM(); PRG_IM1K2_PPM(); PRG_AL1K2_L2SI(); PRG_IM2K2_PPM(); PRG_IM3K2_PPM(); PRG_IM4K2_PPM(); PRG_TM1K2_ATM(); PRG_LI2K2_K2A(); PRG_PF1K2_WFS(); PRG_IM5K2_PPM(); PRG_TM2K2_ATM(); PRG_AT1K2_SOLID(); PRG_AT2K2_SOLID(); PRG_LI3K2_K2B(); PRG_PF2K2_WFS(); PRG_IM6K2_PPM(); PRG_SP1K2_PAX(); PRG_3_PMPS_POST(); PRG_4_LOG(); END_PROGRAM Related: * `Main`_ * `PRG_2_PMPS_PRE`_ * `PRG_3_PMPS_POST`_ * `PRG_4_LOG`_ * `PRG_AL1K2_L2SI`_ * `PRG_AT1K2_SOLID`_ * `PRG_AT2K2_SOLID`_ * `PRG_IM1K1_PPM`_ * `PRG_IM1K2_PPM`_ * `PRG_IM2K1_PPM`_ * `PRG_IM2K2_PPM`_ * `PRG_IM3K2_PPM`_ * `PRG_IM4K2_PPM`_ * `PRG_IM5K2_PPM`_ * `PRG_IM6K2_PPM`_ * `PRG_LI2K2_K2A`_ * `PRG_LI3K2_K2B`_ * `PRG_PF1K2_WFS`_ * `PRG_PF2K2_WFS`_ * `PRG_SP1K2_PAX`_ * `PRG_TM1K2_ATM`_ * `PRG_TM2K2_ATM`_ PRG_2_PMPS_PRE ^^^^^^^^^^^^^^ :: PROGRAM PRG_2_PMPS_PRE VAR END_VAR END_PROGRAM PRG_3_PMPS_POST ^^^^^^^^^^^^^^^ :: PROGRAM PRG_3_PMPS_POST VAR fbArbiterIO: FB_SubSysToArbiter_IO; bMR1K1_Veto: BOOL; bST1K2_Veto: BOOL; bST1K2_Veto_Override: BOOL := FALSE; fb_vetoArbiter: FB_VetoArbiter; ff2_ff1_link_motion: FB_FastFault := (i_xAutoReset := TRUE, i_DevName := 'FF2 to FF1 Link Motion', i_Desc := 'Please DONT BYPASS ME!! This is virtual FF2 fault, Please check faulting motion devices', i_TypeCode := 16#FFFF); END_VAR bMR1K1_Veto := PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN]; bST1K2_Veto := bST1K2_Veto_Override OR PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2]; fbArbiterIO( i_bVeto:=bMR1K1_Veto, Arbiter:=GVL.fbArbiter1, fbFFHWO:=GVL.fbFastFaultOutput1); GVL.fbFastFaultOutput1.Execute(i_xVeto:=bMR1K1_Veto); GVL.fbFastFaultOutput2.Execute(i_xVeto:=bMR1K1_Veto OR bST1K2_Veto); //create a preemptive request from Arbiter 2 in Arbiter 1 fb_vetoArbiter(bVeto:= bST1K2_Veto, HigherAuthority := GVL.fbArbiter1, LowerAuthority := GVL.fbArbiter2, FFO := GVL.fbFastFaultOutput2); ff2_ff1_link_motion( io_fbFFHWO := GVL.fbFastFaultOutput1, i_xOK := GVL.fbFastFaultOutput2.q_xFastFaultOut OR bST1K2_Veto); MOTION_GVL.fbStandardPMPSDB( io_fbFFHWO:=GVL.fbFastFaultOutput1, bEnable:=TRUE, sPLCName:='plc-kfe-rix-motion', ); END_PROGRAM Related: * `GVL`_ PRG_4_LOG ^^^^^^^^^ :: PROGRAM PRG_4_LOG VAR fbLogHandler: FB_LogHandler; END_VAR fbLogHandler(); END_PROGRAM PRG_AL1K2_L2SI ^^^^^^^^^^^^^^ :: PROGRAM PRG_AL1K2_L2SI VAR {attribute 'pytmc' := 'pv: AL1K2:L2SI'} {attribute 'TcLinkTo' := '.fbLaser.iLaserINT := TIIB[AL1K2-EL4004-E4]^AO Outputs Channel 1^Analog output; .fbLaser.iShutdownINT := TIIB[AL1K2-EL4004-E4]^AO Outputs Channel 2^Analog output'} fbAL1K2: FB_REF; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 10, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbAL1K2.stOut, fPosition:=-33.5, sPmpsState:='AL1K2:L2SI-OUT'); fbStateSetup(stPositionState:=fbAL1K2.stIn, fPosition:=-75, sPmpsState:='AL1K2:L2SI-IN'); fbAL1K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M5, sDeviceName := 'AL1K2:L2SI', sTransitionKey := 'AL1K2:L2SI-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_AT1K2_SOLID ^^^^^^^^^^^^^^^ :: PROGRAM PRG_AT1K2_SOLID VAR (* NOTE: use FALSE for simulation and production *) (* NOTE: use TRUE when relying on visualization + actual hardware *) bDebug : BOOL := FALSE; nEnableMode : E_StageEnableMode; {attribute 'pytmc' := ' pv: AT1K2:L2SI:MMS:01 '} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K2-EL3202-01]^RTD Inputs Channel 2^Status^Overrange '} fbStage1: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT1K2:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT1K2-EL3202-02]^RTD Inputs Channel 2^Status^Overrange '} fbStage2: FB_SXR_SATT_Stage; // Special case: inspection mirror {attribute 'pytmc' := 'pv: AT1K2:L2SI:MMS:03'} fbStage3: FB_PositionState1D_InOut; bStage3Init: BOOL; fbMotionStage3: FB_MotionStage; stMirrorOut: ST_PositionState; stMirrorIn: ST_PositionState; // Consider transmission=1 if out, transmission=0 if in fMirrorTrans: LREAL; // Fault unless the mirror is out fbFFMirror: FB_FastFault := ( i_Desc := 'Mirror is not out', i_TypeCode := E_MotionFFType.DEVICE_MOVE, i_xAutoReset := TRUE ); fbStateSetup: FB_StateSetupHelper; stDefaultGood: ST_PositionState := ( fDelta := 0.2, fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); fbBadStateSetup: FB_StateSetupHelper; stDefaultBad: ST_PositionState := ( fPosition := 500, fDelta := 0.2, fVelocity := 1, bMoveOk := FALSE, bValid := FALSE ); {attribute 'pytmc' :='pv: AT1K2:L2SI:FWM'} {attribute 'TcLinkTo' := '.iRaw := TIIB[AT1K2-EL3052-E8]^AI Standard Channel 1^Value'} fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); END_VAR IF bDebug THEN // NEVER: checkouts with the TwinCAT NC GUI. nEnableMode := E_StageEnableMode.NEVER; ELSE // ALWAYS: want active position correction at all times nEnableMode := E_StageEnableMode.ALWAYS; END_IF (* Solid Attenuator notes AT1K2 is JJ-xray SN-11343. JJ Label EPICS Stage NC Location 10XX 1 MMS:01 fbStage1 M25 Upstream-most 10XX 2 MMS:02 fbStage2 M26 Downstream-most 10XX 3 MMS:03 fbStage3 M27 Mirror Insertion Stage *) fbStateSetup(stPositionState:=stDefaultGood, bSetDefault:=TRUE); fbBadStateSetup(stPositionState:=stDefaultBad, bSetDefault:=TRUE); (* State setup - stage 1 *) fbStateSetup(stPositionState:=fbStage1.stOut, sName:='Out', fPosition:=22.00); fbBadStateSetup(stPositionState:=fbStage1.stFilter1, sName:='Filter 1',sPmpsState:='AT1K2:L2SI-RTD'); fbStage1.arrFilters[1].fFilterThickness_um := 0; fbStage1.arrFilters[1].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage1.stFilter2, sName:='Filter 2'); fbStage1.arrFilters[2].fFilterThickness_um := 0; fbStage1.arrFilters[2].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage1.stFilter3, sName:='(3) 11.5 um Al', fPosition:=75.0); fbStage1.arrFilters[3].fFilterThickness_um := 11.5; fbStage1.arrFilters[3].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter4, sName:='(4) 6.18 um Al', fPosition:=90.5); fbStage1.arrFilters[4].fFilterThickness_um := 6.18; fbStage1.arrFilters[4].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter5, sName:='(5) 2.85 um Al', fPosition:=105.5); fbStage1.arrFilters[5].fFilterThickness_um := 2.85; fbStage1.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter6, sName:='(6) 1.52 um Al', fPosition:=122.0); fbStage1.arrFilters[6].fFilterThickness_um := 1.52; fbStage1.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter7, sName:='(7) 0.78 um Al', fPosition:=136.5); fbStage1.arrFilters[7].fFilterThickness_um := 0.78; fbStage1.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter8, sName:='(8) 0.39 um Al', fPosition:=152.2); fbStage1.arrFilters[8].fFilterThickness_um := 0.39; fbStage1.arrFilters[8].sFilterMaterial := 'Al'; fbStage1 (stAxis:=Main.M25,sDeviceName:='AT1K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 2 *) fbStateSetup(stPositionState:=fbStage2.stOut, sName:='Out', fPosition:=22.00); fbBadStateSetup(stPositionState:=fbStage2.stFilter1, sName:='Filter 1',sPmpsState:='AT1K2:L2SI-RTD'); 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 := ''; fbStateSetup(stPositionState:=fbStage2.stFilter3, sName:='(3) 11.5 um Al', fPosition:=75.0); fbStage2.arrFilters[3].fFilterThickness_um := 11.5; fbStage2.arrFilters[3].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter4, sName:='(4) 6.18 um Al', fPosition:=90.5); fbStage2.arrFilters[4].fFilterThickness_um := 6.18; fbStage2.arrFilters[4].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter5, sName:='(5) 1.52 um Al', fPosition:=105.5); fbStage2.arrFilters[5].fFilterThickness_um := 1.52; fbStage2.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter6, sName:='(6) 0.78 um Al', fPosition:=122.0); fbStage2.arrFilters[6].fFilterThickness_um := 0.78; fbStage2.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter7, sName:='(7) 0.39 um Al', fPosition:=136.5); fbStage2.arrFilters[7].fFilterThickness_um := 0.39; fbStage2.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter8, sName:='(8) 0.2 um Al', fPosition:=152.2); fbStage2.arrFilters[8].fFilterThickness_um := 0.2; fbStage2.arrFilters[8].sFilterMaterial := 'Al'; fbStage2(stAxis:=Main.M26,sDeviceName:='AT1K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 3 *) fbStateSetup(stPositionState:=stMirrorOut, sName:='Out', fPosition:=65.00); fbStateSetup(stPositionState:=stMirrorIn, sName:='In', fPosition:=25.00); IF NOT bStage3Init THEN bStage3Init := TRUE; Main.M27.bHardwareEnable := TRUE; Main.M27.bLimitBackwardEnable := TRUE; Main.M27.bLimitForwardEnable := TRUE; Main.M27.bPowerSelf := TRUE; Main.M27.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M27.nHomingMode := ENUM_EpicsHomeCmd.NONE; END_IF fbStage3( stMotionStage:=Main.M27, stOut:=stMirrorOut, stIn:=stMirrorIn, ); fbMotionStage3(stMotionStage:=Main.M27); IF fbStage3.eStateGet = E_EpicsInOut.OUT THEN fMirrorTrans := 1.0; ELSE fMirrorTrans := 0.0; END_IF fbFFMirror( i_DevName := Main.M27.sName, i_xOK := fbStage3.eStateGet = E_EpicsInOut.OUT, io_fbFFHWO := GVL.fbFastFaultOutput2, ); GVL.rCurTrans[PMPS.K_Attenuators.AT1K2].nTran := LREAL_TO_REAL( fbStage1.fTransmission * fbStage2.fTransmission * fMirrorTrans ); fbFlowMeter(); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_AT2K2_SOLID ^^^^^^^^^^^^^^^ :: PROGRAM PRG_AT2K2_SOLID VAR (* NOTE: use FALSE for simulation and production *) (* NOTE: use TRUE when relying on visualization + actual hardware *) bDebug : BOOL := FALSE; nEnableMode : E_StageEnableMode; {attribute 'pytmc' := ' pv: AT2K2:L2SI:MMS:01 '} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT2K2-EL3202-04]^RTD Inputs Channel 2^Status^Overrange '} fbStage1: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:02'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT2K2-EL3202-03]^RTD Inputs Channel 2^Status^Overrange '} fbStage2: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:03'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT2K2-EL3202-02]^RTD Inputs Channel 2^Status^Overrange '} fbStage3: FB_SXR_SATT_Stage; {attribute 'pytmc' := 'pv: AT2K2:L2SI:MMS:04'} {attribute 'TcLinkTo' := ' .fbRTD_1.iRaw := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 1^Value; .fbRTD_1.bError := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 1^Status^Error; .fbRTD_1.bUnderrange := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 1^Status^Underrange; .fbRTD_1.bOverrange := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 1^Status^Overrange; .fbRTD_2.iRaw := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 2^Value; .fbRTD_2.bError := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 2^Status^Error; .fbRTD_2.bUnderrange := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 2^Status^Underrange; .fbRTD_2.bOverrange := TIIB[AT2K2-EL3202-01]^RTD Inputs Channel 2^Status^Overrange '} fbStage4: FB_SXR_SATT_Stage; fbStateSetup: FB_StateSetupHelper; stDefaultGood: ST_PositionState := ( fDelta := 0.2, fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); fbBadStateSetup: FB_StateSetupHelper; stDefaultBad: ST_PositionState := ( fPosition := 500, fDelta := 0.2, fVelocity := 1, bMoveOk := FALSE, bValid := FALSE ); {attribute 'pytmc' :='pv: AT2K2:L2SI:FWM'} {attribute 'TcLinkTo' := '.iRaw := TIIB[TM2K2-EL3052-E6]^AI Standard Channel 1^Value'} // AT2K2 shares flow meter with TM2K2 fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); END_VAR IF bDebug THEN // NEVER: checkouts with the TwinCAT NC GUI. nEnableMode := E_StageEnableMode.NEVER; ELSE // ALWAYS: want active position correction at all times nEnableMode := E_StageEnableMode.ALWAYS; END_IF (* Solid Attenuator notes AT2K2 is JJ-xray SN-11343. JJ Label EPICS Stage NC Location 1087 1 MMS:01 fbStage1 M17 Upstream-most 1088 2 MMS:02 fbStage2 M18 1086 3 MMS:03 fbStage3 M19 1089 4 MMS:04 fbStage4 M20 Downstream-most *) fbStateSetup(stPositionState:=stDefaultGood, bSetDefault:=TRUE); fbBadStateSetup(stPositionState:=stDefaultBad, bSetDefault:=TRUE); (* State setup - stage 1 *) fbStateSetup(stPositionState:=fbStage1.stOut, sName:='Out', fPosition:=27.00); fbBadStateSetup(stPositionState:=fbStage1.stFilter1, sName:='Filter 1',sPmpsState:='AT2K2:L2SI-RTD'); fbStage1.arrFilters[1].fFilterThickness_um := 0; fbStage1.arrFilters[1].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage1.stFilter2, sName:='Filter 2'); fbStage1.arrFilters[2].fFilterThickness_um := 0; fbStage1.arrFilters[2].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage1.stFilter3, sName:='Filter 3'); fbStage1.arrFilters[3].fFilterThickness_um := 0; fbStage1.arrFilters[3].sFilterMaterial := ''; fbBadStateSetup(stPositionState:=fbStage1.stFilter4, sName:='Filter 4'); fbStage1.arrFilters[4].fFilterThickness_um := 0; fbStage1.arrFilters[4].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage1.stFilter5, sName:='(5) 11.5 um Al', fPosition:=103.0); fbStage1.arrFilters[5].fFilterThickness_um := 11.5; fbStage1.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter6, sName:='(6) 6.18 um Al', fPosition:=119.0); fbStage1.arrFilters[6].fFilterThickness_um := 6.18; fbStage1.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter7, sName:='(7) 2.85 um Al', fPosition:=135.0); fbStage1.arrFilters[7].fFilterThickness_um := 2.85; fbStage1.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage1.stFilter8, sName:='(8) 1.52 um Al', fPosition:=150.0); fbStage1.arrFilters[8].fFilterThickness_um := 1.52; fbStage1.arrFilters[8].sFilterMaterial := 'Al'; fbStage1(stAxis:=Main.M17,sDeviceName:='AT2K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 2 *) fbStateSetup(stPositionState:=fbStage2.stOut, sName:='Out', fPosition:=27.72); fbBadStateSetup(stPositionState:=fbStage2.stFilter1, sName:='Filter 1',sPmpsState:='AT2K2:L2SI-RTD'); 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) 6.18 um Al', fPosition:=103.0); fbStage2.arrFilters[5].fFilterThickness_um := 6.18; fbStage2.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter6, sName:='(6) 2.85 um Al', fPosition:=119.0); fbStage2.arrFilters[6].fFilterThickness_um := 2.85; fbStage2.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter7, sName:='(7) 1.52 um Al', fPosition:=135.0); fbStage2.arrFilters[7].fFilterThickness_um := 1.52; fbStage2.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage2.stFilter8, sName:='(8) 0.78 um Al', fPosition:=150.0); fbStage2.arrFilters[8].fFilterThickness_um := 0.78; fbStage2.arrFilters[8].sFilterMaterial := 'Al'; fbStage2(stAxis:=Main.M18,sDeviceName:='AT2K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 3 *) fbStateSetup(stPositionState:=fbStage3.stOut, sName:='Out', fPosition:=27.00); fbBadStateSetup(stPositionState:=fbStage3.stFilter1, sName:='Filter 1',sPmpsState:='AT2K2:L2SI-RTD'); 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 := ''; fbStateSetup(stPositionState:=fbStage3.stFilter5, sName:='(5) 2.85 um Al', fPosition:=103.0); fbStage3.arrFilters[5].fFilterThickness_um := 2.85; fbStage3.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage3.stFilter6, sName:='(6) 1.52 um Al', fPosition:=119.0); fbStage3.arrFilters[6].fFilterThickness_um := 1.52; fbStage3.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage3.stFilter7, sName:='(7) 0.78 um Al', fPosition:=135.0); fbStage3.arrFilters[7].fFilterThickness_um := 0.78; fbStage3.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage3.stFilter8, sName:='(8) 0.39 um Al', fPosition:=150.0); fbStage3.arrFilters[8].fFilterThickness_um := 0.39; fbStage3.arrFilters[8].sFilterMaterial := 'Al'; fbStage3(stAxis:=Main.M19,sDeviceName:='AT2K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); (* State setup - stage 4 *) fbStateSetup(stPositionState:=fbStage4.stOut, sName:='Out', fPosition:=28.03); fbBadStateSetup(stPositionState:=fbStage4.stFilter1, sName:='Filter 1',sPmpsState:='AT2K2:L2SI-RTD'); 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 := ''; fbBadStateSetup(stPositionState:=fbStage4.stFilter4, sName:='Filter 4'); fbStage4.arrFilters[4].fFilterThickness_um := 0; fbStage4.arrFilters[4].sFilterMaterial := ''; fbStateSetup(stPositionState:=fbStage4.stFilter5, sName:='(5) 1.52 um Al', fPosition:=103.0); fbStage4.arrFilters[5].fFilterThickness_um := 1.52; fbStage4.arrFilters[5].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage4.stFilter6, sName:='(6) 0.78 um Al', fPosition:=119.0); fbStage4.arrFilters[6].fFilterThickness_um := 0.78; fbStage4.arrFilters[6].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage4.stFilter7, sName:='(7) 0.39 um Al', fPosition:=135.0); fbStage4.arrFilters[7].fFilterThickness_um := 0.39; fbStage4.arrFilters[7].sFilterMaterial := 'Al'; fbStateSetup(stPositionState:=fbStage4.stFilter8, sName:='(8) 0.20 um Al', fPosition:=150.0); fbStage4.arrFilters[8].fFilterThickness_um := 0.20; fbStage4.arrFilters[8].sFilterMaterial := 'Al'; fbStage4(stAxis:=Main.M20,sDeviceName:='AT2K2:L2SI', nEnableMode:=nEnableMode, fbFFHWO:=GVL.fbFastFaultOutput2, bEnable:=TRUE); GVL.rCurTrans[PMPS.K_Attenuators.AT2K2].nTran := LREAL_TO_REAL( fbStage1.fTransmission * fbStage2.fTransmission * fbStage3.fTransmission * fbStage4.fTransmission ); fbFlowMeter(); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM1K1_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM1K1_PPM VAR {attribute 'pytmc' := 'pv: IM1K1:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM1K1-EL4004]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM1K1-EL2004]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM1K1-EL3062]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM1K1-EL3314]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM1K1-EL3314]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM1K1-EL3314]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM1K1-EL3314]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM1K1-EL3314]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM1K1-EL3314]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM1K1-EL3314]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM1K1-EL3314]^TC Inputs Channel 2^Value'} fbIM1K1: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 10, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM1K1.stOut, fPosition:=-8.82, sPmpsState:='IM1K1:PPM-OUT'); fbStateSetup(stPositionState:=fbIM1K1.stPower, fPosition:=-47.92, sPmpsState:='IM1K1:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM1K1.stYag1, fPosition:=-71.92, sPmpsState:='IM1K1:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM1K1.stYag2, fPosition:=-97.93, sPmpsState:='IM1K1:PPM-YAG2'); fbIM1K1( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter1, stYStage := Main.M1, sDeviceName := 'IM1K1:PPM', sTransitionKey := 'IM1K1:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0624, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM1K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM1K2_PPM VAR {attribute 'pytmc' := 'pv: IM1K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM1K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM1K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM1K2-EL3062-E6]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM1K2-EL3314-E4]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM1K2-EL3052-E5]^AI Standard Channel 1^Value'} fbIM1K2: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 12, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM1K2.stOut, fPosition:=-9.82, sPmpsState:='IM1K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM1K2.stPower, fPosition:=-48.92, sPmpsState:='IM1K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM1K2.stYag1, fPosition:=-72.92, sPmpsState:='IM1K2:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM1K2.stYag2, fPosition:=-98.93, sPmpsState:='IM1K2:PPM-YAG2'); fbIM1K2( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter1, stYStage := Main.M4, sDeviceName := 'IM1K2:PPM', sTransitionKey := 'IM1K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0513, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM2K1_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM2K1_PPM VAR {attribute 'pytmc' := 'pv: IM2K1:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM2K1-EL4004]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM2K1-EL2004]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM2K1-EL3062]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM2K1-EL3314]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM2K1-EL3314]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM2K1-EL3314]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM2K1-EL3314]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM2K1-EL3314]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM2K1-EL3314]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM2K1-EL3314]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM2K1-EL3314]^TC Inputs Channel 2^Value'} fbIM2K1: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 13, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM2K1.stOut, fPosition:=-9.09, sPmpsState:='IM2K1:PPM-OUT'); fbStateSetup(stPositionState:=fbIM2K1.stPower, fPosition:=-48.19, sPmpsState:='IM2K1:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM2K1.stYag1, fPosition:=-72.19, sPmpsState:='IM2K1:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM2K1.stYag2, fPosition:=-98.2, sPmpsState:='IM2K1:PPM-YAG2'); fbIM2K1( fbFFHWO := GVL.fbFastFaultOutput1, fbArbiter := GVL.fbArbiter1, stYStage := Main.M2, sDeviceName := 'IM2K1:PPM', sTransitionKey := 'IM2K1:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0625, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM2K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM2K2_PPM VAR {attribute 'pytmc' := 'pv: IM2K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM2K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM2K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM2K2-EL3062-E6]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM2K2-EL3314-E4]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM1K2-EL3052-E5]^AI Standard Channel 1^Value'} // IM2K2 shares the same flow meter as IM1K2 fbIM2K2: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 15, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM2K2.stOut, fPosition:=-8.49, sPmpsState:='IM2K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM2K2.stPower, fPosition:=-47.59, sPmpsState:='IM2K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM2K2.stYag1, fPosition:=-71.59, sPmpsState:='IM2K2:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM2K2.stYag2, fPosition:=-97.60, sPmpsState:='IM2K2:PPM-YAG2'); fbIM2K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M6, sDeviceName := 'IM2K2:PPM', sTransitionKey := 'IM2K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0670, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM3K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM3K2_PPM VAR {attribute 'pytmc' := 'pv: IM3K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM3K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM3K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM3K2-EL3062-E6]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM3K2-EL3314-E4]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM1K2-EL3052-E5]^AI Standard Channel 1^Value'} // IM3K2 shares the same flow meter as IM1K2 fbIM3K2: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 14, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM3K2.stOut, fPosition:=-9.61, sPmpsState:='IM3K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM3K2.stPower, fPosition:=-48.71, sPmpsState:='IM3K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM3K2.stYag1, fPosition:=-72.71, sPmpsState:='IM3K2:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM3K2.stYag2, fPosition:=-98.72, sPmpsState:='IM3K2:PPM-YAG2'); fbIM3K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M7, sDeviceName := 'IM3K2:PPM', sTransitionKey := 'IM3K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0503 ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM4K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM4K2_PPM VAR {attribute 'pytmc' := 'pv: IM4K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM4K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM4K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageDINT := TIIB[IM4K2-EL3602-0002-E8]^AI Inputs Channel 1^Value; .fbPowerMeter.fbThermoCouple.bError := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbThermoCouple.bUnderrange := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbThermoCouple.bOverrange := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbThermoCouple.iRaw := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagThermoCouple.bError := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagThermoCouple.bUnderrange := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagThermoCouple.bOverrange := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagThermoCouple.iRaw := TIIB[IM4K2-EL3314-E4]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM1K2-EL3052-E5]^AI Standard Channel 1^Value'} // IM4K2 shares the same flow meter as IM1K2 fbIM4K2: FB_PPM_IM4K2; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 12, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM4K2.stOut, fPosition:=-10.80, sPmpsState:='IM4K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM4K2.stPower, fPosition:=-49.90, sPmpsState:='IM4K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM4K2.stYag1, fPosition:=-73.90, sPmpsState:='IM4K2:PPM-YAG1'); fbStateSetup(stPositionState:=fbIM4K2.stYag2, fPosition:=-99.91, sPmpsState:='IM4K2:PPM-YAG2'); fbIM4K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M8, sDeviceName := 'IM4K2:PPM', sTransitionKey := 'IM4K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0584, ); END_PROGRAM Related: * `FB_PPM_IM4K2`_ * `GVL`_ * `Main`_ PRG_IM5K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM5K2_PPM VAR {attribute 'pytmc' := 'pv: IM5K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM5K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM5K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM5K2-EL3062-E6]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM5K2-EL3314-E4]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM5K2-EL3052-E5]^AI Standard Channel 1^Value'} fbIM5K2: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 12, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM5K2.stOut, fPosition:=-8.92, sPmpsState:='IM5K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM5K2.stPower, fPosition:=-48.02, sPmpsState:='IM5K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM5K2.stYag1, fPosition:=-72.02); fbStateSetup(stPositionState:=fbIM5K2.stYag2, fPosition:=-98.03, sPmpsState:='IM5K2:PPM-YAG2'); CASE GVL.ePF1K2State 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 fbIM5K2.stYag1.stPMPS.sPmpsState := 'IM5K2:PPM-YAG1_WFS_IN'; ELSE // Out, Unknown, or an unexpected state: full pmps fbIM5K2.stYag1.stPMPS.sPmpsState := 'IM5K2:PPM-YAG1'; END_CASE fbIM5K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M14, sDeviceName := 'IM5K2:PPM', sTransitionKey := 'IM5K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0574, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_IM6K2_PPM ^^^^^^^^^^^^^ :: PROGRAM PRG_IM6K2_PPM VAR {attribute 'pytmc' := 'pv: IM6K2:PPM'} {attribute 'TcLinkTo' := '.fbGige.iIlluminatorINT := TIIB[IM6K2-EL4004-E7]^AO Outputs Channel 1^Analog output; .fbGige.bGigePower := TIIB[IM6K2-EL2004-E3]^Channel 2^Output; .fbPowerMeter.iVoltageINT := TIIB[IM6K2-EL3062-E6]^AI Standard Channel 1^Value; .fbPowerMeter.fbTempSensor.bError := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 1^Status^Error; .fbPowerMeter.fbTempSensor.bUnderrange := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 1^Status^Underrange; .fbPowerMeter.fbTempSensor.bOverrange := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 1^Status^Overrange; .fbPowerMeter.fbTempSensor.iRaw := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 1^Value; .fbYagTempSensor.bError := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 2^Status^Error; .fbYagTempSensor.bUnderrange := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 2^Status^Underrange; .fbYagTempSensor.bOverrange := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 2^Status^Overrange; .fbYagTempSensor.iRaw := TIIB[IM6K2-EL3314-E4]^TC Inputs Channel 2^Value'} fbIM6K2: FB_PPM; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 14, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbIM6K2.stOut, fPosition:=-8.61, sPmpsState:='IM6K2:PPM-OUT'); fbStateSetup(stPositionState:=fbIM6K2.stPower, fPosition:=-47.71, sPmpsState:='IM6K2:PPM-POWERMETER'); fbStateSetup(stPositionState:=fbIM6K2.stYag1, fPosition:=-71.71); fbStateSetup(stPositionState:=fbIM6K2.stYag2, fPosition:=-97.72, sPmpsState:='IM6K2:PPM-YAG2'); CASE GVL.ePF2K2State 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 fbIM6K2.stYag1.stPMPS.sPmpsState := 'IM6K2:PPM-YAG1_WFS_IN'; ELSE // Out, Unknown, or an unexpected state: full pmps fbIM6K2.stYag1.stPMPS.sPmpsState := 'IM6K2:PPM-YAG1'; END_CASE fbIM6K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M24, sDeviceName := 'IM6K2:PPM', sTransitionKey := 'IM6K2:PPM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, fResponsivity := 0.0719, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_LI2K2_K2A ^^^^^^^^^^^^^ :: PROGRAM PRG_LI2K2_K2A VAR {attribute 'pytmc' := 'pv: LI2K2:K2A'} fbLI2K2: FB_LIC; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbLI2K2.stOut, fPosition:=1.2, sPmpsState:='LI2K2:K2A-OUT'); fbStateSetup(stPositionState:=fbLI2K2.stMirror1, fPosition:=-35.3, sPmpsState:='LI2K2:K2A-MIRROR1'); fbStateSetup(stPositionState:=fbLI2K2.stMirror2, fPosition:=-69.3, sPmpsState:='LI2K2:K2A-MIRROR2'); fbStateSetup(stPositionState:=fbLI2K2.stTarget1, fPosition:=-101.3, sPmpsState:='LI2K2:K2A-TARGET1'); fbLI2K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M11, sDeviceName := 'LI2K2:K2A', sTransitionKey := 'LI2K2:K2A-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_LI3K2_K2B ^^^^^^^^^^^^^ :: PROGRAM PRG_LI3K2_K2B VAR {attribute 'pytmc' := 'pv: LI3K2:K2B'} fbLI3K2: FB_LIC; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbLI3K2.stOut, fPosition:=0.118, sPmpsState:='LI3K2:K2B-OUT'); fbStateSetup(stPositionState:=fbLI3K2.stMirror1, fPosition:=-36.38, sPmpsState:='LI3K2:K2B-MIRROR1'); fbStateSetup(stPositionState:=fbLI3K2.stMirror2, fPosition:=-70.38, sPmpsState:='LI3K2:K2B-MIRROR2'); fbStateSetup(stPositionState:=fbLI3K2.stTarget1, fPosition:=-102.38, sPmpsState:='LI3K2:K2B-TARGET1'); fbLI3K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M21, sDeviceName := 'LI3K2:K2B', sTransitionKey := 'LI3K2:K2B-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_PF1K2_WFS ^^^^^^^^^^^^^ :: PROGRAM PRG_PF1K2_WFS VAR {attribute 'pytmc' := 'pv: PF1K2:WFS'} {attribute 'TcLinkTo' := '.fbThermoCouple1.bError := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 1^Status^Error; .fbThermoCouple1.bUnderrange := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 1^Status^Underrange; .fbThermoCouple1.bOverrange := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 1^Status^Overrange; .fbThermoCouple1.iRaw := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 1^Value; .fbThermoCouple2.bError := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 2^Status^Error; .fbThermoCouple2.bUnderrange := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 2^Status^Underrange; .fbThermoCouple2.bOverrange := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 2^Status^Overrange; .fbThermoCouple2.iRaw := TIIB[PF1K2-EL3314-E5]^TC Inputs Channel 2^Value; .fbFlowMeter.iRaw := TIIB[IM5K2-EL3052-E5]^AI Standard Channel 1^Value '} // PF1K2 shares the same flow meter as IM5K2 fbPF1K2: FB_WFS; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbPF1K2.stOut, fPosition:=-13.80, sPmpsState:='PF1K2:WFS-OUT'); fbStateSetup(stPositionState:=fbPF1K2.stTarget1, fPosition:=-94.00, sPmpsState:='PF1K2:WFS-TARGET1'); fbStateSetup(stPositionState:=fbPF1K2.stTarget2, fPosition:=-82.755, sPmpsState:='PF1K2:WFS-TARGET2'); fbStateSetup(stPositionState:=fbPF1K2.stTarget3, fPosition:=-68.38, sPmpsState:='PF1K2:WFS-TARGET3'); fbStateSetup(stPositionState:=fbPF1K2.stTarget4, fPosition:=-54.004, sPmpsState:='PF1K2:WFS-TARGET4'); fbStateSetup(stPositionState:=fbPF1K2.stTarget5, fPosition:=-39.629, sPmpsState:='PF1K2:WFS-TARGET5'); fbPF1K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M12, stZStage := Main.M13, sDeviceName := 'PF1K2:WFS', sTransitionKey := 'PF1K2:WFS-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, eEnumGet=>GVL.ePF1K2State, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_PF2K2_WFS ^^^^^^^^^^^^^ :: PROGRAM PRG_PF2K2_WFS VAR {attribute 'pytmc' := 'pv: PF2K2:WFS'} {attribute 'TcLinkTo' := '.fbThermoCouple1.bError := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 1^Status^Error; .fbThermoCouple1.bUnderrange := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 1^Status^Underrange; .fbThermoCouple1.bOverrange := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 1^Status^Overrange; .fbThermoCouple1.iRaw := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 1^Value; .fbThermoCouple2.bError := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 2^Status^Error; .fbThermoCouple2.bUnderrange := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 2^Status^Underrange; .fbThermoCouple2.bOverrange := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 2^Status^Overrange; .fbThermoCouple2.iRaw := TIIB[PF2K2-EL3314-E5]^TC Inputs Channel 2^Value'} fbPF2K2: FB_WFS; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbPF2K2.stOut, fPosition:=-15.00, sPmpsState:='PF2K2:WFS-OUT'); fbStateSetup(stPositionState:=fbPF2K2.stTarget1, fPosition:=-97.789, sPmpsState:='PF2K2:WFS-TARGET1'); fbStateSetup(stPositionState:=fbPF2K2.stTarget2, fPosition:=-83.416, sPmpsState:='PF2K2:WFS-TARGET2'); fbStateSetup(stPositionState:=fbPF2K2.stTarget3, fPosition:=-69.043, sPmpsState:='PF2K2:WFS-TARGET3'); fbStateSetup(stPositionState:=fbPF2K2.stTarget4, fPosition:=-54.669, sPmpsState:='PF2K2:WFS-TARGET4'); fbStateSetup(stPositionState:=fbPF2K2.stTarget5, fPosition:=-40.296, sPmpsState:='PF2K2:WFS-TARGET5'); fbPF2K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M22, stZStage := Main.M23, sDeviceName := 'PF2K2:WFS', sTransitionKey := 'PF2K2:WFS-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, eEnumGet=>GVL.ePF2K2State, ); END_PROGRAM Related: * `GVL`_ * `Main`_ PRG_SP1K2_PAX ^^^^^^^^^^^^^ :: PROGRAM PRG_SP1K2_PAX VAR bInit : BOOL := TRUE; fbPAX_TAR_X : FB_MotionStage; fbPAX_TAR_Y : FB_MotionStage; fbPAX_TAR_Z : FB_MotionStage; fbPAX_BB_Y_01 : FB_MotionStage; fbPAX_BB_Y_02 : FB_MotionStage; fbPAX_FRAME_X : FB_MotionStage; fbPAX_FRAME_Y_01 : FB_MotionStage; fbPAX_FRAME_Y_02 : FB_MotionStage; fbPAX_FRAME_Y_03 : FB_MotionStage; END_VAR IF bInit THEN Main.M28.bHardwareEnable := TRUE; Main.M28.bPowerSelf := TRUE; Main.M29.bHardwareEnable := TRUE; Main.M29.bPowerSelf := TRUE; Main.M30.bHardwareEnable := TRUE; Main.M30.bPowerSelf := TRUE; Main.M31.bHardwareEnable := TRUE; Main.M31.bPowerSelf := TRUE; Main.M32.bHardwareEnable := TRUE; Main.M32.bPowerSelf := TRUE; Main.M33.bHardwareEnable := TRUE; Main.M33.bPowerSelf := TRUE; Main.M34.bHardwareEnable := TRUE; Main.M34.bPowerSelf := TRUE; Main.M36.bHardwareEnable := TRUE; Main.M36.bPowerSelf := TRUE; Main.M37.bHardwareEnable := TRUE; Main.M37.bPowerSelf := TRUE; bInit := FALSE; END_IF // PAX TAR fbPAX_TAR_X(stMotionStage:= Main.M32); fbPAX_TAR_Y(stMotionStage:= Main.M33); fbPAX_TAR_Z(stMotionStage:= Main.M34); // PAX BB Main.M36.bLimitForwardEnable := TRUE; Main.M36.bLimitBackwardEnable := TRUE; fbPAX_BB_Y_01(stMotionStage:= Main.M36); Main.M37.bLimitForwardEnable := TRUE; Main.M37.bLimitBackwardEnable := TRUE; fbPAX_BB_Y_02(stMotionStage:= Main.M37); // FRAME fbPAX_FRAME_X(stMotionStage:= Main.M31); fbPAX_FRAME_Y_01(stMotionStage:= Main.M28); fbPAX_FRAME_Y_02(stMotionStage:= Main.M29); fbPAX_FRAME_Y_03(stMotionStage:= Main.M30); END_PROGRAM Related: * `Main`_ PRG_ST3K2_TERM ^^^^^^^^^^^^^^ :: PROGRAM PRG_ST3K2_TERM VAR {attribute 'pytmc' := 'pv: ST3K2:TERM'} {attribute 'TcLinkTo' := '.i_xInsertedLS := TIIB[ST3K2-TERM (EP2338-0001)]^Channel 4^Input; .i_xRetractedLS:= TIIB[ST3K2-TERM (EP2338-0001)]^Channel 3^Input; .q_xRetract_DO := TIIB[ST3K2-TERM (EP2338-0001)]^Channel 9^Output '} ST3K2: FB_MotionPneumaticActuator; ibPMPS_OK : BOOL; END_VAR ST3K2( ibInsertOK:= TRUE, ibRetractOK:= TRUE, ibPMPS_OK:= ibPMPS_OK, ibSingleCntrl:= TRUE , ibCntrlHold:= TRUE, ibOverrideInterlock:= , i_xReset:= , stPneumaticActuator=> , xMPS_OK=> , io_fbFFHWO:= GVL.fbFastFaultOutput2 ); END_PROGRAM Related: * `GVL`_ PRG_TM1K2_ATM ^^^^^^^^^^^^^ :: PROGRAM PRG_TM1K2_ATM VAR {attribute 'pytmc' := 'pv: TM1K2:ATM'} {attribute 'TcLinkTo' := '.fbThermoCouple1.bError := TIIB[TM1K2-EL3314-E5]^TC Inputs Channel 1^Status^Error; .fbThermoCouple1.bUnderrange := TIIB[TM1K2-EL3314-E5]^TC Inputs Channel 1^Status^Underrange; .fbThermoCouple1.bOverrange := TIIB[TM1K2-EL3314-E5]^TC Inputs Channel 1^Status^Overrange; .fbThermoCouple1.iRaw := TIIB[TM1K2-EL3314-E5]^TC Inputs Channel 1^Value; .fbFlowMeter.iRaw := TIIB[AT1K2-EL3052-E8]^AI Standard Channel 1^Value '} // TM1K2 shares the same cooling meter as AT1K2 fbTM1K2: FB_TM1K2; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbTM1K2.stOut, fPosition:=-16.00, fDelta:=7, sPmpsState:='TM1K2:ATM-OUT'); fbStateSetup(stPositionState:=fbTM1K2.stTarget1, fPosition:=-28, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET1'); fbStateSetup(stPositionState:=fbTM1K2.stTarget2, fPosition:=-38, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET2'); fbStateSetup(stPositionState:=fbTM1K2.stTarget3, fPosition:=-48, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET3'); fbStateSetup(stPositionState:=fbTM1K2.stTarget4, fPosition:=-58, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET4'); fbStateSetup(stPositionState:=fbTM1K2.stTarget5, fPosition:=-68, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET5'); fbStateSetup(stPositionState:=fbTM1K2.stTarget6, fPosition:=-80, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET6'); fbStateSetup(stPositionState:=fbTM1K2.stTarget7, fPosition:=-96, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET7'); fbStateSetup(stPositionState:=fbTM1K2.stTarget8, fPosition:=-114.5, fDelta:=7, sPmpsState:='TM1K2:ATM-TARGET8'); fbTM1K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M9, stXStage := Main.M10, sDeviceName := 'TM1K2:ATM', sTransitionKey := 'TM1K2:ATM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `FB_TM1K2`_ * `GVL`_ * `Main`_ PRG_TM2K2_ATM ^^^^^^^^^^^^^ :: PROGRAM PRG_TM2K2_ATM VAR {attribute 'pytmc' := 'pv: TM2K2:ATM'} {attribute 'TcLinkTo' := '.fbThermoCouple1.bError := TIIB[TM2K2-EL3314-E5]^TC Inputs Channel 1^Status^Error; .fbThermoCouple1.bUnderrange := TIIB[TM2K2-EL3314-E5]^TC Inputs Channel 1^Status^Underrange; .fbThermoCouple1.bOverrange := TIIB[TM2K2-EL3314-E5]^TC Inputs Channel 1^Status^Overrange; .fbThermoCouple1.iRaw := TIIB[TM2K2-EL3314-E5]^TC Inputs Channel 1^Value; .fbFlowMeter.iRaw := TIIB[TM2K2-EL3052-E6]^AI Standard Channel 1^Value '} fbTM2K2: FB_TM2K2; fbStateSetup: FB_StateSetupHelper; stDefault: ST_PositionState := ( fVelocity := 1, bMoveOk := TRUE, bValid := TRUE ); END_VAR fbStateSetup(stPositionState:=stDefault, bSetDefault:=TRUE); fbStateSetup(stPositionState:=fbTM2K2.stOut, fPosition:=5.3, fDelta:=7, sPmpsState:='TM2K2:ATM-OUT'); fbStateSetup(stPositionState:=fbTM2K2.stTarget1, fPosition:=-15.5, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET1'); fbStateSetup(stPositionState:=fbTM2K2.stTarget2, fPosition:=-36.5, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET2'); fbStateSetup(stPositionState:=fbTM2K2.stTarget3, fPosition:=-52.0, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET3'); fbStateSetup(stPositionState:=fbTM2K2.stTarget4, fPosition:=-61.50, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET4'); fbStateSetup(stPositionState:=fbTM2K2.stTarget5, fPosition:=-77.0, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET5'); fbStateSetup(stPositionState:=fbTM2K2.stTarget6, fPosition:=-96.6, fDelta:=7, sPmpsState:='TM2K2:ATM-TARGET6'); fbTM2K2( fbFFHWO := GVL.fbFastFaultOutput2, fbArbiter := GVL.fbArbiter2, stYStage := Main.M15, stXStage := Main.M16, sDeviceName := 'TM2K2:ATM', sTransitionKey := 'TM2K2:ATM-TRANSITION', bEnableMotion := TRUE, bEnableBeamParams := TRUE, bEnablePositionLimits := TRUE, ); END_PROGRAM Related: * `FB_TM2K2`_ * `GVL`_ * `Main`_