7 Commits
0.1.0 ... 0.1.1

Author SHA1 Message Date
1abf42ec4f Depend on ecmc 9 2024-09-13 09:04:33 +02:00
b1743a29b4 Set startGui.sh as executable 2024-05-07 16:45:53 +02:00
755ef8abe3 Convert tool to pyside2 2024-05-07 16:39:35 +02:00
f3413d2c96 Cleanup examples 2024-05-02 14:52:16 +02:00
fd41f95d84 Update makefile 2024-05-02 14:48:37 +02:00
1074a0c9e3 Restruct 2024-05-02 14:43:10 +02:00
a6a53ddfc0 WIP 2024-05-02 14:40:24 +02:00
36 changed files with 847 additions and 581 deletions

6
.gitignore vendored
View File

@@ -15,4 +15,8 @@ core.*
*-loc/*.Makefile
ecmc_plugin_motion/*.Makefile
*__*
O*
O*
tools/bin
tools/lib
tools/lib64
tools/pyvenv.cfg

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.7-ESS
ecmc_VERSION = 9
################################################################################
# THIS RELATES TO THE EtherCAT MASTER LIBRARY
@@ -29,10 +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
SOURCES += $(SRC_DIR)/ecmcMotionPlg.cpp
@@ -41,6 +41,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

@@ -4,6 +4,7 @@ Plugin designed for commisioning and troubleshooting of motion axes.
Motion data are sampled, buffered and exposed to epics as waveforms.
python3 ecmcMotionMainPyQtGraph.py c6025a-04 0

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

@@ -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);

View File

@@ -1,345 +0,0 @@
IOC_TEST:m0s001-Drv01-Cmd-RB
IOC_TEST:m0s001-Drv01-Spd-RB
IOC_TEST:m0s001-Enc01-PosAct
IOC_TEST:m0s001-Enc01-LtchPosAct
IOC_TEST:m0s001-Enc01-Cmd-RB
IOC_TEST:m0s001-Enc01-PosCmd-RB
IOC_TEST:Axis1-Vel-RB
IOC_TEST:Axis1-Acc-RB
IOC_TEST:Axis1-EncAct
IOC_TEST:Axis1-CfgSREV-RB
IOC_TEST:Axis1-CfgUREV-RB
IOC_TEST:Axis1-CfgPMIN-RB
IOC_TEST:Axis1-CfgPMAX-RB
IOC_TEST:Axis1-CfgSPDB-RB
IOC_TEST:Axis1-CfgRDBD-RB
IOC_TEST:Axis1-CfgRDBD-Tim-RB
IOC_TEST:Axis1-CfgPOSLAG-RB
IOC_TEST:Axis1-CfgPOSLAG-Tim-RB
IOC_TEST:Axis1-CfgDHLM-RB
IOC_TEST:Axis1-CfgDLLM-RB
IOC_TEST:Axis1-CfgVELO-RB
IOC_TEST:Axis1-CfgVMAX-RB
IOC_TEST:Axis1-CfgJVEL-RB
IOC_TEST:Axis1-CfgACCS-RB
IOC_TEST:Axis1-HomPos-RB
IOC_TEST:Axis1-PosAct
IOC_TEST:Axis1-VelAct
IOC_TEST:Axis1-PosSet
IOC_TEST:Axis1-PosErr
IOC_TEST:Axis1-PLC-Err
IOC_TEST:Plg-Mtn0-SmpHz-RB
IOC_TEST:Plg-Mtn0-BuffSze
IOC_TEST:Plg-Mtn0-ElmCnt
IOC_TEST:MCU-AppMode
IOC_TEST:MCU-ErrId
IOC_TEST:MCU-ThdLatMin
IOC_TEST:MCU-ThdLatMax
IOC_TEST:MCU-ThdPrdMin
IOC_TEST:MCU-ThdPrdMax
IOC_TEST:MCU-ThdExeMin
IOC_TEST:MCU-ThdExeMax
IOC_TEST:MCU-ThdSndMin
IOC_TEST:MCU-ThdSndMax
IOC_TEST:m0s001-Drv01-WrnAlrm
IOC_TEST:m0s001-Drv01-ErrAlrm
IOC_TEST:m0s001-Drv01-StlAlrm
IOC_TEST:m0s001-Drv01-SyncErrAlrm
IOC_TEST:m0s001-Enc01-ExtLtchOK
IOC_TEST:m0s001-Enc01-OpnCrctAlrm
IOC_TEST:m0s001-Enc01-WrnAlrm
IOC_TEST:m0s001-Enc01-SyncErrAlrm
IOC_TEST:m0s001-Online
IOC_TEST:m0s001-Operational
IOC_TEST:m0s001-Alstate-Init
IOC_TEST:m0s001-Alstate-Preop
IOC_TEST:m0s001-Alstate-Safeop
IOC_TEST:m0s001-Alstate-Op
IOC_TEST:m0s002-BO01-RB
IOC_TEST:m0s002-BO02-RB
IOC_TEST:m0s002-BO03-RB
IOC_TEST:m0s002-BO04-RB
IOC_TEST:m0s002-BO05-RB
IOC_TEST:m0s002-BO06-RB
IOC_TEST:m0s002-BO07-RB
IOC_TEST:m0s002-BO08-RB
IOC_TEST:m0s002-BO09-RB
IOC_TEST:m0s002-BO10-RB
IOC_TEST:m0s002-BO11-RB
IOC_TEST:m0s002-BO12-RB
IOC_TEST:m0s002-BO13-RB
IOC_TEST:m0s002-BO14-RB
IOC_TEST:m0s002-BO15-RB
IOC_TEST:m0s002-BO16-RB
IOC_TEST:m0s002-BO01-OvrTmpAlrm
IOC_TEST:m0s002-BO01-OpnLdAlrm
IOC_TEST:m0s002-BO01-OvrCurrAlrm
IOC_TEST:m0s002-BO01-ShrtCircAlrm
IOC_TEST:m0s002-BO02-OvrTmpAlrm
IOC_TEST:m0s002-BO02-OpnLdAlrm
IOC_TEST:m0s002-BO02-OvrCurrAlrm
IOC_TEST:m0s002-BO02-ShrtCircAlrm
IOC_TEST:m0s002-BO03-OvrTmpAlrm
IOC_TEST:m0s002-BO03-OpnLdAlrm
IOC_TEST:m0s002-BO03-OvrCurrAlrm
IOC_TEST:m0s002-BO03-ShrtCircAlrm
IOC_TEST:m0s002-BO04-OvrTmpAlrm
IOC_TEST:m0s002-BO04-OpnLdAlrm
IOC_TEST:m0s002-BO04-OvrCurrAlrm
IOC_TEST:m0s002-BO04-ShrtCircAlrm
IOC_TEST:m0s002-BO05-OvrTmpAlrm
IOC_TEST:m0s002-BO05-OpnLdAlrm
IOC_TEST:m0s002-BO05-OvrCurrAlrm
IOC_TEST:m0s002-BO05-ShrtCircAlrm
IOC_TEST:m0s002-BO06-OvrTmpAlrm
IOC_TEST:m0s002-BO06-OpnLdAlrm
IOC_TEST:m0s002-BO06-OvrCurrAlrm
IOC_TEST:m0s002-BO06-ShrtCircAlrm
IOC_TEST:m0s002-BO07-OvrTmpAlrm
IOC_TEST:m0s002-BO07-OpnLdAlrm
IOC_TEST:m0s002-BO07-OvrCurrAlrm
IOC_TEST:m0s002-BO07-ShrtCircAlrm
IOC_TEST:m0s002-BO08-OvrTmpAlrm
IOC_TEST:m0s002-BO08-OpnLdAlrm
IOC_TEST:m0s002-BO08-OvrCurrAlrm
IOC_TEST:m0s002-BO08-ShrtCircAlrm
IOC_TEST:m0s002-BO09-OvrTmpAlrm
IOC_TEST:m0s002-BO09-OpnLdAlrm
IOC_TEST:m0s002-BO09-OvrCurrAlrm
IOC_TEST:m0s002-BO09-ShrtCircAlrm
IOC_TEST:m0s002-BO10-OvrTmpAlrm
IOC_TEST:m0s002-BO10-OpnLdAlrm
IOC_TEST:m0s002-BO10-OvrCurrAlrm
IOC_TEST:m0s002-BO10-ShrtCircAlrm
IOC_TEST:m0s002-BO11-OvrTmpAlrm
IOC_TEST:m0s002-BO11-OpnLdAlrm
IOC_TEST:m0s002-BO11-OvrCurrAlrm
IOC_TEST:m0s002-BO11-ShrtCircAlrm
IOC_TEST:m0s002-BO12-OvrTmpAlrm
IOC_TEST:m0s002-BO12-OpnLdAlrm
IOC_TEST:m0s002-BO12-OvrCurrAlrm
IOC_TEST:m0s002-BO12-ShrtCircAlrm
IOC_TEST:m0s002-BO13-OvrTmpAlrm
IOC_TEST:m0s002-BO13-OpnLdAlrm
IOC_TEST:m0s002-BO13-OvrCurrAlrm
IOC_TEST:m0s002-BO13-ShrtCircAlrm
IOC_TEST:m0s002-BO14-OvrTmpAlrm
IOC_TEST:m0s002-BO14-OpnLdAlrm
IOC_TEST:m0s002-BO14-OvrCurrAlrm
IOC_TEST:m0s002-BO14-ShrtCircAlrm
IOC_TEST:m0s002-BO15-OvrTmpAlrm
IOC_TEST:m0s002-BO15-OpnLdAlrm
IOC_TEST:m0s002-BO15-OvrCurrAlrm
IOC_TEST:m0s002-BO15-ShrtCircAlrm
IOC_TEST:m0s002-BO16-OvrTmpAlrm
IOC_TEST:m0s002-BO16-OpnLdAlrm
IOC_TEST:m0s002-BO16-OvrCurrAlrm
IOC_TEST:m0s002-BO16-ShrtCircAlrm
IOC_TEST:m0s002-Online
IOC_TEST:m0s002-Operational
IOC_TEST:m0s002-Alstate-Init
IOC_TEST:m0s002-Alstate-Preop
IOC_TEST:m0s002-Alstate-Safeop
IOC_TEST:m0s002-Alstate-Op
IOC_TEST:Axis1-EnaCmd-RB
IOC_TEST:Axis1-EnaAct
IOC_TEST:Axis1-ExeCmd-RB
IOC_TEST:Axis1-Busy
IOC_TEST:Axis1-AtTarget
IOC_TEST:Axis1-Moving
IOC_TEST:Axis1-LimFwd
IOC_TEST:Axis1-LimBwd
IOC_TEST:Axis1-HomeSwitch
IOC_TEST:Axis1-Homed
IOC_TEST:Axis1-InRT
IOC_TEST:Axis1-TrjSrcTyp-RB
IOC_TEST:Axis1-EncSrcTyp-RB
IOC_TEST:Axis1-CmdFrmPLCCmd-RB
IOC_TEST:Axis1-SftLimFwdEna-RB
IOC_TEST:Axis1-SftLimBwdEna-RB
IOC_TEST:Axis1-PLC-EnaCmd-RB
IOC_TEST:Axis1-PLC-FirstScan
IOC_TEST:Axis1-Err
IOC_TEST:Axis1-Wrn
IOC_TEST:MCU-ThdRTPrioOK
IOC_TEST:MCU-ThdMemLocked
IOC_TEST:m0-LinkUp
IOC_TEST:m0-AlStates-Init
IOC_TEST:m0-AlStates-Preop
IOC_TEST:m0-AlStates-Safeop
IOC_TEST:m0-AlStates-Op
IOC_TEST:m0-Dom-RedunActive
IOC_TEST:m0-Dom-WC-Zero
IOC_TEST:m0-Dom-WC-Incomplete
IOC_TEST:m0-Dom-WC-Complete
IOC_TEST:m0-Stat-OK
REQMOD:raspberrypi-10406:exit
REQMOD:raspberrypi-10406:MODULES
REQMOD:raspberrypi-10406:VERSIONS
REQMOD:raspberrypi-10406:MOD_VER
IOC_TEST:Axis1-Arr-Stat
IOC_TEST:Axis1-PLC-Expr-RB
IOC_TEST:Plg-Mtn0-PosAct-Arr
IOC_TEST:Plg-Mtn0-PosSet-Arr
IOC_TEST:Plg-Mtn0-PosErr-Arr
IOC_TEST:Plg-Mtn0-Time-Arr
IOC_TEST:Plg-Mtn0-Ena-Arr
IOC_TEST:Plg-Mtn0-EnaAct-Arr
IOC_TEST:Plg-Mtn0-Bsy-Arr
IOC_TEST:Plg-Mtn0-Exe-Arr
IOC_TEST:Plg-Mtn0-TrjSrc-Arr
IOC_TEST:Plg-Mtn0-EncSrc-Arr
IOC_TEST:Plg-Mtn0-AtTrg-Arr
IOC_TEST:Plg-Mtn0-ErrId-Arr
IOC_TEST:MCU-ErrMsg
IOC_TEST:MCU-Updated
IOC_TEST:m0s001-Enc01-LtchCmd
IOC_TEST:Axis1-MtnCmd
IOC_TEST:Axis1-movVelCmd
IOC_TEST:Axis1-movRelCmd
IOC_TEST:Axis1-movAbsCmd
IOC_TEST:Axis1-movHomCmd
IOC_TEST:Axis1-HomProc-RB
IOC_TEST:Axis1-Type
IOC_TEST:Axis1-DrvType
IOC_TEST:Axis1-TrajType
IOC_TEST:m0s001-One
IOC_TEST:m0s001-Zero
IOC_TEST:m0s002-One
IOC_TEST:m0s002-Zero
IOC_TEST:Axis1-DIR_
IOC_TEST:Axis1-ErrRst
IOC_TEST:Axis1-HomProc
IOC_TEST:Axis1-MtnCmdData
IOC_TEST:Plg-Mtn0-Mde-RB
IOC_TEST:Plg-Mtn0-Cmd-RB
IOC_TEST:m0s001-Stat
IOC_TEST:m0s002-Stat
IOC_TEST:Axis1-MR-ErrId
IOC_TEST:Axis1-CfgRDBD-En-RB
IOC_TEST:Axis1-CfgPOSLAG-En-RB
IOC_TEST:Axis1-CfgDHLM-En-RB
IOC_TEST:Axis1-CfgDLLM-En-RB
IOC_TEST:Axis1-Stat
IOC_TEST:Axis1-ErrId
IOC_TEST:Axis1-WrnId
IOC_TEST:Plg-Mtn0-Stat
IOC_TEST:m0-Stat
IOC_TEST:m0-SlvCntr
IOC_TEST:m0-MemmapCntr
IOC_TEST:m0-DomFailCntrTot
IOC_TEST:m0-EntryCntr
IOC_TEST:m0-Dom-Stat
IOC_TEST:MCU-Cfg-Info
IOC_TEST:MCU-Cfg-Naming
IOC_TEST:MCU-Cfg-Mode
IOC_TEST:MCU-Cfg-PVA
IOC_TEST:Axis1-DbgStrToLOG
IOC_TEST:MCU-Cfg-AX1-Pfx
IOC_TEST:MCU-Cfg-AX1-Nam
IOC_TEST:MCU-Cfg-AX1-PfxNam
IOC_TEST:m0s001-EntryCntr
IOC_TEST:m0s002-EntryCntr
IOC_TEST:Axis1-SeqState
IOC_TEST:Axis1-LastIlock
IOC_TEST:m0-SlvRsp
IOC_TEST:m0-Dom-WC
IOC_TEST:m0s001-Enc01-LtchRst
IOC_TEST:Axis1-Cmd_
REQMOD:raspberrypi-10406:BaseVersion
REQMOD:raspberrypi-10406:require_VER
REQMOD:raspberrypi-10406:ecmccfg_VER
REQMOD:raspberrypi-10406:asyn_VER
REQMOD:raspberrypi-10406:exprtk_VER
REQMOD:raspberrypi-10406:motor_VER
REQMOD:raspberrypi-10406:ruckig_VER
REQMOD:raspberrypi-10406:ecmc_VER
IOC_TEST:m0s001-HWType
IOC_TEST:m0s002-HWType
IOC_TEST:Axis1-MsgTxt
REQMOD:raspberrypi-10406:ecmc_plugin_motion_VER
IOC_TEST:m0s001-Drv01-Stat
IOC_TEST:m0s001-Enc01-Stat
IOC_TEST:m0s001-Stat_
IOC_TEST:m0s002-BO01-Stat
IOC_TEST:m0s002-BO02-Stat
IOC_TEST:m0s002-BO03-Stat
IOC_TEST:m0s002-BO04-Stat
IOC_TEST:m0s002-BO05-Stat
IOC_TEST:m0s002-BO06-Stat
IOC_TEST:m0s002-BO07-Stat
IOC_TEST:m0s002-BO08-Stat
IOC_TEST:m0s002-BO09-Stat
IOC_TEST:m0s002-BO10-Stat
IOC_TEST:m0s002-BO11-Stat
IOC_TEST:m0s002-BO12-Stat
IOC_TEST:m0s002-BO13-Stat
IOC_TEST:m0s002-BO14-Stat
IOC_TEST:m0s002-BO15-Stat
IOC_TEST:m0s002-BO16-Stat
IOC_TEST:m0s002-Stat_
IOC_TEST:Axis1-Stat_
IOC_TEST:ThdRTStat_
IOC_TEST:m0-Stat_
IOC_TEST:m0-Dom-Stat_
IOC_TEST:m0s001-Enc01-LtchAutRst
IOC_TEST:Axis1-MtnCmd_
IOC_TEST:MCU-Cfg-EC-Mst
IOC_TEST:MCU-Cfg-Rate
IOC_TEST:MCU-Cfg-Time
IOC_TEST:MCU-Cfg-PV-Time
IOC_TEST:m0s001-Drv01-Cmd
IOC_TEST:m0s001-Drv01-Spd
IOC_TEST:m0s001-Enc01-Cmd
IOC_TEST:m0s001-Enc01-PosCmd
IOC_TEST:m0s001-NxtObjId
IOC_TEST:MCU-Cfg-EC-FrstObjId
IOC_TEST:m0s002-NxtObjId
IOC_TEST:Axis1-OFF_
IOC_TEST:Axis1-MRES_
IOC_TEST:Axis1-HomPos
IOC_TEST:Axis1-VelToHom
IOC_TEST:Axis1-VelFrmHom
IOC_TEST:Axis1-AccHom
IOC_TEST:Axis1-TgtPosCmd
IOC_TEST:Axis1-TgtVelCmd
IOC_TEST:Axis1-Id
IOC_TEST:MCU-Cfg-AX1-NxtObjId
IOC_TEST:MCU-Cfg-AX-FrstObjId
IOC_TEST:MCU-Cfg-PLG{Index}-NxtObjId
IOC_TEST:MCU-Cfg-PLG-FrstObjId
IOC_TEST:Plg-Mtn0-AxCmd-RB
IOC_TEST:MCU-Cfg-Eng-Mode
IOC_TEST:m0s001-Enc01-LchAutRstSp
IOC_TEST:m0s002-BO01
IOC_TEST:m0s002-BO02
IOC_TEST:m0s002-BO03
IOC_TEST:m0s002-BO04
IOC_TEST:m0s002-BO05
IOC_TEST:m0s002-BO06
IOC_TEST:m0s002-BO07
IOC_TEST:m0s002-BO08
IOC_TEST:m0s002-BO09
IOC_TEST:m0s002-BO10
IOC_TEST:m0s002-BO11
IOC_TEST:m0s002-BO12
IOC_TEST:m0s002-BO13
IOC_TEST:m0s002-BO14
IOC_TEST:m0s002-BO15
IOC_TEST:m0s002-BO16
IOC_TEST:Axis1-EnaCmd
IOC_TEST:Axis1-ExeCmd
IOC_TEST:Axis1-StpCmd
IOC_TEST:Axis1-RstCmd
IOC_TEST:Axis1-EncSrcTyp-Cmd
IOC_TEST:Axis1-TrjSrcTyp-Cmd
IOC_TEST:Axis1-PLC-EnaCmd
IOC_TEST:Axis1-CmdFrmPLCCmd
IOC_TEST:Axis1-SftLimBwdEna
IOC_TEST:Axis1-SftLimFwdEna
IOC_TEST:Plg-Mtn0-EnaCmd-RB
IOC_TEST:Plg-Mtn0-TrgCmd-RB
IOC_TEST:MCU-ErrRst
IOC_TEST:Axis1-MCU1-asyn
IOC_TEST:MCU-Cmd
IOC_TEST:Axis1

View File

@@ -0,0 +1,92 @@
# Macros:
# AX_ID : This axis id
# AX_NAME : This axis name
# DRV_ID : Slave id of drive
# OFFSET : Offset
axis:
id: ${AX_ID=1}
mode: CSV
# parameters: powerAutoOnOff=2;powerOnDelay=6.0;powerOffDelay=1.0;
epics:
name: ${AX_NAME=Axis1}
precision: 4
unit: revs
motorRecord:
enable: true
description: ""
fieldInit: "RTRY=0,FOFF=Frozen"
# Max scale is 8000Hz
drive:
numerator: 8000 #rev/s, Max speed is 8000 rev/sec for drive
denominator: 2147483648
type: 1 # Stepper: 0, DS402: 1 (servos)
control: ec0.s$(DRV_ID).driveControl01
status: ec0.s$(DRV_ID).driveStatus01
setpoint: ec0.s$(DRV_ID).velocitySetpoint01
reset: 7
# 0.02mm/rev (0.4mm pitch and gr of 20).
# in data sheet it states 0.364mm pitch and gr of 20 (which is not true)
encoder:
type: 1
position: ec0.s$(DRV_ID).positionActual01
numerator: 1
denominator: 1048576
bits: 32
absBits: 32
absOffset: $(OFFSET=0)
status: ec0.s$(DRV_ID).ONE
# error:
# - 7
# ready: 6
controller:
Kp: 140.0
Ki: 0.1
Kd: 0.0
deadband:
tol: 0.0 # Stop control if within this distance from target for the below time
time: 100
trajectory:
source: 0
type: 1
axis:
velocity: 50
acceleration: 50000
decceleration: 50000
input:
limit:
# forward: ec0.s$(DRV_ID).infoData02.1
# backward: ec0.s$(DRV_ID).infoData02.0
forward: ec0.s$(DRV_ID).ONE.1
backward: ec0.s$(DRV_ID).ONE.0
home: ec0.s$(DRV_ID).ONE.0
interlock: ec0.s$(DRV_ID).ONE.0
softlimits:
enable: no
backwardEnable: yes
forwardEnable: yes
forward: 10
backward: -10
monitoring:
lag:
enable: no
tolerance: 0.01
time: 100
target:
enable: yes
tolerance: 0.1
time: 100
velocity:
enable: no
max: 10000
time:
trajectory: 100
drive: 200

View File

@@ -0,0 +1,43 @@
##############################################################################
## Example config for ep7211-0010.. Why power cycle sometimes needed??? SDO 8000:17 (enc offset) gives error
##############################################################################
## Initiation:
require ecmccfg "ECMC_VER=EC_RATE=1000,ENG_MODE=1,MASTER_ID=1"
require ecmccomp
epicsEnvSet("ECMC_EC_SLAVE_NUM_DRIVE", "0")
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "SLAVE_ID=$(ECMC_EC_SLAVE_NUM_DRIVE), HW_DESC=EP7211-0034_ALL_FB"
${SCRIPTEXEC} ${ecmccomp_DIR}applyComponent.cmd "COMP= Motor-Beckhoff-AM8121-XFX0"
#Apply hardware configuration
ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
#epicsEnvSet("ECMC_SAMPLE_RATE_MS", "${RATE="1"}")
##############################################################################
## AXIS 1
#
epicsEnvSet("DEV", "$(IOC)")
$(SCRIPTEXEC) $(ecmccfg_DIR)loadYamlAxis.cmd "FILE=./cfg/el7201_hipa.yaml,DRV_ID=$(ECMC_EC_SLAVE_NUM_DRIVE),AX_NAME='Axis1',AX_ID=1"
#epicsEnvSet("ECMC_SAMPLE_RATE_MS", "${RATE="10"}")
##############################################################################
## Load plugin: MOTION
#
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}"
##############################################################################
############# Configure diagnostics:
ecmcConfigOrDie "Cfg.EcSetDiagnostics(1)"
ecmcConfigOrDie "Cfg.EcEnablePrintouts(0)"
ecmcConfigOrDie "Cfg.SetDiagAxisEnable(0)"
# go active
$(SCRIPTEXEC) ($(ecmccfg_DIR)setAppMode.cmd)

View File

@@ -1,62 +0,0 @@
##############################################################################
## Example: Configuraftion for running ecmc motion plugin
##############################################################################
## Initiation:
epicsEnvSet("IOC" ,"$(IOC="IOC_TEST")")
epicsEnvSet("SCRIPTEXEC" ,"$(SCRIPTEXEC="iocshLoad")")
require ecmccfg "9.0.1_RC1"
# 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"
##############################################################################
## Configure hardware
epicsEnvSet("ECMC_EC_SLAVE_NUM", "1")
${SCRIPTEXEC} ${ecmccfg_DIR}configureSlave.cmd, "SLAVE_ID=$(ECMC_EC_SLAVE_NUM), HW_DESC=EL7031, CONFIG=-Motor-Trinamic-QMot-QSH4218-41-10-035"
epicsEnvSet("DRV_ID", "${ECMC_EC_SLAVE_NUM}")
${SCRIPTEXEC} ${ecmccfg_DIR}addSlave.cmd, "HW_DESC=EL2819"
epicsEnvSet("DO_ID", "${ECMC_EC_SLAVE_NUM}")
# Configure drv input 1 as drv enable
ecmcConfigOrDie "Cfg.EcAddSdo(${DRV_ID},0x8012,0x32,1,1)"
OK
# Control external drv enable
ecmcConfigOrDie "Cfg.WriteEcEntryIDString(${DO_ID},binaryOutput02,1)"
#Apply hardware configuration
ecmcConfigOrDie "Cfg.EcApplyConfig(1)"
##############################################################################
## AXIS 1
#
epicsEnvSet("DEV", "$(IOC)")
$(SCRIPTEXEC) ($(ecmccfg_DIR)configureAxis.cmd, CONFIG=./cfg/el7031.ax)
##############################################################################
## Load plugin: MOTION
#
epicsEnvSet(ECMC_PLUGIN_CONFIG,"PLUGIN_ID=1,AX=1,BUFF_SIZE=200,DBG=0,ENA=1")
require ecmc_plugin_motion master ${ECMC_PLUGIN_CONFIG}
# below needed at ESS but not PSI:
${SCRIPTEXEC} ${ecmc_plugin_motion_DIR}startup.cmd "${ECMC_PLUGIN_CONFIG}"
##############################################################################
############# Configure diagnostics:
ecmcConfigOrDie "Cfg.EcSetDiagnostics(1)"
ecmcConfigOrDie "Cfg.EcEnablePrintouts(0)"
ecmcConfigOrDie "Cfg.EcSetDomainFailedCyclesLimit(100)"
ecmcConfigOrDie "Cfg.SetDiagAxisIndex(1)"
ecmcConfigOrDie "Cfg.SetDiagAxisFreq(2)"
ecmcConfigOrDie "Cfg.SetDiagAxisEnable(0)"
##############################################################################
############# go active:
$(SCRIPTEXEC) ($(ecmccfg_DIR)setAppMode.cmd)
iocInit
dbl > pvs.log

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

@@ -906,7 +906,7 @@ asynStatus ecmcMotionPlg::writeInt32(asynUser *pasynUser, epicsInt32 value) {
} else if( function == asynAxisId_){
return setAxis(value) > 0 ? asynSuccess : asynError;
} else if( function == asynModeId_){
return setMode((TRIGG_MODE)value) > 0 ? asynSuccess : asynError;
return setMode((TRIGG_MODE)value) == 0 ? asynSuccess : asynError;
} else if( function == asynModeId_){
return setTrigg(value) ? asynSuccess :asynError;
}

View File

@@ -48,10 +48,10 @@ int motionConstruct(char *configStr)
**/
void motionDestruct(void)
{
deleteAllMotionObjs();
if(lastConfStr){
free(lastConfStr);
}
//deleteAllMotionObjs();
//if(lastConfStr){
// free(lastConfStr);
//}
}
/** Optional function.

View File

@@ -1,8 +1,2 @@
# FFT tools
## GUI
A python gui for vizualization and control of the FFT plugin can be found in the ecmccomgui repo:
https://github.com/anderssandstrom/ecmccomgui
![ecmcFFTMainGui.py](docs/gui/ecmcFFTMainGui.png)
# Tool for visualization
python3 ecmcMotionMainPyQtGraph.py c6025a-04 0

View File

@@ -2,12 +2,16 @@
import sys
import epics
import numpy as np
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import QObject
from PySide2.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
from PyQt5 import QtCore,QtWidgets, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtCore import QObject
from PyQt5.QtGui import *
#from PyQt5 import QtCore,QtWidgets, QtGui
#from PyQt5.QtWidgets import *
#from PyQt5.QtCore import *
#from PyQt5.QtCore import QObject
#from PyQt5.QtGui import *
import random
import ecmcTrend

View File

@@ -14,18 +14,27 @@
import sys
import epics
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
#from PyQt5.QtWidgets import *
#from PyQt5 import QtWidgets
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
import numpy as np
from ecmcOneMotorGUI import *
import pyqtgraph as pg
from ecmcPvDataItem import *
from ecmcParseAxisStatusWord import *
import os
# Allow buffering of 10s data, need to add setting for this
xMaxTime = 10
caqtdmAxisExpertPanelName = "ecmcAxisExpert_v1.ui"
caqtdmExe ="/usr/local/bin/caqtdm"
# List of pv names
pvlist = [ 'BuffSze',
@@ -58,14 +67,12 @@ pvAnalog = ['PosAct-Arr',
'Stat-Arr']
pvAnaPLotsDefaultEnabled = ['PosAct-Arr',
'PosSet-Arr',
'PosErr-Arr']
'PosSet-Arr']
pvBinPLotsDefaultEnabled = ['enable',
'enabled',
'busy',
'attarget',
'moving']
'attarget']
pvBinBlock = ['instartup',
'inrealtime',
'axisType',
@@ -83,7 +90,7 @@ pvFistAxisIndexName = 'MCU-Cfg-AX-FrstObjId'
pvNextAxisIndexNamePart1 = 'MCU-Cfg-AX'
pvNextAxisIndexNamePart2 = '-NxtObjId'
pvmiddlestring='Plg-Mtn'
pvmiddlestring=':Plg-Mtn'
class ecmcMtnMainGui(QtWidgets.QDialog):
def __init__(self,prefix="IOC_TEST:",mtnPluginId=0):
@@ -188,7 +195,8 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
# Check connection and read sample rate
pvSampleRate = epics.PV(self.pvPrefixStr + pvmiddlestring + str(int(self.mtnPluginId))+ '-SmpHz-RB')
connected = pvSampleRate.wait_for_connection(timeout = 2)
print(self.pvPrefixStr + pvmiddlestring + str(int(self.mtnPluginId))+ '-SmpHz-RB')
connected = pvSampleRate.wait_for_connection(timeout = 3)
if connected:
print('Connected to ecmc')
self.offline = False
@@ -200,7 +208,8 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
else:
print('Not Connected')
self.offline = True
self.pause = True
self.pause = True
self.sampleRate = 1000
self.sampleRateValid = True
@@ -242,37 +251,58 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.plotItemBinary.setFixedHeight(150)
self.plotItemBinary.setMouseEnabled(y=False)
self.plotItemBinary.setLabel('bottom', 'Time [s]')
self.pauseBtn = QPushButton(text = 'pause')
self.pauseBtn.setFixedSize(100, 50)
self.pauseBtn.clicked.connect(self.pauseBtnAction)
self.pauseBtn.setStyleSheet("background-color: green")
#self.pauseBtn.setEnabled(False)
#self.pauseBtn.setVisible(False)
self.openBtn = QPushButton(text = 'open data')
self.openBtn.setFixedSize(100, 50)
self.openBtn.clicked.connect(self.openBtnAction)
self.openBtn.setEnabled(False)
self.openBtn.setVisible(False)
self.saveBtn = QPushButton(text = 'save data')
self.saveBtn.setFixedSize(100, 50)
self.saveBtn.clicked.connect(self.saveBtnAction)
self.saveBtn.setEnabled(False)
self.saveBtn.setVisible(False)
self.enableBtn = QPushButton(text = 'enable Mtn')
self.enableBtn.setFixedSize(100, 50)
self.enableBtn.clicked.connect(self.enableBtnAction)
self.triggBtn = QPushButton(text = 'trigg Mtn')
self.triggBtn.setFixedSize(100, 50)
self.triggBtn.setEnabled(False)
self.triggBtn.setVisible(False)
self.triggBtn.clicked.connect(self.triggBtnAction)
self.zoomBtn = QPushButton(text = 'auto zoom')
self.zoomBtn.setFixedSize(100, 50)
self.zoomBtn.clicked.connect(self.zoomBtnAction)
self.zoomBtn.setEnabled(False)
self.zoomBtn.setVisible(False)
self.modeCombo = QComboBox()
self.modeCombo.setFixedSize(100, 50)
self.modeCombo.currentIndexChanged.connect(self.newModeIndexChanged)
self.modeCombo.addItem("CONT")
self.modeCombo.addItem("TRIGG")
self.modeCombo.setEnabled(False)
self.modeCombo.setVisible(False)
self.progressBar = QProgressBar()
self.progressBar.reset()
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(100) #100%
self.progressBar.setValue(0)
self.progressBar.setFixedHeight(20)
self.progressBar.setEnabled(False)
self.progressBar.setVisible(False)
# Fix layout
self.setGeometry(300, 300, 1200, 900)
@@ -367,17 +397,23 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
frameMotion = QFrame(self)
layoutMotionGrid = QGridLayout()
frameMotion.setLayout(layoutMotionGrid)
self.btnMotorRecord = QPushButton(text = 'Motor Record')
self.btnMotorRecord.clicked.connect(self.openMotorRecordPanel)
self.btnMotorRecord.setFixedSize(100, 50)
self.btnMotorRecord.setFixedSize(150, 50)
layoutMotionGrid.addWidget(self.btnMotorRecord,0,0)
self.btnCaQTDmAxisExpert = QPushButton(text = 'caqtdm ecmc Axis')
self.btnCaQTDmAxisExpert.clicked.connect(self.openCaQTDmAxisExpert)
self.btnCaQTDmAxisExpert.setFixedSize(150, 50)
layoutMotionGrid.addWidget(self.btnCaQTDmAxisExpert,1,0)
label = QLabel('Axis id:')
self.cmbBxSelectAxis = QComboBox()
self.cmbBxSelectAxis.currentIndexChanged.connect(self.changeAxisIndex)
layoutMotionGrid.addWidget(label,1,0)
layoutMotionGrid.addWidget(self.cmbBxSelectAxis,1,1)
layoutMotionGrid.addWidget(label,2,0)
layoutMotionGrid.addWidget(self.cmbBxSelectAxis,2,1)
layoutVertMain.addWidget(frameMotion)
@@ -432,10 +468,14 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
QCoreApplication.processEvents()
def sig_cb_PosAct_Arr(self,value):
if self.pause:
return
if(np.size(value)) > 0:
self.MtnYDataValid = True
def sig_cb_Time_Arr(self,value):
if self.pause:
return
if(np.size(value)) > 0:
self.MtnXDataValid = True
self.plotAll()
@@ -467,13 +507,13 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
if id >= 0:
self.cmbBxSelectAxis.setCurrentIndex(id)
axisPrefixPvName = self.pvPrefixStr + pvAxisPrefixNamePart1 + str(int(value)) + pvAxisPrefixNamePart2
axisPrefixPvName = self.pvPrefixStr + ":" + pvAxisPrefixNamePart1 + str(int(value)) + pvAxisPrefixNamePart2
prefixPV = epics.PV(axisPrefixPvName)
axisPrefix = prefixPV.get()
if axisPrefix is not None:
self.axisPrefix = axisPrefix
self.axisPrefix = axisPrefix.rstrip(':')
axisNamePvName = self.pvPrefixStr + pvAxisNamePart1 + str(int(value)) + pvAxisNamePart2
axisNamePvName = self.pvPrefixStr + ":" + pvAxisNamePart1 + str(int(value)) + pvAxisNamePart2
namePV = epics.PV(axisNamePvName)
axisName = namePV.get()
if axisName is not None:
@@ -488,6 +528,8 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
return
def sig_cb_Stat_Arr(self,value):
if self.pause:
return
data = self.parseAxisStatWd.convert(value)
self.addStatWdData(data)
@@ -521,7 +563,7 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.plotBinary()
def readAxisList(self):
axIdPV = epics.PV(self.pvPrefixStr + pvFistAxisIndexName)
axIdPV = epics.PV(self.pvPrefixStr + ":" + pvFistAxisIndexName)
axId = axIdPV.get()
if axId is None:
print('ERROR: First Axis Index PV not found.')
@@ -532,7 +574,7 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
while axId >= 0:
# Get next axis id
pvName = self.pvPrefixStr + pvNextAxisIndexNamePart1 + str(int(axId)) + pvNextAxisIndexNamePart2
pvName = self.pvPrefixStr + ":" + pvNextAxisIndexNamePart1 + str(int(axId)) + pvNextAxisIndexNamePart2
axIdPV = epics.PV(pvName)
axId = axIdPV.get()
@@ -544,10 +586,22 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.pvItems['AxCmd-RB'].pvPut(self.cmbBxSelectAxis.currentData(), use_complete=True)
def openMotorRecordPanel(self,xxx):
self.dialog = MotorPanel(self,self.axisPrefix ,self.axisName)
self.dialog.resize(500, 900)
self.dialog = MotorPanel(self,self.axisPrefix + ':' ,self.axisName)
self.dialog.resize(500, 900)
self.dialog.show()
def openCaQTDmAxisExpert(self,xxx):
# caqtdm -macro "IOC=$I,SYS=$S,Axis=$A" ecmcAxisExpert_v1.ui
caqtdmString = caqtdmExe + " -macro "
caqtdmMacros = "SYS=" + self.axisPrefix
caqtdmMacros += ",IOC=" + self.axisPrefix
caqtdmMacros += ",Axis=" + self.axisName
caqtdmString+= "\"" + caqtdmMacros + "\"" + " " + caqtdmAxisExpertPanelName
print(caqtdmString)
#subprocess.call(caqtdmString)
os.system(caqtdmString)
###### Widget callbacks
def pauseBtnAction(self):
self.pause = not self.pause
@@ -815,9 +869,9 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
def printOutHelp():
print("ecmcMtnMainGui: Plots waveforms of Mtn data (updates on Y data callback). ")
print("python ecmcMtnMainGui.py <prefix> <mtnId>")
print("<prefix>: Ioc prefix ('IOC_TEST:')")
print("<prefix>: Ioc prefix ('IOC_TEST')")
print("<mtnId> : Id of mtn plugin ('0')")
print("example : python ecmcMotionMainGui.py 'IOC_TEST:' '0'")
print("example : python ecmcMotionMainGui.py 'IOC_TEST' '0'")
print("Will connect to Pvs: <prefix>Plg-Mtn<mtnId>-*")
if __name__ == "__main__":

View File

@@ -1,7 +1,12 @@
#!/usr/bin/env python3.6
import epics
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
#from PyQt5 import QtWidgets, QtGui, QtCore
from ecmcArrayStat import *
#Define pvs

View File

@@ -4,7 +4,11 @@ import epics
import numpy as np
import time
import threading
from PyQt5.QtCore import *
#from PyQt5.QtCore import *
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import QObject
from PySide2.QtCore import Signal as pyqtSignal, Slot as pyqtSlot
class comSignal(QObject):
data_signal = pyqtSignal(object)

View File

@@ -15,11 +15,13 @@
import sys
import os
import epics
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets
from PySide2 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
#from PyQt5.QtWidgets import *
#from PyQt5 import QtWidgets
#
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
import functools
import numpy as np
import random as rd

View File

@@ -15,10 +15,15 @@
import sys
import os
import ecmcRTCanvas
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
#from PyQt5.QtWidgets import *
#from PyQt5 import QtWidgets
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
import functools
import numpy as np
import random as rd

View File

@@ -18,10 +18,15 @@ import sys
import os
import epics
import ecmcTrend
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
#from PyQt5.QtWidgets import *
#from PyQt5 import QtWidgets
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
import functools
import numpy as np
import random as rd

View File

@@ -166,12 +166,14 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.pauseBtn.setFixedSize(100, 50)
self.pauseBtn.clicked.connect(self.pauseBtnAction)
self.pauseBtn.setStyleSheet("background-color: green")
self.openBtn = QPushButton(text = 'open data')
self.openBtn = QPushButton(text = 'open data')
self.openBtn.setFixedSize(100, 50)
self.openBtn.setEnabled(False) # Not yet supported
self.openBtn.clicked.connect(self.openBtnAction)
self.saveBtn = QPushButton(text = 'save data')
self.saveBtn.setFixedSize(100, 50)
self.saveBtn.clicked.connect(self.saveBtnAction)
self.saveBtn.setEnabled(False) # Not yet supported
self.enableBtn = QPushButton(text = 'enable Mtn')
self.enableBtn.setFixedSize(100, 50)
self.enableBtn.clicked.connect(self.enableBtnAction)
@@ -181,11 +183,13 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.zoomBtn = QPushButton(text = 'auto zoom')
self.zoomBtn.setFixedSize(100, 50)
self.zoomBtn.clicked.connect(self.zoomBtnAction)
self.zoomBtn.setEnabled(False) # Not yet supported
self.modeCombo = QComboBox()
self.modeCombo.setFixedSize(100, 50)
self.modeCombo.currentIndexChanged.connect(self.newModeIndexChanged)
self.modeCombo.addItem("CONT")
self.modeCombo.addItem("TRIGG")
self.modeCombo.addItem("TRIGG"
self.modeCombo.setEnabled(False)) # Not yet supported
self.progressBar = QProgressBar()
self.progressBar.reset()
self.progressBar.setMinimum(0)

22
tools/startGui.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Install virt env and execute python GUI
P=$1
ID=$2
DIR=$3
ENV_DIR="${DIR=/tmp}"/.venv
if [ -d "${ENV_DIR}" ]; then
. "${ENV_DIR}"/bin/activate
else
python3 -m venv "${ENV_DIR}"
. "${ENV_DIR}"/bin/activate
pip3 install wheel
pip3 install matplotlib==3.
pip3 install PySide2 pyepics pyqtgraph numpy
fi
echo "Prefix=${P=c6025a-04}"
echo "plugin id=${ID=0}"
python ecmcMotionMainPyQtGraph.py ${P=c6025a-04} ${ID=0}

BIN
tools/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB