From 2db113c0e79d8769fed71ca5b3c7cabf2747cc2a Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 08:55:23 -0500 Subject: [PATCH 1/8] doc: remove useless `d` in pH neutralization ex. --- docs/src/manual/nonlinmpc2.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/manual/nonlinmpc2.md b/docs/src/manual/nonlinmpc2.md index 031eb7caf..4d3b906c0 100644 --- a/docs/src/manual/nonlinmpc2.md +++ b/docs/src/manual/nonlinmpc2.md @@ -218,7 +218,6 @@ function simDAE(plant, N; x_0) x, d = x_0, [10.0] for i=1:N u = i ≤ (1N÷4) ? [10.0] : [11.0] - d = i ≤ (2N÷4) ? [10.0] : [12.0] c_Ain = i ≤ (3N÷4) ? c_Ain_0 : (c_Ain_0 - 0.01) plant.p[1] = c_Ain y = plant(d) From 24a97593381002564f1e3710c1538fa9558505cc Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 09:08:19 -0500 Subject: [PATCH 2/8] test: removing `aarch64` from the CI It is too unreliable, presumably because not enough RAM on remote server. --- .github/workflows/juliaci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/juliaci.yml b/.github/workflows/juliaci.yml index 459c3f56e..32e52a499 100644 --- a/.github/workflows/juliaci.yml +++ b/.github/workflows/juliaci.yml @@ -15,9 +15,9 @@ jobs: julia-ci: uses: franckgaga/testitem-workflow/.github/workflows/juliaci.yml@patch-1 with: - memory-threshold: 0.9 include-windows-x86: false include-macos-x64: false + include-macos-aarch64: false permissions: write-all secrets: codecov_token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From 559ca22c7d56f5367e80b7814c7d19c508864b77 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 10:00:38 -0500 Subject: [PATCH 3/8] test: trying `allow-failure` instead --- .github/workflows/juliaci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/juliaci.yml b/.github/workflows/juliaci.yml index 32e52a499..6e6b3faa8 100644 --- a/.github/workflows/juliaci.yml +++ b/.github/workflows/juliaci.yml @@ -17,7 +17,7 @@ jobs: with: include-windows-x86: false include-macos-x64: false - include-macos-aarch64: false + allow-failure: macos-aarch64 permissions: write-all secrets: codecov_token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From ada4b2e253c6cc0d611bba21d40579f8846e6495 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 11:38:17 -0500 Subject: [PATCH 4/8] debug: use most recent `d` in MHE `direct=true` and `SingleShooting` --- src/estimator/mhe/transcription.jl | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/estimator/mhe/transcription.jl b/src/estimator/mhe/transcription.jl index ee5f8b285..5e4f6f508 100644 --- a/src/estimator/mhe/transcription.jl +++ b/src/estimator/mhe/transcription.jl @@ -1517,18 +1517,22 @@ function predict_mhe!( i_d0arr = estim.direct ? 0 : nd # the first nd elements in D0 are useless if p=1 x̂0 = @views x̂0arr[1:nx̂] for j=1:Nk - u0 = @views estim.U0[(1+nu*(j-1)):(nu*j)] - d0 = @views estim.D0[(1+nd*(j-1) + i_d0arr):(nd*j + i_d0arr)] - ŵ = @views Ŵ[(1+nŵ*(j-1)):(nŵ*j)] - k̄ = @views K̄[(1+nk̄*(j-1)):(nk̄*j)] - û0 = @views Û0[(1+nu*(j-1)):(nu*j)] - ûi = @views Ûi[(1 + nu*(j-1)):(nu*j)] - di = @views Di[(1 + nd*(j-1)):(nd*j)] - x̂0next = @views X̂0[(1+nx̂*(j-1)):(nx̂*j)] - d0next = @views (j < Nk) ? estim.D0[(1+nd*j + i_d0arr):(nd*(j+1) + i_d0arr)] : d0 + u0 = @views estim.U0[(1+nu*(j-1)):(nu*j)] + d0 = @views estim.D0[(1+nd*(j-1) + i_d0arr):(nd*j + i_d0arr)] + ŵ = @views Ŵ[(1+nŵ*(j-1)):(nŵ*j)] + k̄ = @views K̄[(1+nk̄*(j-1)):(nk̄*j)] + û0 = @views Û0[(1+nu*(j-1)):(nu*j)] + ûi = @views Ûi[(1 + nu*(j-1)):(nu*j)] + di = @views Di[(1 + nd*(j-1)):(nd*j)] + x̂0next = @views X̂0[(1+nx̂*(j-1)):(nx̂*j)] + if estim.direct || j < Nk # d0(k+1) is never needed if estim.direct + d0next = @views estim.D0[(1+nd*j + i_d0arr):(nd*(j+1) + i_d0arr)] + else # special case, d0(k+1)≈d0(k), since d0(k+1) is not available at time k: + d0next = d0 + end if h > 0 && j < Nk u0next = estim.U0[(1+nu*j):(nu*(j+1))] - else + else # special case, û0(k+p)≈û0(k+p-1), since û0(k+p) is not available at time k: u0next = u0 end û0next = @views j < Nk ? Û0[(1+nu*j):(nu*(j+1))] : Û0[1:nu] From 83a4e3a8cbdcdaf59c2f8554136f34f301779648 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 11:44:00 -0500 Subject: [PATCH 5/8] test: trying the wildcard to allow MacOS failures --- .github/workflows/juliaci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/juliaci.yml b/.github/workflows/juliaci.yml index 6e6b3faa8..165a4724e 100644 --- a/.github/workflows/juliaci.yml +++ b/.github/workflows/juliaci.yml @@ -17,7 +17,7 @@ jobs: with: include-windows-x86: false include-macos-x64: false - allow-failure: macos-aarch64 + allow-failure: "*:macos-aarch64" permissions: write-all secrets: codecov_token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From 520f736e98a5eeba7b970e23ab7adb3f54e1d25b Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 12:13:15 -0500 Subject: [PATCH 6/8] CI: re-adding `TagBot.yml` Since the `juliaci.yml` workflow no longer trigger the TagBot, let's try the old way. --- .github/workflows/TagBot.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/TagBot.yml diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 000000000..623860f70 --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,15 @@ +name: TagBot +on: + issue_comment: + types: + - created + workflow_dispatch: +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} \ No newline at end of file From a5c1209baab8eab6cd7b8bc1dbe9eb719a6760b3 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 12:44:32 -0500 Subject: [PATCH 7/8] debug: add a forgotten `@view` --- src/estimator/mhe/transcription.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/estimator/mhe/transcription.jl b/src/estimator/mhe/transcription.jl index 5e4f6f508..d18d9b39a 100644 --- a/src/estimator/mhe/transcription.jl +++ b/src/estimator/mhe/transcription.jl @@ -1531,7 +1531,7 @@ function predict_mhe!( d0next = d0 end if h > 0 && j < Nk - u0next = estim.U0[(1+nu*j):(nu*(j+1))] + u0next = @views estim.U0[(1+nu*j):(nu*(j+1))] else # special case, û0(k+p)≈û0(k+p-1), since û0(k+p) is not available at time k: u0next = u0 end From d5a8e57a0f231bf5c34e95b76e83a19873160dab Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 4 Nov 2026 12:44:53 -0500 Subject: [PATCH 8/8] test: improve coverage on MHE with `SingleShooting` --- Project.toml | 2 +- test/2_test_state_estim.jl | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index fdb6f89f5..ea7e74a04 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ModelPredictiveControl" uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c" -version = "2.16.0" +version = "2.16.1" authors = ["Francis Gagnon"] [deps] diff --git a/test/2_test_state_estim.jl b/test/2_test_state_estim.jl index 74f17b290..c24efde7c 100644 --- a/test/2_test_state_estim.jl +++ b/test/2_test_state_estim.jl @@ -1379,10 +1379,14 @@ end model = NonLinModel(f!, h!, 100.0, 1, 1, 1, 1; p) transcription = SingleShooting(1) mhe_foh = MovingHorizonEstimator(model; He=3, transcription) - preparestate!(mhe_foh, [0.0], [0.0]) - x̂ = updatestate!(mhe_foh, [1.0], [0.0], [0.0]) - info = getinfo(mhe_foh) @test mhe_foh.transcription.h == 1 + for i in 1:50 + preparestate!(mhe_foh, [1.5], [0.0]) + updatestate!(mhe_foh, [0.0], [1.5], [0.0]) + end + x̂ = preparestate!(mhe_foh, [1.5], [0.0]) + @test mhe_foh([0.0]) ≈ [1.5] + info = getinfo(mhe_foh) @test info[:x̂] ≈ x̂ end