ECMC: Open Source Motion Control with EtherCAT Overview

ECMC Open Source Motion Control
Based on the Etherlab open source EtherCAT master (www.etherlab.org)
Anders Sandström
ESS Motion Control and Automation Group
www.europeanspallationsource.se
Outline
What is ECMC
EtherCAT Overview
ECMC Basic Features:
Architecture
Hardware Configuration Tree
Axis, Trajectory, Monitor, Controller, Drive, Encoder
Data links
Configurations
ECMC Advanced Features:
PLC:s
Synchronization
ECMC and EtherCAT data access 
Commands from EPICS records
Motion Interlocks
Distributed Clocks
Acknowledgments
2
ECMC: 
E
ther
C
AT 
M
otion 
C
ontrol
ECMC is an open source motion control module for EPICS environment:
General functionalities:
-
All data accessible in EPICS PVs:
-
Motion
-
EtherCAT
-
ECMC System status
=> 
 
Acquisition and control from EPICS possible
-
PLC functionalities in ECMC by scriptable language:
-
General I/O (Several libs available)
-
Motion control possible (motion library)
-
SDO (Settings in EtherCAT slaves)
-
Oversampling terminals (analogue <=100kHz, digital <=1Mhz)
Motion (with EPICS Motor Record support):
-
Positioning (absolute, relative)
-
Constant speed
-
Referencing sequences
-
Limits, softlimits
Motion (extension to Motor Record)
-
Synchronization axis to axis
-
Synchronisation to external source (timing system)
-
Motion interlocks
-
Triggering, latching positions
3
 
 
Electronics
Mechanics
Motion: Overview
Motion: Control Loops
C
u
r
r
e
n
t
 
C
o
n
t
r
o
l
 
L
o
o
p
:
Needed for both open and closed loop setups (however depends on actuator)
Functionality depends on motor type (phase shift output for commutation)
C
u
r
r
e
n
t
 
i
s
 
r
e
l
a
t
e
d
 
t
o
 
t
o
r
q
u
e
 
v
i
a
 
t
h
e
 
m
o
t
o
r
 
K
T
 
c
o
n
s
t
a
n
t
 
f
o
r
 
r
o
t
a
r
y
 
m
o
t
o
r
s
 
o
r
 
t
o
 
a
 
f
o
r
c
e
 
f
o
r
l
i
n
e
a
r
 
m
o
t
o
r
s
.
Common sample rate range: 10-50kHz
Type: PI controller (maybe filters, observer)
V
e
l
o
c
i
t
y
 
C
o
n
t
r
o
l
 
L
o
o
p
:
Needed for closed loop, sometimes used for open loop (frequency control)
Common sample rate range: 1-10kHz
Type: PI controller
P
o
s
i
t
i
o
n
 
C
o
n
t
r
o
l
 
L
o
o
p
:
Needed for closed loop, sometimes used for open loop (for consistency)
Common sample rate range100-5kHz
Type: P or PI controller (if P the stationary error will be handled by velocity PI)
5
Motion: Control Loops cont.
6
Mech., motor, feedback
Motion: Feed Forward and Trajectory
7
P(ID)
Position
PI(D)
Speed
PI(D)
I (torque)
Process
+
+
Already known changes can be fed forward. The error for the controller
to handle will be less. Scaling of velocity feed forward is made by
setting the drive scale parameters.
Motion: Feed Forward
Target position
Actual position
Position Controller output
Time
Position / Output
Trajectory generator set-point
Feed Forward output (to speed PID)
8
Time
Position / Output
No Feed Forward
Feed Forward
Already known changes can be fed forward to
increase performance.
The error for the controller to handle will be smaller.
Feed Forward handles 
main part of the control
Position controller 
only handles small 
deviations 
EtherCAT: Control
 
Loop
 
Execution
 
Options
9
Act. position
Position setp.
Act. position
Velocity setp.
Act. position
Torque setp.
CSP-Mode
Cyclic Sync. Position
CSV-Mode
Cyclic Sync. Velocity
Control:
Pos.
Velo.
Torque
Control:
Velo.
Torque
- Trajectory gen.
- No control
-Trajectory gen.
-Position cont.
-Trajectory gen.
-Position cont.
-Velocity cont.
Control:
Torque
Amplifier 
Level
Controller: No loops needed
Drive: All control loops
Controller: Position loop
Drive: Velocity and current loop
Controller: Position, velocity loop
Drive: Current loop
CST-Mode
Cyclic Sync. Torque
ECMC: EtherCAT Overview
EtherCAT = 
Ether
net for 
C
ontrol 
A
utomation 
T
echnology
Open fieldbus standard originally developed by Beckhoff GmbH
Maintained by EtherCAT Technology Group (
www.EtherCAT.org
). 
Hardware requirements:
Master: standard computer hardware (NIC)
Slaves: dedicated hardware, EtherCAT Slave Controller (ESC)
Masters: Several commercial and 
open source 
masters available
Slaves: Several 100 manufacturers of slaves (drives, I/O, sensors, robots)
Topologies: Line, Star, Ring
Media: Cat 5 cable, plastic fiber, glass fiber
Supports Distributed Clock (DC) in slaves 
Bandwidth utilization: 80%-97% (100 Mbit/s , Ethernet, Full-Duplex) 
Applications: 
Motion, large or long distance systems, synchronized systems
Cycle times > 50μs (ECMC 1ms)
Linux Controller (Centos)
11
ECMC: Overview
 
PV Access
HMI (CSS, BOB)
EPICS IOC
EtherCAT Terminals
EtherCAT Terminals
EtherCAT Drive
EtherCAT
Igh open source EtherCAT master
 (www.etherlab.org) 
asynPortDriver
Motion Control 
(ECMC) 
ECMC: Architecture
12
Linux Controller
EtherCAT master / User space
EtherCAT
Iocsh conf. cmd:
“ecmcConfigOrDie()”
Kernel
EPICS motor records
EPICS records
EthercatMC
Motor model 3 drv.
ECMC: Real Time Thread Execution
EtherCAT
Axis 1
Axis PLC 1
Axis 2
Axis PLC 2
Axis n
Axis PLC n
PLC 1
PLC 2
PLC n
Read from EC
Write to EC
Sleep 
(next ms)
EtherCAT
Motion
General PLC
ECMC: Axis object
14
Encoder
PID-Control
Monitor
Drive
Axis
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
ECPdoEntry
EC master
EC master
EC master
Axis object executes and links objects:
Encoder 
Trajectory Generation
PID-Controller
Monitor
Drive
Sequences
Homing (different types)
“Cfg.CreateAxis(…)”
Types:
 
Normal
 / Virtual
Optional Axis PLC for syncronization / control (executed in sync with axis object)
Trajectory
Normal
, Virtual
Normal
, Virtual
Normal
, Virtual
Normal
Normal
ECMC: Configuration
All configuration in EPICS startup file:
E
C
M
C
 
c
o
n
f
i
g
u
r
a
t
i
o
n
s
 
(speed, acceleration…..)
T
e
r
m
i
n
a
l
 
c
o
n
f
i
g
u
r
a
t
i
o
n
s
 
(Service Data Object access: 
max current, mode…)
ECMC: Configuration cont.
C
o
n
f
i
g
u
r
a
t
i
o
n
 
i
o
c
s
h
 
c
o
m
m
a
n
d
:
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
c
o
m
m
a
n
d
:
E
x
i
t
s
 
i
f
 
r
e
t
u
r
n
 
c
o
d
e
 
!
=
0
e
c
m
c
C
o
n
f
i
g
 
c
o
m
m
a
n
d
:
A
c
c
e
p
t
s
 
r
e
t
u
r
n
 
c
o
d
e
s
 
!
=
0
R
e
t
u
r
n
s
:
 
0
 
f
o
r
 
s
u
c
c
e
s
s
 
o
r
 
o
t
h
e
r
w
i
s
e
 
e
r
r
o
r
 
c
o
d
e
.
E
x
a
m
p
l
e
 
1
:
 
C
r
e
a
t
e
 
A
x
i
s
 
1
 
o
b
j
e
c
t
:
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
C
f
g
.
C
r
e
a
t
e
D
e
f
a
u
l
t
A
x
i
s
(
1
)
E
x
a
m
p
l
e
 
2
:
 
S
e
t
 
p
o
s
i
t
i
o
n
 
c
o
n
t
r
o
l
l
e
r
 
g
a
i
n
 
f
o
r
 
a
x
i
s
 
1
 
t
o
 
0
.
1
ecmcConfigOrDie  ”Cfg.SetAxisCntrlKp(1,0.1)”
E
x
a
m
p
l
e
 
3
:
 
R
e
a
d
 
m
a
x
 
c
u
r
r
e
n
t
 
o
f
 
E
L
7
0
4
1
 
d
r
i
v
e
 
a
t
 
b
u
s
 
p
o
s
i
t
i
o
n
 
1
:
ecmcConfig  ”EcReadSdo(1,0x8010,0x1)”
16
Terminal Configurations
 (SDO)
A
c
c
e
s
s
 
t
o
 
t
e
r
m
i
n
a
l
 
s
p
e
c
i
f
i
c
 
s
e
t
t
i
n
g
s
 
i
s
 
o
v
e
r
 
S
D
O
 
a
c
c
e
s
s
:
-
E
c
A
d
d
S
d
o
(
)
 
w
r
i
t
e
 
a
n
d
 
v
e
r
i
f
y
 
S
D
O
 
(
W
r
i
t
t
e
n
 
a
t
 
 
t
r
a
n
s
i
t
i
o
n
 
P
R
E
O
P
-
>
O
P
)
-
E
c
W
r
i
t
e
S
d
o
(
)
 
w
r
i
t
e
 
d
i
r
e
c
t
l
y
 
S
D
O
 
(
O
n
l
y
 
i
n
 
P
R
E
O
P
)
-
E
c
R
e
a
d
S
d
o
(
)
r
e
a
d
 
d
i
r
e
c
t
l
y
 
S
D
O
 
(
O
n
l
y
 
i
n
 
P
R
E
O
P
)
“Cfg.EcAddSdo(
 
slaveBusPosition,
    
// Slave position on EtherCAT bus
   
sdoIndex,
     
// Sdo index address (see manual for terminal)
   
sdoSubIndex,
    
// Sdo sub index address (see manual for terminal)
   
value,
      
// value to write
   
byteSize 
     
// number of bytes to write
   
)”
 
E
x
a
m
p
l
e
 
1
:
 
S
e
t
 
