From 9dd5db69afabbab7d1bb025f97426fa22b97d8b7 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Sun, 21 Sep 2025 17:00:33 -0400 Subject: [PATCH 1/4] doc: minor corrections --- src/controller/transcription.jl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/controller/transcription.jl b/src/controller/transcription.jl index 81902f086..d2b22438f 100644 --- a/src/controller/transcription.jl +++ b/src/controller/transcription.jl @@ -1169,8 +1169,8 @@ The method mutates `Ŷ0`, `x̂0end`, `X̂0`, `Û0` and `K0` arguments. The aug [`f̂!`](@ref) and [`ĥ!`](@ref) functions is called recursively in a `for` loop: ```math \begin{aligned} -\mathbf{x̂_0}(k+1) &= \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k) \Big) \\ -\mathbf{ŷ_0}(k) &= \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d_0}(k) \Big) +\mathbf{x̂_0}(k+1) &= \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d̂_0}(k) \Big) \\ +\mathbf{ŷ_0}(k) &= \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d̂_0}(k) \Big) \end{aligned} ``` """ @@ -1211,7 +1211,7 @@ Compute vectors if `model` is a [`NonLinModel`](@ref) and other [`TranscriptionM The method mutates `Ŷ0` and `x̂0end` arguments. The augmented output function [`ĥ!`](@ref) is called multiple times in a `for` loop: ```math -\mathbf{ŷ_0}(k) = \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d_0}(k) \Big) +\mathbf{ŷ_0}(k) = \mathbf{ĥ}\Big(\mathbf{x̂_0}(k), \mathbf{d̂_0}(k) \Big) ``` in which ``\mathbf{x̂_0}`` is the augmented state extracted from the decision variable `Z̃`. """ @@ -1332,7 +1332,7 @@ Nonlinear equality constrains for [`NonLinModel`](@ref) and [`MultipleShooting`] The method mutates the `geq`, `X̂0`, `Û0` and `K0` vectors in argument. The nonlinear equality constraints `geq` only includes the augmented state defects, computed with: ```math -\mathbf{ŝ}(k+1) = \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d_0}(k)\Big) +\mathbf{ŝ}(k+1) = \mathbf{f̂}\Big(\mathbf{x̂_0}(k), \mathbf{u_0}(k), \mathbf{d̂_0}(k)\Big) - \mathbf{x̂_0}(k+1) ``` in which the augmented state ``\mathbf{x̂_0}`` are extracted from the decision variables @@ -1395,8 +1395,8 @@ extracted from the decision variables `Z̃`. The ``\mathbf{k}`` coefficients are evaluated from the continuous-time function `model.f!` and: ```math \begin{aligned} -\mathbf{k}_1 &= \mathbf{f}\Big(\mathbf{x_0}(k), \mathbf{û_0}(k), \mathbf{d_0}(k) \Big) \\ -\mathbf{k}_2 &= \mathbf{f}\Big(\mathbf{x_0}(k+1), \mathbf{û_0}(k+h), \mathbf{d_0}(k+1)\Big) +\mathbf{k}_1 &= \mathbf{f}\Big(\mathbf{x_0}(k), \mathbf{û_0}(k), \mathbf{d̂_0}(k) \Big) \\ +\mathbf{k}_2 &= \mathbf{f}\Big(\mathbf{x_0}(k+1), \mathbf{û_0}(k+h), \mathbf{d̂_0}(k+1)\Big) \end{aligned} ``` in which ``h`` is the hold order `transcription.h` and the disturbed input is: @@ -1419,7 +1419,6 @@ function con_nonlinprogeq!( nk = get_nk(model, transcription) D̂0 = mpc.D̂0 X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)] - #TODO: allow parallel for loop or threads? @threadsif f_threads for j=1:Hp if j < 2 x̂0 = @views mpc.estim.x̂0[1:nx̂] From eedfd841dfb2a375e7cea41aa37ce26c5f6a5285 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Mon, 22 Sep 2025 03:27:46 -0400 Subject: [PATCH 2/4] added: `progress` kwarg for `sim!` --- src/ModelPredictiveControl.jl | 3 ++- src/general.jl | 11 +++++++++++ src/plot_sim.jl | 14 +++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/ModelPredictiveControl.jl b/src/ModelPredictiveControl.jl index 679768bfa..ec246c121 100644 --- a/src/ModelPredictiveControl.jl +++ b/src/ModelPredictiveControl.jl @@ -5,7 +5,6 @@ using LinearAlgebra, SparseArrays using Random: randn using RecipesBase -using ProgressLogging using DifferentiationInterface: ADTypes.AbstractADType, AutoForwardDiff, AutoSparse using DifferentiationInterface: gradient!, jacobian!, prepare_gradient, prepare_jacobian @@ -14,6 +13,8 @@ using DifferentiationInterface: Constant, Cache using SparseConnectivityTracer: TracerSparsityDetector using SparseMatrixColorings: GreedyColoringAlgorithm, sparsity_pattern +import ProgressLogging + import ForwardDiff import ControlSystemsBase diff --git a/src/general.jl b/src/general.jl index 127feb24b..ab0f3e7f8 100644 --- a/src/general.jl +++ b/src/general.jl @@ -133,4 +133,15 @@ macro threadsif(flag, expr) $expr end end |> esc +end + +"Add `ProgressLogging.@progress` with the name `name` to a `for` loop if `flag==true`" +macro progressif(flag, name, expr) + quote + if $(flag) + ProgressLogging.@progress $name $expr + else + $expr + end + end |> esc end \ No newline at end of file diff --git a/src/plot_sim.jl b/src/plot_sim.jl index 31ab098a7..b0d049768 100644 --- a/src/plot_sim.jl +++ b/src/plot_sim.jl @@ -106,13 +106,14 @@ end @doc raw""" - sim!(plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; x_0=plant.xop) -> res + sim!(plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; x_0=plant.xop, progress=true) -> res Open-loop simulation of `plant` for `N` time steps, default to unit bump test on all inputs. The manipulated inputs ``\mathbf{u}`` and measured disturbances ``\mathbf{d}`` are held constant at `u` and `d` values, respectively. The plant initial state ``\mathbf{x}(0)`` is -specified by `x_0` keyword arguments. The function returns [`SimResult`](@ref) instances +specified by `x_0` keyword arguments. If `progress` is `true`, VS Code will display a +progress percentage of the simulation. The function returns [`SimResult`](@ref) instances that can be visualized by calling `plot` on them. Note that the method mutates `plant` internal states. @@ -129,7 +130,8 @@ function sim!( N::Int, u::Vector = plant.uop.+1, d::Vector = plant.dop; - x_0 = plant.xop + x_0 = plant.xop, + progress = true ) where {NT<:Real} T_data = collect(plant.Ts*(0:(N-1))) Y_data = Matrix{NT}(undef, plant.ny, N) @@ -137,7 +139,7 @@ function sim!( D_data = Matrix{NT}(undef, plant.nd, N) X_data = Matrix{NT}(undef, plant.nx, N) setstate!(plant, x_0) - @progress name="$(nameof(typeof(plant))) simulation" for i=1:N + @progressif progress name="$(nameof(typeof(plant))) simulation" for i=1:N y = evaloutput(plant, d) Y_data[:, i] .= y U_data[:, i] .= u @@ -187,6 +189,7 @@ vectors. The simulated sensor and process noises of `plant` are specified by `y_ - `x̂_0 = nothing` or *`xhat_0`* : initial estimate ``\mathbf{x̂}(0)``, [`initstate!`](@ref) is used if `nothing` - `lastu = plant.uop` : last plant input ``\mathbf{u}`` for ``\mathbf{x̂}`` initialization +- `progress = true` : display a progress percentage in VS Code if `true` # Examples ```jldoctest @@ -263,6 +266,7 @@ function sim_closedloop!( x_0 = plant.xop, xhat_0 = nothing, lastu = plant.uop, + progress = true, x̂_0 = xhat_0 ) where {NT<:Real} model = estim.model @@ -282,7 +286,7 @@ function sim_closedloop!( lastd, lasty = d, evaloutput(plant, d) initstate!(est_mpc, lastu, lasty[estim.i_ym], lastd) isnothing(x̂_0) || setstate!(est_mpc, x̂_0) - @progress name="$(nameof(typeof(est_mpc))) simulation" for i=1:N + @progressif progress name="$(nameof(typeof(est_mpc))) simulation" for i=1:N d = lastd + d_step + d_noise.*randn(plant.nd) y = evaloutput(plant, d) + y_step + y_noise.*randn(plant.ny) ym = y[estim.i_ym] From 25307035c79a206d210dad659a130c74a21d5c84 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Mon, 22 Sep 2025 14:18:27 -0400 Subject: [PATCH 3/4] doc: minor modification --- src/plot_sim.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plot_sim.jl b/src/plot_sim.jl index b0d049768..5e010a73d 100644 --- a/src/plot_sim.jl +++ b/src/plot_sim.jl @@ -106,7 +106,9 @@ end @doc raw""" - sim!(plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; x_0=plant.xop, progress=true) -> res + sim!( + plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; x_0=plant.xop, progress=true + ) -> res Open-loop simulation of `plant` for `N` time steps, default to unit bump test on all inputs. From c9d662aedb3a0e42c8d37588893ff94202c2d651 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Mon, 22 Sep 2025 15:17:21 -0400 Subject: [PATCH 4/4] test: basic tests with `progress=false` --- test/4_test_plot_sim.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/4_test_plot_sim.jl b/test/4_test_plot_sim.jl index e419edac0..6e5905fe1 100644 --- a/test/4_test_plot_sim.jl +++ b/test/4_test_plot_sim.jl @@ -10,6 +10,8 @@ @test res.D_data[:, 1] ≈ model.dop @test res.X_data[:, 1] ≈ zeros(model.nx) + @test_nowarn sim!(model, 15, progress=false) + res_man = SimResult(model, res.U_data, res.Y_data, res.D_data; X_data=res.X_data) @test res_man.U_data ≈ res.U_data @test res_man.Y_data ≈ res.Y_data @@ -56,6 +58,8 @@ end @test res.X_data[:, 1] ≈ zeros(estim.model.nx) @test res.X̂_data[:, 1] ≈ zeros(estim.nx̂) + @test_nowarn sim!(estim, 15, progress=false) + res_man = SimResult( estim, res.U_data, res.Y_data, res.D_data; X_data=res.X_data, X̂_data=res.X̂_data @@ -140,6 +144,8 @@ end @test res.X_data[:, 1] ≈ zeros(mpc1.estim.model.nx) @test res.X̂_data[:, 1] ≈ zeros(mpc1.estim.nx̂) + @test_nowarn sim!(mpc1, 15, progress=false) + mpc2 = ExplicitMPC(LinModel(sys, Ts, i_d=[3])) res = sim!(mpc2, 15) @test isa(res.obj, ExplicitMPC)