2
edits
m (→Control Design) |
|||
(77 intermediate revisions by 8 users not shown) | |||
Line 7: | Line 7: | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Chapter !! Function !! Implemented !! File | ! Chapter !! Function !! Implemented !! File | ||
|- | |- | ||
| rowspan="11" | Basic Models || tf || style="background: green;" | yes || @tf/tf.m | | rowspan="11" | Basic Models || tf || style="background: green;" | yes || @tf/tf.m | ||
|- | |- | ||
| zpk || style="background: green;" | yes || zpk.m | | zpk || style="background: green;" | yes || zpk.m | ||
|- | |- | ||
| ss || style="background: green;" | yes || @ss/ss.m | | ss || style="background: green;" | yes || @ss/ss.m | ||
|- | |- | ||
| frd || style="background: green;" | yes || @frd/frd.m | | frd || style="background: green;" | yes || @frd/frd.m | ||
|- | |- | ||
| pid || style="background: red;" | no | | pid || style="background: red;" | no || | ||
|- | |- | ||
| pidstd || style="background: red;" | no | | pidstd || style="background: red;" | no || | ||
|- | |- | ||
| pid2 || style="background: red;" | no | | pid2 || style="background: red;" | no || | ||
|- | |- | ||
| dss || style="background: green;" | yes || @lti/dss.m | | dss || style="background: green;" | yes || @lti/dss.m | ||
|- | |- | ||
| drss || style="background: red;" | no | | drss || style="background: red;" | no || | ||
|- | |- | ||
| filt || style="background: green;" | yes || filt.m | | filt || style="background: green;" | yes || filt.m | ||
|- | |- | ||
| rss || style="background: red;" | no | | rss || style="background: red;" | no || | ||
|- | |- | ||
| rowspan="24" | Tunable Models || ltiblock.gain || style="background: red;" | no | | rowspan="24" | Tunable Models || ltiblock.gain || style="background: red;" | no || | ||
|- | |- | ||
| ltiblock.pid || style="background: red;" | no | | ltiblock.pid || style="background: red;" | no || | ||
|- | |- | ||
| ltiblock.pid2 || style="background: red;" | no | | ltiblock.pid2 || style="background: red;" | no || | ||
|- | |- | ||
| ltiblock.ss || style="background: red;" | no | | ltiblock.ss || style="background: red;" | no || | ||
|- | |- | ||
| ltiblock.tf || style="background: red;" | no | | ltiblock.tf || style="background: red;" | no || | ||
|- | |- | ||
| realp || style="background: red;" | no | | realp || style="background: red;" | no || | ||
|- | |- | ||
| AnalysisPoint || style="background: red;" | no | | AnalysisPoint || style="background: red;" | no || | ||
|- | |- | ||
| genss || style="background: red;" | no | | genss || style="background: red;" | no || | ||
|- | |- | ||
| genfrd || style="background: red;" | no | | genfrd || style="background: red;" | no || | ||
|- | |- | ||
| genmat || style="background: red;" | no | | genmat || style="background: red;" | no || | ||
|- | |- | ||
| getLoopTransfer || style="background: red;" | no | | getLoopTransfer || style="background: red;" | no || | ||
|- | |- | ||
| getIOTransfer || style="background: red;" | no | | getIOTransfer || style="background: red;" | no || | ||
|- | |- | ||
| getSensitivity || style="background: red;" | no | | getSensitivity || style="background: red;" | no || | ||
|- | |- | ||
| getCompSensitivity || style="background: red;" | no | | getCompSensitivity || style="background: red;" | no || | ||
|- | |- | ||
| getPoints || style="background: red;" | no | | getPoints || style="background: red;" | no || | ||
|- | |- | ||
| replaceBlock || style="background: red;" | no | | replaceBlock || style="background: red;" | no || | ||
|- | |- | ||
| getValue || style="background: red;" | no | | getValue || style="background: red;" | no || | ||
|- | |- | ||
| setValue || style="background: red;" | no | | setValue || style="background: red;" | no || | ||
|- | |- | ||
| getBlockValue || style="background: red;" | no | | getBlockValue || style="background: red;" | no || | ||
|- | |- | ||
| setBlockValue || style="background: red;" | no | | setBlockValue || style="background: red;" | no || | ||
|- | |- | ||
| showBlockValue || style="background: red;" | no | | showBlockValue || style="background: red;" | no || | ||
|- | |- | ||
| showTunable || style="background: red;" | no | | showTunable || style="background: red;" | no || | ||
|- | |- | ||
| nblocks || style="background: red;" | no | | nblocks || style="background: red;" | no || | ||
|- | |- | ||
| getLFTModel || style="background: red;" | no | | getLFTModel || style="background: red;" | no || | ||
|- | |- | ||
| rowspan="9" | Model with Time Delays || pade || style="background: red;" | no | | rowspan="9" | Model with Time Delays || pade || style="background: red;" | no || | ||
|- | |- | ||
| absorbDelay || style="background: red;" | no | | absorbDelay || style="background: red;" | no || | ||
|- | |- | ||
| thiran || style="background: green;" | yes || thiran.m | | thiran || style="background: green;" | yes || thiran.m | ||
|- | |- | ||
| hasdelay || style="background: red;" | no | | hasdelay || style="background: red;" | no || | ||
|- | |- | ||
| hasInternalDelay || style="background: red;" | no | | hasInternalDelay || style="background: red;" | no || | ||
|- | |- | ||
| totaldelay || style="background: red;" | no | | totaldelay || style="background: red;" | no || | ||
|- | |- | ||
| delayss || style="background: red;" | no | | delayss || style="background: red;" | no || | ||
|- | |- | ||
| setDelayModel || style="background: red;" | no | | setDelayModel || style="background: red;" | no || | ||
|- | |- | ||
| getDelayModel || style="background: red;" | no | | getDelayModel || style="background: red;" | no || | ||
|- | |- | ||
| rowspan="26" | Model Attributes || get || style="background: green;" | yes || @iddata/get.m | | rowspan="26" | Model Attributes || get || style="background: green;" | yes || @iddata/get.m | ||
|- | |- | ||
| set || style="background: green;" | yes || @iddata/set.m | | set || style="background: green;" | yes || @iddata/set.m | ||
|- | |- | ||
| tfdata || style="background: green;" | yes || @lti/tfdata.m | | tfdata || style="background: green;" | yes || @lti/tfdata.m | ||
|- | |- | ||
| zpkdata || style="background: green;" | yes || @lti/zpkdata.m | | zpkdata || style="background: green;" | yes || @lti/zpkdata.m | ||
|- | |- | ||
| ssdata || style="background: green;" | yes || @lti/ssdata.m | | ssdata || style="background: green;" | yes || @lti/ssdata.m | ||
|- | |- | ||
| frdata || style="background: green;" | yes || @lti/frdata.m | | frdata || style="background: green;" | yes || @lti/frdata.m | ||
|- | |- | ||
| piddata || style="background: red;" | no | | piddata || style="background: red;" | no || | ||
|- | |- | ||
| pidstddata || style="background: red;" | no | | pidstddata || style="background: red;" | no || | ||
|- | |- | ||
| piddata2 || style="background: red;" | no | | piddata2 || style="background: red;" | no || | ||
|- | |- | ||
| pidstddata2 || style="background: red;" | no | | pidstddata2 || style="background: red;" | no || | ||
|- | |- | ||
| dssdata || style="background: green;" | yes || @lti/dssdata.m | | dssdata || style="background: green;" | yes || @lti/dssdata.m | ||
|- | |- | ||
| chgFreqUnit || style="background: red;" | no | | chgFreqUnit || style="background: red;" | no || | ||
|- | |- | ||
| chgTimeUnit || style="background: red;" | no | | chgTimeUnit || style="background: red;" | no || | ||
|- | |- | ||
| isct || style="background: green;" | yes || @lti/isct.m | | isct || style="background: green;" | yes || @lti/isct.m | ||
|- | |- | ||
| isdt || style="background: green;" | yes || @lti/isdt.m | | isdt || style="background: green;" | yes || @lti/isdt.m | ||
|- | |- | ||
| isempty || style="background: green;" | yes || built-in function | | isempty || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| isfinite || style="background: green;" | yes || built-in function | | isfinite || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| isParametric || style="background: red;" | no | | isParametric || style="background: red;" | no || | ||
|- | |- | ||
| isproper || style="background: red;" | no | | isproper || style="background: red;" | no || | ||
|- | |- | ||
| isreal || style="background: green;" | yes || built-in function | | isreal || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| isiso || style="background: red;" | no | | isiso || style="background: red;" | no || | ||
|- | |- | ||
| isstable || style="background: green;" | yes || @lti/isstable.m | | isstable || style="background: green;" | yes || @lti/isstable.m | ||
|- | |- | ||
| isstatic || style="background: red;" | no | | isstatic || style="background: red;" | no || | ||
|- | |- | ||
| order || style="background: red;" | no | | order || style="background: red;" | no || | ||
|- | |- | ||
| ndims || style="background: green;" | yes || built-in function | | ndims || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| size || style="background: green;" | yes || built-in function | | size || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| rowspan="5" | Model Arrays || stack || style="background: red;" | no | | rowspan="5" | Model Arrays || stack || style="background: red;" | no || | ||
|- | |- | ||
| nmodels || style="background: red;" | no | | nmodels || style="background: red;" | no || | ||
|- | |- | ||
| permute || style="background: green;" | yes || built-in function | | permute || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| reshape || style="background: green;" | yes || built-in function | | reshape || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| repsys || style="background: green;" | yes || repsys.m | | repsys || style="background: green;" | yes || repsys.m | ||
|- | |- | ||
|} | |} | ||
Line 165: | Line 165: | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Function !! Implemented !! File | ! Function !! Implemented !! File | ||
|- | |- | ||
| feedback || style="background: green;" | yes || @lti/feedback.m | | feedback || style="background: green;" | yes || @lti/feedback.m | ||
|- | |- | ||
| connect || style="background: green;" | yes || @lti/connect.m | | connect || style="background: green;" | yes || @lti/connect.m | ||
|- | |- | ||
| sumblk || style="background: green;" | yes || sumblk.m | | sumblk || style="background: green;" | yes || sumblk.m | ||
|- | |- | ||
| series || style="background: | | series || style="background: green;" | yes || @lti/series.m | ||
|- | |- | ||
| parallel || style="background: | | parallel || style="background: green;" | yes || @lti/parallel.m | ||
|- | |- | ||
| append || style="background: green;" | yes || append.m | | append || style="background: green;" | yes || append.m | ||
|- | |- | ||
| blkdiag || style="background: green;" | yes || @lti/blkdiag.m | | blkdiag || style="background: green;" | yes || @lti/blkdiag.m | ||
|- | |- | ||
| imp2exp || style="background: red;" | no | | imp2exp || style="background: red;" | no || | ||
|- | |- | ||
| inv || style="background: green;" | yes || built-in function | | inv || style="background: green;" | yes || built-in function | ||
|- | |- | ||
| lft || style="background: red;" | no | | lft || style="background: red;" | no || | ||
|- | |- | ||
| connectOptions || style="background: red;" | no | | connectOptions || style="background: red;" | no || | ||
|- | |- | ||
|} | |} | ||
Line 317: | Line 317: | ||
| getPeakGain || style="background: red;" | no || || || || || | | getPeakGain || style="background: red;" | no || || || || || | ||
|- | |- | ||
| rowspan=" | | rowspan="11" | Stability Analysis || pole || style="background: green;" | yes || @lti/pole.m || || || || | ||
|- | |- | ||
| zero || style="background: green;" | yes || @lti/zero.m || || || || | | zero || style="background: green;" | yes || @lti/zero.m || || || || | ||
|- | |- | ||
| damp || style="background: | | damp || style="background: green;" | yes || damp.m || || || || | ||
|- | |- | ||
| dsort || style="background: | | dsort || style="background: green;" | yes || dsort.m || || || || | ||
|- | |- | ||
| esort || style="background: | | esort || style="background: green;" | yes || esort.m || || || || | ||
|- | |- | ||
| tzero || style="background: red;" | no || || || || || | | tzero || style="background: red;" | no || || || || || | ||
|- | |||
| pzmap || style="background: green;" | yes || pzmap.m || || || || | |||
|- | |- | ||
| pzplot || style="background: red;" | no || || || || || | | pzplot || style="background: red;" | no || || || || || | ||
Line 373: | Line 375: | ||
| pidtuneOptions || style="background: red;" | no || || || || || | | pidtuneOptions || style="background: red;" | no || || || || || | ||
|- | |- | ||
| rowspan=" | | rowspan="5" | SISO Feedback Loops || rlocus || style="background: green;" | yes || rlocus.m || || || || | ||
|- | |||
| sgrid || style="background: red;" | no || || || || || | |||
|- | |- | ||
| rlocusplot || style="background: red;" | no || || || || || | | rlocusplot || style="background: red;" | no || || || || || | ||
Line 405: | Line 409: | ||
| norm || style="background: green;" | yes || @lti/norm.m || || || || | | norm || style="background: green;" | yes || @lti/norm.m || || || || | ||
|- | |- | ||
| rowspan=" | | rowspan="4" | Pole Placement || estim || style="background: green;" | yes || estim.m || || || || | ||
|- | |- | ||
| place || style="background: green;" | yes || place.m || || || || | | place || style="background: green;" | yes || place.m || || || || | ||
|- | |- | ||
| reg || style="background: red;" | no || || | | acker || style="background: green;" | yes || acker.m || || || || | ||
|- | |||
| reg || style="background: red;" | no || || || || | |||
|- | |- | ||
|} | |} | ||
Line 451: | Line 457: | ||
== Examples == | == Examples == | ||
=== PT1/ | === PT1 / Low-pass filter step response === | ||
<!-- {{SyntaxHighlight| --> | <!-- {{SyntaxHighlight| --> | ||
{{Code|Creating a transfer function and plotting its response|<syntaxhighlight lang="octave" style="font-size: | {{Code|Creating a transfer function and plotting its response|<syntaxhighlight lang="octave" style="font-size:14px"> | ||
T1=0.4; | T1 = 0.4; # time constant | ||
P=tf([1], [T1 1]) | P = tf([1], [T1 1]); # create transfer function model | ||
step(P,2) # plot step response | step(P, 2) # plot step response | ||
#add some common markers like the tangent line at the origin, which crosses lim(n->inf) f(t) at t=T1 | #add some common markers like the tangent line at the origin, which crosses lim(n->inf) f(t) at t=T1 | ||
hold on | hold on | ||
plot ([0 T1], | plot ([0 T1], [0 1], "g") | ||
plot ([T1 T1], | plot ([T1 T1], [0 1], "k") | ||
plot ([0 T1], | plot ([0 T1], [1-1/e 1-1/e], "m") | ||
hold off | hold off | ||
</syntaxhighlight>}} | </syntaxhighlight>}} | ||
Line 468: | Line 475: | ||
[[File:Pt1.png|600px]] | [[File:Pt1.png|600px]] | ||
==== Bode Diagram with TikZ/PGFplots ==== | |||
(a first order low-pass filter has - | |||
We use the same system as before but we draw now with <code style="font-size:14px; border:solid lightgray 1px; padding: 2px">bode(P)</code> a bode diagram. | |||
The output is written to a .csv file. | |||
<!-- {{SyntaxHighlight| --> | |||
{{Code|Creating a transfer function and calculating its bode diagram|<syntaxhighlight lang="octave" style="font-size:14px"> | |||
T1 = 0.4; # time constant | |||
P = tf([1], [T1 1]); | |||
[mag, pha, w] = bode(P); | |||
csvwrite("dat/bode_p.csv", [w', 20*log10(mag), pha]); | |||
</syntaxhighlight>}} | |||
We can then invoke LaTeX with the following .tex file | |||
<!-- {{SyntaxHighlight| --> | |||
{{Code|Creating a bode diagram with pgfplots|<syntaxhighlight lang="latex" style="font-size:14px"> | |||
\documentclass[tikz]{standalone} | |||
\usepackage{pgfplotstable} | |||
\usepackage{siunitx} | |||
\usetikzlibrary{pgfplots.groupplots} | |||
\begin{document} | |||
\pgfplotstableread[col sep=comma]{\detokenize{/path/to/csv/file/dat/bode_p.csv}}\datatable | |||
\begin{tikzpicture} | |||
\begin{groupplot}[ | |||
group style={rows=2}, | |||
width=0.8\textwidth, | |||
height=0.4\textwidth, | |||
xmajorgrids, | |||
ymajorgrids, | |||
enlarge x limits=false, | |||
xmode=log, | |||
] | |||
\nextgroupplot[ | |||
title={Bode Diagram of $P$}, | |||
ylabel={Magnitude / \si{\decibel}}, | |||
] | |||
\addplot[blue,line width=1pt] table[x index=0,y index=1]{\datatable}; | |||
\nextgroupplot[ | |||
xlabel={Frequency / \si{\radian\per\second}}, | |||
ylabel={Phase / \si{\degree}}, | |||
] | |||
\addplot[red,line width=1pt] table[x index=0,y index=2]{\datatable}; | |||
\end{groupplot} | |||
\end{tikzpicture} | |||
\end{document} | |||
</syntaxhighlight>}} | |||
to generate a beautiful bode diagram | |||
[[File:bode_p.png]] | |||
It can be seen that a first order low-pass filter has <math display="inline">-3\,dB</math> magnitude at <math display="inline">f=1/T_1=2.5\,rad/s</math>. | |||
=== Inverted Pendulum === | |||
==== Model ==== | |||
A nonlinear model of the inverted pendulum can be derived by | |||
<math> | |||
\begin{cases} | |||
(M+m)\ddot{x}+c\dot{x}-ml\cos{\theta}\ddot{\theta}+ml\sin{\theta}\dot{\theta}^2&=f(t)\\ | |||
-ml\ddot{x}\cos{\theta}+(ml^2+I)\ddot{\theta}+b\dot{\theta}+mgl\sin{\theta}&=0 | |||
\end{cases}\text{,} | |||
</math> | |||
where the variables are defined as | |||
{| | |||
! align="left" | Name | |||
! align="left" | Definition | |||
|- | |||
|<math display="inline">M</math> | |||
|Mass of the cart | |||
|- | |||
|<math display="inline">m</math> | |||
|Mass of the pendulum | |||
|- | |||
|<math display="inline">c</math> | |||
|Translational damping coefficient | |||
|- | |||
|<math display="inline">l</math> | |||
|Length of the pendulum | |||
|- | |||
|<math display="inline">I</math> | |||
|Inertia of the pendulum | |||
|- | |||
|<math display="inline">b</math> | |||
|Rotational damping coefficient | |||
|} | |||
[[File:inverted_pendulum_new.png|frame|Schematic drawing of the inverted pendulum.]] | |||
Linearization around the point <math display="inline">\theta=\pi</math> and substitution of <math display="inline">\theta'=\theta-\pi</math> (from here on in the analysis, <math display="inline">\theta'</math> will be written as <math display="inline">\theta</math>, but it should be noted that <math display="inline">\theta</math> now | |||
measures from a new reference) leads to | |||
<math> | |||
\begin{cases} | |||
(M+m)\ddot{x}+c\dot{x}+ml\ddot{\theta}&=f(t)\\ | |||
ml\dot{x}+(ml^2+I)\ddot{\theta}+b\dot{\theta}-mgl\theta&=0 | |||
\end{cases}\text{.} | |||
</math> | |||
This can be expressed in the frequency domain like | |||
<math> | |||
\begin{cases} | |||
(M+m)s^2X(s)+csX(s)+mls^2\Theta(s)&=F(s)\\ | |||
mlsX(s)+(ml^2+I)s^2\Theta(s)+bs\Theta(s)-mgl\Theta(s)&=0 | |||
\end{cases} | |||
</math> | |||
==== Transfer functions ==== | |||
By dividing the state variables by the input one obtains the transfer functions | |||
<math> | |||
\begin{align} | |||
G_1(s)&=\frac{X(s)}{F(s)}=\frac{\alpha_2s^2+\alpha_1s+\alpha_0}{\beta_4s^4+\beta_3s^3+\beta_2s^2+\beta_1s}\\ | |||
G_2(s)&=\frac{\Theta(s)}{F(s)}=\frac{\gamma_1s}{\beta_4s^3+\beta_3s^2+\beta_2s+\beta_1} | |||
\end{align} | |||
</math> | |||
with | |||
{| | |||
|<math display="inline">\alpha_2=ml^2+I</math> | |||
|- | |||
|<math display="inline">\alpha_1=b</math> | |||
|- | |||
|<math display="inline">\alpha_0=-mgl</math> | |||
|- | |||
|<math display="inline">\beta_4=(M+m)(ml^2+I)-m^2l^2</math> | |||
|- | |||
|<math display="inline">\beta_3=(M+m)b+(ml^2+I)c</math> | |||
|- | |||
|<math display="inline">\beta_2=-(M+m)mgl+bc</math> | |||
|- | |||
|<math display="inline">\beta_1=-mglc</math> | |||
|- | |||
|<math display="inline">\gamma_1=-ml</math> | |||
|} | |||
This can be expressed in Octave | |||
<!-- {{SyntaxHighlight| --> | |||
{{Code|Creating the transfer functions for the inverted pendulum|<syntaxhighlight lang="octave" style="font-size:14px"> | |||
m = 0.15; | |||
l = 0.314; | |||
M = 1.3; | |||
I = 0; | |||
g = 9.80665; | |||
b = 20; | |||
c = 20; | |||
G1 = tf([m*l^2+I b -m*g*l], | |||
[(M+m)*(m*l^2+I)-m^2*l^2 (M+m)*b+(m*l^2+I)*c -(M+m)*m*g*l+b*c -m*g*l*c 0]); | |||
G2 = tf([-m*l], | |||
[(M+m)*(m*l^2+I)-m^2*l^2 (M+m)*b+(m*l^2+I)*c -(M+m)*m*g*l+b*c -m*g*l*c]); | |||
</syntaxhighlight>}} | |||
and by invoking the <code style="font-size:14px; border:solid lightgray 1px; padding: 2px">bode</code> command | |||
<!-- {{SyntaxHighlight| --> | |||
{{Code|Creating Bode plots for the inverted pendulum|<syntaxhighlight lang="octave" style="font-size:14px"> | |||
bode(G1); | |||
bode(G2); | |||
</syntaxhighlight>}} | |||
one obtains the bode diagrams of the two transfer functions. | |||
<div><ul> | |||
<li style="display: inline-block;"> [[File:bode_g1.png|frame|Bode diagram of the cart movement transfer function.]] </li> | |||
<li style="display: inline-block;"> [[File:bode_g2.png|frame|Bode diagram of the pendulums rotation transfer function.]] </li> | |||
</ul></div> | |||
[[Category:Octave | [[Category:Octave Forge]] |
edits