@@ -3,8 +3,8 @@ const COLLOCATION_NODE_TYPE = Float64
33"""
44Abstract 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"""
99abstract type TranscriptionMethod end
1010abstract type ShootingMethod <: TranscriptionMethod end
129129Construct an orthogonal collocation on finite elements [`TranscriptionMethod`](@ref).
130130
131131Also known as pseudo-spectral method. The `h` argument is the hold order for ``\m athbf{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\m athbf{Z} = \b egin{bmatrix} \m athbf{ΔU} \\ \m athbf{X̂_0} \\ \m athbf{K} \e nd{bmatrix}
137137```
@@ -150,8 +150,8 @@ where ``\mathbf{K}`` encompasses all the intermediate stages of the deterministi
150150```
151151and ``\m athbf{k}_o(k+j)`` is the deterministic state prediction for the ``o``th collocation
152152point 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
156156This transcription computes the predictions by enforcing the collocation and continuity
157157constraints 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 ``\m athbf{K}`` vector since collocation methods required
172+ states are left out of the ``\m athbf{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
13211321end
@@ -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 k̇ = @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
14131414end
@@ -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 k̇ = @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̃ - k̇
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
15141515end
0 commit comments