m
a
x
i
m
u
m
 
c
u
r
r
e
n
t
 
t
o
 
1
0
0
0
m
A
 
o
n
 
E
L
7
0
3
7
 
(
s
l
a
v
e
 
6
)
:
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
 
"
C
f
g
.
E
c
A
d
d
S
d
o
(
6
,
0
x
8
0
1
0
,
0
x
1
,
1
0
0
0
,
2
)
17
ECMC: Configuration with ecmccfg
Configuration is made by adding commands to the ioc startup file.
In order to simplify, a configuration framework called ecmccfg have been
developed (originally at PSI):
Main repo: 
https://github.com/paulscherrerinstitute/ecmccfg
Local fork: 
https://github.com/icshwi/ecmccfg
.
ecmccfg contains:
Hardware configuration files for:
EtherCAT slaves
Motors, encoders, and sensors
Default database files
Extensive set of examples for different hardware's and applications
ecmccfg will be presented in detail in a separate presentation by Niko
18
Part 2 Advanced 
Based on the Etherlab open source EtherCAT master (www.etherlab.org)
Anders Sandström
ESS Motion Control and Automation Group
www.europeanspallationsource.se
Outline
PLC:s
Synchronization
ECMC and EtherCAT data access 
Commands from EPICS records
Motion Interlocks
Distributed Clocks
20
PLCs
1.
PLC functionality can be added by PLC objects
2.
P
L
C
 
s
o
u
r
c
e
 
f
i
l
e
s
 
c
a
n
 
b
e
 
t
r
a
n
s
f
e
r
r
e
d
 
a
n
d
 
e
x
e
c
u
t
e
d
 
i
n
 
t
h
e
 
P
L
C
 
o
b
j
e
c
t
.
 
S
y
n
t
a
x
 
b
a
s
e
d
 
o
n
 
e
x
p
r
t
k
p
a
r
s
e
r
 
(
h
o
w
e
v
e
r
 
e
x
t
e
n
d
e
d
 
w
i
t
h
 
m
a
n
y
 
a
d
d
i
t
i
o
n
a
l
 
f
e
a
t
u
r
e
s
)
3.
PLC objects can execute in custom frequencies.
4.
Accessible Variables:
1.
EtherCAT pdo entries: ec<id>.s<id>.alias:  
 
ec0.s1.POSITION
2.
Motion data: ax<id>.<obj>.<data>  
  
ax1.enc.actpos
3.
PLC variables: plc<id>.<data>  
  
plc0.error
4.
Local variables: var <any name> 
  
var errorCode
5.
Static variables: static.<any name>    
  
static.cycleCounter
6.
Global variables: global.<any name> 
  
global.scaleFactor
5.
Accessible functions:
1.
Expr tk functions: 
 
math (sin,cos,ln,…), println,…., see exprtk readme
2.
MC Lib: 
   
Motion functions
3.
DS Lib: 
   
Access to data storages (buffers)
4.
EC Lib: 
   
Bit functions and ec status
6.
Macros can be used in source files (if ecmccfg is used, same syntax as iocsh macros):
E
x
a
m
p
l
e
:
 
 
$
(
D
B
G
=
#
)
,
$
(
A
X
I
S
_
I
D
=
1
)
 
,
 
