add PBTuneing.py
This commit is contained in:
182
python/PBTuning.py
Executable file
182
python/PBTuning.py
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python
|
||||
# *-----------------------------------------------------------------------*
|
||||
# | |
|
||||
# | Copyright (c) 2016 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
# | |
|
||||
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
|
||||
# *-----------------------------------------------------------------------*
|
||||
'''
|
||||
tuning functions for deltatau:
|
||||
For now it does 10 step move and uploads the data
|
||||
other available tuning progs on the powerbrick are:
|
||||
analyzerautotunemove
|
||||
autotunecalc
|
||||
autotunemove
|
||||
chirpmove
|
||||
currentautotunecalc
|
||||
currentstep
|
||||
filtercalculation
|
||||
openloopchirp
|
||||
openloopsine
|
||||
openlooptestmove
|
||||
othertrajectory
|
||||
parabolicmove
|
||||
randommove
|
||||
sinesweep
|
||||
sinusoidal
|
||||
stepmove
|
||||
user_gantry_crosscoupled.h
|
||||
usertrajectory
|
||||
|
||||
TODO:
|
||||
use openloopsine to create a bode diagram of the 'strecke'
|
||||
'''
|
||||
|
||||
import os, sys, json, time
|
||||
import numpy as np
|
||||
import matplotlib as mpl
|
||||
#mpl.use('GTKAgg')
|
||||
import matplotlib.pyplot as plt
|
||||
import subprocess as sprc
|
||||
import telnetlib
|
||||
from utilities import *
|
||||
|
||||
class PBTuning:
|
||||
tuneDir='/opt/ppmac/tune/'
|
||||
|
||||
def __init__(self,args):
|
||||
self.args=args
|
||||
|
||||
def do_command(self,cmd,*param):
|
||||
args=self.args
|
||||
host=args.host
|
||||
cmd=('ssh','root@'+host, self.tuneDir+cmd)+tuple(map(str,param))
|
||||
p=sprc.Popen(cmd, shell=False, stdin=sprc.PIPE, stdout=sprc.PIPE, stderr=sprc.PIPE)
|
||||
res=p.wait()
|
||||
print(res)
|
||||
print(p.stderr.read())
|
||||
print(p.stdout.read())
|
||||
PBGatherPlot='/home/zamofing_t/scripts/PBGatherPlot'
|
||||
try:
|
||||
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)
|
||||
retval = p.wait()
|
||||
print(p.stderr.read())
|
||||
#print(p.stdout.read())
|
||||
|
||||
#self.meta = {'timebase': ServoPeriod*gather['Period']}
|
||||
self.data = np.genfromtxt(fnLoc, delimiter=' ')
|
||||
return self.data
|
||||
|
||||
def phase_amp(self,frq,rep):
|
||||
try:
|
||||
ax1=self.ax1
|
||||
ax2=self.ax2
|
||||
ax1.clear()
|
||||
ax2.clear()
|
||||
except AttributeError:
|
||||
fig = plt.figure(); self.ax1=ax1 = fig.add_subplot(1, 1, 1)
|
||||
fig = plt.figure(); self.ax2=ax2 = fig.add_subplot(1, 1, 1)
|
||||
n = self.data.shape[0]
|
||||
w=np.hamming(n)
|
||||
res=np.ndarray((2,2))
|
||||
col=('b-','g-')
|
||||
for i in (0,1):
|
||||
data=self.data[:,i]
|
||||
data=(data-data[0])*w
|
||||
ax1.plot(data, col[i])
|
||||
f = np.fft.fft(data)
|
||||
ax2.plot(np.absolute(f) , col[i])
|
||||
idx = int(rep)
|
||||
bias = np.absolute(f[0] / n)
|
||||
phase = np.angle(f[idx])
|
||||
#ampl = np.absolute(f[idx]) * 2 / n
|
||||
ampl = np.absolute(f[idx]) * 2 / w.sum()
|
||||
res[i,:]=(ampl,phase)
|
||||
plt.pause(.05)
|
||||
return (res[1,0]/res[0,0],res[1,1]-res[0,1])
|
||||
|
||||
def bode_gather(self,motor=1,minFrq=1,maxFrq= 100,numFrq= 100,amp=10,file='/tmp/bode.npz'):
|
||||
#amp= percentage of maximum amplitude
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1)
|
||||
frqLst=np.logspace(np.log10(minFrq),np.log10(maxFrq),numFrq)
|
||||
n=len(frqLst)
|
||||
#frqLst=(10,15,20,25,30)
|
||||
bode=np.ndarray((n,3))
|
||||
bode[:, 0]=frqLst
|
||||
for i in range(n):
|
||||
frq=frqLst[i]
|
||||
t=1
|
||||
rep=max(1,frq*t)
|
||||
self.fnLoc='/tmp/gather%d.txt'%i
|
||||
data=self.do_command('openloopsine',motor,amp,frq,rep,0)
|
||||
ax.clear()
|
||||
ax.plot(data[:, 0]-data[0, 0] , 'b-', label='input')
|
||||
ax.plot(data[:, 1]-data[0, 1], 'g-', label='output')
|
||||
plt.pause(.05)
|
||||
bode[i,1:]=self.phase_amp(frq, rep)
|
||||
print('frq %g ampl %g phase %g'%tuple(bode[i,:]))
|
||||
plt.draw_all()
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(2, 1, 1)
|
||||
ax.semilogx(frqLst, bode[:,0]) # Bode magnitude plot
|
||||
#ax.loglog(frqLst, bode[:,0],'.-') # Bode magnitude plot
|
||||
ax = fig.add_subplot(2, 1, 2)
|
||||
ax.semilogx(frqLst, bode[:,1]) # Bode phase plot
|
||||
plt.show()
|
||||
meta={'motor':motor,'date':time.asctime()}
|
||||
np.savez_compressed(file, bode=bode, meta=meta)
|
||||
|
||||
def bode_plot(self,file):
|
||||
f=np.load(file)
|
||||
bode=f['bode']
|
||||
meta=f('meta')
|
||||
frq=bode[:,0]
|
||||
db_mag=20*np.log10(bode[:,1])
|
||||
phase=np.unwrap(bode[:,2])# numpy.unwrap(p, discont=3.141592653589793, axis=-1)
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(2, 1, 1)
|
||||
ax.semilogx(frq, db_mag,'.-') # Bode magnitude plot
|
||||
ax.xaxis.set_label_text('dB Mag.')
|
||||
#ax.loglog(frqLst, bode[:,0],'.-') # Bode magnitude plot
|
||||
ax = fig.add_subplot(2, 1, 2)
|
||||
ax.semilogx(frq, phase,'.-') # Bode phase plot
|
||||
ax.xaxis.set_label_text('phase')
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
from argparse import ArgumentParser,RawDescriptionHelpFormatter
|
||||
def parse_args():
|
||||
'main command line interpreter function'
|
||||
#usage: gpasciiCommunicator.py --host=PPMACZT84 myPowerBRICK.cfg
|
||||
(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' '
|
||||
exampleCmd=('-n',
|
||||
'-v15'
|
||||
)
|
||||
epilog=__doc__+'''
|
||||
Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
|
||||
|
||||
parser=ArgumentParser(epilog=epilog,formatter_class=RawDescriptionHelpFormatter)
|
||||
|
||||
parser.add_argument('--host', help='hostname', metavar='HOST', required=True)
|
||||
parser.add_argument('--verbose', '-v', type=int, help='verbosity bits (see below)', default=0)
|
||||
parser.add_argument('--dryrun', '-n', action='store_true', help='dryrun to stdout')
|
||||
args=parser.parse_args()
|
||||
|
||||
plt.ion()
|
||||
tune=PBTuning(args)
|
||||
base='/home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/data/'
|
||||
file=sys.path.join(base,'bode1.npz')
|
||||
tune.bode(file=file,motor=1)
|
||||
tune.bode_plot(file)
|
||||
#tune.do_command('stepmove',1,100,500,0,0)
|
||||
#------------------ Main Code ----------------------------------
|
||||
#ssh_test()
|
||||
ret=parse_args()
|
||||
exit(ret)
|
||||
@@ -86,7 +86,7 @@ class ShapePath:
|
||||
#cfg = {"sequencer": ['gen_grid_points(w=20,h=20,pitch=50,rnd=0.2)', 'sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=10,acq_per=10)', 'plot_gather("'+fn+'.npz")']}
|
||||
#cfg = {"sequencer": ['gen_rand_points(n=400, scale=1000)', 'sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=10)', 'plot_gather("'+fn+'.npz")']}
|
||||
cfg = {"sequencer": ['gen_grid_points(w=40,h=40,pitch=100,rnd=0.4)', 'sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=10,cnt=1)', 'plot_gather("'+fn+'.npz")']}
|
||||
#cfg = {"sequencer":['gen_rand_points(n=400, scale=1000)','sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=20,acq_per=10)','plot_gather("'+fn+'.npz")']}
|
||||
cfg = {"sequencer":['gen_rand_points(n=900, scale=1000)','sort_points()','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=40,acq_per=10)','plot_gather("'+fn+'.npz")']}
|
||||
#cfg = {"sequencer": ['gen_swissfel_points(scale=300)','gen_prog(file="'+fn+'.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=100,acq_per=10)', 'plot_gather("'+fn+'.npz")']}
|
||||
#cfg = {"sequencer": ['opt_pts("'+fn+'.npz")','gen_prog(file="'+fn+'_corr.prg",host="SAR-CPPM-EXPMX1",mode=1,pt2pt_time=10,cnt=1)', 'plot_gather("'+fn+'_corr.npz")']}
|
||||
#cfg = {"sequencer": ['opt_pts("'+fn+'.npz")','gen_prog(file="'+fn+'.prg",mode=1,pt2pt_time=10,cnt=1)']}
|
||||
|
||||
Reference in New Issue
Block a user