11" Includes all signals of [`sim!`](@ref), view them with `plot` on `SimResult` instances."
22struct SimResult{O<: Union{SimModel, StateEstimator, PredictiveController} }
3- T_data :: Vector{Float64} # time in seconds
4- Y_data :: Matrix{Float64} # plant outputs (both measured and unmeasured)
5- Ry_data:: Matrix{Float64} # output setpoints
6- Ŷ_data :: Matrix{Float64} # estimated outputs
7- U_data :: Matrix{Float64} # manipulated inputs
8- Ud_data:: Matrix{Float64} # manipulated inputs including load disturbances
9- D_data :: Matrix{Float64} # measured disturbances
10- X_data :: Matrix{Float64} # plant states
11- X̂_data :: Matrix{Float64} # estimated states
12- obj :: O # simulated instance
3+ T_data :: Vector{Float64} # time in seconds
4+ Y_data :: Matrix{Float64} # plant outputs (both measured and unmeasured)
5+ Ry_data:: Matrix{Float64} # output setpoints
6+ Ŷ_data :: Matrix{Float64} # estimated outputs
7+ U_data :: Matrix{Float64} # manipulated inputs
8+ Ud_data:: Matrix{Float64} # manipulated inputs including load disturbances
9+ D_data :: Matrix{Float64} # measured disturbances
10+ X_data :: Matrix{Float64} # plant states
11+ X̂_data :: Matrix{Float64} # estimated states
12+ plantIsModel:: Bool # true if simulated plant is identical to estimation model
13+ obj:: O # simulated instance
1314end
1415
1516@doc raw """
@@ -55,7 +56,7 @@ 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, U_data, U_data, D_data, X_data, X_data, true , plant
5960 )
6061end
6162
@@ -96,7 +97,7 @@ vectors. The simulated sensor and process noises of `plant` are specified by `y_
9697```julia-repl
9798julia> model = LinModel(tf(3, [30, 1]), 0.5);
9899
99- julia> estim = SteadyKalmanFilter (model, σR=[0.5], σQ=[0.25], σQ_int=[0.01]);
100+ julia> estim = KalmanFilter (model, σR=[0.5], σQ=[0.25], σQ_int=[0.01], σP0_int=[0.1 ]);
100101
101102julia> res = sim!(estim, 50, [0], y_noise=[0.5], x_noise=[0.25], x0=[-10], x̂0=[0, 0]);
102103
@@ -170,6 +171,7 @@ function sim_closedloop!(
170171 lastu = plant. uop,
171172)
172173 model = estim. model
174+ plantIsModel = (plant === model)
173175 model. Ts ≈ plant. Ts || error (" Sampling time of controller/estimator ≠ plant.Ts" )
174176 old_x0 = copy (plant. x)
175177 T_data = collect (plant. Ts* (0 : (N- 1 )))
@@ -207,7 +209,9 @@ function sim_closedloop!(
207209 updatestate! (est_mpc, u, ym, d)
208210 end
209211 res = SimResult (
210- T_data, Y_data, U_Ry_data, Ŷ_data, U_data, Ud_data, D_data, X_data, X̂_data, est_mpc
212+ T_data, Y_data, U_Ry_data, Ŷ_data,
213+ U_data, Ud_data, D_data, X_data, X̂_data,
214+ plantIsModel, est_mpc
211215 )
212216 setstate! (plant, old_x0)
213217 return res
304308 plotx̂ = false
305309)
306310 t = res. T_data
311+ plantIsModel = res. plantIsModel
307312 ny = size (res. Y_data, 1 )
308313 nu = size (res. U_data, 1 )
309314 nd = size (res. D_data, 1 )
312317 layout_mat = [(ny, 1 )]
313318 plotu && (layout_mat = [layout_mat (nu, 1 )])
314319 (plotd && nd ≠ 0 ) && (layout_mat = [layout_mat (nd, 1 )])
315- plotx && (layout_mat = [layout_mat (nx, 1 )])
316- plotx̂ && (layout_mat = [layout_mat (nx̂, 1 )])
320+ if plantIsModel && plotx && ! plotx̂
321+ layout_mat = [layout_mat (nx, 1 )]
322+ elseif plantIsModel && plotx̂
323+ layout_mat = [layout_mat (nx̂, 1 )]
324+ elseif ! plantIsModel
325+ plotx && (layout_mat = [layout_mat (nx, 1 )])
326+ plotx̂ && (layout_mat = [layout_mat (nx̂, 1 )])
327+ end
317328 layout := layout_mat
318329 xguide --> " Time (s)"
319330 # --- outputs y ---
369380 t, res. D_data[i, :]
370381 end
371382 end
383+ subplot_base += nd
372384 end
373385 # --- plant states x ---
374386 if plotx
@@ -382,19 +394,20 @@ end
382394 t, res. X_data[i, :]
383395 end
384396 end
385- subplot_base += nx
397+ ! plantIsModel && ( subplot_base += nx)
386398 end
387399 # --- estimated states x̂ ---
388400 if plotx̂
389401 for i in 1 : nx̂
390402 @series begin
391- yguide --> " \$\\ hat{x}_$i \$ "
403+ withPlantState = plantIsModel && plotx && i ≤ nx
404+ yguide --> (withPlantState ? " \$ x_$i \$ " : " \$\\ hat{x}_$i \$ " )
392405 color --> 2
393406 subplot --> subplot_base + i
394407 linestyle --> :dashdot
395408 linewidth --> 0.75
396409 label --> " \$\\ mathbf{\\ hat{x}}\$ "
397- legend --> false
410+ legend --> (withPlantState ? true : false )
398411 t, res. X̂_data[i, :]
399412 end
400413 end
417430 plotx̂ = false
418431)
419432 mpc = res. obj
420-
421433 t = res. T_data
434+ plantIsModel = res. plantIsModel
422435 ny = size (res. Y_data, 1 )
423436 nu = size (res. U_data, 1 )
424437 nd = size (res. D_data, 1 )
@@ -427,12 +440,16 @@ end
427440 layout_mat = [(ny, 1 )]
428441 plotu && (layout_mat = [layout_mat (nu, 1 )])
429442 (plotd && nd ≠ 0 ) && (layout_mat = [layout_mat (nd, 1 )])
430- plotx && (layout_mat = [layout_mat (nx, 1 )])
431- plotx̂ && (layout_mat = [layout_mat (nx̂, 1 )])
432-
443+ if plantIsModel && plotx && ! plotx̂
444+ layout_mat = [layout_mat (nx, 1 )]
445+ elseif plantIsModel && plotx̂
446+ layout_mat = [layout_mat (nx̂, 1 )]
447+ elseif ! plantIsModel
448+ plotx && (layout_mat = [layout_mat (nx, 1 )])
449+ plotx̂ && (layout_mat = [layout_mat (nx̂, 1 )])
450+ end
433451 layout := layout_mat
434452 xguide --> " Time (s)"
435-
436453 # --- outputs y ---
437454 subplot_base = 0
438455 for i in 1 : ny
475492 color --> 4
476493 subplot --> subplot_base + i
477494 linestyle --> :dot
478- linewidth --> 2.0
495+ linewidth --> 1.5
479496 label --> " \$\\ mathbf{\\ hat{y}_{min}}\$ "
480497 legend --> true
481498 t, fill (mpc. con. Ŷmin[i], length (t))
487504 color --> 5
488505 subplot --> subplot_base + i
489506 linestyle --> :dot
490- linewidth --> 2.0
507+ linewidth --> 1.5
491508 label --> " \$\\ mathbf{\\ hat{y}_{max}}\$ "
492509 legend --> true
493510 t, fill (mpc. con. Ŷmax[i], length (t))
525542 color --> 4
526543 subplot --> subplot_base + i
527544 linestyle --> :dot
528- linewidth --> 2.0
545+ linewidth --> 1.5
529546 label --> " \$\\ mathbf{u_{min}}\$ "
530547 legend --> true
531548 t, fill (mpc. con. Umin[i], length (t))
537554 color --> 5
538555 subplot --> subplot_base + i
539556 linestyle --> :dot
540- linewidth --> 2.0
557+ linewidth --> 1.5
541558 label --> " \$\\ mathbf{u_{max}}\$ "
542559 legend --> true
543560 t, fill (mpc. con. Umax[i], length (t))
559576 t, res. D_data[i, :]
560577 end
561578 end
579+ subplot_base += nd
562580 end
563581 # --- plant states x ---
564582 if plotx
@@ -572,19 +590,20 @@ end
572590 t, res. X_data[i, :]
573591 end
574592 end
575- subplot_base += nx
593+ ! plantIsModel && ( subplot_base += nx)
576594 end
577595 # --- estimated states x̂ ---
578596 if plotx̂
579597 for i in 1 : nx̂
580598 @series begin
581- yguide --> " \$\\ hat{x}_$i \$ "
599+ withPlantState = plantIsModel && plotx && i ≤ nx
600+ yguide --> (withPlantState ? " \$ x_$i \$ " : " \$\\ hat{x}_$i \$ " )
582601 color --> 2
583602 subplot --> subplot_base + i
584603 linestyle --> :dashdot
585604 linewidth --> 0.75
586605 label --> " \$\\ mathbf{\\ hat{x}}\$ "
587- legend --> false
606+ legend --> (withPlantState ? true : false )
588607 t, res. X̂_data[i, :]
589608 end
590609 end
0 commit comments