7 Commits
wip ... 0.1.0

Author SHA1 Message Date
df56af568e Use ecmc 9.5.0 2024-05-01 10:25:06 +02:00
ddc48262ce Clenup 2024-05-01 10:18:49 +02:00
7632be616d Update readme 2024-04-30 16:05:06 +02:00
64a651cc23 Set axis index even if not valid (for alarm to work). 2024-04-30 16:01:35 +02:00
54043bba44 WIP 2024-04-30 15:55:23 +02:00
d86c753975 WIP 2024-04-30 14:36:41 +02:00
59c2db6578 Restructure 2024-04-30 10:00:54 +02:00
20 changed files with 733 additions and 194 deletions

View File

@@ -2,7 +2,7 @@
record(waveform,"$(P)Plg-Mtn${INDEX}-PosAct-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Pos Act")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynFloat64ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.actpos_arr")
field(FTVL, "DOUBLE")
@@ -10,13 +10,14 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-PosAct-Arr"){
field(SCAN, "I/O Intr")
field(TSE, "0")
field(EGU, "${RAW_EGU= }")
field(PREC, "${PREC=3 }")
}
# Set pos
record(waveform,"$(P)Plg-Mtn${INDEX}-PosSet-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Pos Set")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynFloat64ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.setpos_arr")
field(FTVL, "DOUBLE")
@@ -24,13 +25,14 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-PosSet-Arr"){
field(SCAN, "I/O Intr")
field(TSE, "0")
field(EGU, "${RAW_EGU= }")
field(PREC, "${PREC=3 }")
}
# Position Error
record(waveform,"$(P)Plg-Mtn${INDEX}-PosErr-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Pos Error (diff)")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynFloat64ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.diffpos_arr")
field(FTVL, "DOUBLE")
@@ -38,26 +40,28 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-PosErr-Arr"){
field(SCAN, "I/O Intr")
field(TSE, "0")
field(EGU, "${RAW_EGU= }")
field(PREC, "${PREC=3 }")
}
# X axis time (reltive within buffer)
record(waveform,"$(P)Plg-Mtn${INDEX}-Time-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Rel. time within buffer")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynFloat64ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.x_arr")
field(FTVL, "DOUBLE")
field(NELM, "$(NELM)")
field(SCAN, "I/O Intr")
field(TSE, "0")
field(PREC, "${PREC=3 }")
}
# Axis Enable
record(waveform,"$(P)Plg-Mtn${INDEX}-Ena-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Enable")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.enable_arr")
field(FTVL, "CHAR")
@@ -70,7 +74,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Ena-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-EnaAct-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Enabled")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.enabled_arr")
field(FTVL, "CHAR")
@@ -83,7 +87,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-EnaAct-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-Bsy-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Busy")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.busy_arr")
field(FTVL, "CHAR")
@@ -96,7 +100,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Bsy-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-Exe-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Execute")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.execute_arr")
field(FTVL, "CHAR")
@@ -109,7 +113,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Exe-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-TrjSrc-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Traj source")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.trajsrc_arr")
field(FTVL, "CHAR")
@@ -122,7 +126,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-TrjSrc-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-EncSrc-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Enc source")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.encsrc_arr")
field(FTVL, "CHAR")
@@ -135,7 +139,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-EncSrc-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-AtTrg-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "At target")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt8ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.attarget_arr")
field(FTVL, "CHAR")
@@ -148,7 +152,7 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-AtTrg-Arr"){
record(waveform,"$(P)Plg-Mtn${INDEX}-ErrId-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Error Id")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt32ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.error_arr")
field(FTVL, "LONG")
@@ -157,11 +161,11 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-ErrId-Arr"){
field(TSE, "0")
}
# Axis Error Id
# Axis status word
record(waveform,"$(P)Plg-Mtn${INDEX}-Stat-Arr"){
info(asyn:FIFO, "1000")
field(DESC, "Status wd")
field(PINI, "1")
#field(PINI, "1")
field(DTYP, "asynInt32ArrayIn")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.statuswd_arr")
field(FTVL, "LONG")
@@ -187,10 +191,13 @@ record(ao,"$(P)Plg-Mtn${INDEX}-AxCmd-RB"){
field(DTYP,"asynInt32")
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.axis_id")
field(DOL, "0")
field(PREC,"0")
field(DRVL,"0")
field(DRVH,"100")
field(VAL, "1")
}
record(ai,"$(P)Plg-Mtn${INDEX}-SmpHz-RB"){
record(ai,"$(P)Plg-Mtn${INDEX}-SmpHz"){
info(asyn:READBACK,"1")
field(DESC, "Sample rate")
field(DTYP,"asynFloat64")
@@ -200,52 +207,63 @@ record(ai,"$(P)Plg-Mtn${INDEX}-SmpHz-RB"){
field(SCAN, "I/O Intr")
}
record(ai,"$(P)Plg-Mtn${INDEX}-BuffSze"){
info(asyn:READBACK,"1")
field(DESC, "Buffer Size")
field(DTYP,"asynInt32")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.buff_size")
field(VAL, "1")
}
# Future use
#record(ai,"$(P)Plg-Mtn${INDEX}-BuffSze"){
# info(asyn:READBACK,"1")
# field(DESC, "Buffer Size")
# field(DTYP,"asynInt32")
# field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.buff_size")
# field(VAL, "1")
#}
record(ai,"$(P)Plg-Mtn${INDEX}-ElmCnt"){
info(asyn:READBACK,"1")
field(DESC, "Elements in buffer count")
field(DTYP,"asynInt32")
field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.elem_count")
field(VAL, "1")
}
# Future use
#record(ai,"$(P)Plg-Mtn${INDEX}-ElmCnt"){
# info(asyn:READBACK,"1")
# field(DESC, "Elements in buffer count")
# field(DTYP,"asynInt32")
# field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.elem_count")
# field(VAL, "1")
#}
record(bo,"$(P)Plg-Mtn${INDEX}-TrgCmd-RB"){
info(asyn:READBACK,"1")
field(DESC, "Trigg command")
field(DTYP,"asynInt32")
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.trigg")
field(ZNAM,"IDLE")
field(ONAM,"TRIGG")
field(VAL, "0")
field(HIGH, 0.001)
}
# Future use
#record(bo,"$(P)Plg-Mtn${INDEX}-TrgCmd-RB"){
# info(asyn:READBACK,"1")
# field(DESC, "Trigg command")
# field(DTYP,"asynInt32")
# field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.trigg")
# field(ZNAM,"IDLE")
# field(ONAM,"TRIGG")
# field(VAL, "0")
# field(HIGH, 0.001)
#}
record(longout,"$(P)Plg-Mtn${INDEX}-Mde-RB"){
info(asyn:READBACK,"1")
field(DESC, "Mode selection")
field(PINI, "1")
field(TSE, "0")
field(DTYP, "asynInt32")
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.mode")
field(SCAN, "Passive")
}
# Future use
#record(mbbo, "$(P)Plg-Mtn${INDEX}-Mde-RB"){
# info(asyn:READBACK,"1")
# field(DESC, "Mode selection")
# field(PINI, "1")
# field(TSE, "0")
# field(DTYP, "asynInt32")
# field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.mode")
# field(ZRST, "NO_COMMAND")
# field(ZRVL, 0)
# field(ONST, "CONT")
# field(ONVL, 1)
# field(TWST, "TRIGG")
# field(TWVL, 2)
# field(VAL, 1)
#}
record(longout,"$(P)Plg-Mtn${INDEX}-Cmd-RB"){
info(asyn:READBACK,"1")
field(DESC, "Command")
field(PINI, "1")
field(TSE, "0")
field(DTYP, "asynInt32")
field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.cmd")
field(SCAN, "Passive")
}
# Future use
# record(longout,"$(P)Plg-Mtn${INDEX}-Cmd-RB"){
# info(asyn:READBACK,"1")
# field(DESC, "Command")
# field(PINI, "1")
# field(TSE, "0")
# field(DTYP, "asynInt32")
# field(OUT, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.cmd")
# field(SCAN, "Passive")
# }
record(longin,"$(P)Plg-Mtn${INDEX}-Stat"){
info(asyn:READBACK,"1")

View File

@@ -6,7 +6,7 @@ BUILDCLASSES = Linux
ARCH_FILTER = deb10%
# Run 7.0.6 for now
EXCLUDE_VERSIONS+=3 7.0.5 7.0.7
EXCLUDE_VERSIONS+=3 7.0.5 7.0.6
IGNORE_MODULES += asynMotor
IGNORE_MODULES += motorBase
@@ -16,8 +16,8 @@ OPT_CXXFLAGS_YES = -O3
# dependencies
ECmasterECMC_VERSION = v1.1.0
motorECMC_VERSION = 7.0.7-ESS
ecmc_VERSION = v9.0.1_RC1
motorECMC_VERSION = 7.0.9-ESS
ecmc_VERSION = 9.5.0
################################################################################
# THIS RELATES TO THE EtherCAT MASTER LIBRARY
@@ -29,9 +29,10 @@ EC_MASTER_LIB = ${EPICS_MODULES}/ECmasterECMC/${ECmasterECMC_VERSION}/R${EPICSVE
USR_LDFLAGS += -Wl,-rpath=${EC_MASTER_LIB}
USR_LDFLAGS += -L ${EC_MASTER_LIB}
BASE_DIR = ecmc_plugin_motion
BASE_DIR = .
SRC_DIR = $(BASE_DIR)/src
DB_DIR = $(BASE_DIR)/Db
SCRIPTS_DIR = $(BASE_DIR)/scripts
SOURCES += $(SRC_DIR)/ecmcPluginMotion.c
SOURCES += $(SRC_DIR)/ecmcMotionPlgWrap.cpp
@@ -41,6 +42,5 @@ SOURCES += $(SRC_DIR)/ecmcMotionPlg.cpp
HEADERS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.h))
DBDS += $(foreach d,${SRC_DIR}, $(wildcard $d/*.dbd))
SCRIPTS += $(BASE_DIR)/startup.cmd
SCRIPTS += $(BASE_DIR)/addMotionObj.cmd
SCRIPTS += $(SCRIPTS_DIR)/addMotionObj.cmd
TEMPLATES += $(wildcard $(DB_DIR)/*.template)

View File

@@ -1,10 +1,76 @@
ecmc_plugin_motion
======
Plugin designed for commisioning and troubleshooting of motion axes.
Motion data are sampled, buffered and exposed to epics as waveforms.
Motion data are sampled, buffered and exposed as epics as waveforms.
# Panel
```
# Plugin loaded once (MTN_ID defaults to 0)
caqtdm -macro "SYS=c6025a" ecmc_plugin_motion_main.ui
# If loaded more times
caqtdm -macro "SYS=c6025a,MTN_ID=1" ecmc_plugin_motion_main.ui
```
# Python panels
In tools directory.. WIP...
# PVs
The following PVs are created:
```
c6025a> dbgrep *Plg*
c6025a:Plg-Mtn0-SmpHz
c6025a:Plg-Mtn0-AxCmd-RB
c6025a:Plg-Mtn0-EnaCmd-RB
c6025a:Plg-Mtn0-Stat
c6025a:Plg-Mtn0-PosAct-Arr
c6025a:Plg-Mtn0-PosSet-Arr
c6025a:Plg-Mtn0-PosErr-Arr
c6025a:Plg-Mtn0-Time-Arr
c6025a:Plg-Mtn0-Ena-Arr
c6025a:Plg-Mtn0-EnaAct-Arr
c6025a:Plg-Mtn0-Bsy-Arr
c6025a:Plg-Mtn0-Exe-Arr
c6025a:Plg-Mtn0-TrjSrc-Arr
c6025a:Plg-Mtn0-EncSrc-Arr
c6025a:Plg-Mtn0-AtTrg-Arr
c6025a:Plg-Mtn0-ErrId-Arr
c6025a:Plg-Mtn0-Stat-Arr
```
# Plugin Report
```
Plugin info:
Index = 1
Name = ecmc_plugin_motion
Description = Motion plugin for commissioning of ecmc motion axes.
Option description =
DBG_PRINT=<1/0> : Enables/disables printouts from plugin, default = disabled.
AXIS=<axis id> : Sets default source axis id.
BUFFER_SIZE=<size> : Data points to collect, default = 4096.
RATE=<rate hz> : Sampling rate in Hz
Filename = /gfa/.mounts/sls_ioc/modules/ecmc_plugin_motion/test/R7.0.7//lib/deb10-x86_64/libecmc_plugin_motion.so
Config string = AXIS=1;BUFFER_SIZE=2000;DBG_PRINT=0;ENABLE=1;
Version = 2
Interface version = 65536 (ecmc = 65536)
max plc funcs = 64
max plc func args = 10
max plc consts = 64
Construct func = @0x7f0badafb780
Enter realtime func = @0x7f0badafb7c0
Exit realtime func = @0x7f0badafb770
Realtime func = @0x7f0badafb7a0
Destruct func = @0x7f0badafb760
dlhandle = @0x563c3aba7d00
Plc functions:
Plc constants:
```
# TODO
* Triggered mode
* Add control functionalities (step response)
* Fix python gui (and venv)

View File

@@ -1,99 +0,0 @@
#
# Copyright (c) 2023 Paul Scherrer Institute
#
# The program is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 2 of the
# License, or any newer version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt
#
#
# Author : anderssandstrom
# email : anders.sandstroem@psi.ch
# Date : 2023 July 10
# version : 0.0.0
#
## The following lines are mandatory, please don't change them.
where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(E3_REQUIRE_TOOLS)/driver.makefile
include $(E3_REQUIRE_CONFIG)/DECOUPLE_FLAGS
ifneq ($(strip $(ASYN_DEP_VERSION)),)
asyn_VERSION=$(ASYN_DEP_VERSION)
endif
ifneq ($(strip $(ECMC_DEP_VERSION)),)
ecmc_VERSION=$(ECMC_DEP_VERSION)
endif
ifneq ($(strip $(RUCKIG_DEP_VERSION)),)
ruckig_VERSION=$(RUCKIG_DEP_VERSION)
endif
ifeq ($(T_A),linux-x86_64)
# Assume that the etherlab user library is done via
# https://github.com/icshwi/etherlabmaster
USR_INCLUDES += -I/opt/etherlab/include
USR_CFLAGS += -fPIC
USR_LDFLAGS += -L /opt/etherlab/lib
USR_LDFLAGS += -lethercat
USR_LDFLAGS += -Wl,-rpath=/opt/etherlab/lib
else
ifeq ($(T_A),linux-arm)
# Assume that the etherlab user library is done via
# https://github.com/icshwi/etherlabmaster
USR_INCLUDES += -I/opt/etherlab/include
USR_CFLAGS += -fPIC
USR_LDFLAGS += -L /opt/etherlab/lib
USR_LDFLAGS += -lethercat
USR_LDFLAGS += -Wl,-rpath=/opt/etherlab/lib
else
# Assume that the etherlab user library is done via
# Yocto ESS Linux bb recipe
USR_INCLUDES += -I$(SDKTARGETSYSROOT)/usr/include/etherlab
USR_CFLAGS += -fPIC
USR_LDFLAGS += -L $(SDKTARGETSYSROOT)/usr/lib/etherlab
USR_LDFLAGS += -lethercat
USR_LDFLAGS += -Wl,-rpath=$(SDKTARGETSYSROOT)/usr/lib/etherlab
USR_LDFLAGS += -lstdc++
endif
endif
APP:="."
#APPDB:=$(APP)/Db
#APPSRC:=$(APP)/src
APPSRC:=src
APPDB:=Db
USR_CFLAGS += -shared -fPIC -Wall -Wextra
USR_LDFLAGS += -lstdc++
USR_INCLUDES += -I$(where_am_I)$(APPSRC)
TEMPLATES += $(wildcard $(APPDB)/*.db)
TEMPLATES += $(wildcard $(APPDB)/*.template)
SOURCES += $(APPSRC)/ecmcPluginMotion.c
SOURCES += $(APPSRC)/ecmcMotionPlgWrap.cpp
SOURCES += $(APPSRC)/ecmcMotionPlg.cpp
#SOURCES += $(APPSRC)/ecmcDataBuffer.cpp
SCRIPTS += startup.cmd
SCRIPTS += addMotionObj.cmd
db:
.PHONY: db
vlibs:
.PHONY: vlibs
###

View File

@@ -2,15 +2,10 @@
## Example: Configuraftion for running ecmc motion plugin
##############################################################################
## Initiation:
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")
require ecmccfg "9.0.1_RC1"
require ecmccfg "9.4.0" "ECMC_VER=9.4.0,EC_RATE=500"
# run module startup.cmd (only needed at ESS PSI auto call at require)
$(ECMCCFG_INIT="")$(SCRIPTEXEC) ${ecmccfg_DIR}startup.cmd, "IOC=$(IOC),ECMC_VER=v9.0.1_RC1, EC_RATE=500"
$(ECMCCFG_INIT="")$(SCRIPTEXEC) ${ecmccfg_DIR}startup.cmd, "IOC=$(IOC),ECMC_VER=9.4.0, EC_RATE=500"
##############################################################################
## Configure hardware

View File

@@ -2,15 +2,9 @@
## Example: Configuraftion for running ecmc motion plugin
##############################################################################
## Initiation:
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
epicsEnvSet("ECMCCFG_INIT" ,"") #Only run startup once (auto at PSI, need call at ESS), variable set to "#" in startup.cmd
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")
require ecmccfg "sandst_a_v9.0.1_RC1" "ECMC_VER=v9.0.1_RC1"
require ecmccfg "9.4.0" "ECMC_VER=9.4.0"
##############################################################################
## Configure hardware
## Configue
epicsEnvSet("ECMC_EC_SLAVE_NUM", "4")
${SCRIPTEXEC} ${ecmccfg_DIR}configureSlave.cmd, "SLAVE_ID=$(ECMC_EC_SLAVE_NUM), HW_DESC=EL7031, CONFIG=-Motor-Trinamic-QMot-QSH4218-41-10-035"
@@ -33,8 +27,6 @@ $(SCRIPTEXEC) ($(ecmccfg_DIR)configureAxis.cmd, CONFIG=./cfg/el7031.ax)
#
epicsEnvSet(ECMC_PLUGIN_CONFIG,"PLUGIN_ID=1,AX=1,BUFF_SIZE=200,DBG=0,ENA=1")
require ecmc_plugin_motion sandst_a "${ECMC_PLUGIN_CONFIG}"
# below needed at ESS but not PSI:
#${SCRIPTEXEC} ${ecmc_plugin_motion_DIR}startup.cmd "${ECMC_PLUGIN_CONFIG}"
##############################################################################
############# Configure diagnostics:

View File

View File

@@ -0,0 +1,543 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1420</width>
<height>893</height>
</rect>
</property>
<property name="windowTitle">
<string>ecmc expert axis</string>
</property>
<widget class="caStripPlot" name="castripplot">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>1200</width>
<height>500</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>4</pointsize>
</font>
</property>
<property name="Title" stdset="0">
<string notr="true">Analog</string>
</property>
<property name="TitleX">
<string notr="true"/>
</property>
<property name="TitleY">
<string notr="true">Position</string>
</property>
<property name="channels" stdset="0">
<string>$(SYS):Plg-Mtn$(MTN_ID=0)-PosAct-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-PosSet-Arr;</string>
</property>
<property name="period">
<double>30.000000000000000</double>
</property>
<property name="refreshRate" stdset="0">
<enum>caStripPlot::High</enum>
</property>
<property name="XaxisType">
<enum>caStripPlot::TimeScale</enum>
</property>
<property name="numberOfXticks" stdset="0">
<number>4</number>
</property>
<property name="YAxisScaling" stdset="0">
<enum>caStripPlot::autoScale</enum>
</property>
<property name="YaxisLimitsMax_1">
<double>600.000000000000000</double>
</property>
<property name="YaxisLimitsMin_1">
<double>200.000000000000000</double>
</property>
<property name="YaxisScalingMax_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_1">
<color>
<red>255</red>
<green>216</green>
<blue>217</blue>
</color>
</property>
<property name="YaxisLimitsMin_2">
<double>-100.000000000000000</double>
</property>
<property name="YaxisScalingMax_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_2">
<color>
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</property>
<property name="YaxisLimitsMax_3">
<double>30.000000000000000</double>
</property>
<property name="YaxisLimitsMin_3">
<double>0.000000000000000</double>
</property>
<property name="YaxisScalingMax_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_3">
<color>
<red>159</red>
<green>207</green>
<blue>255</blue>
</color>
</property>
<property name="foreground">
<color alpha="0">
<red>133</red>
<green>190</green>
<blue>232</blue>
</color>
</property>
<property name="XaxisEnabled">
<bool>false</bool>
</property>
<property name="LegendEnabled">
<bool>true</bool>
</property>
<property name="XaxisSyncGroup">
<number>1</number>
</property>
</widget>
<widget class="caStripPlot" name="castripplot_2">
<property name="geometry">
<rect>
<x>10</x>
<y>680</y>
<width>1231</width>
<height>200</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>4</pointsize>
</font>
</property>
<property name="Title" stdset="0">
<string notr="true"/>
</property>
<property name="TitleX">
<string notr="true">Time</string>
</property>
<property name="TitleY">
<string notr="true">State</string>
</property>
<property name="channels" stdset="0">
<string>$(SYS):Plg-Mtn$(MTN_ID=0)-Ena-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-EnaAct-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-Bsy-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-Exe-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-TrjSrc-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-EncSrc-Arr;$(SYS):Plg-Mtn$(MTN_ID=0)-AtTrg-Arr;</string>
</property>
<property name="period">
<double>30.000000000000000</double>
</property>
<property name="refreshRate" stdset="0">
<enum>caStripPlot::High</enum>
</property>
<property name="XaxisType">
<enum>caStripPlot::TimeScaleFix</enum>
</property>
<property name="numberOfXticks" stdset="0">
<number>4</number>
</property>
<property name="YAxisScaling" stdset="0">
<enum>caStripPlot::fixedScale</enum>
</property>
<property name="YaxisLimitsMax_1">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_1">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_1">
<color>
<red>255</red>
<green>216</green>
<blue>217</blue>
</color>
</property>
<property name="YaxisLimitsMax_2">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_2">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_2">
<color>
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</property>
<property name="YaxisLimitsMax_3">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_3">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_3">
<color>
<red>159</red>
<green>207</green>
<blue>255</blue>
</color>
</property>
<property name="YaxisLimitsMax_4">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_4">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_4" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_4" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisLimitsMax_5">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_5">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_5" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_5" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisLimitsMax_6">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_6">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_6" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_6" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisLimitsMax_7">
<double>1.200000000000000</double>
</property>
<property name="YaxisLimitsMin_7">
<double>-0.200000000000000</double>
</property>
<property name="YaxisScalingMax_7" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_7" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="foreground">
<color alpha="0">
<red>133</red>
<green>190</green>
<blue>232</blue>
</color>
</property>
<property name="LegendEnabled">
<bool>true</bool>
</property>
<property name="XaxisSyncGroup">
<number>1</number>
</property>
</widget>
<widget class="caStripPlot" name="castripplot_3">
<property name="geometry">
<rect>
<x>10</x>
<y>530</y>
<width>1200</width>
<height>151</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>4</pointsize>
</font>
</property>
<property name="Title" stdset="0">
<string notr="true"/>
</property>
<property name="TitleX">
<string notr="true"/>
</property>
<property name="TitleY">
<string notr="true">Position Error</string>
</property>
<property name="channels" stdset="0">
<string>$(SYS):Plg-Mtn$(MTN_ID=0)-PosErr-Arr;</string>
</property>
<property name="period">
<double>30.000000000000000</double>
</property>
<property name="refreshRate" stdset="0">
<enum>caStripPlot::High</enum>
</property>
<property name="XaxisType">
<enum>caStripPlot::TimeScale</enum>
</property>
<property name="numberOfXticks" stdset="0">
<number>4</number>
</property>
<property name="YAxisScaling" stdset="0">
<enum>caStripPlot::autoScale</enum>
</property>
<property name="YaxisLimitsMax_1">
<double>600.000000000000000</double>
</property>
<property name="YaxisLimitsMin_1">
<double>200.000000000000000</double>
</property>
<property name="YaxisScalingMax_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_1" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_1">
<color>
<red>255</red>
<green>216</green>
<blue>217</blue>
</color>
</property>
<property name="YaxisLimitsMin_2">
<double>-100.000000000000000</double>
</property>
<property name="YaxisScalingMax_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_2" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_2">
<color>
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</property>
<property name="YaxisLimitsMax_3">
<double>30.000000000000000</double>
</property>
<property name="YaxisLimitsMin_3">
<double>0.000000000000000</double>
</property>
<property name="YaxisScalingMax_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="YaxisScalingMin_3" stdset="0">
<enum>caStripPlot::User</enum>
</property>
<property name="color_3">
<color>
<red>159</red>
<green>207</green>
<blue>255</blue>
</color>
</property>
<property name="foreground">
<color alpha="0">
<red>133</red>
<green>190</green>
<blue>232</blue>
</color>
</property>
<property name="XaxisEnabled">
<bool>false</bool>
</property>
<property name="LegendEnabled">
<bool>true</bool>
</property>
<property name="XaxisSyncGroup">
<number>1</number>
</property>
</widget>
<widget class="caToggleButton" name="catogglebutton">
<property name="geometry">
<rect>
<x>1270</x>
<y>80</y>
<width>100</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Enable</string>
</property>
<property name="channel" stdset="0">
<string notr="true">$(SYS):Plg-Mtn$(MTN_ID=0)-EnaCmd-RB</string>
</property>
</widget>
<widget class="caNumeric" name="canumeric">
<property name="geometry">
<rect>
<x>1300</x>
<y>120</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="integerDigits" stdset="0">
<number>1</number>
</property>
<property name="decimalDigits" stdset="0">
<number>0</number>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
<property name="channel" stdset="0">
<string notr="true">$(SYS):Plg-Mtn$(MTN_ID=0)-AxCmd-RB</string>
</property>
<property name="colorMode">
<enum>caNumeric::Alarm</enum>
</property>
<property name="precisionMode">
<enum>caNumeric::User</enum>
</property>
<property name="fixedFormat">
<bool>true</bool>
</property>
<property name="limitsMode">
<enum>caNumeric::User</enum>
</property>
<property name="maxValue">
<double>100.000000000000000</double>
</property>
<property name="minValue">
<double>0.000000000000000</double>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>1230</x>
<y>130</y>
<width>63</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Axis ID:</string>
</property>
</widget>
<widget class="caLineEdit" name="calineedit">
<property name="geometry">
<rect>
<x>1330</x>
<y>190</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">$(SYS):Plg-Mtn$(MTN_ID=0)-SmpHz</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>1230</x>
<y>190</y>
<width>63</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Rate [Hz]:</string>
</property>
</widget>
<widget class="caLabel" name="calabel">
<property name="geometry">
<rect>
<x>1310</x>
<y>290</y>
<width>90</width>
<height>28</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">$(SYS):Plg-Mtn$(MTN_ID=0)-SmpHz</string>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>caNumeric</class>
<extends>QFrame</extends>
<header>caNumeric</header>
</customwidget>
<customwidget>
<class>caToggleButton</class>
<extends>QCheckBox</extends>
<header>caToggleButton</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>caStripPlot</class>
<extends>QwtPlot</extends>
<header>caStripPlot</header>
</customwidget>
<customwidget>
<class>QwtPlot</class>
<extends>QFrame</extends>
<header>qwt_plot.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -28,7 +28,7 @@
#- First loaded object will therefore have index
epicsEnvSet(ECMC_PLG_MOTION_OBJ_INDEX,${ECMC_PLG_MOTION_OBJ_INDEX=0})
# Might need differet paths for PSI and ESS.. must check
#- Might need differet paths for PSI and ESS.. must check
epicsEnvSet(ECMC_PLUGIN_FILNAME,"$(ecmc_plugin_motion_DIR)/lib/${EPICS_HOST_ARCH=linux-x86_64}/libecmc_plugin_motion.so")
epicsEnvSet(ECMC_PLUGIN_CONFIG,"AXIS=${AX};BUFFER_SIZE=${BUFF_SIZE};DBG_PRINT=${DBG=1};ENABLE=${ENA=1};")
${SCRIPTEXEC} ${ecmccfg_DIR}loadPlugin.cmd, "PLUGIN_ID=${PLUGIN_ID},FILE=${ECMC_PLUGIN_FILNAME},CONFIG='${ECMC_PLUGIN_CONFIG}', REPORT=${REPORT=1}"

View File

@@ -833,9 +833,9 @@ void ecmcMotionPlg::executeMotionObject() {
return;
}
if(cfgMode_==TRIGG && !bTriggInProgress_) {
return;
}
//if(cfgMode_==TRIGG && !bTriggInProgress_) {
// return;
//}
// protect axis_ if axis object id is changed over asyn
epicsMutexLock(axisMutex_);
@@ -966,7 +966,7 @@ int ecmcMotionPlg::setAxis(int axisId) {
//set old value again
setParamAlarmStatus(asynAxisId_,1);
setParamAlarmSeverity(asynAxisId_,1);
setIntegerParam(asynAxisId_, (epicsInt32)cfgAxisIndex_);
setIntegerParam(asynAxisId_, (epicsInt32)axisId); // Set anyway to make alarms colors valid for correct index
callParamCallbacks();
return ECMC_PLUGIN_MOTION_ERROR_AXIS_OUT_OF_RANGE;
}

View File

@@ -27,7 +27,7 @@ extern "C" {
#include "ecmcMotionPlgWrap.h"
static int lastEcmcError = 0;
static char* lastConfStr = NULL;
static char* lastConfStr = NULL;
/** Optional.
* Will be called once after successfull load into ecmc.
@@ -38,7 +38,7 @@ int motionConstruct(char *configStr)
{
//This module is allowed to load several times so no need to check if loaded
// create FFT object and register data callback
// create object and register data callback
lastConfStr = strdup(configStr);
return createMotionObj(configStr);
}
@@ -48,10 +48,10 @@ int motionConstruct(char *configStr)
**/
void motionDestruct(void)
{
deleteAllMotionObjs();
if(lastConfStr){
free(lastConfStr);
}
//deleteAllMotionObjs();
//if(lastConfStr){
// free(lastConfStr);
//}
}
/** Optional function.
@@ -112,7 +112,7 @@ struct ecmcPluginData pluginDataDef = {
// Allways use ECMC_PLUG_VERSION_MAGIC
.ifVersion = ECMC_PLUG_VERSION_MAGIC,
// Name
.name = "ecmcPlugin_Motion",
.name = "ecmc_plugin_motion",
// Description
.desc = "Motion plugin for commissioning of ecmc motion axes.",
// Option description
@@ -120,7 +120,7 @@ struct ecmcPluginData pluginDataDef = {
" "ECMC_PLUGIN_AXIS_OPTION_CMD"<axis id> : Sets default source axis id.\n"
" "ECMC_PLUGIN_BUFFER_SIZE_OPTION_CMD"<size> : Data points to collect, default = 4096.\n"
" "ECMC_PLUGIN_RATE_OPTION_CMD"<rate hz> : Sampling rate in Hz"
" "ECMC_PLUGIN_MODE_OPTION_CMD"<TRIGG/CONT> : Sampling rate in Hz"
// " "ECMC_PLUGIN_MODE_OPTION_CMD"<TRIGG/CONT> : Cont or triggered mode"
,
// Plugin version
.version = ECMC_EXAMPLE_PLUGIN_VERSION,

View File

@@ -334,39 +334,63 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.pv_signal_cbs['ElmCnt'].data_signal.emit(value)
def on_change_PosAct_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['PosAct-Arr'].data_signal.emit(value)
def on_change_PosSet_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
def on_change_PosSet_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['PosSet-Arr'].data_signal.emit(value)
def on_change_PosErr_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['PosErr-Arr'].data_signal.emit(value)
def on_change_Time_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['Time-Arr'].data_signal.emit(value)
def on_change_Ena_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['Ena-Arr'].data_signal.emit(value)
def on_change_EnaAct_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['EnaAct-Arr'].data_signal.emit(value)
def on_change_Bsy_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['Bsy-Arr'].data_signal.emit(value)
def on_change_Exe_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['Exe-Arr'].data_signal.emit(value)
def on_change_TrjSrc_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['TrjSrc-Arr'].data_signal.emit(value)
def on_change_EncSrc_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['EncSrc-Arr'].data_signal.emit(value)
def on_change_AtTrg_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['AtTrg-Arr'].data_signal.emit(value)
def on_change_ErrId_Arr(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
if self.pause:
return
self.pv_signal_cbs['ErrId-Arr'].data_signal.emit(value)
def on_change_Mde_RB(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):