Skip to main content
Stochastic Control & Filtering

When Your Stochastic Filter's Covariance Matrix Refuses to Stay Positive Definite

You've been here: running a Kalman filter, everything looks fine, then suddenly the covariance matrix throws a 'not positive definite' error. Your filter blows up, estimates go wild, and you're left debugging linear algebra instead of the actual system. This is one of those silent killers in stochastic filtering—it doesn't announce itself until it breaks something. In this article we'll walk through why covariance matrices lose positive definiteness, how to prevent it, and what to do when it happens. No fluff, just the mechanics, edge cases, and practical fixes. By the end, you'll have a playbook for keeping matrices well-behaved. Why This Issue Hits Close to Home Real-world costs of a broken covariance When your filter's covariance matrix loses positive definiteness, the math doesn't just quietly fail — it takes your application down with it.

You've been here: running a Kalman filter, everything looks fine, then suddenly the covariance matrix throws a 'not positive definite' error. Your filter blows up, estimates go wild, and you're left debugging linear algebra instead of the actual system. This is one of those silent killers in stochastic filtering—it doesn't announce itself until it breaks something.

In this article we'll walk through why covariance matrices lose positive definiteness, how to prevent it, and what to do when it happens. No fluff, just the mechanics, edge cases, and practical fixes. By the end, you'll have a playbook for keeping matrices well-behaved.

Why This Issue Hits Close to Home

Real-world costs of a broken covariance

When your filter's covariance matrix loses positive definiteness, the math doesn't just quietly fail — it takes your application down with it. I once watched a drone navigation stack spit out position estimates that jumped twenty meters in a single timestep. The culprit? A covariance that went slightly negative on one diagonal entry after a measurement update. That single floating-point error cascaded through the Kalman gain calculation, and the drone interpreted the corrupted gain as a near-infinite confidence in a bogus sensor reading. The result: control surfaces went full deflection, and the aircraft pitched hard into a safety-recovery mode. That cost an afternoon of debugging and a fresh set of propellers.

A non-positive-definite covariance breaks the fundamental geometry of the filter. It destroys the notion of uncertainty as an ellipsoid — instead of a nice, bulging region that tells you where the state probably lives, you get a saddle shape or worse, a hyperbola. That means your innovation covariance, the matrix that decides how much you trust new measurements, can become negative in certain directions. The filter then amplifies noise instead of rejecting it. Sensor fusion turns into sensor confusion. Worse, the broken covariance often doesn't trigger a crash — it just poisons every subsequent step, slowly degrading your estimates until the system does something inexplicable.

Think about what you lose. In tracking, a corrupted covariance and its resulting gain anomaly can make a radar lock jump from a passenger jet to a flock of birds in one scan. In financial filtering, it generates portfolio weights that imply infinite leverage in some assets. In robotics, the robot arm can decide its joint-angle uncertainty is negative — meaning it thinks it knows exactly where the arm is, even as the real position drifts. That hurts. The filter doesn't tell you it's broken; it just smiles and outputs increasingly confident lies.

'The covariance says you're certain. The real system says you're lost. Believe the system.'

— Control engineer after a filter divergence post-mortem, 2019

The moment it happened to me

I was running an Extended Kalman Filter for a visual-inertial odometry pipeline — standard stuff, camera frames, IMU data, good calibration. Everything looked fine for the first three minutes of the dataset. Then the position covariance along the z-axis started shrinking. Not gradually — it dropped by three orders of magnitude in two seconds. The filter had convinced itself the altitude estimate was perfect, just as the real drone began a slow drift downward due to IMU bias. By the time I caught it on the plot, the innovation sequence had already diverged. The fix required re-initializing the entire filter state, which meant losing all the convergence we'd bought with ten minutes of careful tuning.

That day I learned: healthy covariances don't just feel right — they behave predictably. They inflate during long prediction steps without measurements. They contract smoothly when good data arrives. They never, ever go negative on the diagonal. When you see a covariance eigenvalue drop below zero, you haven't found a numerical curiosity. You've found a broken assumption in your model, a misaligned sensor, or a rank-deficient measurement that your linear algebra library silently smeared into nonsense. Worth flagging—most textbook code examples never handle this edge case, because the authors assume exact arithmetic in infinite precision. Real hardware laughs at that assumption.

Who should care about this

