Skip to content

Fix lqi_controller partial/discrete handling; add LQGProblem method; docs port#139

Merged
baggepinnen merged 1 commit into
masterfrom
lqi_fixes_and_docs
May 15, 2026
Merged

Fix lqi_controller partial/discrete handling; add LQGProblem method; docs port#139
baggepinnen merged 1 commit into
masterfrom
lqi_fixes_and_docs

Conversation

@baggepinnen
Copy link
Copy Markdown
Member

Summary

  • Fix two latent bugs in lqi_controller (src/lqg.jl):
    • Partial integrator_outputs was silently mis-wired: nr got overwritten to ny, so calling lqi_controller with anything other than the default integrator_outputs=1:ny either errored or produced a controller wired up for a different number of references than lqi had actually augmented.
    • Discrete-time plants didn't work: ss(lqi(...)) was created without a timeevol, so the gain block was always continuous-time and connect rejected it on a discrete plant with "Sampling time mismatch". Now stamps G.timeevol on it.
  • Align the controller's integrator discretization with add_output_integrator(::Discrete) — both now use tf(Ts, [1, -(1-ϵ)], Ts) — and expose ϵ as a kwarg so plant augmentation and the controller agree even with leakage.
  • Add lqi_controller(prob::LQGProblem, Qi; integrator_outputs, ϵ) that builds the Kalman observer internally from prob and forms Q1_aug = blkdiag(prob.Q1, Qi). This closes the f(::LQGProblem) API parity gap for lqi_controller.
  • lqi docstring: replace stale Q3 in the signature with args... and clarify that the reference enters at the closed-loop level inside lqi_controller, not in the augmented plant.
  • Docs port: add an "Explicit error integration via LQI" section to docs/src/lqg_disturbance.md showing the LQI alternative alongside the disturbance-model approach. This replaces the example add integrator option to extended_controller #106 was trying to add (which has been closed in favor of this approach).

Test plan

  • Full test suite (Pkg.test()): 1374 pass, 6 broken (pre-existing), 0 fail.
  • New test/test_lqi.jl cases:
    • MIMO continuous, all outputs integrated — reference-to-output DC gain ≈ I.
    • Partial integrator_outputs=[1] on a 2-output plant — only the integrated channel tracks exactly.
    • Discrete-time SISO with ϵ=1e-4 — verifies the integrator pole sits at 1-ϵ.
    • lqi_controller(::LQGProblem, Qi) — same dimensions and integrator behavior as the explicit-observer form.
  • cd docs && julia --project make.jl — clean build; the new LQG_DIST @example block evaluates without errors.
  • Closes add integrator option to extended_controller #106 (already closed remotely with a comment referencing this work).

🤖 Generated with Claude Code

… method

- lqi_controller silently mis-wired when integrator_outputs != 1:ny because nr
  was overwritten to ny. Now nr = length(integrator_outputs) and the feedback
  comparator/integrator/reference symbols all use the correct subset.
- ss(lqi(...)) was created without a timeevol, so the gain block was always
  continuous-time and connect() rejected it for discrete plants. Stamp the
  plant's timeevol on it.
- Replace c2d(1/s, Ts) for the controller integrator with the same form used
  by add_output_integrator(::Discrete) (Ts/(z-(1-ϵ))) and expose ϵ as a kwarg
  so plant augmentation and controller agree even with leakage.
- Add lqi_controller(prob::LQGProblem, Qi; ...) that builds the Kalman
  observer internally and forms Q1_aug = blkdiag(prob.Q1, Qi).
- lqi docstring: replace stale Q3 signature with args... and clarify that the
  reference enters in lqi_controller, not in the augmented plant.
- New tests cover MIMO continuous, partial integrator_outputs, discrete-time
  with ϵ, and the LQGProblem method.
- Add an LQI section to docs/src/lqg_disturbance.md showing the explicit
  error-integration design alongside the disturbance-model approach.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.99%. Comparing base (5b9b30d) to head (ac58c12).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #139      +/-   ##
==========================================
+ Coverage   90.87%   90.99%   +0.12%     
==========================================
  Files          20       20              
  Lines        3045     3055      +10     
==========================================
+ Hits         2767     2780      +13     
+ Misses        278      275       -3     
Flag Coverage Δ
unittests 90.99% <100.00%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@baggepinnen baggepinnen merged commit 44481c9 into master May 15, 2026
2 checks passed
@baggepinnen baggepinnen deleted the lqi_fixes_and_docs branch May 15, 2026 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants