From ea681abb4cca8b9dd584fa24f460550dd15f81f0 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Tue, 5 Feb 2019 16:51:35 +0100 Subject: [PATCH] working on document --- MXfastStageDoc/MXfastStage.tex | 262 +++++++++++++++++++++++++++++++-- MXfastStageDoc/model.svg | 238 ++++++++++++++++++++++++------ matlab/current_loop.slx | Bin 0 -> 25541 bytes matlab/identifyFxFyStage.m | 4 +- matlab/stage_closed_loop.slx | Bin 36018 -> 36273 bytes python/MXTuning.py | 113 +++++++++++--- 6 files changed, 537 insertions(+), 80 deletions(-) create mode 100644 matlab/current_loop.slx diff --git a/MXfastStageDoc/MXfastStage.tex b/MXfastStageDoc/MXfastStage.tex index 23b7f31..00162f8 100644 --- a/MXfastStageDoc/MXfastStage.tex +++ b/MXfastStageDoc/MXfastStage.tex @@ -16,6 +16,7 @@ \usepackage{hyperref} \usepackage{amsmath} \renewcommand{\deg}{$^\circ$} +\usepackage[section]{placeins} %place images in section \title{Tuning/modeling fast stages of ESB-MX} \author{Thierry Zamofing} @@ -42,15 +43,12 @@ This is set in the gpasciiCommander templates: PwmSf=15134.8909 # =.95*16384. PMAC3-style DSPGATE3 ASIC is being used for the output, the counter moves between +/- 16384. PwmSf is typically set to 95% of 16384 \end{verbatim} -Nerverless the documentation is confusing. Therefore PwmSf will measure to convert idCmd bits values to idVolts bits at a DC value. - -In steady state an idMeas=... results in idVolts=... -(TO BE DONE)\\ +Nerverless the documentation is confusing. Therefore PwmSf will be measured to convert idCmd bits values to idVolts bits in section \ref{sec:measCurStep} The Parker stages are configured to contCur=800mA ,peakCur=2400mA. Specs of the D11 stage are 0.8Amp RMS (producing 4N force) and 2.4Amp RMS peak.\\ It should be save to set 0.92Amp DC and 2.8Amp DC. -\subsection{Measure Current Step} +\subsection{Measure Current Step}\label{sec:measCurStep} \verb|MXTuning.py –mode 1| $\rightarrow$ \verb|identifyFxFyStage.m|\\ \includegraphics[scale=.5]{../matlab/figures/currstep_1.eps} @@ -64,6 +62,27 @@ The loop parameters are:\\ IiGain=5, IpfGain=8, IpbGain=8 +In steady state an idCmd=idMeas=406. results in aprox. idVolts=7400\\ +This has been measured precisly from gathered data \verb|chirp_all_1a.npz| +at frequencies from 10 to 220 Hz. +The images have been generated with +\verb|./MXTuning.py --dir MXTuning/19_01_29 --mode 128|.\\ + +The overall aplification $iqCmd \rightarrow iqVolts$ is approx. 18.2. + +\begin{figure}[h!] +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/iqCmd_TF0.eps} +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/iqCmd_TF1.eps} +\caption{IqCmd->IqMeas of motor 1 (bode same for both motors)} +\end{figure} + +\begin{figure}[h!] +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/iqCmd_TF2.eps} +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/iqCmd_TF3.eps} +\caption{IqCmd->IqVolts of motor 1 (bode same for both motors)} +\end{figure} + +\FloatBarrier \subsection{Measure Open Loop} The frequency response has been measured with chirps at different amplitudes and frequency regions. The yellow line is averaged measurement data. The black line is the approximated model. The diagram shows \verb|curr_bits| (ca.1mA) to \verb|ActPos| (in um) transfer function.\\ @@ -74,6 +93,7 @@ The images have been generated with \includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/bode_model_plot0.eps} \includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/bode_model_plot2.eps} \caption{open loop of motor 1 and 2} +\label{fig:mot_open} \end{figure} @@ -130,8 +150,9 @@ The parameters for that sweep is:\\ \begin{figure}[h!] \includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_2b0.eps} -\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_2b1.eps} +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_2b1.eps} \caption{DesPos->ActPos of motor 2} +\label{fig:mot1_chirp} \end{figure} @@ -139,6 +160,7 @@ The parameters for that sweep is:\\ \includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_1b2.eps} \includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_1b3.eps} \caption{DesPos->IqCmd of motor 1} +\label{fig:mot2_chirp} \end{figure} \begin{figure}[h!] @@ -147,10 +169,9 @@ The parameters for that sweep is:\\ \caption{DesPos->IqCmd of motor 2} \end{figure} - Moving 5um with frequencies from 10 to 220Hz\\ $\rightarrow$ at frequencies above 200 Hz, the current increses up to 2 amps, and the the following error kicks in\\ -$\rightarrow$ The response becomes bad above 15Hz (about 3dB)\\ +$\rightarrow$ The closed loop response becomes bad above 20Hz (motor 1 ca. -10\%, motor 2 +5\% )\\ $\rightarrow$ Moving 1um at 1kHz seems to consume a current of about 2 amps.\\ @@ -214,6 +235,18 @@ d=1\\ \end{aligned} \] +To use real values we have to consider: The values +$IiGain=5, IpfGain=8, IpbGain=8$ for the Deltatau are in z-domain.\\ +Therefore for the continous domain they have to be scaled: +$Ii=IiGain/ts \quad Ipf=IpfGain \quad Ipb=IpbGain$ with $ts=50\mu s$ (20kHz)\\ + +The overall aplification $iqCmd \rightarrow iqVolts$ measured in section {sec:measCurStep} is approx. 18.2. + +The resistance of the stage is 8.8 $\Omega$\\ +The inductance of the stage is 2.4 mH.\\ + +It seems that this works only in the discrete space. s.a. \verb|current_loop.slx|.\\ +Therefore the only approach is to use the transfer function as approximated in section \ref{sec:measCurStep}. \subsection{Mechanical model} @@ -340,22 +373,229 @@ U=R\cdot I \qquad P=U \cdot I \quad \rightarrow \quad P=R \cdot I^2\\ at a constant current of 0.92A we have $ 8.8 \cdot 0.92^2 = 7.44 $W the resulting force will be:\\ $1.46N \cdot \sqrt{7.44} = 3.98 N$ + +\subsection{identification of stages} + +The goal is to build an optimal state space model of the plant with following input and output taps: + +\begin{figure}[h!] +\center +\includegraphics[scale=.7]{model4.eps} +\caption{model taps} +\end{figure} + + +\verb|full_bode_mot[1|2].mat| is generated from \verb|MXTuning.py| in function \verb|bode_model_plot()|. It contains the bode data of real measurements and approximated transfer functions. + +\verb|identifyFxFyStage.m| reads the python data \verb|full_bode_mot[1|2].mat| and build motor objects with transfer functions and state space models. + +The approximated transfer functions can be tweaked and edited with: e.g. \verb|controlSystemDesigner('bode',1,mot1.tf_xx)| to enhance the model. +The full transfer function is then split in individual parts that are put back into \verb|MXTuning.py|.\\ + +the transfer functions for each two motors are separated in:\\ + +\begin{tabular}{|l|l|l|l|} +\hline +key & description & motor1 (fy) & motor2 (fx) \\ +\hline +tfc & curren loop tf & f=694 ? 1389 , d=0.75 & same \\ +tf1 & \vtop{\hbox{\strut main mechanical tf} \hbox{\strut with -40dB/dec }} + & mag=6dB f=7.96Hz d=0.6 & mag=12dB f=3.34 d=0.4 \\ +tf2 & mechanical resonance tf & f=[197,199] d=[0.02,0.02] & f=[55|61] d=[0.2|0.2] \\ +tf3 & mechanical resonance tf & & f=[128|137] d=[0.05|0.05] \\ +tf4 & mechanical resonance tf & & f=[410|417] d=[0.015|0.015] \\ +tf5 & mechanical resonance tf & & f=[230|233] d=[0.04|0.04] \\ +\hline +\end{tabular} + +\vspace{1pc} +The black line on figure \ref{fig:mot_open} shows the concatenate transfer function. +\vspace{1pc} + +\fbox{\parbox[t]{15cm}{The current loop frequency from the MATLAB identification looks different than the used one. Matlab identifies $w_0=8727rad/sec = f0=1389Hz$ but to match the bode plot a value of half frequency need to be taken:$f_0=694$.}} +\vspace{1pc} + +The motor objects contains also 'state space models' of different complexity. From the best approach to the most simlified model. + +As first approach the tf function is just converted to the ss space and the ss matrices are glued together. + +The matlab models are:\\ + +\begin{tabular}{ll} +\texttt{ssPlt:} & best approach of the plant with mechanics, resonance, current loop etc.\\ +\texttt{ssMdl\_c1:} & model without resonance (only current and main mechanical)\\ +\texttt{ssMdl\_12:} & model without current loop, with one resonance (main mechanical + first resonance)\\ +\texttt{ssMdl\_1:} & model without current loop, no resonance (only main mechanical)\\ +\end{tabular} + + \section{Simulink/MATLAB simulations} +It has to be checked if the model matches the real stage. Therefore simulations in MATLAB have been done to validate the identification process of the stages. -TODO: describe the identification process to get a model out of the bode plots. identifyFxFyStage.m\\ +\subsection{chirp sine closed loop with simulink model} -Simulink simulation \verb|stage_closed_loop.slx| with \verb|ServoDeltaTau_z G(z)| showed similar response -Therefore the model seems good enough +To compare the measurements with the model following lines were executed in MATLAB +\begin{verbatim} +clear;clear global;close all; +mot=cell(2,1); +[mot{1},mot{2}]=identifyFxFyStage(); +for k =1:2 + [pb]=simFxFyStage(mot{k});sim('stage_closed_loop'); + f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g'); + set(h(1), 'color', 'b'); set(h(2), 'color', [0 0.5 0]); + print(f,sprintf('figures/sim_cl_DTGz_%d',mot{k}.id),'-depsc'); +end +\end{verbatim} + +The Simulink model \verb|stage_closed_loop| contains various controller blocks. as \verb|PID G(s)|, \verb|PID G(z)|, \verb|ServoDeltaTau_z G(s)| and \verb|ServoDeltaTau_z G(z)|. + +With the controller block \verb|ServoDeltaTau_z G(z)| the real measurements can be compared with the simulated model. +Figures \ref{fig:mot_chirp_sim} showed similar response as the real stages (Figures \ref{fig:mot1_chirp}, \ref{fig:mot2_chirp}). Therefore the model matches the real stage well. + + +\begin{figure}[h!] +\center + +\includegraphics[scale=.45]{../matlab/figures/sim_cl_DTGz.png} +\includegraphics[scale=.65]{../matlab/figures/sim_cl_DTGz_1.eps} +\includegraphics[scale=.65]{../matlab/figures/sim_cl_DTGz_2.eps} +\caption{Motor 1 sim Motor 2 sim} +\label{fig:mot_chirp_sim} +\end{figure} + + +The model can be used to imrove the controller in MATLAB/simulink. + +Improvement of the regulation with a simple PID loop and with prefilters did not improve the regulation quality.\\ +Therefore for better regulation quality more sophisticated controllers as state controllers will be tested. + +\subsection{State Space Controller with Observer} + +\verb|(s.a. http://ctms.engin.umich.edu/CTMS/index.php?example=Introduction§ion=ControlStateSpace)| + +A standard PID controller uses feedback to detect errors between the desired position and the actual position and applies corrective commands to compensate for those errors. Although PID control is the most common type of industrial controller, it does have limitations. +The idea of a state space controller with observer is to have a model of the plant which follows all internal states of the real plant. All these internal states of the model can then be used states to build an optimal controller. +opposite to the PID cpntroller which is a ‘black-box design’, the state space controller with observer is a ‘white box design’ + +To implement a state space controller with observer the model has to be observable and controllable. The full model as used above is not controllable due to the various resonance frequencies. Therefore for the state space controller a simplified model without the resonance frequencies is used. +Following lines are used to build the state space controller + +\begin{figure}[h!] +\centering +\includegraphics[scale=.75]{observer_statefeedback.png} +\caption{observer controller} +\end{figure} +\begin{verbatim} +clear;clear global;close all; +[mot{1},mot{2}]=identifyFxFyStage(); +for k =1:2 + close all;[ssc]=StateSpaceControlDesign(mot{k});sim('observer'); + f=figure(); + h=plot(desPos_actPos.Time,desPos_actPos.Data,'g'); + set(h(1), 'color', 'b'); + set(h(2), 'color', [0 0.5 0]); + print(f,sprintf('figures/sim_cl_DTGz_%d',mot{k}.id),'-depsc'); +end + +close all;[ssc]=StateSpaceControlDesign(mot2);sim('observer'); + +close all;[ssc]=StateSpaceControlDesign(mot1);sim('observer'); +[pb]=simFxFyStage(mot2);sim('stage_closed_loop'); +close all;[ssc]=StateSpaceControlDesign(mot2);sim('observer'); + +\end{verbatim} +This plot displays bode diagrams of motor 2. The used model for the controller is the blue line, which contains the current loop model and the mechanical model. + +The state space controller is calculated by pole placement on the observer model and on the closed loop system + +Now the controller must be implemented on deltatau to check the performance on the real stage. + +\subsection{Implementing state space controller on Deltatau} + +In MATLAB the function StateSpaceControlDesign() MATLAB produces files /tmp/ssc[1|2].mat. +The driver code can be generated with: MXTuning.py –mode 8 + +Finally the real time servo code for the DeltaTau has to be compiled with: +\verb|/epics_ioc_modules/ESB_MX/python/usr_code$ make| + + +The system was simulated with 5kHz servo loop frequency +Higher servo loop frequency does not help, because a continious state space controller behaves not relevantly better than a sampled state space controller at 5kHz. + + +Model of the stage instead of measuring transfer function + +\textbf{Overview of code}\\ + +\vspace{1pc} + +\begin{tabular}{ll} +\texttt{identifyFxFyStage.m}& read python data and build motor objects. plot bode\\ +\texttt{simFxFyStage.m}& build a pb structure which contains current (Jan 2019) Powerbrick controller settings\\ +\texttt{StateSpaceControlDesign.m}& design a discrete observer for Fx,Fy stages\\ +\end{tabular} + + + +\newpage +\section{SCRATCH} + +\begin{verbatim} +clear; +clear global; +close all; +[mot1,mot2]=identifyFxFyStage(); +[pb]=simFxFyStage(mot1);sim('stage_closed_loop'); +close all;[ssc]=StateSpaceControlDesign(mot1);sim('observer'); +[pb]=simFxFyStage(mot2);sim('stage_closed_loop'); +close all;[ssc]=StateSpaceControlDesign(mot2);sim('observer'); + +mögliche tf: +iqCmd---->iqMeas +iqVolts-->iqMeas +iqMeas--->actPos + +identifyFxFyStage.m +controlSystemDesigner('bode',1,mot1.tf_py); % <<<<<<<<< This opens a transferfunction that can be edited +\end{verbatim} + +\begin{figure}[h!] +\center +\framebox[5cm]{\vtop{\vspace{2cm}\hbox{INSERT GRAPHICS}\vspace{2cm}}} +\framebox[5cm]{\vtop{\vspace{2cm}\hbox{INSERT GRAPHICS}\vspace{2cm}}} +%\includegraphics[scale=.7]{model4.eps} +\caption{Motor 1 sim Motor 2 sim} +\end{figure} + + + +\newpage +\section{shapepath} +\begin{verbatim} +Add section shapepath: +---------------------- +TODO: +trajectory generation: trajectory.py +images of spiral motion: +with pvt motion -> +with pvt0 motion -> +with ift motion -> + +TODO: +timing of motion +\end{verbatim} + + \newpage \section{HelicalScan coordinates} diff --git a/MXfastStageDoc/model.svg b/MXfastStageDoc/model.svg index 04e1608..b4f71ea 100644 --- a/MXfastStageDoc/model.svg +++ b/MXfastStageDoc/model.svg @@ -484,11 +484,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1.9795908" - inkscape:cx="236.80936" - inkscape:cy="676.66651" + inkscape:zoom="3.9591816" + inkscape:cx="214.19855" + inkscape:cy="140.433" inkscape:document-units="mm" - inkscape:current-layer="g4662" + inkscape:current-layer="layer1" showgrid="true" inkscape:snap-grids="false" inkscape:snap-nodes="true" @@ -535,7 +535,7 @@ image/svg+xml - + @@ -544,7 +544,8 @@ inkscape:groupmode="layer" id="layer1"> + id="g4751" + transform="translate(-115.97567,-159.20536)"> @@ -561,7 +562,7 @@ inkscape:connector-curvature="0" /> k2 d2 k3 d3 k4 d4 k1 d1 F x1 + id="g3751" + transform="translate(-76.164766,-80.012455)"> Ipf 1/s Ii Ipb F x x - + id="g4644" + transform="translate(-17.784359,-38.086449)"> iqVolts + + + + + iqCmd + + + iqVolts + + + + iqMeas (equals force and acceleration) + + + + actVel + + + + actPos + + stagex or y + diff --git a/matlab/current_loop.slx b/matlab/current_loop.slx new file mode 100644 index 0000000000000000000000000000000000000000..c83fb3a313c50df74836c61b5070d36f3ddecefa GIT binary patch literal 25541 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 literal 0 HcmV?d00001 diff --git a/matlab/identifyFxFyStage.m b/matlab/identifyFxFyStage.m index 75087ca..749bf66 100644 --- a/matlab/identifyFxFyStage.m +++ b/matlab/identifyFxFyStage.m @@ -62,12 +62,12 @@ function [mot1,mot2]=identifyFxFyStage() s=str2ndOrd(tfc); t=(0:199)*50E-6; [y,t]=step(tfc,t); - f=figure();f.Position=[200,100,900,500] + f=figure();f.Position=[200,100,900,500]; subplot(1,2,1); plot(t*1000,obj.currstep.OutputData(11:210),'b',t*1000,y*1000,'r'); xlabel('ms') ylabel('curr\_bits') - grid on + grid on; legend('real signal','model','Location','southeast') title(s); subplot(1,2,2); diff --git a/matlab/stage_closed_loop.slx b/matlab/stage_closed_loop.slx index cecc097d1b06bb501edbebe7db3b97075933261f..9f72091335ca2dc8c9934b5d2d1b6dc432bfe93a 100644 GIT binary patch delta 23451 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 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 @@ -37,6 +38,27 @@ from pbtools.misc.gather import Gather from pbtools.misc.tuning import Tuning +# import sys, os + +def wait_key(): + ''' Wait for a key press on the console and return it. ''' + result = None + import termios + fd = sys.stdin.fileno() + + oldterm = termios.tcgetattr(fd) + newattr = termios.tcgetattr(fd) + newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO + termios.tcsetattr(fd, termios.TCSANOW, newattr) + try: + result = sys.stdin.read(1) + except IOError: + pass + finally: + termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) + return result + + class MXTuning(Tuning): tuneDir='/opt/ppmac/tune/' @@ -75,7 +97,7 @@ class MXTuning(Tuning): #identify matlab: k:0.671226 w0:134.705 damp:0.191004 mag1=6 #10**(db_mag1/20) db_mag1=20*np.log10(mag1)#dB - w1=53.4705*_N #rad/sec + w1=50.*_N #rad/sec f1=w1/2/np.pi; # ca. 6.5Hz T1=1/w1 d1=0.6 # daempfung =1 -> keine resonanz -> den1= np.poly1d([T1,1])**2 @@ -126,7 +148,7 @@ class MXTuning(Tuning): #identify matlab: k:1.7282 w0:51.069 damp:0.327613 mag1=12. #10**(db_mag1/20) db_mag1=20*np.log10(mag1)#dB - w1=18.*_N #rad/sec + w1=21.*_N #rad/sec f1=w1/2/np.pi; # ca. 6.5Hz T1=1/w1 d1=0.4 # daempfung =1 -> keine resonanz -> den1= np.poly1d([T1,1])**2 @@ -134,8 +156,8 @@ class MXTuning(Tuning): den1 = np.poly1d([T1**2,2*T1*d1,1]) #resonance frequency - f2=np.array([57.8,61.8]) - d2=np.array([.08,.095])#daempfung + f2=np.array([55.,61.]) + d2=np.array([.2,.2])#daempfung w2=f2*2*np.pi #rad/sec T2=1/w2 num2 = np.poly1d([T2[0]**2,2*T2[0]*d2[0],1]) @@ -144,7 +166,7 @@ class MXTuning(Tuning): #bode(mdl) #resonance frequency - f3=np.array([136,148]) + f3=np.array([128,137]) d3=np.array([.05,.05])#daempfung w3=f3*2*np.pi #rad/sec T3=1/w3 @@ -456,7 +478,7 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) save_figs(os.path.join(self.baseDir,'bode_model_plot')) if mode&64: # plot all raw acquired data files - # display bode plots + plt.close('all') import glob for fn in glob.glob(os.path.join(self.baseDir,'*.npz')): print(fn) @@ -464,11 +486,64 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) meta = fh['meta'].item() data = fh['data'] plt.close('all') - self.bode_plot(data, mode=25, kwargs=meta) + bm=25 + if fn.find('all')>0: + bm+=32 #amplitude linear (not dB) + self.bode_plot(data, mode=bm, kwargs=meta) plt.show(block=False) save_figs(fn) + #wait_key() + raw_input('press return') - if mode&128: #generater code + + if mode&128: #custom plots + plt.close('all') + G1=signal.lti([1/8.8], [2.4E-3/8.8,1]) # num denum + print('rise time %e s'%(2.4E-3/8.8)) + bode(G1) + t,y=G1.step() + fig=plt.figure();ax=fig.add_subplot(1,1,1) + ax.plot(t,y) + #current loop 2nd order approx + #identification with matlab: k=1, w0=8725, d=0.75 + dc=.75 # daempfung =1 -> keine resonanz -> den1= np.poly1d([T1,1])**2 + wc=8725. # rad/sec + #...but phase lag seems to have earlier effect -> reduce wc. Probably because of the slower outer servo loop + wc*=.5 # rad/sec + Tc=1/wc + num=np.poly1d([1.]) + den=np.poly1d([Tc**2,2*Tc*dc,1]) + mdl=signal.lti(num, den) # num denum + bode(mdl) + t,y=mdl.step() + ax.plot(t,y) + ax.grid(True) + plt.show(block=False) + raw_input('press return') + + plt.close('all') + fn=os.path.join(self.baseDir,'chirp_all_1a.npz') + fh=np.load(fn) + data=fh['data'] + meta=fh['meta'].item() + meta['file']=fn + # 2 DesPos,ActPos,IqCmd,IqMeas,IqVolts (for current, plant and regulation transfer function) + for xy in ((2, 3), (2, 4)): + self.bode_plot(data, xy=xy, mode=25+32, kwargs=meta) + + fig=plt.figure(2) + fig.axes[0].set_ylim(.9, 1.1) + fig.axes[1].set_ylim(-40,10) + fig.suptitle('tf: iqCmd->iqMeas', fontsize=16) + fig=plt.figure(4) + fig.axes[0].set_ylim(15,30) + fig.axes[1].set_ylim(-20,20) + fig.suptitle('tf: iqCmd->iqVolts', fontsize=16) + plt.show(block=False) + save_figs(os.path.join(self.baseDir,'iqCmd_TF')) + + + if mode&256: #generater code #before this can be done, the observer controller has to be designed with matlab: #s.a.ESB_MX/matlab/Readme.md #clear; @@ -501,9 +576,10 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) fh.close() print(fnc+' generated.') print('now compile it looking at PBTools/pbtools/usr_servo_phase/usrServoSample') - print('done') - plt.show() + plt.show(block=False) + raw_input('press return') + def save_figs(fn): figures = [manager.canvas.figure @@ -524,14 +600,14 @@ def bode(mdl): w,mag,phase = signal.bode(mdl,1000) f=w/(2*np.pi) fig = plt.figure() - ax = fig.add_subplot(2, 1, 1) - ax.semilogx(f,mag,'-') # Bode magnitude plot - ax.yaxis.set_label_text('dB ampl') + ax1 = fig.add_subplot(2, 1, 1) + ax1.semilogx(f,mag,'-') # Bode magnitude plot + ax1.yaxis.set_label_text('dB ampl') plt.grid(True) - ax = fig.add_subplot(2, 1, 2) - ax.semilogx(f,phase,'-') # Bode magnitude plot - ax.yaxis.set_label_text('phase') - ax.xaxis.set_label_text('frequency [Hz]') + ax2 = fig.add_subplot(2, 1, 2, sharex = ax1) + ax2.semilogx(f,phase,'-') # Bode magnitude plot + ax2.yaxis.set_label_text('phase') + ax2.xaxis.set_label_text('frequency [Hz]') plt.grid(True) #plt.show() @@ -577,6 +653,7 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' tune.baseDir=args.dir assert(os.path.exists(tune.baseDir)) tune.run(args.mode) + #------------------ Main Code ---------------------------------- #ssh_test()'/tmp/usrcode.c' ret=parse_args()