Skip to content

Commit 0f95475

Browse files
committed
wip: multiple shooting method
1 parent b42e6ab commit 0f95475

File tree

6 files changed

+90
-64
lines changed

6 files changed

+90
-64
lines changed

src/controller/construct.jl

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ function setconstraint!(
340340
i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax,
341341
i_Ymin, i_Ymax, i_x̂min, i_x̂max,
342342
con.A_Umin, con.A_Umax, con.A_ΔŨmin, con.A_ΔŨmax,
343-
con.A_Ymin, con.A_Ymax, con.A_x̂min, con.A_x̂max
343+
con.A_Ymin, con.A_Ymax, con.A_x̂min, con.A_x̂max,
344+
con.A_ŝ
344345
)
345346
A = con.A[con.i_b, :]
346347
b = con.b[con.i_b]
@@ -368,23 +369,25 @@ end
368369
model::LinModel, nc::Int,
369370
i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
370371
args...
371-
) -> i_b, i_g, A
372+
) -> i_b, i_g, A, Aeq
372373
373-
Init `i_b`, `i_g` and `A` matrices for the linear and nonlinear inequality constraints.
374+
Init `i_b`, `i_g`, `A` and `Aeq` matrices for the linear and nonlinear constraints.
374375
375-
The linear and nonlinear inequality constraints are respectively defined as:
376+
The linear and nonlinear constraints are respectively defined as:
376377
```math
377378
\begin{aligned}
378-
\mathbf{A ΔŨ } &≤ \mathbf{b} \\
379-
\mathbf{g(ΔŨ)} &≤ \mathbf{0}
379+
\mathbf{A Z̃ } &≤ \mathbf{b} \\
380+
\mathbf{A_{eq} Z̃} &= \mathbf{b_{eq}} \\
381+
\mathbf{g(Z̃)} &≤ \mathbf{0} \\
382+
\mathbf{g_{eq}(Z̃)} &= \mathbf{0} \\
380383
\end{aligned}
381384
```
382-
The argument `nc` is the number of custom nonlinear constraints in ``\mathbf{g_c}``. `i_b`
383-
is a `BitVector` including the indices of ``\mathbf{b}`` that are finite numbers. `i_g` is a
384-
similar vector but for the indices of ``\mathbf{g}``. The method also returns the
385-
``\mathbf{A}`` matrix if `args` is provided. In such a case, `args` needs to contain all
386-
the inequality constraint matrices:
387-
`A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max`.
385+
The argument `nc` is the number of custom nonlinear inequality constraints in
386+
``\mathbf{g_c}``. `i_b` is a `BitVector` including the indices of ``\mathbf{b}`` that are
387+
finite numbers. `i_g` is a similar vector but for the indices of ``\mathbf{g}``. The method
388+
also returns the ``\mathbf{A, A_{eq}}`` matrices if `args` is provided. In such a case,
389+
`args` needs to contain all the inequality and equality constraint matrices:
390+
`A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ`.
388391
"""
389392
function init_matconstraint_mpc(
390393
::LinModel{NT}, nc::Int,
@@ -394,12 +397,13 @@ function init_matconstraint_mpc(
394397
i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax; i_Ymin; i_Ymax; i_x̂min; i_x̂max]
395398
i_g = trues(nc)
396399
if isempty(args)
397-
A = nothing
400+
A, Aeq = nothing, nothing
398401
else
399-
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max = args
400-
A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
402+
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
403+
A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
404+
Aeq = A_ŝ
401405
end
402-
return i_b, i_g, A
406+
return i_b, i_g, A, Aeq
403407
end
404408

405409
"Init `i_b, A` without outputs and terminal constraints if `model` is not a [`LinModel`](@ref)."
@@ -411,12 +415,13 @@ function init_matconstraint_mpc(
411415
i_b = [i_Umin; i_Umax; i_ΔŨmin; i_ΔŨmax]
412416
i_g = [i_Ymin; i_Ymax; i_x̂min; i_x̂max; trues(nc)]
413417
if isempty(args)
414-
A = nothing
418+
A, Aeq = nothing, nothing
415419
else
416-
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, _ , _ , _ , _ = args
417-
A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax]
420+
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂min, A_x̂max, A_ŝ = args
421+
A = [A_Umin; A_Umax; A_ΔŨmin; A_ΔŨmax; A_Ymin; A_Ymax; A_x̂min; A_x̂max]
422+
Aeq = A_ŝ
418423
end
419-
return i_b, i_g, A
424+
return i_b, i_g, A, Aeq
420425
end
421426

422427
"By default, there is no nonlinear constraint, thus do nothing."
@@ -541,12 +546,14 @@ function init_defaultcon_mpc(
541546
i_ΔŨmin, i_ΔŨmax = .!isinf.(ΔŨmin), .!isinf.(ΔŨmax)
542547
i_Ymin, i_Ymax = .!isinf.(Y0min), .!isinf.(Y0max)
543548
i_x̂min, i_x̂max = .!isinf.(x̂0min), .!isinf.(x̂0max)
544-
i_b, i_g, A = init_matconstraint_mpc(
549+
i_b, i_g, A, Aeq = init_matconstraint_mpc(
545550
model, nc,
546551
i_Umin, i_Umax, i_ΔŨmin, i_ΔŨmax, i_Ymin, i_Ymax, i_x̂min, i_x̂max,
547-
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂max, A_x̂min
552+
A_Umin, A_Umax, A_ΔŨmin, A_ΔŨmax, A_Ymin, A_Ymax, A_x̂max, A_x̂min,
553+
A_ŝ
548554
)
549-
b = zeros(NT, size(A, 1)) # dummy b vector (updated just before optimization)
555+
# dummy b and beq vectors (updated just before optimization)
556+
b, beq = zeros(NT, size(A, 1)), zeros(NT, size(Aeq, 1))
550557
con = ControllerConstraint{NT, GCfunc}(
551558
ẽx̂ , fx̂ , gx̂ , jx̂ , kx̂ , vx̂ , bx̂ ,
552559
Ẽŝ , Fŝ , Gŝ , Jŝ , Kŝ , Vŝ , Bŝ ,
@@ -620,8 +627,10 @@ Augment input increments constraints with slack variable ϵ for softening.
620627
Denoting the decision variables augmented with the slack variable
621628
``\mathbf{Z̃} = [\begin{smallmatrix} \mathbf{Z} \\ ϵ \end{smallmatrix}]``, it returns the
622629
augmented conversion matrix ``\mathbf{P̃}``, similar to the one described at
623-
[`init_ZtoΔU`](@ref). It also returns the augmented constraints ``\mathbf{ΔŨ_{min}}`` and
624-
``\mathbf{ΔŨ_{max}}`` and the ``\mathbf{A}`` matrices for the inequality constraints:
630+
[`init_ZtoΔU`](@ref). Knowing that ``0 ≤ ϵ ≤ ∞``, it also returns the augmented bounds
631+
``\mathbf{ΔŨ_{min}} = [\begin{smallmatrix} \mathbf{ΔU_{min}} \\ 0 \end{smallmatrix}]`` and
632+
``\mathbf{ΔŨ_{max}} = [\begin{smallmatrix} \mathbf{ΔU_{min}} \\\end{smallmatrix}]``,
633+
and the ``\mathbf{A}`` matrices for the inequality constraints:
625634
```math
626635
\begin{bmatrix}
627636
\mathbf{A_{ΔŨ_{min}}} \\
@@ -632,20 +641,21 @@ augmented conversion matrix ``\mathbf{P̃}``, similar to the one described at
632641
+ \mathbf{ΔŨ_{max}}
633642
\end{bmatrix}
634643
```
644+
Note that strictly speaking, the lower bound on the slack variable ϵ is a decision variable
645+
bound, which is more specific than a linear inequality constraint. However, it is more
646+
convenient to treat it as a linear inequality constraint since the optimizer `OSQP.jl` does
647+
not support pure bounds on the decision variables.
635648
"""
636649
function relaxΔU(::SimModel{NT}, nϵ, C_Δumin, C_Δumax, ΔUmin, ΔUmax, P) where NT<:Real
637-
nΔU = length(ΔUmin)
638650
nZ = size(P, 2)
639651
if== 1 # Z̃ = [Z; ϵ]
640-
# 0 ≤ ϵ ≤ ∞
641-
ΔŨmin, ΔŨmax = [ΔUmin; NT[0.0]], [ΔUmax; NT[Inf]]
642-
A_ϵ = [zeros(NT, 1, nΔU) NT[1.0]]
643-
A_ΔŨmin, A_ΔŨmax = -[I C_Δumin; A_ϵ], [I -C_Δumax; A_ϵ]
652+
ΔŨmin, ΔŨmax = [ΔUmin; NT[0.0]], [ΔUmax; NT[Inf]] # 0 ≤ ϵ ≤ ∞
653+
A_ϵ = [zeros(NT, 1, nZ) NT[1.0]]
654+
A_ΔŨmin, A_ΔŨmax = -[P C_Δumin; A_ϵ], [P -C_Δumax; A_ϵ]
644655
= [P zeros(NT, size(P, 1), 1)]
645656
else # Z̃ = Z (only hard constraints)
646657
ΔŨmin, ΔŨmax = ΔUmin, ΔUmax
647-
I_Hc = Matrix{NT}(I, nΔU, nΔU)
648-
A_ΔŨmin, A_ΔŨmax = -I_Hc, I_Hc
658+
A_ΔŨmin, A_ΔŨmax = -P, P
649659
= P
650660
end
651661
return A_ΔŨmin, A_ΔŨmax, ΔŨmin, ΔŨmax, P̃
@@ -656,15 +666,15 @@ end
656666
657667
Augment linear output prediction constraints with slack variable ϵ for softening.
658668
659-
Denoting the input increments augmented with the slack variable
660-
``\mathbf{ΔŨ} = [\begin{smallmatrix} \mathbf{ΔU} \\ ϵ \end{smallmatrix}]``, it returns the
669+
Denoting the decision variables augmented with the slack variable
670+
``\mathbf{} = [\begin{smallmatrix} \mathbf{Z} \\ ϵ \end{smallmatrix}]``, it returns the
661671
``\mathbf{Ẽ}`` matrix that appears in the linear model prediction equation
662-
``\mathbf{Ŷ_0 = Ẽ ΔŨ + F}``, and the ``\mathbf{A}`` matrices for the inequality constraints:
672+
``\mathbf{Ŷ_0 = Ẽ + F}``, and the ``\mathbf{A}`` matrices for the inequality constraints:
663673
```math
664674
\begin{bmatrix}
665675
\mathbf{A_{Y_{min}}} \\
666676
\mathbf{A_{Y_{max}}}
667-
\end{bmatrix} \mathbf{ΔŨ} ≤
677+
\end{bmatrix} \mathbf{} ≤
668678
\begin{bmatrix}
669679
- \mathbf{(Y_{min} - Y_{op}) + F} \\
670680
+ \mathbf{(Y_{max} - Y_{op}) - F}
@@ -674,12 +684,12 @@ in which ``\mathbf{Y_{min}, Y_{max}}`` and ``\mathbf{Y_{op}}`` vectors respectiv
674684
``\mathbf{y_{min}, y_{max}}`` and ``\mathbf{y_{op}}`` repeated ``H_p`` times.
675685
"""
676686
function relaxŶ(::LinModel{NT}, nϵ, C_ymin, C_ymax, E) where NT<:Real
677-
if== 1 # ΔŨ = [ΔU; ϵ]
687+
if== 1 # = [Z; ϵ]
678688
# ϵ impacts predicted output constraint calculations:
679689
A_Ymin, A_Ymax = -[E C_ymin], [E -C_ymax]
680690
# ϵ has no impact on output predictions:
681691
= [E zeros(NT, size(E, 1), 1)]
682-
else # ΔŨ = ΔU (only hard constraints)
692+
else # = Z (only hard constraints)
683693
= E
684694
A_Ymin, A_Ymax = -E, E
685695
end
@@ -698,29 +708,29 @@ end
698708
699709
Augment terminal state constraints with slack variable ϵ for softening.
700710
701-
Denoting the input increments augmented with the slack variable
702-
``\mathbf{ΔŨ} = [\begin{smallmatrix} \mathbf{ΔU} \\ ϵ \end{smallmatrix}]``, it returns the
711+
Denoting the decision variables augmented with the slack variable
712+
``\mathbf{} = [\begin{smallmatrix} \mathbf{Z} \\ ϵ \end{smallmatrix}]``, it returns the
703713
``\mathbf{ẽ_{x̂}}`` matrix that appears in the terminal state equation
704-
``\mathbf{x̂_0}(k + H_p) = \mathbf{ẽ_x̂ ΔŨ + f_x̂}``, and the ``\mathbf{A}`` matrices for
714+
``\mathbf{x̂_0}(k + H_p) = \mathbf{ẽ_x̂ + f_x̂}``, and the ``\mathbf{A}`` matrices for
705715
the inequality constraints:
706716
```math
707717
\begin{bmatrix}
708718
\mathbf{A_{x̂_{min}}} \\
709719
\mathbf{A_{x̂_{max}}}
710-
\end{bmatrix} \mathbf{ΔŨ} ≤
720+
\end{bmatrix} \mathbf{} ≤
711721
\begin{bmatrix}
712722
- \mathbf{(x̂_{min} - x̂_{op}) + f_x̂} \\
713723
+ \mathbf{(x̂_{max} - x̂_{op}) - f_x̂}
714724
\end{bmatrix}
715725
```
716726
"""
717727
function relaxterminal(::LinModel{NT}, nϵ, c_x̂min, c_x̂max, ex̂) where {NT<:Real}
718-
if== 1 # ΔŨ = [ΔU; ϵ]
728+
if== 1 # = [Z; ϵ]
719729
# ϵ impacts terminal state constraint calculations:
720730
A_x̂min, A_x̂max = -[ex̂ c_x̂min], [ex̂ -c_x̂max]
721731
# ϵ has no impact on terminal state predictions:
722732
ẽx̂ = [ex̂ zeros(NT, size(ex̂, 1), 1)]
723-
else # ΔŨ = ΔU (only hard constraints)
733+
else # = Z (only hard constraints)
724734
ẽx̂ = ex̂
725735
A_x̂min, A_x̂max = -ex̂, ex̂
726736
end
@@ -734,15 +744,21 @@ function relaxterminal(::SimModel{NT}, nϵ, c_x̂min, c_x̂max, ex̂) where {NT<
734744
return A_x̂min, A_x̂max, ẽx̂
735745
end
736746

737-
"""
747+
@doc raw"""
738748
augmentdefect(::LinModel{NT}, nϵ, Eŝ) where NT<:Real
739749
740750
Augment defect equality constraints with slack variable ϵ if `nϵ == 1`.
751+
752+
It returns the ``\mathbf{Ẽŝ}`` matrix that appears in the defect equation
753+
``\mathbf{Ŝ = Ẽ_ŝ Z̃ + F_ŝ}`` and the ``\mathbf{A}`` matrix for the equality constraints:
754+
```math
755+
\mathbf{A_ŝ Z̃} = - \mathbf{F_ŝ}
756+
```
741757
"""
742758
function augmentdefect(::LinModel{NT}, nϵ, Eŝ) where NT<:Real
743-
if== 1 # ΔŨ = [ΔU; ϵ]
759+
if== 1 # = [Z; ϵ]
744760
Ẽŝ = [Eŝ zeros(NT, size(Eŝ, 1), 1)]
745-
else # ΔŨ = ΔU (only hard constraints)
761+
else # = Z (only hard constraints)
746762
Ẽŝ = Eŝ
747763
end
748764
A_ŝ = Ẽŝ

src/controller/explicitmpc.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct ExplicitMPC{NT<:Real, SE<:StateEstimator} <: PredictiveController{NT}
99
weights::ControllerWeights{NT}
1010
R̂u::Vector{NT}
1111
R̂y::Vector{NT}
12+
::Matrix{NT}
1213
::Matrix{NT}
1314
T::Matrix{NT}
1415
T_lastu::Vector{NT}

src/controller/linmpc.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ struct LinMPC{
88
JM<:JuMP.GenericModel
99
} <: PredictiveController{NT}
1010
estim::SE
11+
transcription::TM
1112
# note: `NT` and the number type `JNT` in `JuMP.GenericModel{JNT}` can be
1213
# different since solvers that support non-Float64 are scarce.
13-
transcription::TM
1414
optim::JM
1515
con::ControllerConstraint{NT, Nothing}
1616
ΔŨ::Vector{NT}
@@ -21,6 +21,7 @@ struct LinMPC{
2121
weights::ControllerWeights{NT}
2222
R̂u::Vector{NT}
2323
R̂y::Vector{NT}
24+
::Matrix{NT}
2425
::Matrix{NT}
2526
T::Matrix{NT}
2627
T_lastu::Vector{NT}
@@ -58,10 +59,13 @@ struct LinMPC{
5859
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
5960
model, estim, transcription, Hp, Hc
6061
)
62+
Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat(model, estim, transcription, Hp, Hc)
6163
# dummy vals (updated just before optimization):
62-
F, fx̂ = zeros(NT, ny*Hp), zeros(NT, nx̂)
64+
F, fx̂, Fŝ = zeros(NT, ny*Hp), zeros(NT, nx̂), zeros(NT, nx̂*Hp)
6365
con, nϵ, P̃, S̃, Ẽ, Ẽŝ = init_defaultcon_mpc(
64-
estim, Hp, Hc, Cwt, P, S, E, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, bx̂
66+
estim, Hp, Hc, Cwt, P, S, E,
67+
ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, bx̂,
68+
Eŝ, Fŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ
6569
)
6670
= init_quadprog(model, weights, Ẽ, S̃)
6771
# dummy vals (updated just before optimization):

src/controller/nonlinmpc.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct NonLinMPC{
66
SE<:StateEstimator,
77
TM<:TranscriptionMethod,
88
JM<:JuMP.GenericModel,
9-
P<:Any,
9+
PT<:Any,
1010
JEfunc<:Function,
1111
GCfunc<:Function
1212
} <: PredictiveController{NT}
@@ -23,9 +23,10 @@ struct NonLinMPC{
2323
::Int
2424
weights::ControllerWeights{NT}
2525
JE::JEfunc
26-
p::P
26+
p::PT
2727
R̂u::Vector{NT}
2828
R̂y::Vector{NT}
29+
::Matrix{NT}
2930
::Matrix{NT}
3031
T::Matrix{NT}
3132
T_lastu::Vector{NT}
@@ -50,14 +51,14 @@ struct NonLinMPC{
5051
buffer::PredictiveControllerBuffer{NT}
5152
function NonLinMPC{NT}(
5253
estim::SE,
53-
Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE::JEfunc, gc!::GCfunc, nc, p::P,
54+
Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt, JE::JEfunc, gc!::GCfunc, nc, p::PT,
5455
transcription::TM, optim::JM
5556
) where {
5657
NT<:Real,
5758
SE<:StateEstimator,
5859
TM<:TranscriptionMethod,
5960
JM<:JuMP.GenericModel,
60-
P<:Any,
61+
PT<:Any,
6162
JEfunc<:Function,
6263
GCfunc<:Function,
6364
}
@@ -72,10 +73,14 @@ struct NonLinMPC{
7273
E, G, J, K, V, B, ex̂, gx̂, jx̂, kx̂, vx̂, bx̂ = init_predmat(
7374
model, estim, transcription, Hp, Hc
7475
)
76+
Eŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ = init_defectmat(model, estim, transcription, Hp, Hc)
7577
# dummy vals (updated just before optimization):
76-
F, fx̂ = zeros(NT, ny*Hp), zeros(NT, nx̂)
78+
F, fx̂, Fŝ = zeros(NT, ny*Hp), zeros(NT, nx̂), zeros(NT, nx̂*Hp)
7779
con, nϵ, P̃, S̃, Ẽ, Ẽŝ = init_defaultcon_mpc(
78-
estim, Hp, Hc, Cwt, P, S, E, ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, bx̂
80+
estim, Hp, Hc, Cwt, P, S, E,
81+
ex̂, fx̂, gx̂, jx̂, kx̂, vx̂, bx̂,
82+
Eŝ, Fŝ, Gŝ, Jŝ, Kŝ, Vŝ, Bŝ,
83+
gc!, nc
7984
)
8085
= init_quadprog(model, weights, Ẽ, S̃)
8186
# dummy vals (updated just before optimization):
@@ -88,7 +93,7 @@ struct NonLinMPC{
8893
nΔŨ = size(Ẽ, 2)
8994
ΔŨ = zeros(NT, nΔŨ)
9095
buffer = PredictiveControllerBuffer{NT}(nu, ny, nd, Hp, Hc, nϵ)
91-
mpc = new{NT, SE, TM, JM, P, JEfunc, GCfunc}(
96+
mpc = new{NT, SE, TM, JM, PT, JEfunc, GCfunc}(
9297
estim, transcription, optim, con,
9398
ΔŨ, ŷ,
9499
Hp, Hc, nϵ,

src/controller/transcription.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,12 @@ function init_predmat(
382382
end
383383

384384
"""
385-
init_defectmat(model::LinModel, estim, transcription::SingleShooting, Hp, Hc)
385+
init_defectmat(model::SimModel, estim, transcription::SingleShooting, Hp, Hc)
386386
387387
Return empty matrices if `transcription` is a [`SingleShooting`](@ref) (N/A).
388388
"""
389389
function init_defectmat(
390-
model, estim::StateEstimator{NT}, transcription::SingleShooting, Hp, Hc
390+
model::SimModel, estim::StateEstimator{NT}, transcription::SingleShooting, Hp, Hc
391391
) where {NT<:Real}
392392
nx̂, nu, nd = estim.nx̂, model.nu, model.nd
393393
Eŝ = zeros(NT, 0, nu*Hc)

src/model/nonlinmodel.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
struct NonLinModel{
2-
NT<:Real, F<:Function, H<:Function, P<:Any, DS<:DiffSolver
2+
NT<:Real, F<:Function, H<:Function, PT<:Any, DS<:DiffSolver
33
} <: SimModel{NT}
44
x0::Vector{NT}
55
f!::F
66
h!::H
7-
p::P
7+
p::PT
88
solver::DS
99
Ts::NT
1010
t::Vector{NT}
@@ -23,8 +23,8 @@ struct NonLinModel{
2323
xname::Vector{String}
2424
buffer::SimModelBuffer{NT}
2525
function NonLinModel{NT}(
26-
f!::F, h!::H, Ts, nu, nx, ny, nd, p::P, solver::DS
27-
) where {NT<:Real, F<:Function, H<:Function, P<:Any, DS<:DiffSolver}
26+
f!::F, h!::H, Ts, nu, nx, ny, nd, p::PT, solver::DS
27+
) where {NT<:Real, F<:Function, H<:Function, PT<:Any, DS<:DiffSolver}
2828
Ts > 0 || error("Sampling time Ts must be positive")
2929
uop = zeros(NT, nu)
3030
yop = zeros(NT, ny)
@@ -38,7 +38,7 @@ struct NonLinModel{
3838
x0 = zeros(NT, nx)
3939
t = zeros(NT, 1)
4040
buffer = SimModelBuffer{NT}(nu, nx, ny, nd)
41-
return new{NT, F, H, P, DS}(
41+
return new{NT, F, H, PT, DS}(
4242
x0,
4343
f!, h!,
4444
p,

0 commit comments

Comments
 (0)