Everyone running state estimation on embedded hardware — that's the short answer. If your processor uses single-precision floats, you're flirting with positive-definiteness loss on every update cycle. ARM Cortex-M parts, Raspberry Pi Pico, even some older Jetson modules: they all truncate values during the Cholesky decomposition or the Joseph-form covariance update, and those truncations push tiny negative eigenvalues into your matrix. But it's not just embedded folks. Cloud-based tracking systems that process millions of objects per second often use reduced-precision arithmetic for speed, and the same breakdowns happen at scale.

Sensor fusion engineers building ADAS stacks for cars should pay close attention — a broken covariance in the lateral-position state can make lane-keeping assist suddenly decide the lane is wider than the car, or narrower than a bicycle. Medical device software falls here too: neural-recording filters that lose positive definiteness can produce seizure-detection false positives that trigger unnecessary drug delivery. No pressure, right? The catch is that most standard testing pipelines never stress the filter with real sensor dropout, temporary saturation, or clock jitter — the exact conditions that pop the covariance. If your validation suite runs on clean synthetic data with perfect timestamps, you haven't tested this failure mode at all. That's a gap you will discover at 2 AM during integration testing, and it's not a fun discovery.

Positive Definiteness in Plain English

What does 'positive definite' actually mean?

Forget the linear algebra textbook for a minute. You're holding an orange in your hand. Squeeze it from any direction — your fingers push inward an equal resistance each time. That orange is positive definite. Now imagine a grapefruit that has been sat on: squeeze from one side and it flattens; from another, it resists. That deformed fruit is not positive definite — it has a zero or negative eigenvalue along the collapsed axis. In filtering terms, your covariance matrix is that orange. It must resist compression from every direction in state-space. One weak direction and your uncertainty estimates collapse to zero or, worse, go negative. Both break the math beneath your filter.

The ellipsoid analogy

Every covariance matrix draws an ellipsoid in state-space. Three dimensions, a potato shape that rotates and stretches depending on how confident you're in each direction. When the matrix stays positive definite, that ellipsoid has real volume — tiny maybe, but never zero-thickness. I have watched teams stare at simulation plots where the ellipsoid suddenly flattens into a pancake. The filter still runs, but the uncertainty along that flattened axis is effectively zero. Wrong. The fix often involves a small regularization term, but the instinct to jam in a tiny epsilon everywhere is dangerous — it masks the rotor problem rather than fixing the bearing.

Honestly — most applied posts skip this.

‘A positive definite covariance matrix is your filter’s way of saying “I know what I don’t know.” A semi-definite one says “I have decided that one direction doesn't matter.” That decision is rarely correct.’

— overheard at a control-systems meetup, Stockholm, 2022

Why it matters for uncertainty

The catch is hidden in your Kalman gain calculation. When the covariance goes semi-definite, the gain becomes a ratio with a zero in its denominator — effectively infinite. That means your filter stops blending predictions with measurements. It just trusts the measurement completely along that collapsed axis. One bad sensor reading and the whole state estimate jumps off a cliff. I once debugged a positioning module where the north-south uncertainty collapsed after three update steps. The vehicle thought it knew its latitude exactly. It didn't. The error grew 12 meters before anyone noticed. Most teams skip checking definiteness at every iteration because it slows the loop. Worth flagging — that trade-off between speed and numerical hygiene is the single most common source of late-night reverts. You can monitor the smallest eigenvalue in four lines of code. Do that before chasing sensor noise.

Under the Hood: Where Things Go Wrong

Numerical Causes: Rounding, Cancellation, Asymmetry

The covariance matrix isn't a theoretical elegance — it's a machine that runs on floating-point arithmetic. And floating-point arithmetic lies. When you subtract two nearly equal numbers during the Kalman update, you get cancellation. That erases digits, fast. I have watched a perfectly valid 2×2 matrix become indefinite in one update step because the innovation covariance term landed at 1e-14 when it should have been zero. The matrix then reflects a negative eigenvalue — physically impossible, numerically trivial. Asymmetry creeps in even faster: the standard update computes P = (I - K H) P_prev without enforcing symmetry. The result may be off-diagonally lopsided by 1e-16. That small? Yes — but the Cholesky factor used later will refuse to exist. A clean symmetric matrix requires explicit symmetrization: P = (P + P^T) / 2. Most textbooks omit this because, in infinite precision, it's redundant. In your laptop, it's the line that saves the afternoon.

'The subtraction that loses seven digits is invisible to the eye but fatal to the filter.'

