Add mirror

This commit is contained in:
2024-09-16 10:32:31 +02:00
parent 73c5fd71b5
commit a4f10cdf9f
44 changed files with 2648 additions and 5 deletions
+1 -1
View File
@@ -8,4 +8,4 @@ EXCLUDE_VERSIONS+=3 7.0.5 7.0.6
SCRIPTS += axis_sm.plc_inc
SCRIPTS += axis_kin_slit.plc_inc
SCRIPTS += axis_kin_mirror.plc_inc
+19
View File
@@ -0,0 +1,19 @@
#- Real axes: Y1 Y2 Y3 X1 X2
var REAL_AXES[5] := {ax${AX_Y1}.enc.actpos, ax${AX_Y2}.enc.actpos, ax${AX_Y3}.enc.actpos, ax${AX_X1}.enc.actpos, ax${AX_X2}.enc.actpos};
#- Virtual axes: X Y PITCH ROLL YAW
var VIRT_AXES[5] := {ax${AX_TRX}.traj.setpos, ax${AX_TRY}.traj.setpos, ax${AX_PITCH}.traj.setpos, ax${AX_ROLL}.traj.setpos, ax${AX_YAW}.traj.setpos};
#- forward kinematics
ax${AX_TRX}.enc.actpos := dot(FWD1, REAL_AXES);
ax${AX_TRY}.enc.actpos := dot(FWD2, REAL_AXES);
ax${AX_PITCH}.enc.actpos := dot(FWD3, REAL_AXES);
ax${AX_ROLL}.enc.actpos := dot(FWD4, REAL_AXES);
ax${AX_YAW}.enc.actpos := dot(FWD5, REAL_AXES);
#- inverse kinematics
ax${AX_Y1}.traj.extsetpos := dot(INV1, VIRT_AXES);
ax${AX_Y2}.traj.extsetpos := dot(INV2, VIRT_AXES);
ax${AX_Y3}.traj.extsetpos := dot(INV3, VIRT_AXES);
ax${AX_X1}.traj.extsetpos := dot(INV4, VIRT_AXES);
ax${AX_X2}.traj.extsetpos := dot(INV5, VIRT_AXES);
+4 -4
View File
@@ -1,15 +1,15 @@
#- Initial PLC values
if(plc${PLC_ID}.firstscan) {
if(${SELF}.firstscan) {
static.counter:=0;
static.VMState:=-2;
};
#- this is needed because initially upon IocInit, motor busy flags are briefly enabled, and the first motorRecord poll at 100ms might cause issues
if ( static.counter<105 ) {
static.counter+=1;
if ( static.counter<0.105 ) {
static.counter += ${SELF}.scantime;
if ( static.counter==105) { static.VMState:=0 };
if ( static.counter>=0.105) { static.VMState:=0 };
#- VMs in Internal mode, ready to listen
mc_grp_set_traj_src(${GRP_ID_VA},0);
+609
View File
@@ -0,0 +1,609 @@
# Optics table record
# SRI Geometry:
# +---------------------+
# | M1| - <------- origin
# | | |
# | M2 | LX
# | | |
# | M0| -
# +---------------------+
# |------LZ----------|
# Macros:
# P : Prefix, e.g. X04SA-OP-
# T : Name of table record, e.g. MI1:T
# Q : Prefix to all other records, e.g. MI1
# M0X : Point 0 X direction motor
# M0Y : Point 0 Y direction motor
# M1Y : Point 1 Y direction motor
# M2X : Point 2 X direction motor
# M2Y : Point 2 Y direction motor
# M2Z : Point 2 Z direction motor
# LX : Table length perpendicular to beam direction
# LZ : Table length along the beam direction
# SX : X of rotation point
# SY : Y of rotation point
# SZ : Z of rotation point
record(ao, "$(P)$(Q):ax_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(STAT, "NO_ALARM")
field(SEVR, "NO_ALARM")
field(UDF, "0")
}
record(ao, "$(P)$(Q):ay_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(STAT, "NO_ALARM")
field(SEVR, "NO_ALARM")
field(UDF, "0")
}
record(ao, "$(P)$(Q):az_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(STAT, "NO_ALARM")
field(SEVR, "NO_ALARM")
field(UDF, "0")
}
record(ao, "$(P)$(Q):x_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(STAT, "NO_ALARM")
field(SEVR, "NO_ALARM")
field(UDF, "0")
}
record(ao, "$(P)$(Q):y_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(STAT, "NO_ALARM")
field(SEVR, "NO_ALARM")
field(UDF, "0")
}
record(ao, "$(P)$(Q):z_tweakVal") {
field(DTYP, "Soft Channel")
field(PREC, "3")
field(DRVH, "1000")
field(HOPR, "1000")
field(SEVR, "NO_ALARM")
field(STAT, "NO_ALARM")
field(UDF, "0")
}
record(bo, "$(P)$(Q):doSync") {
field(PINI, "YES")
field(DTYP, "Soft Channel")
field(DOL, "1")
field(OUT, "$(P)$(T).SYNC PP MS")
}
record(bo, "$(P)$(Q):stop") {
field(DTYP, "Soft Channel")
field(OUT, "$(P)$(Q):stop1.A PP MS")
}
record(bo, "$(P)$(Q):update") {
field(SCAN, ".2 second")
field(DTYP, "Soft Channel")
field(SDIS, "$(P)$(Q):done.VAL NPP MS")
field(OMSL, "closed_loop")
field(DOL, "1")
field(OUT, "$(P)$(T).READ PP MS")
field(ONAM, "Sync")
}
record(calc, "$(P)$(Q):geomIsGEOCARS") {
field(CALC, "a=1")
field(INPA, "$(P)$(T).GEOM CP MS")
}
record(calc, "$(P)$(Q):geomIsNEWPORT") {
field(CALC, "a=2")
field(INPA, "$(P)$(T).GEOM CP MS")
}
record(calc, "$(P)$(Q):geomIsSRI") {
field(CALC, "a=0")
field(INPA, "$(P)$(T).GEOM CP MS")
}
record(calcout, "$(P)$(Q):dmov") {
field(DESC, "Get DMOV and check links")
# field(INPA, "$(P)$(M0X).DMOV CP MS")
field(INPB, "$(P)$(M0Y).DMOV CP MS")
field(INPC, "$(P)$(M1Y).DMOV CP MS")
# field(INPD, "$(P)$(M2X).DMOV CP MS")
field(INPE, "$(P)$(M2Y).DMOV CP MS")
# field(INPF, "$(P)$(M2Z).DMOV CP MS")
field(CALC, "0")
}
record(calcout, "$(P)$(Q):done") {
field(CALC, "A&(I||!J)&(K||!L)")
field(INPA, "$(P)$(Q):done1.VAL CP MS")
field(INPI, "$(P)$(Q):dmov.E CP MS")
field(INPJ, "$(P)$(Q):dmov.INEV CP MS")
field(INPK, "$(P)$(Q):dmov.F CP MS")
field(INPL, "$(P)$(Q):dmov.INFV CP MS")
field(OUT, "$(P)$(T).READ PP MS")
field(OOPT, "Transition To Non-zero")
}
record(calcout, "$(P)$(Q):done1") {
field(CALC, "(A||!B)&(C||!D)&(E||!F)&(G||!H)")
field(INPA, "$(P)$(Q):dmov.A CP MS")
field(INPB, "$(P)$(Q):dmov.INAV CP MS")
field(INPC, "$(P)$(Q):dmov.B CP MS")
field(INPD, "$(P)$(Q):dmov.INBV CP MS")
field(INPE, "$(P)$(Q):dmov.C CP MS")
field(INPF, "$(P)$(Q):dmov.INCV CP MS")
field(INPG, "$(P)$(Q):dmov.D CP MS")
field(INPH, "$(P)$(Q):dmov.INDV CP MS")
}
record(table, "$(P)$(T)") {
field(DESC, "Optical Table")
field(LX, "$(LX)")
field(LZ, "$(LZ)")
field(SX, "$(SX)")
field(SY, "$(SY)")
field(SZ, "$(SZ)")
# field(M0XL, "$(P)$(M0X).VAL PP MS")
field(M0YL, "$(P)$(M0Y).VAL PP MS")
field(M1YL, "$(P)$(M1Y).VAL PP MS")
# field(M2XL, "$(P)$(M2X).VAL PP MS")
field(M2YL, "$(P)$(M2Y).VAL PP MS")
# field(M2ZL, "$(P)$(M2Z).VAL PP MS")
# field(R0XI, "$(P)$(M0X).VAL NPP NMS")
field(R0YI, "$(P)$(M0Y).VAL NPP NMS")
field(R1YI, "$(P)$(M1Y).VAL NPP NMS")
# field(R2XI, "$(P)$(M2X).VAL NPP NMS")
field(R2YI, "$(P)$(M2Y).VAL NPP NMS")
# field(R2ZI, "$(P)$(M2Z).VAL NPP NMS")
# field(E0XI, "$(P)$(M0X).RBV NPP NMS")
field(E0YI, "$(P)$(M0Y).RBV NPP NMS")
field(E1YI, "$(P)$(M1Y).RBV NPP NMS")
# field(E2XI, "$(P)$(M2X).RBV NPP NMS")
field(E2YI, "$(P)$(M2Y).RBV NPP NMS")
# field(E2ZI, "$(P)$(M2Z).RBV NPP NMS")
# field(V0XL, "$(P)$(M0X).VELO NPP NMS")
field(V0YL, "$(P)$(M0Y).VELO NPP NMS")
field(V1YL, "$(P)$(M1Y).VELO NPP NMS")
# field(V2XL, "$(P)$(M2X).VELO NPP NMS")
field(V2YL, "$(P)$(M2Y).VELO NPP NMS")
# field(V2ZL, "$(P)$(M2Z).VELO NPP NMS")
# field(V0XI, "$(P)$(M0X).VELO NPP NMS")
field(V0YI, "$(P)$(M0Y).VELO NPP NMS")
field(V1YI, "$(P)$(M1Y).VELO NPP NMS")
# field(V2XI, "$(P)$(M2X).VELO NPP NMS")
field(V2YI, "$(P)$(M2Y).VELO NPP NMS")
# field(V2ZI, "$(P)$(M2Z).VELO NPP NMS")
# field(H0XL, "$(P)$(M0X).HLM NPP NMS")
field(H0YL, "$(P)$(M0Y).HLM NPP NMS")
field(H1YL, "$(P)$(M1Y).HLM NPP NMS")
# field(H2XL, "$(P)$(M2X).HLM NPP NMS")
field(H2YL, "$(P)$(M2Y).HLM NPP NMS")
# field(H2ZL, "$(P)$(M2Z).HLM NPP NMS")
# field(L0XL, "$(P)$(M0X).LLM NPP NMS")
field(L0YL, "$(P)$(M0Y).LLM NPP NMS")
field(L1YL, "$(P)$(M1Y).LLM NPP NMS")
# field(L2XL, "$(P)$(M2X).LLM NPP NMS")
field(L2YL, "$(P)$(M2Y).LLM NPP NMS")
# field(L2ZL, "$(P)$(M2Z).LLM NPP NMS")
field(LEGU, "mm")
field(AEGU, "degrees")
field(PREC, "4")
field(GEOM, "$(GEOM)")
}
record(transform, "$(P)$(Q):ax_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):ax_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).AX NPP MS")
field(OUTE, "$(P)$(T).AX PP MS")
field(OUTF, "$(P)$(Q):ax_tweak.B NPP MS")
field(OUTG, "$(P)$(Q):ax_tweak.A NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
}
record(transform, "$(P)$(Q):ay_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):ay_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).AY NPP MS")
field(OUTE, "$(P)$(T).AY PP MS")
field(OUTF, "$(P)$(Q):ay_tweak.B NPP MS")
field(OUTG, "$(P)$(Q):ay_tweak.A NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
field(SEVR, "NO_ALARM")
field(STAT, "NO_ALARM")
field(UDF, "0")
}
record(transform, "$(P)$(Q):az_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):az_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).AZ NPP MS")
field(OUTE, "$(P)$(T).AZ PP MS")
field(OUTF, "$(P)$(Q):az_tweak.B NPP MS")
field(OUTG, "$(P)$(Q):az_tweak.A NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
}
record(transform, "$(P)$(Q):stop1") {
field(DESC, "Table-stop distribution")
field(CLCB, "a")
field(CLCC, "a")
field(CLCD, "a")
field(CLCE, "a")
field(CLCF, "a")
# field(OUTA, "$(P)$(M0X).STOP PP MS")
field(OUTB, "$(P)$(M0Y).STOP PP MS")
field(OUTC, "$(P)$(M1Y).STOP PP MS")
# field(OUTD, "$(P)$(M2X).STOP PP MS")
field(OUTE, "$(P)$(M2Y).STOP PP MS")
# field(OUTF, "$(P)$(M2Z).STOP PP MS")
}
record(transform, "$(P)$(Q):x_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):x_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).X NPP MS")
field(OUTE, "$(P)$(T).X PP MS")
field(OUTF, "$(P)$(Q):x_tweak.A NPP MS")
field(OUTG, "$(P)$(Q):x_tweak.B NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
}
record(transform, "$(P)$(Q):y_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):y_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).Y NPP MS")
field(OUTE, "$(P)$(T).Y PP MS")
field(OUTF, "$(P)$(Q):y_tweak.A NPP MS")
field(OUTG, "$(P)$(Q):y_tweak.B NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
}
record(transform, "$(P)$(Q):z_tweak") {
field(CLCE, "a?d+c:b?d-c:d")
field(CLCF, "0")
field(CLCG, "0")
field(INPC, "$(P)$(Q):z_tweakVal.VAL NPP MS")
field(INPD, "$(P)$(T).Z NPP MS")
field(OUTE, "$(P)$(T).Z PP MS")
field(OUTF, "$(P)$(Q):z_tweak.B NPP MS")
field(OUTG, "$(P)$(Q):z_tweak.A NPP MS")
field(PREC, "3")
field(CMTA, "tweak forward (if = 1)")
field(CMTB, "tweak reverse (if = 1)")
field(CMTC, "tweak step size")
field(CMTD, "get old value")
field(CMTE, "put new value")
field(CMTF, "zero tweak button")
field(CMTG, "zero tweak button")
}
record(calc, "$(P)$(Q):geomIsPNC") {
field(CALC, "a=2")
field(INPA, "$(P)$(T).GEOM CP MS")
}
record(sseq, "$(P)$(Q)fp") {
field(LNK2, "$(P)$(T).SX")
field(LNK3, "$(P)$(T).SY")
field(LNK4, "$(P)$(T).SZ PP")
field(STR1, "_default_")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(SELM, "All")
field(DO4, "$(SZ)")
}
record(sseq, "$(P)$(Q)fp0") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "Default")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp1") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 1")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fpSeq") {
field(SELM, "Specified")
field(DOL1, "$(P)$(Q)fpSelect.ZRST")
field(LNK1, "$(P)$(Q)fp0.STR1 PP")
field(DOL2, "$(P)$(Q)fpSelect.ONST")
field(LNK2, "$(P)$(Q)fp1.STR1 PP")
field(DOL3, "$(P)$(Q)fpSelect.TWST")
field(LNK3, "$(P)$(Q)fp2.STR1 PP")
field(DOL4, "$(P)$(Q)fpSelect.THST")
field(LNK4, "$(P)$(Q)fp3.STR1 PP")
field(DOL5, "$(P)$(Q)fpSelect.FRST")
field(LNK5, "$(P)$(Q)fp4.STR1 PP")
field(DOL6, "$(P)$(Q)fpSelect.FVST")
field(LNK6, "$(P)$(Q)fp5.STR1 PP")
field(DOL7, "$(P)$(Q)fpSelect.SXST")
field(LNK7, "$(P)$(Q)fp6.STR1 PP")
field(DOL8, "$(P)$(Q)fpSelect.SVST")
field(LNK8, "$(P)$(Q)fp7.STR1 PP")
field(DOL9, "$(P)$(Q)fpSelect.EIST")
field(LNK9, "$(P)$(Q)fp8.STR1 PP")
field(DOLA, "$(P)$(Q)fpSelect.NIST")
field(LNKA, "$(P)$(Q)fp9.STR1 PP")
}
record(sseq, "$(P)$(Q)fp2") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 2")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp3") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 3")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp4") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 4")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp5") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 5")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp6") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 6")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp7") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 7")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp8") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 8")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(sseq, "$(P)$(Q)fp9") {
field(LNK1, "$(P)$(Q)fp.STR1")
field(LNK2, "$(P)$(Q)fp.DO2")
field(STR1, "User 9")
field(DO2, "$(SX)")
field(DO3, "$(SY)")
field(LNK3, "$(P)$(Q)fp.DO3")
field(DO4, "$(SZ)")
field(SELM, "All")
field(LNK4, "$(P)$(Q)fp.DO4 PP")
field(PREC, "3")
}
record(mbbo, "$(P)$(Q)fpSelect") {
field(DTYP, "Raw Soft Channel")
field(OUT, "$(P)$(Q)fpSeq.SELN PP")
field(ZRVL, "1")
field(ONVL, "2")
field(TWVL, "3")
field(THVL, "4")
field(FRVL, "5")
field(FVVL, "6")
field(SXVL, "7")
field(SVVL, "8")
field(EIVL, "9")
field(NIVL, "10")
field(ZRST, "Default")
field(ONST, "User 1")
field(TWST, "User 2")
field(THST, "User 3")
field(FRST, "User 4")
field(FVST, "User 5")
field(SXST, "User 6")
field(SVST, "User 7")
field(EIST, "User 8")
field(NIST, "User 9")
}
record(stringout, "$(P)$(Q)fp0Name") {
field(OUT, "$(P)$(Q)fpSelect.ZRST")
field(VAL, "Default")
}
record(stringout, "$(P)$(Q)fp1Name") {
field(OUT, "$(P)$(Q)fpSelect.ONST")
field(VAL, "User 1")
}
record(stringout, "$(P)$(Q)fp2Name") {
field(OUT, "$(P)$(Q)fpSelect.TWST")
field(VAL, "User 2")
}
record(stringout, "$(P)$(Q)fp3Name") {
field(OUT, "$(P)$(Q)fpSelect.THST")
field(VAL, "User 3")
}
record(stringout, "$(P)$(Q)fp4Name") {
field(OUT, "$(P)$(Q)fpSelect.FRST")
field(VAL, "User 4")
}
record(stringout, "$(P)$(Q)fp5Name") {
field(OUT, "$(P)$(Q)fpSelect.FVST")
field(VAL, "User 5")
}
record(stringout, "$(P)$(Q)fp6Name") {
field(OUT, "$(P)$(Q)fpSelect.SXST")
field(VAL, "User 6")
}
record(stringout, "$(P)$(Q)fp7Name") {
field(OUT, "$(P)$(Q)fpSelect.SVST")
field(VAL, "User 7")
}
record(stringout, "$(P)$(Q)fp8Name") {
field(OUT, "$(P)$(Q)fpSelect.EIST")
field(VAL, "User 8")
}
record(stringout, "$(P)$(Q)fp9Name") {
field(OUT, "$(P)$(Q)fpSelect.NIST")
field(VAL, "User 9")
}
record(fanout, "$(P)$(Q)fpInit") {
field(FLNK, "$(P)$(Q)fpInit1.PROC PP")
field(LNK1, "$(P)$(Q)fp0Name.PROC PP")
field(LNK2, "$(P)$(Q)fp1Name.PROC PP")
field(LNK3, "$(P)$(Q)fp2Name.PROC PP")
field(LNK4, "$(P)$(Q)fp3Name.PROC PP")
field(LNK5, "$(P)$(Q)fp4Name.PROC PP")
field(LNK6, "$(P)$(Q)fp5Name.PROC PP")
field(PINI, "YES")
}
record(fanout, "$(P)$(Q)fpInit1") {
field(LNK1, "$(P)$(Q)fp6Name.PROC PP")
field(LNK2, "$(P)$(Q)fp7Name.PROC PP")
field(LNK3, "$(P)$(Q)fp8Name.PROC PP")
field(LNK4, "$(P)$(Q)fp9Name.PROC PP")
field(LNK5, "$(P)$(Q)fpSelect.PROC PP")
}
@@ -0,0 +1,6 @@
file G_DRV_table.template {
pattern
{ P Q T LX LZ SX SY SZ GEOM M0X M0Y M1Y M2X M2Y M2Z }
{ X10SA-ES1-VFM: t T 250 500 125 0 250 GEOCARS "" TRYR TRYDW "" TRYUW "" }
}
+29
View File
@@ -0,0 +1,29 @@
/* Forward kinematics to calculate virtual axes from real axes
| Tx | | Y1 |
| Yy | | Y2 |
| Pitch | = FWD * | Y3 |
| Roll | | X1 |
| Yaw | | X2 |
*/
var FWD1[5] := { 0, 0, 0, 1/2, 1/2};
var FWD2[5] := { 133/100,- 166/100, 133/100, 0, 0};
var FWD3[5] := { 0, 0, 0, -2, 2};
var FWD4[5] := { 2, -4, 2, 0, 00};
var FWD5[5] := { -2, 0, 2, 0, 0};
/* Inverse kinematics to calculate real axes from virtal axes
| Y1 | | Tx |
| Y2 | | Ty |
| Y3 | = INV * | Pitch |
| X1 | | Roll |
| X2 | | Yaw |
*/
var INV1[5] := { 0, 1, 0, -83/200, -1/4};
var INV2[5] := { 0, 1, 0, -133/200, 0};
var INV3[5] := { 0, 1, 0, -83/200, 1/4};
var INV4[5] := { 1, 0, -1/4, 0, 0};
var INV5[5] := { 1, 0, 1/4, 0, 0};
include "axis_calculation.plc"
include "axis_statemachine.plc"
+30
View File
@@ -0,0 +1,30 @@
/* Forward kinematics to calculate virtual axes from real axes
| Tx | | Y1 |
| Yy | | Y2 |
| Pitch | = FWD * | Y3 |
| Roll | | X1 |
| Yaw | | X2 |
*/
var FWD1[5] := {27/25, -54/25, 27/25, 1/2, 1/2};
var FWD2[5] := { 1/4, 1/2, 1/4, 0, 0};
var FWD3[5] := { -2, 0, 2, 0, 0};
var FWD4[5] := { 2, -4, 2, 0, 0};
var FWD5[5] := { 0, 0, 0, -2, 2};
/* Inverse kinematics to calculate real axes from virtal axes
| Y1 | | Tx |
| Y2 | | Ty |
| Y3 | = INV * | Pitch |
| X1 | | Roll |
| X2 | | Yaw |
*/
var INV1[5] := { 0, 1, -1/4, 1/8, 0};
var INV2[5] := { 0, 1, 0, -1/8, 0};
var INV3[5] := { 0, 1, 1/4, 1/8, 0};
var INV4[5] := { 1, 0, 0, -27/50, -1/4};
var INV5[5] := { 1, 0, 0, -27/50, 1/4};
include "axis_kin_mirror.plc_inc"
include "axis_sm.plc_inc"
+56
View File
@@ -0,0 +1,56 @@
axis:
id: 10
type: virtual
group: VFM_VIRT
epics:
name: ROLL
precision: 4
unit: mrad
motorRecord:
enable: true
description: "ROLL"
fieldInit: "SPAM=0,RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5
decceleration: 0.5
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
softlimits:
enable: false
forwardEnable: true
backwardEnable: true
forward: 10
backward: -10
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+56
View File
@@ -0,0 +1,56 @@
axis:
id: 11
type: virtual
group: VFM_VIRT
epics:
name: YAW
precision: 4
unit: mrad
motorRecord:
enable: true
description: "YAW"
fieldInit: "SPAM=0,RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5
decceleration: 0.5
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
softlimits:
enable: false
forwardEnable: true
backwardEnable: true
forward: 10
backward: -10
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+93
View File
@@ -0,0 +1,93 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 1
mode: CSV
group: VFM_REAL
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYUW
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y1 Upstream at Wall"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -51.8429 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
softlimits:
enable: yes
backwardEnable: yes
forwardEnable: yes
forward: 10.0
backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+93
View File
@@ -0,0 +1,93 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 2
mode: CSV
group: VFM_REAL
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYR
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y2 at Ring"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -50.7923 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
softlimits:
enable: yes
backwardEnable: yes
forwardEnable: yes
forward: 10.0
backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+93
View File
@@ -0,0 +1,93 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 3
mode: CSV
group: VFM_REAL
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYDW
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y3 Downtream at Wall"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -50.1910 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
softlimits:
enable: yes
backwardEnable: yes
forwardEnable: yes
forward: 10.0
backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+93
View File
@@ -0,0 +1,93 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 4
mode: CSV
group: VFM_REAL
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYUR
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y1 Upstream at Ring"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -50.0440 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+86
View File
@@ -0,0 +1,86 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 4
mode: CSV
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
epics:
name: TRYUW
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y1 Upstream at Wall"
fieldInit: "RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+86
View File
@@ -0,0 +1,86 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 5
mode: CSV
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
epics:
name: TRYR
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y2 at Ring"
fieldInit: "RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+93
View File
@@ -0,0 +1,93 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 5
mode: CSV
group: VFM_REAL
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYW
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y2 at Wall"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -51.9945 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+92
View File
@@ -0,0 +1,92 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 6
mode: CSV
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
features:
allowSrcChangeWhenEnabled: true
epics:
name: TRYDR
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y3 Downtream at Ring"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: -50.8668 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
plc:
enable: true
externalCommands: true
+86
View File
@@ -0,0 +1,86 @@
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
#
# Configuration is based on FAT report from Toyama
#
# OrientalMotors PK264D28B geared stepper 1/200/40 --> 0.000125 mm/step
# Renishaw RESOLUTE RL32BAT005B30A --> 5 nm/count
#
axis:
id: 6
mode: CSV
#parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
epics:
name: TRYDW
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y3 Downtream at Wall"
fieldInit: "RTRY=1,FOFF=Frozen,TWV=0.1"
drive:
numerator: 0.25 # Vmax 2000 step/s * 1/200 rev/step * 0.025mm/rev = 0.25 mm/s
denominator: 32768 # Always 16-bit MAX_INT for this stepper drive!
type: 0 # Type (0=Stepper, 1=Complex)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
reduceTorqueEnable: yes
reduceTorque: 2
reset: 1
warning: 7
error:
- 3 # Error 0 bit of status word
encoder:
position: ec$(MASTER_ID).s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 5 # 5 nm
denominator: 1000000 #
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders)
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
velocityFilterSize: 5
controller:
Kp: 10.0
Ki: 0.01
Kd: 0.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5 # accel. time 0.2 s
decceleration: 0.5 # deaccel. time 0.2 s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.11
backward: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01.12
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
#softlimits:
# enable: yes
# backwardEnable: yes
# forwardEnable: yes
# forward: 20.0
# backward: -10.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+56
View File
@@ -0,0 +1,56 @@
axis:
id: 7
type: virtual
group: VFM_VIRT
epics:
name: TRX
precision: 4
unit: mm
motorRecord:
enable: true
description: "X"
fieldInit: "SPAM=0,RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.05
acceleration: 0.05
decceleration: 0.05
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
softlimits:
enable: false
forwardEnable: true
backwardEnable: true
forward: 12
backward: -12
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+48
View File
@@ -0,0 +1,48 @@
axis:
id: 7
type: virtual
epics:
name: TRY
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y"
fieldInit: "RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.05
acceleration: 0.05
decceleration: 0.05
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+47
View File
@@ -0,0 +1,47 @@
axis:
id: 8
type: virtual
epics:
name: PITCH
precision: 4
unit: mrad
motorRecord:
enable: true
description: "PITCH"
fieldInit: "RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5
decceleration: 0.5
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+56
View File
@@ -0,0 +1,56 @@
axis:
id: 8
type: virtual
group: VFM_VIRT
epics:
name: TRY
precision: 4
unit: mm
motorRecord:
enable: true
description: "Y"
fieldInit: "SPAM=0,RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.05
acceleration: 0.05
decceleration: 0.05
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
softlimits:
enable: false
forwardEnable: true
backwardEnable: true
forward: 10
backward: -10
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+56
View File
@@ -0,0 +1,56 @@
axis:
id: 9
type: virtual
group: VFM_VIRT
epics:
name: PITCH
precision: 4
unit: mrad
motorRecord:
enable: true
description: "PITCH"
fieldInit: "SPAM=0,RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
numerator: 1
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5
decceleration: 0.5
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
softlimits:
enable: false
forwardEnable: true
backwardEnable: true
forward: 3
backward: -3
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+47
View File
@@ -0,0 +1,47 @@
axis:
id: 9
type: virtual
epics:
name: ROLL
precision: 4
unit: mrad
motorRecord:
enable: true
description: "ROLL"
fieldInit: "RTRY=0,FOFF=Frozen,TWV=0.1"
encoder:
type: 1 # Type (0=Incremental, 1=Absolute)
source: 1 # Source (0=Internal, 1=PLC)
bits: 32
position: ec0.s0.ONE.0
trajectory:
axis:
velocity: 0.1
acceleration: 0.5
decceleration: 0.5
input:
limit:
forward: ec0.s0.ONE.0
backward: ec0.s0.ONE.0
home: ec0.s0.ONE.0
interlock: ec0.s0.ONE.0
monitoring:
lag:
enable: yes
tolerance: 0.125
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: yes
max: 0.25
time:
trajectory: 100
drive: 200
+71
View File
@@ -0,0 +1,71 @@
axis:
id: 12
mode: CSV
epics:
name: AXIS
precision: 3
unit: deg
motorRecord:
enable: true
description: "Detector TR"
drive:
numerator: 2160000 # Vmax 6000 rev/s * 360 deg/rev = 2160000 deg/s
denominator: 2147483648 # 32-bit MAX_INT for ECMC_EC_ALIAS_DRV_VELO_SET
type: 1 # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
# control bit for reset in 'control'
reset: 7
# status bit for warning in 'status'
warning: 7
# list of error bits in 'status', or if type==string, complete EC-link
# error:
# - 3 # Error
# - 7 # Warning as Error
encoder:
numerator: 360 # 360 deg/rev
denominator: 1048576 # 2**20 count/rev
type: 1 # Type: 0=Incremental, 1=Absolute
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders) always least significant part of 'bits'
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
position: ec$(MASTER_ID).s$(DRV_SLAVE).positionActual01 # Ethercat entry for actual position input (encoder)
controller:
Kp: 10.0
Ki: 0.1
Kd: 0.0
trajectory:
type: 1
axis:
velocity: 90 # 1000 rpm (name plate) => 6000 deg/s
acceleration: 900
jerk: 900
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
backward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
monitoring:
lag:
enable: true
tolerance: 360
time: 100
target:
enable: yes
tolerance: 0.1
time: 100
velocity:
enable: true
max: 1800
time:
trajectory: 100
drive: 200
+95
View File
@@ -0,0 +1,95 @@
axis:
id: 12
mode: CSV
epics:
name: AXIS
precision: 3
unit: deg
motorRecord:
enable: true
description: "Detector TR"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=10"
drive:
numerator: 2160000 # Vmax 6000 rev/s * 360 deg/rev = 2160000 deg/s
denominator: 2147483648 # 32-bit MAX_INT for ECMC_EC_ALIAS_DRV_VELO_SET
type: 1 # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
# control bit for reset in 'control'
reset: 7
# status bit for warning in 'status'
warning: 7
# list of error bits in 'status', or if type==string, complete EC-link
# error:
# - 3 # Error
# - 7 # Warning as Error
encoder:
numerator: 360 # 360 deg/rev
denominator: 1048576 # 2**20 count/rev
type: 1 # Type: 0=Incremental, 1=Absolute
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders) always least significant part of 'bits'
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
position: ec$(MASTER_ID).s$(DRV_SLAVE).positionActual01 # Ethercat entry for actual position input (encoder)
controller:
Kp: 10.0
Ki: 0.1
Kd: 0.0
trajectory:
type: 1
axis:
velocity: 90 # 1000 rpm (name plate) => 6000 deg/s
acceleration: 900
jerk: 900
##trajectory:
## type: 1
## axis:
## velocity: 10 # 1000 rpm (name plate) 1000rev / 60s * 2mm/rev = 33.33 mm/s
## acceleration: 50
## jerk: 50
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
backward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
monitoring:
lag:
enable: true
tolerance: 360
time: 100
target:
enable: yes
tolerance: 0.1
time: 100
velocity:
enable: true
max: 1800
time:
trajectory: 100
drive: 200
##monitoring:
## lag:
## enable: true
## tolerance: 0.01
## time: 1000
## target:
## enable: yes
## tolerance: 0.001
## time: 100
## velocity:
## enable: true
## max: 20
## time:
## trajectory: 100
## drive: 200
+72
View File
@@ -0,0 +1,72 @@
axis:
id: 12
mode: CSV
epics:
name: AXIS
precision: 3
unit: mm
motorRecord:
enable: true
description: "Detector TR"
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=1"
drive:
numerator: # Vmax 6000 rev/s * 2 mm/rev = 12000 mm/s
denominator: 2147483648 # 32-bit MAX_INT for ECMC_EC_ALIAS_DRV_VELO_SET
type: 1 # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
control: ec$(MASTER_ID).s$(DRV_SLAVE).driveControl01
status: ec$(MASTER_ID).s$(DRV_SLAVE).driveStatus01
setpoint: ec$(MASTER_ID).s$(DRV_SLAVE).velocitySetpoint01
# control bit for reset in 'control'
reset: 7
# status bit for warning in 'status'
warning: 7
# list of error bits in 'status', or if type==string, complete EC-link
error:
- 3 # Error
- 7 # Warning as Error
encoder:
numerator: 2 # 2 mm/rev
denominator: 1048576 # 2**20 count/rev
type: 1 # Type: 0=Incremental, 1=Absolute
bits: 32 # Total bit count of encoder raw data
absBits: 32 # Absolute bit count (for absolute encoders) always least significant part of 'bits'
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
position: ec$(MASTER_ID).s$(DRV_SLAVE).positionActual01 # Ethercat entry for actual position input (encoder)
controller:
Kp: 10.0
Ki: 0.1
Kd: 0.0
trajectory:
type: 1
axis:
velocity: 10 # 1000 rpm (name plate) 1000rev / 60s * 2mm/rev = 33.33 mm/s
acceleration: 50 # time 0.2s
jerk: 50 # time 1s
input:
limit:
forward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
backward: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
home: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
interlock: ec$(MASTER_ID).s$(DRV_SLAVE).ONE.0
monitoring:
lag:
enable: true
tolerance: 0.01
time: 1000
target:
enable: yes
tolerance: 0.001
time: 100
velocity:
enable: true
max: 15
time:
trajectory: 100
drive: 200
+19
View File
@@ -0,0 +1,19 @@
#- Real axes: Y1 Y2 Y3 X1 X2
var REAL_AXES[5] := {ax${AX_Y1}.enc.actpos, ax${AX_Y2}.enc.actpos, ax${AX_Y3}.enc.actpos, ax${AX_X1}.enc.actpos, ax${AX_X2}.enc.actpos};
#- Virtual axes: X Y PITCH ROLL YAW
var VIRT_AXES[5] := {ax${AX_TRX}.traj.setpos, ax${AX_TRY}.traj.setpos, ax${AX_PITCH}.traj.setpos, ax${AX_ROLL}.traj.setpos, ax${AX_YAW}.traj.setpos};
#- forward kinematics
ax${AX_TRX}.enc.actpos := dot(FWD1, REAL_AXES);
ax${AX_TRY}.enc.actpos := dot(FWD2, REAL_AXES);
ax${AX_PITCH}.enc.actpos := dot(FWD3, REAL_AXES);
ax${AX_ROLL}.enc.actpos := dot(FWD4, REAL_AXES);
ax${AX_YAW}.enc.actpos := dot(FWD5, REAL_AXES);
#- inverse kinematics
ax${AX_Y1}.traj.extsetpos := dot(INV1, VIRT_AXES);
ax${AX_Y2}.traj.extsetpos := dot(INV2, VIRT_AXES);
ax${AX_Y3}.traj.extsetpos := dot(INV3, VIRT_AXES);
ax${AX_X1}.traj.extsetpos := dot(INV4, VIRT_AXES);
ax${AX_X2}.traj.extsetpos := dot(INV5, VIRT_AXES);
+122
View File
@@ -0,0 +1,122 @@
#- ECMC real/virtal axes state machine
#- Initial PLC values
if(plc${PLC_ID}.firstscan) {
static.counter:=0;
static.VMState:=-2;
};
#- this is needed because initially upon IocInit, motor busy flags are briefly enabled, and the first motorRecord poll at 100ms might cause issues
if ( static.counter<0.105 ) {
static.counter += plc${PLC_ID}.scantime;
if ( static.counter>=0.105) { static.VMState:=0 };
#- VMs in Internal mode, ready to listen
mc_grp_set_traj_src(${GRP_ID_VA},0);
};
# STATES
# State -1: at least 1 RM is in motion, RM in charge.
# State 0: all RM and VM are off.
# State 1: at least 1 VM is in motion, VM in charge.
#- State -1
if(static.VMState==-1) {
#- RM are no longer in motion
#- -1 -> 0
#- Trigger Condition:
#- - all RM are not busy
if( mc_grp_get_any_busy(${GRP_ID_RA})==0 ) {
#- disable real motors
mc_grp_set_enable(${GRP_ID_RA},0);
#- VMs in Internal mode, back to ground state
mc_grp_set_traj_src(${GRP_ID_VA},0);
#- state change
println('-1 -> 0');
static.VMState:=0;
};
#- If RM Motion is occuring, and user commands VM motion: simply disable the VMs to void the command.
if( mc_grp_get_any_enabled(${GRP_ID_VA})==1 and mc_grp_get_any_enable(${GRP_ID_VA})==1 ) {
mc_grp_set_enable(${GRP_ID_VA},0);
};
}
#- State 0
else if(static.VMState==0) {
#- 0 -> -1
#- Trigger Condition:
#- - at least 1 RM is running
#- - all RM are in internal mode
#- - all VM are disabled
mc_grp_get_any_traj_src_ext(${GRP_ID_RA})==0
if( mc_grp_get_any_busy(${GRP_ID_RA})==1 and mc_grp_get_any_traj_src_ext(${GRP_ID_RA})==0 and mc_grp_get_any_enabled(${GRP_ID_VA})==0 ) {
#- VMs in PLC mode, so no following errors occur
mc_grp_set_traj_src(${GRP_ID_VA},0);
#- state change
println('0 -> -1');
static.VMState:=-1;
}
#- 0 -> 1
#- Trigger Condition:
#- - at least 1 VM is enabled
else if( mc_grp_get_any_enabled(${GRP_ID_VA})==1 ) {
#- Exit Condition: all axes are on
if( mc_grp_get_enabled(${GRP_ID_RA})==1 and mc_grp_get_enabled(${GRP_ID_VA})==1 and mc_grp_get_any_busy(${GRP_ID_RA})==0 ) {
if( mc_grp_get_any_busy(${GRP_ID_VA})==1 ) {
mc_grp_set_traj_src(${GRP_ID_RA},1);
#- state change
println('0 -> 1');
static.VMState:=1;
};
}
#- Actions: If Exit Conditions not met
else {
#- enable motors
mc_grp_set_enable(${GRP_ID_VA},1);
mc_grp_set_enable(${GRP_ID_RA},1);
#- halt real motors
#mc_grp_halt(${GRP_ID_RA});
};
};
}
#- State 1
else if(static.VMState==1) {
#- basically a done test
#- 1 -> 0
if( mc_grp_get_any_busy(${GRP_ID_VA})==0 ) {
#- disable motors and set source
mc_grp_set_enable(${GRP_ID_VA},0);
mc_grp_set_enable(${GRP_ID_RA},0);
mc_grp_set_traj_src(${GRP_ID_RA},0);
#- once VMs are done, RMs need a bit longer to disable
if( mc_grp_get_any_busy(${GRP_ID_RA})==0 ) {
#- For some reason, an interlock is raised, but not sure why or what the implications are. It can be cleared this way.
mc_grp_reset_error(${GRP_ID_RA});
#- state change
println('1 -> 0');
static.VMState:=0;
};
};
};
+18
View File
@@ -0,0 +1,18 @@
# Open loop configuration
var:
drive: $(DRV_SLAVE)
encoder:
position: ec$(MASTER_ID).s$(DRV_SLAVE).positionActual01
type: 1 # Type (0=Incremental, 1=Absolute)
numerator: 0.025 # 0.025 mm/rev
denominator: 12800 # 200 x 64 microstep/rev
bits: 16 # Total bit count of encoder raw data
absBits: 16 # Absolute bit count (for absolute encoders)
absOffset: 0.0 # Encoder offset in eng units (for absolute encoders)
primary: 0
homing:
refToEncIDAtStartup: 1 # At startup then set the start value of this encoder
# to actpos of the given encoder id
refAtHome: 1 # If homing is executed then set position of this encoder
+78
View File
@@ -0,0 +1,78 @@
# EtherCAT slaves on xtest-sioc-ecat02
# 0 0:0 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
# 1 0:1 PREOP + EL9227-5500 ?berstromschutz 24V DC, 2K., max. 10A (Summe), eins
# 2 0:2 PREOP + EL1034 4Ch. Dig. Input 24V, potential-free, 10?s
# 3 0:3 PREOP + EL1034 4K. Dig. Eingang 24V, potenzialfrei, 10?s
# 4 0:4 PREOP + EL1034 4K. Dig. Eingang 24V, potenzialfrei, 10?s
# 5 0:5 PREOP + EL5042 2K. BiSS-C Encoder
# 6 0:6 PREOP + EL5042 2K. BiSS-C Encoder
# 7 0:7 PREOP + EL5042 2K. BiSS-C Encoder
# 8 0:8 PREOP + EL5042 2K. BiSS-C Encoder
# 9 0:9 PREOP + EL5101-0010 1K. Inc. Encoder 5V (20 Mio. Inkremente/s)
# 10 0:10 PREOP + EL3314 4K. Ana. Eingang Thermoelement (TC)
# 11 0:11 PREOP + EL3202-0010 2K. Ana. Eingang PT100 (RTD), hochgenau
# 12 0:12 PREOP + EL9410 E-Bus Power Supplier (Diagnostics)
# 13 0:13 PREOP + EL9227-5500 ?berstromschutz 24V DC, 2K., max. 10A (Summe), eins
# 14 0:14 PREOP + EL2819 16Ch. Dig. Output 24V, 0,5A, Diagnostic
# 15 0:15 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 16 0:16 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 17 0:17 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 18 0:18 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 19 0:19 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 20 0:20 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 21 0:21 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
# 22 0:22 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
file "${ecmccomp_DIR}/HWTemplate.cmd" {
pattern { SLAVE_ID HW_DESC COMP COMP_CH COMP_MACROS}
{ 0 EK1100 -1 -1 -1}
{ 1 EL9227-5500 -1 -1 -1}
{ 2 EL1034 -1 -1 -1}
{ 3 EL1034 -1 -1 -1}
{ 4 EL1034 -1 -1 -1}
# Encoders
{ 5 EL5042 Encoder-Renishaw-26bit-BISS-C 1 ""}
{ 5 EL5042 Encoder-Renishaw-26bit-BISS-C 2 ""}
{ 6 EL5042 Encoder-Renishaw-26bit-BISS-C 1 ""}
{ 6 EL5042 Encoder-Renishaw-26bit-BISS-C 2 ""}
{ 7 EL5042 Encoder-Renishaw-26bit-BISS-C 1 ""}
{ 7 EL5042 Encoder-Renishaw-26bit-BISS-C 2 ""}
{ 8 EL5042 Encoder-Renishaw-26bit-BISS-C 1 ""}
{ 8 EL5042 Encoder-Renishaw-26bit-BISS-C 2 ""}
{10 EL3314 -1 -1 -1}
{11 EL3202-0010 -1 -1 -1}
{12 EL9410 -1 -1 -1}
{13 EL9227-5500 -1 -1 -1}
{14 EL2819 -1 -1 -1}
# KB Mirror V
# TRX
# {15 EL7041-0052 Motor-Phytron-VSS57.200.1 1 ""}
# {16 EL7041-0052 Motor-Phytron-VSS57.200.1 1 ""}
# TRY
{15 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
{16 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
{17 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
# Bender
# {20 EL7041-0052 Motor-Phytron-VSS57.200.1 1 ""}
# {21 EL7041-0052 Motor-Phytron-VSS57.200.1 1 ""}
# KB Mirror H
# TRX
# {12 EL7041 Motor-Phytron-VSS57.200.1 1 ""}
# {12 EL7041 Motor-Phytron-VSS57.200.1 1 ""}
# TRY
{18 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
{19 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
{20 EL7041-0052 Motor-OrientalMotor-PKP264D28B 1 "INV_DIR=1"}
{21 EL7221-9014_ALL_INPUTS Motor-Beckhoff-AM8131-XFX1 1 ""}
{22 EL9576 -1 1 ""}
# Bender
# {21 EL7041 Motor-Phytron-VSS57.200.1 1 ""}
# {22 EL7041 Motor-Phytron-VSS57.200.1 1 ""}
}
+139
View File
@@ -0,0 +1,139 @@
#- forward kinematics
ax${AX_TRY}.enc.actpos := (ax${AX_Y1}.enc.actpos + ax${AX_Y2}.enc.actpos) / 2;
#- inverse kinematics
ax${AX_Y1}.traj.setpos := ax${AX_TRY}.traj.setpos;
ax${AX_Y2}.traj.setpos := ax${AX_TRY}.traj.setpos;
#- Initial PLC values
if (plc${PLC_ID}.firstscan) {
static.counter := 0;
static.VMState := -2;
};
#- this is needed because initially upon IocInit, motor busy flags are briefly enabled, and the first motorRecord poll at 100ms might cause issues
if (static.counter < 105) {
static.counter += 1;
if ( static.counter==105) {
static.VMState := 0;
};
#- VMs in Internal mode, ready to listen
mc_grp_set_traj_src(${GRP_VIRT_ID}, 0);
};
# STATES
# State -1: at least 1 RM is in motion, RM in charge.
# State 0: all RM and VM are off.
# State 1: at least 1 VM is in motion, VM in charge.
#- State -1
if (static.VMState == -1) {
#- RM are no longer in motion
#- -1 -> 0
#- Trigger Condition:
#- - all RM are not busy
if (mc_grp_get_any_busy(${GRP_REAL_ID}) == 0) {
#- disable real motors
mc_grp_set_enable(${GRP_REAL_ID}, 0);
#- VMs in Internal mode, back to ground state
mc_grp_set_traj_src(${GRP_VIRT_ID}, 0);
ax${AX_TRY}.traj.setpos := ax${AX_TRY}.enc.actpos
ax${AX_PITCH}.traj.setpos := ax${AX_PITCH}.enc.actpos
ax${AX_ROLL}.traj.setpos := ax${AX_ROLL}.enc.actpos
#- state change
println('-1 -> 0');
static.VMState := 0;
};
#- If RM Motion is occuring, and user commands VM motion: simply disable the VMs to void the command.
if (mc_grp_get_any_enabled(${GRP_VIRT_ID}) == 1 and mc_grp_get_any_enable(${GRP_VIRT_ID}) == 1) {
mc_grp_set_enable(${GRP_VIRT_ID}, 0);
};
}
#- State 0
else if (static.VMState == 0) {
#- 0 -> -1
#- Trigger Condition:
#- - at least 1 RM is running
#- - all RM are in internal mode
#- - all VM are disabled
if (mc_grp_get_any_busy(${GRP_REAL_ID}) == 1 and ax${AX_Y1}.traj.source == 0 and ax${AX_Y2}.traj.source == 0 and ax${AX_Y3}.traj.source == 0 and mc_grp_get_any_enabled(${GRP_VIRT_ID}) == 0) {
#- VMs in PLC mode, so no following errors occur
mc_grp_set_traj_src(${GRP_VIRT_ID}, 0);
#- state change
println('0 -> -1');
static.VMState := -1;
}
#- 0 -> 1
#- Trigger Condition:
#- - at least 1 VM is enabled
else if (mc_grp_get_any_enabled(${GRP_VIRT_ID}) == 1) {
#- Exit Condition: all axes are on
if (mc_grp_get_enabled(${GRP_REAL_ID}) == 1 and mc_grp_get_enabled(${GRP_VIRT_ID}) == 1 and mc_grp_get_any_busy(${GRP_REAL_ID}) == 0) {
if (mc_grp_get_any_busy(${GRP_VIRT_ID}) == 1) {
mc_grp_set_traj_src(${GRP_REAL_ID}, 1);
#- state change
println('0 -> 1');
static.VMState := 1;
};
}
#- Actions: If Exit Conditions not met
else {
#- enable motors
mc_grp_set_enable(${GRP_VIRT_ID}, 1);
mc_grp_set_enable(${GRP_REAL_ID}, 1);
#- halt real motors
mc_grp_halt(${GRP_REAL_ID});
println('state 0: eanble all');
}
}
}
#- State 1
else if (static.VMState == 1) {
#- basically a done test
#- 1 -> 0
if (mc_grp_get_any_busy(${GRP_VIRT_ID}) == 0) {
#- disable motors and set source to internal
mc_grp_set_enable(${GRP_VIRT_ID}, 0);
mc_grp_set_enable(${GRP_REAL_ID}, 0);
#if (mc_grp_get_any_enabled(${GRP_REAL_ID}) == 0) {
mc_grp_set_traj_src(${GRP_REAL_ID}, 0);
#}
#- once VMs are done, RMs need a bit longer to disable
if (mc_grp_get_any_busy(${GRP_REAL_ID}) == 0) {
#- For some reason, an interlock is raised, but not sure why or what the implications are. It can be cleared this way.
#mc_grp_reset_error(${GRP_REAL_ID});
#- state change
println('1 -> 0');
static.VMState := 0;
};
};
}
+11
View File
@@ -0,0 +1,11 @@
# The following lines were generated by "ioc install"
# Generated at: 2024-09-10 09:38:28.856785
epicsEnvSet IOC X10SA-CPCL-ES1
epicsEnvSet ENGINEER wang_x1
< /ioc/startup/startup.script_linux
# ---- ioc/system specific startup script(s)
< startup.script_X10SA-CPCL-ES1
iocInit
@@ -0,0 +1,87 @@
epicsEnvSet("MASTER_ID", "0")
require ecmccfg v9.5.5_RC1,"ENG_MODE=1,ECMC_VER=v9.5.5_RC1"
require ecmccomp
require ecmc_master_slave sandst_a
#- #################################################################
# only print error messages
asynSetTraceMask(${ECMC_ASYN_PORT}, -1, 0x01)
##############################################################################
# - apply hardware configuration
${SCRIPTEXEC} ${ecmccfg_DIR}loadSubstConfig.cmd, "FILE=cfg/hw.subst"
# Set all slave 9 outputs to feed switches
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput01,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput02,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput03,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput04,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput05,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput06,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput07,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput08,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput09,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput10,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput11,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput12,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput13,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput14,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput15,1)"
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(14,binaryOutput16,1)"
##############################################################################
# - load motor configuration
epicsEnvSet("DEV", "X10SA-ES1-VFM")
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax1_TRYUW.yaml, DRV_SLAVE=015, ENC_SLAVE=005, ENC_CHANNEL=01"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=015"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax2_TRYR.yaml, DRV_SLAVE=016, ENC_SLAVE=005, ENC_CHANNEL=02"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=016"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax3_TRYDW.yaml, DRV_SLAVE=017, ENC_SLAVE=008, ENC_CHANNEL=01"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=017"
epicsEnvSet("DEV", "X10SA-ES1-HFM")
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax4_TRYUR.yaml, DRV_SLAVE=018, ENC_SLAVE=008, ENC_CHANNEL=02"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=018"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax5_TRYW.yaml, DRV_SLAVE=019, ENC_SLAVE=007, ENC_CHANNEL=01"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=019"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax6_TRYDR.yaml, DRV_SLAVE=020, ENC_SLAVE=007, ENC_CHANNEL=02"
$(SCRIPTEXEC) ${ECMC_CONFIG_ROOT}loadYamlEnc.cmd, "FILE=cfg/enc_openloop_Y.yaml, DRV_SLAVE=020"
# virtual axes
epicsEnvSet("DEV", "X10SA-ES1-VFM")
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax7_TRX.yaml"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax8_TRY.yaml"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax9_PITCH.yaml"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax10_ROLL.yaml"
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax11_YAW.yaml"
# load the VFM virtual axes PLC
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadPLCFile.cmd, "FILE=cfg/VFM.plc,PLC_ID=1,INC=.:${ecmc_master_slave_DIR},PLC_MACROS='PLC_ID=1,AX_Y1=1,AX_Y2=2,AX_Y3=3,AX_X1=4,AX_X2=5,AX_TRX=7,AX_TRY=8,AX_PITCH=9,AX_ROLL=10,AX_YAW=11,GRP_ID_RA=${GRP_VFM_REAL_ID=0},GRP_ID_VA=${GRP_VFM_VIRT_ID=0}'"
#- #############################################################################
#- Temporary test
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=cfg/ax_Servo_angle.yaml, DRV_SLAVE=021"
#- #################################################################
#- apply the configuration
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}applyConfig.cmd
#- #################################################################
#- go active
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}setAppMode.cmd
require "calc"
require "opticaltable","wang_x1"
# The following lines were generated by "ioc install"
# Generated at: 2024-09-10 09:38:28.853780
cd "/ioc/X10SA-CPCL-ES1"
dbLoadTemplate("X10SA-CPCL-ES1_mirrors.subs")
+1
View File
@@ -0,0 +1 @@
7.0.7