wip
This commit is contained in:
@@ -33,7 +33,7 @@ This document describes the tuning and modeling process of the ESB-MX fast stage
|
||||
\section{Measurements}
|
||||
The tool used to record data of the fast stages is the bode plots is MXTuning.py, a script specially developed to record system responses. The main call to collect all data was:\\
|
||||
\verb|./MXTuning.py --dir MXTuning/19_01_29 --mode 64|\\
|
||||
The used frequencies are: 20 kHz Phase, 5 kHz Servo, 6.25MHz AdcAmp. This results in 50us PhaseTime and 0.2ms ServoTime.\\
|
||||
The used frequencies are: 20 kHz phase loop, 5 kHz servo loop, 6.25MHz AdcAmp. This results in 50us phase time and 0.2ms servo time.\\
|
||||
|
||||
According to the amplifier specs \cite[19]{PMAClv} a DAC Value of $32737=2^{15}$ corresponds to 33.85A current. So 1 \verb|curr_bit| is $33.85/32737A =1.034mA$.\\
|
||||
|
||||
@@ -46,7 +46,7 @@ the counter moves between +/- 16384. PwmSf is typically set to 95% of 16384
|
||||
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.
|
||||
It should be save to use the higher DC value of 0.92Amp and 2.8Amp instead of the RMS value.
|
||||
|
||||
\subsection{Measure Current Step}\label{sec:measCurStep}
|
||||
\verb|MXTuning.py –mode 1| $\rightarrow$ \verb|identifyFxFyStage.m|\\
|
||||
@@ -97,7 +97,7 @@ The images have been generated with
|
||||
\end{figure}
|
||||
|
||||
|
||||
\emph{Motor 1 (fy) has a better response, as expected because it has less mass to move.}\\
|
||||
\emph{Motor 1 (fy) has as expected a better response than Motor 2 (fx), because it has less mass to move.}\\
|
||||
|
||||
\hbox{
|
||||
\parbox[t]{5cm}{
|
||||
@@ -136,8 +136,9 @@ motor_servo(mot=2,Kp=22,Kvfb=350,Ki=0.02,Kvff=240,Kaff=1500,MaxInt=1000)
|
||||
\subsubsection{chirp sine closed loop}
|
||||
|
||||
|
||||
Chirp plot with input(blue) and output(green) and its bode plots.
|
||||
The parameters for that sweep is:\\
|
||||
Figures \ref{fig:mot1_chirp} to \ref{fig:mot2_chirp_cmd}
|
||||
shows chirp plot with the input(blue) and the output(green) and its bode plots.
|
||||
The parameters for that chirp is:\\
|
||||
\verb| amp: 5, minFrq: 10, maxFrq: 220, ts: 0.0002, tSec: 20|
|
||||
|
||||
|
||||
@@ -146,13 +147,14 @@ The parameters for that sweep is:\\
|
||||
\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_1b0.eps}
|
||||
\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_1b1.eps}
|
||||
\caption{DesPos->ActPos of motor 1}
|
||||
\label{fig:mot1_chirp}
|
||||
\end{figure}
|
||||
|
||||
\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}
|
||||
\caption{DesPos->ActPos of motor 2}
|
||||
\label{fig:mot1_chirp}
|
||||
\label{fig:mot2_chirp}
|
||||
\end{figure}
|
||||
|
||||
|
||||
@@ -160,13 +162,14 @@ 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}
|
||||
\label{fig:mot1_chirp_cmd}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_2b2.eps}
|
||||
\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/chirp_all_2b3.eps}
|
||||
\caption{DesPos->IqCmd of motor 2}
|
||||
\label{fig:mot2_chirp_cmd}
|
||||
\end{figure}
|
||||
|
||||
Moving 5um with frequencies from 10 to 220Hz\\
|
||||
@@ -183,6 +186,7 @@ $\rightarrow$ Moving 1um at 1kHz seems to consume a current of about 2 amps.\\
|
||||
\newpage
|
||||
\section{Modeling the system}
|
||||
\subsection{Electrical model}
|
||||
\label{sec:mdlElec}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[scale=.45]{model1.eps}
|
||||
@@ -240,13 +244,13 @@ $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 overall aplification $iqCmd \rightarrow iqVolts$ measured in section \ref{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}.
|
||||
Nevertheless simulations with \verb|current_loop.slx| showed, that the current loop only works in the discrete domain. In continous domain neither the amplification nor the shape mached.\\
|
||||
Therefore the only approach is to use the second order transfer function as approximated in section \ref{sec:measCurStep}.
|
||||
|
||||
\subsection{Mechanical model}
|
||||
|
||||
@@ -273,17 +277,17 @@ springs: $k=k_1+k_2+\ldots+k_n$\\
|
||||
m_2\ddot{x}_2= & k_2(x_2-x_1)+d_2(\dot{x}_2-\dot{x}_1)\\
|
||||
m_3\ddot{x}_3= & k_3(x_3-x_1)+d_3(\dot{x}_3-\dot{x}_1)\\
|
||||
m_4\ddot{x}_4= & k_4(x_4-x_1)+d_4(\dot{x}_4-\dot{x}_1)\\
|
||||
\end{aligned}\label{mech1}
|
||||
\end{aligned}\label{eq:mech1}
|
||||
\end{equation}
|
||||
|
||||
\begin{equation}
|
||||
\begin{aligned}
|
||||
\dot{x} = Ax + Bu\\
|
||||
y = Cx + Du
|
||||
\end{aligned}\label{mech2}
|
||||
\end{aligned}\label{eq:mech2}
|
||||
\end{equation}
|
||||
|
||||
\eqref{mech2} are the general input output equations in matrix form with x and A defines as \eqref{mech3}:
|
||||
\eqref{eq:mech2} are the general input output equations in matrix form with x and A defines as \eqref{eq:mech3}:
|
||||
|
||||
\begin{equation}
|
||||
x=
|
||||
@@ -330,12 +334,12 @@ B=\begin{bmatrix}
|
||||
%\1 \\ 1 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0\\
|
||||
%\end{bmatrix},\quad
|
||||
%D=0
|
||||
\label{mech2}
|
||||
\label{eq:mech3}
|
||||
\end{equation}
|
||||
|
||||
\subsection{Stage data}
|
||||
|
||||
This data comes from datasheets and construction information [biblio: 'Dynamics of Parker Stage', Wayne Glettig 5.12.2018].
|
||||
This data comes from datasheets and construction information \cite{DynParker}.
|
||||
|
||||
\begin{tabular}{|r|l|}
|
||||
\hline
|
||||
@@ -392,8 +396,10 @@ The goal is to build an optimal state space model of the plant with following in
|
||||
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:\\
|
||||
the transfer functions for each two motors are separated atomic transfer function as stated in table \ref{tab:trfFunc1}\\
|
||||
|
||||
\begin{table}[h!]
|
||||
\center
|
||||
\begin{tabular}{|l|l|l|l|}
|
||||
\hline
|
||||
key & description & motor1 (fy) & motor2 (fx) \\
|
||||
@@ -407,28 +413,17 @@ tf4 & mechanical resonance tf & & f=[41
|
||||
tf5 & mechanical resonance tf & & f=[230|233] d=[0.04|0.04] \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{plant partial transfer functions}
|
||||
\label{tab:trfFunc1}
|
||||
\end{table}
|
||||
%\vspace{1pc}
|
||||
|
||||
\vspace{1pc}
|
||||
The black line on figure \ref{fig:mot_open} shows the concatenate transfer function.
|
||||
The black line on figure \ref{fig:mot_open} shows the concatenate transfer function $tf1 \cdot tf2 \cdot tf3 \cdot tf4 \cdot tf5 \cdot tfc$ .
|
||||
\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$.}}
|
||||
\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$. The reason could be discretization and time delay because the servo loop is processed after the phase loop.}}
|
||||
\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.
|
||||
@@ -443,7 +438,7 @@ mot=cell(2,1);
|
||||
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]);
|
||||
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}
|
||||
@@ -476,153 +471,118 @@ Therefore for better regulation quality more sophisticated controllers as state
|
||||
|
||||
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
|
||||
opposite to the PID cpntroller which is a ‘black-box design’, the state space controller with observer is a ‘white box design’. (Figure \ref{fig:observer1})\\
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[scale=.75]{observer_statefeedback.png}
|
||||
\caption{observer controller}
|
||||
\caption{observer controller}\label{fig:observer1}
|
||||
\end{figure}
|
||||
|
||||
|
||||
To implement a state space controller with observer the model has to be observable and controllable. The full model of the tranfer function $tf1 \cdot tf2 \cdot tf3 \cdot tf4 \cdot tf5 \cdot tfc$ is not controllable due to the various resonance frequencies. Therefore for the observer design the state space model has to be simplified.
|
||||
|
||||
In addition to the transferfunction in table \ref{tab:trfFunc1} following simplified transfer functions have been added:\\
|
||||
|
||||
\begin{tabular}{|l|l|l|l|}
|
||||
\hline
|
||||
key & description & motor1 (fy) & motor2 (fx) \\
|
||||
\hline
|
||||
tfd & simplified loop tf $PT_1$ & f-3dB, 45\deg at 400Hz & same \\
|
||||
tf0 & \vtop{\hbox{\strut simplified mechanical tf} \hbox{\strut 2 integrators with -40dB/dec }}
|
||||
& 0dB at 19.8Hz & 0dB at 11.84Hz\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\vspace{1pc}
|
||||
|
||||
Figure \ref{fig:mdl_bode1} shows the bode plots of the best approch (plant) and its simplified models.
|
||||
|
||||
\begin{figure}[h!]
|
||||
\center
|
||||
\includegraphics[scale=.44]{../python/MXTuning/19_01_29/img/bode_model_plot1.eps}
|
||||
\includegraphics[scale=.44]{../python/MXTuning/19_01_29/img/bode_model_plot3.eps}
|
||||
\caption{bode plots of best and simplified models}
|
||||
\label{fig:mdl_bode1}
|
||||
\end{figure}
|
||||
|
||||
\verb|identifyFxFyStage.m| is the code that generates 'state space models' of different complexity out of the these transfer functions. All that information is stored in the 'motor objects'.\\
|
||||
|
||||
|
||||
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}\\
|
||||
\vspace{1pc}
|
||||
|
||||
The state space controller is calculated by pole placement.\\
|
||||
Following code calculates parameters for a observer controller, does a simulation and plots the results:
|
||||
\begin{verbatim}
|
||||
clear;clear global;close all;
|
||||
mot=cell(2,1);
|
||||
[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');
|
||||
[ssc]=StateSpaceControlDesign(mot1{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_observer_%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}
|
||||
|
||||
With an additional prefilter resonance and reductions can be suppressed a bit.\\
|
||||
|
||||
|
||||
|
||||
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
|
||||
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.\\
|
||||
|
||||
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
|
||||
In MATLAB the function \verb|StateSpaceControlDesign()| produces files \verb%/tmp/ssc[1|2].mat%.\\
|
||||
|
||||
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 servo loop code is generated with: \verb|MXTuning.py –mode 256|.\\
|
||||
This python code reads \verb%/tmp/ssc[1|2].mat% and substitutes part of
|
||||
\verb%usr_code/usrcode_template.[h|c]% to build the servo loop code \verb%usr_code/usrcode.[h|c]%.\\
|
||||
|
||||
Finally the real time servo code is compliled for the DeltaTau with:\\
|
||||
|
||||
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.
|
||||
\verb|/epics_ioc_modules/ESB_MX/python/usr_code$ make|\\
|
||||
|
||||
Following lines in gpasciiCommander will activate the user servo loop code:
|
||||
|
||||
Model of the stage instead of measuring transfer function
|
||||
|
||||
\textbf{Overview of code}\\
|
||||
\verb|TODO...|
|
||||
|
||||
\vspace{1pc}
|
||||
|
||||
\begin{appendix}
|
||||
\section{Appendix}
|
||||
|
||||
\textbf{Overview of code:}\\
|
||||
|
||||
\begin{tabular}{ll}
|
||||
\texttt{MXTuning.py} & tuning functions to gather/plot data and to generate c servo loop code\\
|
||||
|
||||
\texttt{helicalscan.py} & functions for helical scan motion (motion program, coordinate transformation, calibration)\\
|
||||
\texttt{shapepath.py} & functions for x,y-scan motion (trajectory planing, motion program)\\
|
||||
\texttt{ShapePathAnalyser.py} & interactive analyse tool of recorded x,y-scan motion\\
|
||||
\\
|
||||
\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}
|
||||
|
||||
|
||||
\begin{figure}[h!]
|
||||
\includegraphics[scale=.4]{helicalscan1a.eps}
|
||||
\includegraphics[scale=.4]{helicalscan2a.eps}
|
||||
\includegraphics[scale=.4]{helicalscan3a.eps}
|
||||
\caption{coordinate transformation}
|
||||
\end{figure}
|
||||
|
||||
|
||||
%proces compiled as job \texttt{\jobname} from the file \texttt{\currfileabspath}\\
|
||||
%\eject
|
||||
%
|
||||
%hyperref package sample
|
||||
%\url{http://stackoverflow.com/questions/9845292/converting-matlab-to-python}\\
|
||||
%
|
||||
%fancyvrb package sample
|
||||
%\begin{Verbatim}[frame=single]
|
||||
%Verbatim Verbatim Verbatim
|
||||
%Verbatim
|
||||
% Verbatim
|
||||
%\end{Verbatim}
|
||||
\newpage
|
||||
\bibliographystyle{alpha}
|
||||
\bibliography{myBib}
|
||||
%\printbibliography
|
||||
\end{appendix}
|
||||
|
||||
\include{Scratch}
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user