helicalscan commissioned at ESB_MX!

This commit is contained in:
2018-09-26 16:43:34 +02:00
parent 6f5278ec5c
commit d589cf8aed
3 changed files with 207 additions and 65 deletions

View File

@@ -34,7 +34,10 @@ Modes:
3: sine bode closed loop
4: chirp bode closed loop
5: full bode open loop record of both motors (including init_stage
10: bode of current step -> does not work because gathering phase data not implemented
-> check https://github.com/klauer/ppmac for fast data gathering server which supports
phase gathering -> not yet compiling: /home/zamofing_t/Documents/prj/SwissFEL/PowerBrickInspector/ppmac/fast_gather
BUT data acquired and stored in: /media/zamofing_t/DataUbuHD/VirtualBox/shared/data
TODO:
use openloopsine to create a bode diagram of the 'strecke'
'''
@@ -48,6 +51,8 @@ import subprocess as sprc
import telnetlib
from scipy.signal.waveforms import chirp
from scipy import signal
from scipy import interpolate
from scipy import stats
from utilities import *
class PBTuning:
@@ -71,8 +76,9 @@ class PBTuning:
fnLoc=self.fnLoc
except AttributeError:
fnLoc = '/tmp/gather.txt'
cmd=(PBGatherPlot,'-m24','-v0','--host',host,'--dat',fnLoc)
p = sprc.Popen(cmd, shell=False, stdin=sprc.PIPE, stdout=sprc.PIPE, stderr=sprc.PIPE)
cmd=(PBGatherPlot,'-m24','-v255','--host',host,'--dat',fnLoc)
#p = sprc.Popen(cmd, shell=False, stdin=sprc.PIPE, stdout=sprc.PIPE, stderr=sprc.PIPE)
p = sprc.Popen(cmd, shell=False)
retval = p.wait()
print(p.stderr.read())
#print(p.stdout.read())
@@ -312,11 +318,10 @@ class PBTuning:
f=np.load(file)
bode=f['bode']
meta=f['meta'].item()
frq=bode[:,0]
mag=bode[:,1]
phase=np.unwrap(bode[:,2])
frq=[bode[:,0],]
mag=[bode[:,1],]
phase=[np.unwrap(bode[:,2]),]
l=[0,len(frq)]
#for fn in ('chirp_ol_mot%da.npz','chirp_ol_mot%db.npz','chirp_ol_mot%dc.npz','chirp_ol_mot%dd.npz'):
# fn=fn%mot
# file=os.path.join(base,fn)
@@ -325,7 +330,7 @@ class PBTuning:
f=np.load(file)
data=f['data']
meta=f['meta'].item()
tSec=meta['tSec']
tSec=float(meta['tSec'])
minFrq=meta['minFrq']
maxFrq=meta['maxFrq']
amp=meta['amp']
@@ -342,42 +347,68 @@ class PBTuning:
ftX=np.fft.rfft(c)
ftY=np.fft.rfft(o)
i=int(minFrq*tSec); j=int(maxFrq*tSec); #print(w[i],w[j])
f=np.arange(n+1)/tSec #Hz
f=f[i:j+1]
frq_=np.arange(n+1)/tSec #Hz
frq_=frq_[i:j+1]
ftX=ftX[i:j+1]
ftY=ftY[i:j+1]
ft=ftY/ftX
frq=np.concatenate((frq,f))
frq.append(frq_)
phase_=np.unwrap(np.angle(ft))
if phase_[0]>0:
phase_-=2*np.pi
phase=np.concatenate((phase,phase_))
mag=np.concatenate((mag,(np.abs(ftY)/np.abs(ftX))))
l.append(len(frq))
phase.append(phase_)
mag.append(np.abs(ftY)/np.abs(ftX))
db_mag=20*np.log10(mag)
phase=np.degrees(phase)# numpy.unwrap(p, discont=3.141592653589793, axis=-1)
numFrq=1000
fFrq= np.logspace(np.log10(frq[0][0]), np.log10(frq[-1][-1]),numFrq)
fdb_mag = np.zeros(fFrq.shape)
fdeg_phase = np.zeros(fFrq.shape)
fig = plt.figure()
fig.canvas.set_window_title('full bode of motor %d'%mot)
ax = fig.add_subplot(2, 1, 1)
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
plt.title('bode of motor %d'%mot)
for i in range(len(l)-1):
ax.semilogx(frq[l[i]:l[i+1]], db_mag[l[i]:l[i+1]],'-') # Bode magnitude plot
ax.yaxis.set_label_text('dB ampl')
ax.set_xlim(1,2000)
plt.grid(True)
#ax.loglog(frqLst, bode[:,0],'.-') # Bode magnitude plot
ax = fig.add_subplot(2, 1, 2)
for i in range(len(l)-1):
ax.semilogx(frq[l[i]:l[i+1]], phase[l[i]:l[i+1]],'-')#,zorder=i) # Bode phase plot
ax.yaxis.set_label_text('phase')
ax.xaxis.set_label_text('frequency [Hz]')
ax.set_xlim(1,2000)
ax.set_ylim(-360,0)
plt.grid(True)
for i in range(len(frq)):
db_mag = 20 * np.log10(mag[i])
deg_phase = np.degrees(phase[i]) # numpy.unwrap(p, discont=3.141592653589793, axis=-1)
if deg_phase[0]>0:
deg_phase-=360
ax1.semilogx(frq[i], db_mag,'-') # Bode magnitude plot
ax2.semilogx(frq[i], deg_phase, '-') # ,zorder=i) # Bode phase plot
#fill the final magnitude and phase
if i==0:
f=interpolate.interp1d(frq[i], db_mag,bounds_error=False)
fdb_mag=f(fFrq)
f=interpolate.interp1d(frq[i], deg_phase,bounds_error=False)
fdeg_phase=f(fFrq)
else:
print((frq[i][0],frq[i][-1]))
s=stats.binned_statistic(frq[i], db_mag,'mean',fFrq)[0]
b=~np.isnan(s); fdb_mag[:-1][b]=s[b] #[:-2][b] because the statistics has one less entry than the count of bins
s=stats.binned_statistic(frq[i], deg_phase,'mean',fFrq)[0]
b=~np.isnan(s); fdeg_phase[:-1][b]=s[b]
pass
ax1.semilogx(fFrq, fdb_mag,'y')
ax2.semilogx(fFrq, fdeg_phase, 'y')
#export bode plot fot matlab analysis
fn = os.path.join(base,'full_bode_mot%d.mat'%mot)
import scipy.io
scipy.io.savemat(fn, mdict={'db_mag':fdb_mag,'deg_phase':fdeg_phase})
#scipy.io.savemat('/home/zamofing_t/afs/ESB-MX/data/' + fn + '.mat', mdict=f)
ax1.yaxis.set_label_text('dB ampl')
ax1.set_xlim(1,2000)
ax1.grid(True)
ax2.yaxis.set_label_text('phase')
ax2.xaxis.set_label_text('frequency [Hz]')
ax2.set_xlim(1,2000)
ax2.set_ylim(-360,0)
ax2.grid(True)
pass
def bode_model_plot(self, mot,base):
self.bode_full_plot(mot,base)
@@ -481,7 +512,7 @@ class PBTuning:
den=den1*den2*den3*den4*den5*denc
mdl= signal.lti(num, den) #num denum
bode(mdl)
w=np.logspace(0,3,1000)*2*np.pi
w=np.logspace(0,np.log10(2000),1000)*2*np.pi
w,mag,phase = signal.bode(mdl,w)
f=w/(2*np.pi)
ax=fig.axes[0]
@@ -490,8 +521,24 @@ class PBTuning:
ax.semilogx(f, phase,'-k',lw=2) # Bode phase plot
# tp print see also: print(np.poly1d([1,2,3], variable='s')), print(np.poly1d([1,2,3], r=True, variable='s'))
def bode_current(self,openloop=True,motor=1,magMove=1000,magPhase=500,dwell=10,file='/tmp/bode.npz'):
#currentstep 2 1000 500 10
#magPhase: set this current to move the stage at a stable position: vslue in bits
#magMove: set this current to measure the current transition: value in bits
#dwell: measurement time in ms.the time the current is set
# Amplifier specs (Power Brick LV User Manual.pdf p.19)
# 5A_rms continous current
# 15A_rms peak current
# 14 bit ADC resolution
# 2us PWM deadBand
# 33.85A Maximum ADC Current (corresponds to a DAC Value 32737 ==2^15)
data = self.do_command('currentstep', motor, magMove, magPhase, dwell)
def bode(mdl):
w,mag,phase = signal.bode(mdl)
w,mag,phase = signal.bode(mdl,1000)
f=w/(2*np.pi)
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)
@@ -626,6 +673,10 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
tune.bode_chirp(openloop=True,file=file[:-4]+'c.npz',motor=mot,amp=50,minFrq=300,maxFrq=1500,tSec=10)
tune.init_stage()
tune.bode_chirp(openloop=True,file=file[:-4]+'d.npz',motor=mot,amp=100,minFrq=300,maxFrq=2000,tSec=10)
elif mode==10:
#for mot in (1,2):
tune.bode_current(motor=mot, magMove=1000, magPhase=500, dwell=10, file='/tmp/curr_step%d.npz'%mot)
print 'done'
plt.show()
#------------------ Main Code ----------------------------------
#ssh_test()