5 Commits

Author SHA1 Message Date
sandst_a 184f01302d use common cfgs for slit example 2024-09-26 15:21:57 +02:00
sandst_a d4bd266180 split examples 2024-09-26 14:44:46 +02:00
sandst_a 96b924debf Add generic scripts for 2..6DoF 2024-09-26 14:37:28 +02:00
sandst_a 825c941b59 Update 2024-09-17 11:22:24 +02:00
sandst_a 2b501490dd Remove MR sync in satte 0 2024-09-16 16:04:42 +02:00
22 changed files with 203 additions and 48 deletions
+5
View File
@@ -9,3 +9,8 @@ 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
SCRIPTS += axis_kin_2DoF.plc_inc
SCRIPTS += axis_kin_3DoF.plc_inc
SCRIPTS += axis_kin_4DoF.plc_inc
SCRIPTS += axis_kin_5DoF.plc_inc
SCRIPTS += axis_kin_6DoF.plc_inc
+13
View File
@@ -0,0 +1,13 @@
#- Slave axes (normally physical/real axes): AX_S1, AX_S2
var SLAVE_AXES[2] := {ax${AX_S1}.enc.actpos, ax${AX_S2}.enc.actpos};
#- Master axes (normally virtual axes): AX_M1, AX_M2
var MASTER_AXES[2] := {ax${AX_M1}.traj.setpos, ax${AX_M2}.traj.setpos};
#- forward kinematics
ax${AX_M1}.enc.actpos := dot(FWD1, SLAVE_AXES);
ax${AX_M2}.enc.actpos := dot(FWD2, SLAVE_AXES);
#- inverse kinematics
ax${AX_S1}.traj.extsetpos := dot(INV1, MASTER_AXES);
ax${AX_S2}.traj.extsetpos := dot(INV2, MASTER_AXES);
+16
View File
@@ -0,0 +1,16 @@
#- Slave axes (normally physical/real axes): AX_S1, AX_S2, AX_S3
var SLAVE_AXES[3] := {ax${AX_S1}.enc.actpos, ax${AX_S2}.enc.actpos, ax${AX_S3}.enc.actpos};
#- Master axes (normally virtual axes): AX_M1, AX_M2, AX_M3
var MASTER_AXES[3] := {ax${AX_M1}.traj.setpos, ax${AX_M2}.traj.setpos, ax${AX_M3}.traj.setpos};
#- forward kinematics
ax${AX_M1}.enc.actpos := dot(FWD1, SLAVE_AXES);
ax${AX_M2}.enc.actpos := dot(FWD2, SLAVE_AXES);
ax${AX_M3}.enc.actpos := dot(FWD3, SLAVE_AXES);
#- inverse kinematics
ax${AX_S1}.traj.extsetpos := dot(INV1, MASTER_AXES);
ax${AX_S2}.traj.extsetpos := dot(INV2, MASTER_AXES);
ax${AX_S3}.traj.extsetpos := dot(INV3, MASTER_AXES);
+18
View File
@@ -0,0 +1,18 @@
#- Slave axes (normally physical/real axes): AX_S1, AX_S2, AX_S3, AX_S4
var SLAVE_AXES[4] := {ax${AX_S1}.enc.actpos, ax${AX_S2}.enc.actpos, ax${AX_S3}.enc.actpos, ax${AX_S4}.enc.actpos};
#- Master axes (normally virtual axes): AX_M1, AX_M2, AX_M3, AX_M4
var MASTER_AXES[4] := {ax${AX_M1}.traj.setpos, ax${AX_M2}.traj.setpos, ax${AX_M3}.traj.setpos, ax${AX_M4}.traj.setpos};
#- forward kinematics
ax${AX_M1}.enc.actpos := dot(FWD1, SLAVE_AXES);
ax${AX_M2}.enc.actpos := dot(FWD2, SLAVE_AXES);
ax${AX_M3}.enc.actpos := dot(FWD3, SLAVE_AXES);
ax${AX_M4}.enc.actpos := dot(FWD4, SLAVE_AXES);
#- inverse kinematics
ax${AX_S1}.traj.extsetpos := dot(INV1, MASTER_AXES);
ax${AX_S2}.traj.extsetpos := dot(INV2, MASTER_AXES);
ax${AX_S3}.traj.extsetpos := dot(INV3, MASTER_AXES);
ax${AX_S4}.traj.extsetpos := dot(INV4, MASTER_AXES);
+20
View File
@@ -0,0 +1,20 @@
#- Slave axes (normally physical/real axes): AX_S1, AX_S2, AX_S3, AX_S4, AX_S5
var SLAVE_AXES[5] := {ax${AX_S1}.enc.actpos, ax${AX_S2}.enc.actpos, ax${AX_S3}.enc.actpos, ax${AX_S4}.enc.actpos, ax${AX_S5}.enc.actpos};
#- Master axes (normally virtual axes): AX_M1, AX_M2, AX_M3, AX_M4, AX_M5
var MASTER_AXES[5] := {ax${AX_M1}.traj.setpos, ax${AX_M2}.traj.setpos, ax${AX_M3}.traj.setpos, ax${AX_M4}.traj.setpos, ax${AX_M5}.traj.setpos};
#- forward kinematics
ax${AX_M1}.enc.actpos := dot(FWD1, SLAVE_AXES);
ax${AX_M2}.enc.actpos := dot(FWD2, SLAVE_AXES);
ax${AX_M3}.enc.actpos := dot(FWD3, SLAVE_AXES);
ax${AX_M4}.enc.actpos := dot(FWD4, SLAVE_AXES);
ax${AX_M5}.enc.actpos := dot(FWD5, SLAVE_AXES);
#- inverse kinematics
ax${AX_S1}.traj.extsetpos := dot(INV1, MASTER_AXES);
ax${AX_S2}.traj.extsetpos := dot(INV2, MASTER_AXES);
ax${AX_S3}.traj.extsetpos := dot(INV3, MASTER_AXES);
ax${AX_S4}.traj.extsetpos := dot(INV4, MASTER_AXES);
ax${AX_S5}.traj.extsetpos := dot(INV5, MASTER_AXES);
+22
View File
@@ -0,0 +1,22 @@
#- Slave axes (normally physical/real axes): AX_S1, AX_S2, AX_S3, AX_S4, AX_S5, AX_S6
var SLAVE_AXES[6] := {ax${AX_S1}.enc.actpos, ax${AX_S2}.enc.actpos, ax${AX_S3}.enc.actpos, ax${AX_S4}.enc.actpos, ax${AX_S5}.enc.actpos, ax${AX_S6}.enc.actpos};
#- Master axes (normally virtual axes): AX_M1, AX_M2, AX_M3, AX_M4, AX_M5, AX_M6
var MASTER_AXES[6] := {ax${AX_M1}.traj.setpos, ax${AX_M2}.traj.setpos, ax${AX_M3}.traj.setpos, ax${AX_M4}.traj.setpos, ax${AX_M5}.traj.setpos, ax${AX_M6}.traj.setpos};
#- forward kinematics
ax${AX_M1}.enc.actpos := dot(FWD1, SLAVE_AXES);
ax${AX_M2}.enc.actpos := dot(FWD2, SLAVE_AXES);
ax${AX_M3}.enc.actpos := dot(FWD3, SLAVE_AXES);
ax${AX_M4}.enc.actpos := dot(FWD4, SLAVE_AXES);
ax${AX_M5}.enc.actpos := dot(FWD5, SLAVE_AXES);
ax${AX_M6}.enc.actpos := dot(FWD6, SLAVE_AXES);
#- inverse kinematics
ax${AX_S1}.traj.extsetpos := dot(INV1, MASTER_AXES);
ax${AX_S2}.traj.extsetpos := dot(INV2, MASTER_AXES);
ax${AX_S3}.traj.extsetpos := dot(INV3, MASTER_AXES);
ax${AX_S4}.traj.extsetpos := dot(INV4, MASTER_AXES);
ax${AX_S5}.traj.extsetpos := dot(INV5, MASTER_AXES);
ax${AX_S6}.traj.extsetpos := dot(INV6, MASTER_AXES);
+1 -1
View File
@@ -16,4 +16,4 @@ 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);
ax${AX_X2}.traj.extsetpos := dot(INV5, VIRT_AXES);
+2 -5
View File
@@ -26,7 +26,7 @@ if ( static.counter<0.105 ) {
if(static.VMState==-1) {
#- Trigg MR sync for all virt axes
mc_grp_set_mr_sync_next_poll(${GRP_ID_VA},1);
mc_grp_sync_act_set(${GRP_ID_VA},1);
#- RM are no longer in motion
#- -1 -> 0
@@ -54,9 +54,6 @@ if(static.VMState==-1) {
#- State 0
else if(static.VMState==0) {
#- Trigg MR sync for all virt axes
mc_grp_set_mr_sync_next_poll(${GRP_ID_VA},1);
#- 0 -> -1
#- Trigger Condition:
#- - at least 1 RM is running
@@ -87,7 +84,7 @@ else if(static.VMState==0) {
println('0 -> 1');
static.VMState:=1;
#- Disable MR sync for all virt axes
mc_grp_set_mr_sync_next_poll(${GRP_ID_VA},0);
mc_grp_sync_act_set(${GRP_ID_VA},0);
};
}
@@ -1,16 +1,4 @@
#- Configuration scripts
require ecmccfg sandst_a,"ECMC_VER=sandst_a,ENG_MODE=1,EC_RATE=100"
#- Components lib
require ecmccomp
#- Syncronization configs
require ecmc_master_slave
#- Only output errors
asynSetTraceMask(${ECMC_ASYN_PORT}, -1, 0x01)
#- ############################################################################
#- add slaves
#- list of slaves (4 axis test motion box)
@@ -52,12 +40,12 @@ ${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL1008"
# 0:7 - EL7041 1Ch Stepper
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Motor-Generic-2Phase-Stepper,MACROS='I_MAX_MA=1000,I_STDBY_MA=500,U_NOM_MV=48000,R_COIL_MOHM=1230'"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=cfg/axis_ax5_LO.yaml, DRV_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_CHANNEL=01"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=../common/axis_ax5_LO.yaml, DRV_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_CHANNEL=01"
# 0:8 - EL7041 1Ch Stepper
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Motor-Generic-2Phase-Stepper,MACROS='I_MAX_MA=1000,I_STDBY_MA=500,U_NOM_MV=48000,R_COIL_MOHM=1230'"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=cfg/axis_ax6_HI.yaml, DRV_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_CHANNEL=01"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=../common/axis_ax6_HI.yaml, DRV_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_SLAVE=${ECMC_EC_SLAVE_NUM}, ENC_CHANNEL=01"
# 0:9 - EL7041 1Ch Stepper
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
@@ -67,19 +55,5 @@ ${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
#- #################################################################
#- Virtual axes
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=cfg/axis_vax5_YCEN.yaml, AX_ID=${AX_NUM=12}"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=cfg/axis_vax6_YGAP.yaml, AX_ID=${AX_NUM=13}"
#- #################################################################
#- PLCs with inverse kinematics (note the INC var including dirs to search for include files)
#- The group ID:s configured in yaml are stored in GRP_<axis.group>_ID
${SCRIPTEXEC} ${ecmccfg_DIR}loadPLCFile.cmd, "FILE=./cfg/axis_main.plc, PLC_ID=1, INC=.:${ecmc_master_slave_DIR}, PLC_MACROS='PLC_ID=1, AX_CEN=12, AX_GAP=13, AX_LO=5, AX_HI=6, GRP_ID_RA=${GRP_realAxes_ID}, GRP_ID_VA=${GRP_virtualAxes_ID}'"
#- #################################################################
#- go active
${SCRIPTEXEC} ${ecmccfg_DIR}applyConfig.cmd
${SCRIPTEXEC} ${ecmccfg_DIR}setAppMode.cmd
#- #############################################################################
#- reset all errors
afterInit("ecmcConfigOrDie 'ControllerErrorReset()'")
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=../common/axis_vax5_YCEN.yaml, AX_ID=${AX_NUM=12}"
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=../common/axis_vax6_YGAP.yaml, AX_ID=${AX_NUM=13}"
-12
View File
@@ -1,15 +1,3 @@
# Test ioc for a slit system
Note: Motor record disabled in this test system
## Changes
1. Use ecmc/ecmccfg version 9.5.4 or newer.
2. Divide statemachine and kinematics into separate include files (add INC param to loadPLCFile.cmd needed)
3. Use extsetpos in kinematics
4. Use new axis group functions in statemachine to make it generic (no direct access to axes in statemachine)
5. Set allow source change when enabled in axis yaml cfg (remove in startup script)
6. Remove encoder.position in virtual axis (not needed anymore)
7. Remove filter cfgs in yaml files
## Panel
```
caqtdm -macro "IOC=c6025a" ecmcMain.ui
@@ -0,0 +1,30 @@
#- Configuration scripts
require ecmccfg,"ENG_MODE=1,EC_RATE=100"
#- Components lib
require ecmccomp
#- Syncronization configs
require ecmc_master_slave sandst_a
#- Only output errors
asynSetTraceMask(${ECMC_ASYN_PORT}, -1, 0x01)
#- #################################################################
# Configure Hardware and Motion
< ../common/cfgHW_and_motion.cmd
#- #################################################################
#- PLCs with inverse kinematics (note the INC var including dirs to search for include files)
#- The group ID:s configured in yaml are stored in GRP_<axis.group>_ID
${SCRIPTEXEC} ${ecmccfg_DIR}loadPLCFile.cmd, "FILE=./cfg/axis_main.plc, PLC_ID=1, INC=.:${ecmc_master_slave_DIR}, PLC_MACROS='PLC_ID=1, AX_CEN=12, AX_GAP=13, AX_LO=5, AX_HI=6, GRP_ID_RA=${GRP_realAxes_ID}, GRP_ID_VA=${GRP_virtualAxes_ID}'"
#- #################################################################
#- go active
${SCRIPTEXEC} ${ecmccfg_DIR}applyConfig.cmd
${SCRIPTEXEC} ${ecmccfg_DIR}setAppMode.cmd
#- #############################################################################
#- reset all errors
afterInit("ecmcConfigOrDie 'ControllerErrorReset()'")
@@ -0,0 +1 @@
7.0.7
@@ -0,0 +1,31 @@
/* Forward kinematics to calculate virtual axes from real axes
| CEN | = FWD * | S1_LO |
| GAP | | S2_HI |
Equations:
ax{AX_CEN}.enc.actpos:=(ax{AX_LO}.enc.actpos+ax{AX_HI}.enc.actpos)/2;
ax{AX_GAP}.enc.actpos:=ax{AX_HI}.enc.actpos-ax{AX_LO}.enc.actpos;
*/
var FWD1[2] := {0.5, 0.5};
var FWD2[2] := { -1, 1 };
/* Inverse kinematics to calculate real axes from virtal axes
| S1_LO | = INV * | CEN |
| S2_HI | | GAP |
Equations:
ax{AX_LO}.traj.extsetpos:=ax{AX_CEN}.traj.setpos-ax{AX_GAP}.traj.setpos/2;
ax{AX_HI}.traj.extsetpos:=ax{AX_CEN}.traj.setpos+ax{AX_GAP}.traj.setpos/2;
*/
var INV1[2] := { 1, -0.5};
var INV2[2] := { 1, 0.5};
####### Kinematics for slit system.
# Macros cannot be used in an include. In order to find files, the loadPLCFile.cmd parameter "INC" defines the dirs that MSI will look for the file)
include "axis_kin_2DoF.plc_inc"
####### State machine
# Macros cannot be used in an include. In order to find files, the loadPLCFile.cmd parameter "INC" defines the dirs that MSI will look for the file)
include "axis_sm.plc_inc"
+11
View File
@@ -0,0 +1,11 @@
# The following lines were generated by "ioc install"
# Generated at: 2024-08-07 16:32:41.171272
epicsEnvSet IOC c6025a
epicsEnvSet ENGINEER sandst_a
< /ioc/startup/startup.script_linux
# ---- ioc/system specific startup script(s)
< startup.script_ecmc
iocInit
@@ -0,0 +1,29 @@
#- Configuration scripts
require ecmccfg,"ENG_MODE=1,EC_RATE=100"
#- Components lib
require ecmccomp
#- Syncronization configs
require ecmc_master_slave sandst_a
#- Only output errors
asynSetTraceMask(${ECMC_ASYN_PORT}, -1, 0x01)
#- #################################################################
# Configure Hardware and Motion
< ../common/cfgHW_and_motion.cmd
#- #################################################################
#- PLCs with kinematics (note the INC var including dirs to search for include files)
#- The group ID:s configured in yaml are stored in GRP_<axis.group>_ID
${SCRIPTEXEC} ${ecmccfg_DIR}loadPLCFile.cmd, "FILE=./cfg/axis_main.plc, PLC_ID=1, INC=.:${ecmc_master_slave_DIR}, PLC_MACROS='PLC_ID=1, AX_M1=12, AX_M2=13, AX_S1=5, AX_S2=6, GRP_ID_RA=${GRP_realAxes_ID}, GRP_ID_VA=${GRP_virtualAxes_ID}'"
#- #################################################################
#- go active
${SCRIPTEXEC} ${ecmccfg_DIR}applyConfig.cmd
${SCRIPTEXEC} ${ecmccfg_DIR}setAppMode.cmd
#- #############################################################################
#- reset all errors
afterInit("ecmcConfigOrDie 'ControllerErrorReset()'")