$
{
P
L
C
_
I
D
=
1
}
21
PLCs: Simple Example Code:
if(plc0.firstscan){       
       
# Initiations
  plc3.enable:=0;                                  
    
# Block other plc
  ax1.blockcom:=1;                                           
   
# Block Epics Communication for axis 1
  $(DBG=”#”)println('Startup seq. PLC0 starting!’);       
  
# Print Diagnostics if DBG is set to””
};
var blink_cycles:=1/plc0.scantime;                      
   
# Local variable (losses value between cycles)
var warning_light:=ec0.s2.OUPIN_4.0;
ec0.s2.BO_8:=ec0.s1.BI_1 and ax1.enc.actpos>0;  # Set output
static.counter+=1;                                                
   
# Static variable (keeps value between cycles)
if(static.counter>=blink_cycles)
{
  warning_light:=not(warning_light);
  static.counter:=0;
  plc0.error:=123;                                                    
   
# PLC error code
};
global.test:=warning_light;                                    
   
# global.test is accessible in all PLC objects
ec0.s2.BO_4.0:= warning_light;
      
# Output will flash in 1Hz
# This is a comment
return []
         
# Returns
$(DBG=”#”)
println(‘Never here!!!’);
     
# Will never execute since return before
22
PLCs: Variables
 
23
 
 
1
.
 
 
s
t
a
t
i
c
.
<
v
a
r
n
a
m
e
>
 
 
 
 
 
 
 
 
 
 
S
t
a
t
i
c
 
v
a
r
i
a
b
l
e
.
 
I
n
i
t
i
a
t
e
d
 
t
o
 
0
.
 
(
r
w
)
                                    
   
Access only in the PLC where defined.
                                    
   
Will keep value between execution loops.
Example: static.cycleCounter+=1;   
 
# Add one each execution
 
 
 
2
.
 
 
g
l
o
b
a
l
.
<
v
a
r
n
a
m
e
>
 
 
 
 
 
 
 
 
 
 
 
 
 
G
l
o
b
a
l
 
v
a
r
i
a
b
l
e
.
 
I
n
i
t
i
a
t
e
d
 
t
o
 
0
.
 
(
r
w
)
                                    
   
Access from all PLCs.
                                    
   
Will keep value between execution loops.
Example: global.enableAll:=1;   
 
# Global var set to 1
 
 
 
3
.
 
 
v
a
r
 
<
v
a
r
n
a
m
e
>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
L
o
c
a
l
 
v
a
r
i
a
b
l
e
 
(
e
x
p
r
t
k
 
s
y
n
t
a
x
)
 
 
 
(
r
w
)
                                    
   
Will NOT keep value between execution loops.
Example: var errorCode:=100;   
 
# Local var set to 100
PLCs: PLC
 
24
P
L
C
 
v
a
r
i
a
b
l
e
s
:
 1.  plc<id>.enable               
  
plc enable                       
    
(rw)
                                   
  
(end exe with "plc<id>.enable:=0"
                                   
  
Could be usefull for startup sequences)
  2.  plc<id>.error                
  
plc error                        
    
(rw)
                                   
  
Will be forwarded to user as controller error.
  3.  plc<id>.scantime             
 
plc sample time in seconds       
   
(ro)
  4.  plc<id>.firstscan           
  
true during first plc scan only  
   
(ro)
     
usefull for initiations of variables
Example: plc1.enable:=0;
  
Disable PLC 1 (stop execution)
PLCs: EtherCAT
 
25
D
i
r
e
c
t
 
a
c
c
e
s
s
 
t
o
 
e
t
h
e
r
c
a
t
 
d
a
t
a
   1.  ec<mid>.s<sid>.<alias>
 
ethetcat data                
    
(rw)
                                    
  
mid:  
 
ethercat master index
                                    
  
sid:   
 
ethercat slave bus position
                                    
  
alias: 
 
entry name as defined in "Cfg.EcAddEntryComplete()
                                    
  
   Example: ec0.s1.POSITION:=100;
 
 # Set ethercat value to 100;
F
u
n
c
t
i
o
n
 
L
i
b
:
 
E
C
1
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
s
e
t
_
b
i
t
(
<
v
a
l
u
e
>
,
 
<
b
i
t
i
n
d
e
x
>
)
;
 
 
 
S
e
t
s
 
b
i
t
 
a
t
 
b
i
t
i
n
d
e
x
 
p
o
s
i
t
i
o
n
 
o
f
 
v
a
l
u
e
.
 
R
e
t
u
r
n
s
 
t
h
e
 
n
e
w
 
v
a
l
u
e
.
2
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
w
r
t
_
b
i
t
(
<
v
a
l
u
e
>
,
 
<
w
r
t
V
a
l
u
e
>
,
<
b
i
t
i
n
d
e
x
>
)
;
 
 
 
W
r
i
t
e
 
w
r
t
v
a
l
u
e
 
t
o
 
b
i
t
 
a
t
 
b
i
t
i
n
d
e
x
 
p
o
s
i
t
i
o
n
 
o
f
 
v
a
l
u
e
.
 
R
e
t
u
r
n
s
 
t
h
e
 
n
e
w
 
v
a
l
u
e
.
3
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
c
l
r
_
b
i
t
(
<
v
a
l
u
e
>
,
 
<
b
i
t
i
n
d
e
x
>
)
;
C
l
e
a
r
s
 
b
i
t
 
a
t
 
b
i
t
i
n
d
e
x
 
p
o
s
i
t
i
o
n
 
o
f
 
v
a
l
u
e
.
 
R
e
t
u
r
n
s
 
t
h
e
 
n
e
w
 
v
a
l
u
e
.
4
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
f
l
p
_
b
i
t
(
<
v
a
l
u
e
>
,
 
<
b
i
t
i
n
d
e
x
>
)
;
 
 
 
 
 
 
F
l
i
p
s
 
b
i
t
 
a
t
 
b
i
t
i
n
d
e
x
 
p
o
s
i
t
i
o
n
 
o
f
 
v
a
l
u
e
.
 
R
e
t
u
r
n
s
 
t
h
e
 
n
e
w
 
v
a
l
u
e
.
5
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
c
h
k
_
b
i
t
(
<
v
a
l
u
e
>
,
 
<
b
i
t
i
n
d
e
x
>
)
;
 
 
 
 
 
 
C
h
e
c
k
s
 
b
i
t
 
a
t
 
b
i
t
i
n
d
e
x
 
p
o
s
i
t
i
o
n
 
o
f
 
v
a
l
u
e
.
 
R
e
t
u
r
n
s
 
t
h
e
 
v
a
l
u
e
 
o
f
 
b
i
t
.
6
.
 
r
e
t
v
a
l
u
e
 
:
=
 
e
c
_
g
e
t
_
e
r
r
(
)
:
 
 
 
 
 
 
R
e
t
u
r
n
s
 
e
r
r
o
r
 
c
o
d
e
 
f
r
o
m
 
l
a
s
t
 
l
i
b
 
c
a
l
l
.
 7.  …. More availble….
Example: ec0.s2.CONTROL:=ec_wrt_bit(ec0.s2.CONTROL,1,5);  # Write 1 to bit 5 of ”ec0.s2.CONTROL”
PLCs: Motion Variables
 
26
V
a
r
i
a
b
l
e
s
 
(
s
t
r
u
c
t
 
o
n
l
y
 
r
e
f
r
e
s
h
e
s
 
o
n
e
 
t
i
m
e
 
p
e
r
 
e
x
e
c
u
t
i
o
n
)
:
1.  ax<id>.id                    
  
axis id                          
   
(ro)
2.  ax<id>.reset                 
  
reset axis error                
 
 
  
(rw)
3.  ax<id>.counter              
  
execution counter                
   
(ro)
4.  ax<id>.error                 
  
error                            
   
(ro)
5
.
 
 
a
x
<
i
d
>
.
e
n
c
.
a
c
t
p
o
s
 
 
 
 
 
 
 
 
 
a
c
t
u
a
l
 
p
o
s
i
t
i
o
n
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
(
r
o
)
,
 
(
r
w
 
i
f
 
a
x
<
i
d
>
.
 
e
n
c
.
s
o
u
r
c
e
 
=
1
)
6
.
 
 
a
x
<
i
d
>
.
e
n
c
.
a
c
t
v
e
l
 
 
 
 
 
 
 
a
c
t
u
a
l
 
v
e
l
o
c
i
t
y
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
(
r
o
)
7
.
 
 
a
x
<
i
d
>
.
e
n
c
.
r
a
w
p
o
s
 
 
 
 
 
 
a
c
t
u
a
l
 
r
a
w
 
p
o
s
i
t
i
o
n
 
 
 
 
 
 
 
 
 
 
 
 
 
 
(
r
o
)
8.  ax<id>.enc.source       
  
internal source or expressions   
  
(ro)
                                   
   
source = 0: internal encoder
                                   
   
source > 0: actual pos from plc
9.  ax<id>.enc.homed      
  
encoder homed                    
   
(rw)
10. ax<id>.enc.homepos   
  
homing position                  
   
(rw)
11. ax<id>.traj.setpos       
  
current trajectory setpoint       
  
(ro), (rw if ax<id>.traj.source =1)
12. ax<id>.traj.targetpos        
 
target position                  
   
(rw)
1
3
.
 
a
x
<
i
d
>
.
t
r
a
j
.
t
a
r
g
e
t
v
e
l
 
 
 
 
 
 
 
 
t
a
r
g
e
t
 
v
e
l
o
c
i
t
y
 
s
e
t
p
o
i
n
t
 
 
 
 
 
 
 
 
 
(
r
w
)
14. ax<id>.traj.targetacc        
 
target acceleration setpoint     
  
(rw)
15. ax<id>.traj.targetdec        
 
target deceleration setpoint     
  
(rw)
16. ax<id>.traj.setvel           
  
current velocity setpoint        
  
(ro)
17. ax<id>.traj.setvelffraw      
 
feed forward raw velocity        
  
(ro)
18. ax<id>.traj.command          
 
command                          
   
(rw)
                                  
   
command=1: move velocity
                                  
   
command=2: move rel. pos
                                   
   
command=3: move abs. pos
                                   
   
command=10: homing
19. ax<id>.traj.cmddata          
 
cmddata Homing procedure
   
(rw)
                                  
   
only valid if ax<id>.traj.command=10
                                  
   
cmddata=1 : ref low limit
                                   
   
cmddata=2 : ref high limit
                                   
   
cmddata=3 : ref home sensor (via low limit)
   
                         
 
cmddata=4 : ref home sensor (via high limit)
                                   
   
cmddata=5 : ref center of home sensor (via low limit)
                                   
   
cmddata=6 : ref center of home sensor (via high limit)
                                   
   
cmddata=15 : direct homing
                                   
   
cmddata=21 : ref partly abs. Encoder (via low limit). ref at abs bits over/under-flow..
                                   
   
cmddata=22 : ref partly abs. Encoder (via high limit).  ref at abs bits over/under-flow..
PLCs: Motion Variables Cont.
 
27
  20. ax<id>.traj.source           
 
internal source or expressions   
  
(ro)
                                   
   
source = 0: internal traj
                                   
   
source > 0: setpoints from plc
  21. ax<id>.traj.execute          
 
execute motion command           
  
(rw)
  22. ax<id>.traj.busy             
 
axis busy                        
   
(ro)
  23. ax<id>.traj.dir              
  
axis setpoint direction          
   
(ro)
                                   
   
ax<id>.traj.dir>0: forward
                                   
   
ax<id>.traj.dir<0: backward
                                   
   
ax<id>.traj.dir=0: standstill
  24. ax<id>.cntrl.error           
 
actual controller error          
   
(ro)
  25. ax<id>.cntrl.poserror        
 
actual position error            
   
(ro)
  26. ax<id>.cntrl.output          
 
actual controller output        
   
(ro)
  27. ax<id>.drv.setvelraw         
 
actual raw velocity setpoint     
  
(ro)
  28. ax<id>.drv.enable            
 
enable drive command             
  
(rw)
  29. ax<id>.drv.enabled           
 
drive enabled                    
   
(ro)
  30. ax<id>.seq.state             
 
sequence state (homing)          
  
(ro)
  31. ax<id>.mon.ilock             
 
motion interlock                 
   
(rw)
                                   
   
ax<id>.mon.ilock=1: motion allowed
                                   
   
ax<id>.mon.ilock=0: motion not allowed
  32. ax<id>.mon.attarget          
 
axis at taget                    
   
(ro)
  33. ax<id>.mon.lowlim            
 
low limit switch                 
   
(ro)
  34. ax<id>.mon.highlim           
 
high limit switch                
   
(ro)
  35. ax<id>.mon.homesensor        
 
home sensor                      
   
(ro)
  36. ax<id>.mon.lowsoftlim        
 
low soft limit                   
   
(rw)
  37. ax<id>.mon.highsoftlim       
 
high soft limit                  
   
(rw)
  38. ax<id>.mon.lowsoftlimenable  
 
low soft limit enable            
   
(rw)
  39. ax<id>.mon.highsoftlimenable 
 
high soft limit enable           
   
(rw)
  40. ax<id>.blockcom              
 
enables/disables "set" commands   
  
(rw)
                                   
  
via command parser (ascii commands)
                                   
  
Statuses can still be read.
                                   
  
Exceptions ("set"-commands) that will work:
  
                                   
 
- "StopMotion(axid)"
                                  
   
- "Cfg.SetAxisBlockCom(axid,block)"
PLCs: Motion Lib Functions
 
28
F
u
n
c
t
i
o
n
 
L
i
b
:
 
M
C
1
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
m
o
v
e
_
a
b
s
(
<
a
x
I
n
d
e
x
>
,
 
<
e
x
e
c
u
t
e
>
,
 
<
p
o
s
>
,
 
<
v
e
l
>
,
 
<
a
c
c
>
,
 
<
d
e
c
>
)
;
 
A
b
s
o
l
u
t
e
 
m
o
t
i
o
n
 
o
f
 
a
x
i
s
.
      
          
Motion is triggerd with a positive edge on <execute> input.
     
          
returns 0 if success or error code.
2
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
m
o
v
e
_
r
e
l
(
<
a
x
I
n
d
e
x
>
,
 
<
e
x
e
c
u
t
e
>
,
 
<
p
o
s
>
,
 
<
v
e
l
>
,
 
<
a
c
c
>
,
 
<
d
e
c
>
)
;
R
e
l
a
t
i
v
e
 
m
o
t
i
o
n
 
o
f
 
a
x
i
s
 
<
a
x
I
n
d
e
x
>
.
      
          
Motion is triggerd with a positive edge on <execute> input.
      
          
returns 0 if success or error code.
3
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
m
o
v
e
_
v
e
l
(
<
a
x
I
n
d
e
x
>
,
 
<
e
x
e
c
u
t
e
>
,
 
<
v
e
l
>
,
 
<
a
c
c
>
,
 
<
d
e
c
>
)
;
 
 
 
 
 
C
o
n
s
t
a
n
t
 
v
e
l
o
c
i
t
y
 
m
o
t
i
o
n
 
o
f
 
a
x
i
s
 
<
a
x
I
n
d
e
x
>
.
 
 
 
 
 
 
M
o
t
i
o
n
 
i
s
 
t
r
i
g
g
e
r
d
 
w
i
t
h
 
a
 
p
o
s
i
t
i
v
e
 
e
d
g
e
 
o
n
 
<
e
x
e
c
u
t
e
>
 
i
n
p
u
t
.
 
 
 
 
 
 
r
e
t
u
r
n
s
 
0
 
i
f
 
s
u
c
c
e
s
s
 
o
r
 
e
r
r
o
r
 
c
o
d
e
.
4
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
h
o
m
e
(
<
a
x
I
n
d
e
x
>
,
 
<
e
x
e
c
u
t
e
>
,
 
<
s
e
q
I
d
>
,
 
<
v
e
l
T
w
o
a
r
d
s
C
a
m
>
,
 
<
v
e
l
O
f
f
C
a
m
>
)
;
P
e
r
f
o
r
m
 
a
 
h
o
m
i
n
g
 
s
e
q
u
e
n
c
e
 
o
f
 
a
x
i
s
 
<
a
x
I
n
d
e
x
>
.
      
          
Motion is triggerd with a positive edge on <execute> input.
      
          
returns 0 if success or error code.
5
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
h
a
l
t
(
<
a
x
I
n
d
e
x
>
,
 
<
e
x
e
c
u
t
e
>
)
;
 
 
 
 
 
 
S
t
o
p
 
m
o
t
i
o
n
 
o
f
 
a
x
i
s
 
<
a
x
I
n
d
e
x
>
.
      
          
returns 0 if success or error code.
      
          
6
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
p
o
w
e
r
(
<
a
x
I
n
d
e
x
>
,
 
<
e
n
a
b
l
e
>
)
;
 
 
 
 
 
 
E
n
a
b
l
e
 
p
o
w
e
r
 
o
f
 
 
a
x
i
s
 
<
a
x
I
n
d
e
x
>
.
 
 
 
 
 
 
r
e
t
u
r
n
s
 
0
 
i
f
 
s
u
c
c
e
s
s
 
o
r
 
e
r
r
o
r
 
c
o
d
e
.
7
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
g
e
t
_
b
u
s
y
(
<
 
a
x
I
n
d
e
x
 
>
)
;
r
e
t
u
r
n
s
 
b
u
s
y
 
s
t
a
t
e
 
o
f
 
a
x
i
s
 
<
a
x
i
s
i
n
d
e
x
>
8
.
 
r
e
t
v
a
l
u
e
 
:
=
 
m
c
_
g
e
t
_
h
o
m
e
d
(
<
a
x
I
n
d
e
x
>
)
;
r
e
t
u
r
n
s
 
h
o
m
e
d
 
s
t
a
t
e
 
o
f
 
a
x
i
s
 
<
a
x
i
s
i
n
d
e
x
>
      
          
9
.
 
r
e
t
v
a
l
u
e
 
=
 
m
c
_
g
e
t
_
e
r
r
(
)
;
R
e
t
u
r
n
s
 
e
r
r
o
r
 
c
o
d
e
 
f
o
r
 
l
a
s
t
 
l
i
b
 
c
a
l
l
.
E
x
a
m
p
l
e
:
r
e
t
v
a
l
u
e
:
=
m
c
_
p
o
w
e
r
(
2
,
1
)
;
 
 
#
 
S
e
t
 
p
o
w
e
r
 
o
n
 
a
m
p
l
i
f
i
e
r
 
o
f
 
a
x
i
s
 
2
PLCs: General ECMC commands
 
29
C
r
e
a
t
e
 
a
 
n
e
w
 
P
L
C
:
 
"Cfg.CreatePLC(<plcindex>,<rate_ms>)”
L
o
a
d
 
P
L
C
 
c
o
d
e
 
t
e
x
t
 
f
i
l
e
 
 
(
a
n
d
 
c
o
m
p
i
l
e
 
a
n
d
 
e
n
a
b
l
e
)
:
 
"Cfg.LoadPLCFile(<plcIndex>,<filename>)"
A
d
d
 
c
o
d
e
 
l
i
n
e
 
b
y
 
l
i
n
e
:
 
"Cfg.AppendPLCExpr(<plcIndex>)=  <code>”
C
o
m
p
i
l
e
 
P
L
C
 
c
o
d
e
:
 
"Cfg.CompilePLC(<plcindex>)"
E
n
a
b
l
e
/
D
i
s
a
b
l
e
 
P
L
C
:
 
"Cfg.SetPLCEnable(<plcindex>,<enable>)"
PLCs: Motion Example Code:
 
30
if(static.seqStep==1)
       
 # State 1. Put power on axis (run mc_power())
{
  if(not(ax1.error))
  {
 
 
 
 
e
r
r
o
r
C
o
d
e
=
m
c
_
p
o
w
e
r
(
1
,
1
)
;
#
 
P
u
t
 
p
o
w
e
r
 
o
n
 
a
x
i
s
 
1
    if(errorCode)
    {
      println('Function mc_power() returned error: ', errorCode);
   
# Printout in iocsh window
      plc3.error:=errorCode;
       
# Error code
    };
  }
  else
  {
 
 
 
 
m
c
_
r
e
s
e
t
(
1
)
;
#
 
R
e
s
e
t
 
e
r
r
o
r
 
o
n
 
a
x
i
s
 
1
  };
  if(ax1.drv.enabled){
    static.seqStep:=2;
       
# Start homing if enabled
    println('2. Function mc_home()  triggered!');
  };
};
if(static.seqStep==2) 
       
 # State 2. Do homing sequence (run mc_home())
{
  var homingSeq:=3;
  var velTwoardsCam:=5;
  var velOffCam:=4;
 
 
e
r
r
o
r
C
o
d
e
=
m
c
_
h
o
m
e
(
1
,
1
,
h
o
m
i
n
g
S
e
q
,
v
e
l
T
w
o
a
r
d
s
C
a
m
,
v
e
l
O
f
f
C
a
m
)
;
#
 
H
o
m
e
 
a
x
i
s
 
1
  if(errorCode){
    println('Function mc_home() returned error: ', errorCode);
    plc3.error:=errorCode;
  };
 
 
i
f
(
m
c
_
g
e
t
_
h
o
m
e
d
(
1
)
 
a
n
d
 
n
o
t
(
m
c
_
g
e
t
_
b
u
s
y
(
1
)
)
)
#
 
H
o
m
i
n
g
 
r
e
a
d
y
?
.
.
  {
    static.seqStep:=3;
    println('3. Function mc_move_abs() triggered!');
  };
};
Synchronization
Normal axis:
Controller
Drive
Trajectory
Encoders
Monitor
Virtual axis:
Trajectory
Encoder
Monitor
Synchronization is handled through PLCs objects.
Each axis object have a dedicated “Axis PLC”-object that is
executed just before the axis object.
Axis PLC objects behave exactly as normal PLC objects.
Any Axis PLC or Normal PLC object can be used for
synchronization (or other PLC code).
ECMC: Synchronization
Synchronization of axes is handled by a axis synchronous PLC:
-
ax<id>.traj.setpos 
 
= 
 
Trajectory generated setpoint for axis <id>
-
ax<id>.enc.actpos
 
= 
 
Actual position of axis <id>
-
ax<id>.drv.enable
 
=
 
Enable amplifier of axis <id>
-
ax<id>.mon.ilock
  
=
 
Motion interlock of axis <id> (allowed to move if 1)
-
ax<id>.mon.ilockfwd
 
=
 
Motion interlock of axis fwd <id> (allowed to move if 1)
-
ax<id>.mon.ilockfwd
 
=
 
Motion interlock of axis bwd <id> (allowed to move if 1)
-
….. Any plc expression can be entered.
Axis PLCs are recalculated / refreshed in 1kHz
Examples
:
Slaving: 
    
ax2.traj.setpos := ax1.
enc
.actpos;
Synchronization: 
   
ax2.traj.setpos := ax1.
traj
.setpos;
Gearing:
    
ax2.traj.setpos := 0.5 * ax1.traj.setpos;
Phasing:
    
ax3.traj.setpos := ax1.traj.setpos + ax2.traj.setpos;
Advanced:
    
ax1.traj.setpos := 10*sin(ax2.traj.setpos + ec0.s3.VALUE);
Timing system:
   
ax1.traj.setpos := ec0.s3.VALUE * 0.5 + ec0.s4.AO_1;
Interlocks: 
    
ax1.mon.ilock  
:=
 ax2.mon.ilock 
and 
ax5.mon.ilock
 and 
    
     
ax4.enc.actpos > ax3.enc.actpos;
Enable:
    
ax2.drv.enable := ax1.drv.enable;
Enable alternative:
  
mc_power(1,ax1.drv.enable);
32
Application: 2-Axes Slit Set
2 virtual axes
-
Slit center position
-
Slit gap/opening
2 normal axes (blade positions)
Forward Kinematics:
ax3.traj.setpos
:=
ax1.traj.setpos 
-
 ax2.traj.setpos
/2;
ax4.traj.setpos
:=
ax1.traj.setpos 
+ 
ax2.traj.setpos
/2;
Inverse Kinematics:
ax1.enc.actpos
:=(
ax3.enc.actpos
+
ax4.enc.actpos 
)/2;
ax2.enc.actpos
:=(
ax4.enc.actpos 
 ax3.enc.actpos
);
Amplifier enable:
ax3.drv.enable:=ax1.drv.enable or ax2.drv.enable;
ax4.drv.enable:=ax1.drv.enable or ax2.drv.enable;
Or:
mc_power(3, ax1.drv.enable or ax2.drv.enable);
mc_power(4, ax1.drv.enable or ax2.drv.enable);
Blade
Axis
3
Blade
Axis
4
Axis 4 (Normal: Blade position)
Axis 
3
 (Normal: Blade position)
Axis 
1
 (Virt: Center position)
Axis 
2
 (Virt: Gap)
33
Application: 2-Axes Slit Set, External Sync.
Axis 4 Right blade
Axis 1 (Centre)
Axis 2 (Gap)
Axis 3 Left blade
34
2 virtual axes:
-
External timing system (function generator)
-
Amplitude
§
2 virtual axes:
-
External timing system (function generator)
-
Amplitude
§
2 virtual axes:
-
External timing system (function generator)
-
Amplitude
§
2 virtual axes:
-
External timing system (function generator)
-
Amplitude
§
Add 2 virtual axes
-
Timing system (Signal Generator connected to EL5101)
-
Amplitude
Old syntax..
Application: 2-Axes Slit Set, External
Sync.
 
Axis 4
Axis 1 (Centre)
Axis 2 (Gap)
Axis 3
Old syntax..
ECMC data access over Asyn:
Note
: ECMC data are transferred to EPICS records by default if ecmccfg is used but can also be customized.
Data in ECMC can be exposed to EPICS records over Asyn framework (“I/O Intr”):
EtherCAT:
-
EtherCAT entries (also waveforms for oversampling cards)
-
EtherCAT slave diagnostics
-
EtherCAT master diagnostics
Diagnostics:
-
Motion thread time jitter
Motion Axis:
-
Trajectory generated setpoint
-
Actual position
-
Following error
-
Diagnostic string (containing most info of axis)
PLC vatriables
Available data can be listed with the iocsh command ”ecmcReport <detail>”
ecmcReport 0 : Display basic information
ecmcReport 1 : Display all parameters that are linked to records
ecmcReport 2 : Display all available parameters (that can be accessed)
Note
: “asynReport” can be used in the same way but will also list information from other loaded asyn modules like
EthercatMC
36
ECMC data access over Asyn: EtherCAT
R
e
c
o
r
d
 
I
N
P
/
O
U
T
P
 
f
i
e
l
d
 
s
y
n
t
a
x
:
"
@
a
s
y
n
(
<
a
s
y
n
P
o
r
t
>
,
<
a
d
d
r
e
s
s
>
,
<
t
i
m
e
o
u
t
>
)
e
c
m
c
I
n
f
o
S
t
r
)
e
c
m
c
I
n
f
o
S
t
r
:
C
M
D
=
<
c
m
d
>
/
T
_
S
M
P
_
M
S
=
<
s
a
m
p
l
e
t
i
m
e
>
/
T
Y
P
E
=
<
t
y
p
e
>
/
<
p
a
r
a
m
e
t
e
r
 
n
a
m
e
>
<
r
e
a
d
/
w
r
i
t
e
>
"
1.
C
M
D
 
(
o
p
t
i
o
n
a
l
)
:
1.
“UINT64TOFLOAT64”:
  
Converts 64bit uint data to float64 before push to EPICS (64 bit positions and time)
2.
“FLOAT64TOINT32”:
  
Converts float 64 to int32  before push to epics (binary PLC values)
2.
T
_
S
M
P
_
M
S
 
(
o
p
t
i
o
n
a
l
)
:
 
R
e
c
o
r
d
 
u
p
d
a
t
e
 
r
a
t
e
 
i
n
 
m
i
l
l
i
s
e
c
o
n
d
s
3.
T
Y
P
E
 
(
m
a
n
d
a
t
o
r
y
)
:
 
T
y
p
e
 
o
f
 
d
a
t
a
 
t
o
 
t
r
a
n
s
f
e
r
 
(
a
s
y
n
I
n
t
3
2
,
 
a
s
y
n
F
l
o
a
t
6
4
,
 
a
s
y
n
I
n
t
3
2
A
r
r
a
y
I
n
.
.
)
4.
<
p
a
r
a
m
e
t
e
r
 
n
a
m
e
>
 
(
m
a
n
d
a
t
o
r
y
)
:
Example for Ec data: 
  
“ec<master index>.s<slave index>.<data alias>”
Use “ecmcReport 3” to see available parameter names
5.
<
r
e
a
d
/
w
r
i
t
e
>
 
(
m
a
n
d
a
t
o
r
y
)
 
read  
  
“?”
 
write 
 
 
 
“=”
37
ECMC data access over Asyn: Example
Example
 of analog input EL3002:
master=0, slave=2, data alias = “CH1_VALUE”, T_SMP_MS=1:
Record definition:
record(ai,”IOC:ec0-s2-EL3002-AI1")
{
 
field(INP,
 
"@asyn(
TEST
,0,1)
T_SMP_MS=1/TYPE=asynInt32/ec0.s2.CH1_VALUE?
")
 
field(DTYP, 
 
"
asynInt32
")
 
field(SCAN, 
 
"I/O Intr")
 
………
 
…..
}
38
Example: Temperature
Analog Data Acquisition:
Example: Motor temperature (PT100 or similar)
Data accessible through EPICS PV (AI record)
Update EPICS PV on change
Resolution 0,1
º
C
 
(standard)
39
Temperature Sensor
 (PT100)
Temperature Sensor 
(PT1000)
Stepper
Example: Vibration Analysis
Vibration measurement:
IEPE interface (or normal analog)
Oversampling max 50kHz (other analog 100kHz)
Data accessible through EPICS PV (waveform record)
40
Stepper motor full step freq.
Accelerometer
Stepper
FFT Stepper Motor Vibrations
Analysis in Python (pyepics, scipy, numpy, and matplotlib)
Data Acquisition: Position Data Analysis
Analysis of position error during move:
Data accessible in EPICS PVs (AI records)
Example: Positioning task from 0mm to 50mm
41
*5mm/s , 60mm/rev, 200 steps/rev=> 16.67Hz full step freq
FFT of Position Error
Amplitude [mm]
Frequency [Hz]
Commands from EPICS records:
A
l
l
 
c
o
m
m
a
n
d
s
 
c
a
n
 
b
e
 
e
x
e
c
u
t
e
d
 
f
r
o
m
E
P
I
C
S
 
r
e
c
o
r
d
s
 
u
s
i
n
g
 
s
t
r
e
a
m
 
d
e
v
i
c
e
 
o
r
a
s
y
n
-
r
e
c
o
r
d
.
T
y
p
i
c
a
l
l
y
 
s
e
t
t
i
n
g
s
 
a
n
d
 
c
o
m
m
u
n
i
c
a
t
i
o
n
t
h
a
t
 
a
r
e
 
n
o
t
 
h
a
n
d
l
e
d
 
b
y
 
m
o
t
o
r
 
r
e
c
o
r
d
 
o
r
m
o
d
e
l
 
3
 
d
r
i
v
e
r
 
c
a
n
 
b
e
 
a
p
p
l
i
e
d
 
t
h
r
o
u
g
h
s
t
r
e
a
m
 
d
e
v
i
c
e
 
o
r
 
A
S
Y
N
 
r
e
c
o
r
d
.
E
x
a
m
p
l
e
:
42
Motor
record
Stream
Device
Motion Interlocks
1
.
 
I
n
t
e
r
l
o
c
k
 
b
y
 
I
/
O
:
Any digital EtherCAT entry can be linked to interlock motion
E
x
a
m
p
l
e
:
 
L
i
n
k
 
I
/
O
 
t
o
 
i
n
t
e
r
l
o
c
k
 
a
x
i
s
 
n
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
"
C
f
g
.
L
i
n
k
E
c
E
n
t
r
y
T
o
A
x
i
s
M
o
n
i
t
o
r
(
0
,
I
N
P
U
T
_
7
,
n
,
3
,
0
)
"
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
"
C
f
g
.
S
e
t
A
x
i
s
M
o
n
E
n
a
b
l
e
E
x
t
H
W
I
n
t
e
r
l
o
c
k
(
n
,
1
)
2
.
 
I
n
t
e
r
l
o
c
k
 
b
y
 
I
/
O
 
i
n
 
m
o
t
i
o
n
 
t
e
r
m
i
n
a
l
:
Inputs of some motion terminals, like Beckhoff Stepper terminals, can be configured to disable
power of amplifier.
E
x
a
m
p
l
e
:
 
H
a
r
d
w
a
r
e
 
e
n
a
b
l
e
 
o
n
 
i
n
p
u
t
 
1
 
o
f
 
E
L
7
0
3
7
 
(
s
l
a
v
e
 
b
u
s
 
p
o
s
i
t
i
o
n
 
m
)
e
c
m
c
C
o
n
f
i
g
O
r
D
i
e
 
"
C
f
g
.
E
c
A
d
d
S
d
o
(
m
,
0
x
8
0
1
2
,
0
x
3
2
,
1
,
1
)
"
3
.
 
I
n
t
e
r
l
o
c
k
s
 
f
r
o
m
 
P
L
C
:
E
x
a
m
p
l
e
:
 
I
n
t
e
r
l
o
c
k
 
a
x
i
s
 
1
 
f
r
o
m
 
p
l
c
:
ax1.mon.ilock:=ax2.enc.actvel<2 and ax4.mon.ilock and ax3.enc.actpos<1000;
4
.
 
S
a
f
e
 
T
o
r
q
u
e
 
O
f
f
:
 
T
h
e
 
d
r
i
v
e
s
 
I
P
O
S
8
0
2
0
 
a
n
d
 
I
P
O
S
4
8
0
8
 
h
a
v
e
 
s
a
f
e
t
y
 
r
a
t
e
d
 
S
T
O
 
i
n
p
u
t
s
 
(
S
I
L
3
/
P
l
e
)
43
Data Storage
Data storage objects is a basically a data buffer/array. Types:
Normal: 
 
Fill from beginning stop when full
Ring: 
  
Fill from beginning start over when full
FIFO:
  
Fill from end. Oldest value are “pushed” out when full
Can be accessed from waveforms from EPICS records (r/w)
Can be accessed from PLCs (r/w)
Useful for:
latching fast data.
Implementation of simple filters
Storing custom trajectories
D
a
t
a
 
S
t
o
r
a
g
e
 
C
o
m
m
a
n
d
s
:
“Cfg.
CreateDataStorage (….)”
“Cfg.
ClearStorage (….)”
“ReadStorageBuffer(….)”
“Cfg.SetStorageEnablePrintouts (….)”
“Cfg.
PrintStorageBuffer (….)”
44
Data Storage: PLC access
 
45
V
a
r
i
a
b
l
e
s
 
(
s
t
r
u
c
t
 
o
n
l
y
 
r
e
f
r
e
s
h
e
s
 
o
n
e
 
t
i
m
e
 
p
e
r
 
e
x
e
c
u
t
i
o
n
)
:
1.
   ds<id>.size
  
Set/get size of data storage  (set will clear the data storage)   
 
(rw)                                    
 
2.
   ds<id>.append            
 
Add new data at end, current position index will be increased
 
(rw)
3.
   ds<id>.data                 
 
Set/get data ar current position 
     
(rw)
4.
   ds<id>.index               
 
Set/get current position index   
     
(rw)
5.
   ds<id>.error               
 
Data storage object error error        
     
(ro)
6.
   ds<id>.clear               
 
Data buffer clear (set to zero)  
     
(ro)
7.
   ds<id>.full                 
 
True if data storage is full     
     
(ro)
F
u
n
c
t
i
o
n
 
L
i
b
:
 
D
S
1.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
a
p
p
e
n
d
_
d
a
t
a
(
<
d
s
I
n
d
e
x
>
,
<
d
a
t
a
>
)
;
 
 
 
A
p
p
e
n
d
 
d
a
t
a
 
t
o
 
d
a
t
a
 
s
t
o
r
a
g
e
2.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
c
l
e
a
r
_
d
a
t
a
(
<
d
s
I
n
d
e
x
>
)
;
 
C
l
e
a
r
 
d
a
t
a
 
t
o
 
d
a
t
a
 
s
t
o
r
a
g
e
.
3.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
d
a
t
a
(
<
d
s
I
n
d
e
x
>
,
 
<
b
u
f
f
e
r
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
d
a
t
a
 
f
r
o
m
 
b
u
f
f
e
r
.
4.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
s
e
t
_
d
a
t
a
(
<
d
s
I
n
d
e
x
>
,
 
<
b
u
f
f
e
r
I
n
d
e
x
>
)
;
 
 
 
 
 
 
S
e
t
s
 
d
a
t
a
 
i
n
 
d
a
t
a
 
s
t
o
r
a
g
e
 
b
u
f
f
e
r
.
5.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
b
u
f
f
_
i
d
(
<
d
s
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
c
u
r
r
e
n
t
 
b
u
f
f
e
r
 
i
n
d
e
x
.
6.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
s
e
t
_
b
u
f
f
_
i
d
(
<
d
s
I
n
d
e
x
>
,
 
<
b
u
f
f
e
r
I
n
d
e
x
>
)
;
S
e
t
s
 
c
u
r
r
e
n
t
 
b
u
f
f
e
r
 
i
n
d
e
x
 
i
n
 
d
a
t
a
 
s
t
o
r
a
g
e
 
b
u
f
f
e
r
.
7.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
i
s
_
f
u
l
l
(
<
d
s
I
n
d
e
x
>
)
;
R
e
t
u
r
n
s
 
t
r
u
e
 
i
f
 
b
u
f
f
e
r
 
i
s
 
f
u
l
l
.
8.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
s
i
z
e
(
<
d
s
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
b
u
f
f
e
r
 
s
i
z
e
 
o
f
 
d
a
t
a
 
s
t
o
r
a
g
e
.
9.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
p
u
s
h
_
a
s
y
n
(
<
d
s
I
n
d
e
x
>
)
;
 
P
u
s
h
 
d
a
t
a
 
s
t
o
r
a
g
e
 
t
o
 
E
P
I
C
S
10.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
a
v
g
(
<
d
s
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
a
v
e
r
a
g
e
 
v
a
l
u
e
 
o
f
 
s
t
o
r
e
d
 
v
a
l
u
e
s
11.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
m
i
n
(
<
d
s
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
m
i
n
 
v
a
l
u
e
 
o
f
 
s
t
o
r
e
d
 
v
a
l
u
e
s
12.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
m
a
x
(
<
d
s
I
n
d
e
x
>
)
;
 
R
e
t
u
r
n
s
 
m
a
x
 
v
a
l
u
e
 
o
f
 
s
t
o
r
e
d
 
v
a
l
u
e
s
13.
r
e
t
v
a
l
u
e
 
:
=
 
d
s
_
g
e
t
_
e
r
r
(
)
;
R
e
t
u
r
n
s
 
e
r
r
o
r
 
c
o
d
e
 
f
o
r
 
l
a
s
t
 
l
i
b
 
c
a
l
l
.
Example:
retvalue := ds_get_avg(1);    # Returns average of all values in buffer (can be used as simple filter). 
 
Distributed Clocks
C
o
m
m
a
n
d
s
:
“Cfg.EcSlaveConfigDC(….)”
 
“Cfg.EcSelectReferenceDC (….)”
 
46
Etherlab EtherCAT tool:
 
47
EtherCAT tool from 
www.etherlab.org
Display master status:
e
t
h
e
r
c
a
t
 
m
a
s
t
e
r
Display slaves and status:
e
t
h
e
r
c
a
t
 
s
l
a
v
e
s
Display available PDOs for slave 3:
e
t
h
e
r
c
a
t
 
p
3
 
p
d
o
s
Display available SDOs for slave 3:
e
t
h
e
r
c
a
t
 
p
3
 
s
d
o
s
Display help:
e
t
h
e
r
c
a
t
 
h
Acknowledgments
Igh open source EtherCAT master (www.etherlab.org)
EPICS community (base, motor, asyn, stream device)
ExprTK C++ Mathematical Expression Library
Questions? 
48
Slide Note
Embed
Share

ECMC is an open-source motion control module designed for EPICS environments, integrating EtherLab's EtherCAT master. It offers advanced features like synchronized motion, distributed clocks, and PLC functionalities, making it ideal for various automation applications. The system architecture and hardware configurations allow for precise motion control and monitoring, with support for various motor control operations and interlocks.

  • Open Source
  • Motion Control
  • EtherCAT
  • Automation
  • EPICS

Uploaded on May 16, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. ECMC Open Source Motion Control Based on the Etherlab open source EtherCAT master (www.etherlab.org) Anders Sandstr m ESS Motion Control and Automation Group www.europeanspallationsource.se

  2. Outline What is ECMC EtherCAT Overview ECMC Basic Features: Architecture Hardware Configuration Tree Axis, Trajectory, Monitor, Controller, Drive, Encoder Data links Configurations ECMC Advanced Features: PLC:s Synchronization ECMC and EtherCAT data access Commands from EPICS records Motion Interlocks Distributed Clocks Acknowledgments 2

  3. ECMC: EtherCAT Motion Control ECMC is an open source motion control module for EPICS environment: General functionalities: - All data accessible in EPICS PVs: - Motion - EtherCAT - ECMC System status => Acquisition and control from EPICS possible - PLC functionalities in ECMC by scriptable language: - General I/O (Several libs available) - Motion control possible (motion library) - SDO (Settings in EtherCAT slaves) - Oversampling terminals (analogue <=100kHz, digital <=1Mhz) Motion (with EPICS Motor Record support): - Positioning (absolute, relative) - Constant speed - Referencing sequences - Limits, softlimits Motion (extension to Motor Record) - Synchronization axis to axis - Synchronisation to external source (timing system) - Motion interlocks - Triggering, latching positions 3

  4. ECMC: EtherCAT Overview EtherCAT = Ethernet for Control Automation Technology Open fieldbus standard originally developed by Beckhoff GmbH Maintained by EtherCAT Technology Group (www.EtherCAT.org). Hardware requirements: Master: standard computer hardware (NIC) Slaves: dedicated hardware, EtherCAT Slave Controller (ESC) Masters: Several commercial and open source masters available Slaves: Several 100 manufacturers of slaves (drives, I/O, sensors, robots) Topologies: Line, Star, Ring Media: Cat 5 cable, plastic fiber, glass fiber Supports Distributed Clock (DC) in slaves Bandwidth utilization: 80%-97% (100 Mbit/s , Ethernet, Full-Duplex) Applications: Motion, large or long distance systems, synchronized systems Cycle times > 50 s (ECMC 1ms)

  5. ECMC: Overview HMI (CSS, BOB) PV Access Linux Controller (Centos) EPICS IOC asynPortDriver Motion Control (ECMC) EtherCAT Igh open source EtherCAT master (www.etherlab.org) EtherCAT Terminals EtherCAT Terminals EtherCAT Drive Analog Analog Digital Digital XXXX XXXX Drive Drive 11

  6. ECMC: Architecture Linux Controller Iocsh conf. cmd: ecmcConfigOrDie() EPICS motor records EPICS records EthercatMC Motor model 3 drv. asynPortDriver Interfaces asynint32 asynfloat64 asynarrayxxx asynoctet command parser ECMC Core Real Time Thread (1kHz) Axis 1 Axis 2 Axis n PLC 1 PLC n EtherCAT process image EtherCAT master / User space Kernel EtherCAT 12

  7. ECMC: Real Time Thread Execution Sleep (next ms) EtherCAT Read from EC Axis PLC 1 Axis 1 Motion Axis PLC 2 Axis 2 Axis PLC n Axis n PLC 1 General PLC PLC 2 PLC n EtherCAT Write to EC

  8. ECMC: Axis object Types: Normal / Virtual Axis Cfg.CreateAxis( ) Encoder Normal, Virtual PID-Control Normal Monitor Normal, Virtual Drive Normal Trajectory Normal, Virtual Optional Axis PLC for syncronization / control (executed in sync with axis object) ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry ECPdoEntry Axis object executes and links objects: Encoder Trajectory Generation PID-Controller Monitor Drive Sequences Homing (different types) EC master EC master EC master 14

  9. ECMC: Configuration ECMC: Configuration All configuration in EPICS startup file: All configuration in EPICS startup file: ECMC configurations (speed, acceleration ..) (speed, acceleration ..) ECMC configurations Terminal configurations (Service Data Object access: max current, mode ) max current, mode ) Terminal configurations (Service Data Object access:

  10. ECMC: Configuration cont. Configuration iocsh command: ecmcConfigOrDie command ecmcConfig command : : Exits if return code !=0 Accepts return codes !=0 Returns: 0 for success or otherwise error code. Example 1: Create Axis 1 object: ecmcConfigOrDie Cfg.CreateDefaultAxis(1) Example 2: Set position controller gain for axis 1 to 0.1 ecmcConfigOrDie Cfg.SetAxisCntrlKp(1,0.1) Example 3: Read max current of EL7041 drive at bus position 1: ecmcConfig EcReadSdo(1,0x8010,0x1) 16

  11. Terminal Configurations (SDO) Access to terminal specific settings is over SDO access: - EcAddSdo() write and verify SDO (Written at transition PREOP->OP) - EcWriteSdo() write directly SDO - EcReadSdo() read directly SDO (Only in PREOP) (Only in PREOP) Cfg.EcAddSdo( slaveBusPosition, sdoIndex, sdoSubIndex, value, byteSize ) // Slave position on EtherCAT bus // Sdo index address (see manual for terminal) // Sdo sub index address (see manual for terminal) // value to write // number of bytes to write Example 1: Set maximum current to 1000mA on EL7037 (slave 6): ecmcConfigOrDie "Cfg.EcAddSdo(6,0x8010,0x1,1000,2) 17

  12. ECMC: Configuration with ecmccfg Configuration is made by adding commands to the ioc startup file. In order to simplify, a configuration framework called ecmccfg have been developed (originally at PSI): Main repo: https://github.com/paulscherrerinstitute/ecmccfg Local fork: https://github.com/icshwi/ecmccfg. ecmccfg contains: Hardware configuration files for: EtherCAT slaves Motors, encoders, and sensors Default database files Extensive set of examples for different hardware's and applications ecmccfg will be presented in detail in a separate presentation by Niko 18

  13. Part 2 Advanced Based on the Etherlab open source EtherCAT master (www.etherlab.org) Anders Sandstr m ESS Motion Control and Automation Group www.europeanspallationsource.se

  14. Outline PLC:s Synchronization ECMC and EtherCAT data access Commands from EPICS records Motion Interlocks Distributed Clocks 20

  15. PLCs Execution flow: 1. PLC functionality can be added by PLC objects 2. PLC source files can be transferred and executed in the PLC object. Syntax based on exprtk parser (however extended with many additional features) 3. PLC objects can execute in custom frequencies. Read from EC 4. Accessible Variables: 1. EtherCAT pdo entries: ec<id>.s<id>.alias: ec0.s1.POSITION Axis PLC 1 2. Motion data: ax<id>.<obj>.<data> ax1.enc.actpos Axis 1 3. PLC variables: plc<id>.<data> plc0.error Axis PLC 2 4. Local variables: var <any name> var errorCode Axis 2 5. Static variables: static.<any name> static.cycleCounter Axis PLC n 6. Global variables: global.<any name> global.scaleFactor Axis n 5. Accessible functions: 1. Expr tk functions: math (sin,cos,ln, ), println, ., see exprtk readme PLC 1 2. MC Lib: Motion functions PLC 2 3. DS Lib: Access to data storages (buffers) PLC n 4. EC Lib: Bit functions and ec status 6. Macros can be used in source files (if ecmccfg is used, same syntax as iocsh macros): Write to EC Example: $(DBG= # ), $(AXIS_ID= 1 ) , ${PLC_ID= 1 } 21

  16. PLCs: Simple Example Code: if(plc0.firstscan){ plc3.enable:=0; ax1.blockcom:=1; $(DBG= # )println('Startup seq. PLC0 starting! ); }; # Initiations # Block other plc # Block Epics Communication for axis 1 # Print Diagnostics if DBG is set to var blink_cycles:=1/plc0.scantime; var warning_light:=ec0.s2.OUPIN_4.0; ec0.s2.BO_8:=ec0.s1.BI_1 and ax1.enc.actpos>0; # Set output static.counter+=1; # Local variable (losses value between cycles) # Static variable (keeps value between cycles) if(static.counter>=blink_cycles) { warning_light:=not(warning_light); static.counter:=0; plc0.error:=123; }; # PLC error code global.test:=warning_light; ec0.s2.BO_4.0:= warning_light; # global.test is accessible in all PLC objects # Output will flash in 1Hz # This is a comment return [] $(DBG= # )println( Never here!!! ); # Returns # Will never execute since return before 22

  17. PLCs: Variables Static variable. Initiated to 0. Access only in the PLC where defined. Will keep value between execution loops. (rw) 1. static.<varname> Example: static.cycleCounter+=1; # Add one each execution Global variable. Initiated to 0. Access from all PLCs. Will keep value between execution loops. (rw) 2. global.<varname> Example: global.enableAll:=1; # Global var set to 1 Local variable (exprtk syntax) Will NOT keep value between execution loops. (rw) 3. var <varname> Example: var errorCode:=100; # Local var set to 100 23

  18. PLCs: PLC PLC variables: 1. plc<id>.enable plc enable (end exe with "plc<id>.enable:=0" Could be usefull for startup sequences) plc error Will be forwarded to user as controller error. plc sample time in seconds true during first plc scan only usefull for initiations of variables (rw) 2. plc<id>.error (rw) 3. plc<id>.scantime 4. plc<id>.firstscan (ro) (ro) Example: plc1.enable:=0; Disable PLC 1 (stop execution) 24

  19. PLCs: EtherCAT Direct access to ethercat data 1. ec<mid>.s<sid>.<alias> ethetcat data mid: sid: alias: entry name as defined in "Cfg.EcAddEntryComplete() (rw) ethercat master index ethercat slave bus position Example: ec0.s1.POSITION:=100; # Set ethercat value to 100; Function Lib: EC 1. retvalue := ec_set_bit(<value>, <bitindex>); Sets bit at bitindex position of value. Returns the new value. 2. retvalue := ec_wrt_bit(<value>, <wrtValue>,<bitindex>); Write wrtvalue to bit at bitindex position of value. Returns the new value. 3. retvalue := ec_clr_bit(<value>, <bitindex>); Clears bit at bitindex position of value. Returns the new value. 4. retvalue := ec_flp_bit(<value>, <bitindex>); Flips bit at bitindex position of value. Returns the new value. 5. retvalue := ec_chk_bit(<value>, <bitindex>); Checks bit at bitindex position of value. Returns the value of bit. 6. retvalue := ec_get_err(): Returns error code from last lib call. 7. . More availble . Example: ec0.s2.CONTROL:=ec_wrt_bit(ec0.s2.CONTROL,1,5); # Write 1 to bit 5 of ec0.s2.CONTROL 25

  20. PLCs: Motion Variables Variables (struct only refreshes one time per execution): 1. ax<id>.id 2. ax<id>.reset 3. ax<id>.counter 4. ax<id>.error 5. ax<id>.enc.actpos 6. ax<id>.enc.actvel 7. ax<id>.enc.rawpos 8. ax<id>.enc.source axis id reset axis error execution counter error actual position actual velocity actual raw position internal source or expressions source = 0: internal encoder source > 0: actual pos from plc encoder homed homing position current trajectory setpoint target position target velocity setpoint target acceleration setpoint target deceleration setpoint current velocity setpoint feed forward raw velocity command command=1: move velocity command=2: move rel. pos command=3: move abs. pos command=10: homing cmddata Homing procedure only valid if ax<id>.traj.command=10 cmddata=1 : ref low limit cmddata=2 : ref high limit cmddata=3 : ref home sensor (via low limit) cmddata=4 : ref home sensor (via high limit) cmddata=5 : ref center of home sensor (via low limit) cmddata=6 : ref center of home sensor (via high limit) cmddata=15 : direct homing cmddata=21 : ref partly abs. Encoder (via low limit). ref at abs bits over/under-flow.. cmddata=22 : ref partly abs. Encoder (via high limit). ref at abs bits over/under-flow.. (ro) (rw) (ro) (ro) (ro), (rw if ax<id>. enc.source =1) (ro) (ro) (ro) 9. ax<id>.enc.homed 10. ax<id>.enc.homepos 11. ax<id>.traj.setpos 12. ax<id>.traj.targetpos 13. ax<id>.traj.targetvel 14. ax<id>.traj.targetacc 15. ax<id>.traj.targetdec 16. ax<id>.traj.setvel 17. ax<id>.traj.setvelffraw 18. ax<id>.traj.command (rw) (rw) (ro), (rw if ax<id>.traj.source =1) (rw) (rw) (rw) (rw) (ro) (ro) (rw) 19. ax<id>.traj.cmddata (rw) 26

  21. PLCs: Motion Variables Cont. 20. ax<id>.traj.source internal source or expressions source = 0: internal traj source > 0: setpoints from plc execute motion command axis busy axis setpoint direction ax<id>.traj.dir>0: forward ax<id>.traj.dir<0: backward ax<id>.traj.dir=0: standstill actual controller error actual position error actual controller output actual raw velocity setpoint enable drive command drive enabled sequence state (homing) motion interlock ax<id>.mon.ilock=1: motion allowed ax<id>.mon.ilock=0: motion not allowed axis at taget low limit switch high limit switch home sensor low soft limit high soft limit low soft limit enable high soft limit enable enables/disables "set" commands via command parser (ascii commands) Statuses can still be read. Exceptions ("set"-commands) that will work: - "StopMotion(axid)" - "Cfg.SetAxisBlockCom(axid,block)" (ro) 21. ax<id>.traj.execute 22. ax<id>.traj.busy 23. ax<id>.traj.dir (rw) (ro) (ro) 24. ax<id>.cntrl.error 25. ax<id>.cntrl.poserror 26. ax<id>.cntrl.output 27. ax<id>.drv.setvelraw 28. ax<id>.drv.enable 29. ax<id>.drv.enabled 30. ax<id>.seq.state 31. ax<id>.mon.ilock (ro) (ro) (ro) (ro) (rw) (ro) (ro) (rw) 32. ax<id>.mon.attarget 33. ax<id>.mon.lowlim 34. ax<id>.mon.highlim 35. ax<id>.mon.homesensor 36. ax<id>.mon.lowsoftlim 37. ax<id>.mon.highsoftlim 38. ax<id>.mon.lowsoftlimenable 39. ax<id>.mon.highsoftlimenable 40. ax<id>.blockcom (ro) (ro) (ro) (ro) (rw) (rw) (rw) (rw) (rw) 27

  22. PLCs: Motion Lib Functions Function Lib: MC 1. retvalue := mc_move_abs(<axIndex>, <execute>, <pos>, <vel>, <acc>, <dec>); Absolute motion of axis. Motion is triggerd with a positive edge on <execute> input. returns 0 if success or error code. 2. retvalue := mc_move_rel(<axIndex>, <execute>, <pos>, <vel>, <acc>, <dec>); Relative motion of axis <axIndex>. Motion is triggerd with a positive edge on <execute> input. returns 0 if success or error code. 3. retvalue := mc_move_vel(<axIndex>, <execute>, <vel>, <acc>, <dec>); Constant velocity motion of axis <axIndex>. Motion is triggerd with a positive edge on <execute> input. returns 0 if success or error code. 4. retvalue := mc_home(<axIndex>, <execute>, <seqId>, <velTwoardsCam>, <velOffCam>); Perform a homing sequence of axis <axIndex>. Motion is triggerd with a positive edge on <execute> input. returns 0 if success or error code. 5. retvalue := mc_halt(<axIndex>, <execute>); Stop motion of axis <axIndex>. returns 0 if success or error code. 6. retvalue := mc_power(<axIndex>, <enable>); Enable power of axis <axIndex>. returns 0 if success or error code. 7. retvalue := mc_get_busy(< axIndex >); returns busy state of axis <axisindex> 8. retvalue := mc_get_homed(<axIndex>); returns homed state of axis <axisindex> 9. retvalue = mc_get_err(); Returns error code for last lib call. Example: retvalue:=mc_power(2,1); # Set power on amplifier of axis 2 28

  23. PLCs: General ECMC commands Create a new PLC: "Cfg.CreatePLC(<plcindex>,<rate_ms>) Load PLC code text file (and compile and enable): "Cfg.LoadPLCFile(<plcIndex>,<filename>)" Add code line by line: "Cfg.AppendPLCExpr(<plcIndex>)= <code> Compile PLC code: "Cfg.CompilePLC(<plcindex>)" Enable/Disable PLC: "Cfg.SetPLCEnable(<plcindex>,<enable>)" 29

  24. PLCs: Motion Example Code: if(static.seqStep==1) { if(not(ax1.error)) { errorCode=mc_power(1,1); if(errorCode) { println('Function mc_power() returned error: ', errorCode); plc3.error:=errorCode; }; } else { mc_reset(1); }; if(ax1.drv.enabled){ static.seqStep:=2; println('2. Function mc_home() triggered!'); }; }; # State 1. Put power on axis (run mc_power()) # Put power on axis 1 # Printout in iocsh window # Error code # Reset error on axis 1 # Start homing if enabled if(static.seqStep==2) { var homingSeq:=3; var velTwoardsCam:=5; var velOffCam:=4; errorCode=mc_home(1,1,homingSeq,velTwoardsCam,velOffCam); if(errorCode){ println('Function mc_home() returned error: ', errorCode); plc3.error:=errorCode; }; if(mc_get_homed(1) and not(mc_get_busy(1))) { static.seqStep:=3; println('3. Function mc_move_abs() triggered!'); }; }; # State 2. Do homing sequence (run mc_home()) # Home axis 1 # Homing ready?.. 30

  25. Synchronization Execution flow: Normal axis: Controller Drive Trajectory Encoders Monitor Virtual axis: Trajectory Encoder Monitor Read from EC Axis PLC 1 Axis 1 Axis PLC 2 Axis 2 Axis PLC n Axis n Synchronization is handled through PLCs objects. Each axis object have a dedicated Axis PLC -object that is executed just before the axis object. Axis PLC objects behave exactly as normal PLC objects. Any Axis PLC or Normal PLC object can be used for synchronization (or other PLC code). PLC 1 PLC 2 PLC n Write to EC 31

  26. ECMC: Synchronization Execution flow: Synchronization of axes is handled by a axis synchronous PLC: - ax<id>.traj.setpos = - ax<id>.enc.actpos = - ax<id>.drv.enable = - ax<id>.mon.ilock = - ax<id>.mon.ilockfwd = - ax<id>.mon.ilockfwd = - .. Any plc expression can be entered. Trajectory generated setpoint for axis <id> Actual position of axis <id> Enable amplifier of axis <id> Motion interlock of axis <id> (allowed to move if 1) Motion interlock of axis fwd <id> (allowed to move if 1) Motion interlock of axis bwd <id> (allowed to move if 1) Read from EC Axis PLC 1 Axis 1 Axis PLC 2 Axis PLCs are recalculated / refreshed in 1kHz Axis 2 Examples: Slaving: Synchronization: Gearing: Phasing: Advanced: Timing system: Interlocks: Enable: Enable alternative: Axis PLC n ax2.traj.setpos := ax1.enc.actpos; ax2.traj.setpos := ax1.traj.setpos; ax2.traj.setpos := 0.5 * ax1.traj.setpos; ax3.traj.setpos := ax1.traj.setpos + ax2.traj.setpos; ax1.traj.setpos := 10*sin(ax2.traj.setpos + ec0.s3.VALUE); ax1.traj.setpos := ec0.s3.VALUE * 0.5 + ec0.s4.AO_1; ax1.mon.ilock := ax2.mon.ilock and ax5.mon.ilock and ax4.enc.actpos > ax3.enc.actpos; ax2.drv.enable := ax1.drv.enable; mc_power(1,ax1.drv.enable); Axis n PLC 1 PLC 2 PLC n Write to EC 32 32

  27. Application: 2-Axes Slit Set 2 virtual axes - Slit center position - Slit gap/opening 2 normal axes (blade positions) Axis 1 (Virt: Center position) Forward Kinematics: ax3.traj.setpos:=ax1.traj.setpos - ax2.traj.setpos/2; ax4.traj.setpos:=ax1.traj.setpos + ax2.traj.setpos/2; Axis 2 (Virt: Gap) Axis 3 (Normal: Blade position) Inverse Kinematics: ax1.enc.actpos:=(ax3.enc.actpos+ax4.enc.actpos )/2; ax2.enc.actpos:=(ax4.enc.actpos ax3.enc.actpos); Axis 4 (Normal: Blade position) Amplifier enable: ax3.drv.enable:=ax1.drv.enable or ax2.drv.enable; ax4.drv.enable:=ax1.drv.enable or ax2.drv.enable; Or: mc_power(3, ax1.drv.enable or ax2.drv.enable); mc_power(4, ax1.drv.enable or ax2.drv.enable); Blade Axis 3 Blade Axis 4 33

  28. Application: 2-Axes Slit Set, External Sync. Add 2 virtual axes - Timing system (Signal Generator connected to EL5101) - Amplitude Axis 1 (Centre) Axis 2 (Gap) Axis 3 Left blade Axis 4 Right blade 34 Old syntax..

  29. Application: 2-Axes Slit Set, External Sync. Axis 4 Axis 1 (Centre) Axis 2 (Gap) Axis 3 Old syntax..

  30. ECMC data access over Asyn: Note: ECMC data are transferred to EPICS records by default if ecmccfg is used but can also be customized. Data in ECMC can be exposed to EPICS records over Asyn framework ( I/O Intr ): EtherCAT: - EtherCAT entries (also waveforms for oversampling cards) - EtherCAT slave diagnostics - EtherCAT master diagnostics Diagnostics: - Motion thread time jitter Motion Axis: - Trajectory generated setpoint - Actual position - Following error - Diagnostic string (containing most info of axis) PLC vatriables Available data can be listed with the iocsh command ecmcReport <detail> ecmcReport 0 : Display basic information ecmcReport 1 : Display all parameters that are linked to records ecmcReport 2 : Display all available parameters (that can be accessed) Note: asynReport can be used in the same way but will also list information from other loaded asyn modules like EthercatMC 36

  31. ECMC data access over Asyn: EtherCAT Record INP/OUTP field syntax: "@asyn(<asynPort>,<address>,<timeout>)ecmcInfoStr) ecmcInfoStr: CMD=<cmd>/T_SMP_MS=<sampletime>/TYPE=<type>/<parameter name><read/write>" 1. CMD (optional): 1. 2. UINT64TOFLOAT64 : FLOAT64TOINT32 : Converts 64bit uint data to float64 before push to EPICS (64 bit positions and time) Converts float 64 to int32 before push to epics (binary PLC values) 2. T_SMP_MS (optional): Record update rate in milliseconds 3. TYPE (mandatory): Type of data to transfer (asynInt32, asynFloat64, asynInt32ArrayIn..) 4. <parameter name> (mandatory): Example for Ec data: Use ecmcReport 3 to see available parameter names ec<master index>.s<slave index>.<data alias> 5. <read/write> (mandatory) read write ? = 37

  32. ECMC data access over Asyn: Example Example of analog input EL3002: master=0, slave=2, data alias = CH1_VALUE , T_SMP_MS=1: Record definition: record(ai, IOC:ec0-s2-EL3002-AI1") { field(INP, "@asyn(TEST,0,1)T_SMP_MS=1/TYPE=asynInt32/ec0.s2.CH1_VALUE?") field(DTYP, "asynInt32") field(SCAN, "I/O Intr") .. } 38

  33. Example: Temperature Analog Data Acquisition: Example: Motor temperature (PT100 or similar) Data accessible through EPICS PV (AI record) Update EPICS PV on change Resolution 0,1 C (standard) Temperature [ C] Stepper Temperature Sensor (PT1000) Temperature Sensor (PT100) Time 39 Motor in Operation Motor Idle

  34. Example: Vibration Analysis Vibration measurement: IEPE interface (or normal analog) Oversampling max 50kHz (other analog 100kHz) Data accessible through EPICS PV (waveform record) Accelerometer Stepper FFT Stepper Motor Vibrations Stepper motor full step freq. 40 0 2.5kHz Analysis in Python (pyepics, scipy, numpy, and matplotlib)

  35. Data Acquisition: Position Data Analysis Positioning 0 to 50 mm Analysis of position error during move: Data accessible in EPICS PVs (AI records) Example: Positioning task from 0mm to 50mm Position [mm] FFT of Position Error Time Stepper motor full step freq.* Amplitude [mm] Frequency [Hz] 41 *5mm/s , 60mm/rev, 200 steps/rev=> 16.67Hz full step freq

  36. Commands from EPICS records: Motor record All commands can be executed from EPICS records using stream device or asyn-record. Typically settings and communication that are not handled by motor record or model 3 driver can be applied through stream device or ASYN record. Stream Device Example: 42

  37. Motion Interlocks 1. Interlock by I/O: Any digital EtherCAT entry can be linked to interlock motion Example: Link I/O to interlock axis n ecmcConfigOrDie "Cfg.LinkEcEntryToAxisMonitor(0,INPUT_7,n,3,0)" ecmcConfigOrDie "Cfg.SetAxisMonEnableExtHWInterlock(n,1) 2. Interlock by I/O in motion terminal: Inputs of some motion terminals, like Beckhoff Stepper terminals, can be configured to disable power of amplifier. Example: Hardware enable on input 1 of EL7037 (slave bus position m) ecmcConfigOrDie "Cfg.EcAddSdo(m,0x8012,0x32,1,1)" 3. Interlocks from PLC: Example: Interlock axis 1 from plc: ax1.mon.ilock:=ax2.enc.actvel<2 and ax4.mon.ilock and ax3.enc.actpos<1000; 4. Safe Torque Off: The drives IPOS8020 and IPOS4808 have safety rated STO inputs (SIL3/Ple) 43

  38. Data Storage Data storage objects is a basically a data buffer/array. Types: Normal: Fill from beginning stop when full Ring: Fill from beginning start over when full FIFO: Fill from end. Oldest value are pushed out when full Can be accessed from waveforms from EPICS records (r/w) Can be accessed from PLCs (r/w) Useful for: latching fast data. Implementation of simple filters Storing custom trajectories Data Storage Commands: Cfg.CreateDataStorage ( .) Cfg.ClearStorage ( .) ReadStorageBuffer( .) Cfg.SetStorageEnablePrintouts ( .) Cfg.PrintStorageBuffer ( .) 44

  39. Data Storage: PLC access Variables (struct only refreshes one time per execution): 1. ds<id>.size Set/get size of data storage (set will clear the data storage) 2. ds<id>.append Add new data at end, current position index will be increased 3. ds<id>.data Set/get data ar current position 4. ds<id>.index Set/get current position index 5. ds<id>.error Data storage object error error 6. ds<id>.clear Data buffer clear (set to zero) 7. ds<id>.full True if data storage is full (rw) (rw) (rw) (rw) (ro) (ro) (ro) Function Lib: DS 1. retvalue := ds_append_data(<dsIndex>,<data>); 2. retvalue := ds_clear_data(<dsIndex>); 3. retvalue := ds_get_data(<dsIndex>, <bufferIndex>); 4. retvalue := ds_set_data(<dsIndex>, <bufferIndex>); 5. retvalue := ds_get_buff_id(<dsIndex>); 6. retvalue := ds_set_buff_id(<dsIndex>, <bufferIndex>); 7. retvalue := ds_is_full(<dsIndex>); 8. retvalue := ds_get_size(<dsIndex>); 9. retvalue := ds_push_asyn(<dsIndex>); 10. retvalue := ds_get_avg(<dsIndex>); 11. retvalue := ds_get_min(<dsIndex>); 12. retvalue := ds_get_max(<dsIndex>); 13. retvalue := ds_get_err(); Append data to data storage Clear data to data storage. Returns data from buffer. Sets data in data storage buffer. Returns current buffer index. Sets current buffer index in data storage buffer. Returns true if buffer is full. Returns buffer size of data storage. Push data storage to EPICS Returns average value of stored values Returns min value of stored values Returns max value of stored values Returns error code for last lib call. Example: retvalue := ds_get_avg(1); # Returns average of all values in buffer (can be used as simple filter). 45

  40. Distributed Clocks Commands: Cfg.EcSlaveConfigDC( .) Cfg.EcSelectReferenceDC ( .) 46

  41. Etherlab EtherCAT tool: EtherCAT tool from www.etherlab.org Display master status: ethercatmaster Display slaves and status: ethercat slaves Display available PDOs for slave 3: ethercat p3 pdos Display available SDOs for slave 3: ethercat p3 sdos Display help: ethercat h 47

  42. Acknowledgments Igh open source EtherCAT master (www.etherlab.org) EPICS community (base, motor, asyn, stream device) ExprTK C++ Mathematical Expression Library Questions? 48

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#