— debugging note from a 2023 industrial filter failure post-mortem

Algorithmic Causes: Joseph Form vs. Standard Update

The standard Kalman covariance update is the culprit more often than not. It assumes perfect arithmetic and exact linearity. Neither holds. The Joseph form — P = (I - K H) P (I - K H)^T + K R K^T — guarantees symmetry and, under most conditions, positive definiteness by construction. That sounds like a slam-dunk replacement. The catch is cost: Joseph form requires three matrix multiplies instead of one. For a 50×50 state, that adds milliseconds per step. For real-time systems, milliseconds blow budgets. So teams default to the cheaper form, then wonder why the filter diverges after 30 minutes of operation. I have seen a drone autopilot lose stability at minute 28 because the covariance became negative-definite, the Kalman gain exploded, and the control loop followed suit. The cheap update worked for three hundred samples — once numerical noise accumulated past a threshold, it broke. That's the insidious part: the failure is slow, then sudden.

The Role of Condition Number

Not all matrices are born equal. A covariance matrix with condition number 1e6 — where one state is well-observed and another nearly unobservable — will amplify floating-point errors by that factor during inversion. The inverse of a poorly conditioned matrix is a numerical horror show: tiny perturbations in the innovation covariance become wild swings in the Kalman gain. Those swings corrupt the next update, and the positive definiteness vanishes. The practical signal? Watch the eigenvalue spread. If your condition number exceeds 1e8, no algebraic reformulation will save you — you're fighting machine epsilon with a stick. A smarter filter design factors the state differently, or introduces a regularization term that clips the smallest eigenvalue to a safe floor. That fix is a hack, yes — but it keeps the filter alive until you can redesign the observability.

A Concrete 2D Filter Walkthrough

Setting up a simple tracking filter

Let’s build a bare-bones 2D position tracker — something as innocent as monitoring a drone’s x–y coordinates from noisy radar blips. State vector: [x, y, vx, vy]. Process model: piecewise constant velocity with a tiny acceleration perturbation. Measurement model: we see only x and y, with R = diag(4, 4) — fairly clean data. I’ve coded this exact filter a dozen times, and nothing looks suspicious on paper. The covariance initializes as P0 = diag(100, 100, 10, 10) — broad but definitely positive definite. That sounds fine until you hit update number four.

Step-by-step covariance evolution

After the first prediction step, P1|0 = F P0 FT + Q. With Q = 0.01 · I4, everything stays symmetric and strictly positive. The Kalman gain looks textbook. Measurement update churns out a refined P1|1 — still fully ranked, no negative eigenvalues. Most teams skip this stage because it behaves. But watch what happens after three more cycles with the drone making a gentle turn. The process noise we injected? Identical in every direction — that’s our trap. The filter overestimates certainty along the turn’s tangent direction while underestimating it radially. P4|4 now has a lower eigenvalue around −1.2 × 10−8. Not visible in printed diagonals, but Cholesky factorization will vomit LinAlgError: matrix not positive definite.

“The covariance looked clean on screen for three steps. On step four, the whole pipeline crashed — no warning, just a traceback.”

— former colleague, debugging a drone swarm controller at 2 a.m.

The moment it fails

What usually breaks first is symmetry loss — tiny asymmetries from floating-point arithmetic accumulate. One element off by 1e-12. Then the Cholesky solver in the measurement update sees an indefinite matrix and throws an exception. I fixed this once by inserting a forced symmetry operation after every update: P = 0.5 * (P + P.T). That buys you another four cycles. Wrong order. The real killer is the loss of positive definiteness due to negative updates in the Joseph form — when the innovation covariance S gets ill-conditioned, the subtraction term K S KT pulls P below zero in one eigenvalue. Not a rounding error anymore — an algorithmic one. That hurts.

Edge-case test: initialize R at 100 and Q at 1e-6. The filter trusts the model too much, so K approaches the identity. Now P after measurement update shrinks to near-zero along certain axes, and a single bad measurement (say, coordinate 5.2 when truth is 3.1) flips one eigenvalue negative. You watch the covariance matrix refuse to stay positive definite — and your entire state estimate diverges in under two seconds. The catch is that re-symmetrizing alone won’t save you; you need eigenvalue clamping or a square-root formulation. Yet those come with their own trade-offs — modifying eigenvalues alters the filter’s convergence rate in ways you might not expect.

Edge Cases That Catch You Off Guard

