|
129 | 129 | Construct an orthogonal collocation on finite elements [`TranscriptionMethod`](@ref). |
130 | 130 |
|
131 | 131 | Also known as pseudo-spectral method. It supports continuous-time [`NonLinModel`](@ref)s |
132 | | -only. The `h` argument is the hold order for ``\mathbf{u}``, and `no` argument, the number |
133 | | -of collocation points ``n_o``. Only zero-order hold is currently implemented, so `h` must |
134 | | -be `0`. The decision variable is similar to [`MultipleShooting`](@ref), but it also includes |
135 | | -the collocation points: |
| 132 | +only. The `h` argument is the hold order for ``\mathbf{u}``, and the `no` argument, the |
| 133 | +number of collocation points ``n_o``. The decision variable is similar to [`MultipleShooting`](@ref), |
| 134 | +but it also includes the collocation points: |
136 | 135 | ```math |
137 | 136 | \mathbf{Z} = \begin{bmatrix} \mathbf{ΔU} \\ \mathbf{X̂_0} \\ \mathbf{K} \end{bmatrix} |
138 | 137 | ``` |
@@ -187,9 +186,6 @@ struct OrthogonalCollocation <: CollocationMethod |
187 | 186 | function OrthogonalCollocation( |
188 | 187 | h::Int=0, no::Int=3; f_threads=false, h_threads=false, roots=:gaussradau |
189 | 188 | ) |
190 | | - if !(h == 0) |
191 | | - throw(ArgumentError("Only the zero-order hold (h=0) is currently implemented.")) |
192 | | - end |
193 | 189 | if roots==:gaussradau |
194 | 190 | x, _ = FastGaussQuadrature.gaussradau(no, COLLOCATION_NODE_TYPE) |
195 | 191 | # we reverse the nodes to include the τ=1.0 node: |
@@ -1378,6 +1374,10 @@ function con_nonlinprogeq!( |
1378 | 1374 | nk = get_nk(model, transcription) |
1379 | 1375 | D̂0 = mpc.D̂0 |
1380 | 1376 | X̂0_Z̃ = @views Z̃[(nΔU+1):(nΔU+nX̂)] |
| 1377 | + # prefilling Û0 to avoid race-condition: |
| 1378 | + # TODO: do the same in orthogonoal collocation and I will be able to interpolate |
| 1379 | + |
| 1380 | + |
1381 | 1381 | @threadsif f_threads for j=1:Hp |
1382 | 1382 | if j < 2 |
1383 | 1383 | x̂0_Z̃ = @views mpc.estim.x̂0[1:nx̂] |
@@ -1456,16 +1456,21 @@ extracted from the decision variable `Z̃`. The ``\mathbf{x_0}`` vectors are the |
1456 | 1456 | deterministic state extracted from `Z̃`. The ``\mathbf{k̇}_i`` derivative for the ``i``th |
1457 | 1457 | collocation point is computed from the continuous-time function `model.f!` and: |
1458 | 1458 | ```math |
1459 | | -\mathbf{k̇}_i(k+j) = \mathbf{f}\Big(\mathbf{k}_i(k+j), \mathbf{û_0}(k+j), \mathbf{d̂}_i(k+j), \mathbf{p}\Big) |
| 1459 | +\mathbf{k̇}_i(k+j) = \mathbf{f}\Big(\mathbf{k}_i(k+j), \mathbf{û_i}(k+j), \mathbf{d̂}_i(k+j), \mathbf{p}\Big) |
1460 | 1460 | ``` |
1461 | | -The disturbed input ``\mathbf{û_0}(k+j)`` is defined in [`f̂_input!`](@ref). Based on the |
1462 | | -normalized time ``τ_i ∈ [0, 1]``, measured disturbances are linearly interpolated: |
| 1461 | +Based on the normalized time ``τ_i ∈ [0, 1]`` and hold order `transcription.h`, the inputs |
| 1462 | +and disturbances are piecewise constant or linear: |
1463 | 1463 | ```math |
1464 | | -\mathbf{d̂}_i(k+j) = (1-τ_i)\mathbf{d̂_0}(k+j) + τ_i\mathbf{d̂_0}(k+j+1) |
| 1464 | +\begin{aligned} |
| 1465 | +\mathbf{û}_i(k+j) &= \begin{cases} |
| 1466 | + \mathbf{û_0}(k+1) & h = 0 \\ |
| 1467 | + (1-τ_i)\mathbf{û_0}(k+j) + τ_i\mathbf{û_0}(k+j+1) & h = 1 \end{cases} \\ |
| 1468 | +\mathbf{d̂}_i(k+j) &= (1-τ_i)\mathbf{d̂_0}(k+j) + τ_i\mathbf{d̂_0}(k+j+1) |
| 1469 | +\end{aligned} |
1465 | 1470 | ``` |
1466 | | -The defects for the stochastic states ``\mathbf{s_s}`` are computed as in the |
1467 | | -[`TrapezoidalCollocation`](@ref) method, and the ones for the continuity constraint of the |
1468 | | -deterministic state trajectories are given by: |
| 1471 | +The disturbed input ``\mathbf{û_0}(k+j)`` is defined in [`f̂_input!`](@ref). The defects for |
| 1472 | +the stochastic states ``\mathbf{s_s}`` are computed as the [`TrapezoidalCollocation`](@ref) |
| 1473 | +method, and the ones for the continuity constraint of the deterministic states are: |
1469 | 1474 | ```math |
1470 | 1475 | \mathbf{s_c}(k+j+1) |
1471 | 1476 | = \mathbf{C_o} \begin{bmatrix} |
@@ -1520,8 +1525,17 @@ function con_nonlinprogeq!( |
1520 | 1525 | ssnext .= @. xsnext - xsnext_Z̃ |
1521 | 1526 | # ----------------- collocation constraint defects ----------------------------- |
1522 | 1527 | u0 = @views U0[(1 + nu*(j-1)):(nu*j)] |
| 1528 | + if j ≥ Hp |
| 1529 | + # j = Hp special case: u(k+Hp-1) = u(k+Hp) since Hc ≤ Hp implies Δu(k+Hp) = 0 |
| 1530 | + u0next = u0 |
| 1531 | + else |
| 1532 | + u0next = @views U0[(1 + nu*j):(nu*(j+1))] |
| 1533 | + end |
| 1534 | + |
1523 | 1535 | û0 = @views Û0[(1 + nu*(j-1)):(nu*j)] |
1524 | 1536 | f̂_input!(û0, mpc.estim, model, x̂0_Z̃, u0) |
| 1537 | + f̂_input!(û0next, mpc.estim, model, x̂0next_Z̃, u0next) |
| 1538 | + |
1525 | 1539 | Δk = k̇ |
1526 | 1540 | for i=1:no |
1527 | 1541 | Δk[(1 + (i-1)*nx):(i*nx)] = @views k_Z̃[(1 + (i-1)*nx):(i*nx)] .- x0_Z̃ |
|
0 commit comments