Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b97b5a53c | |||
| 81b0013a57 | |||
| e43935510e | |||
| bddba4be91 | |||
| 4df2642299 | |||
| 261f93ed43 | |||
| 8f68bc021d | |||
| 07acbe990e | |||
| ece0240a5d | |||
| 7583975ab2 | |||
| 6e4d9e2933 | |||
| 3d0896a290 | |||
| 0b9d22b327 | |||
| 9f0147c83e | |||
| f85f010d06 | |||
| fa77ffb099 | |||
| 7893207cb6 | |||
| 7431834bd3 | |||
| 980aeeecdc | |||
| 9042a39a1b | |||
| 1fb017ac64 | |||
| e0d93179a8 | |||
| 18e4821a83 | |||
| eeaffaad96 | |||
| 31fd9d8851 | |||
| adc421ba42 | |||
| a1110a3aa4 | |||
| 4930b2bfeb | |||
| eea8ea48e9 | |||
| 817b1a2b8d | |||
| 876ddb1d4a | |||
| 7550551cc4 | |||
| 0c5f9a4091 | |||
| 28c25a4345 | |||
| 5d1ff4fc99 | |||
| a1b4ec01b8 | |||
| 05654f8917 | |||
| 694be265d0 | |||
| aade802526 | |||
| ae7697bd08 | |||
| bedf777537 | |||
| ad8dd2cc36 | |||
| 50ce0d45ca | |||
| b8da66f0a5 | |||
| d6f04bfa4d | |||
| 4bc5bf475f | |||
| 940d2c5a71 | |||
| de10cade0f | |||
| 3272fd62ed | |||
| a5c2b5a4b3 | |||
| fec9293520 | |||
| 1c051995c3 | |||
| c02541c711 | |||
| 67f6c739e0 | |||
| ea4d26fd31 | |||
| 9bd3a2b124 | |||
| 48c6070a62 | |||
| dd1b229322 | |||
| 10d5b1deb7 | |||
| f68a2602d5 | |||
| ed84fa26e3 | |||
| 8f3a9d5b59 | |||
| 0eb4a8032e | |||
| f9cf3e1fe2 | |||
| 68210c6e40 | |||
| c7a147b219 | |||
| 7f28d95db4 | |||
| 0d22b4f935 | |||
| 19a46aa738 | |||
| added6a7cd | |||
| 611dce9c7a | |||
| 72c4bf0697 |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -2,6 +2,7 @@
|
||||
"files.associations": {
|
||||
"string_view": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"iosfwd": "cpp"
|
||||
"iosfwd": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
25
Db/ecmcSS1Axis.template
Normal file
25
Db/ecmcSS1Axis.template
Normal file
@@ -0,0 +1,25 @@
|
||||
#- Will be a sub record to the axis object, example:
|
||||
#- AXIS_PREFIX=c6015a-02:M1
|
||||
record(stringin,"$(AXIS_PREFIX)-SS1-GrpNam") {
|
||||
field(DESC, "Name of Saftey Grp ")
|
||||
field(VAL, "${NAME}")
|
||||
}
|
||||
|
||||
record(bi,"${AXIS_PREFIX}-SS1-EnaAct"){
|
||||
field(DESC, "Safety PLG active for this axis")
|
||||
field(VAL, 1)
|
||||
field(ONAM, "1")
|
||||
field(ZNAM, "0")
|
||||
}
|
||||
|
||||
record(ai,"${AXIS_PREFIX}-SS1-VelMaxLim"){
|
||||
field(DESC, "Velocity max limit (not safety...)")
|
||||
field(VAL, ${VEL_MAX_LIM=-1})
|
||||
field(PREC, 3)
|
||||
}
|
||||
|
||||
record(ai,"${AXIS_PREFIX}-SS1-VelRestLim"){
|
||||
field(DESC, "Velocity rest limit (not safety...)")
|
||||
field(VAL, ${VEL_REST_LIM=-1})
|
||||
field(PREC, 3)
|
||||
}
|
||||
@@ -51,4 +51,33 @@ record(bi,"${P}SS1-${NAME}-AxsStndStllAct"){
|
||||
field(ONAM, "Standstill")
|
||||
field(ZSV, "NO_ALARM")
|
||||
field(OSV, "NO_ALARM")
|
||||
field(FLNK, "${P}SS1-${NAME}-RedVeloCmdAct.PROC")
|
||||
}
|
||||
|
||||
# // bit 3 reduce velo active
|
||||
record(bi,"${P}SS1-${NAME}-RedVeloCmdAct"){
|
||||
field(DESC, "SS1-${NAME}: Reduce velo active")
|
||||
field(INP, "${P}SS1-${NAME}-Stat_.B3")
|
||||
field(ZNAM, "Not Active")
|
||||
field(ONAM, "Active")
|
||||
field(ZSV, "NO_ALARM")
|
||||
field(OSV, "NO_ALARM")
|
||||
}
|
||||
|
||||
record(ai,"$(P)SS1-${NAME}-Dly") {
|
||||
field(DESC, "Power off delay [ms]")
|
||||
field(EGU, "ms")
|
||||
field(VAL, "$(DELAY=0)")
|
||||
field(PREC, "0")
|
||||
}
|
||||
|
||||
|
||||
record(stringin,"$(P)SS1-Grp${ID=0}-Nam") {
|
||||
field(DESC, "Name of Grp ${ID=0}")
|
||||
field(VAL, "${NAME}")
|
||||
}
|
||||
|
||||
record(ai,"$(P)SS1-GrpCnt") {
|
||||
field(DESC, "Group Count")
|
||||
field(VAL, "$(COUNT=0)")
|
||||
}
|
||||
11
Db/ecmcSS1Main.template
Normal file
11
Db/ecmcSS1Main.template
Normal file
@@ -0,0 +1,11 @@
|
||||
record(stringin,"$(P)SS1-PnlTyp") {
|
||||
field(DESC, "Panel name")
|
||||
field(VAL, "ecmc_plugin_safety_main.ui")
|
||||
}
|
||||
|
||||
record(bi,"${P}SS1-Loaded"){
|
||||
field(DESC, "Plugin loaded")
|
||||
field(VAL, 1)
|
||||
field(ONAM, "1")
|
||||
field(ZNAM, "0")
|
||||
}
|
||||
33
GNUmakefile
33
GNUmakefile
@@ -2,11 +2,14 @@ include /ioc/tools/driver.makefile
|
||||
|
||||
MODULE = ecmc_plugin_safety
|
||||
|
||||
# "Transfer" module name to plugin
|
||||
USR_CFLAGS +=-DECMC_PLUGIN_MODULE_NAME=${MODULE}
|
||||
|
||||
BUILDCLASSES = Linux
|
||||
ARCH_FILTER = deb10%
|
||||
ARCH_FILTER = deb10% deb12%
|
||||
|
||||
# Run 7.0.6 for now
|
||||
EXCLUDE_VERSIONS+=3 7.0.5 7.0.6
|
||||
EXCLUDE_VERSIONS+=3 7.0.5 7.0.6 7.0.7 7.0.9
|
||||
|
||||
IGNORE_MODULES += asynMotor
|
||||
IGNORE_MODULES += motorBase
|
||||
@@ -15,20 +18,24 @@ USR_CXXFLAGS += -std=c++17
|
||||
OPT_CXXFLAGS_YES = -O3
|
||||
|
||||
# dependencies
|
||||
ecmc_VERSION = 10.0
|
||||
ECmasterECMC_VERSION = v1.1.0
|
||||
# motorECMC_VERSION = 7.0.7-ESS
|
||||
#ecmc_VERSION = v9.0.1_RC4
|
||||
ecmc_VERSION = 9.1.0
|
||||
|
||||
################################################################################
|
||||
# THIS RELATES TO THE EtherCAT MASTER LIBRARY
|
||||
# IT IS OF PARAMOUNT IMPORTANCE TO LOAD THE PROPER KERNEL MODULE
|
||||
# ################################################################################
|
||||
USR_LDFLAGS += -lethercat
|
||||
# ethercat
|
||||
EC_BASE_PATH = /ioc/NeedfulThings/EtherCAT/4epics/
|
||||
USR_CXXFLAGS_deb12-x86_64 += -I${EC_BASE_PATH}${T_A}/include/
|
||||
USR_CXXFLAGS_deb12-x86_64 += -L${EC_BASE_PATH}${T_A}/lib/
|
||||
|
||||
OPT_CXXFLAGS_YES = -O3
|
||||
|
||||
LIB_SYS_LIBS += ethercat
|
||||
USR_LDFLAGS_deb12-x86_64 += -Wl,-rpath=${EC_BASE_PATH}${T_A}/lib/
|
||||
USR_LDFLAGS_deb12-x86_64 += -L ${EC_BASE_PATH}${T_A}/lib/
|
||||
|
||||
USR_LDFLAGS_deb10-x86_64 += -lethercat
|
||||
EC_MASTER_LIB = ${EPICS_MODULES}/ECmasterECMC/${ECmasterECMC_VERSION}/R${EPICSVERSION}/lib/${T_A}
|
||||
USR_LDFLAGS += -Wl,-rpath=${EC_MASTER_LIB}
|
||||
USR_LDFLAGS += -L ${EC_MASTER_LIB}
|
||||
USR_LDFLAGS_deb10-x86_64 += -Wl,-rpath=${EC_MASTER_LIB}
|
||||
USR_LDFLAGS_deb10-x86_64 += -L ${EC_MASTER_LIB}
|
||||
|
||||
BASE_DIR = .
|
||||
SRC_DIR = $(BASE_DIR)/src
|
||||
@@ -43,5 +50,5 @@ HEADERS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.h))
|
||||
DBDS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.dbd))
|
||||
SCRIPTS += $(BASE_DIR)/startup.cmd
|
||||
SCRIPTS += $(BASE_DIR)/scripts/addSS1Group.cmd
|
||||
SCRIPTS += $(BASE_DIR)/scripts/addAxisToGroup.cmd
|
||||
SCRIPTS += $(BASE_DIR)/scripts/addAxisToSafetyGroup.cmd
|
||||
TEMPLATES += $(wildcard $(DB_DIR)/*.template)
|
||||
|
||||
117
README.md
117
README.md
@@ -10,37 +10,61 @@ This plugin is designed for interfacing safety systems, see example in below pic
|
||||
# SS1-t
|
||||
The plugin supports stopping axes according to a concept described as SS1-t, see below picture. In SS1-t the STO (or removal of power) from the axes are delayed for a certain defined time allowing a controlled rampdown of velocity. The rampdown of the axis is handled by the non-safe motion controller while the removal of power (or triggering of STO) after the time delay is handled by a safety system, . This makes it possible to stop moving axes in a controlled way and disable the drives before the power is interrupted (or STO triggered). This will result in a safer system and less harware failures and error messages.
|
||||
|
||||
After the time delay expires, hopfully all axes are at standstill and power is already removed from the drives.
|
||||
After the time delay expires, hopfully all axes are at standstill and power is already removed from the drives.
|
||||
|
||||

|
||||
|
||||
## Velocity limit
|
||||
An additional optional feature of this plugin is limiting of axis velocity based on an the state of an ethercat I/O (this is not a safety certified fucntionality).
|
||||
|
||||
Axes that are configured with a max velocity will be monitored by this plugin and if exceeding the configured max velocity, the axis will be disabled.
|
||||
|
||||
For initiation of new movements, the target velocity will be limited to 95% of the configured maximum velocity. The reason for this is toi allow small fluctuations in actual velocity without disablaing the axes.
|
||||
|
||||
## Interface
|
||||
Basically the safey system is interfaced with two binary signals (ethercat I/O):
|
||||
* Ramp down command (from safety system to ecmc)
|
||||
* Axis stand still status (to safety system from ecmc)
|
||||
Basically the safey system is interfaced with three binary signals (ethercat I/O):
|
||||
* Ramp down command (from safety system to ecmc). 0 means ramp down command is active.
|
||||
* Axis stand still status (to safety system from ecmc). 1 means that all axes are at rest _AND_ disabled
|
||||
* Limitation of velocity (optional). 0 means limitation of velocity is acrive
|
||||
|
||||
If, for instance, an safety event is triggerd by the safety system, it will immediately command this plugin to rampdown velocity of all axes (that a configured to stop). When all axes, that are configured to rampdown, have stopped then this plugin will disable the axes and set an ethercat output informing the safety system that the axes are standstill. After a certain timout the safety system will make sure power is removed from the motion axes by triggering an STO or removing power. The removal of power or triggering of STO will made regardless if the axes are at rest or not. A reset of the safety system, allowing power to the drives, will only be possible once the safety system gets a confirmation that all axes are at rest.
|
||||
|
||||
The configuration is made by two commands:
|
||||
1. ecmcAddSS1SafetyGroup()
|
||||
2. ecmcAddAxisToSafetyGroup()
|
||||
1. ecmcAddSS1SafetyGroup() wrapped into addSS1Group.cmd
|
||||
2. ecmcAddAxisToSafetyGroup() wrapped in snippet addAxisToSafetyGroup.cmd
|
||||
|
||||
## ecmcAddSS1SafetyGroup()
|
||||
|
||||
The ecmcAddSS1SafetyGroup() adds a SS1 safety group. The command takes the following parameters:
|
||||
```
|
||||
ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<time_delay_ms>)
|
||||
<name> : Name of group.
|
||||
<ec_rampdown> : Ethercat entry input for rampdown cmd.
|
||||
<ec_axes_at_rest> : Ethercat entry output for group standstill status.
|
||||
<time_delay_ms> : Time delay of STO [ms].
|
||||
ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<ec_max_velo_cmd>,<time_delay_ms>)
|
||||
<name> : Name of group
|
||||
<ec_rampdown_cmd> : Ethercat entry input for rampdown cmd
|
||||
<ec_standstill_status> : Ethercat entry output for group standstill status
|
||||
<ec_max_velo_cmd> : Ethercat entry input for activation of maximum velo limitation (set to "empty" to disable)
|
||||
<time_delay_ms> : Time delay of STO [ms]
|
||||
```
|
||||
Each group is interfacing the safety system through the same I/O (ethercat).
|
||||
Axes that needs the SS1 fucntionality can be added to this group with the ecmcAddAxisToSafetyGroup() command.
|
||||
|
||||
This command is also wrapped in a snippet:
|
||||
* addSS1Group.cmd
|
||||
This command is also wrapped in a snippet addSS1Group.cmd with the follwoing parameters:
|
||||
* NAME : Name of group
|
||||
* EC_RAMP_DOWN : Ethercat input of ramp down signal from safety PLC
|
||||
* EC_AXES_REST : Ethercat entry for signaling that all axes in group are at rest, output from ecmc (feedback to safety PLC/system)
|
||||
* EC_AXES_MAX_VELO : Ethercat entry for reducing velocity, input to ecmc (command from safety PLC/system), put 0 to disable
|
||||
* DELAY_MS : Safety system delay time of STO or removal of power
|
||||
|
||||
Example:
|
||||
```
|
||||
# Create SS1 group
|
||||
epicsEnvSet(EC_RAMP_DOWN,"ec${ECMC_EC_MASTER_ID}.s${BI_SLAVE}.binaryInput08.0")
|
||||
epicsEnvSet(EC_AXES_REST,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.binaryOutput07.0")
|
||||
epicsEnvSet(SAFETY_TIMEOUT,500)
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN=${EC_RAMP_DOWN},EC_AXES_REST=${EC_AXES_REST},DELAY_MS=${SAFETY_TIMEOUT}"
|
||||
|
||||
```
|
||||
## ecmcAddAxisToSafetyGroup()
|
||||
|
||||
With the "ecmcAddAxisToSafetyGroup()" command an ecmc axis can be added to a safety group.
|
||||
All axes linked to a certain group will act on command from the safety system (initiation of velocity rampdown).
|
||||
|
||||
@@ -49,31 +73,76 @@ The ecmcAddAxisToSafetyGroup() command takes the following parameters:
|
||||
ecmcAddAxisToSafetyGroup(<group_name>, <axis_index>, <velo_limit>, <filter_time>)
|
||||
<name> : Name of safety group to add axis to.
|
||||
<Axis id> : Axis index to add (ecmc axis index).
|
||||
<velo limit> : Axis standstill velo limit [unit of axis].
|
||||
<velo_rest_limit> : Axis at rest velo limit [unit of axis].
|
||||
<velo_max_limit> : Axis max velo limit [unit of axis].
|
||||
<filter_time> : NOT USED (for future implemenation). Time for axis to be below velo limit [ms].
|
||||
```
|
||||
Note: The "filter_time" parameter is not used right now. As soon as the axis is below teh velo_limit it will be considered to stand still and will then be disabled.
|
||||
|
||||
Note: The plugin checks the trajectory generated velocity setpoint and not the actual velocity.
|
||||
|
||||
This command is also wrapped in a snippet:
|
||||
* addAxisToGroup.cmd
|
||||
This command is also wrapped in a snippet addAxisToSafetyGroup.cmd with the following parameters:
|
||||
* NAME : Name of group to add axis to (group must be created first with addSS1Group.cmd)
|
||||
* AX_ID : ecmc axis index of axis to add
|
||||
* VELO_REST_LIM : Velocity at rest limit [unit same as EGU of axis]
|
||||
* VELO_MAX_LIM : Velocity maximum limit, -1 to disable [unit same as EGU of axis]
|
||||
|
||||
Example:
|
||||
```
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToSafetyGroup.cmd "NAME=first,AX_ID=1,VELO_REST_LIM=1,VELO_MAX_LIM=100"
|
||||
```
|
||||
|
||||
# Example of startup script:
|
||||
```
|
||||
##############################################################################
|
||||
## Load safety plugin
|
||||
#
|
||||
|
||||
require ecmc_plugin_safety sandst_a
|
||||
|
||||
# Create SS1 group
|
||||
epicsEnvSet(RAMP_DOWN_CMD,"ec${ECMC_EC_MASTER_ID}.s${DRV_SLAVE}.ZERO.0")
|
||||
epicsEnvSet(STANDSTILL_STAT,"ec${ECMC_EC_MASTER_ID}.s${DRV_SLAVE}.ZERO.1")
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN_CMD=${RAMP_DOWN_CMD},EC_STANDSTILL_STAT=${STANDSTILL_STAT},DELAY_MS=500"
|
||||
|
||||
# Add axes to group "first"
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToGroup.cmd "NAME=first,AX_ID=1,VELO_LIM=1"
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToGroup.cmd "NAME=first,AX_ID=2,VELO_LIM=1"
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToGroup.cmd "NAME=first,AX_ID=3,VELO_LIM=1"
|
||||
# Create SS1 group
|
||||
#- EC_RAMP_DOWN : Ethercat entry for ramp down command, input to ecmc (command from safety PLC/system)
|
||||
#- EC_AXES_REST : Ethercat entry for signaling that all axes in group are at rest, output from ecmc (feedback to safety PLC/system)
|
||||
#- EC_AXES_MAX_VELO : Ethercat entry for reducing velocity, input to ecmc (command from safety PLC/system), set to "empty" to disable
|
||||
#- DELAY_MS : Time between rampdown command and STO
|
||||
epicsEnvSet(EC_RAMP_DOWN,"ec${ECMC_EC_MASTER_ID}.s${BI_SLAVE}.binaryInput08.0")
|
||||
epicsEnvSet(EC_AXES_REST,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.binaryOutput07.0")
|
||||
epicsEnvSet(EC_AXES_MAX_VELO,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.ONE.0")
|
||||
epicsEnvSet(SAFETY_TIMEOUT,500)
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN=${EC_RAMP_DOWN},EC_AXES_REST=${EC_AXES_REST},EC_AXES_MAX_VELO=${EC_AXES_MAX_VELO},DELAY_MS=${SAFETY_TIMEOUT}"
|
||||
|
||||
#- Add axis
|
||||
#- AX_ID : Axis ID
|
||||
#- VELO_REST_LIM : Velocity at rest limit [unit same as EGU of axis]
|
||||
#- VELO_MAX_LIM : Velocity maximum limit, -1 to disable [unit same as EGU of axis]
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToSafetyGroup.cmd "NAME=first,AX_ID=1,VELO_REST_LIM=1,VELO_MAX_LIM=100"
|
||||
....
|
||||
```
|
||||
|
||||
# Test
|
||||
Triggering of e-stop:
|
||||
* Velo 500mm/s
|
||||
* Stop ramp 1200mm/s/s
|
||||
|
||||
[Test data](docs/data_log.txt)
|
||||
|
||||

|
||||

|
||||
|
||||
# Test at Debye
|
||||
|
||||
```
|
||||
libversionShow
|
||||
require 3.3.1 /gfa/.mounts/sls_ioc/modules/require/3.3.1/R7.0.7/
|
||||
misc 2.15.0 /gfa/.mounts/sls_ioc/modules/misc/2.15.0/R7.0.7/
|
||||
ecmccfg safety3 /gfa/.mounts/sls_ioc/modules/ecmccfg/safety3/R7.0.7/
|
||||
ECmasterECMC v1.1.0 /gfa/.mounts/sls_ioc/modules/ECmasterECMC/v1.1.0/R7.0.7/
|
||||
calc 3.7.6 /gfa/.mounts/sls_ioc/modules/calc/3.7.6/R7.0.7/
|
||||
asyn 4.42.2 /gfa/.mounts/sls_ioc/modules/asyn/4.42.2/R7.0.7/
|
||||
motorECMC 7.0.9-ESS /gfa/.mounts/sls_ioc/modules/motorECMC/7.0.9-ESS/R7.0.7/
|
||||
ruckig 0.6.3 /gfa/.mounts/sls_ioc/modules/ruckig/0.6.3/R7.0.7/
|
||||
ecmc safety3 /gfa/.mounts/sls_ioc/modules/ecmc/safety3/R7.0.7/
|
||||
ecmccomp 0.1.0 /gfa/.mounts/sls_ioc/modules/ecmccomp/0.1.0/R7.0.7/
|
||||
ecmc_plugin_safety safety3 /gfa/.mounts/sls_ioc/modules/ecmc_plugin_safety/safety3/R7.0.7/
|
||||
```
|
||||
|
||||
425
docs/data_log.txt
Normal file
425
docs/data_log.txt
Normal file
@@ -0,0 +1,425 @@
|
||||
c6025a:m0s006-BI08 2024-02-28 12:07:05.294742 1
|
||||
c6025a:m0s005-BO07 2024-02-28 12:07:05.294742 1
|
||||
c6025a:Axis1-EnaAct 2024-02-28 12:07:05.294742 0
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:05.294742 0
|
||||
c6025a:Axis1-EnaAct 2024-02-28 12:07:05.294742 1
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.894679 0.28125
|
||||
c6025a:m0s005-BO07 2024-02-28 12:07:06.894708 0
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.904782 0.5625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.914794 1.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.924633 1.96875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.934677 2.8125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.944878 3.9375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.954778 5.34375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.964832 6.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.974675 8.4375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.984744 10.4063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:06.994771 12.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.004719 14.3438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.014668 16.3125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.024860 18.2812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.034780 20.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.044877 22.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.054717 24.4688
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.064741 26.4375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.074748 28.6875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.084629 30.6563
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.094523 32.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.104632 34.5937
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.114639 36.5625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.124609 38.5313
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.134548 40.7812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.144687 42.4687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.154661 44.7187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.164621 46.9687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.174524 48.6562
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.184630 50.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.194575 52.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.204647 54.8437
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.214532 57.0937
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.224681 59.0625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.234638 61.0313
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.244621 63
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.254531 64.9688
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.264625 66.9375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.274624 69.1875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.284604 71.1562
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.294620 73.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.304609 75.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.314694 77.0625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.324532 79.3125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.334747 81.2813
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.344719 83.5313
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.354545 85.2187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.364593 87.4687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.374513 89.4375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.384706 91.4062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.394533 93.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.404724 95.3438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.414536 97.5938
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.424718 99.2812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.434576 101.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.444675 103.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.454711 105.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.464727 107.438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.474662 109.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.484694 111.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.494580 113.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.504554 115.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.514593 117.562
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.524542 119.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.534518 121.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.544705 123.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.554553 125.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.564548 127.687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.574571 129.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.584575 131.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.594579 133.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.604569 135.563
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.614496 137.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.624543 139.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.634565 141.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.644578 143.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.654534 145.687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.664575 147.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.674540 149.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.684578 151.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.694520 153.563
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.704569 155.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.714592 157.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.724494 159.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.734526 161.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.744597 163.688
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.754577 165.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.764576 167.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.774517 169.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.784631 171.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.794569 173.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.804553 175.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.814502 177.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.824549 179.437
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.834559 181.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.844593 183.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.854506 185.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.864635 187.312
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.874661 189.563
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.884596 191.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.894512 193.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.904671 195.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.914657 197.156
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.924587 199.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.934617 201.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.944662 203.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.954738 205.031
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.964674 207.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.974606 208.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.984655 211.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:07.994602 212.906
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.004556 215.156
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.014613 217.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.024574 218.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.034573 221.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.044554 223.031
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.054509 225.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.064582 226.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.074572 228.937
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.084616 230.906
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.094522 232.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.104545 234.844
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.114632 236.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.124551 239.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.134601 240.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.144662 242.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.154610 244.688
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.164547 246.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.174630 248.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.184625 250.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.194636 252.844
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.204622 254.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.214551 256.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.224561 258.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.234632 260.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.244638 262.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.254549 264.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.264547 266.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.274631 268.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.284625 270.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.294527 272.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.304614 274.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.314635 276.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.324638 278.438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.334528 280.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.344631 282.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.354587 284.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.364635 286.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.374554 288.562
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.384685 290.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.394625 292.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.404630 294.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.414552 296.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.424636 298.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.434677 300.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.444640 302.906
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.454526 304.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.464783 306.844
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.474788 309.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.484778 311.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.494686 312.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.504781 315
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.514644 316.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.524646 318.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.534652 321.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.544703 322.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.554719 324.844
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.564640 327.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.574526 329.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.584638 330.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.594675 333.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.604566 335.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.614530 337.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.624670 339.187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.634730 340.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.644675 343.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.654589 345.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.664629 347.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.674658 349.031
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.684631 351.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.694558 353.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.704666 355.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.714633 356.906
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.724594 359.438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.734569 361.687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.744528 363.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.754723 365.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.764646 367.312
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.774660 369.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.784783 371.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.794773 373.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.804756 375.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.814574 377.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.824743 379.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.834760 381.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.844610 383.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.854743 385.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.864865 387.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.874783 389.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.884777 391.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.894662 393.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.904839 395.437
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.914789 397.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.924780 399.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.934554 401.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.944572 403.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.954670 405.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.964716 407.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.974672 408.937
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.984756 411.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:08.994706 413.438
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.004777 415.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.014692 417.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.024787 419.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.034704 421.312
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.044693 423
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.054529 425.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.064598 427.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.074568 429.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.084623 430.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.094540 433.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.104589 435.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.114614 437.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.124543 439.312
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.134559 441.562
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.144724 443.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.154719 445.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.164719 447.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.174616 449.437
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.184700 451.688
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.194669 453.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.204819 455.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.214639 457.594
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.224767 459.281
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.234744 461.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.244766 463.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.254707 465.188
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.264731 467.156
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.274712 469.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.284713 471.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.294630 473.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.304679 474.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.314716 477
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.324576 478.687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.334664 481.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.344739 483.187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.354767 484.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.364750 487.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.374593 489.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.384798 491.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.394769 493.313
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.404718 494.719
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.414746 496.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.424742 497.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.434777 498.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.444781 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.454631 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.464793 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.474788 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.484871 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.494809 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.524798 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.544762 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.564858 500.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.574713 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.594788 500.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.605067 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.614688 500.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.624776 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.644627 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.654623 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.664624 500.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.674660 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.684688 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.694677 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.704654 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.714659 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.724708 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.734636 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.744752 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.764665 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.774628 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.784686 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.794617 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.834628 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.844649 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.854550 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.864618 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.874694 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.884521 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.894502 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.904675 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.914546 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.934575 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.944676 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.954656 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.964621 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.974529 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.984651 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:09.994613 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.004640 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.014519 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.024644 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.034712 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.044862 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.054593 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.064688 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.074866 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.084742 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.094637 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.104632 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.114668 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.124553 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.134645 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.144672 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.154658 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.164493 499.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.174558 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.184658 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.194675 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.204634 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.214565 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.224550 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.234716 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.244661 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.264668 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.284644 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.294536 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.304630 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.314639 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.324658 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.334527 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.344702 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.354650 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.364544 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.384659 499.5
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.394639 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.414495 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.424640 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.434609 500.063
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.444591 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.454518 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.464662 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.474641 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.484634 500.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.494591 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.524641 500.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.534561 500.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.544647 499.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.554678 500.344
|
||||
c6025a:m0s006-BI08 2024-02-28 12:07:10.574556 0
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.584617 500.062
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.594646 498.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.604644 496.687
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.614528 493.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.624638 489.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.634658 484.031
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.644652 478.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.654683 470.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.664770 462.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.674767 453.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.684621 443.531
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.694674 433.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.704723 423
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.714780 412.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.724635 402.75
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.734512 392.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.744636 382.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.754596 372.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.764606 362.812
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.774654 352.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.784561 342
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.794658 332.156
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.804674 322.312
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.814531 311.906
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.824686 301.781
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.834649 291.656
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.844586 281.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.854558 271.406
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.864770 261
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.874783 251.156
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.884754 241.031
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.894669 230.625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.904844 220.219
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.914783 210.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.924773 200.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.934565 190.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.944765 180
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.954775 169.875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.964800 159.469
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.974678 149.344
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.984575 138.938
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:10.994651 129.094
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.004591 118.969
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.014573 108.844
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.024572 98.7187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.034612 88.5938
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.044612 78.1875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.054502 68.0625
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.064659 58.2187
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.074643 48.0937
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.084611 38.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.094559 29.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.104667 21.375
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.114636 14.3437
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.124627 9
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.134527 4.78125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.144553 1.6875
|
||||
c6025a:Axis1-EnaAct 2024-02-28 12:07:11.154581 0
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.154623 -0.5625
|
||||
c6025a:m0s005-BO07 2024-02-28 12:07:11.154636 1
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.164637 -1.96875
|
||||
c6025a:m0s005-BO07 2024-02-28 12:07:11.164653 0
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.174543 -2.25
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.184536 -1.6875
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.194595 -1.125
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.204578 -0.5625
|
||||
c6025a:m0s005-BO07 2024-02-28 12:07:11.204628 1
|
||||
c6025a:Axis1-VelAct 2024-02-28 12:07:11.214568 0
|
||||
BIN
docs/digital.png
Normal file
BIN
docs/digital.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
BIN
docs/velo.png
Normal file
BIN
docs/velo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -1,204 +1,94 @@
|
||||
macros: LIMIT=10000,TYPE=0,DRV_SLAVE=${DRV_SLAVE} # Macros for all below (evaluated before jinja linter)
|
||||
|
||||
axis:
|
||||
id: 1 # Axis id
|
||||
type: joint # this is for future selection of axis type
|
||||
# mode: CSV # supported mode, CSV and CSP, defaults CSV
|
||||
# parameters: 'axisPar' # additional parameters # Additional params to motor record driver
|
||||
#healthOutput: ec0... # Ethercat entry for health output
|
||||
# autoMode: # Switch drive modes automaticaly for normal motion and homing (smaract for instance)
|
||||
# modeSet: ec0.. # Ethercat entry drive mode write (set CSV,CSP,homing)
|
||||
# modeAct: ec0.. # Ethercat entry drive mode reading (set CSV,CSP,homing)
|
||||
# modeCmdMotion: 9 # Drive mode value for normal motion (written to axis.drvMode.modeSet when normal motion)
|
||||
# modeCmdHome: 10 # Drive mode value for when homing (written to axis.drvMode.modeSet when homing)
|
||||
# features:
|
||||
# blockCom: false # Block communication to axis
|
||||
# allowedFunctions:
|
||||
# homing: true # Allow homing
|
||||
# constantVelocity: true # Allow constant velocity
|
||||
# positioning: true # Allow positioning
|
||||
id: ${AXIS_ID=1} # Axis id
|
||||
parameters: 'powerAutoOnOff=2;powerOffDelay=-1;'
|
||||
# feedSwitchesOutput: ec0.s${BO_SID}.binaryOutput${BO_CH=01} # Ethercat entry for feed switches
|
||||
|
||||
epics:
|
||||
name: Axis1 # Axis anme
|
||||
name: ${AX_NAME=M1} # Axis anme
|
||||
precision: 3 # Decimal count
|
||||
description: very important motor axis # Axis description
|
||||
description: Test cfg # Axis description
|
||||
unit: mm # Unit
|
||||
# motorRecord:
|
||||
# enable: true
|
||||
# description: This is MR
|
||||
# fieldInit: 'RRES=1.0,RTRY=2,RMOD=1,UEIP=0,RDBD=0.1,URIP=1,RDBL=$(IOC):$(ECMC_MOTOR_NAME)-PosActSim' # Extra config for Motor record
|
||||
motorRecord:
|
||||
fieldInit: 'RTRY=0,FOFF=Frozen' # Extra config for Motor record
|
||||
|
||||
drive:
|
||||
numerator: 3600 # Fastest speed in engineering units
|
||||
denominator: 32768 # I/O range for ECMC_EC_ALIAS_DRV_VELO_SET
|
||||
# type: 0 # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
|
||||
control: ec0.s$(DRV_SLAVE).driveControl01 # Control word ethercat entry
|
||||
numerator: 10 # Fastest speed in eng. units (2000 Fullsteps/s==10mm/s)
|
||||
denominator: 32768 # I/O range for ECMC_EC_ALIAS_DRV_VELO_SET (normally +-16bit)
|
||||
type: 0 # Stepper: 0. DS402: 1 (DS402 = servos and advanced stepper drives)
|
||||
setpoint: ec0.s$(DRV_SID).velocitySetpoint01 # Velocity setpoint if CSV. Position setpoint if CSP
|
||||
control: ec0.s$(DRV_SID).driveControl01 # Control word ethercat entry
|
||||
enable: 0 # Enable bit index in control word (not used if DS402)
|
||||
enabled: 1 # Enabled bit index in status word (not used if DS402)
|
||||
status: ec0.s$(DRV_SLAVE).driveStatus01 # Status word ethercat entry
|
||||
setpoint: ec0.s$(DRV_SLAVE).velocitySetpoint01 # Velocity setpoint if CSV. Position setpoint if CSP
|
||||
# reduceTorque: 2 # Reduce torque bit in drive control word
|
||||
# reduceTorqueEnable: True # Enable reduce torque functionality
|
||||
# brake:
|
||||
# enable: true # Enable brake
|
||||
# output: ec0... # Ethercat link to brake output
|
||||
# openDelay: 0 # Brake timing parameter in cycles (default 1kHz)
|
||||
# closeAhead: 0 # Brake timing parameter in cycles (default 1kHz)
|
||||
# reset: 1 # Reset (if no drive reset bit then leave empty)
|
||||
# warning: 2 # Warning (if no drive warning bit then leave empty)
|
||||
# error: # max 3
|
||||
# - 3 # Error 0 (if no drive error bit then leave empty)
|
||||
# - 7 # Error 1 (if no drive error bit then leave empty)
|
||||
# - 14 # Error 2 (if no drive error bit then leave empty)
|
||||
reset: 1 # Reset bit in control word (if no drive reset bit then leave empty)
|
||||
reduceTorque: 2 # Reduce torque bit in drive control word
|
||||
reduceTorqueEnable: True # Enable reduce torque functionality
|
||||
status: ec0.s$(DRV_SID).driveStatus01 # Status word ethercat entry
|
||||
enabled: 1 # Enabled bit index in status word (not used if DS402)
|
||||
warning: 2 # Warning bit in status word (if no drive warning bit then leave empty)
|
||||
error: # max 3 error bits in status word
|
||||
- 3 # Error 0 (if no drive error bit then leave empty)
|
||||
- 7 # Error 1 (if no drive error bit then leave empty)
|
||||
- 14 # Error 2 (if no drive error bit then leave empty)
|
||||
|
||||
encoder:
|
||||
numerator: 360 # Scaling numerator example 360 deg/rev
|
||||
denominator: 12800 # Scaling denominator example 4096 ticks per 360 degree
|
||||
# type: 0 # Type: 0=Incremental, 1=Absolute
|
||||
bits: 16 # Total bit count of encoder raw data
|
||||
# absBits: 0 # Absolute bit count (for absolute encoders) always least significant part of 'bits'
|
||||
# absOffset: 0 # Encoder offset in eng units (for absolute encoders)
|
||||
# mask: '0xFFF00' # Mask applied to raw encoder value
|
||||
position: ec0.s$(DRV_SLAVE).positionActual01 # Ethercat entry for actual position input (encoder)
|
||||
control: ec0.s$(DRV_SLAVE).encoderControl01 # mandatory only if 'reset' is used
|
||||
status: ec0.s$(DRV_SLAVE).encoderStatus01 # mandatory only if 'warning' or 'error' are used
|
||||
# ready: 10 # Bit in encoder status word for encoder ready
|
||||
# source: 0 # 0 = Encoder value from etehrcat hardware, 1 = Encoder value from PLC
|
||||
# reset: 1 # Reset (optional)
|
||||
# warning: 2 # Warning (optional)
|
||||
# error: # max 3 (optional)
|
||||
# - 5 # Error 0
|
||||
# - 9 # Error 1
|
||||
# - 11 # Error 2
|
||||
# filter:
|
||||
# velocity:
|
||||
# size: 100 # Filter size for velocity
|
||||
# enable: true # enable velocity filter
|
||||
# position:
|
||||
# size: 100 # Filter size for encoder value
|
||||
# enable: true # enable encoder value filter
|
||||
# latch:
|
||||
# position: '' # Link to latched value. Used for some homing seqs
|
||||
# control: 0 # Bit in encoder control word to arm latch. Used for some homing seqs
|
||||
# status: 0 # Bit in encoder status word for latch triggered status. Used for some homing seqs
|
||||
# primary: 1 # Use this encoder as primary (for control)
|
||||
# homing:
|
||||
# type: 3 # Homing sequence type
|
||||
# position: -30 # Position to reference encoder to
|
||||
# velocity:
|
||||
# to: 10 # Velocity to cam/sensor (used for some homing seqs)
|
||||
# from: 5 # Velocity from cam/sensor (used for some homing seqs)
|
||||
# acceleration: 20 # Acceleration during homing
|
||||
# deceleration: 100 # Deceleration during homing
|
||||
# refToEncIDAtStartup: 1 # At startup then set the start value of this encoder to actpos of this encoder id
|
||||
# refAtHome: 1 # If homing is executed then set position of this encoder
|
||||
# tolToPrim: 0 # If set then this is the max allowed tolerance between prim encoder and this encoder
|
||||
# postMoveEnable: yes # Enable move after successfull homing
|
||||
# postMovePosition: 10 # Position to move to after successfull homing
|
||||
# trigg: ec0.. # Ethercat entry for triggering drive internal homing seq (seq id 26)
|
||||
# ready: ec0.. # Ethercat entry for readinf drive internal homing seq ready (seq id 26)
|
||||
desc: BISS-C
|
||||
numerator: 1 # Scaling numerator example 1 mm/rev
|
||||
denominator: 4096 # Scaling denominator example 4096 ticks per 360 degree
|
||||
type: 1 # Type: 0=Incremental, 1=Absolute
|
||||
bits: 32 # Total bit count of encoder raw data
|
||||
absBits: 26 # Absolute bit count (for absolute encoders) always least significant part of 'bits'
|
||||
absOffset: -15615 # Encoder offset in eng units (for absolute encoders)
|
||||
position: ec0.s$(ENC_SID).positionActual${ENC_CH=01} # Ethercat entry for actual position input (encoder)
|
||||
status: ec0.s$(ENC_SID).encoderStatus${ENC_CH=01} # mandatory only if 'warning' or 'error' are used
|
||||
ready: 2 # Bit in encoder status word for encoder ready
|
||||
warning: 0 # Warning (optional)
|
||||
error: # max 3 (optional)
|
||||
- 1 # Error 0
|
||||
delayComp: # Delay compensation for time between application of setpoint to reading of encoder (normally atleast 2 cycles)
|
||||
time: 0 # Delay time between set and act [cycles]
|
||||
enable: true # enable (defaults to 1 if not set)
|
||||
|
||||
|
||||
controller:
|
||||
Kp: 1 # Kp proportinal gain
|
||||
Ki: 0.02 # Ki integral gain
|
||||
Kd: 0 # Kd derivative gain
|
||||
# Kff: 1 # Feed forward gain
|
||||
# deadband:
|
||||
# tol: 0.01 # Stop control if within this distance from target for the below time
|
||||
# time: 100
|
||||
# limits:
|
||||
# minOutput: -100 # Minimum controller output
|
||||
# maxOutput: 100 # Maximum controller output
|
||||
# minIntegral: -100 # Minimum integral output
|
||||
# maxIntegral: 100 # Maximum integral output
|
||||
# inner:
|
||||
# Kp: 0.1 # Kp for when close to target
|
||||
# Ki: 0.1 # Ki for when close to target
|
||||
# Kd: 0.1 # Kd for when close to target
|
||||
# tol: 0.1 # Distance from target for when inner PID params will be used, defaults to atTarget tol
|
||||
Kp: 10 # Kp proportinal gain
|
||||
Ki: 0 # Ki integral gain
|
||||
Kd: 0 # Kd derivative gain
|
||||
|
||||
trajectory:
|
||||
# type: 1 # Default 0 = trapetz, 1 = S-curve (ruckig)
|
||||
axis:
|
||||
velocity: 500 # Default velo for axis
|
||||
acceleration: 200 # Default acc for axis
|
||||
deceleration: 200 # Default dec for axis
|
||||
emergencyDeceleration: 1000 # Deceleration when axis in error state
|
||||
velocity: 2 # Default velo for axis
|
||||
acceleration: 2 # Default acc for axis
|
||||
deceleration: 2 # Default dec for axis
|
||||
emergencyDeceleration: 5 # Deceleration when axis in error state
|
||||
jerk: 10 # Default jerk for axis
|
||||
jog:
|
||||
velocity: 5 # Default velo fro JOG (motor record)
|
||||
# modulo:
|
||||
# range: 360 # Modulo range 0..360
|
||||
# type: 0 # Modulo type
|
||||
velocity: 1 # Default velo fro JOG (motor record)
|
||||
|
||||
input:
|
||||
limit:
|
||||
forward: ec0.s$(DRV_SLAVE).driveStatus01.12 # Ethercat entry for low limit switch input
|
||||
# forwardPolarity: 0 # Polarity of forward limit switch
|
||||
backward: ec0.s$(DRV_SLAVE).driveStatus01.11 # Ethercat entry for high limit switch input
|
||||
# backwardPolarity: 0 # Polarity of forward limit switch
|
||||
home: 'ec0.s$(DRV_SLAVE).ONE.0' # Ethercat entry for home switch
|
||||
# homePolarity: 0 # Polarity of home switch
|
||||
interlock: 'ec0.s$(DRV_SLAVE).ONE.0' # Ethercat entry for interlock switch input
|
||||
# interlockPolarity: 0 # Polarity of interlock switch
|
||||
|
||||
# homing:
|
||||
# type: 3 # Homing sequence type
|
||||
# position: -30 # Position to reference encoder to
|
||||
# velocity:
|
||||
# to: 10 # Velocity to cam/sensor (used for some homing seqs)
|
||||
# from: 5 # Velocity from cam/sensor (used for some homing seqs)
|
||||
# acc: 20 # Acceleration during homing
|
||||
# dec: 100 # Deceleration during homing
|
||||
# refToEncIDAtStartup: 1 # At startup then set the start value of this encoder to actpos of this encoder id
|
||||
# refAtHome: 1 # If homing is executed then set position of this encoder
|
||||
# tolToPrim: 0 # If set then this is the max allowed tolerance between prim encoder and this encoder
|
||||
# postMoveEnable: yes # Enable move after successfull homing
|
||||
# postMovePosition: 10 # Position to move to after successfull homing
|
||||
# timeout: 100 # Sequence timeout
|
||||
forward: ec0.s$(DRV_SID).driveStatus01.12 # Ethercat entry for low limit switch input
|
||||
backward: ec0.s$(DRV_SID).driveStatus01.11 # Ethercat entry for high limit switch input
|
||||
home: 'ec0.s$(DRV_SID).ONE.0' # Ethercat entry for home switch
|
||||
interlock: 'ec0.s-1.ONE.0' # Ethercat entry for interlock switch input
|
||||
|
||||
softlimits:
|
||||
enable: false # Enable soft limits
|
||||
forward: 100 # Soft limit position fwd
|
||||
forwardEnable: false # Soft limit position fwd enable
|
||||
backward: -100 # Soft limit position bwd
|
||||
backwardEnable: false # Soft limit position bwd enable
|
||||
enable: true # Enable soft limits
|
||||
forward: 30 # Soft limit position fwd
|
||||
forwardEnable: true # Soft limit position fwd enable
|
||||
backward: -30 # Soft limit position bwd
|
||||
backwardEnable: true # Soft limit position bwd enable
|
||||
|
||||
monitoring:
|
||||
lag:
|
||||
enable: true # Enable position lag monitoring (following error)
|
||||
tolerance: 2 # Allowed tolerance
|
||||
tolerance: 0.1 # Allowed tolerance
|
||||
time: 10 # Allowed time outside tolerance target:
|
||||
target:
|
||||
enable: true # Enable at target monitoring (needs to be enabled if using motor record)
|
||||
tolerance: 0.5 # Allowed tolerance
|
||||
time: 10 # Filter time inside tolerance to be at target
|
||||
velocity:
|
||||
enable: false # Enable velocity monitoring
|
||||
max: 100 # Allowed max velocity
|
||||
max: 8 # Allowed max velocity
|
||||
time:
|
||||
trajectory: 100 # Time allowed outside max velo before system init halt
|
||||
drive: 200 # Time allowed outside max velo before system disables drive
|
||||
# velocityDifference:
|
||||
# enable: true # Enable velocity diff monitoring (velo set vs velo act)
|
||||
# max: 100 # Allowed max difference
|
||||
# time:
|
||||
# trajectory: 100 # Time allowed outside max diff velo before system init halt
|
||||
# drive: 200 # Time allowed outside max diff velo before system disables drive
|
||||
|
||||
#plc:
|
||||
# enable: true # Enable axis plc
|
||||
# externalCommands: true # Allow axis to inputs from PLC
|
||||
# file: ${PLC_PATH}test.plc
|
||||
# code: # Sync code
|
||||
# - "if(static.counter % ${LIMIT} == 0){println('AX PLC: Appended');static.counter:=0;};" # calculate set pos for physical axis
|
||||
# - "if(not(static.plc_code_loaded)) {static.counter:=static.counter+1;};"
|
||||
# - ec0.s$(DRV_SLAVE).ONE > 1; # Enable axis if one of master axes is enabled
|
||||
# - ec0.s$(DRV_SLAVE).ZERO > 1; # calculate set pos for physical axis
|
||||
# velocity_filter: # Filter used to smother velocity feedforward
|
||||
# encoder: # Filter plc enc velo
|
||||
# enable: false # Filter enable
|
||||
# size: 100 # Filter size
|
||||
# trajectory: # Filter plc traj velo
|
||||
# enable: false # Filter enable
|
||||
# size: 100 # Filter size
|
||||
target:
|
||||
enable: true # Enable at target monitoring (needs to be enabled if using motor record)
|
||||
tolerance: 0.01 # Allowed tolerance
|
||||
time: 10 # Filter time inside tolerance to be at target
|
||||
|
||||
12
iocsh/cfg/enc_open_loop.yaml
Normal file
12
iocsh/cfg/enc_open_loop.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
encoder:
|
||||
desc: 'Open loop'
|
||||
unit: mm
|
||||
numerator: 1 # Scaling numerator
|
||||
denominator: 12800 # Scaling denominator
|
||||
type: 0 # Type: 0=Incremental, 1=Absolute
|
||||
bits: 16 # Total bit count of encoder raw data
|
||||
absBits: 0 # Absolute bit count (for absolute encoders)
|
||||
absOffset: 0 # Encoder offset in eng units (for absolute encoders)
|
||||
position: ec0.s$(ENC_SID).positionActual01 # Ethercat entry for actual position input (encoder)
|
||||
homing:
|
||||
refToEncIDAtStartup: 1 # Ref encoder at startup (to BISS value)
|
||||
@@ -1,9 +0,0 @@
|
||||
macros: LIMIT=1000,TYPE=1 # Macros to pass to this file (also plc.file)
|
||||
plc:
|
||||
id: 1
|
||||
enable: yes
|
||||
rateMilliseconds: 1
|
||||
file: ${PLC_PATH}test.plc
|
||||
code:
|
||||
- "if(static.counter % ${LIMIT} == 0){println('PLC: Appended');static.counter:=0;};" # calculate set pos for physical axis
|
||||
- "if(not(static.plc_code_loaded)) {static.counter:=static.counter+1;};"
|
||||
@@ -1,9 +0,0 @@
|
||||
###############################################################################################
|
||||
# For help on syntax, variables and functions, please read the file: "plcSyntaxHelp.plc"
|
||||
#
|
||||
# PLC Functionality Demo:
|
||||
# No hardware related variables
|
||||
#
|
||||
|
||||
static.time:=ec_get_time()/1E9;
|
||||
static.sineval:=sin(2*pi*${FREQ=10}*static.time);
|
||||
@@ -1,9 +0,0 @@
|
||||
static.counter:=static.counter+1;
|
||||
static.plc_code_loaded:=1;
|
||||
if(static.counter % ${LIMIT} == 0) {
|
||||
if(${TYPE}=0) {
|
||||
println('AX PLC: File');
|
||||
} else {
|
||||
println('PLC : File');
|
||||
};
|
||||
};
|
||||
22
iocsh/readme.md
Normal file
22
iocsh/readme.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Start IOC
|
||||
```
|
||||
sudo iocsh test_4ax_box.script
|
||||
```
|
||||
|
||||
# Collect data
|
||||
```
|
||||
camon -d -t -nostat -nounit -int c6025a:m0s006-BI08 c6025a:m0s005-BO07 c6025a:Axis1-EnaAct c6025a:Axis1-VelAct
|
||||
|
||||
# for classic camonitor format:
|
||||
/usr/local/epics/base-7.0.7/bin/RHEL8-x86_64/camonitor -n c6025a:m0s006-BI08 c6025a:m0s005-BO07 c6025a:Axis1-EnaAct c6025a:Axis1-VelAct
|
||||
```
|
||||
# Plot
|
||||
```
|
||||
Must be in "classic" camonitor format to use plotCaMonitor.py
|
||||
|
||||
Velo:
|
||||
cat data_log.txt | grep Vel | python3 ~/myhome/sources/ecmccomgui/pyDataManip/plotCaMonitor.py
|
||||
|
||||
Digital:
|
||||
cat data_log.txt | grep -v Vel | python3 ~/myhome/sources/ecmccomgui/pyDataManip/plotCaMonitor.py
|
||||
```
|
||||
@@ -11,8 +11,7 @@
|
||||
## camon c6025a:SS1-first-Err c6025a:SS1-first-RmpDwnCmdAct c6025a:SS1-first-AxsStndStllAct
|
||||
##
|
||||
|
||||
epicsEnvSet(IOC,c6025a)
|
||||
require ecmccfg v9.0.1_RC4,"ECMC_VER=v9.0.1_RC4,ENG_MODE=1"
|
||||
require ecmccfg "ENG_MODE=1,MASTER_ID=0"
|
||||
|
||||
##############################################################################
|
||||
## Load components lib
|
||||
@@ -22,13 +21,22 @@ require ecmccomp
|
||||
##############################################################################
|
||||
## Configure hardware
|
||||
|
||||
epicsEnvSet("DRV_SLAVE", "13")
|
||||
epicsEnvSet("DRV_SLAVE", "7")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=$(DRV_SLAVE), HW_DESC=EL7041-0052"
|
||||
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Motor-Generic-2Phase-Stepper,MACROS='I_STDBY_MA=200,I_MAX_MA=1000,R_COIL_MOHM=1700'"
|
||||
|
||||
epicsEnvSet("ENC_SLAVE", "14")
|
||||
epicsEnvSet("ENC_SLAVE", "2")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=$(ENC_SLAVE), HW_DESC=EL5042"
|
||||
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Encoder-RLS-LA11-24bit-BISS-C"
|
||||
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Encoder-RLS-LA11-26bit-BISS-C,CH_ID=1"
|
||||
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP=Encoder-RLS-LA11-26bit-SSI,CH_ID=2"
|
||||
|
||||
epicsEnvSet("BO_SLAVE", "5")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=$(BO_SLAVE), HW_DESC=EL2008"
|
||||
# This hardware box need to set BO6 to get power
|
||||
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(${BO_SLAVE},binaryOutput06,1)"
|
||||
|
||||
epicsEnvSet("BI_SLAVE", "6")
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=$(BI_SLAVE), HW_DESC=EL1008"
|
||||
|
||||
#Apply hardware configuration
|
||||
ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
|
||||
@@ -37,26 +45,29 @@ ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
|
||||
## AXIS 1
|
||||
#
|
||||
epicsEnvSet("DEV", "$(IOC)")
|
||||
epicsEnvSet("PLC_PATH", "/ioc/c6025a5a/ecmccfg/examples/test/ecmccomp/plc/")
|
||||
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=./cfg/axis.yaml,LIMIT=1000,TYPE=0"
|
||||
|
||||
##############################################################################
|
||||
## PLC 1
|
||||
#
|
||||
#-${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlPlc.cmd, "FILE=./plc/plc_cfg.yaml,LIMIT=5000,TYPE=1"
|
||||
${SCRIPTEXEC} ${ECMC_CONFIG_ROOT}loadYamlAxis.cmd, "FILE=./cfg/axis.yaml"
|
||||
|
||||
##############################################################################
|
||||
## Load safety plugin
|
||||
#
|
||||
require ecmc_plugin_safety v9.0.1_RC4
|
||||
require ecmc_plugin_safety
|
||||
|
||||
# Create SS1 group
|
||||
epicsEnvSet(RAMP_DOWN_CMD,"ec${ECMC_EC_MASTER_ID}.s${DRV_SLAVE}.ZERO.0")
|
||||
epicsEnvSet(STANDSTILL_STAT,"ec${ECMC_EC_MASTER_ID}.s${DRV_SLAVE}.ZERO.1")
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN_CMD=${RAMP_DOWN_CMD},EC_STANDSTILL_STAT=${STANDSTILL_STAT},DELAY_MS=500"
|
||||
#- EC_RAMP_DOWN_CMD : EtherCAT entry for ramp down command, input to ecmc (command from safety PLC/system)
|
||||
#- EC_REST_STAT : EtherCAT entry for signaling that all axes in group are at rest, output from ecmc (feedback to safety PLC/system)
|
||||
#- EC_RED_VEL_CMD : EtherCAT entry for reducing velocity, input to ecmc (command from safety PLC/system)
|
||||
#- DELAY_MS : Time between rampdown command and STO
|
||||
epicsEnvSet(EC_RAMP_DOWN_CMD,"ec${ECMC_EC_MASTER_ID}.s${BI_SLAVE}.binaryInput08.0")
|
||||
epicsEnvSet(EC_REST_STAT,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.binaryOutput07.0")
|
||||
epicsEnvSet(EC_RED_VEL_CMD,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.ONE.0")
|
||||
epicsEnvSet(SAFETY_TIMEOUT,500)
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN_CMD=${EC_RAMP_DOWN_CMD},EC_REST_STAT=${EC_REST_STAT},EC_RED_VEL_CMD=${EC_RED_VEL_CMD=empty},DELAY_MS=${SAFETY_TIMEOUT}"
|
||||
|
||||
#- Add axis
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToGroup.cmd "NAME=first,AX_ID=1,VELO_LIM=1"
|
||||
#- AX_ID : Axis ID
|
||||
#- VELO_REST_LIM : Velocity at rest limit [unit same as EGU of axis]
|
||||
#- VELO_MAX_LIM : Velocity maximum limit when EC_RED_VEL_CMD, set to -1 to disable [unit same as EGU of axis]
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToSafetyGroup.cmd "NAME=first,AX_ID=1,VELO_REST_LIM=1,VELO_MAX_LIM=100"
|
||||
|
||||
##############################################################################
|
||||
## Configure diagnostics:
|
||||
77
iocsh/test_lab_rack.script
Normal file
77
iocsh/test_lab_rack.script
Normal file
@@ -0,0 +1,77 @@
|
||||
##############################################################################
|
||||
#- test config for ecmc_plugin_safety
|
||||
#-
|
||||
#- In this config the interface to safety system is liked to simulated ethercat entries:
|
||||
#- * To allow motion:
|
||||
#- caput c6025a:m0s013-Zero 3
|
||||
#- * To simulate interlock from safety system:
|
||||
#- caput c6025a:m0s013-Zero 0
|
||||
#-
|
||||
#- Monitor status with:
|
||||
#- camon c6025a:SS1-first-Err c6025a:SS1-first-RmpDwnCmdAct c6025a:SS1-first-AxsStndStllAct
|
||||
#-
|
||||
#- ethercat slaves
|
||||
#- 0 0:0 PREOP + EK1100 EtherCAT Coupler (2A E-Bus)
|
||||
#- 1 0:1 PREOP + EL2068 8Ch. Dig Output 24V, 0.5A
|
||||
#- 2 0:2 PREOP + EL2819 16K. Dig. Ausgang 24V, 0,5A, Diagnose
|
||||
#- 3 0:3 PREOP + EL5001 1K. SSI Encoder
|
||||
#- 4 0:4 PREOP + EL6224 (IO Link Master)
|
||||
#- 5 0:5 PREOP + EL2008 8K. Dig. Ausgang 24V, 0.5A
|
||||
#- 6 0:6 PREOP + EL2522 2K. Pulse Train Ausgang
|
||||
#- 7 0:7 PREOP + EL5072 2Ch. Inductive sensor interface (LVDT, Half Bridge)
|
||||
#- 8 0:8 PREOP + EL1008 8K. Dig. Eingang 24V, 3ms
|
||||
#- 9 0:9 PREOP + EL5042 2Ch. BiSS-C Encoder
|
||||
#- 10 0:10 PREOP + EL6692 EtherCAT Bridge-Klemme (Prim<69>r)
|
||||
#- 11 0:11 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
|
||||
#- 12 0:12 PREOP + EL7031 1K. Schrittmotor-Endstufe (24V, 1.5A)
|
||||
#- 13 0:13 PREOP + EL7201 1K. MDP742 Servo-Motor-Endstufe (50V, 4A)
|
||||
#- 14 0:14 PREOP + EL7041-0052 1Ch. Stepper motor output stage (50V, 5A)
|
||||
#- 15 0:15 PREOP + EL7342 2Ch. DC motor output stage (50V, 3.5A)
|
||||
#- 16 0:16 PREOP + EL7411 BLDC Terminal with incremental encoder/Hall, 50 V DC, 4.
|
||||
#- 17 0:17 PREOP + EL7211-9014 1K. MDP742 Servo-Motor-Endstufe mit OCT (50V, 4,5A
|
||||
#- 18 0:18 PREOP + EL9576 Bremschopper Klemme
|
||||
|
||||
require ecmccfg v10.0.0_RC1 "ENG_MODE=1,MASTER_ID=0,ECMC_VER=v10.0.0_RC1"
|
||||
|
||||
# 0:14 - EL7041 1Ch Stepper
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=14,HW_DESC=EL7041-0052"
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}applyComponent.cmd "COMP=Motor-Generic-2Phase-Stepper, MACROS='I_MAX_MA=1500, I_STDBY_MA=1000, U_NOM_MV=48000, R_COIL_MOHM=1230'"
|
||||
epicsEnvSet(DRV_SID,${ECMC_EC_SLAVE_NUM})
|
||||
|
||||
# 0:9 - EL5042 2Ch BiSS-C Encoder, RLS-LA11
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=9,HW_DESC=EL5042"
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}applyComponent.cmd "COMP=Encoder-RLS-LA11-26bit-BISS-C,CH_ID=1"
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}applyComponent.cmd "COMP=Encoder-RLS-LA11-26bit-BISS-C,CH_ID=2"
|
||||
epicsEnvSet(ENC_SID,${ECMC_EC_SLAVE_NUM})
|
||||
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlAxis.cmd, "FILE=./cfg/axis.yaml, DEV=${IOC}, AX_NAME=M1, AXIS_ID=1, DRV_SID=${DRV_SID}, ENC_SID=${ENC_SID}, ENC_CH=01"
|
||||
${SCRIPTEXEC} ${ecmccfg_DIR}loadYamlEnc.cmd, "FILE=./cfg/enc_open_loop.yaml, DEV=${IOC}, ENC_SID=${DRV_SID}"
|
||||
|
||||
|
||||
##############################################################################
|
||||
## Load safety plugin
|
||||
require ecmc_plugin_safety v10.0.0_RC1
|
||||
|
||||
# simulate inputs and outputs in drive "ZERO" and ONE dummy-entry
|
||||
epicsEnvSet(BI_SLAVE,${DRV_SID})
|
||||
epicsEnvSet(BO_SLAVE,${DRV_SID})
|
||||
|
||||
# Create SS1 group
|
||||
#- EC_RAMP_DOWN_CMD : Digital Input: Ethercat entry for ramp down command, input to ecmc (command from safety PLC/system)
|
||||
#- EC_AXES_AT_REST_STAT : Digital Output: Ethercat entry for signaling that all axes in group are at rest, output from ecmc (feedback to safety PLC/system)
|
||||
#- EC_AXES_LIM_VELO_CMD : Digital Input: Ethercat entry for reducing velocity, input to ecmc (command from safety PLC/system)
|
||||
#- DELAY_MS : Time between rampdown command and STO
|
||||
epicsEnvSet(EC_RAMP_DOWN_CMD,"ec${ECMC_EC_MASTER_ID}.s${BI_SLAVE}.ONE.0")
|
||||
epicsEnvSet(EC_AXES_AT_REST_STAT,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.ZERO.0")
|
||||
epicsEnvSet(EC_AXES_LIM_VELO_CMD,"ec${ECMC_EC_MASTER_ID}.s${BO_SLAVE}.ONE.1")
|
||||
epicsEnvSet(SAFETY_TIMEOUT,500)
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addSS1Group.cmd "NAME=first,EC_RAMP_DOWN_CMD=${EC_RAMP_DOWN_CMD},EC_AXES_AT_REST_STAT=${EC_AXES_AT_REST_STAT},EC_AXES_LIM_VELO_CMD=${EC_AXES_LIM_VELO_CMD=empty},DELAY_MS=${SAFETY_TIMEOUT}"
|
||||
|
||||
#- Add axis
|
||||
#- AX_ID : Axis ID
|
||||
#- VELO_REST_LIM : Velocity at rest limit [unit same as EGU of axis]
|
||||
#- VELO_MAX_LIM : Velocity maximum limit, -1 to disable [unit same as EGU of axis]
|
||||
${SCRIPTEXEC} ${ecmc_plugin_safety_DIR}addAxisToSafetyGroup.cmd "NAME=first,AX_ID=1,VELO_REST_LIM=0.01,VELO_MAX_LIM=1"
|
||||
|
||||
ecmcEpicsEnvSetCalc(S_ID, "${DRV_SID}", "%03d")
|
||||
afterInit "dbpf ${IOC}:m${ECMC_EC_MASTER_ID=0}s${S_ID}-One 0"
|
||||
271
qt/ecmc_plugin_safety_group.ui
Normal file
271
qt/ecmc_plugin_safety_group.ui
Normal file
@@ -0,0 +1,271 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>311</width>
|
||||
<height>269</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>35</y>
|
||||
<width>296</width>
|
||||
<height>151</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Diagnostics</string>
|
||||
</property>
|
||||
<widget class="caLabel" name="calabel_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>60</y>
|
||||
<width>206</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reduced velo cmd active:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLed" name="caled_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>245</x>
|
||||
<y>30</y>
|
||||
<width>30</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-$(SAFETY_GRP)-RmpDwnCmdAct</string>
|
||||
</property>
|
||||
<property name="falseColor">
|
||||
<color>
|
||||
<red>0</red>
|
||||
<green>85</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="trueColor">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLed" name="caled_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>245</x>
|
||||
<y>60</y>
|
||||
<width>30</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-$(SAFETY_GRP)-RedVeloCmdAct</string>
|
||||
</property>
|
||||
<property name="falseColor">
|
||||
<color>
|
||||
<red>0</red>
|
||||
<green>85</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="trueColor">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>30</y>
|
||||
<width>246</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>E-Stop (rampdown cmd active):</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>85</y>
|
||||
<width>251</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Axes at rest:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLed" name="caled">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>245</x>
|
||||
<y>88</y>
|
||||
<width>30</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-$(SAFETY_GRP)-AxsStndStllAct</string>
|
||||
</property>
|
||||
<property name="falseColor">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="trueColor">
|
||||
<color>
|
||||
<red>0</red>
|
||||
<green>85</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLineEdit" name="calineedit_47">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>225</x>
|
||||
<y>120</y>
|
||||
<width>61</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-$(SAFETY_GRP)-Dly</string>
|
||||
</property>
|
||||
<property name="colorMode">
|
||||
<enum>caLineEdit::Default</enum>
|
||||
</property>
|
||||
<property name="alarmHandling">
|
||||
<enum>caLineEdit::onBackground</enum>
|
||||
</property>
|
||||
<property name="precisionMode">
|
||||
<enum>caLineEdit::Channel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>115</y>
|
||||
<width>206</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Power off delay [ms]:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>5</y>
|
||||
<width>221</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SS1 group: $(SAFETY_GRP=)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caMultiLineString" name="camultilinestring">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>195</y>
|
||||
<width>291</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Lucida Sans Typewriter</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="plainText">
|
||||
<string>NOTE:
|
||||
ecmc_plugin_safety has NO safety rated
|
||||
features. It only acts as an interface to a
|
||||
dedicated safety system.</string>
|
||||
</property>
|
||||
<property name="fontScaleMode" stdset="0">
|
||||
<enum>caMultiLineString::None</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>caLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>caLabel</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLed</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>caLed</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>caLineEdit</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caMultiLineString</class>
|
||||
<extends>QPlainTextEdit</extends>
|
||||
<header>caMultiLineString</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
458
qt/ecmc_plugin_safety_main.ui
Normal file
458
qt/ecmc_plugin_safety_main.ui
Normal file
@@ -0,0 +1,458 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>146</width>
|
||||
<height>315</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="caLabel" name="calabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>0</y>
|
||||
<width>136</width>
|
||||
<height>36</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Safety plugin</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>35</y>
|
||||
<width>136</width>
|
||||
<height>241</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Group:</string>
|
||||
</property>
|
||||
<widget class="caFrame" name="caframe_11">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>30</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=01,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=1</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_13">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>80</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=03,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=3</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_14">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>105</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=04,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=4</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_15">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>130</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=05,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=5</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_16">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>155</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=06,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=6</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_17">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>180</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=07,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=7</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_12">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_18">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>205</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=08,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=8</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_13">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caFrame" name="caframe_12">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>55</y>
|
||||
<width>120</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="macro">
|
||||
<string notr="true">GRP_ID=02,IOC=$(IOC)</string>
|
||||
</property>
|
||||
<property name="visibility">
|
||||
<enum>caFrame::Calc</enum>
|
||||
</property>
|
||||
<property name="visibilityCalc">
|
||||
<string notr="true">A>=2</string>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
<widget class="caShellCommand" name="cashellcommand_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>5</y>
|
||||
<width>100</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string notr="true">$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="labels">
|
||||
<string>$(GRP_ID)</string>
|
||||
</property>
|
||||
<property name="files">
|
||||
<string>bash /ioc/modules/qt/ecmcOpenObject.sh</string>
|
||||
</property>
|
||||
<property name="args">
|
||||
<string>PLG_SAFETY_GRP $(IOC) $(GRP_ID);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="caLineEdit" name="calineedit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>95</x>
|
||||
<y>285</y>
|
||||
<width>41</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):SS1-GrpCnt</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>285</y>
|
||||
<width>91</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Group cnt:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>caFrame</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>caFrame</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>caLabel</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>caLineEdit</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caShellCommand</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>caShellCommand</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
10
qt/readme.md
Normal file
10
qt/readme.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Panel for plugin
|
||||
```
|
||||
caqtdm -macro "IOC=c6015a-02,SAFETY_GRP=first" ecmc_plugin_safety_main.ui
|
||||
```
|
||||
|
||||
# Panel to simulate motion safety box
|
||||
To be used together with the test scripts in the iocsh dir
|
||||
```
|
||||
caqtdm -macro "IOC=c6015a-02,BI_S_ID=014,BO_S_ID=014" sim_motion_safety_box.ui
|
||||
```
|
||||
247
qt/sim_motion_safety_box.ui
Normal file
247
qt/sim_motion_safety_box.ui
Normal file
@@ -0,0 +1,247 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>341</width>
|
||||
<height>312</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="caByteController" name="cabytecontroller">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>55</x>
|
||||
<y>40</y>
|
||||
<width>40</width>
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):m$(M_ID=0)s$(BI_S_ID)-One</string>
|
||||
</property>
|
||||
<property name="endBit">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="foreground" stdset="0">
|
||||
<color>
|
||||
<red>78</red>
|
||||
<green>154</green>
|
||||
<blue>6</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="background" stdset="0">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="fontScaleMode" stdset="0">
|
||||
<enum>EPushButton::None</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caByte" name="cabyte">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>55</x>
|
||||
<y>200</y>
|
||||
<width>40</width>
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):m$(M_ID=0)s$(BO_S_ID)-Zero</string>
|
||||
</property>
|
||||
<property name="endBit">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="foreground" stdset="0">
|
||||
<color>
|
||||
<red>78</red>
|
||||
<green>154</green>
|
||||
<blue>6</blue>
|
||||
</color>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>125</x>
|
||||
<y>65</y>
|
||||
<width>171</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>E-Stop command</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>125</x>
|
||||
<y>140</y>
|
||||
<width>186</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reduce velo command</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>125</x>
|
||||
<y>225</y>
|
||||
<width>161</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Axes at rest status</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caTextEntry" name="catextentry">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>54</x>
|
||||
<y>280</y>
|
||||
<width>41</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):m$(M_ID=0)s$(BI_S_ID)-One</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>10</y>
|
||||
<width>301</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Simulation of motion safety box</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caByteController" name="cabytecontroller_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>55</x>
|
||||
<y>120</y>
|
||||
<width>40</width>
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<string notr="true">$(IOC):m$(M_ID=0)s$(BI_S_ID)-One</string>
|
||||
</property>
|
||||
<property name="startBit">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="endBit">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="foreground" stdset="0">
|
||||
<color>
|
||||
<red>78</red>
|
||||
<green>154</green>
|
||||
<blue>6</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="background" stdset="0">
|
||||
<color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="fontScaleMode" stdset="0">
|
||||
<enum>EPushButton::None</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>135</x>
|
||||
<y>85</y>
|
||||
<width>131</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(Ramp down command)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="caLabel" name="calabel_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>275</y>
|
||||
<width>171</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Command PV (ONE)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>caTextEntry</class>
|
||||
<extends>caLineEdit</extends>
|
||||
<header>caTextEntry</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caByteController</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>caByteController</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>caLabel</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>caLineEdit</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>caByte</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>caByte</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#==============================================================================
|
||||
# addAxisToGroup.cmd
|
||||
# addAxisToSafetyGroup.cmd
|
||||
#-
|
||||
#- !!!!!!!!!!!!! IMPORTANT !!!!!!!!!
|
||||
#- This plugin has _NO_ safety rated functionalities.
|
||||
@@ -17,14 +17,19 @@
|
||||
#- Arguments:
|
||||
#- NAME : Name of safety group
|
||||
#- AX_ID : Axis ID
|
||||
#- VELO_LIM : Velocity standstill limit [unit same as EGU of axis]
|
||||
#- VELO_REST_LIM : Velocity at rest limit [unit same as EGU of axis]
|
||||
#- VELO_MAX_LIM : Velocity maximum limit when EC_RED_VEL_CMD, set to -1 to disable [unit same as EGU of axis]
|
||||
#-
|
||||
#################################################################################
|
||||
|
||||
#- ecmcAddAxisToSafetyGroup(<group_name>, <axis_index>, <velo_limit>, <filter_time>)
|
||||
#- <name> : Name of safety group to add axis to.
|
||||
#- <Axis id> : Axis index to add (ecmc axis index).
|
||||
#- <velo limit> : Axis standstill velo limit [unit of axis].
|
||||
#- <velo_rest_limit> : Axis at rest velo limit [unit of axis].
|
||||
#- <velo_max_limit> : Velocity maximum limit when EC_RED_VEL_CMD, set to -1 to disable [unit same as EGU of axis]
|
||||
#- <filter_time> : NOT USED (for future implemenation). Time for axis to be below velo limit [ms].
|
||||
|
||||
ecmcAddAxisToSafetyGroup("${NAME}",${AX_ID},${VELO_LIM=0},0)
|
||||
ecmcAddAxisToSafetyGroup("${NAME}",${AX_ID},${VELO_REST_LIM=0},0,${VELO_MAX_LIM=0.0})
|
||||
|
||||
#- Load SS1 axis records
|
||||
dbLoadRecords("ecmcSS1Axis.template","AXIS_PREFIX=${ECMC_MOTOR_${AX_ID}_FULL_NAME=},NAME=${NAME},VEL_MAX_LIM=${VELO_MAX_LIM=0.0},VEL_REST_LIM=${VELO_REST_LIM=0.0}")
|
||||
@@ -15,19 +15,26 @@
|
||||
#-###############################################################################
|
||||
#-
|
||||
#- Arguments:
|
||||
#- NAME : Name of safety group
|
||||
#- EC_RAMP_DOWN : Ethercat entry for rampd down command, input to ecmc (command from safety PLC/system)
|
||||
#- EC_AXES_STANDSTILL : Ethercat entry for all axes in group at standstill, output from ecmc (feedback to safety PLC/system)
|
||||
#- DELAY_MS : Time between rampdown command and STO
|
||||
#- NAME : Name of safety group
|
||||
#- EC_RAMP_DOWN_CMD : Ethercat entry for ramp down command, input to ecmc (command from safety PLC/system)
|
||||
#- EC_AXES_REST_STAT : Ethercat entry for signaling that all axes in group are at rest, output from ecmc (feedback to safety PLC/system)
|
||||
#- EC_AXES_LIM_VELO_CMD : Ethercat entry for reducing velocity, input to ecmc (command from safety PLC/system)
|
||||
#- DELAY_MS : Time between rampdown command and STO
|
||||
#-
|
||||
#################################################################################
|
||||
|
||||
#- ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<time_delay_ms>)
|
||||
#- <name> : Name of group.
|
||||
#- <ec_rampdown> : Ethercat entry input for rampdown cmd.
|
||||
#- <ec_standstill> : Ethercat entry output for group standstill status.
|
||||
#- <time_delay_ms> : Time delay of STO [ms].
|
||||
ecmcAddSS1SafetyGroup("${NAME}","${EC_RAMP_DOWN}","${EC_AXES_STANDSTILL}",${DELAY_MS=0})
|
||||
#-Use ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<time_delay_ms>)
|
||||
#- <name> : Name of group
|
||||
#- <ec_rampdown_cmd> : Ethercat entry input for rampdown cmd
|
||||
#- <ec_standstill_status> : Ethercat entry output for group standstill status
|
||||
#- <ec_red_velo_cmd> : Ethercat entry input for activation of maximum velo limitation (set to "empty" to disable)
|
||||
#- <time_delay_ms> : Time delay of STO [ms]
|
||||
|
||||
|
||||
ecmcAddSS1SafetyGroup("${NAME}","${EC_RAMP_DOWN_CMD}","${EC_AXES_AT_REST_STAT}","${EC_AXES_LIM_VELO_CMD=empty}",${DELAY_MS=0})
|
||||
|
||||
ecmcEpicsEnvSetCalc(ECMC_PLG_SAFETY_GRP_CNT, "${ECMC_PLG_SAFETY_GRP_CNT=0}+1", "%02d")
|
||||
|
||||
#- Load SS1 group records
|
||||
dbLoadRecords("ss1.template","P=${ECMC_PREFIX},NAME=${NAME}")
|
||||
dbLoadRecords("ecmcSS1Group.template","P=${ECMC_PREFIX},NAME=${NAME},ID=${ECMC_PLG_SAFETY_GRP_CNT},COUNT=${ECMC_PLG_SAFETY_GRP_CNT},DELAY=${DELAY_MS=0}")
|
||||
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
* Created on: jan 29, 2024
|
||||
* Author: anderssandstrom
|
||||
*
|
||||
* Instructions:
|
||||
* - IMPORTANT: Add "USR_CFLAGS +=-DECMC_PLUGIN_MODULE_NAME=${MODULE}" to GNUMakefile
|
||||
* - All functions and ecmcPluginData struct must be declared static
|
||||
\*************************************************************************/
|
||||
|
||||
// Needed to get headers in ecmc right...
|
||||
#define ECMC_IS_PLUGIN
|
||||
#define ECMC_PLUGIN_VERSION 0
|
||||
#define ECMC_PLUGIN_VERSION 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -31,11 +34,11 @@ static int alreadyLoaded = 0;
|
||||
static int destructs_ = 0;
|
||||
|
||||
/** Optional.
|
||||
* Will be called once after successfull load into ecmc.
|
||||
* Will be called once after successful load into ecmc.
|
||||
* Return value other than 0 will be considered error.
|
||||
* configStr can be used for configuration parameters.
|
||||
**/
|
||||
int safetyConstruct(char *configStr)
|
||||
static int construct(char *configStr)
|
||||
{
|
||||
|
||||
if(alreadyLoaded) {
|
||||
@@ -50,19 +53,19 @@ int safetyConstruct(char *configStr)
|
||||
/** Optional function.
|
||||
* Will be called once at unload.
|
||||
**/
|
||||
void safetyDestruct(void)
|
||||
static void safetyDestruct(void)
|
||||
{
|
||||
destructs_ = 1;
|
||||
deleteAllSafetyGroups();
|
||||
}
|
||||
|
||||
/** Optional function.
|
||||
* Will be called each realtime cycle if definded
|
||||
* ecmcError: Error code of ecmc. Makes it posible for
|
||||
* Will be called each realtime cycle if defined
|
||||
* ecmcError: Error code of ecmc. Makes it possible for
|
||||
* this plugin to react on ecmc errors
|
||||
* Return value other than 0 will be considered to be an error code in ecmc.
|
||||
**/
|
||||
int safetyRealtime(int ecmcError)
|
||||
static int safetyRealtime(int ecmcError)
|
||||
{
|
||||
if(destructs_) return 0;
|
||||
|
||||
@@ -71,10 +74,10 @@ int safetyRealtime(int ecmcError)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Link to data source here since all sources should be availabe at this stage
|
||||
/** Link to data source here since all sources should be available at this stage
|
||||
* (for example ecmc PLC variables are defined only at enter of realtime)
|
||||
**/
|
||||
int safetyEnterRT(){
|
||||
static int safetyEnterRT(){
|
||||
return validate();
|
||||
}
|
||||
|
||||
@@ -82,37 +85,12 @@ int safetyEnterRT(){
|
||||
* Will be called once just before leaving realtime mode
|
||||
* Return value other than 0 will be considered error.
|
||||
**/
|
||||
int safetyExitRT(void){
|
||||
static int safetyExitRT(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// Plc function for clear of buffers
|
||||
//double fft_clear(double index) {
|
||||
// return (double)clearFFT((int)index);
|
||||
//}
|
||||
//
|
||||
//// Plc function for enable
|
||||
//double fft_enable(double index, double enable) {
|
||||
// return (double)enableFFT((int)index, (int)enable);
|
||||
//}
|
||||
//
|
||||
//// Plc function for trigg new measurement (will clear buffers)
|
||||
//double fft_trigg(double index) {
|
||||
// return (double)triggFFT((int)index);
|
||||
//}
|
||||
//
|
||||
//// Plc function for enable
|
||||
//double fft_mode(double index, double mode) {
|
||||
// return (double)modeFFT((int)index, (FFT_MODE)((int)mode));
|
||||
//}
|
||||
//
|
||||
//// Plc function for enable
|
||||
//double fft_stat(double index) {
|
||||
// return (double)statFFT((int)index);
|
||||
//}
|
||||
|
||||
// Register data for plugin so ecmc know what to use
|
||||
struct ecmcPluginData pluginDataDef = {
|
||||
static struct ecmcPluginData pluginDataDef = {
|
||||
// Allways use ECMC_PLUG_VERSION_MAGIC
|
||||
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
|
||||
// Name
|
||||
@@ -124,170 +102,19 @@ struct ecmcPluginData pluginDataDef = {
|
||||
,
|
||||
// Plugin version
|
||||
.version = ECMC_PLUGIN_VERSION,
|
||||
// Optional construct func, called once at load. NULL if not definded.
|
||||
.constructFnc = safetyConstruct,
|
||||
// Optional destruct func, called once at unload. NULL if not definded.
|
||||
// Optional construct func, called once at load. NULL if not defined.
|
||||
.constructFnc = construct,
|
||||
// Optional destruct func, called once at unload. NULL if not defined.
|
||||
.destructFnc = safetyDestruct,
|
||||
// Optional func that will be called each rt cycle. NULL if not definded.
|
||||
// Optional func that will be called each rt cycle. NULL if not defined.
|
||||
.realtimeFnc = safetyRealtime,
|
||||
// Optional func that will be called once just before enter realtime mode
|
||||
.realtimeEnterFnc = safetyEnterRT,
|
||||
// Optional func that will be called once just before exit realtime mode
|
||||
.realtimeExitFnc = safetyExitRT,
|
||||
// PLC funcs
|
||||
// .funcs[0] =
|
||||
// { /*----fft_clear----*/
|
||||
// // Function name (this is the name you use in ecmc plc-code)
|
||||
// .funcName = "fft_clear",
|
||||
// // Function description
|
||||
// .funcDesc = "double fft_clear(index) : Clear/reset fft[index].",
|
||||
// /**
|
||||
// * 7 different prototypes allowed (only doubles since reg in plc).
|
||||
// * Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
// **/
|
||||
// .funcArg0 = NULL,
|
||||
// .funcArg1 = fft_clear,
|
||||
// .funcArg2 = NULL,
|
||||
// .funcArg3 = NULL,
|
||||
// .funcArg4 = NULL,
|
||||
// .funcArg5 = NULL,
|
||||
// .funcArg6 = NULL,
|
||||
// .funcArg7 = NULL,
|
||||
// .funcArg8 = NULL,
|
||||
// .funcArg9 = NULL,
|
||||
// .funcArg10 = NULL,
|
||||
// .funcGenericObj = NULL,
|
||||
// },
|
||||
// .funcs[1] =
|
||||
// { /*----fft_enable----*/
|
||||
// // Function name (this is the name you use in ecmc plc-code)
|
||||
// .funcName = "fft_enable",
|
||||
// // Function description
|
||||
// .funcDesc = "double fft_enable(index, enable) : Set enable for fft[index].",
|
||||
// /**
|
||||
// * 7 different prototypes allowed (only doubles since reg in plc).
|
||||
// * Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
// **/
|
||||
// .funcArg0 = NULL,
|
||||
// .funcArg1 = NULL,
|
||||
// .funcArg2 = fft_enable,
|
||||
// .funcArg3 = NULL,
|
||||
// .funcArg4 = NULL,
|
||||
// .funcArg5 = NULL,
|
||||
// .funcArg6 = NULL,
|
||||
// .funcArg7 = NULL,
|
||||
// .funcArg8 = NULL,
|
||||
// .funcArg9 = NULL,
|
||||
// .funcArg10 = NULL,
|
||||
// .funcGenericObj = NULL,
|
||||
// },
|
||||
// .funcs[2] =
|
||||
// { /*----fft_trigg----*/
|
||||
// // Function name (this is the name you use in ecmc plc-code)
|
||||
// .funcName = "fft_trigg",
|
||||
// // Function description
|
||||
// .funcDesc = "double fft_trigg(index) : Trigg new measurement for fft[index]. Will clear buffers.",
|
||||
// /**
|
||||
// * 7 different prototypes allowed (only doubles since reg in plc).
|
||||
// * Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
// **/
|
||||
// .funcArg0 = NULL,
|
||||
// .funcArg1 = fft_trigg,
|
||||
// .funcArg2 = NULL,
|
||||
// .funcArg3 = NULL,
|
||||
// .funcArg4 = NULL,
|
||||
// .funcArg5 = NULL,
|
||||
// .funcArg6 = NULL,
|
||||
// .funcArg7 = NULL,
|
||||
// .funcArg8 = NULL,
|
||||
// .funcArg9 = NULL,
|
||||
// .funcArg10 = NULL,
|
||||
// .funcGenericObj = NULL,
|
||||
// },
|
||||
// .funcs[3] =
|
||||
// { /*----fft_mode----*/
|
||||
// // Function name (this is the name you use in ecmc plc-code)
|
||||
// .funcName = "fft_mode",
|
||||
// // Function description
|
||||
// .funcDesc = "double fft_mode(index, mode) : Set mode Cont(1)/Trigg(2) for fft[index].",
|
||||
// /**
|
||||
// * 7 different prototypes allowed (only doubles since reg in plc).
|
||||
// * Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
// **/
|
||||
// .funcArg0 = NULL,
|
||||
// .funcArg1 = NULL,
|
||||
// .funcArg2 = fft_mode,
|
||||
// .funcArg3 = NULL,
|
||||
// .funcArg4 = NULL,
|
||||
// .funcArg5 = NULL,
|
||||
// .funcArg6 = NULL,
|
||||
// .funcArg7 = NULL,
|
||||
// .funcArg8 = NULL,
|
||||
// .funcArg9 = NULL,
|
||||
// .funcArg10 = NULL,
|
||||
// .funcGenericObj = NULL,
|
||||
// },
|
||||
// .funcs[4] =
|
||||
// { /*----fft_stat----*/
|
||||
// // Function name (this is the name you use in ecmc plc-code)
|
||||
// .funcName = "fft_stat",
|
||||
// // Function description
|
||||
// .funcDesc = "double fft_stat(index) : Get status of fft (NO_STAT, IDLE, ACQ, CALC) for fft[index].",
|
||||
// /**
|
||||
// * 7 different prototypes allowed (only doubles since reg in plc).
|
||||
// * Only funcArg${argCount} func shall be assigned the rest set to NULL.
|
||||
// **/
|
||||
// .funcArg0 = NULL,
|
||||
// .funcArg1 = fft_stat,
|
||||
// .funcArg2 = NULL,
|
||||
// .funcArg3 = NULL,
|
||||
// .funcArg4 = NULL,
|
||||
// .funcArg5 = NULL,
|
||||
// .funcArg6 = NULL,
|
||||
// .funcArg7 = NULL,
|
||||
// .funcArg8 = NULL,
|
||||
// .funcArg9 = NULL,
|
||||
// .funcArg10 = NULL,
|
||||
// .funcGenericObj = NULL,
|
||||
// },
|
||||
.funcs[0] = {0}, // last element set all to zero..
|
||||
// PLC consts
|
||||
/* CONTINIOUS MODE = 1 */
|
||||
// .consts[0] = {
|
||||
// .constName = "fft_CONT",
|
||||
// .constDesc = "FFT Mode: Continious",
|
||||
// .constValue = CONT
|
||||
// },
|
||||
// /* TRIGGERED MODE = 2 */
|
||||
// .consts[1] = {
|
||||
// .constName = "fft_TRIGG",
|
||||
// .constDesc = "FFT Mode :Triggered",
|
||||
// .constValue = TRIGG
|
||||
// },
|
||||
// /* TRIGGERED MODE = 2 */
|
||||
// .consts[2] = {
|
||||
// .constName = "fft_NO_STAT",
|
||||
// .constDesc = "FFT Status: Invalid state",
|
||||
// .constValue = NO_STAT,
|
||||
// },
|
||||
// /* TRIGGERED MODE = 2 */
|
||||
// .consts[3] = {
|
||||
// .constName = "fft_IDLE",
|
||||
// .constDesc = "FFT Status: Idle state (waiting for trigger)",
|
||||
// .constValue = IDLE
|
||||
// },
|
||||
// /* TRIGGERED MODE = 2 */
|
||||
// .consts[4] = {
|
||||
// .constName = "fft_ACQ",
|
||||
// .constDesc = "FFT Status: Acquiring data",
|
||||
// .constValue = ACQ
|
||||
// },
|
||||
// /* TRIGGERED MODE = 2 */
|
||||
// .consts[5] = {
|
||||
// .constName = "fft_CALC",
|
||||
// .constDesc = "FFT Status: Calculating result",
|
||||
// .constValue = CALC
|
||||
// },
|
||||
.consts[0] = {0}, // last element set all to zero..
|
||||
};
|
||||
|
||||
|
||||
@@ -35,11 +35,12 @@ extern DBBASE *pdbbase;
|
||||
* - runtime_error
|
||||
*/
|
||||
ecmcSS1SafetyGroup::ecmcSS1SafetyGroup(const char *name,
|
||||
const char *ec_rampdown_cmd,
|
||||
const char *ec_standstill_status,
|
||||
int time_delay_ms,
|
||||
const char *cfg_string,
|
||||
char* portName)
|
||||
const char *ec_rampdown_cmd,
|
||||
const char *ec_standstill_status,
|
||||
const char *ec_limit_velo,
|
||||
int time_delay_ms,
|
||||
const char *cfg_string,
|
||||
char* portName)
|
||||
: asynPortDriver(portName,
|
||||
1, /* maxAddr */
|
||||
asynInt32Mask | asynFloat64Mask | asynFloat32ArrayMask |
|
||||
@@ -55,49 +56,62 @@ ecmcSS1SafetyGroup::ecmcSS1SafetyGroup(const char *name,
|
||||
0, /* Default priority */
|
||||
0) /* Default stack size */
|
||||
{
|
||||
sName_ = strdup(name);
|
||||
sEcRampDownCmdNameOrg_ = strdup(ec_rampdown_cmd);
|
||||
sEcAxesStandStillStatOrg_= strdup(ec_standstill_status);
|
||||
sEcRampDownCmdNameStrip_ = strdup(ec_rampdown_cmd);
|
||||
sEcAxesStandStillStatStrip_ = strdup(ec_standstill_status);
|
||||
sConfig_ = strdup(cfg_string);
|
||||
delayMs_ = time_delay_ms;
|
||||
sName_ = strdup(name);
|
||||
sEcRampDownCmdNameOrg_ = strdup(ec_rampdown_cmd);
|
||||
sEcAxesStandStillStatOrg_ = strdup(ec_standstill_status);
|
||||
sEcLimitVeloOrg_ = strdup(ec_limit_velo);
|
||||
limitMaxVeloEnable_ = 1;
|
||||
|
||||
if(strcmp(sEcLimitVeloOrg_, "empty") == 0) {
|
||||
limitMaxVeloEnable_ = 0;
|
||||
}
|
||||
|
||||
sConfig_ = strdup(cfg_string);
|
||||
delayMs_ = time_delay_ms;
|
||||
ptrStatus_ = (int*)&status_;
|
||||
asynStatusId_ = -1;
|
||||
axesCounter_ = 0;
|
||||
ecmcSampleRateHz_ = getEcmcSampleRate();
|
||||
dataSourcesLinked_ = 0;
|
||||
ecMaster_ = NULL;
|
||||
ecEntryRampDown_ = NULL;
|
||||
ecEntryStandstill_ = NULL;
|
||||
ecEntryLimitVelo_ = NULL;
|
||||
masterId_ = 0;
|
||||
slaveIdRampDown_ = 0;
|
||||
bitRampDown_ = 0;
|
||||
slaveIdStandStill_ = 0;
|
||||
bitStandStill_ = 0;
|
||||
aliasRampDown_[0] = 0;
|
||||
aliasStandStill_[0] = 0;
|
||||
aliasLimitVelo_[0] = 0;
|
||||
rampDownCmd_ = 0;
|
||||
axesAreStandstill_ = 0;
|
||||
rampDownCmdOld_ = 0;
|
||||
axesAreStandstillOld_ = 0;
|
||||
printEnableStatus_ = 1;
|
||||
limitVeloCmdOld_ = 0;
|
||||
limitVeloCmd_ = 0;
|
||||
axesDisabled_ = 0;
|
||||
cfgDbgMode_ = 0;
|
||||
oldStop_ = 0;
|
||||
memset(&status_,0,sizeof(status_));
|
||||
ptrStatus_ = (int*)&status_;
|
||||
asynStatusId_ = -1;
|
||||
axesCounter_ = 0;
|
||||
ecmcSampleRateHz_ = getEcmcSampleRate();
|
||||
dataSourcesLinked_ = 0;
|
||||
ecMaster_ = NULL;
|
||||
ecEntryRampDown_ = NULL;
|
||||
ecEntryStandstill_ = NULL;
|
||||
masterId_ = 0;
|
||||
slaveIdRampDown_ = 0;
|
||||
bitRampDown_ = 0;
|
||||
slaveIdStandStill_ = 0;
|
||||
bitStandStill_ = 0;
|
||||
aliasRampDown_[0] = 0;
|
||||
aliasStandStill_[0] = 0;
|
||||
rampDownCmd_ = 0;
|
||||
axesAreStandstill_ = 0;
|
||||
rampDownCmdOld_ = 0;
|
||||
axesAreStandstillOld_ = 0;
|
||||
printEnableStatus_ = 1;
|
||||
|
||||
// Config defaults
|
||||
cfgDbgMode_ = 0;
|
||||
parseConfigStr(cfg_string);
|
||||
initAsyn();
|
||||
if(cfgDbgMode_) {
|
||||
printf("Safety %s: Safety group created:\n"
|
||||
" Type: SS1\n"
|
||||
" Name: %s\n"
|
||||
" I/O for rampdown command from saftey PLC: %s\n"
|
||||
" I/O for axes standstill status: %s\n"
|
||||
" STO delay [ms]: %d\n"
|
||||
" Configuration string: %s\n",
|
||||
printf("Safety %s: Group created:\n"
|
||||
" Type: SS1-t\n"
|
||||
" Name: %s\n"
|
||||
" I/O for rampdown command from saftey PLC: %s\n"
|
||||
" I/O for axes standstill status: %s\n"
|
||||
" I/O for velo limit command from safety PLC: %s (%s)\n"
|
||||
" STO delay [ms]: %d\n"
|
||||
" Configuration string: %s\n",
|
||||
sName_,sName_,sEcRampDownCmdNameOrg_,
|
||||
sEcAxesStandStillStatOrg_,delayMs_,sConfig_);
|
||||
sEcAxesStandStillStatOrg_,sEcLimitVeloOrg_,
|
||||
limitMaxVeloEnable_ ? "enabled" : "disabled",
|
||||
delayMs_,sConfig_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +123,8 @@ ecmcSS1SafetyGroup::~ecmcSS1SafetyGroup() {
|
||||
free(sName_);
|
||||
free(sEcRampDownCmdNameOrg_);
|
||||
free(sEcAxesStandStillStatOrg_);
|
||||
free(sEcRampDownCmdNameStrip_);
|
||||
free(sEcAxesStandStillStatStrip_);
|
||||
free(sConfig_);
|
||||
free(sEcLimitVeloOrg_);
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::parseConfigStr(const char *configStr) {
|
||||
@@ -167,8 +180,20 @@ void ecmcSS1SafetyGroup::validateCfgs() {
|
||||
&bitStandStill_)) {
|
||||
throw std::runtime_error( "Safety: Parse error: Data source for standstill status.");
|
||||
}
|
||||
|
||||
// init to masterIdRampDown if case !limitMaxVeloEnable_
|
||||
int masterIdLimitVelo = masterIdStandStill;
|
||||
if(limitMaxVeloEnable_) {
|
||||
if(parseEcPath(sEcLimitVeloOrg_,
|
||||
&masterIdLimitVelo,
|
||||
&slaveIdLimitVelo_,
|
||||
aliasLimitVelo_,
|
||||
&bitLimitVelo_)) {
|
||||
throw std::runtime_error( "Safety: Parse error: Data source for limit velo.");
|
||||
}
|
||||
}
|
||||
|
||||
if(masterIdStandStill != masterIdRampDown ) {
|
||||
if(masterIdStandStill != masterIdRampDown || masterIdLimitVelo != masterIdRampDown) {
|
||||
throw std::runtime_error( "Safety: Parse error: Master id for datasources different.");
|
||||
}
|
||||
masterId_ = masterIdStandStill;
|
||||
@@ -180,6 +205,10 @@ void ecmcSS1SafetyGroup::validateCfgs() {
|
||||
if(bitStandStill_ < 0) {
|
||||
throw std::runtime_error( "Safety: Parse error: Standstill status, bit invalid.");
|
||||
}
|
||||
|
||||
if(bitLimitVelo_ < 0) {
|
||||
throw std::runtime_error( "Safety: Parse error: Limit velo, bit invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::validateAxes() {
|
||||
@@ -226,6 +255,22 @@ void ecmcSS1SafetyGroup::validateAxes() {
|
||||
printf("Safety %s: Error, group empty (axis count zero)\n",sName_);
|
||||
throw std::runtime_error( "Safety: Error, empty group not allowed.");
|
||||
}
|
||||
|
||||
// Check if max velo enabled in axis
|
||||
int axesMaxVeloEnabled = 0;
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
axesMaxVeloEnabled = (*saxis)->veloMaxLimitEnabled_ || axesMaxVeloEnabled;
|
||||
}
|
||||
|
||||
if(limitMaxVeloEnable_ && !axesMaxVeloEnabled) {
|
||||
printf("Safety %s: Error, Limit max velo enabled but no axis configured with max velo\n",sName_);
|
||||
throw std::runtime_error( "Safety: Error, Limit max velo enabled but no axis configured with max velo");
|
||||
}
|
||||
|
||||
if(!limitMaxVeloEnable_ && axesMaxVeloEnabled) {
|
||||
printf("Safety %s: Error, Limit max velo disabled but axis configured with a max velo\n",sName_);
|
||||
throw std::runtime_error( "Safety: Error, Limit max velo disabled but axis configured with a max velo");
|
||||
}
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::connectToDataSources() {
|
||||
@@ -247,6 +292,10 @@ void ecmcSS1SafetyGroup::connectToDataSources() {
|
||||
throw std::runtime_error( "Safety: EtherCAT entry for rampdown I/O NULL.");
|
||||
}
|
||||
|
||||
if(bitRampDown_ >= ecEntryRampDown_->getBits()) {
|
||||
throw std::runtime_error( "Safety: Bit out of range for rampdown ethercat entry.");
|
||||
}
|
||||
|
||||
// standstill
|
||||
slave = ecMaster_->findSlave(slaveIdStandStill_);
|
||||
if(!slave) {
|
||||
@@ -255,30 +304,32 @@ void ecmcSS1SafetyGroup::connectToDataSources() {
|
||||
|
||||
ecEntryStandstill_ = slave->findEntry(aliasStandStill_);
|
||||
if(!ecEntryStandstill_) {
|
||||
throw std::runtime_error( "Safety: EtherCAT entry for rampdown I/O NULL.");
|
||||
throw std::runtime_error( "Safety: EtherCAT entry for standstill I/O NULL.");
|
||||
};
|
||||
|
||||
if(bitStandStill_ >= ecEntryStandstill_->getBits()) {
|
||||
throw std::runtime_error( "Safety: Bit out of range for standstill ethercat entry.");
|
||||
}
|
||||
|
||||
// Limit velo
|
||||
if( limitMaxVeloEnable_ ) {
|
||||
slave = ecMaster_->findSlave(slaveIdLimitVelo_);
|
||||
if(!slave) {
|
||||
throw std::runtime_error( "Safety: EtherCAT slave limit velo I/O NULL.");
|
||||
}
|
||||
|
||||
ecEntryLimitVelo_ = slave->findEntry(aliasLimitVelo_);
|
||||
if(!ecEntryLimitVelo_) {
|
||||
throw std::runtime_error( "Safety: EtherCAT entry for limit velo I/O NULL.");
|
||||
};
|
||||
|
||||
if(bitLimitVelo_ >= ecEntryLimitVelo_->getBits()) {
|
||||
throw std::runtime_error( "Safety: Bit out of range for limit velo ethercat entry.");
|
||||
}
|
||||
}
|
||||
dataSourcesLinked_ = 1;
|
||||
|
||||
return;
|
||||
|
||||
//// Get dataItem for rampdown command
|
||||
//dataItemRampDownCmd_ = (ecmcDataItem*) getEcmcDataItem(sEcRampDownCmdNameStrip_);
|
||||
//if(!dataItemRampDownCmd_) {
|
||||
// throw std::runtime_error( "Safety: Data item for ramp down command NULL.");
|
||||
//}
|
||||
//
|
||||
//// Get dataItem for axes standstill status
|
||||
//dataItemStandStillStat_ = (ecmcDataItem*) getEcmcDataItem(sEcAxesStandStillStatStrip_);
|
||||
//if(!dataItemStandStillStat_) {
|
||||
// throw std::runtime_error( "Safety: Data item for axes standstill status NULL.");
|
||||
//}
|
||||
//
|
||||
//if(cfgDbgMode_) {
|
||||
// printf("Safety: Safety group \"%s\"\": Data sources linked.\n",sName_);
|
||||
//}
|
||||
//
|
||||
//dataSourcesLinked_ = 1;
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::refreshAsyn() {
|
||||
@@ -318,9 +369,8 @@ std::string ecmcSS1SafetyGroup::to_string(int value) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// Executed by ecmc rt thread.
|
||||
void ecmcSS1SafetyGroup::execute() {
|
||||
|
||||
// Ramp down and disable if safety interlock
|
||||
void ecmcSS1SafetyGroup::exeRampDown() {
|
||||
uint64_t data = 0;
|
||||
// Read ramp down command from safety plc
|
||||
if(ecEntryRampDown_->readBit(bitRampDown_,
|
||||
@@ -333,7 +383,7 @@ void ecmcSS1SafetyGroup::execute() {
|
||||
}
|
||||
|
||||
rampDownCmdOld_ = rampDownCmd_;
|
||||
rampDownCmd_ = data == 0;
|
||||
rampDownCmd_ = data == 0;
|
||||
|
||||
if(rampDownCmdOld_ != rampDownCmd_) {
|
||||
|
||||
@@ -353,8 +403,12 @@ void ecmcSS1SafetyGroup::execute() {
|
||||
|
||||
// set safety interlock in ecmc
|
||||
setAxesSafetyInterlocks(rampDownCmd_);
|
||||
|
||||
axesDisabled_ = checkAxesDisabled();
|
||||
|
||||
// check if axes are standstill to safety PLC
|
||||
axesAreStandstill_ = checkAxesStandstillAndDisableIfNeeded();
|
||||
|
||||
setAxesStandstillStatus(axesAreStandstill_);
|
||||
|
||||
// Disable
|
||||
@@ -365,6 +419,56 @@ void ecmcSS1SafetyGroup::execute() {
|
||||
}
|
||||
}
|
||||
|
||||
// Limit velo if needed
|
||||
void ecmcSS1SafetyGroup::exeLimitVelo() {
|
||||
|
||||
if(!limitMaxVeloEnable_) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t data = 0;
|
||||
// Read ramp down command from safety plc
|
||||
if(ecEntryLimitVelo_->readBit(bitLimitVelo_,
|
||||
&data)) {
|
||||
// Disable all axes
|
||||
setAxesDisable(); // disable
|
||||
setAxesSafetyInterlocks(0); // stop
|
||||
setAxesStandstillStatus(0); // set output
|
||||
throw std::out_of_range("Safety: Read limit velo cmd failed");
|
||||
}
|
||||
|
||||
limitVeloCmdOld_ = limitVeloCmd_;
|
||||
limitVeloCmd_ = data == 0;
|
||||
|
||||
if(limitVeloCmdOld_ != limitVeloCmd_) {
|
||||
// Update asyn status wd
|
||||
status_.limitVeloCmdActive = limitVeloCmd_;
|
||||
refreshAsyn();
|
||||
|
||||
resetPrintoutStatus();
|
||||
if(cfgDbgMode_) {
|
||||
if(limitVeloCmd_) {
|
||||
printf("Safety %s: Limit velo cmd active\n",sName_);
|
||||
} else {
|
||||
printf("Safety %s: Limit velo cmd not active\n",sName_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(limitVeloCmd_) {
|
||||
checkAxesMaxVeloAndDisableIfNeeded();
|
||||
}
|
||||
|
||||
// Write velo limit and activation to ecmc axis object
|
||||
setAxesMaxVelo();
|
||||
}
|
||||
|
||||
// Executed by ecmc rt thread.
|
||||
void ecmcSS1SafetyGroup::execute() {
|
||||
exeRampDown();
|
||||
exeLimitVelo();
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::resetPrintoutStatus() {
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
(*saxis)->printEnableStat_ = 1;
|
||||
@@ -384,9 +488,10 @@ void ecmcSS1SafetyGroup::setAxesStandstillStatus(int standstill) {
|
||||
status_.axesAtStandstill = standstill;
|
||||
refreshAsyn();
|
||||
}
|
||||
|
||||
|
||||
// Only write axis standstill bit if all axes are disabled
|
||||
if(ecEntryStandstill_->writeBit(bitStandStill_,
|
||||
standstill > 0)) {
|
||||
((standstill > 0) && axesDisabled_) )) {
|
||||
throw std::out_of_range("Safety: Read rampdown cmd failed");
|
||||
}
|
||||
axesAreStandstillOld_ = standstill;
|
||||
@@ -396,19 +501,82 @@ void ecmcSS1SafetyGroup::setAxesStandstillStatus(int standstill) {
|
||||
bool ecmcSS1SafetyGroup::checkAxesStandstill() {
|
||||
bool standstill = 1;
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
standstill= standstill && checkAxisStandstill((*saxis));
|
||||
standstill= standstill && checkAxisStandstill((*saxis));
|
||||
}
|
||||
return standstill;
|
||||
}
|
||||
|
||||
// Check standstill axis
|
||||
bool ecmcSS1SafetyGroup::checkAxisStandstill(safetyAxis* axis) {
|
||||
double velo = 1;
|
||||
int err = getAxisTrajVelo(axis->axisId_, &velo);
|
||||
// Check axes disabled
|
||||
bool ecmcSS1SafetyGroup::checkAxesDisabled() {
|
||||
bool enabledsum = 1;
|
||||
int enabled = 0;
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
getAxisEnabled((*saxis)->axisId_,&enabled);
|
||||
enabledsum = enabledsum && enabled;
|
||||
}
|
||||
return !enabledsum;
|
||||
}
|
||||
|
||||
// Check max velo violation
|
||||
void ecmcSS1SafetyGroup::checkAxesMaxVeloAndDisableIfNeeded() {
|
||||
if(!limitVeloCmd_) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
if(!(*saxis)->veloMaxLimitEnabled_) {
|
||||
break;
|
||||
}
|
||||
if(checkAxisMaxVelo((*saxis))) {
|
||||
printf("Safety %s: Axis %d, velo too high, disabling axis.\n", sName_, (*saxis)->axisId_);
|
||||
setAxisEnable((*saxis)->axisId_,0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set max velo in axis object
|
||||
void ecmcSS1SafetyGroup::setAxesMaxVelo() {
|
||||
for(std::vector<safetyAxis*>::iterator saxis = axes_.begin(); saxis != axes_.end(); ++saxis) {
|
||||
if( (*saxis)->veloMaxLimitEnabled_ ) {
|
||||
setAxisExtMaxVelo((*saxis)->axisId_,0.95*(*saxis)->veloMaxLimit_,limitVeloCmd_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ecmcSS1SafetyGroup::checkAxisMaxVelo(safetyAxis* axis) {
|
||||
double traj = 1;
|
||||
|
||||
int err = getAxisTrajVelo(axis->axisId_, &traj);
|
||||
if(err) {
|
||||
return 0;
|
||||
}
|
||||
return std::abs(velo) <= axis->veloLimit_;
|
||||
|
||||
double enc = 1;
|
||||
err = getAxisEncVelo(axis->axisId_, &enc);
|
||||
if(err) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::abs(traj) >= axis->veloMaxLimit_ || std::abs(enc) >= axis->veloMaxLimit_;
|
||||
}
|
||||
|
||||
// Check standstill axis
|
||||
bool ecmcSS1SafetyGroup::checkAxisStandstill(safetyAxis* axis) {
|
||||
double traj = 1;
|
||||
|
||||
int err = getAxisTrajVelo(axis->axisId_, &traj);
|
||||
if(err) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double enc = 1;
|
||||
err = getAxisEncVelo(axis->axisId_, &enc);
|
||||
if(err) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::abs(traj) <= axis->veloStandstillLimit_ && std::abs(enc) <= axis->veloStandstillLimit_;
|
||||
}
|
||||
|
||||
// Check standstill and disable
|
||||
@@ -439,7 +607,7 @@ void ecmcSS1SafetyGroup::setAxesDisable() {
|
||||
if(!*saxis) {
|
||||
throw std::runtime_error("Safety: Axis object NULL.");
|
||||
}
|
||||
setAxisEnable((*saxis)->axisId_,0);
|
||||
setAxisEnable((*saxis)->axisId_,0);
|
||||
}
|
||||
|
||||
if(printEnableStatus_ && cfgDbgMode_) {
|
||||
@@ -454,22 +622,46 @@ void ecmcSS1SafetyGroup::setAxesSafetyInterlocks(int stop) {
|
||||
if(!*saxis) {
|
||||
throw std::runtime_error( "Safety: Axis object NULL.");
|
||||
}
|
||||
setAxisEmergencyStopInterlock((*saxis)->axisId_,stop);
|
||||
|
||||
setAxisEmergencyStopInterlock((*saxis)->axisId_,stop);
|
||||
|
||||
if(!oldStop_ && stop) {
|
||||
//Calcualte new deceleration if delay is defined and abs(velo) > 0
|
||||
if(delayMs_ > 0) {
|
||||
double velo = 0;
|
||||
getAxisTrajVelo((*saxis)->axisId_,&velo);
|
||||
velo = std::abs(velo);
|
||||
if(velo > 0) {
|
||||
double newEmergDec = velo / (ECMC_PLUGIN_RAMP_DOWN_TIME_RATIO * delayMs_ / 1000.0);
|
||||
setAxisEmergDeceleration((*saxis)->axisId_,newEmergDec);
|
||||
printf("Safety %s: Set new emergency deceleration %lf \n",sName_,newEmergDec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
oldStop_ = stop;
|
||||
}
|
||||
|
||||
void ecmcSS1SafetyGroup::addAxis(int axisId, double veloLimit,int standStillTimeMs) {
|
||||
void ecmcSS1SafetyGroup::addAxis(int axisId,
|
||||
double veloStandstillLimit,
|
||||
int standStillTimeMs,
|
||||
double veloMaxLimit) {
|
||||
|
||||
if(!getAxisValid(axisId)) {
|
||||
throw std::out_of_range("Safety: Invalid axis id");
|
||||
}
|
||||
|
||||
axes_.push_back(new safetyAxis(axisId, veloLimit, standStillTimeMs));
|
||||
axes_.push_back(new safetyAxis(axisId, veloStandstillLimit,
|
||||
standStillTimeMs, veloMaxLimit));
|
||||
axesCounter_++;
|
||||
|
||||
|
||||
|
||||
if(cfgDbgMode_) {
|
||||
printf("Safety %s: Added axis %d to safety group\n",sName_,axisId);
|
||||
printf("Safety %s: Added axis %d to safety group.\n"
|
||||
" Velo stand still limit: %lf\n"
|
||||
" velo max limit: %lf (%s)\n"
|
||||
" standstill filter time: %d\n"
|
||||
,sName_,axisId,veloStandstillLimit,veloMaxLimit,
|
||||
veloMaxLimit>0 ? "enabled" : "disabled", standStillTimeMs);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -25,26 +25,45 @@ typedef struct {
|
||||
bool error : 1;
|
||||
bool rampDownCmdActive : 1;
|
||||
bool axesAtStandstill : 1;
|
||||
int dummy : 29;
|
||||
bool limitVeloCmdActive : 1;
|
||||
int dummy : 28;
|
||||
} ecmcSafetyStatusWd;
|
||||
|
||||
class safetyAxis {
|
||||
public:
|
||||
safetyAxis(int axisId,
|
||||
double veloLimit,
|
||||
int standStillTimeMs) {
|
||||
veloLimit_ = veloLimit;
|
||||
axisId_ = axisId;
|
||||
standStillTimeMs_ = standStillTimeMs;
|
||||
printEnableStat_ = 1;
|
||||
double velostandstillLimit,
|
||||
int standStillTimeMs,
|
||||
double veloMaxLimit) {
|
||||
veloStandstillLimit_ = velostandstillLimit;
|
||||
axisId_ = axisId;
|
||||
standStillTimeMs_ = standStillTimeMs;
|
||||
veloMaxLimit_ = veloMaxLimit;
|
||||
veloMaxLimitEnabled_ = veloMaxLimit > 0;
|
||||
printEnableStat_ = 1;
|
||||
}
|
||||
|
||||
double veloLimit_;
|
||||
safetyAxis(int axisId,
|
||||
double velostandstillLimit,
|
||||
int standStillTimeMs) {
|
||||
veloStandstillLimit_ = velostandstillLimit;
|
||||
axisId_ = axisId;
|
||||
standStillTimeMs_ = standStillTimeMs;
|
||||
veloMaxLimit_ = -1;
|
||||
veloMaxLimitEnabled_ = 0;
|
||||
printEnableStat_ = 1;
|
||||
}
|
||||
|
||||
double veloStandstillLimit_;
|
||||
double veloMaxLimit_; // disable with -1
|
||||
int axisId_;
|
||||
int standStillTimeMs_;
|
||||
int printEnableStat_;
|
||||
int veloMaxLimitEnabled_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ecmcSS1SafetyGroup : public asynPortDriver {
|
||||
public:
|
||||
|
||||
@@ -54,17 +73,21 @@ class ecmcSS1SafetyGroup : public asynPortDriver {
|
||||
* - out_of_range
|
||||
*/
|
||||
ecmcSS1SafetyGroup(const char *name,
|
||||
const char *ec_rampdown_cmd,
|
||||
const char *ec_standstill_status,
|
||||
int time_delay_ms,
|
||||
const char *cfg_string,
|
||||
char* portName);
|
||||
const char *ec_rampdown_cmd,
|
||||
const char *ec_standstill_status,
|
||||
const char *ec_limit_velo,
|
||||
int time_delay_ms,
|
||||
const char *cfg_string,
|
||||
char* portName);
|
||||
|
||||
~ecmcSS1SafetyGroup();
|
||||
|
||||
// Call just before realtime because then all data sources should be available
|
||||
void validate();
|
||||
void addAxis(int axisId, double veloLimit,int standStillTimeMs);
|
||||
void addAxis(int axisId,
|
||||
double veloLimit,
|
||||
int standStillTimeMs,
|
||||
double veloMaxLimit);
|
||||
void execute();
|
||||
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
std::string getName();
|
||||
@@ -77,19 +100,27 @@ class ecmcSS1SafetyGroup : public asynPortDriver {
|
||||
void setAxesDisable();
|
||||
void setAxesStandstillStatus(int standstill);
|
||||
bool checkAxesStandstill();
|
||||
bool checkAxesDisabled();
|
||||
bool checkAxisStandstill(safetyAxis* axis);
|
||||
bool checkAxisStandstillAndDisableIfNeeded(safetyAxis* axis);
|
||||
bool checkAxesStandstillAndDisableIfNeeded();
|
||||
void checkAxesMaxVeloAndDisableIfNeeded();
|
||||
void setAxesMaxVelo();
|
||||
bool checkAxisMaxVelo(safetyAxis* axis);
|
||||
void resetPrintoutStatus();
|
||||
void parseConfigStr(const char *configStr);
|
||||
void initAsyn();
|
||||
void refreshAsyn();
|
||||
void exeRampDown();
|
||||
void exeLimitVelo();
|
||||
double ecmcSampleRateHz_;
|
||||
int dataSourcesLinked_; // To avoid link several times
|
||||
int objectId_; // Unique object id
|
||||
int cycleCounter_;
|
||||
int rampDownCmd_;
|
||||
int rampDownCmdOld_;
|
||||
int limitVeloCmdOld_;
|
||||
int limitVeloCmd_;
|
||||
|
||||
// Config options
|
||||
int cfgDbgMode_; // Config: allow dbg printouts
|
||||
@@ -105,8 +136,7 @@ class ecmcSS1SafetyGroup : public asynPortDriver {
|
||||
char* sName_;
|
||||
char* sEcRampDownCmdNameOrg_;
|
||||
char* sEcAxesStandStillStatOrg_;
|
||||
char* sEcRampDownCmdNameStrip_;
|
||||
char* sEcAxesStandStillStatStrip_;
|
||||
char* sEcLimitVeloOrg_;
|
||||
char* sConfig_;
|
||||
|
||||
int delayMs_;
|
||||
@@ -115,18 +145,26 @@ class ecmcSS1SafetyGroup : public asynPortDriver {
|
||||
int bitRampDown_;
|
||||
int slaveIdStandStill_;
|
||||
int bitStandStill_;
|
||||
int slaveIdLimitVelo_;
|
||||
int bitLimitVelo_;
|
||||
|
||||
int limitMaxVeloEnable_;
|
||||
int axesDisabled_;
|
||||
int axesAreStandstill_;
|
||||
int axesAreStandstillOld_;
|
||||
int printEnableStatus_;
|
||||
|
||||
char aliasRampDown_[EC_MAX_OBJECT_PATH_CHAR_LENGTH];
|
||||
char aliasStandStill_[EC_MAX_OBJECT_PATH_CHAR_LENGTH];
|
||||
|
||||
char aliasLimitVelo_[EC_MAX_OBJECT_PATH_CHAR_LENGTH];
|
||||
|
||||
ecmcEc *ecMaster_;
|
||||
ecmcEcEntry *ecEntryRampDown_;
|
||||
ecmcEcEntry *ecEntryStandstill_;
|
||||
|
||||
ecmcEcEntry *ecEntryLimitVelo_;
|
||||
bool oldStop_;
|
||||
static std::string to_string(int value);
|
||||
|
||||
};
|
||||
|
||||
#endif /* ECMC_SAFETY_GROUP_PLG_H_ */
|
||||
|
||||
@@ -25,4 +25,7 @@
|
||||
#define ECMC_PLUGIN_SAFETY_ERROR_CODE 1
|
||||
#define ECMC_PLUGIN_ALREADY_LOADED_ERROR_CODE 2
|
||||
|
||||
// How big part of delay is used for rampdown
|
||||
#define ECMC_PLUGIN_RAMP_DOWN_TIME_RATIO 0.9
|
||||
|
||||
#endif /* ECMC_MOTION_PLG_DEFS_H_ */
|
||||
|
||||
@@ -51,6 +51,7 @@ ecmcSS1SafetyGroup* getGroupFromName(const char *name) {
|
||||
int createSafetyGroup(const char *name,
|
||||
const char *ec_rampdown_cmd,
|
||||
const char *ec_standstill_status,
|
||||
const char *ec_max_velo_cmd,
|
||||
int time_delay_ms) {
|
||||
|
||||
// ensure group does not already exist
|
||||
@@ -71,6 +72,7 @@ int createSafetyGroup(const char *name,
|
||||
safetyGroup = new ecmcSS1SafetyGroup(name,
|
||||
ec_rampdown_cmd,
|
||||
ec_standstill_status,
|
||||
ec_max_velo_cmd,
|
||||
time_delay_ms,
|
||||
configString,
|
||||
portNameBuffer);
|
||||
@@ -90,7 +92,8 @@ int createSafetyGroup(const char *name,
|
||||
int addAxisToSafetyGroup(const char *groupName,
|
||||
int axisId,
|
||||
double veloLimit,
|
||||
int standStillTimeMs) {
|
||||
int standStillTimeMs,
|
||||
double maxVeloLimit) {
|
||||
|
||||
ecmcSS1SafetyGroup* grp = getGroupFromName(groupName);
|
||||
|
||||
@@ -99,7 +102,7 @@ int addAxisToSafetyGroup(const char *groupName,
|
||||
throw std::runtime_error( "Safety: Error, group not found.");
|
||||
}
|
||||
|
||||
grp->addAxis(axisId,veloLimit,standStillTimeMs);
|
||||
grp->addAxis(axisId,veloLimit,standStillTimeMs,maxVeloLimit);
|
||||
|
||||
return asynSuccess;
|
||||
}
|
||||
@@ -160,15 +163,20 @@ int executeSafetyGroups() {
|
||||
*/
|
||||
void ecmcAddSS1SafetyGroupPrintHelp() {
|
||||
printf("\n");
|
||||
printf(" Use ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<time_delay_ms>)\n");
|
||||
printf(" Use ecmcAddSS1SafetyGroup(<name>, <ec_rampdown_cmd>, <ec_standstill_status>,<ec_max_velo_cmd>,<time_delay_ms>)\n");
|
||||
printf(" <name> : Name of group.\n");
|
||||
printf(" <ec_rampdown_cmd> : Ethercat entry input for rampdown cmd.\n");
|
||||
printf(" <ec_standstill_status> : Ethercat entry output for group standstill status.\n");
|
||||
printf(" <ec_max_velo_cmd> : Ethercat entry input for activation of maximum velo limitation (set to \"empty\" to disable).\n");
|
||||
printf(" <time_delay_ms> : Time delay of STO [ms].\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int ecmcAddSS1SafetyGroup(const char* name, const char* ec_rampdown_cmd,const char* ec_standstill_status,int time_delay_ms) {
|
||||
int ecmcAddSS1SafetyGroup(const char* name,
|
||||
const char* ec_rampdown_cmd,
|
||||
const char* ec_standstill_status,
|
||||
const char* ec_max_velo_cmd,
|
||||
int time_delay_ms) {
|
||||
if(!name) {
|
||||
ecmcAddSS1SafetyGroupPrintHelp();
|
||||
return asynError;
|
||||
@@ -190,13 +198,20 @@ int ecmcAddSS1SafetyGroup(const char* name, const char* ec_rampdown_cmd,const ch
|
||||
ecmcAddSS1SafetyGroupPrintHelp();
|
||||
return asynError;
|
||||
}
|
||||
|
||||
if(!ec_max_velo_cmd) {
|
||||
printf("Error: ec_max_velo_cmd ethercat entry not defined.\n");
|
||||
ecmcAddSS1SafetyGroupPrintHelp();
|
||||
return asynError;
|
||||
}
|
||||
|
||||
if(time_delay_ms <= 0) {
|
||||
printf("Error: time_delay invalid.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
try {
|
||||
createSafetyGroup(name,ec_rampdown_cmd,ec_standstill_status, time_delay_ms);
|
||||
createSafetyGroup(name,ec_rampdown_cmd,ec_standstill_status,ec_max_velo_cmd,time_delay_ms);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Add safety group failed.\n",e.what());
|
||||
@@ -213,16 +228,19 @@ static const iocshArg initArg1_1 =
|
||||
static const iocshArg initArg2_1 =
|
||||
{ "ec entry output axes standstill status", iocshArgString };
|
||||
static const iocshArg initArg3_1 =
|
||||
{ "ec entry input activate max velo", iocshArgString };
|
||||
static const iocshArg initArg4_1 =
|
||||
{ "STO delay [ms]", iocshArgInt };
|
||||
|
||||
static const iocshArg *const initArgs_1[] = { &initArg0_1,
|
||||
&initArg1_1,
|
||||
&initArg2_1,
|
||||
&initArg3_1};
|
||||
&initArg3_1,
|
||||
&initArg4_1,};
|
||||
|
||||
static const iocshFuncDef initFuncDef_1 = { "ecmcAddSS1SafetyGroup", 4, initArgs_1 };
|
||||
static const iocshFuncDef initFuncDef_1 = { "ecmcAddSS1SafetyGroup", 5, initArgs_1 };
|
||||
static void initCallFunc_1(const iocshArgBuf *args) {
|
||||
ecmcAddSS1SafetyGroup(args[0].sval, args[1].sval, args[2].sval, args[3].ival);
|
||||
ecmcAddSS1SafetyGroup(args[0].sval, args[1].sval, args[2].sval, args[3].sval, args[4].ival);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,14 +249,19 @@ static void initCallFunc_1(const iocshArgBuf *args) {
|
||||
void ecmcAddAxisToSafetyGroupPrintHelp() {
|
||||
printf("\n");
|
||||
printf(" Use ecmcAddAxisToSafetyGroup(<group_name>, <axis_index>)\n");
|
||||
printf(" <name> : Name of safety group.\n");
|
||||
printf(" <Axis id> : Axis index to add.\n");
|
||||
printf(" <velo limit> : Axis standstill velo limit [unit of axis].\n");
|
||||
printf(" <time> : Time for axis to be below velo limit [ms].\n");
|
||||
printf(" <name> : Name of safety group.\n");
|
||||
printf(" <Axis id> : Axis index to add.\n");
|
||||
printf(" <standstill_velo_limit> : Axis standstill velo limit [unit of axis].\n");
|
||||
printf(" <standstill_time> : Time for axis to be below standstill_velo_limit [ms].\n");
|
||||
printf(" <max_velo_limit> : Axis max velo limit [unit of axis] (0 to disable).\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int ecmcAddAxisToSafetyGroup(const char* name, int axis_id, double velo_lim, int stand_still_time) {
|
||||
int ecmcAddAxisToSafetyGroup(const char* name,
|
||||
int axis_id,
|
||||
double standstill_velo_limit,
|
||||
int stand_still_time,
|
||||
double max_velo_limit) {
|
||||
if(!name) {
|
||||
ecmcAddAxisToSafetyGroupPrintHelp();
|
||||
return asynError;
|
||||
@@ -254,17 +277,26 @@ int ecmcAddAxisToSafetyGroup(const char* name, int axis_id, double velo_lim, int
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(velo_lim < 0) {
|
||||
printf("Error: Invalid velocity limit.\n");
|
||||
if(standstill_velo_limit < 0) {
|
||||
printf("Error: Invalid standstill velocity limit.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(stand_still_time < 0) {
|
||||
printf("Error: Invalid stand still filter time.\n");
|
||||
printf("Error: Invalid standstill filter time.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(max_velo_limit < 0) {
|
||||
printf("Error: Invalid maximum velocity limit.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
try {
|
||||
return addAxisToSafetyGroup(name,axis_id, velo_lim, stand_still_time);
|
||||
return addAxisToSafetyGroup(name,axis_id,
|
||||
standstill_velo_limit,
|
||||
stand_still_time,
|
||||
max_velo_limit);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
printf("Exception: %s. Add axis to safety group failed.\n",e.what());
|
||||
@@ -279,18 +311,21 @@ static const iocshArg initArg0_2 =
|
||||
static const iocshArg initArg1_2 =
|
||||
{ "Axis id []", iocshArgInt };
|
||||
static const iocshArg initArg2_2 =
|
||||
{ "Velo limit [unit same as axis cfg]", iocshArgDouble };
|
||||
{ "Velo stand still limit [unit same as axis cfg]", iocshArgDouble };
|
||||
static const iocshArg initArg3_2 =
|
||||
{ "Velo stand still filter time [ms]", iocshArgInt };
|
||||
static const iocshArg initArg4_2 =
|
||||
{ "Velo max limit [unit same as axis cfg]", iocshArgDouble };
|
||||
|
||||
static const iocshArg *const initArgs_2[] = { &initArg0_2,
|
||||
&initArg1_2,
|
||||
&initArg2_2,
|
||||
&initArg3_2};
|
||||
&initArg3_2,
|
||||
&initArg4_2};
|
||||
|
||||
static const iocshFuncDef initFuncDef_2 = { "ecmcAddAxisToSafetyGroup", 4, initArgs_2};
|
||||
static const iocshFuncDef initFuncDef_2 = { "ecmcAddAxisToSafetyGroup", 5, initArgs_2};
|
||||
static void initCallFunc_2(const iocshArgBuf *args) {
|
||||
ecmcAddAxisToSafetyGroup(args[0].sval, args[1].ival, args[2].dval, args[3].ival);
|
||||
ecmcAddAxisToSafetyGroup(args[0].sval, args[1].ival, args[2].dval, args[3].ival, args[4].dval);
|
||||
}
|
||||
|
||||
void ecmcSafetyPlgRegister(void) {
|
||||
|
||||
@@ -25,11 +25,11 @@ int setCfgString(const char* cfgString);
|
||||
* \param[in] name Name of safety group.\n
|
||||
* \param[in] ec_rampdown_cmd Name of ethercat entry for ramp down command\n
|
||||
* \param[in] ec_standstill_status Name of ethercat entry all axis standstill status\n
|
||||
* \param[in] time_delay_ms Timedelay between ec_rampdown_cmd going high untill STO is triggered by safety relay.\n
|
||||
* \param[in] time_delay_ms Timedelay between ec_ramp-down_cmd going high until STO is triggered by safety relay.\n
|
||||
*
|
||||
* \return 0 if success or otherwise an error code.\n
|
||||
*/
|
||||
//int createSafetyGroup(name,ec_rampdown_cmd,ec_standstill_status, time_delay_ms);
|
||||
//int createSafetyGroup(name,ec_ramp-down_cmd,ec_standstill_status, time_delay_ms);
|
||||
|
||||
/** \brief Deletes all created objects\n
|
||||
*
|
||||
@@ -41,8 +41,8 @@ void deleteAllSafetyGroups();
|
||||
*
|
||||
* This tells the safety lib to connect to ecmc to find it's data sources.\n
|
||||
* This function should be called just before entering realtime since then all\n
|
||||
* data sources in ecmc will be definded (plc sources are compiled just before runtime\n
|
||||
* so are only fist accesible now).\n
|
||||
* data sources in ecmc will be defined (plc sources are compiled just before runtime\n
|
||||
* so are only fist accessible now).\n
|
||||
* \return 0 if success or otherwise an error code.\n
|
||||
*/
|
||||
int validate();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#-
|
||||
#################################################################################
|
||||
|
||||
#- Print discalimer
|
||||
#- Print disclaimer
|
||||
#
|
||||
# !!!!!!!!!!!!! IMPORTANT !!!!!!!!!
|
||||
# This plugin has _NO_ safety rated functionalities.
|
||||
@@ -24,3 +24,6 @@
|
||||
epicsEnvSet(ECMC_PLUGIN_FILNAME,"$(ecmc_plugin_safety_DIR)/lib/${EPICS_HOST_ARCH=linux-x86_64}/libecmc_plugin_safety.so")
|
||||
epicsEnvSet(ECMC_PLUGIN_CONFIG,"DBG_PRINT=1;")
|
||||
ecmcConfigOrDie "Cfg.LoadSafetyPlugin(${ECMC_PLUGIN_FILNAME},${ECMC_PLUGIN_CONFIG=""})"
|
||||
|
||||
#- Load SS1 group records
|
||||
dbLoadRecords("ecmcSS1Main.template","P=${ECMC_PREFIX}")
|
||||
|
||||
Reference in New Issue
Block a user