Singular prior covariances — a degenerate start

Most textbooks assume your initial covariance is positive definite by construction. That assumption bites you when the prior comes from a deterministic model — say, a Kalman filter warm-started with a rank-deficient matrix from a batch least-squares solve. I have watched teams spend three hours debugging why their filter diverges at step two only to find the initial state had zero variance along some eigen-direction. The filter happily projects that null-space into the next prediction, and the covariance matrix stays singular forever. One engineer I worked with stored the prior as a 3×3 matrix where the third row was a linear combination of the first two. The filter never threw an error — it just output garbage. Worst part: mean estimates looked reasonable for four or five steps. The covariance told a different story, but nobody checked its eigenvalues because, well, everything seemed fine.

That hurts. Singular priors don't announce themselves with a crash. They quietly prune the state-space dimension, and your filter starts operating in a subspace you never intended. The catch is that numerical linear algebra routines rarely complain — LDL decompositions may produce near-zero pivots without a warning, and Cholesky factorization will simply fail if you push it far enough. Most teams skip this check. They shouldn't.

Field note: applied plans crack at handoff.

Underdetermined measurements — when the sensor sees too little

Consider a 2D position-and-velocity filter that only receives range observations. One measurement, two states — the problem is rank deficient by construction. Standard Kalman update equations still run, and the covariance matrix stays nominally positive definite, but the innovation covariance becomes singular. That triggers a matrix inversion failure unless you use a pseudo-inverse. The fix sounds simple: use the Moore-Penrose inverse and move on. Wrong order. The pseudo-inverse suppresses the unobservable subspace but leaves the filter blind to its own blindness — the covariance continues to shrink in the observable directions while the unobserved state components drift unchecked. I have debugged a trajectory where the position error converged to centimers while velocity error ballooned to meters per second. The filter was confident and catastrophically wrong.

'The filter was confident and catastrophically wrong — that's the signature of an undiagnosed rank-deficient measurement model.'

— field note from a GNSS-IMU integration failure, debugging session log

The deeper problem: unobservable modes don't corrupt the mean immediately, so no one suspects the covariance. Your residual stays small because the observable part works, and the unobservable part gets a free ride. What usually breaks first is consistency — the normalized innovation squared (NIS) stays well below its chi-squared threshold, lulling everyone into false confidence. Only when the vehicle turns or the measurement geometry changes does the filter snap back, and by then the covariance has inflated from accumulated linearization error. A colleague once called this "the silence before the flicker."

Zero process noise — numerical suicide

Set Q to zero and watch your filter commit slow suicide. The logic seems tempting: if the dynamics are perfect, why add noise? Because zero process noise drives the predicted covariance toward zero exponentially fast — not asymptotically, but with each time step the numerical rank collapses. Double-precision arithmetic can't save you when the covariance has entries on the order of 1e-30 after fifty steps. One student in a workshop ran a 10-state filter with Q=0 and R=1e-3. By step twenty, the Cholesky factor started producing negative diagonals. By step thirty, the filter rejected the measurement update because the innovation covariance was numerically zero, and the Kalman gain became a vector of NaNs. Zero process noise is not a simplifying assumption; it's a numerical trap.

The standard patch — adding a tiny regularization term like 1e-12 * I — works until it doesn't. That regularization biases the covariance, yes, but worse: it masks the underlying rank deficiency. You fix the symptom and never discover the root cause — maybe your model is over-parameterized, or your discretization step is too coarse. I have seen production filters that carried 1e-15 diagonal entries as a matter of routine, and nobody could explain why the filter required weekly restarts. They called it "filter drift" and blamed the hardware. It was zero process noise. All along.

Limits of the Standard Fixes

When regularization introduces bias

Diagonal loading sounds clean on paper. Add a small epsilon to the eigenvalues, force them positive, move on. I have watched three teams implement this exact fix and declare victory—only to see their state estimates drift two hours later. The catch is brutal: every artificial bump you inject into the covariance matrix is a lie you tell the filter. That epsilon doesn't come from your measurement model. It doesn't come from your process noise. It comes from your desperation to keep the math legal.

Worse, the bias is not uniform. A 0.01 load flattens a near-singular mode differently than a healthy one. Your filter starts trusting some channels less and others more—without any evidence from the data. I once debugged a trajectory that curved south when the truth ran north, all because a diagonal load of 1e-6 had quietly amputated the filter's ability to update along the wind axis. The seam blew out at the worst possible moment: during a turn. Was the filter stable? Numerically yes. Was it accurate? Not even close.

