From 9c4a37884bd127098214ef177246ba1b54ba69b3 Mon Sep 17 00:00:00 2001 From: Anders Sandstrom Date: Fri, 4 Aug 2023 22:28:37 +0200 Subject: [PATCH] WIP --- .../Db/ecmcPluginMotion.template | 15 +- iocsh/pvs.log | 26 +-- tools/ecmcMotionMainGui.py | 214 +++++++++++------- 3 files changed, 148 insertions(+), 107 deletions(-) diff --git a/ecmc_plugin_motion/Db/ecmcPluginMotion.template b/ecmc_plugin_motion/Db/ecmcPluginMotion.template index c1cd5dd..089e920 100644 --- a/ecmc_plugin_motion/Db/ecmcPluginMotion.template +++ b/ecmc_plugin_motion/Db/ecmcPluginMotion.template @@ -51,7 +51,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Time-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Enable @@ -65,7 +64,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Ena-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Enabled @@ -79,7 +77,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-EnaAct-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Busy @@ -93,7 +90,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Bsy-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Execute @@ -107,7 +103,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-Exe-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Traj source @@ -121,7 +116,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-TrjSrc-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Enc source @@ -135,7 +129,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-EncSrc-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis At target @@ -149,7 +142,6 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-AtTrg-Arr"){ field(NELM, "$(NELM)") field(SCAN, "I/O Intr") field(TSE, "0") - field(EGU, "s") } # Axis Error Id @@ -157,13 +149,12 @@ record(waveform,"$(P)Plg-Mtn${INDEX}-ErrId-Arr"){ info(asyn:FIFO, "1000") field(DESC, "Error Id") field(PINI, "1") - field(DTYP, "asynInt8ArrayIn") + field(DTYP, "asynInt32ArrayIn") field(INP, "@asyn(PLUGIN.MOTION_${INDEX},$(ADDR=0),$(TIMEOUT=1000))plugin.motion_${INDEX}.error_arr") - field(FTVL, "CHAR") + field(FTVL, "LONG") field(NELM, "$(NELM)") field(SCAN, "I/O Intr") - field(TSE, "0") - field(EGU, "s") + field(TSE, "0") } record(bo,"$(P)Plg-Mtn${INDEX}-EnaCmd-RB"){ diff --git a/iocsh/pvs.log b/iocsh/pvs.log index 9b73ea2..a6985e0 100644 --- a/iocsh/pvs.log +++ b/iocsh/pvs.log @@ -172,10 +172,10 @@ 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-4952:exit -REQMOD:raspberrypi-4952:MODULES -REQMOD:raspberrypi-4952:VERSIONS -REQMOD:raspberrypi-4952:MOD_VER +REQMOD:raspberrypi-7906:exit +REQMOD:raspberrypi-7906:MODULES +REQMOD:raspberrypi-7906:VERSIONS +REQMOD:raspberrypi-7906:MOD_VER IOC_TEST:Axis1-Arr-Stat IOC_TEST:Axis1-PLC-Expr-RB IOC_TEST:Plg-Mtn0-PosAct-Arr @@ -245,18 +245,18 @@ IOC_TEST:m0-SlvRsp IOC_TEST:m0-Dom-WC IOC_TEST:m0s001-Enc01-LtchRst IOC_TEST:Axis1-Cmd_ -REQMOD:raspberrypi-4952:BaseVersion -REQMOD:raspberrypi-4952:require_VER -REQMOD:raspberrypi-4952:ecmccfg_VER -REQMOD:raspberrypi-4952:asyn_VER -REQMOD:raspberrypi-4952:exprtk_VER -REQMOD:raspberrypi-4952:motor_VER -REQMOD:raspberrypi-4952:ruckig_VER -REQMOD:raspberrypi-4952:ecmc_VER +REQMOD:raspberrypi-7906:BaseVersion +REQMOD:raspberrypi-7906:require_VER +REQMOD:raspberrypi-7906:ecmccfg_VER +REQMOD:raspberrypi-7906:asyn_VER +REQMOD:raspberrypi-7906:exprtk_VER +REQMOD:raspberrypi-7906:motor_VER +REQMOD:raspberrypi-7906:ruckig_VER +REQMOD:raspberrypi-7906:ecmc_VER IOC_TEST:m0s001-HWType IOC_TEST:m0s002-HWType IOC_TEST:Axis1-MsgTxt -REQMOD:raspberrypi-4952:ecmc_plugin_motion_VER +REQMOD:raspberrypi-7906:ecmc_plugin_motion_VER IOC_TEST:m0s001-Drv01-Stat IOC_TEST:m0s001-Enc01-Stat IOC_TEST:m0s001-Stat_ diff --git a/tools/ecmcMotionMainGui.py b/tools/ecmcMotionMainGui.py index c2a71ac..3f90c16 100644 --- a/tools/ecmcMotionMainGui.py +++ b/tools/ecmcMotionMainGui.py @@ -31,27 +31,40 @@ import matplotlib.pyplot as plt import threading # List of pv names -pvlist= [ 'BuffSze', - 'ElmCnt', - 'PosAct-Arr', - 'PosSet-Arr', - 'PosErr-Arr', - 'Time-Arr', - 'Ena-Arr', - 'EnaAct-Arr', - 'Bsy-Arr', - 'Exe-Arr', - 'TrjSrc-Arr', - 'EncSrc-Arr', - 'AtTrg-Arr', - 'ErrId-Arr', - 'Mde-RB', - 'Cmd-RB', - 'Stat', - 'AxCmd-RB', - 'SmpHz-RB', - 'TrgCmd-RB', - 'EnaCmd-RB' ] +pvlist = [ 'BuffSze', + 'ElmCnt', + 'PosAct-Arr', + 'PosSet-Arr', + 'PosErr-Arr', + 'Time-Arr', + 'Ena-Arr', + 'EnaAct-Arr', + 'Bsy-Arr', + 'Exe-Arr', + 'TrjSrc-Arr', + 'EncSrc-Arr', + 'AtTrg-Arr', + 'ErrId-Arr', + 'Mde-RB', + 'Cmd-RB', + 'Stat', + 'AxCmd-RB', + 'SmpHz-RB', + 'TrgCmd-RB', + 'EnaCmd-RB' ] + +pvAnalog = ['PosAct-Arr', + 'PosSet-Arr', + 'PosErr-Arr', + 'ErrId-Arr'] + +pvBinary = ['Ena-Arr', + 'EnaAct-Arr', + 'Bsy-Arr', + 'Exe-Arr', + 'TrjSrc-Arr', + 'EncSrc-Arr', + 'AtTrg-Arr'] pvmiddlestring='Plg-Mtn' @@ -66,8 +79,34 @@ class ecmcMtnMainGui(QtWidgets.QDialog): self.pvs={} self.pv_signal_cbs={} self.data={} + self.plottedLineAnalog={} + self.plottedLineBinary={} + + for pv in pvAnalog: + self.plottedLineAnalog[pv] = None + + for pv in pvBinary: + self.plottedLineBinary[pv] = None + for data in self.data: - data = None; + data = None + + #Set some default plot colours + self.plotColor={} + # Analog + self.plotColor['PosAct-Arr']='g' + self.plotColor['PosSet-Arr']='b' + self.plotColor['PosErr-Arr']='k' + self.plotColor['ErrId-Arr']='r' + + # Binary + self.plotColor['Ena-Arr']='b' + self.plotColor['EnaAct-Arr']='c' + self.plotColor['Bsy-Arr']='r' + self.plotColor['Exe-Arr']='m' + self.plotColor['TrjSrc-Arr']='g' + self.plotColor['EncSrc-Arr']='k' + self.plotColor['AtTrg-Arr']='g' self.offline = False self.pvPrefixStr = prefix @@ -111,11 +150,11 @@ class ecmcMtnMainGui(QtWidgets.QDialog): return def createWidgets(self): - self.figure = plt.figure() - self.plottedLineSpect = None - self.plottedLineRaw = None - self.axSpect = None + self.figure = plt.figure() + #self.plottedLineAnalog = None + #self.plottedLineBinary = None self.axAnalog = None + self.axBinary = None self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.pauseBtn = QPushButton(text = 'pause') @@ -364,7 +403,7 @@ class ecmcMtnMainGui(QtWidgets.QDialog): self.data['PosSet-Arr'] = value def sig_cb_PosErr_Arr(self,value): - self.data['PosErr-Ar'] = value + self.data['PosErr-Arr'] = value def sig_cb_Time_Arr(self,value): if(np.size(value)) > 0: @@ -613,58 +652,12 @@ class ecmcMtnMainGui(QtWidgets.QDialog): def plotAll(self): if self.MtnYDataValid and self.MtnXDataValid: - self.plotData() - self.MtnYDataValid = False - self.RawYDataValid = False + self.plotAnalog() + self.plotBinary() + self.MtnYDataValid = False + self.RawYDataValid = False - ###### Plotting - # def plotSpect(self, autozoom=False): - # if self.dataX is None: - # return - # if self.spectY is None: - # return - # - # # create an axis for spectrum - # if self.axSpect is None: - # self.axSpect = self.figure.add_subplot(212) -# - # # plot data - # if self.plottedLineSpect is not None: - # self.plottedLineSpect.remove() -# - # self.plottedLineSpect, = self.axSpect.plot(self.dataX,self.spectY, 'b*-') - # self.axSpect.grid(True) -# -# - # self.axSpect.set_xlabel("Frequency [Hz]") - # self.axSpect.set_ylabel(self.labelSpectY + ' ' +self.unitSpectY) -# - # if autozoom: - # ymin = np.min(self.spectY) - # ymax = np.max(self.spectY) - # # ensure different values - # if ymin == ymax: - # ymin = ymin - 1 - # ymax = ymax + 1 - # range = ymax - ymin - # ymax += range * 0.1 - # ymin -= range * 0.1 - # xmin = np.min(self.dataX) - # xmax = np.max(self.dataX) - # if xmin == xmax: - # xmin = xmin - 1 - # xmax = xmax + 1 - # range = xmax - xmin - # xmax += range * 0.02 - # xmin -= range * 0.02 - # self.axSpect.set_ylim(ymin,ymax) - # self.axSpect.set_xlim(xmin,xmax) -# - # # refresh canvas - # self.canvas.draw() - # self.axSpect.autoscale(enable=False) -# - def plotData(self, autozoom=False): + def plotAnalog(self, autozoom=False): if self.data['Time-Arr'] is None: return @@ -676,10 +669,18 @@ class ecmcMtnMainGui(QtWidgets.QDialog): self.axAnalog = self.figure.add_subplot(211) # plot data - if self.plottedLineRaw is not None: - self.plottedLineRaw.remove() - self.plottedLineRaw, = self.axAnalog.plot(self.data['Time-Arr'],self.data['PosAct-Arr'], 'b*-') - + x = self.data['Time-Arr'] + x_len = len(x) + for pv in pvAnalog: + if self.plottedLineAnalog[pv] is not None: + self.plottedLineAnalog[pv].remove() + y = self.data[pv] + y_len=len(y) + if x_len==y_len: + self.plottedLineAnalog[pv], = self.axAnalog.plot(x,y,self.plotColor[pv]) + else: + print("Pv length mismatch (Time=" + str(x_len) + "," + pv + "=" + str(y_len) + ")") + self.axAnalog.grid(True) self.axAnalog.set_xlabel('Time [s]') self.axAnalog.set_ylabel(self.labelRawY + ' ' + self.unitRawY) @@ -712,6 +713,55 @@ class ecmcMtnMainGui(QtWidgets.QDialog): self.saveBtn.setEnabled(True) self.axAnalog.autoscale(enable=False) + def plotBinary(self, autozoom=False): + if self.data['Time-Arr'] is None: + return + + #if self.data['PosAct-Arr'] is None: + # return + + # create an axis + if self.axBinary is None: + self.axBinary = self.figure.add_subplot(212) + + # plot data + for pv in pvBinary: + if self.plottedLineBinary[pv] is not None: + self.plottedLineBinary[pv].remove() + self.plottedLineBinary[pv], = self.axBinary.plot(self.data['Time-Arr'],self.data[pv],self.plotColor[pv]) + + self.axBinary.grid(True) + self.axBinary.set_xlabel('Time [s]') + self.axBinary.set_ylabel(self.labelRawY + ' ' + self.unitRawY) + self.axBinary.set_title(self.title) + + if autozoom: + ymin = np.min(self.data['PosAct-Arr']) + ymax = np.max(self.data['PosAct-Arr']) + # ensure different values + if ymin == ymax: + ymin=ymin-1 + ymax=ymax+1 + range = ymax - ymin + ymax += range * 0.1 + ymin -= range * 0.1 + xmin = np.min(self.data['Time-Arr']) + xmax = np.max(self.data['Time-Arr']) + if xmin == xmax: + xmin = xmin - 1 + xmax = xmax + 1 + range = xmax - xmin + xmax += range * 0.02 + xmin -= range * 0.02 + self.axBinary.set_ylim(ymin,ymax) + self.axBinary.set_xlim(xmin,xmax) + + # refresh canvas + self.canvas.draw() + self.allowSave = True + self.saveBtn.setEnabled(True) + self.axBinary.autoscale(enable=False) + def printOutHelp(): print("ecmcMtnMainGui: Plots waveforms of Mtn data (updates on Y data callback). ") print("python ecmcMtnMainGui.py ")