Skip to content

Commit f9daafe

Browse files
committed
removed most keyword arguments for sim! method on SimModel object
1 parent ca50f3b commit f9daafe

File tree

7 files changed

+72
-84
lines changed

7 files changed

+72
-84
lines changed

src/controller/nonlinmpc.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Use custom state estimator `estim` to construct `NonLinMPC`.
164164
165165
# Examples
166166
```jldoctest
167-
julia> model = NonLinModel((x,u,_)->0.5x+u, (x,_)->2x, 10, 1, 1, 1);
167+
julia> model = NonLinModel((x,u,_)->0.5x+u, (x,_)->2x, 10.0, 1, 1, 1);
168168
169169
julia> estim = UnscentedKalmanFilter(model, σQ_int=[0.05]);
170170

src/estimator/internal_model.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ function InternalModel(
9191
model::M;
9292
i_ym::IntRangeOrVector = 1:model.ny,
9393
stoch_ym::Union{StateSpace, TransferFunction} = ss(1,1,1,1,model.Ts).*I(length(i_ym))
94-
) where {M<:SimModel}
94+
) where {M<:SimModel}
9595
if isa(stoch_ym, TransferFunction)
9696
stoch_ym = minreal(ss(stoch_ym))
9797
end

src/estimator/kalman.jl

+14-14
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ you can use 0 integrator on `model` integrating outputs, or the alternative time
123123
function SteadyKalmanFilter(
124124
model::LinModel;
125125
i_ym::IntRangeOrVector = 1:model.ny,
126-
σQ::Vector{<:Real} = fill(0.1, model.nx),
127-
σR::Vector{<:Real} = fill(0.1, length(i_ym)),
126+
σQ::Vector = fill(0.1, model.nx),
127+
σR::Vector = fill(0.1, length(i_ym)),
128128
nint_ym::IntVectorOrInt = fill(1, length(i_ym)),
129-
σQ_int::Vector{<:Real} = fill(0.1, max(sum(nint_ym), 0))
129+
σQ_int::Vector = fill(0.1, max(sum(nint_ym), 0))
130130
)
131131
if nint_ym == 0 # alias for no output integrator at all :
132132
nint_ym = fill(0, length(i_ym));
@@ -253,12 +253,12 @@ KalmanFilter estimator with a sample time Ts = 0.5 s, LinModel and:
253253
function KalmanFilter(
254254
model::LinModel;
255255
i_ym::IntRangeOrVector = 1:model.ny,
256-
σP0::Vector{<:Real} = fill(10, model.nx),
257-
σQ::Vector{<:Real} = fill(0.1, model.nx),
258-
σR::Vector{<:Real} = fill(0.1, length(i_ym)),
256+
σP0::Vector = fill(10, model.nx),
257+
σQ::Vector = fill(0.1, model.nx),
258+
σR::Vector = fill(0.1, length(i_ym)),
259259
nint_ym::IntVectorOrInt = fill(1, length(i_ym)),
260-
σP0_int::Vector{<:Real} = fill(10, max(sum(nint_ym), 0)),
261-
σQ_int::Vector{<:Real} = fill(0.1, max(sum(nint_ym), 0))
260+
σP0_int::Vector = fill(10, max(sum(nint_ym), 0)),
261+
σQ_int::Vector = fill(0.1, max(sum(nint_ym), 0))
262262
)
263263
if nint_ym == 0 # alias for no output integrator at all :
264264
nint_ym = fill(0, length(i_ym));
@@ -400,7 +400,7 @@ unmeasured ones, for ``\mathbf{ĥ^u}``).
400400
401401
# Examples
402402
```jldoctest
403-
julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10, 1, 1, 1);
403+
julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10.0, 1, 1, 1);
404404
405405
julia> estim = UnscentedKalmanFilter(model, σR=[1], nint_ym=[2], σP0_int=[1, 1])
406406
UnscentedKalmanFilter estimator with a sample time Ts = 10.0 s, NonLinModel and:
@@ -414,12 +414,12 @@ UnscentedKalmanFilter estimator with a sample time Ts = 10.0 s, NonLinModel and:
414414
function UnscentedKalmanFilter(
415415
model::M;
416416
i_ym::IntRangeOrVector = 1:model.ny,
417-
σP0::Vector{<:Real} = fill(10, model.nx),
418-
σQ::Vector{<:Real} = fill(0.1, model.nx),
419-
σR::Vector{<:Real} = fill(0.1, length(i_ym)),
417+
σP0::Vector = fill(10, model.nx),
418+
σQ::Vector = fill(0.1, model.nx),
419+
σR::Vector = fill(0.1, length(i_ym)),
420420
nint_ym::IntVectorOrInt = fill(1, length(i_ym)),
421-
σP0_int::Vector{<:Real} = fill(10, max(sum(nint_ym), 0)),
422-
σQ_int::Vector{<:Real} = fill(0.1, max(sum(nint_ym), 0)),
421+
σP0_int::Vector = fill(10, max(sum(nint_ym), 0)),
422+
σQ_int::Vector = fill(0.1, max(sum(nint_ym), 0)),
423423
α::Real = 1e-3,
424424
β::Real = 2,
425425
κ::Real = 0

src/model/nonlinmodel.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ See also [`LinModel`](@ref).
4949
5050
# Examples
5151
```jldoctest
52-
julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10, 1, 1, 1)
52+
julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10.0, 1, 1, 1)
5353
Discrete-time nonlinear model with a sample time Ts = 10.0 s and:
5454
1 manipulated inputs u
5555
1 states x

src/plot_sim.jl

+47-59
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,49 @@ struct SimResult{O<:Union{SimModel, StateEstimator, PredictiveController}}
1313
end
1414

1515
@doc raw"""
16-
sim!(plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; <keyword arguments>)
16+
sim!(plant::SimModel, N::Int, u=plant.uop.+1, d=plant.dop; x0=zeros(plant.nx))
1717
18-
Open-loop simulation of `plant` for `N` time steps, default to input bumps.
18+
Open-loop simulation of `plant` for `N` time steps, default to unit bump test on all inputs.
1919
20-
See Arguments for the available options. The noises are provided as standard deviations σ
21-
vectors. The simulated sensor and process noises of `plant` are specified by `y_noise` and
22-
`x_noise` arguments, respectively. The function returns `SimResult` instances that can be
23-
visualized by calling `plot` from [`Plots.jl`](https://github.com/JuliaPlots/Plots.jl) on
20+
The manipulated inputs ``\mathbf{u}`` and measured disturbances ``\mathbf{d}`` are held
21+
constant at `u` and `d` values, respectively. The plant initial state ``\mathbf{x}(0)`` is
22+
specified by `x0` keyword arguments. The function returns `SimResult` instances that can be
23+
visualized by calling `plot` from [`Plots.jl`](https://github.com/JuliaPlots/Plots.jl) on
2424
them (see Examples below).
2525
26-
# Arguments
27-
- `plant::SimModel` : plant model to simulate.
28-
- `N::Int` : simulation length in time steps.
29-
- `u = estim.model.uop .+ 1` : manipulated input ``\mathbf{u}`` value.
30-
- `d = estim.model.dop` : plant measured disturbance ``\mathbf{d}`` value.
31-
- `u_step = zeros(plant.nu)` : step load disturbance on plant inputs ``\mathbf{u}``.
32-
- `u_noise = zeros(plant.nu)` : additive gaussian noise on plant inputs ``\mathbf{u}``.
33-
- `y_step = zeros(plant.ny)` : step disturbance on plant outputs ``\mathbf{y}``.
34-
- `y_noise = zeros(plant.ny)` : additive gaussian noise on plant outputs ``\mathbf{y}``.
35-
- `d_step = zeros(plant.nd)` : step on measured disturbances ``\mathbf{d}``.
36-
- `d_noise = zeros(plant.nd)` : additive gaussian noise on measured dist. ``\mathbf{d}``.
37-
- `x_noise = zeros(plant.nx)` : additive gaussian noise on plant states ``\mathbf{x}``.
38-
- `x0 = zeros(plant.nx)` : plant initial state ``\mathbf{x}(0)``.
39-
4026
# Examples
4127
```julia-repl
42-
julia> plant = NonLinModel((x,u,d)->0.1x+u+d, (x,_)->2x, 10, 1, 1, 1, 1);
28+
julia> plant = NonLinModel((x,u,d)->0.1x+u+d, (x,_)->2x, 10.0, 1, 1, 1, 1);
4329
4430
julia> res = sim!(plant, 15, [0], [0], x0=[1]);
4531
4632
julia> using Plots; plot(res, plotu=false, plotd=false, plotx=true)
33+
4734
```
4835
"""
4936
function sim!(
50-
plant::SimModel,
37+
plant::SimModel,
5138
N::Int,
52-
u::Vector{<:Real} = plant.uop .+ 1,
53-
d::Vector{<:Real} = plant.dop;
54-
u_step ::Vector{<:Real} = zeros(plant.nu),
55-
u_noise::Vector{<:Real} = zeros(plant.nu),
56-
y_step ::Vector{<:Real} = zeros(plant.ny),
57-
y_noise::Vector{<:Real} = zeros(plant.ny),
58-
d_step ::Vector{<:Real} = zeros(plant.nd),
59-
d_noise::Vector{<:Real} = zeros(plant.nd),
60-
x_noise::Vector{<:Real} = zeros(plant.nx),
39+
u::Vector = plant.uop.+1,
40+
d::Vector = plant.dop;
6141
x0 = zeros(plant.nx)
6242
)
6343
T_data = collect(plant.Ts*(0:(N-1)))
6444
Y_data = Matrix{Float64}(undef, plant.ny, N)
6545
U_data = Matrix{Float64}(undef, plant.nu, N)
66-
Ud_data = Matrix{Float64}(undef, plant.nu, N)
6746
D_data = Matrix{Float64}(undef, plant.nd, N)
6847
X_data = Matrix{Float64}(undef, plant.nx, N)
6948
setstate!(plant, x0)
70-
d0 = d
7149
for i=1:N
72-
d = d0 + d_step + d_noise.*randn(plant.nd)
73-
y = evaloutput(plant, d) + y_step + y_noise.*randn(plant.ny)
74-
ud = u + u_step + u_noise.*randn(plant.nu)
50+
y = evaloutput(plant, d)
7551
Y_data[:, i] = y
7652
U_data[:, i] = u
77-
Ud_data[:, i] = ud
7853
D_data[:, i] = d
7954
X_data[:, i] = plant.x
80-
x = updatestate!(plant, ud, d);
81-
x[:] += x_noise.*randn(plant.nx)
55+
updatestate!(plant, u, d);
8256
end
8357
return SimResult(
84-
T_data, Y_data, U_data, Y_data, U_data, Ud_data, D_data, X_data, X_data, plant
58+
T_data, Y_data, U_data, Y_data, U_data, U_data, D_data, X_data, X_data, plant
8559
)
8660
end
8761

@@ -96,18 +70,27 @@ end
9670
9771
Closed-loop simulation of `estim` estimator for `N` time steps, default to input bumps.
9872
99-
See Arguments for the available options.
73+
See Arguments for the available options. The noises are provided as standard deviations σ
74+
vectors. The simulated sensor and process noises of `plant` are specified by `y_noise` and
75+
`x_noise` arguments, respectively.
10076
10177
# Arguments
10278
- `estim::StateEstimator` : state estimator to simulate.
10379
- `N::Int` : simulation length in time steps.
10480
- `u = estim.model.uop .+ 1` : manipulated input ``\mathbf{u}`` value.
10581
- `d = estim.model.dop` : plant measured disturbance ``\mathbf{d}`` value.
10682
- `plant::SimModel = estim.model` : simulated plant model.
83+
- `u_step = zeros(plant.nu)` : step load disturbance on plant inputs ``\mathbf{u}``.
84+
- `u_noise = zeros(plant.nu)` : gaussian load disturbance on plant inputs ``\mathbf{u}``.
85+
- `y_step = zeros(plant.ny)` : step disturbance on plant outputs ``\mathbf{y}``.
86+
- `y_noise = zeros(plant.ny)` : additive gaussian noise on plant outputs ``\mathbf{y}``.
87+
- `d_step = zeros(plant.nd)` : step on measured disturbances ``\mathbf{d}``.
88+
- `d_noise = zeros(plant.nd)` : additive gaussian noise on measured dist. ``\mathbf{d}``.
89+
- `x_noise = zeros(plant.nx)` : additive gaussian noise on plant states ``\mathbf{x}``.
90+
- `x0 = zeros(plant.nx)` : plant initial state ``\mathbf{x}(0)``.
10791
- `x̂0 = nothing` : `mpc.estim` state estimator initial state ``\mathbf{x̂}(0)``, if `nothing`
10892
then ``\mathbf{x̂}`` is initialized with [`initstate!`](@ref).
10993
- `lastu = plant.uop` : last plant input ``\mathbf{u}`` for ``\mathbf{x̂}`` initialization.
110-
- `<keyword arguments>` of [`sim!(::SimModel, ::Int)`](@ref).
11194
11295
# Examples
11396
```julia-repl
@@ -118,19 +101,19 @@ julia> estim = SteadyKalmanFilter(model, σR=[0.5], σQ=[0.25], σQ_int=[0.01]);
118101
julia> res = sim!(estim, 50, [0], y_noise=[0.5], x_noise=[0.25], x0=[-10], x̂0=[0, 0]);
119102
120103
julia> using Plots; plot(res, plotŷ=true, plotu=false, plotx=true, plotx̂=true)
104+
121105
```
122106
"""
123107
function sim!(
124108
estim::StateEstimator,
125109
N::Int,
126-
u::Vector{<:Real} = estim.model.uop .+ 1,
127-
d::Vector{<:Real} = estim.model.dop;
110+
u::Vector = estim.model.uop .+ 1,
111+
d::Vector = estim.model.dop;
128112
kwargs...
129113
)
130114
return sim_closedloop!(estim, estim, N, u, d; kwargs...)
131115
end
132116

133-
134117
@doc raw"""
135118
sim!(
136119
mpc::PredictiveController,
@@ -142,8 +125,8 @@ end
142125
143126
Closed-loop simulation of `mpc` controller for `N` time steps, default to setpoint bumps.
144127
145-
The argument `ry` is output setpoint ``\mathbf{r_y}`` value applied at ``t = 0``. The
146-
keyword arguments are identical to [`sim!(::StateEstimator, ::Int)`](@ref).
128+
The output setpoints ``\mathbf{r_y}`` are held constant at `r_y`. The keyword arguments are
129+
identical to [`sim!(::StateEstimator, ::Int)`](@ref).
147130
148131
# Examples
149132
```julia-repl
@@ -154,34 +137,34 @@ julia> mpc = setconstraint!(LinMPC(model, Mwt=[0, 1], Nwt=[0.01], Hp=30), ŷmin
154137
julia> res = sim!(mpc, 25, [0, 0], y_noise=[0.1], y_step=[-10, 0]);
155138
156139
julia> using Plots; plot(res, plotry=true, plotŷ=true, plotŷmin=true, plotu=true)
140+
157141
```
158142
"""
159143
function sim!(
160144
mpc::PredictiveController,
161145
N::Int,
162-
ry::Vector{<:Real} = mpc.estim.model.yop .+ 1,
163-
d ::Vector{<:Real} = mpc.estim.model.dop;
146+
ry::Vector = mpc.estim.model.yop .+ 1,
147+
d ::Vector = mpc.estim.model.dop;
164148
kwargs...
165149
)
166150
return sim_closedloop!(mpc, mpc.estim, N, ry, d; kwargs...)
167151
end
168152

169-
170153
"Quick simulation function for `StateEstimator` and `PredictiveController` instances."
171154
function sim_closedloop!(
172155
est_mpc::Union{StateEstimator, PredictiveController},
173156
estim::StateEstimator,
174157
N::Int,
175-
u_ry::Vector{<:Real},
176-
d::Vector{<:Real};
158+
u_ry::Vector,
159+
d::Vector;
177160
plant::SimModel = estim.model,
178-
u_step ::Vector{<:Real} = zeros(plant.nu),
179-
u_noise::Vector{<:Real} = zeros(plant.nu),
180-
y_step ::Vector{<:Real} = zeros(plant.ny),
181-
y_noise::Vector{<:Real} = zeros(plant.ny),
182-
d_step ::Vector{<:Real} = zeros(plant.nd),
183-
d_noise::Vector{<:Real} = zeros(plant.nd),
184-
x_noise::Vector{<:Real} = zeros(plant.nx),
161+
u_step ::Vector = zeros(plant.nu),
162+
u_noise::Vector = zeros(plant.nu),
163+
y_step ::Vector = zeros(plant.ny),
164+
y_noise::Vector = zeros(plant.ny),
165+
d_step ::Vector = zeros(plant.nd),
166+
d_noise::Vector = zeros(plant.nd),
167+
x_noise::Vector = zeros(plant.nx),
185168
x0 = zeros(plant.nx),
186169
x̂0 = nothing,
187170
lastu = plant.uop,
@@ -230,9 +213,12 @@ function sim_closedloop!(
230213
return res
231214
end
232215

216+
"Keep manipulated input `u` unchanged for state estimator simulation."
233217
sim_getu!(::StateEstimator, u, _ , _ ) = u
218+
"Compute new `u` for predictive controller simulation."
234219
sim_getu!(mpc::PredictiveController, ry, d, ym) = moveinput!(mpc, ry, d; ym)
235220

221+
"Plots.jl recipe for `SimResult` objects constructed with `SimModel` objects."
236222
@recipe function simresultplot(
237223
res::SimResult{<:SimModel};
238224
plotu = true,
@@ -308,6 +294,7 @@ sim_getu!(mpc::PredictiveController, ry, d, ym) = moveinput!(mpc, ry, d; ym)
308294
end
309295
end
310296

297+
"Plots.jl recipe for `SimResult` objects constructed with `StateEstimator` objects."
311298
@recipe function simresultplot(
312299
res::SimResult{<:StateEstimator};
313300
plotŷ = true,
@@ -414,6 +401,7 @@ end
414401
end
415402
end
416403

404+
"Plots.jl recipe for `SimResult` objects constructed with `PredictiveController` objects."
417405
@recipe function simresultplot(
418406
res::SimResult{<:PredictiveController};
419407
plotry = true,

src/predictive_control.jl

+7-7
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,11 @@ julia> u = moveinput!(mpc, [5]); round.(u, digits=3)
246246
"""
247247
function moveinput!(
248248
mpc::PredictiveController,
249-
ry::Vector{<:Real},
250-
d ::Vector{<:Real} = Float64[];
251-
R̂y::Vector{<:Real} = repeat(ry, mpc.Hp),
252-
::Vector{<:Real} = repeat(d, mpc.Hp),
253-
ym::Union{Vector{<:Real}, Nothing} = nothing
249+
ry::Vector,
250+
d ::Vector = Float64[];
251+
R̂y::Vector = repeat(ry, mpc.Hp),
252+
::Vector = repeat(d, mpc.Hp),
253+
ym::Union{Vector, Nothing} = nothing
254254
)
255255
validate_setpointdist(mpc, ry, d, R̂y, D̂)
256256
getestimates!(mpc, mpc.estim, ym, d)
@@ -1019,8 +1019,8 @@ end
10191019

10201020
"Functor allowing callable `PredictiveController` object as an alias for `moveinput!`."
10211021
function (mpc::PredictiveController)(
1022-
ry::Vector{<:Real},
1023-
d ::Vector{<:Real} = Float64[];
1022+
ry::Vector,
1023+
d ::Vector = Float64[];
10241024
kwargs...
10251025
)
10261026
return moveinput!(mpc, ry, d; kwargs...)

src/sim_model.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Functor allowing callable `SimModel` object as an alias for [`evaloutput`](@ref)
1111
1212
# Examples
1313
```jldoctest
14-
julia> model = NonLinModel((x,u,_)->-x + u, (x,_)->x .+ 20, 10, 1, 1, 1);
14+
julia> model = NonLinModel((x,u,_)->-x + u, (x,_)->x .+ 20, 10.0, 1, 1, 1);
1515
1616
julia> y = model()
1717
1-element Vector{Float64}:

0 commit comments

Comments
 (0)