Add generic scripts for 2..6DoF
This commit is contained in:
5
Makefile
5
Makefile
@@ -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
axis_kin_2DoF.plc_inc
Normal file
13
axis_kin_2DoF.plc_inc
Normal 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
axis_kin_3DoF.plc_inc
Normal file
16
axis_kin_3DoF.plc_inc
Normal 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
axis_kin_4DoF.plc_inc
Normal file
18
axis_kin_4DoF.plc_inc
Normal 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
axis_kin_5DoF.plc_inc
Normal file
20
axis_kin_5DoF.plc_inc
Normal 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
axis_kin_6DoF.plc_inc
Normal file
22
axis_kin_6DoF.plc_inc
Normal 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);
|
||||
@@ -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);
|
||||
|
||||
31
example/slit_equations/cfg/axis_main_matrix.plc
Normal file
31
example/slit_equations/cfg/axis_main_matrix.plc
Normal file
@@ -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"
|
||||
85
example/slit_equations/startup_matrix.script_ecmc
Normal file
85
example/slit_equations/startup_matrix.script_ecmc
Normal file
@@ -0,0 +1,85 @@
|
||||
#- 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)
|
||||
|
||||
|
||||
#- ############################################################################
|
||||
#- add slaves
|
||||
#- list of slaves (4 axis test motion box)
|
||||
# Master0
|
||||
# 0 0:0 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
|
||||
# 1 0:1 PREOP + EL9227-5500 <20>berstromschutz 24V DC, 2K., max. 10A (Summe), eins
|
||||
# 2 0:2 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 3 0:3 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 4 0:4 PREOP + EL3204 4K. Ana. Eingang PT100 (RTD)
|
||||
# 5 0:5 PREOP + EL2008 8K. Dig. Ausgang 24V, 0.5A
|
||||
# 6 0:6 PREOP + EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
# 7 0:7 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 8 0:8 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 9 0:9 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 10 0:10 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
#
|
||||
|
||||
# 0:0 - EK1100 EtherCAT coupler
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EK1100"
|
||||
|
||||
# 0:1 - EL9227-5500
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL9227-5500"
|
||||
|
||||
# 0:2 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:3 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:4 - EL3204
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL3204"
|
||||
|
||||
# 0:5 - EL2008
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL2008"
|
||||
|
||||
# 0:6 - EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
${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"
|
||||
|
||||
# 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"
|
||||
|
||||
# 0:9 - EL7041 1Ch Stepper
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
|
||||
|
||||
# 0:10 - EL7041 1Ch Stepper
|
||||
${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_matrix.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()'")
|
||||
1
example/slit_matrix/cfg/EPICSVERSION
Normal file
1
example/slit_matrix/cfg/EPICSVERSION
Normal file
@@ -0,0 +1 @@
|
||||
7.0.7
|
||||
79
example/slit_matrix/cfg/axis_ax5_LO.yaml
Normal file
79
example/slit_matrix/cfg/axis_ax5_LO.yaml
Normal file
@@ -0,0 +1,79 @@
|
||||
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
|
||||
|
||||
axis:
|
||||
id: 5
|
||||
group: realAxes
|
||||
mode: CSV
|
||||
features:
|
||||
allowSrcChangeWhenEnabled: true
|
||||
|
||||
epics:
|
||||
name: TR_LO
|
||||
precision: 4
|
||||
unit: mm
|
||||
motorRecord:
|
||||
description: "Low"
|
||||
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=1"
|
||||
|
||||
drive:
|
||||
numerator: 10 # max velo in EGU/s
|
||||
denominator: 32768 # MAX_INT for a 16-bit register, always this for this stepper drive!
|
||||
type: 0
|
||||
control: ec0.s$(DRV_SLAVE).driveControl01
|
||||
status: ec0.s$(DRV_SLAVE).driveStatus01
|
||||
setpoint: ec0.s$(DRV_SLAVE).velocitySetpoint01
|
||||
|
||||
encoder:
|
||||
numerator: 1 # 1egu = 1mm
|
||||
denominator: 12800 # Number of ticks when motor moves numerator (=1mm): 1 mm / 50 nm = 20000
|
||||
type: 0 # Type: 0=Incremental, 1=Absolute
|
||||
bits: 16 # Total bit count of encoder raw data
|
||||
absBits: 0 # Absolute bit count (for abs enc) always least significant part of 'bits'
|
||||
absOffset: 0.0000 # Encoder offset in eng units (for absolute encoders)
|
||||
position: ec0.s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
|
||||
|
||||
controller:
|
||||
Kp: 10.00
|
||||
Ki: 0.001
|
||||
Kd: 0.000
|
||||
Kff: 1.00
|
||||
|
||||
trajectory:
|
||||
axis:
|
||||
velocity: 1.0
|
||||
acceleration: 1.0
|
||||
deceleration: 1.0
|
||||
|
||||
input:
|
||||
limit:
|
||||
forward: ec0.s$(DRV_SLAVE).driveStatus01.12 # 1119994 cnts // 55.9997 mm
|
||||
backward: ec0.s$(DRV_SLAVE).driveStatus01.11 # 98010 cnts // 4.9005 mm
|
||||
home: ec0.s$(DRV_SLAVE).ONE.0 # unused
|
||||
interlock: ec0.s$(DRV_SLAVE).ONE.0 # unused
|
||||
|
||||
softlimits:
|
||||
enable: false
|
||||
backwardEnable: true
|
||||
forwardEnable: true
|
||||
forward: 55.8
|
||||
backward: 5.1
|
||||
|
||||
monitoring:
|
||||
lag:
|
||||
enable: true
|
||||
tolerance: 0.05
|
||||
time: 100
|
||||
target:
|
||||
enable: true
|
||||
tolerance: 0.05
|
||||
time: 100
|
||||
velocity:
|
||||
enable: true
|
||||
max: 5
|
||||
time:
|
||||
trajectory: 100
|
||||
drive: 200
|
||||
|
||||
plc:
|
||||
enable: true
|
||||
externalCommands: true
|
||||
79
example/slit_matrix/cfg/axis_ax6_HI.yaml
Normal file
79
example/slit_matrix/cfg/axis_ax6_HI.yaml
Normal file
@@ -0,0 +1,79 @@
|
||||
# https://paulscherrerinstitute.github.io/ecmccfg/manual/axis/axisyaml/
|
||||
|
||||
axis:
|
||||
id: 6
|
||||
group: realAxes
|
||||
mode: CSV
|
||||
features:
|
||||
allowSrcChangeWhenEnabled: true
|
||||
|
||||
epics:
|
||||
name: TR_HI
|
||||
precision: 4
|
||||
unit: mm
|
||||
motorRecord:
|
||||
description: "Hi"
|
||||
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=1"
|
||||
|
||||
drive:
|
||||
numerator: 10 # max velo in EGU/s
|
||||
denominator: 32768 # MAX_INT for a 16-bit register, always this for this stepper drive!
|
||||
type: 0
|
||||
control: ec0.s$(DRV_SLAVE).driveControl01
|
||||
status: ec0.s$(DRV_SLAVE).driveStatus01
|
||||
setpoint: ec0.s$(DRV_SLAVE).velocitySetpoint01
|
||||
|
||||
encoder:
|
||||
numerator: 1 # 1egu = 1mm
|
||||
denominator: 12800 # Number of ticks when motor moves numerator (=1mm): 1 mm / 50 nm = 20000
|
||||
type: 0 # Type: 0=Incremental, 1=Absolute
|
||||
bits: 16 # Total bit count of encoder raw data
|
||||
absBits: 0 # Absolute bit count (for abs enc) always least significant part of 'bits'
|
||||
absOffset: 0.0000 # Encoder offset in eng units (for absolute encoders)
|
||||
position: ec0.s$(ENC_SLAVE).positionActual$(ENC_CHANNEL)
|
||||
|
||||
controller:
|
||||
Kp: 2.000
|
||||
Ki: 0.001
|
||||
Kd: 0.000
|
||||
Kff: 1.00
|
||||
|
||||
trajectory:
|
||||
axis:
|
||||
velocity: 1.0
|
||||
acceleration: 1.0
|
||||
deceleration: 1.0
|
||||
|
||||
input:
|
||||
limit:
|
||||
forward: ec0.s$(DRV_SLAVE).driveStatus01.12 # 1111969 cnts // 55.5984 mm
|
||||
backward: ec0.s$(DRV_SLAVE).driveStatus01.11 # 109007 cnts // 5.4504 mm
|
||||
home: ec0.s$(DRV_SLAVE).ONE.0 # unused
|
||||
interlock: ec0.s$(DRV_SLAVE).ONE.0 # unused
|
||||
|
||||
softlimits:
|
||||
enable: false
|
||||
backwardEnable: true
|
||||
forwardEnable: true
|
||||
forward: 55.4
|
||||
backward: 5.7
|
||||
|
||||
monitoring:
|
||||
lag:
|
||||
enable: true
|
||||
tolerance: 0.05
|
||||
time: 100
|
||||
target:
|
||||
enable: true
|
||||
tolerance: 0.05
|
||||
time: 100
|
||||
velocity:
|
||||
enable: true
|
||||
max: 5
|
||||
time:
|
||||
trajectory: 100
|
||||
drive: 200
|
||||
|
||||
plc:
|
||||
enable: true
|
||||
externalCommands: true
|
||||
8
example/slit_matrix/cfg/axis_main.plc
Executable file
8
example/slit_matrix/cfg/axis_main.plc
Executable file
@@ -0,0 +1,8 @@
|
||||
|
||||
####### 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_slit.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"
|
||||
31
example/slit_matrix/cfg/axis_main_matrix.plc
Normal file
31
example/slit_matrix/cfg/axis_main_matrix.plc
Normal file
@@ -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"
|
||||
65
example/slit_matrix/cfg/axis_vax5_YCEN.yaml
Normal file
65
example/slit_matrix/cfg/axis_vax5_YCEN.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
axis:
|
||||
id: ${AX_ID}
|
||||
group: virtualAxes
|
||||
type: end effector
|
||||
|
||||
epics:
|
||||
name: CENTERY
|
||||
precision: 4
|
||||
unit: mm
|
||||
motorRecord:
|
||||
description: "Center (Virtual)"
|
||||
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=1"
|
||||
|
||||
encoder:
|
||||
type: 1
|
||||
source: 1
|
||||
numerator: 1
|
||||
bits: 32
|
||||
|
||||
trajectory:
|
||||
axis:
|
||||
velocity: 0.5
|
||||
acceleration: 0.25
|
||||
jerk: 0.25
|
||||
|
||||
input:
|
||||
limit:
|
||||
forward: ec0.s0.ONE.0 # unused
|
||||
backward: ec0.s0.ONE.0 # unused
|
||||
home: ec0.s0.ONE.0 # unused
|
||||
interlock: ec0.s0.ONE.0 # unused
|
||||
|
||||
softlimits:
|
||||
enable: false
|
||||
forwardEnable: true
|
||||
backwardEnable: true
|
||||
forward: 52
|
||||
backward: 8
|
||||
|
||||
monitoring:
|
||||
lag:
|
||||
enable: yes
|
||||
tolerance: 0.02
|
||||
time: 100
|
||||
target:
|
||||
enable: yes
|
||||
tolerance: 0.02
|
||||
time: 100
|
||||
velocity:
|
||||
enable: yes
|
||||
max: 0.6
|
||||
time:
|
||||
trajectory: 100
|
||||
drive: 100
|
||||
|
||||
plc:
|
||||
enable: true
|
||||
externalCommands: true
|
||||
filter:
|
||||
velocity:
|
||||
enable: false
|
||||
size: 10
|
||||
trajectory:
|
||||
enable: false
|
||||
size: 10
|
||||
65
example/slit_matrix/cfg/axis_vax6_YGAP.yaml
Normal file
65
example/slit_matrix/cfg/axis_vax6_YGAP.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
axis:
|
||||
id: ${AX_ID}
|
||||
group: virtualAxes
|
||||
type: end effector
|
||||
|
||||
epics:
|
||||
name: GAPY
|
||||
precision: 4
|
||||
unit: mm
|
||||
motorRecord:
|
||||
description: "Gap (Virtual)"
|
||||
fieldInit: "SPAM=0,RTRY=1,FOFF=Frozen,TWV=1"
|
||||
|
||||
encoder:
|
||||
type: 1
|
||||
source: 1
|
||||
numerator: 1
|
||||
bits: 32
|
||||
|
||||
trajectory:
|
||||
axis:
|
||||
velocity: 0.5
|
||||
acceleration: 0.25
|
||||
jerk: 0.25
|
||||
|
||||
input:
|
||||
limit:
|
||||
forward: ec0.s0.ONE.0 # unused
|
||||
backward: ec0.s0.ONE.0 # unused
|
||||
home: ec0.s0.ONE.0 # unused
|
||||
interlock: ec0.s0.ONE.0 # unused
|
||||
|
||||
softlimits:
|
||||
enable: false
|
||||
forwardEnable: true
|
||||
backwardEnable: true
|
||||
forward: 20
|
||||
backward: -20
|
||||
|
||||
monitoring:
|
||||
lag:
|
||||
enable: yes
|
||||
tolerance: 0.02
|
||||
time: 100
|
||||
target:
|
||||
enable: yes
|
||||
tolerance: 0.02
|
||||
time: 100
|
||||
velocity:
|
||||
enable: yes
|
||||
max: 0.6
|
||||
time:
|
||||
trajectory: 100
|
||||
drive: 100
|
||||
|
||||
plc:
|
||||
enable: true
|
||||
externalCommands: true
|
||||
filter:
|
||||
velocity:
|
||||
enable: false
|
||||
size: 10
|
||||
trajectory:
|
||||
enable: false
|
||||
size: 10
|
||||
19
example/slit_matrix/readme.md
Normal file
19
example/slit_matrix/readme.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
## TODO
|
||||
Test with motor record.
|
||||
11
example/slit_matrix/startup.script
Normal file
11
example/slit_matrix/startup.script
Normal 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
|
||||
85
example/slit_matrix/startup.script_ecmc
Normal file
85
example/slit_matrix/startup.script_ecmc
Normal file
@@ -0,0 +1,85 @@
|
||||
#- Configuration scripts
|
||||
require ecmccfg,"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)
|
||||
# Master0
|
||||
# 0 0:0 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
|
||||
# 1 0:1 PREOP + EL9227-5500 <20>berstromschutz 24V DC, 2K., max. 10A (Summe), eins
|
||||
# 2 0:2 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 3 0:3 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 4 0:4 PREOP + EL3204 4K. Ana. Eingang PT100 (RTD)
|
||||
# 5 0:5 PREOP + EL2008 8K. Dig. Ausgang 24V, 0.5A
|
||||
# 6 0:6 PREOP + EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
# 7 0:7 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 8 0:8 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 9 0:9 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 10 0:10 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
#
|
||||
|
||||
# 0:0 - EK1100 EtherCAT coupler
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EK1100"
|
||||
|
||||
# 0:1 - EL9227-5500
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL9227-5500"
|
||||
|
||||
# 0:2 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:3 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:4 - EL3204
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL3204"
|
||||
|
||||
# 0:5 - EL2008
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL2008"
|
||||
|
||||
# 0:6 - EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
${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"
|
||||
|
||||
# 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"
|
||||
|
||||
# 0:9 - EL7041 1Ch Stepper
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
|
||||
|
||||
# 0:10 - EL7041 1Ch Stepper
|
||||
${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()'")
|
||||
85
example/slit_matrix/startup_matrix.script_ecmc
Normal file
85
example/slit_matrix/startup_matrix.script_ecmc
Normal file
@@ -0,0 +1,85 @@
|
||||
#- 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)
|
||||
|
||||
|
||||
#- ############################################################################
|
||||
#- add slaves
|
||||
#- list of slaves (4 axis test motion box)
|
||||
# Master0
|
||||
# 0 0:0 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
|
||||
# 1 0:1 PREOP + EL9227-5500 <20>berstromschutz 24V DC, 2K., max. 10A (Summe), eins
|
||||
# 2 0:2 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 3 0:3 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
# 4 0:4 PREOP + EL3204 4K. Ana. Eingang PT100 (RTD)
|
||||
# 5 0:5 PREOP + EL2008 8K. Dig. Ausgang 24V, 0.5A
|
||||
# 6 0:6 PREOP + EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
# 7 0:7 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 8 0:8 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 9 0:9 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
# 10 0:10 PREOP + EL7041 1Ch. Stepper motor output stage (50V, 5A)
|
||||
#
|
||||
|
||||
# 0:0 - EK1100 EtherCAT coupler
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EK1100"
|
||||
|
||||
# 0:1 - EL9227-5500
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL9227-5500"
|
||||
|
||||
# 0:2 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:3 - EL5042 2Ch BiSS-C Encoder
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL5042"
|
||||
|
||||
# 0:4 - EL3204
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL3204"
|
||||
|
||||
# 0:5 - EL2008
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL2008"
|
||||
|
||||
# 0:6 - EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
${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"
|
||||
|
||||
# 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"
|
||||
|
||||
# 0:9 - EL7041 1Ch Stepper
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL7041-0052"
|
||||
|
||||
# 0:10 - EL7041 1Ch Stepper
|
||||
${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_matrix.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()'")
|
||||
Reference in New Issue
Block a user