Intuition What this page is
The parent note gave you the rank test for observability . Here we run it across every kind of case a problem can hand you — clean full-rank systems, degenerate zero-coupling systems, systems that need a picture, systems that are technically observable but barely , and a couple of exam traps. By the end, no scenario should surprise you.
Recall the one tool we use everywhere:
O = C C A C A 2 ⋮ C A n − 1 , observable ⟺ rank ( O ) = n .
Here n = number of states, O has one block-row per power of A , and "rank" counts how many rows are linearly independent (i.e. not copies or scaled sums of each other).
Every observability problem falls into one of these cells . Each worked example below is tagged with the cell(s) it covers.
Cell
What makes it different
Covered by
A. Coupling saves you
unmeasured state drives a measured one → observable
Ex 1
B. Decoupled & blind
unmeasured state connected to nothing → NOT observable
Ex 2
C. Degenerate zero dynamics
A = 0 (pure integrators), single sensor
Ex 3
D. Multi-output redundancy
extra sensor rows add no rank
Ex 4
E. 3-state chain
need the full A 2 block; picture of information flow
Ex 5
F. Weak/limiting observability
full rank but nearly singular as a parameter → 0
Ex 6
G. Real-world word problem
attitude + gyro bias, sensor choice matters
Ex 7
H. Exam twist
"add a sensor to fix it" / duality with controllability
Ex 8
The examples together touch every cell .
Worked example Position–velocity, measure position only
A = [ 0 0 1 0 ] , C = [ 1 0 ] , n = 2.
State is x = ( position , velocity ) . Sensor reads position.
Forecast: we only measure position — can a filter still recover velocity? Guess yes/no before reading.
Bottom power first: C = [ 1 0 ] .
Why this step? The first block-row of O is always C — it says "what do we see with zero derivatives."
C A = [ 1 0 ] [ 0 0 1 0 ] = [ 0 1 ] .
Why this step? C A is the first derivative y ˙ ( 0 ) = C A x ( 0 ) ; it tells us what the rate of change of the measurement reveals. Here it exposes the velocity component.
Stack and rank:
O = [ 1 0 0 1 ] , rank = 2 = n ⇒ observable .
Why this step? Two independent rows spanning both coordinates ⇒ null space is { 0 } ⇒ unique x ( 0 ) .
Verify: the two rows are the standard basis vectors — clearly independent, determinant = 1 = 0 . Because A 12 = 1 (velocity drives position), how fast the position moves is literally the velocity. The window shows position; the motion of that window leaks velocity.
Worked example Two independent decay modes, measure only one
A = [ − 1 0 0 − 2 ] , C = [ 1 0 ] .
Forecast: two separate springs, we watch only one. Observable?
C = [ 1 0 ] . Why? first block-row.
C A = [ 1 0 ] [ − 1 0 0 − 2 ] = [ − 1 0 ] .
Why this step? The derivative of the measurement. Notice the second entry is still zero — no matter how we differentiate, state 2 never appears.
Stack:
O = [ 1 − 1 0 0 ] , rank = 1 = 2 ⇒ NOT observable .
Why? Second row is − 1 × first row ⇒ only one independent row.
Verify: the null space contains v = ( 0 , 1 ) ⊤ : O v = ( 0 , 0 ) ⊤ . So an initial state of "x 2 = anything, x 1 = 0 " gives y ≡ 0 . State 2 is a sealed box. Its Kalman covariance never shrinks.
Worked example Two pure integrators,
A = 0
A = [ 0 0 0 0 ] , C = [ 1 1 ] .
Forecast: with no internal dynamics (A = 0 ), differentiating the output is useless — everything stands still. Observable?
C = [ 1 1 ] . Why? We measure the sum x 1 + x 2 .
C A = [ 1 1 ] ⋅ 0 = [ 0 0 ] .
Why this step? With A = 0 the state never moves, so y ˙ ( 0 ) = 0 carries no info — the whole "derivative pump" is dead.
Stack:
O = [ 1 0 1 0 ] , rank = 1 = 2 ⇒ NOT observable .
Verify: null space contains v = ( 1 , − 1 ) ⊤ since C v = 1 − 1 = 0 . We only ever learn the sum x 1 + x 2 ; the difference x 1 − x 2 is forever hidden. Lesson: when A = 0 , observability collapses to "does C alone have rank n ?" — you need at least n independent sensor rows.
Worked example A second sensor that adds nothing
A = [ − 1 0 0 − 2 ] , C = [ 1 2 0 0 ] .
We added a second sensor measuring 2 x 1 . Same system as Example 2 but with "more data".
Forecast: more sensors — does that finally make x 2 observable? (This is the classic trap.)
C has two rows [ 1 0 ] and [ 2 0 ] . Why? two sensors ⇒ two block-rows of C .
C A = [ 1 2 0 0 ] [ − 1 0 0 − 2 ] = [ − 1 − 2 0 0 ] .
Why this step? Every derivative still has a zero in the x 2 slot.
Stack (4 rows):
O = 1 2 − 1 − 2 0 0 0 0 , rank = 1 = 2 ⇒ NOT observable .
Why? All four rows are multiples of [ 1 0 ] . Four rows, one independent direction.
Verify: the second sensor reads 2 x 1 — a scalar multiple of what sensor 1 already gives. It is a linear combination already visible . Rank counts independence, not row count. Adding sensors that see the same thing never buys observability.
x 3 → x 2 → x 1 , measure only x 1
A = 0 0 0 1 0 0 0 1 0 , C = [ 1 0 0 ] , n = 3.
This is position–velocity–acceleration: x ˙ 1 = x 2 , x ˙ 2 = x 3 , x ˙ 3 = 0 . We measure position x 1 only. This is the case where you must go all the way to the A 2 block.
Forecast: one sensor at the end of a three-link chain. Observable? Look at the figure of information flow.
C = [ 1 0 0 ] . Why? we see position (derivative order 0).
C A = [ 0 1 0 ] . Why this step? first derivative y ˙ = x 2 — velocity leaks in through A 12 = 1 .
C A 2 = [ 0 0 1 ] . Why this step? second derivative y ¨ = x 3 — acceleration leaks in through the chain A 12 A 23 . This is why we needed the A 2 block: the deepest state only shows up two differentiations later.
Stack:
O = 1 0 0 0 1 0 0 0 1 = I 3 , rank = 3 = n ⇒ observable .
Verify: O = I , determinant 1 — perfectly observable. In the figure, the red arrows show each state pushing into the next until it reaches the window at x 1 . Lesson: a full chain into the measured state is observable even from a single sensor , but you must climb to A n − 1 to prove it.
Worked example Full rank, but barely — the near-degenerate limit
A = [ − 1 0 0 − 1 − ε ] , C = [ 1 1 ] , ε > 0 small .
Two decay modes with almost equal rates, measured through their sum.
Forecast: the two modes are nearly identical. Technically observable? And what happens as ε → 0 ?
C = [ 1 1 ] . Why? we measure x 1 + x 2 .
C A = [ − 1 − 1 − ε ] . Why this step? the derivative weights the two modes differently — this difference is the only thing separating them.
Stack and compute the determinant:
O = [ 1 − 1 1 − 1 − ε ] , det O = ( 1 ) ( − 1 − ε ) − ( 1 ) ( − 1 ) = − ε .
Why this step? For a 2 × 2 square O , rank = 2 ⟺ det = 0 .
Case split on ε :
ε > 0 : det = − ε = 0 ⇒ observable .
ε = 0 : det = 0 ⇒ NOT observable (both modes decay identically, only their sum is ever visible — exactly Example 3's "difference is hidden").
Verify: as ε → 0 + the determinant → 0 , so O becomes ill-conditioned. Technically full rank, but the Gramian has a tiny eigenvalue: the difference mode is weakly observable and noise swamps it. Lesson: "observable" is a yes/no, but the degree matters — near-degenerate systems give confident-looking but fragile estimates.
Worked example Spacecraft attitude + drifting gyro bias
A gyro reports rate ω meas = ω true + b , where b is a slowly-drifting bias . Integrating the gyro gives angle. A star tracker measures the true angle θ . States x = ( θ , b ) :
θ ˙ = ω meas − b , b ˙ = 0 ⇒ A = [ 0 0 − 1 0 ] , C = [ 1 0 ] .
Forecast: we measure angle , but really want to know the bias we can't sense directly. Can the filter calibrate the gyro?
C = [ 1 0 ] . Why? star tracker sees angle, not bias.
C A = [ 1 0 ] [ 0 0 − 1 0 ] = [ 0 − 1 ] .
Why this step? The derivative of the angle measurement is influenced by b (through A 12 = − 1 ): a nonzero bias makes the measured angle drift relative to the true angle, and that drift is visible.
Stack:
O = [ 1 0 0 − 1 ] , rank = 2 = n ⇒ observable .
Verify: det O = − 1 = 0 . The bias reveals itself as a creeping mismatch between the integrated gyro angle and the star-tracker angle. This is exactly why real spacecraft use star-trackers to calibrate gyro bias — the bias is unmeasured yet fully observable. (Contrast Example 2: there the hidden state had no pathway to the output; here A 12 = − 1 opens one.)
Worked example Repair an unobservable system, and check the duality
Start from the blind system of Example 2:
A = [ − 1 0 0 − 2 ] .
We showed C old = [ 1 0 ] gives rank 1. Twist: which single new sensor row makes it observable — C a = [ 2 0 ] or C b = [ 0 1 ] ?
Forecast: guess which sensor actually helps before computing.
Try C a = [ 2 0 ] (redundant, like Ex 4). C a A = [ − 2 0 ] .
O a = [ 2 − 2 0 0 ] , rank = 1 ⇒ still blind .
Why? [ 2 0 ] is a multiple of [ 1 0 ] — no new direction.
Try C b = [ 0 1 ] (measures x 2 ). C b A = [ 0 − 2 ] .
O b = [ 0 0 1 − 2 ] , rank = 1.
Why? Alone it sees only x 2 ! Rank still 1 — this sensor is blind to x 1 .
Combine both sensors C = [ 1 0 0 1 ] .
O = 1 0 − 1 0 0 1 0 − 2 , rank = 2 = n ⇒ observable .
Why this step? Now the two independent sensor directions together span R 2 .
Duality cross-check (controllability link): ( A , C ) observable ⟺ ( A ⊤ , C ⊤ ) controllable. With A ⊤ = A (diagonal) and B = C ⊤ = [ 1 0 0 1 ] = I , the controllability matrix [ B A ⊤ B ] = [ 1 0 0 1 − 1 0 0 − 2 ] has rank 2 — controllable, consistent.
Verify: decoupled diagonal dynamics need one independent sensor per decoupled mode. Redundant sensors (C a ) fail; a genuinely new direction succeeds. And the Cayley–Hamilton -guaranteed dual test agrees.
Recall Which cell is which — quick self-test
Coupling into a measured state (position–velocity) — observable? ::: Yes (Cell A) — velocity drives position.
Two decoupled modes, one measured — observable? ::: No (Cell B) — hidden mode has no output pathway.
A = 0 with a single summing sensor — observable? ::: No (Cell C) — only the sum is seen, difference hidden.
Extra sensor = scalar multiple of an existing one — does it help? ::: No (Cell D) — rows without rank.
Nearly-equal decay rates through their sum — observable and how strongly? ::: Full rank for ε > 0 but weakly (det = − ε → 0 ) (Cell F).
Why can a star tracker calibrate gyro bias? ::: Bias creates a visible drift in the measured angle (A 12 = − 1 ), so it is observable (Cell G).
Mnemonic The single question for every scenario
"Does each hidden state have a path — direct or through the dynamics — to the window?" If yes for all states, rank O = n .