|
84 | 84 | plot_data(t_data, u_data, y_data, ry_data)</code></pre><p><img src="../plot2_LinMPC.svg" alt="plot2_LinMPC"/></p><h2 id="Moving-Horizon-Estimation"><a class="docs-heading-anchor" href="#Moving-Horizon-Estimation">Moving Horizon Estimation</a><a id="Moving-Horizon-Estimation-1"></a><a class="docs-heading-anchor-permalink" href="#Moving-Horizon-Estimation" title="Permalink"></a></h2><p>The <a href="../../public/state_estim/#SteadyKalmanFilter"><code>SteadyKalmanFilter</code></a> is simple but it is not able to handle constraints at estimation. The <a href="../../public/state_estim/#MovingHorizonEstimator"><code>MovingHorizonEstimator</code></a> (MHE) can improve the accuracy of the state estimate <span>$\mathbf{x̂}$</span>. It solves a quadratic optimization problem under a past time window <span>$H_e$</span>. Bounds on the estimated plant state <span>$\mathbf{x̂}$</span>, estimated process noise <span>$\mathbf{ŵ}$</span> and estimated sensor noise <span>$\mathbf{v̂}$</span> can be included in the problem. This can be useful to add physical knowledge on the plant and its disturbances, and it does not require the installation of new physical sensors (e.g. a strictly positive concentration). The closed-loop performance of any state feedback controller, like here, depends on the accuracy of the plant state estimate.</p><p>For the CSTR, we will bound the innovation term <span>$\mathbf{y}(k) - \mathbf{ŷ}(k) = \mathbf{v̂}(k)$</span>, and increase the hot water unmeasured disturbance covariance in <span>$\mathbf{Q_{int_u}}$</span> to accelerate the estimation of the load disturbance:</p><pre><code class="language-julia hljs">estim = MovingHorizonEstimator(model, He=10, nint_u=[1, 1], σQint_u = [1, 2]) |
85 | 85 | estim = setconstraint!(estim, v̂min=[-1, -0.5], v̂max=[+1, +0.5]) |
86 | 86 | mpc_mhe = LinMPC(estim, Hp=10, Hc=2, Mwt=[1, 1], Nwt=[0.1, 0.1]) |
87 | | -mpc_mhe = setconstraint!(mpc_mhe, ymin=[45, -Inf])</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">LinMPC controller with a sample time Ts = 2.0 s: |
| 87 | +mpc_mhe = setconstraint!(mpc_mhe, ymin=[48, -Inf])</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">LinMPC controller with a sample time Ts = 2.0 s: |
88 | 88 | ├ estimator: MovingHorizonEstimator |
89 | 89 | ├ model: LinModel |
90 | 90 | ├ optimizer: OSQP |
|
153 | 153 | u, y, d = model.uop, model(), mpc_d.estim.model.dop |
154 | 154 | initstate!(mpc_d, u, y, d) |
155 | 155 | u_data, y_data, ry_data = test_mpc_d(mpc_d, model) |
156 | | -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><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.16.1 on <span class="colophon-date" title="Saturday 10 January 2026 18:38">Saturday 10 January 2026</span>. Using Julia version 1.12.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html> |
| 156 | +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><option value="catppuccin-latte">catppuccin-latte</option><option value="catppuccin-frappe">catppuccin-frappe</option><option value="catppuccin-macchiato">catppuccin-macchiato</option><option value="catppuccin-mocha">catppuccin-mocha</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.16.1 on <span class="colophon-date" title="Sunday 11 January 2026 16:39">Sunday 11 January 2026</span>. Using Julia version 1.12.4.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html> |
0 commit comments