Difference between revisions of "Control package"
(→Linear System Representation: marked pid and pidstd as implemented) |
|||
(67 intermediate revisions by 9 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: | + | | pid || style="background: green;" | yes || pid.m |
|- | |- | ||
− | | pidstd || style="background: | + | | pidstd || style="background: green;" | yes || pidstd.m |
|- | |- | ||
− | | 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 434: | Line 440: | ||
|- | |- | ||
| gdare || style="background: red;" | no || || || || || | | gdare || style="background: red;" | no || || || || || | ||
+ | |- | ||
+ | | icare || style="background: red;" | no || || || || || | ||
+ | |- | ||
+ | | idare || style="background: red;" | no || || || || || | ||
|- | |- | ||
| ctrb || style="background: green;" | yes || ctrb.m || || || || | | ctrb || style="background: green;" | yes || ctrb.m || || || || | ||
Line 451: | Line 461: | ||
== 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 479: | ||
[[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 === | === Inverted Pendulum === | ||
+ | |||
+ | ==== Model ==== | ||
A nonlinear model of the inverted pendulum can be derived by | A nonlinear model of the inverted pendulum can be derived by | ||
Line 477: | Line 544: | ||
<math> | <math> | ||
\begin{cases} | \begin{cases} | ||
− | (M+m)\ddot{x}+c\dot{x}-ml\cos{\theta}\ddot{\theta}+ml\sin{\theta}\dot{\theta}^2=f(t)\\ | + | (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 | + | -ml\ddot{x}\cos{\theta}+(ml^2+I)\ddot{\theta}+b\dot{\theta}+mgl\sin{\theta}&=0 |
− | \end{cases} | + | \end{cases}\text{,} |
− | </math> | + | </math> |
where the variables are defined as | where the variables are defined as | ||
Line 507: | Line 574: | ||
|} | |} | ||
− | + | [[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> | <math> | ||
\begin{cases} | \begin{cases} | ||
− | (M+m) | + | (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} | \end{cases} | ||
</math> | </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]] |
Latest revision as of 17:50, 23 September 2022
The control package is part of the Octave Forge project.
Function list[edit]
Linear System Representation[edit]
Chapter | Function | Implemented | File |
---|---|---|---|
Basic Models | tf | yes | @tf/tf.m |
zpk | yes | zpk.m | |
ss | yes | @ss/ss.m | |
frd | yes | @frd/frd.m | |
pid | yes | pid.m | |
pidstd | yes | pidstd.m | |
pid2 | no | ||
dss | yes | @lti/dss.m | |
drss | no | ||
filt | yes | filt.m | |
rss | no | ||
Tunable Models | ltiblock.gain | no | |
ltiblock.pid | no | ||
ltiblock.pid2 | no | ||
ltiblock.ss | no | ||
ltiblock.tf | no | ||
realp | no | ||
AnalysisPoint | no | ||
genss | no | ||
genfrd | no | ||
genmat | no | ||
getLoopTransfer | no | ||
getIOTransfer | no | ||
getSensitivity | no | ||
getCompSensitivity | no | ||
getPoints | no | ||
replaceBlock | no | ||
getValue | no | ||
setValue | no | ||
getBlockValue | no | ||
setBlockValue | no | ||
showBlockValue | no | ||
showTunable | no | ||
nblocks | no | ||
getLFTModel | no | ||
Model with Time Delays | pade | no | |
absorbDelay | no | ||
thiran | yes | thiran.m | |
hasdelay | no | ||
hasInternalDelay | no | ||
totaldelay | no | ||
delayss | no | ||
setDelayModel | no | ||
getDelayModel | no | ||
Model Attributes | get | yes | @iddata/get.m |
set | yes | @iddata/set.m | |
tfdata | yes | @lti/tfdata.m | |
zpkdata | yes | @lti/zpkdata.m | |
ssdata | yes | @lti/ssdata.m | |
frdata | yes | @lti/frdata.m | |
piddata | no | ||
pidstddata | no | ||
piddata2 | no | ||
pidstddata2 | no | ||
dssdata | yes | @lti/dssdata.m | |
chgFreqUnit | no | ||
chgTimeUnit | no | ||
isct | yes | @lti/isct.m | |
isdt | yes | @lti/isdt.m | |
isempty | yes | built-in function | |
isfinite | yes | built-in function | |
isParametric | no | ||
isproper | no | ||
isreal | yes | built-in function | |
isiso | no | ||
isstable | yes | @lti/isstable.m | |
isstatic | no | ||
order | no | ||
ndims | yes | built-in function | |
size | yes | built-in function | |
Model Arrays | stack | no | |
nmodels | no | ||
permute | yes | built-in function | |
reshape | yes | built-in function | |
repsys | yes | repsys.m |
Model Interconnection[edit]
Function | Implemented | File |
---|---|---|
feedback | yes | @lti/feedback.m |
connect | yes | @lti/connect.m |
sumblk | yes | sumblk.m |
series | yes | @lti/series.m |
parallel | yes | @lti/parallel.m |
append | yes | append.m |
blkdiag | yes | @lti/blkdiag.m |
imp2exp | no | |
inv | yes | built-in function |
lft | no | |
connectOptions | no |
Model Transformation[edit]
Chapter | Function | Implemented | File | Number of Tests | Status | SLICOT functions | Priority (0-2) |
---|---|---|---|---|---|---|---|
Model Type Conversion | pidstd2 | no | |||||
make1DOF | no | ||||||
make2DOF | no | ||||||
getComponents | no | ||||||
Continuous-Discrete Conversion | c2d | yes | @lti/c2d.m | ||||
d2c | yes | @lti/d2c.m | |||||
d2d | yes | @lti/d2d.m | |||||
upsample | no | ||||||
c2dOptions | no | ||||||
d2cOptions | no | ||||||
d2dOptions | no | ||||||
Model Simplification | hsvd | yes | hsvd.m | ||||
hsvplot | no | ||||||
sminreal | yes | @lti/sminreal.m | |||||
balred | no | ||||||
minreal | yes | @lti/minreal.m | |||||
balreal | no | ||||||
modred | no | ||||||
balredOptions | no | ||||||
hsvdOptions | no | ||||||
State-Coordinate Transformation | canon | no | |||||
prescale | yes | @lti/prescale.m | |||||
ss2ss | no | ||||||
xperm | yes | @lti/xperm.m | |||||
Modal Decomposition | modsep | no | |||||
stabsep | no | ||||||
freqsep | no | ||||||
stabsepOptions | no | ||||||
freqsepOptions | no |
Linear Analysis[edit]
Chapter | Function | Implemented | File | Number of Tests | Status | SLICOT functions | Priority (0-2) |
---|---|---|---|---|---|---|---|
Time-Domain Analysis | linearSystemAnalyzer | no | |||||
impulseplot | no | ||||||
initialplot | no | ||||||
lsimplot | no | ||||||
stepplot | no | ||||||
covar | yes | covar.m | |||||
impulse | yes | impulse.m | |||||
initial | yes | initial.m | |||||
lsim | yes | lsim.m | |||||
step | yes | step.m | |||||
lsiminfo | no | ||||||
stepinfo | no | ||||||
stepDataOptions | no | ||||||
Frequency-Domain Analysis | bodeplot | no | |||||
nicholsplot | no | ||||||
nyquistplot | no | ||||||
sigmaplot | no | ||||||
bode | yes | bode.m | |||||
nichols | yes | nichols.m | |||||
nyquist | yes | nyquist.m | |||||
sigma | yes | sigma.m | |||||
evalfr | no | ||||||
freqresp | yes | @lti/freqresp.m | |||||
bandwidth | yes | built-in function | |||||
dcgain | yes | @lti/dcgain.m | |||||
getGainCrossover | no | ||||||
getPeakGain | no | ||||||
Stability Analysis | pole | yes | @lti/pole.m | ||||
zero | yes | @lti/zero.m | |||||
damp | yes | damp.m | |||||
dsort | yes | dsort.m | |||||
esort | yes | esort.m | |||||
tzero | no | ||||||
pzmap | yes | pzmap.m | |||||
pzplot | no | ||||||
iopzplot | no | ||||||
allmargin | no | ||||||
margin | yes | margin.m | |||||
Plot Customization | bodeoptions | no | |||||
hsvoptions | no | ||||||
nicholsoptions | no | ||||||
nyquistoptions | no | ||||||
pzoptions | no | ||||||
sigmaoptions | no | ||||||
timeoptions | no | ||||||
setoptions | no | ||||||
getoptions | no | ||||||
ctrlpref | no | ||||||
updateSystem | no |
Control Design[edit]
Chapter | Function | Implemented | File | Number of Tests | Status | SLICOT functions | Priority (0-2) |
---|---|---|---|---|---|---|---|
PID Controller Tuning | pidTuner | no | |||||
pidtune | no | ||||||
pidtuneOptions | no | ||||||
SISO Feedback Loops | rlocus | yes | rlocus.m | ||||
sgrid | no | ||||||
rlocusplot | no | ||||||
controlSystemDesigner | no | ||||||
sisoinit | no | ||||||
Linear-Quadratic-Gaussian Control | lqr | yes | lqr.m | ||||
lqry | no | ||||||
lqi | no | ||||||
dlqr | yes | dlqr.m | |||||
lqrd | no | ||||||
kalman | yes | kalman.m | |||||
kalmd | no | ||||||
lqg | no | ||||||
lqgreg | no | ||||||
lqgtrack | no | ||||||
augstate | no | ||||||
norm | yes | @lti/norm.m | |||||
Pole Placement | estim | yes | estim.m | ||||
place | yes | place.m | |||||
acker | yes | acker.m | |||||
reg | no |
Matrix Computations[edit]
Function | Implemented | File | Number of Tests | Status | SLICOT functions | Priority (0-2) |
---|---|---|---|---|---|---|
lyap | yes | lyap.m | ||||
lyapchol | yes | lyapchol.m | ||||
dlyap | yes | dlyap.m | ||||
dlyapchol | yes | dlyapchol.m | ||||
care | yes | care.m | ||||
dare | yes | dare.m | ||||
gcare | no | |||||
gdare | no | |||||
icare | no | |||||
idare | no | |||||
ctrb | yes | ctrb.m | ||||
obsv | yes | obsv.m | ||||
ctrbf | yes | ctrbf.m | ||||
obsvf | yes | obsvf.m | ||||
gram | yes | gram.m | ||||
bdschur | no |
Examples[edit]
PT1 / Low-pass filter step response[edit]
Code: Creating a transfer function and plotting its response |
T1 = 0.4; # time constant
P = tf([1], [T1 1]); # create transfer function model
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
hold on
plot ([0 T1], [0 1], "g")
plot ([T1 T1], [0 1], "k")
plot ([0 T1], [1-1/e 1-1/e], "m")
hold off
|
Bode Diagram with TikZ/PGFplots[edit]
We use the same system as before but we draw now with bode(P)
a bode diagram.
The output is written to a .csv file.
Code: Creating a transfer function and calculating its bode diagram |
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]);
|
We can then invoke LaTeX with the following .tex file
Code: Creating a bode diagram with pgfplots |
\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}
|
to generate a beautiful bode diagram
It can be seen that a first order low-pass filter has magnitude at .
Inverted Pendulum[edit]
Model[edit]
A nonlinear model of the inverted pendulum can be derived by
where the variables are defined as
Name | Definition |
---|---|
Mass of the cart | |
Mass of the pendulum | |
Translational damping coefficient | |
Length of the pendulum | |
Inertia of the pendulum | |
Rotational damping coefficient |
Linearization around the point and substitution of (from here on in the analysis, will be written as , but it should be noted that now measures from a new reference) leads to
This can be expressed in the frequency domain like
Transfer functions[edit]
By dividing the state variables by the input one obtains the transfer functions
with
This can be expressed in Octave
Code: Creating the transfer functions for the inverted pendulum |
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]);
|
and by invoking the bode
command
Code: Creating Bode plots for the inverted pendulum |
bode(G1);
bode(G2);
|
one obtains the bode diagrams of the two transfer functions.