@@ -445,300 +445,6 @@ function validate_args(mpc::PredictiveController, ry, d, D̂, R̂y, R̂u)
445445 size (R̂u) ≠ (nu* Hp,) && throw (DimensionMismatch (" R̂u size $(size (R̂u)) ≠ manip. input size × Hp ($(nu* Hp) ,)" ))
446446end
447447
448-
449- @doc raw """
450- init_ZtoU(estim, Hp, Hc, transcription) -> S, T
451-
452- Init decision variables to inputs over ``H_p`` conversion matrices.
453-
454- The conversion from the input increments ``\m athbf{ΔU}`` to manipulated inputs over ``H_p``
455- are calculated by:
456- ```math
457- \m athbf{U} = \m athbf{S} \m athbf{Z} + \m athbf{T} \m athbf{u}(k-1)
458- ```
459- The ``\m athbf{S}`` and ``\m athbf{T}`` matrices are defined in the Extended Help section.
460-
461- # Extended Help
462- !!! details "Extended Help"
463- The ``\m athbf{U}`` vector and the conversion matrices are defined as:
464- ```math
465- \m athbf{U} = \b egin{bmatrix}
466- \m athbf{u}(k + 0) \\
467- \m athbf{u}(k + 1) \\
468- \v dots \\
469- \m athbf{u}(k + H_c - 1) \\
470- \v dots \\
471- \m athbf{u}(k + H_p - 1) \e nd{bmatrix} , \q uad
472- \m athbf{S^†} = \b egin{bmatrix}
473- \m athbf{I} & \m athbf{0} & \c dots & \m athbf{0} \\
474- \m athbf{I} & \m athbf{I} & \c dots & \m athbf{0} \\
475- \v dots & \v dots & \d dots & \v dots \\
476- \m athbf{I} & \m athbf{I} & \c dots & \m athbf{I} \\
477- \v dots & \v dots & \d dots & \v dots \\
478- \m athbf{I} & \m athbf{I} & \c dots & \m athbf{I} \e nd{bmatrix} , \q uad
479- \m athbf{T} = \b egin{bmatrix}
480- \m athbf{I} \\
481- \m athbf{I} \\
482- \v dots \\
483- \m athbf{I} \\
484- \v dots \\
485- \m athbf{I} \e nd{bmatrix}
486- ```
487- and, depending on the transcription method, we have:
488- - ``\m athbf{S} = \m athbf{S^†}`` if `transcription == :singleshooting`
489- - ``\m athbf{S} = [\b egin{smallmatrix}\m athbf{S^†} \m athbf{0} \e nd{smallmatrix}]`` if
490- `transcription == :multipleshooting`
491- """
492- function init_ZtoU (estim:: StateEstimator{NT} , Hp, Hc, transcription) where {NT<: Real }
493- model = estim. model
494- # S and T are `Matrix{NT}` since conversion is faster than `Matrix{Bool}` or `BitMatrix`
495- I_nu = Matrix {NT} (I, model. nu, model. nu)
496- S_Hc = LowerTriangular (repeat (I_nu, Hc, Hc))
497- if transcription == :singleshooting
498- O = zeros (NT, model. nu* Hp, 0 )
499- elseif transcription == :multipleshooting
500- O = zeros (NT, model. nu* Hp, estim. nx̂* Hp)
501- else
502- throw (ArgumentError (" transcription method not recognized" ))
503- end
504- S = hcat ([S_Hc; repeat (I_nu, Hp - Hc, Hc)], O)
505- T = repeat (I_nu, Hp)
506- return S, T
507- end
508-
509-
510- @doc raw """
511- init_predmat(
512- estim, model::LinModel, Hp, Hc, transcription
513- ) -> E, G, J, K, V, ex̂, gx̂, jx̂, kx̂, vx̂
514-
515- Construct the prediction matrices for [`LinModel`](@ref) `model`.
516-
517- The model predictions are evaluated from the deviation vectors (see [`setop!`](@ref)) and:
518- ```math
519- \b egin{aligned}
520- \m athbf{Ŷ_0} &= \m athbf{E Z} + \m athbf{G d_0}(k) + \m athbf{J D̂_0}
521- + \m athbf{K x̂_0}(k) + \m athbf{V u_0}(k-1)
522- + \m athbf{B} + \m athbf{Ŷ_s} \\
523- &= \m athbf{E Z} + \m athbf{F}
524- \e nd{aligned}
525- ```
526- in which ``\m athbf{x̂_0}(k) = \m athbf{x̂}_i(k) - \m athbf{x̂_{op}}``, with ``i = k`` if
527- `estim.direct==true`, otherwise ``i = k - 1``. The predicted outputs ``\m athbf{Ŷ_0}`` and
528- measured disturbances ``\m athbf{D̂_0}`` respectively include ``\m athbf{ŷ_0}(k+j)`` and
529- ``\m athbf{d̂_0}(k+j)`` values with ``j=1`` to ``H_p``, and input increments ``\m athbf{ΔU}``,
530- ``\m athbf{Δu}(k+j)`` from ``j=0`` to ``H_c-1``. The vector ``\m athbf{B}`` contains the
531- contribution for non-zero state ``\m athbf{x̂_{op}}`` and state update ``\m athbf{f̂_{op}}``
532- operating points (for linearization at non-equilibrium point, see [`linearize`](@ref)). The
533- stochastic predictions ``\m athbf{Ŷ_s=0}`` if `estim` is not a [`InternalModel`](@ref), see
534- [`init_stochpred`](@ref). The method also computes similar matrices for the predicted
535- terminal states at ``k+H_p``:
536- ```math
537- \b egin{aligned}
538- \m athbf{x̂_0}(k+H_p) &= \m athbf{e_x̂ Z} + \m athbf{g_x̂ d_0}(k) + \m athbf{j_x̂ D̂_0}
539- + \m athbf{k_x̂ x̂_0}(k) + \m athbf{v_x̂ u_0}(k-1)
540- + \m athbf{b_x̂} \\
541- &= \m athbf{e_x̂ Z} + \m athbf{f_x̂}
542- \e nd{aligned}
543- ```
544- The matrices ``\m athbf{E, G, J, K, V, B, e_x̂, g_x̂, j_x̂, k_x̂, v_x̂, b_x̂}`` are defined in the
545- Extended Help section. The ``\m athbf{F}`` and ``\m athbf{f_x̂}`` vectors are recalculated at
546- each control period ``k``, see [`initpred!`](@ref) and [`linconstraint!`](@ref).
547-
548- # Extended Help
549- !!! details "Extended Help"
550- Using the augmented matrices ``\m athbf{Â, B̂_u, Ĉ, B̂_d, D̂_d}`` in `estim` (see
551- [`augment_model`](@ref)), and the function ``\m athbf{W}(j) = ∑_{i=0}^j \m athbf{Â}^i``,
552- the prediction matrices are computed by :
553- ```math
554- \b egin{aligned}
555- \m athbf{E} &= \b egin{bmatrix}
556- \m athbf{Ĉ W}(0)\m athbf{B̂_u} & \m athbf{0} & \c dots & \m athbf{0} \\
557- \m athbf{Ĉ W}(1)\m athbf{B̂_u} & \m athbf{Ĉ W}(0)\m athbf{B̂_u} & \c dots & \m athbf{0} \\
558- \v dots & \v dots & \d dots & \v dots \\
559- \m athbf{Ĉ W}(H_p-1)\m athbf{B̂_u} & \m athbf{Ĉ W}(H_p-2)\m athbf{B̂_u} & \c dots & \m athbf{Ĉ W}(H_p-H_c+1)\m athbf{B̂_u} \e nd{bmatrix} \\
560- \m athbf{G} &= \b egin{bmatrix}
561- \m athbf{Ĉ}\m athbf{Â}^{0} \m athbf{B̂_d} \\
562- \m athbf{Ĉ}\m athbf{Â}^{1} \m athbf{B̂_d} \\
563- \v dots \\
564- \m athbf{Ĉ}\m athbf{Â}^{H_p-1} \m athbf{B̂_d} \e nd{bmatrix} \\
565- \m athbf{J} &= \b egin{bmatrix}
566- \m athbf{D̂_d} & \m athbf{0} & \c dots & \m athbf{0} \\
567- \m athbf{Ĉ}\m athbf{Â}^{0} \m athbf{B̂_d} & \m athbf{D̂_d} & \c dots & \m athbf{0} \\
568- \v dots & \v dots & \d dots & \v dots \\
569- \m athbf{Ĉ}\m athbf{Â}^{H_p-2} \m athbf{B̂_d} & \m athbf{Ĉ}\m athbf{Â}^{H_p-3} \m athbf{B̂_d} & \c dots & \m athbf{D̂_d} \e nd{bmatrix} \\
570- \m athbf{K} &= \b egin{bmatrix}
571- \m athbf{Ĉ}\m athbf{Â}^{1} \\
572- \m athbf{Ĉ}\m athbf{Â}^{2} \\
573- \v dots \\
574- \m athbf{Ĉ}\m athbf{Â}^{H_p} \e nd{bmatrix} \\
575- \m athbf{V} &= \b egin{bmatrix}
576- \m athbf{Ĉ W}(0)\m athbf{B̂_u} \\
577- \m athbf{Ĉ W}(1)\m athbf{B̂_u} \\
578- \v dots \\
579- \m athbf{Ĉ W}(H_p-1)\m athbf{B̂_u} \e nd{bmatrix} \\
580- \m athbf{B} &= \b egin{bmatrix}
581- \m athbf{Ĉ W}(0) \\
582- \m athbf{Ĉ W}(1) \\
583- \v dots \\
584- \m athbf{Ĉ W}(H_p-1) \e nd{bmatrix} \m athbf{\b ig(f̂_{op} - x̂_{op}\b ig)}
585- \e nd{aligned}
586- ```
587- For the terminal constraints, the matrices are computed with:
588- ```math
589- \b egin{aligned}
590- \m athbf{e_x̂} &= \b egin{bmatrix}
591- \m athbf{W}(H_p-1)\m athbf{B̂_u} &
592- \m athbf{W}(H_p-2)\m athbf{B̂_u} &
593- \c dots &
594- \m athbf{W}(H_p-H_c+1)\m athbf{B̂_u} \e nd{bmatrix} \\
595- \m athbf{g_x̂} &= \m athbf{Â}^{H_p-1} \m athbf{B̂_d} \\
596- \m athbf{j_x̂} &= \b egin{bmatrix}
597- \m athbf{Â}^{H_p-2} \m athbf{B̂_d} &
598- \m athbf{Â}^{H_p-3} \m athbf{B̂_d} &
599- \c dots &
600- \m athbf{0}
601- \e nd{bmatrix} \\
602- \m athbf{k_x̂} &= \m athbf{Â}^{H_p} \\
603- \m athbf{v_x̂} &= \m athbf{W}(H_p-1)\m athbf{B̂_u} \\
604- \m athbf{b_x̂} &= \m athbf{W}(H_p-1) \m athbf{\b ig(f̂_{op} - x̂_{op}\b ig)}
605- \e nd{aligned}
606- ```
607- """
608- function init_predmat (
609- estim:: StateEstimator{NT} , model:: LinModel , Hp, Hc, transcription
610- ) where {NT<: Real }
611- Â, B̂u, Ĉ, B̂d, D̂d = estim. Â, estim. B̂u, estim. Ĉ, estim. B̂d, estim. D̂d
612- nu, nx̂, ny, nd = model. nu, estim. nx̂, model. ny, model. nd
613- # --- pre-compute matrix powers ---
614- # Apow 3D array : Apow[:,:,1] = A^0, Apow[:,:,2] = A^1, ... , Apow[:,:,Hp+1] = A^Hp
615- Âpow = Array {NT} (undef, nx̂, nx̂, Hp+ 1 )
616- Âpow[:,:,1 ] = I (nx̂)
617- for j= 2 : Hp+ 1
618- Âpow[:,:,j] = @views Âpow[:,:,j- 1 ]* Â
619- end
620- # Apow_csum 3D array : Apow_csum[:,:,1] = A^0, Apow_csum[:,:,2] = A^1 + A^0, ...
621- Âpow_csum = cumsum (Âpow, dims= 3 )
622- # helper function to improve code clarity and be similar to eqs. in docstring:
623- getpower (array3D, power) = @views array3D[:,:, power+ 1 ]
624- # --- state estimates x̂ ---
625- kx̂ = getpower (Âpow, Hp)
626- K = Matrix {NT} (undef, Hp* ny, nx̂)
627- for j= 1 : Hp
628- iRow = (1 : ny) .+ ny* (j- 1 )
629- K[iRow,:] = Ĉ* getpower (Âpow, j)
630- end
631- # --- manipulated inputs u ---
632- vx̂ = getpower (Âpow_csum, Hp- 1 )* B̂u
633- V = Matrix {NT} (undef, Hp* ny, nu)
634- for j= 1 : Hp
635- iRow = (1 : ny) .+ ny* (j- 1 )
636- V[iRow,:] = Ĉ* getpower (Âpow_csum, j- 1 )* B̂u
637- end
638- ex̂ = Matrix {NT} (undef, nx̂, Hc* nu)
639- E = zeros (NT, Hp* ny, Hc* nu)
640- for j= 1 : Hc # truncated with control horizon
641- iRow = (ny* (j- 1 )+ 1 ): (ny* Hp)
642- iCol = (1 : nu) .+ nu* (j- 1 )
643- E[iRow, iCol] = V[iRow .- ny* (j- 1 ),:]
644- ex̂[: , iCol] = getpower (Âpow_csum, Hp- j)* B̂u
645- end
646- # --- measured disturbances d ---
647- gx̂ = getpower (Âpow, Hp- 1 )* B̂d
648- G = Matrix {NT} (undef, Hp* ny, nd)
649- jx̂ = Matrix {NT} (undef, nx̂, Hp* nd)
650- J = repeatdiag (D̂d, Hp)
651- if nd ≠ 0
652- for j= 1 : Hp
653- iRow = (1 : ny) .+ ny* (j- 1 )
654- G[iRow,:] = Ĉ* getpower (Âpow, j- 1 )* B̂d
655- end
656- for j= 1 : Hp
657- iRow = (ny* j+ 1 ): (ny* Hp)
658- iCol = (1 : nd) .+ nd* (j- 1 )
659- J[iRow, iCol] = G[iRow .- ny* j,:]
660- jx̂[: , iCol] = j < Hp ? getpower (Âpow, Hp- j- 1 )* B̂d : zeros (NT, nx̂, nd)
661- end
662- end
663- # --- state x̂op and state update f̂op operating points ---
664- coef_bx̂ = getpower (Âpow_csum, Hp- 1 )
665- coef_B = Matrix {NT} (undef, ny* Hp, nx̂)
666- for j= 1 : Hp
667- iRow = (1 : ny) .+ ny* (j- 1 )
668- coef_B[iRow,:] = Ĉ* getpower (Âpow_csum, j- 1 )
669- end
670- f̂op_n_x̂op = estim. f̂op - estim. x̂op
671- bx̂ = coef_bx̂ * f̂op_n_x̂op
672- B = coef_B * f̂op_n_x̂op
673- return E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂
674- end
675-
676- " Return empty matrices if `model` is not a [`LinModel`](@ref)"
677- function init_predmat (
678- estim:: StateEstimator{NT} , model:: SimModel , Hp, Hc, transcription
679- ) where {NT<: Real }
680- nu, nx̂, nd = model. nu, estim. nx̂, model. nd
681- E = zeros (NT, 0 , nu* Hc)
682- G = zeros (NT, 0 , nd)
683- J = zeros (NT, 0 , nd* Hp)
684- K = zeros (NT, 0 , nx̂)
685- V = zeros (NT, 0 , nu)
686- B = zeros (NT, 0 )
687- ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = E, G, J, K, V, B
688- return E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂
689- end
690-
691-
692- @doc raw """
693- init_defectmat(estim::StateEstimator, model::LinModel, Hp, Hc, transcription)
694-
695- Init the matrices for computing the defects over the predicted states.
696-
697- An equation similar to the prediction matrices (see
698- [`init_predmat`](@ref)) computes the defects over the predicted states:
699- ```math
700- \b egin{aligned}
701- \m athbf{Ŝ} &= \m athbf{E_ŝ Z} + \m athbf{G_ŝ d_0}(k) + \m athbf{J_ŝ D̂_0}
702- + \m athbf{K_ŝ x̂_0}(k) + \m athbf{V_ŝ u_0}(k-1)
703- + \m athbf{B_ŝ} \\
704- &= \m athbf{E_ŝ Z} + \m athbf{F_ŝ}
705- \e nd{aligned}
706- ```
707- They are forced to be ``\m athbf{Ŝ = 0}`` using the optimization equality constraints. The
708- matrices ``\m athbf{E_ŝ, G_ŝ, J_ŝ, K_ŝ, V_ŝ, B_ŝ}`` are defined in the Extended Help section.
709-
710- # Extended Help
711- !!! details "Extended Help"
712- The matrices are computed by:
713- ```math
714- \b egin{aligned}
715- \m athbf{E_ŝ} &= \b egin{bmatrix}
716- \m athbf{B̂_u} & \m athbf{0} & \c dots & \m athbf{0} & -\m athbf{I} & \m athbf{0} & \c dots & \m athbf{0} \\
717- \m athbf{0} & \m athbf{B̂_u} & \c dots & \m athbf{0} & \m athbf{Â} & -\m athbf{I} & \c dots & \m athbf{0} \\
718- \v dots & \v dots & \d dots & \v dots & \v dots & \v dots & \d dots & \v dots \\
719- \m athbf{0} & \m athbf{0} & \c dots & \m athbf{B̂_u} & \m athbf{0} & \m athbf{0} & \c dots & -\m athbf{I} \e nd{bmatrix} \\
720- \m athbf{G_ŝ} &= \b egin{bmatrix}
721- \m athbf{B̂_d} \\ \m athbf{0} \\ \v dots \\ \m athbf{0} \e nd{bmatrix} \\
722- \m athbf{J_ŝ} &= \b egin{bmatrix}
723- \m athbf{0} & \m athbf{0} & \c dots & \m athbf{0} & \m athbf{0} \\
724- \m athbf{B̂_d} & \m athbf{0} & \c dots & \m athbf{0} & \m athbf{0} \\
725- \v dots & \v dots & \d dots & \v dots & \v dots \\
726- \m athbf{0} & \m athbf{0} & \c dots & \m athbf{B̂_d} & \m athbf{0} \e nd{bmatrix} \\
727- \m athbf{K_ŝ} &= \b egin{bmatrix}
728- \m athbf{Â} \\ \m athbf{0} \\ \v dots \\ \m athbf{0} \e nd{bmatrix} \\
729- \m athbf{V_ŝ} &= \b egin{bmatrix}
730- \m athbf{B̂_u} \\ \m athbf{B̂_u} \\ \v dots \\ \m athbf{B̂_u} \e nd{bmatrix} \\
731- \m athbf{B_ŝ} &= \b egin{bmatrix}
732- \m athbf{f̂_{op} - x̂_{op}} \\ \m athbf{f̂_{op} - x̂_{op}} \\ \v dots \\ \m athbf{f̂_{op} - x̂_{op}} \e nd{bmatrix}
733- \e nd{aligned}
734- ```
735- """
736- function init_defectmat (
737- estim:: StateEstimator{NT} , model:: LinModel , Hp, Hc, transcription
738- ) where {NT<: Real }
739-
740- end
741-
742448@doc raw """
743449 init_quadprog(model::LinModel, weights::ControllerWeights, Ẽ, S) -> H̃
744450
0 commit comments