Skip to content

Commit 00ac589

Browse files
committed
wip : foh trapezoidal
1 parent 035fe98 commit 00ac589

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

src/controller/transcription.jl

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ for this transcription method.
6464
struct MultipleShooting <: ShootingMethod end
6565

6666
@doc raw"""
67-
TrapezoidalCollocation()
67+
TrapezoidalCollocation(nh::Int=0)
6868
69-
Construct an implicit trapezoidal [`TranscriptionMethod`](@ref).
69+
Construct an implicit trapezoidal [`TranscriptionMethod`](@ref) with `nh`th order hold.
7070
7171
This is the simplest collocation method. It supports continuous-time [`NonLinModel`](@ref)s
7272
only. The decision variables are the same as for [`MultipleShooting`](@ref), hence similar
73-
computational costs. It currently assumes piecewise constant manipulated inputs (or zero-
74-
order hold) between the samples, but linear interpolation will be added soon.
73+
computational costs. The `nh` argument is `0` or `1`, for piecewise constant or linear
74+
manipulated inputs ``\mathbf{u}`` (`1` is slightly less computationally expensive).
7575
7676
This transcription computes the predictions by calling the continuous-time model in the
7777
equality constraint function and by using the implicit trapezoidal rule. It can handle
@@ -92,10 +92,14 @@ transcription method.
9292
for more details.
9393
"""
9494
struct TrapezoidalCollocation <: CollocationMethod
95+
nh::Int
9596
nc::Int
96-
function TrapezoidalCollocation()
97+
function TrapezoidalCollocation(nh::Int=0)
98+
if !(nh == 0 || nh == 1)
99+
throw(ArgumentError("nh argument must be 0 or 1 for TrapezoidalCollocation."))
100+
end
97101
nc = 2 # 2 collocation points per interval for trapezoidal rule
98-
return new(nc)
102+
return new(nh, nc)
99103
end
100104
end
101105

@@ -1403,8 +1407,6 @@ function con_nonlinprogeq!(
14031407
d0 = @views mpc.d0[1:nd]
14041408
#TODO: allow parallel for loop or threads?
14051409
for j=1:Hp
1406-
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
1407-
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
14081410
k0 = @views K0[(1 + nk*(j-1)):(nk*j)]
14091411
d0next = @views D̂0[(1 + nd*(j-1)):(nd*j)]
14101412
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
@@ -1413,11 +1415,23 @@ function con_nonlinprogeq!(
14131415
xd, xs = @views x̂0[1:nx], x̂0[nx+1:end]
14141416
xdnext_Z̃, xsnext_Z̃ = @views x̂0next_Z̃[1:nx], x̂0next_Z̃[nx+1:end]
14151417
sdnext, ssnext = @views ŝnext[1:nx], ŝnext[nx+1:end]
1416-
mul!(û0, Cs_u, xs) # ys_u = Cs_u*xs
1417-
û0 .+= u0 # û0 = u0 + ys_u
14181418
k1, k2 = @views k0[1:nx], k0[nx+1:2*nx]
1419-
model.f!(k1, xd, û0, d0, p)
1420-
model.f!(k2, xdnext_Z̃, û0, d0next, p) # assuming ZOH on manipulated inputs u
1419+
if iszero(transcription.nh) # piecewise constant manipulated inputs u:
1420+
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
1421+
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
1422+
mul!(û0, Cs_u, xs) # ys_u(k) = Cs_u*xs(k)
1423+
û0 .+= u0 # û0(k) = u0(k) + ys_u(k)
1424+
model.f!(k1, xd, û0, d0, p)
1425+
model.f!(k2, xdnext_Z̃, û0, d0next, p)
1426+
else # piecewise linear manipulated inputs u:
1427+
u0next = @views U0[(1 + nu*j):(nu*(j+1))]
1428+
û0next = @views U0[(1 + nu*j):(nu*(j+1))]
1429+
mul!(û0next, Cs_u, xsnext_Z̃) # ys_u(k+1) = Cs_u*xs(k+1)
1430+
û0next .+= u0next # û0(k+1) = u0(k+1) + ys_u(k+1)
1431+
model.f!(k2, xdnext_Z̃, û0next, d0next, p)
1432+
k1 .= lastk2
1433+
lastk2 = k2
1434+
end
14211435
xsnext = @views x̂0next[nx+1:end]
14221436
mul!(xsnext, As, xs)
14231437
sdnext .= @. xd - xdnext_Z̃ + (Ts/2)*(k1 + k2)

0 commit comments

Comments
 (0)