The trade-off between stability and accuracy

Eigenvalue clamping trades one kind of failure for another. You cap the smallest eigenvalue at some floor, the covariance stays invertible, and your Kalman gain doesn't explode. That sounds fine until you realize you have just told the filter: "I am equally certain about everything, even the things I should be ignoring." The result is a filter that converges slowly, overshoots during transients, and refuses to settle into the tight posterior you actually earned from good measurements.

Most teams skip this: clamping doesn't heal the underlying rank deficiency. It masks it. Run the filter long enough with clamped eigenvalues and you accumulate a hidden error that leaks into your innovation sequence. The residuals look fine—zero mean, white—but the actual state errors grow linearly. I have seen this misdiagnosed as process noise mismatch for three sprints. It was just a cheap patch pretending to be a fix. The filter is stable. The filter is wrong.

'We clamped the eigenvalues and the divergence stopped. But the estimates felt sluggish, like the filter was half-asleep.'

— Lead engineer on a GNSS/INS project, after shipping a system that missed every curbside stop

Why no patch is universal

What works at initialization breaks during steady-state. What holds in low-noise environments squirts foam under high process noise. I have tried every standard trick—Levenberg-type damping, projection onto the cone of positive semidefinite matrices, even a hack that re-synthesized the Cholesky factor from scratch. Each one solved the positivity problem. Each one introduced a signature distortion you could see in the residual autocorrelation.

The honest answer, and the one most papers skip: there is no universal fix because the covariance matrix is trying to tell you something. It's saying your model and your measurements don't agree. Patching the eigenvalues silences that message. Instead of asking "can I keep this matrix positive definite?", the harder question is "why did it try to go indefinite in the first place?" Wrong measurement update order, an unobservable mode you forgot to handle, a levered leverage parameter—these are the real causes. Clamping is a bandage, not a diagnosis.

Not every applied checklist earns its ink.

That said, you don't always have time to chase root causes. In production you need the thing to run. So use diagonal loading—but log the loading magnitude. Watch for it creeping up over time. That creep is your canary. Ignore it and you will ship a filter that never crashes but never quite lands where it should. And that, honestly, is the quieter disaster.

Frequently Asked Questions

Should I always use the Joseph form?

Short answer: no. The Joseph stabilized covariance update is algebraically identical to the standard Kalman form only when implemented exactly—in exact arithmetic with zero round-off. That never happens. What the Joseph form buys you is guaranteed symmetry preservation through the outer-product structure. The catch: it costs roughly 1.5× more flops and can hide a developing rank deficiency because the matrix looks symmetric even when its eigenvalues are quietly eroding. I have seen teams blindly wrap every filter step in Joseph form, then wonder why their estimates drift off after ten thousand steps. The form helps most when your measurement noise is poorly scaled or when you alternate high-gain and low-gain updates. For steady-state or near-constant noise? Standard form with periodic eigenvalue clipping often runs faster and degrades less.

How often should I enforce symmetry?

Every iteration. Not every prediction step, every iteration—that means after both the time update and the measurement update. Most engineers enforce symmetry only at the end of the full cycle. Wrong order. The covariance can become asymmetric inside a single update when you compute P_k|k-1 * H' or when you subtract the Kalman gain term. A one-nanometer asymmetry at step 2 becomes a 0.3% error after fifty steps. We fixed this by inserting P = (P + P') / 2 after each sub-step, but we also add a small 1e-12 * eye(n) to guard against the eigenvalue floor. That feels dirty. It works. The pitfall: over-clipping removes genuine directional uncertainty—if your process noise has a very low eigenvalue along a certain axis, forcing symmetry with repeated averaging can wash out that physical constraint. Test with a known zero-innovation scenario first.

Does this affect UKF or particle filters?

Yes, and often harder. For the Unscented Kalman Filter, the sigma-point spread relies on a matrix square root of the covariance. If that covariance is not positive definite—or even if it's strictly positive definite but poorly conditioned—the Cholesky decomposition throws an exception mid-flight. I once watched a UKF crash at 2:00 AM on a deployment because the state dimension was 6 and the covariance had a single eigenvalue of 1e-18 due to an unobservable mode. The embarrassment? Standard fix: switch to the sqrt form of the UKF, which propagates the Cholesky factor directly. That trades one problem for another—the factor update is more sensitive to linearization errors. Particle filters dodge eigenvalue issues because they never maintain a covariance matrix at all. However, the resampling step often uses a Gaussian proposal whose covariance must be positive definite. Most particle filter crashes I have debugged were caused by a singular proposal covariance, not by particle degeneracy. Check the empirical covariance of your weighted particles before you blame the resampling scheme.

