@@ -13,75 +13,49 @@ struct SimResult{O<:Union{SimModel, StateEstimator, PredictiveController}}
13
13
end
14
14
15
15
@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) )
17
17
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 .
19
19
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 `` \m athbf{u}`` and measured disturbances `` \m athbf{d}`` are held
21
+ constant at `u` and `d` values, respectively. The plant initial state `` \m athbf{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
24
24
them (see Examples below).
25
25
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 ``\m athbf{u}`` value.
30
- - `d = estim.model.dop` : plant measured disturbance ``\m athbf{d}`` value.
31
- - `u_step = zeros(plant.nu)` : step load disturbance on plant inputs ``\m athbf{u}``.
32
- - `u_noise = zeros(plant.nu)` : additive gaussian noise on plant inputs ``\m athbf{u}``.
33
- - `y_step = zeros(plant.ny)` : step disturbance on plant outputs ``\m athbf{y}``.
34
- - `y_noise = zeros(plant.ny)` : additive gaussian noise on plant outputs ``\m athbf{y}``.
35
- - `d_step = zeros(plant.nd)` : step on measured disturbances ``\m athbf{d}``.
36
- - `d_noise = zeros(plant.nd)` : additive gaussian noise on measured dist. ``\m athbf{d}``.
37
- - `x_noise = zeros(plant.nx)` : additive gaussian noise on plant states ``\m athbf{x}``.
38
- - `x0 = zeros(plant.nx)` : plant initial state ``\m athbf{x}(0)``.
39
-
40
26
# Examples
41
27
```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);
43
29
44
30
julia> res = sim!(plant, 15, [0], [0], x0=[1]);
45
31
46
32
julia> using Plots; plot(res, plotu=false, plotd=false, plotx=true)
33
+
47
34
```
48
35
"""
49
36
function sim! (
50
- plant:: SimModel ,
37
+ plant:: SimModel ,
51
38
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;
61
41
x0 = zeros (plant. nx)
62
42
)
63
43
T_data = collect (plant. Ts* (0 : (N- 1 )))
64
44
Y_data = Matrix {Float64} (undef, plant. ny, N)
65
45
U_data = Matrix {Float64} (undef, plant. nu, N)
66
- Ud_data = Matrix {Float64} (undef, plant. nu, N)
67
46
D_data = Matrix {Float64} (undef, plant. nd, N)
68
47
X_data = Matrix {Float64} (undef, plant. nx, N)
69
48
setstate! (plant, x0)
70
- d0 = d
71
49
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)
75
51
Y_data[:, i] = y
76
52
U_data[:, i] = u
77
- Ud_data[:, i] = ud
78
53
D_data[:, i] = d
79
54
X_data[:, i] = plant. x
80
- x = updatestate! (plant, ud, d);
81
- x[:] += x_noise.* randn (plant. nx)
55
+ updatestate! (plant, u, d);
82
56
end
83
57
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
85
59
)
86
60
end
87
61
96
70
97
71
Closed-loop simulation of `estim` estimator for `N` time steps, default to input bumps.
98
72
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.
100
76
101
77
# Arguments
102
78
- `estim::StateEstimator` : state estimator to simulate.
103
79
- `N::Int` : simulation length in time steps.
104
80
- `u = estim.model.uop .+ 1` : manipulated input ``\m athbf{u}`` value.
105
81
- `d = estim.model.dop` : plant measured disturbance ``\m athbf{d}`` value.
106
82
- `plant::SimModel = estim.model` : simulated plant model.
83
+ - `u_step = zeros(plant.nu)` : step load disturbance on plant inputs ``\m athbf{u}``.
84
+ - `u_noise = zeros(plant.nu)` : gaussian load disturbance on plant inputs ``\m athbf{u}``.
85
+ - `y_step = zeros(plant.ny)` : step disturbance on plant outputs ``\m athbf{y}``.
86
+ - `y_noise = zeros(plant.ny)` : additive gaussian noise on plant outputs ``\m athbf{y}``.
87
+ - `d_step = zeros(plant.nd)` : step on measured disturbances ``\m athbf{d}``.
88
+ - `d_noise = zeros(plant.nd)` : additive gaussian noise on measured dist. ``\m athbf{d}``.
89
+ - `x_noise = zeros(plant.nx)` : additive gaussian noise on plant states ``\m athbf{x}``.
90
+ - `x0 = zeros(plant.nx)` : plant initial state ``\m athbf{x}(0)``.
107
91
- `x̂0 = nothing` : `mpc.estim` state estimator initial state ``\m athbf{x̂}(0)``, if `nothing`
108
92
then ``\m athbf{x̂}`` is initialized with [`initstate!`](@ref).
109
93
- `lastu = plant.uop` : last plant input ``\m athbf{u}`` for ``\m athbf{x̂}`` initialization.
110
- - `<keyword arguments>` of [`sim!(::SimModel, ::Int)`](@ref).
111
94
112
95
# Examples
113
96
```julia-repl
@@ -118,19 +101,19 @@ julia> estim = SteadyKalmanFilter(model, σR=[0.5], σQ=[0.25], σQ_int=[0.01]);
118
101
julia> res = sim!(estim, 50, [0], y_noise=[0.5], x_noise=[0.25], x0=[-10], x̂0=[0, 0]);
119
102
120
103
julia> using Plots; plot(res, plotŷ=true, plotu=false, plotx=true, plotx̂=true)
104
+
121
105
```
122
106
"""
123
107
function sim! (
124
108
estim:: StateEstimator ,
125
109
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;
128
112
kwargs...
129
113
)
130
114
return sim_closedloop! (estim, estim, N, u, d; kwargs... )
131
115
end
132
116
133
-
134
117
@doc raw """
135
118
sim!(
136
119
mpc::PredictiveController,
142
125
143
126
Closed-loop simulation of `mpc` controller for `N` time steps, default to setpoint bumps.
144
127
145
- The argument `ry` is output setpoint ``\m athbf{r_y}`` value applied at ``t = 0`` . The
146
- keyword arguments are identical to [`sim!(::StateEstimator, ::Int)`](@ref).
128
+ The output setpoints ``\m athbf{r_y}`` are held constant at `r_y` . The keyword arguments are
129
+ identical to [`sim!(::StateEstimator, ::Int)`](@ref).
147
130
148
131
# Examples
149
132
```julia-repl
@@ -154,34 +137,34 @@ julia> mpc = setconstraint!(LinMPC(model, Mwt=[0, 1], Nwt=[0.01], Hp=30), ŷmin
154
137
julia> res = sim!(mpc, 25, [0, 0], y_noise=[0.1], y_step=[-10, 0]);
155
138
156
139
julia> using Plots; plot(res, plotry=true, plotŷ=true, plotŷmin=true, plotu=true)
140
+
157
141
```
158
142
"""
159
143
function sim! (
160
144
mpc:: PredictiveController ,
161
145
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;
164
148
kwargs...
165
149
)
166
150
return sim_closedloop! (mpc, mpc. estim, N, ry, d; kwargs... )
167
151
end
168
152
169
-
170
153
" Quick simulation function for `StateEstimator` and `PredictiveController` instances."
171
154
function sim_closedloop! (
172
155
est_mpc:: Union{StateEstimator, PredictiveController} ,
173
156
estim:: StateEstimator ,
174
157
N:: Int ,
175
- u_ry:: Vector{<:Real} ,
176
- d:: Vector{<:Real} ;
158
+ u_ry:: Vector ,
159
+ d:: Vector ;
177
160
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),
185
168
x0 = zeros (plant. nx),
186
169
x̂0 = nothing ,
187
170
lastu = plant. uop,
@@ -230,9 +213,12 @@ function sim_closedloop!(
230
213
return res
231
214
end
232
215
216
+ " Keep manipulated input `u` unchanged for state estimator simulation."
233
217
sim_getu! (:: StateEstimator , u, _ , _ ) = u
218
+ " Compute new `u` for predictive controller simulation."
234
219
sim_getu! (mpc:: PredictiveController , ry, d, ym) = moveinput! (mpc, ry, d; ym)
235
220
221
+ " Plots.jl recipe for `SimResult` objects constructed with `SimModel` objects."
236
222
@recipe function simresultplot (
237
223
res:: SimResult{<:SimModel} ;
238
224
plotu = true ,
@@ -308,6 +294,7 @@ sim_getu!(mpc::PredictiveController, ry, d, ym) = moveinput!(mpc, ry, d; ym)
308
294
end
309
295
end
310
296
297
+ " Plots.jl recipe for `SimResult` objects constructed with `StateEstimator` objects."
311
298
@recipe function simresultplot (
312
299
res:: SimResult{<:StateEstimator} ;
313
300
plotŷ = true ,
414
401
end
415
402
end
416
403
404
+ " Plots.jl recipe for `SimResult` objects constructed with `PredictiveController` objects."
417
405
@recipe function simresultplot (
418
406
res:: SimResult{<:PredictiveController} ;
419
407
plotry = true ,
0 commit comments