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:
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
Global_Version
{attribute 'TcGenerated'}
{attribute 'no-analysis'}
{attribute 'linkalways'}
// This function has been automatically generated from the project information.
VAR_GLOBAL CONSTANT
{attribute 'const_non_replaced'}
stLibVersion_plc_kfe_rix_motion : ST_LibVersion := (iMajor := 2, iMinor := 7, iBuild := 1, iRevision := 0, nFlags := 1, sVersion := '2.7.1');
END_VAR
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
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 := 32,
fTermMax := 10,
fTermMin := -10,
fOffset := -2, // 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_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:
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:
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:
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:
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
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
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
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
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
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
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
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
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-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:
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
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
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
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
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
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
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:
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:
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
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