Skip to content

Commit b334b12

Browse files
committed
sim! function for custom ru argument
1 parent 9eabd05 commit b334b12

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

src/controller/nonlinmpc.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ the manipulated inputs, the predicted outputs and measured disturbances from ``k
9696
\mathbf{Ŷ}_E = \begin{bmatrix} \mathbf{ŷ}(k) \\ \mathbf{Ŷ} \end{bmatrix} \text{,} \qquad
9797
\mathbf{D̂}_E = \begin{bmatrix} \mathbf{d}(k) \\ \mathbf{D̂} \end{bmatrix}
9898
```
99-
since ``H_c ≤ H_p`` implies that ``\mathbf{u}(k+H_p) = \mathbf{u}(k+H_p-1)``. The vector
100-
``\mathbf{D̂}`` includes the predicted measured disturbance over ``H_p``.
99+
since ``H_c ≤ H_p`` implies that ``\mathbf{Δu}(k+H_p) = \mathbf{0}`` or ``\mathbf{u}(k+H_p)=
100+
\mathbf{u}(k+H_p-1)``. The vector ``\mathbf{D̂}`` includes the predicted measured disturbance
101+
over ``H_p``.
101102
102103
!!! tip
103104
Replace any of the 3 arguments with `_` if not needed (see `JE` default value below).

src/plot_sim.jl

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ struct SimResult{O<:Union{SimModel, StateEstimator, PredictiveController}}
66
Ŷ_data ::Matrix{Float64} # estimated outputs
77
U_data ::Matrix{Float64} # manipulated inputs
88
Ud_data::Matrix{Float64} # manipulated inputs including load disturbances
9+
Ru_data::Matrix{Float64} # manipulated input setpoints
910
D_data ::Matrix{Float64} # measured disturbances
1011
X_data ::Matrix{Float64} # plant states
1112
X̂_data ::Matrix{Float64} # estimated states
@@ -55,7 +56,9 @@ function sim!(
5556
updatestate!(plant, u, d);
5657
end
5758
return SimResult(
58-
T_data, Y_data, U_data, Y_data, U_data, U_data, D_data, X_data, X_data, plant
59+
T_data, Y_data, U_data, Y_data,
60+
U_data, U_data, U_data, D_data, X_data, X_data,
61+
plant
5962
)
6063
end
6164

@@ -68,7 +71,7 @@ end
6871
<keyword arguments>
6972
) -> res
7073
71-
Closed-loop simulation of `estim` estimator for `N` time steps, default to input bumps.
74+
Closed-loop simulation of `estim` estimator for `N` steps, default to input bumps.
7275
7376
See Arguments for the available options. The noises are provided as standard deviations σ
7477
vectors. The simulated sensor and process noises of `plant` are specified by `y_noise` and
@@ -118,14 +121,15 @@ end
118121
mpc::PredictiveController,
119122
N::Int,
120123
ry = mpc.estim.model.yop .+ 1,
121-
d = mpc.estim.model.dop;
124+
d = mpc.estim.model.dop,
125+
ru = mpc.estim.model.uop;
122126
<keyword arguments>
123127
) -> res
124128
125-
Closed-loop simulation of `mpc` controller for `N` time steps, default to setpoint bumps.
129+
Closed-loop simulation of `mpc` controller for `N` steps, default to output setpoint bumps.
126130
127-
The output setpoint ``\mathbf{r_y}`` is held constant at `ry`. The keyword arguments are
128-
identical to [`sim!(::StateEstimator, ::Int)`](@ref).
131+
The output and manipulated input setpoints are held constant at `ry` and `ru`, respectively.
132+
The keyword arguments are identical to [`sim!(::StateEstimator, ::Int)`](@ref).
129133
130134
# Examples
131135
```julia-repl
@@ -143,10 +147,11 @@ function sim!(
143147
mpc::PredictiveController,
144148
N::Int,
145149
ry::Vector = mpc.estim.model.yop .+ 1,
146-
d ::Vector = mpc.estim.model.dop;
150+
d ::Vector = mpc.estim.model.dop,
151+
ru::Vector = mpc.estim.model.uop;
147152
kwargs...
148153
)
149-
return sim_closedloop!(mpc, mpc.estim, N, ry, d; kwargs...)
154+
return sim_closedloop!(mpc, mpc.estim, N, ry, d, ru; kwargs...)
150155
end
151156

152157
"Quick simulation function for `StateEstimator` and `PredictiveController` instances."
@@ -155,7 +160,8 @@ function sim_closedloop!(
155160
estim::StateEstimator,
156161
N::Int,
157162
u_ry::Vector,
158-
d::Vector;
163+
d ::Vector,
164+
ru ::Vector = estim.model.uop;
159165
plant::SimModel = estim.model,
160166
u_step ::Vector = zeros(plant.nu),
161167
u_noise::Vector = zeros(plant.nu),
@@ -177,6 +183,7 @@ function sim_closedloop!(
177183
U_Ry_data = Matrix{Float64}(undef, length(u_ry), N)
178184
U_data = Matrix{Float64}(undef, plant.nu, N)
179185
Ud_data = Matrix{Float64}(undef, plant.nu, N)
186+
Ru_data = Matrix{Float64}(undef, plant.nu, N)
180187
D_data = Matrix{Float64}(undef, plant.nd, N)
181188
X_data = Matrix{Float64}(undef, plant.nx, N)
182189
X̂_data = Matrix{Float64}(undef, estim.nx̂, N)
@@ -188,13 +195,14 @@ function sim_closedloop!(
188195
d = lastd + d_step + d_noise.*randn(plant.nd)
189196
y = evaloutput(plant, d) + y_step + y_noise.*randn(plant.ny)
190197
ym = y[estim.i_ym]
191-
u = sim_getu!(est_mpc, u_ry, d, ym)
198+
u = sim_getu!(est_mpc, u_ry, d, ru, ym)
192199
ud = u + u_step + u_noise.*randn(plant.nu)
193200
Y_data[:, i] = y
194201
Ŷ_data[:, i] = evalŷ(estim, ym, d)
195202
U_Ry_data[:, i] = u_ry
196203
U_data[:, i] = u
197204
Ud_data[:, i] = ud
205+
Ru_data[:, i] = ru
198206
D_data[:, i] = d
199207
X_data[:, i] = plant.x
200208
X̂_data[:, i] = estim.
@@ -204,17 +212,19 @@ function sim_closedloop!(
204212
end
205213
res = SimResult(
206214
T_data, Y_data, U_Ry_data, Ŷ_data,
207-
U_data, Ud_data, D_data, X_data, X̂_data,
215+
U_data, Ud_data, Ru_data, D_data, X_data, X̂_data,
208216
est_mpc
209217
)
210218
setstate!(plant, old_x0)
211219
return res
212220
end
213221

214-
"Keep manipulated input `u` unchanged for state estimator simulation."
215-
sim_getu!(::StateEstimator, u, _ , _ ) = u
216222
"Compute new `u` for predictive controller simulation."
217-
sim_getu!(mpc::PredictiveController, ry, d, ym) = moveinput!(mpc, ry, d; ym)
223+
function sim_getu!(mpc::PredictiveController, ry, d, ru, ym)
224+
return moveinput!(mpc, ry, d; R̂u=repeat(ru, mpc.Hp), ym)
225+
end
226+
"Keep manipulated input `u` unchanged for state estimator simulation."
227+
sim_getu!(::StateEstimator, u, _ , _ , _ ) = u
218228

219229
"Plots.jl recipe for `SimResult` objects constructed with `SimModel` objects."
220230
@recipe function plot(

0 commit comments

Comments
 (0)