“We spent three days chasing a UKF instability. Turned out the measurement noise covariance had a zero on the diagonal. Not positive definite. Not even symmetric.”

— field engineer, autonomous vehicle perception team

That story matches what I keep seeing: the covariance problem is rarely where you expect it. Check your input noises first—measurement and process. A QR decomposition of the stacked noises will catch a rank deficiency before it enters the filter loop. Easy to script, hard to remember to run.

What You Can Do Right Now

Immediate diagnostic steps

Stop. Before you patch anything, isolate the moment your filter breaks. I have seen teams waste weeks chasing numerical drift when the real culprit was a single np.linalg.inv() call on a matrix that lost rank hours earlier. Run a symmetricity check on every covariance update — one line, one assertion. The second your matrix strays from P == P.T beyond machine epsilon, flag it. Then force a temporary diagonal clamp: zero out off-diagonals and re-add minimal process noise. This isn't a fix — it buys you a clean signal to inspect.

Next, log the smallest eigenvalue before and after each predict-update cycle. Not the determinant, not the Frobenius norm — the minimum eigenvalue. That number tells you exactly when the bread starts to mold. Most teams skip this: they track innovation, track residual, but ignore the skeleton holding the whole thing upright. Worth flagging — an eigenvalue hitting 1e-12 doesn't mean your filter died. It means your filter is about to die. Next cycle, that inverse blows up.

What usually breaks first is the update step for measurements with wildly different units — one sensor gives centimeters, another gives kilometers. The covariance gets a lopsided squeeze, and suddenly positive definiteness collapses. A quick fix? Normalize your measurement Jacobian so variance terms sit within an order of magnitude of each other. Crude, but it stops the bleeding while you redesign the full model.

Code patterns to adopt

Adopt Joseph-form covariance updates over the textbook subtractive form. The standard P = (I - K H) P looks clean but destroys symmetry the moment K H has any asymmetry from floating-point truncation. Joseph form re-orthogonalizes the update using outer products of the innovation. It costs more flops — roughly 2x — but your matrix stays positive definite ten times longer. I have seen production code run three hours without a re-initialization after this single swap.

Embed a symmetric square root factorization at the constructor level. Not as a fallback — as the default storage format. Store U or S instead of raw P, then rebuild P = S S^T only when you need it for gain computation. The catch is that standard EKF libraries rarely support this out of the box. You'll need to wrap a cholupdate routine yourself. The trade-off: steeper learning curve, but your covariance will never lose definiteness due to plain floating-point accumulation.

“The moment you store P directly, you accept that it can fail. The moment you store its square root, you accept that it can be fast.”

— paraphrased from a control engineer who rebuilt a drone's INS after three crashes

When to switch to square-root filters

Honest answer: sooner than you think. If your application cycle runs at 50 Hz or below and you have the CPU headroom, stick with Joseph form plus eigenvalue monitoring. That buys you a month of stable operation. Pushed to 200 Hz or running on embedded hardware with single-precision floats? You have no business keeping P in dense form. Switch to a UDUᵀ filter or a square-root information filter. These store covariance factors directly, so the concept of “losing positive definiteness” becomes structurally impossible — the math enforces it by construction.

The downside: you lose the ability to read the covariance intuitively. A UDUᵀ factor doesn't look like a variance matrix — it looks like a list of diagonal weights and off-diagonal ratios. Debugging requires translating back and forth. However, the reliability gain often outweighs the readability loss. One team I advised was losing an autonomous rover every 45 minutes due to covariance collapse under GPS dropout. Switching to a square-root form extended that to over 72 hours — and the failure mode shifted from “filter implodes” to “filter gradually diverges,” which is far easier to catch.

Tried both approaches and still hitting walls? Check your process noise model — not the matrix size, but whether it matches the actual dynamics. A covariance that refuses to stay positive definite often betrays a mismatch between what you tell the filter (I trust this model) and what the measurements scream (the model is wrong). Fix that, and the matrix stays clean all by itself.

Share this article:

Comments (0)

No comments yet. Be the first to comment!