Skip to content

Commit 5b0b870

Browse files
committed
PBH test for observability of linear systems
1 parent cc5756b commit 5b0b870

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

src/model/linmodel.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,18 +182,20 @@ end
182182
183183
Evaluate the steady-state vector when `model` is a [`LinModel`](@ref).
184184
185-
Omitting the operating points, the method evaluates the equilibrium ``\mathbf{x}(∞)`` from:
185+
Following [`setop!`](@ref) notation, the method evaluates the equilibrium ``\mathbf{x}(∞)``
186+
from:
186187
```math
187-
\mathbf{x}(∞) = \mathbf{(I - A)^{-1}(B_u u + B_d d)}
188+
\mathbf{x}(∞) = \mathbf{(I - A)^{-1}(B_u u_0 + B_d d_0)}
188189
```
189-
with the manipulated inputs held constant at ``\mathbf{u}`` and, the measured disturbances,
190-
at ``\mathbf{d}``. The Moore-Penrose pseudo-inverse computes ``\mathbf{(I - A)^{-1}}``
191-
to support integrating `model` (integrator states will be 0).
190+
with the manipulated inputs held constant at ``\mathbf{u_0}`` and, the measured
191+
disturbances, at ``\mathbf{d_0}``. The Moore-Penrose pseudo-inverse computes
192+
``\mathbf{(I - A)^{-1}}`` to support integrating `model` (integrator states will be 0).
192193
"""
193194
function steadystate(model::LinModel, u, d=Float64[])
194195
return pinv(I - model.A)*(model.Bu*(u - model.uop) + model.Bd*(d - model.dop))
195196
end
196197

198+
197199
"""
198200
f(model::LinModel, x, u, d)
199201

src/state_estim.jl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ function augment_model(model::LinModel, As, Cs)
154154
return Â, B̂u, Ĉ, B̂d, D̂d
155155
end
156156

157+
"""
158+
isobservable(A, C)
159+
160+
Verify if the state-space `A` and `C` matrices of are observable.
161+
162+
Based on the [Popov-Belevitch-Hautus (PBH) test](https://en.wikipedia.org/wiki/Hautus_lemma).
163+
"""
164+
isobservable(A, C) = all(map->rank([λ * I - A; C]) == size(A, 1), eigvals(A)))
165+
157166
@doc raw"""
158167
f̂(estim::StateEstimator, x̂, u, d)
159168
@@ -293,11 +302,12 @@ function updatestate!(estim::StateEstimator, u, ym, d=Float64[])
293302
return estim.
294303
end
295304

296-
include("estimator/kalman.jl")
297-
include("estimator/luenberger.jl")
298-
include("estimator/internal_model.jl")
299-
300305
"Get [`InternalModel`](@ref) output `ŷ` from current measured outputs `ym` and dist. `d`."
301306
evalŷ(estim::InternalModel, ym, d) = evaloutput(estim,ym, d)
302307
"Other [`StateEstimator`](@ref) ignores `ym` to evaluate `ŷ`."
303-
evalŷ(estim::StateEstimator, _, d) = evaloutput(estim, d)
308+
evalŷ(estim::StateEstimator, _, d) = evaloutput(estim, d)
309+
310+
311+
include("estimator/kalman.jl")
312+
include("estimator/luenberger.jl")
313+
include("estimator/internal_model.jl")

0 commit comments

Comments
 (0)