Skip to content

Commit 9990093

Browse files
author
Documenter.jl
committed
build based on 60a9a18
1 parent 7a99c9d commit 9990093

30 files changed

+1248
-1240
lines changed

dev/.documenter-siteinfo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2024-05-01T15:27:16","documenter_version":"1.4.0"}}
1+
{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2024-05-01T21:20:51","documenter_version":"1.4.0"}}

dev/func_index/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dev/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dev/internals/predictive_control/index.html

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

dev/internals/sim_model/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dev/internals/state_estim/index.html

Lines changed: 18 additions & 18 deletions
Large diffs are not rendered by default.

dev/manual/installation/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dev/manual/linmpc/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,4 @@
129129
u, y, d = model.uop, model(), mpc_d.estim.model.dop
130130
initstate!(mpc_d, u, y, d)
131131
u_data, y_data, ry_data = test_mpc_d(mpc_d, model)
132-
plot_data(t_data, u_data, y_data, ry_data)</code></pre><p><img src="../plot4_LinMPC.svg" alt="plot4_LinMPC"/></p><p>Note that measured disturbances are assumed constant in the future by default but custom <span>$\mathbf{D̂}$</span> predictions are possible. The same applies for the setpoint predictions <span>$\mathbf{R̂_y}$</span>.</p><section class="footnotes is-size-7"><ul><li class="footnote" id="footnote-1"><a class="tag is-link" href="#citeref-1">1</a>As an alternative to state observer, we could have use an <a href="../../public/state_estim/#InternalModel"><code>InternalModel</code></a> structure with <code>mpc = LinMPC(InternalModel(model), Hp=15, Hc=2, Mwt=[1, 1], Nwt=[0.1, 0.1])</code>. It was tested on the example of this page and it gave similar results.</li></ul></section></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../installation/">« Installation</a><a class="docs-footer-nextpage" href="../nonlinmpc/">Nonlinear Design »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 1 May 2024 15:27">Wednesday 1 May 2024</span>. Using Julia version 1.9.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
132+
plot_data(t_data, u_data, y_data, ry_data)</code></pre><p><img src="../plot4_LinMPC.svg" alt="plot4_LinMPC"/></p><p>Note that measured disturbances are assumed constant in the future by default but custom <span>$\mathbf{D̂}$</span> predictions are possible. The same applies for the setpoint predictions <span>$\mathbf{R̂_y}$</span>.</p><section class="footnotes is-size-7"><ul><li class="footnote" id="footnote-1"><a class="tag is-link" href="#citeref-1">1</a>As an alternative to state observer, we could have use an <a href="../../public/state_estim/#InternalModel"><code>InternalModel</code></a> structure with <code>mpc = LinMPC(InternalModel(model), Hp=15, Hc=2, Mwt=[1, 1], Nwt=[0.1, 0.1])</code>. It was tested on the example of this page and it gave similar results.</li></ul></section></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../installation/">« Installation</a><a class="docs-footer-nextpage" href="../nonlinmpc/">Nonlinear Design »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 1 May 2024 21:20">Wednesday 1 May 2024</span>. Using Julia version 1.9.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>

dev/manual/nonlinmpc/index.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,25 @@
1919
const par = (9.8, 0.4, 1.2, 0.3)
2020
f(x, u, _ ) = pendulum(par, x, u)
2121
h(x, _ ) = [180/π*x[1]] # [°]
22-
Ts, nu, nx, ny = 0.1, 1, 2, 1
23-
model = NonLinModel(f, h, Ts, nu, nx, ny)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">NonLinModel with a sample time Ts = 0.1 s, RungeKutta solver and:
22+
nu, nx, ny, Ts = 1, 2, 1, 0.1
23+
vu, vx, vy = [&quot;\$τ\$ (N m)&quot;], [&quot;\$θ\$ (rad)&quot;, &quot;\$ω\$ (rad/s)&quot;], [&quot;\$θ\$ (°)&quot;]
24+
model = setname!(NonLinModel(f, h, Ts, nu, nx, ny); u=vu, x=vx, y=vy)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">NonLinModel with a sample time Ts = 0.1 s, RungeKutta solver and:
2425
1 manipulated inputs u
2526
2 states x
2627
1 outputs y
2728
0 measured disturbances d</code></pre><p>The output function <span>$\mathbf{h}$</span> converts the <span>$θ$</span> angle to degrees. Note that special characters like <span>$θ$</span> can be typed in the Julia REPL or VS Code by typing <code>\theta</code> and pressing the <code>&lt;TAB&gt;</code> key. The tuple <code>par</code> is constant here to improve the <a href="https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-untyped-global-variables">performance</a>. Note that a 4th order <a href="../../public/sim_model/#RungeKutta"><code>RungeKutta</code></a> differential equation solver is used by default. It is good practice to first simulate <code>model</code> using <a href="../../public/generic_func/#ModelPredictiveControl.sim!"><code>sim!</code></a> as a quick sanity check:</p><pre><code class="language-julia hljs">using Plots
2829
u = [0.5]
2930
N = 35
3031
res = sim!(model, N, u)
31-
plot(res, plotu=false)</code></pre><p><img src="../plot1_NonLinMPC.svg" alt="plot1_NonLinMPC"/></p><h2 id="Nonlinear-Model-Predictive-Controller"><a class="docs-heading-anchor" href="#Nonlinear-Model-Predictive-Controller">Nonlinear Model Predictive Controller</a><a id="Nonlinear-Model-Predictive-Controller-1"></a><a class="docs-heading-anchor-permalink" href="#Nonlinear-Model-Predictive-Controller" title="Permalink"></a></h2><p>An <a href="../../public/state_estim/#UnscentedKalmanFilter"><code>UnscentedKalmanFilter</code></a> estimates the plant state :</p><pre><code class="language-julia hljs">α=0.01; σQ=[0.1, 0.5]; σR=[0.5]; nint_u=[1]; σQint_u=[0.1]
32+
plot(res, plotu=false)</code></pre><p>The <a href="../../public/sim_model/#ModelPredictiveControl.setname!"><code>setname!</code></a> function allows customizing the Y-axis labels.</p><p><img src="../plot1_NonLinMPC.svg" alt="plot1_NonLinMPC"/></p><h2 id="Nonlinear-Model-Predictive-Controller"><a class="docs-heading-anchor" href="#Nonlinear-Model-Predictive-Controller">Nonlinear Model Predictive Controller</a><a id="Nonlinear-Model-Predictive-Controller-1"></a><a class="docs-heading-anchor-permalink" href="#Nonlinear-Model-Predictive-Controller" title="Permalink"></a></h2><p>An <a href="../../public/state_estim/#UnscentedKalmanFilter"><code>UnscentedKalmanFilter</code></a> estimates the plant state :</p><pre><code class="language-julia hljs">α=0.01; σQ=[0.1, 0.5]; σR=[0.5]; nint_u=[1]; σQint_u=[0.1]
3233
estim = UnscentedKalmanFilter(model; α, σQ, σR, nint_u, σQint_u)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">UnscentedKalmanFilter estimator with a sample time Ts = 0.1 s, NonLinModel and:
3334
1 manipulated inputs u (1 integrating states)
3435
3 estimated states x̂
3536
1 measured outputs ym (0 integrating states)
3637
0 unmeasured outputs yu
3738
0 measured disturbances d</code></pre><p>The vectors <code>σQ</code> and σR <code>σR</code> are the standard deviations of the process and sensor noises, respectively. The value for the velocity <span>$ω$</span> is higher here (<code>σQ</code> second value) since <span>$\dot{ω}(t)$</span> equation includes an uncertain parameter: the friction coefficient <span>$K$</span>. Also, the argument <code>nint_u</code> explicitly adds one integrating state at the model input, the motor torque <span>$τ$</span>, with an associated standard deviation <code>σQint_u</code> of 0.1 N m. The estimator tuning is tested on a plant with a 25 % larger friction coefficient <span>$K$</span>:</p><pre><code class="language-julia hljs">const par_plant = (par[1], par[2], 1.25*par[3], par[4])
3839
f_plant(x, u, _ ) = pendulum(par_plant, x, u)
39-
plant = NonLinModel(f_plant, h, Ts, nu, nx, ny)
40+
plant = setname!(NonLinModel(f_plant, h, Ts, nu, nx, ny); u=vu, x=vx, y=vy)
4041
res = sim!(estim, N, [0.5], plant=plant, y_noise=[0.5])
4142
plot(res, plotu=false, plotxwithx̂=true)</code></pre><p><img src="../plot2_NonLinMPC.svg" alt="plot2_NonLinMPC"/></p><p>The estimate <span>$x̂_3$</span> is the integrating state on the torque <span>$τ$</span> that compensates for static errors. The Kalman filter performance seems sufficient for control.</p><p>As the motor torque is limited to -1.5 to 1.5 N m, we incorporate the input constraints in a <a href="../../public/predictive_control/#NonLinMPC"><code>NonLinMPC</code></a>:</p><pre><code class="language-julia hljs">Hp, Hc, Mwt, Nwt = 20, 2, [0.5], [2.5]
4243
nmpc = NonLinMPC(estim; Hp, Hc, Mwt, Nwt, Cwt=Inf)
@@ -53,8 +54,8 @@
5354
plot(res_ry)</code></pre><p><img src="../plot3_NonLinMPC.svg" alt="plot3_NonLinMPC"/></p><p>The controller seems robust enough to variations on <span>$K$</span> coefficient. Starting from this inverted position, the closed-loop response to a step disturbances of 10° is also satisfactory:</p><pre><code class="language-julia hljs">res_yd = sim!(nmpc, N, [180.0], plant=plant, x_0=[π, 0], x̂_0=[π, 0, 0], y_step=[10])
5455
plot(res_yd)</code></pre><p><img src="../plot4_NonLinMPC.svg" alt="plot4_NonLinMPC"/></p><h2 id="Economic-Model-Predictive-Controller"><a class="docs-heading-anchor" href="#Economic-Model-Predictive-Controller">Economic Model Predictive Controller</a><a id="Economic-Model-Predictive-Controller-1"></a><a class="docs-heading-anchor-permalink" href="#Economic-Model-Predictive-Controller" title="Permalink"></a></h2><p>Economic MPC can achieve the same objective but with lower economical costs. For this case study, the controller will aim to reduce the energy consumed by the motor. The power (W) transmitted by the motor to the pendulum is:</p><p class="math-container">\[Ẇ(t) = τ(t) ω(t)\]</p><p>Thus, the work (J) done by the motor from <span>$t = t_0$</span> to <span>$t_{end}$</span> is:</p><p class="math-container">\[W = \int_{t_0}^{t_{end}} Ẇ(t) \mathrm{d}t = \int_{t_0}^{t_{end}} τ(t) ω(t) \mathrm{d}t\]</p><p>With the sampling time <span>$T_s$</span> in s, the prediction horizon <span>$H_p$</span>, the limits defined as <span>$t_0 = k T_s$</span> and <span>$t_{end} = (k+H_p) T_s$</span>, and the left-endpoint rectangle method for the integral, we get:</p><p class="math-container">\[W ≈ T_s \sum_{j=0}^{H_p-1} τ(k + j) ω(k + j)\]</p><p>The objective function will now include an additive term that penalizes the work done by the motor <span>$W$</span> to reduce the energy consumption. Notice that <span>$W$</span> is a function of the manipulated input <span>$τ$</span> and the angular speed <span>$ω$</span>, a state that is not measured (only the angle <span>$θ$</span> is measured here). As the arguments of <a href="../../public/predictive_control/#NonLinMPC"><code>NonLinMPC</code></a> economic function <code>JE</code> do not include the states, the speed is now defined as an unmeasured output to design a Kalman Filter similar to the previous one (<span>$\mathbf{y^m} = θ$</span> and <span>$\mathbf{y^u} = ω$</span>):</p><pre><code class="language-julia hljs">h2(x, _ ) = [180/π*x[1], x[2]]
5556
nu, nx, ny = 1, 2, 2
56-
model2 = NonLinModel(f , h2, Ts, nu, nx, ny)
57-
plant2 = NonLinModel(f_plant, h2, Ts, nu, nx, ny)
57+
model2 = setname!(NonLinModel(f , h2, Ts, nu, nx, ny), u=vu, x=vx, y=[vy; vx[2]])
58+
plant2 = setname!(NonLinModel(f_plant, h2, Ts, nu, nx, ny), u=vu, x=vx, y=[vy; vx[2]])
5859
estim2 = UnscentedKalmanFilter(model2; σQ, σR, nint_u, σQint_u, i_ym=[1])</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">UnscentedKalmanFilter estimator with a sample time Ts = 0.1 s, NonLinModel and:
5960
1 manipulated inputs u (1 integrating states)
6061
3 estimated states x̂
@@ -142,4 +143,4 @@
142143
return res
143144
end</code></pre><p>The <a href="../../public/generic_func/#ModelPredictiveControl.setmodel!"><code>setmodel!</code></a> method must be called after solving the optimization problem with <a href="../../public/predictive_control/#ModelPredictiveControl.moveinput!"><code>moveinput!</code></a>, and before updating the state estimate with <a href="../../public/generic_func/#ModelPredictiveControl.updatestate!"><code>updatestate!</code></a>. The <a href="../../public/generic_func/#ModelPredictiveControl.SimResult"><code>SimResult</code></a> object is for plotting purposes only. The adaptive <a href="../../public/predictive_control/#LinMPC"><code>LinMPC</code></a> performances are similar to the nonlinear MPC, both for the 180° setpoint:</p><pre><code class="language-julia hljs">res_slin = test_slmpc(model, mpc3, [180], plant, x_0=[0, 0])
144145
plot(res_slin)</code></pre><p><img src="../plot10_NonLinMPC.svg" alt="plot10_NonLinMPC"/></p><p>and the 10° step disturbance:</p><pre><code class="language-julia hljs">res_slin = test_slmpc(model, mpc3, [180], plant, x_0=[π, 0], y_step=[10])
145-
plot(res_slin)</code></pre><p><img src="../plot11_NonLinMPC.svg" alt="plot11_NonLinMPC"/></p><p>The computations of the successive linearization MPC are about 125 times faster than the nonlinear MPC (0.00012 s per time steps versus 0.015 s per time steps, on average), an impressive gain for similar closed-loop performances!</p><section class="footnotes is-size-7"><ul><li class="footnote" id="footnote-1"><a class="tag is-link" href="#citeref-1">1</a>Arnström, D., Bemporad, A., and Axehill, D. (2022). A dual active-set solver for embedded quadratic programming using recursive LDLᵀ updates. IEEE Trans. Autom. Contr., 67(8). <a href="https://doi.org/doi:10.1109/TAC.2022.3176430">https://doi.org/doi:10.1109/TAC.2022.3176430</a>.</li></ul></section></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../linmpc/">« Linear Design</a><a class="docs-footer-nextpage" href="../../public/sim_model/">Plant Models »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 1 May 2024 15:27">Wednesday 1 May 2024</span>. Using Julia version 1.9.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
146+
plot(res_slin)</code></pre><p><img src="../plot11_NonLinMPC.svg" alt="plot11_NonLinMPC"/></p><p>The computations of the successive linearization MPC are about 125 times faster than the nonlinear MPC (0.00012 s per time steps versus 0.015 s per time steps, on average), an impressive gain for similar closed-loop performances!</p><section class="footnotes is-size-7"><ul><li class="footnote" id="footnote-1"><a class="tag is-link" href="#citeref-1">1</a>Arnström, D., Bemporad, A., and Axehill, D. (2022). A dual active-set solver for embedded quadratic programming using recursive LDLᵀ updates. IEEE Trans. Autom. Contr., 67(8). <a href="https://doi.org/doi:10.1109/TAC.2022.3176430">https://doi.org/doi:10.1109/TAC.2022.3176430</a>.</li></ul></section></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../linmpc/">« Linear Design</a><a class="docs-footer-nextpage" href="../../public/sim_model/">Plant Models »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 1 May 2024 21:20">Wednesday 1 May 2024</span>. Using Julia version 1.9.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>

0 commit comments

Comments
 (0)