@@ -26,6 +26,8 @@ const LinConVector = Vector{ConstraintRef{
26
26
ScalarShape
27
27
}}
28
28
29
+ const InfoDictType = Union{Vector{Float64}, Float64}
30
+
29
31
" Include all the data for the constraints of [`PredictiveController`](@ref)"
30
32
struct ControllerConstraint
31
33
Umin :: Vector{Float64}
@@ -249,17 +251,67 @@ function moveinput!(
249
251
R̂y:: Vector{<:Real} = repeat (ry, mpc. Hp),
250
252
D̂ :: Vector{<:Real} = repeat (d, mpc. Hp),
251
253
ym:: Union{Vector{<:Real}, Nothing} = nothing
252
- )
254
+ )
255
+ validate_setpointdist (mpc, ry, d, R̂y, D̂)
253
256
getestimates! (mpc, mpc. estim, ym, d)
254
257
predictstoch! (mpc, mpc. estim, d, ym)
255
- p = initpred! (mpc, mpc. estim. model, d, D̂, R̂y)
258
+ initpred! (mpc, mpc. estim. model, d, D̂, R̂y)
256
259
linconstraint! (mpc, mpc. estim. model)
257
- ΔŨ, _ = optim_objective! (mpc, p )
260
+ ΔŨ = optim_objective! (mpc)
258
261
Δu = ΔŨ[1 : mpc. estim. model. nu] # receding horizon principle: only Δu(k) is used (1st one)
259
262
u = mpc. estim. lastu0 + mpc. estim. model. uop + Δu
260
263
return u
261
264
end
262
265
266
+ #=
267
+
268
+
269
+ "Include the additional information about the optimum to ease troubleshooting."
270
+ mutable struct OptimInfo
271
+ ΔŨ::Vector{Float64}
272
+ ϵ ::Float64
273
+ J ::Float64
274
+ u ::Vector{Float64}
275
+ U ::Vector{Float64}
276
+ ŷ ::Vector{Float64}
277
+ Ŷ ::Vector{Float64}
278
+ ŷs::Vector{Float64}
279
+ Ŷs::Vector{Float64}
280
+ end
281
+ =#
282
+
283
+ #=
284
+ function write_info!(mpc::LinMPC, ΔŨ, J, ŷs, Ŷs)
285
+ mpc.info.ΔŨ = ΔŨ
286
+ mpc.info.ϵ = isinf(mpc.C) ? NaN : ΔŨ[end]
287
+ mpc.info.J = J
288
+ mpc.info.U = mpc.S̃_Hp*ΔŨ + mpc.T_Hp*(mpc.estim.lastu0 + mpc.estim.model.uop)
289
+ mpc.info.u = mpc.info.U[1:mpc.estim.model.nu]
290
+ mpc.info.ŷ = mpc.ŷ
291
+ mpc.info.Ŷ = mpc.Ẽ*ΔŨ + mpc.F
292
+ mpc.info.ŷs, mpc.info.Ŷs = ŷs, Ŷs
293
+ end
294
+ =#
295
+
296
+ function getinfo (mpc:: PredictiveController )
297
+ sol_summary = solution_summary (mpc. optim)
298
+ info = Dict {Symbol, InfoDictType} ()
299
+ info[:ΔU ] = mpc. ΔŨ[1 : mpc. Hc* mpc. estim. model. nu]
300
+ info[:ϵ ] = isinf (mpc. C) ? NaN : mpc. ΔŨ[end ]
301
+ info[:J ] = objective_value (mpc. optim) + mpc. p[begin ]
302
+ info[:U ] = mpc. S̃_Hp* mpc. ΔŨ + mpc. T_Hp* (mpc. estim. lastu0 + mpc. estim. model. uop)
303
+ info[:u ] = info[:U ][1 : mpc. estim. model. nu]
304
+ info[:d ] = mpc. d
305
+ info[:D̂ ] = mpc. D̂
306
+ info[:ŷ ] = mpc. ŷ
307
+ info[:Ŷ ] = predict (mpc, mpc. estim. model, mpc. ΔŨ)
308
+ info[:Ŷs ] = mpc. Ŷs
309
+ info[:Ŷd ] = info[:Ŷ ] - info[:Ŷs ]
310
+ info[:R̂y ] = mpc. R̂y
311
+ info[:R̂u ] = mpc. R̂u
312
+ return info, sol_summary
313
+ end
314
+
263
315
"""
264
316
setstate!(mpc::PredictiveController, x̂)
265
317
@@ -285,6 +337,13 @@ Call [`updatestate!`](@ref) on `mpc.estim` [`StateEstimator`](@ref).
285
337
"""
286
338
updatestate! (mpc:: PredictiveController , u, ym, d= Float64[]) = updatestate! (mpc. estim,u,ym,d)
287
339
340
+ function validate_setpointdist (mpc:: PredictiveController , ry, d, R̂y, D̂)
341
+ ny, nd, Hp = mpc. estim. model. ny, mpc. estim. model. nd, mpc. Hp
342
+ size (ry) ≠ (ny,) && error (" ry size $(size (ry)) ≠ output size ($ny ,)" )
343
+ size (d) ≠ (nd,) && error (" d size $(size (d)) ≠ measured dist. size ($nd ,)" )
344
+ size (R̂y) ≠ (ny* Hp,) && error (" R̂y size $(size (R̂y)) ≠ output size × Hp ($(ny* Hp) ,)" )
345
+ size (D̂) ≠ (nd* Hp,) && error (" D̂ size $(size (D̂)) ≠ measured dist. size × Hp ($(nd* Hp) ,)" )
346
+ end
288
347
289
348
"""
290
349
getestimates!(mpc::PredictiveController, estim::StateEstimator)
@@ -355,14 +414,14 @@ function initpred!(mpc::PredictiveController, model::LinModel, d, D̂, R̂y)
355
414
mpc. R̂y[:] = R̂y
356
415
Ẑ = mpc. F - R̂y
357
416
mpc. q̃[:] = 2 (mpc. M_Hp* mpc. Ẽ)' * Ẑ
358
- p = Ẑ' * mpc. M_Hp* Ẑ
417
+ mpc . p[:] = [ Ẑ' * mpc. M_Hp* Ẑ]
359
418
if ~ isempty (mpc. R̂u)
360
419
lastu = mpc. estim. lastu0 + model. uop
361
420
V̂ = mpc. T_Hp* lastu - mpc. R̂u
362
- mpc. q̃[:] = mpc . q̃ + 2 (mpc. L_Hp* mpc. T_Hp)' * V̂
363
- p += V̂' * mpc. L_Hp* V̂
421
+ mpc. q̃[:] += 2 (mpc. L_Hp* mpc. T_Hp)' * V̂
422
+ mpc . p[:] += [ V̂' * mpc. L_Hp* V̂]
364
423
end
365
- return p
424
+ return nothing
366
425
end
367
426
368
427
@doc raw """
@@ -378,8 +437,7 @@ function initpred!(mpc::PredictiveController, model::SimModel, d, D̂, R̂y)
378
437
mpc. d[:], mpc. D̂[:] = d, D̂
379
438
end
380
439
mpc. R̂y[:] = R̂y
381
- p = 0.0 # only used for LinModel objects
382
- return p
440
+ return nothing
383
441
end
384
442
385
443
"""
448
506
449
507
Optimize the objective function ``J`` of `mpc` controller.
450
508
"""
451
- function optim_objective! (mpc:: PredictiveController , p )
509
+ function optim_objective! (mpc:: PredictiveController )
452
510
optim = mpc. optim
453
511
model = mpc. estim. model
454
512
ΔŨvar:: Vector{VariableRef} = optim[:ΔŨvar ]
@@ -476,8 +534,7 @@ function optim_objective!(mpc::PredictiveController, p)
476
534
@debug solution_summary (optim)
477
535
end
478
536
mpc. ΔŨ[:] = isfatal (status) ? ΔŨ0 : value .(ΔŨvar) # fatal status : use last value
479
- J_val = objective_value (optim) + p # add LinModel p constant (p=0 for NonLinModel)
480
- return mpc. ΔŨ, J_val
537
+ return mpc. ΔŨ
481
538
end
482
539
483
540
" By default, no change to the objective function."
@@ -653,14 +710,16 @@ useless at optimization but required to evaluate the minimal ``J`` value.
653
710
"""
654
711
function init_quadprog (:: LinModel , Ẽ, S_Hp, M_Hp, N_Hc, L_Hp)
655
712
P̃ = 2 * Hermitian (Ẽ' * M_Hp* Ẽ + N_Hc + S_Hp' * L_Hp* S_Hp)
656
- q̃ = zeros (size (P̃, 1 )) # dummy value (updated just before optimization)
657
- return P̃, q̃
713
+ q̃ = zeros (size (P̃, 1 )) # dummy value (updated just before optimization)
714
+ p = zeros (1 ) # dummy value (updated just before optimization)
715
+ return P̃, q̃, p
658
716
end
659
717
" Return empty matrices if `model` is not a [`LinModel`](@ref)."
660
718
function init_quadprog (:: SimModel , Ẽ, S_Hp, M_Hp, N_Hc, L_Hp)
661
719
P̃ = Hermitian (zeros (0 , 0 ))
662
720
q̃ = zeros (0 )
663
- return P̃, q̃
721
+ p = zeros (1 ) # dummy value (updated just before optimization)
722
+ return P̃, q̃, p
664
723
end
665
724
666
725
" Return the quadratic programming objective function, see [`init_quadprog`](@ref)."
0 commit comments