Skip to content

Commit b71a2f0

Browse files
committed
changed: clearer code in TrapezoidalCollocation
1 parent d3cad37 commit b71a2f0

1 file changed

Lines changed: 40 additions & 39 deletions

File tree

src/controller/transcription.jl

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ const COLLOCATION_NODE_TYPE = Float64
33
"""
44
Abstract supertype of all transcription methods of [`PredictiveController`](@ref).
55
6-
The module currently supports [`SingleShooting`](@ref), [`MultipleShooting`](@ref) and
7-
[`TrapezoidalCollocation`](@ref) transcription methods.
6+
The module currently supports [`SingleShooting`](@ref), [`MultipleShooting`](@ref),
7+
[`TrapezoidalCollocation`](@ref) and [`OrthogonalCollocation`](@ref) transcription methods.
88
"""
99
abstract type TranscriptionMethod end
1010
abstract type ShootingMethod <: TranscriptionMethod end
@@ -129,9 +129,9 @@ end
129129
Construct an orthogonal collocation on finite elements [`TranscriptionMethod`](@ref).
130130
131131
Also known as pseudo-spectral method. The `h` argument is the hold order for ``\mathbf{u}``,
132-
and `no`, the number of collocation points ``n_o``. Only zero-order hold is currently
133-
implemented, so `h` must be `0`. The decision variable is similar to [`MultipleShooting`](@ref),
134-
but it also includes the collocation points:
132+
and `no` argument, the number of collocation points ``n_o``. Only zero-order hold is
133+
currently implemented, so `h` must be `0`. The decision variable is similar to
134+
[`MultipleShooting`](@ref), but it also includes the collocation points:
135135
```math
136136
\mathbf{Z} = \begin{bmatrix} \mathbf{ΔU} \\ \mathbf{X̂_0} \\ \mathbf{K} \end{bmatrix}
137137
```
@@ -150,8 +150,8 @@ where ``\mathbf{K}`` encompasses all the intermediate stages of the deterministi
150150
```
151151
and ``\mathbf{k}_o(k+j)`` is the deterministic state prediction for the ``o``th collocation
152152
point at the ``j``th stage/interval/finite element (details in Extended Help). The `roots`
153-
keyword argument is either `:gaussradau` or `:gausslegendre`, for the roots of the
154-
Gauss-Radau or Gauss-Legendre quadrature, respectively.
153+
keyword argument is either `:gaussradau` or `:gausslegendre`, for Gauss-Radau or
154+
Gauss-Legendre quadrature, respectively.
155155
156156
This transcription computes the predictions by enforcing the collocation and continuity
157157
constraints at the collocation points. It is efficient for highly stiff systems, but
@@ -169,7 +169,7 @@ this transcription method (sparser formulation than [`MultipleShooting`](@ref)).
169169
# Extended Help
170170
!!! details "Extended Help"
171171
As explained in the Extended Help of [`TrapezoidalCollocation`](@ref), the stochastic
172-
states are left out of the ``\mathbf{K}`` vector since collocation methods required
172+
states are left out of the ``\mathbf{K}`` vector since collocation methods require
173173
continuous-time dynamics and the stochastic model is discrete.
174174
175175
The collocation points are located at the roots of orthogonal polynomials, which is
@@ -1302,20 +1302,20 @@ function con_nonlinprogeq!(
13021302
X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)]
13031303
@threadsif f_threads for j=1:Hp
13041304
if j < 2
1305-
x̂0 = @views mpc.estim.x̂0[1:nx̂]
1306-
d̂0 = @views mpc.d0[1:nd]
1305+
x̂0_Z̃ = @views mpc.estim.x̂0[1:nx̂]
1306+
d̂0 = @views mpc.d0[1:nd]
13071307
else
1308-
x̂0 = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1309-
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
1308+
x̂0_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1309+
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
13101310
end
13111311
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
13121312
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
13131313
k = @views K[(1 + nk*(j-1)):(nk*j)]
13141314
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
13151315
x̂0next_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*j)]
13161316
ŝnext = @views geq[(1 + nx̂*(j-1)):(nx̂*j)]
1317-
f̂!(x̂0next, û0, k, mpc.estim, model, x̂0, u0, d̂0)
1318-
ŝnext .= x̂0next .- x̂0next_Z̃
1317+
f̂!(x̂0next, û0, k, mpc.estim, model, x̂0_Z̃, u0, d̂0)
1318+
ŝnext .= @. x̂0next - x̂0next_Z̃
13191319
end
13201320
return geq
13211321
end
@@ -1368,33 +1368,34 @@ function con_nonlinprogeq!(
13681368
X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)]
13691369
@threadsif f_threads for j=1:Hp
13701370
if j < 2
1371-
x̂0 = @views mpc.estim.x̂0[1:nx̂]
1372-
d̂0 = @views mpc.d0[1:nd]
1371+
x̂0_Z̃ = @views mpc.estim.x̂0[1:nx̂]
1372+
d̂0 = @views mpc.d0[1:nd]
13731373
else
1374-
x̂0 = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1375-
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
1374+
x̂0_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1375+
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
13761376
end
13771377
= @views K̇[(1 + nk*(j-1)):(nk*j)]
13781378
d̂0next = @views D̂0[(1 + nd*(j-1)):(nd*j)]
13791379
x̂0next = @views X̂0[(1 + nx̂*(j-1)):(nx̂*j)]
13801380
x̂0next_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-1)):(nx̂*j)]
1381-
ŝnext = @views geq[(1 + nx̂*(j-1)):(nx̂*j)]
1382-
x0 = @views x̂0[1:nx]
1383-
xsnext = @views x̂0next[nx+1:end]
1384-
x0next_Z̃, xsnext_Z̃ = @views x̂0next_Z̃[1:nx], x̂0next_Z̃[nx+1:end]
1385-
sdnext, ssnext = @views ŝnext[1:nx], ŝnext[nx+1:end]
1386-
k̇1, k̇2 = @views k̇[1:nx], k̇[nx+1:2*nx]
1381+
sdnext = @views geq[(1 + nx̂*(j-1) ):(nx̂*(j-1) + nx)]
1382+
ssnext = @views geq[(1 + nx̂*(j-1) + nx):(nx̂*j )]
1383+
x0_Z̃ = @views x̂0_Z̃[1:nx]
1384+
x0next_Z̃ = @views x̂0next_Z̃[1:nx]
1385+
k̇1, k̇2 = @views k̇[1:nx], k̇[nx+1:2*nx]
13871386
# ----------------- stochastic defects -----------------------------------------
1388-
fs!(x̂0next, mpc.estim, model, x̂0)
1387+
xsnext = @views x̂0next[nx+1:end]
1388+
xsnext_Z̃ = @views x̂0next_Z̃[nx+1:end]
1389+
fs!(x̂0next, mpc.estim, model, x̂0_Z̃)
13891390
ssnext .= @. xsnext - xsnext_Z̃
13901391
# ----------------- deterministic defects: trapezoidal collocation -------------
13911392
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
13921393
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
1393-
f̂_input!(û0, mpc.estim, model, x̂0, u0)
1394+
f̂_input!(û0, mpc.estim, model, x̂0_Z̃, u0)
13941395
if f_threads || h < 1 || j < 2
13951396
# we need to recompute k1 with multi-threading, even with h==1, since the
13961397
# last iteration (j-1) may not be executed (iterations are re-orderable)
1397-
model.f!(k̇1, x0, û0, d̂0, p)
1398+
model.f!(k̇1, x0_Z̃, û0, d̂0, p)
13981399
else
13991400
k̇1 .= @views K̇[(1 + nk*(j-1)-nx):(nk*(j-1))] # k2 of of the last iter. j-1
14001401
end
@@ -1407,7 +1408,7 @@ function con_nonlinprogeq!(
14071408
f̂_input!(û0next, mpc.estim, model, x̂0next_Z̃, u0next)
14081409
end
14091410
model.f!(k̇2, x0next_Z̃, û0next, d̂0next, p)
1410-
sdnext .= @. x0 - x0next_Z̃ + 0.5*Ts*(k̇1 + k̇2)
1411+
sdnext .= @. x0_Z̃ - x0next_Z̃ + 0.5*Ts*(k̇1 + k̇2)
14111412
end
14121413
return geq
14131414
end
@@ -1471,11 +1472,11 @@ function con_nonlinprogeq!(
14711472
X̂0_Z̃, K_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)], Z̃[(nΔU+nX̂+1):(nΔU+nX̂+nk*Hp)]
14721473
@threadsif f_threads for j=1:Hp
14731474
if j < 2
1474-
x̂0 = @views mpc.estim.x̂0[1:nx̂]
1475-
d̂0 = @views mpc.d0[1:nd]
1475+
x̂0_Z̃ = @views mpc.estim.x̂0[1:nx̂]
1476+
d̂0 = @views mpc.d0[1:nd]
14761477
else
1477-
x̂0 = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1478-
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
1478+
x̂0_Z̃ = @views X̂0_Z̃[(1 + nx̂*(j-2)):(nx̂*(j-1))]
1479+
d̂0 = @views D̂0[(1 + nd*(j-2)):(nd*(j-1))]
14791480
end
14801481
= @views K̇[(1 + nk*(j-1)):(nk*j)]
14811482
k_Z̃ = @views K_Z̃[(1 + nk*(j-1)):(nk*j)]
@@ -1484,31 +1485,31 @@ function con_nonlinprogeq!(
14841485
scnext = @views geq[(1 + nx̂_nk*(j-1) ):(nx̂_nk*(j-1) + nx)]
14851486
ssnext = @views geq[(1 + nx̂_nk*(j-1) + nx):(nx̂_nk*(j-1) + nx̂)]
14861487
sk = @views geq[(1 + nx̂_nk*(j-1) + nx̂):(nx̂_nk*j )]
1487-
x0 = @views x̂0[1:nx]
1488+
x0_Z̃ = @views x̂0_Z̃[1:nx]
14881489
x0next_Z̃ = @views x̂0next_Z̃[1:nx]
1489-
xsnext = @views x̂0next[nx+1:end]
1490-
xsnext_Z̃ = @views x̂0next_Z̃[nx+1:end]
14911490
# ----------------- stochastic defects -----------------------------------------
1492-
fs!(x̂0next, mpc.estim, model, x̂0)
1491+
xsnext = @views x̂0next[nx+1:end]
1492+
xsnext_Z̃ = @views x̂0next_Z̃[nx+1:end]
1493+
fs!(x̂0next, mpc.estim, model, x̂0_Z̃)
14931494
ssnext .= @. xsnext - xsnext_Z̃
14941495
# ----------------- collocation point defects ----------------------------------
14951496
u0 = @views U0[(1 + nu*(j-1)):(nu*j)]
14961497
û0 = @views Û0[(1 + nu*(j-1)):(nu*j)]
1497-
f̂_input!(û0, mpc.estim, model, x̂0, u0)
1498+
f̂_input!(û0, mpc.estim, model, x̂0_Z̃, u0)
14981499
# TODO: remove this allocation
14991500
Δk = similar(k̇)
15001501
for o=1:no
15011502
k̇o = @views k̇[(1 + (o-1)*nx):(o*nx)]
15021503
ko_Z̃ = @views k_Z̃[(1 + (o-1)*nx):(o*nx)]
15031504
Δko = @views Δk[(1 + (o-1)*nx):(o*nx)]
1504-
Δko .= ko_Z̃ .- x0
1505+
Δko .= ko_Z̃ .- x0_Z̃
15051506
model.f!(k̇o, ko_Z̃, û0, d̂0, p)
15061507
end
15071508
# TODO: remove the following allocations
15081509
k̇_Z̃ = Mo*Δk
15091510
sk .= @. k̇_Z̃ -
15101511
# ----------------- continuity constraint defects ------------------------------
1511-
scnext .= λo*x0 + Co*k_Z̃ - x0next_Z̃
1512+
scnext .= λo*x0_Z̃ + Co*k_Z̃ - x0next_Z̃
15121513
end
15131514
return geq
15141515
end

0 commit comments

Comments
 (0)