I have an unscented Kalman filter (UKF) that tracks the state of a robot. The state vector has 12 variables. Each time I carry out a prediction step, my transfer function (naturally) acts on the entire state. However, my sensors provide measurements of different parts of the robot's state, so I may get roll, pitch, yaw and their respective velocities in one measurement, and then linear velocity in another.
My approach to handling this so far has been to simply create sub-matrices for the covariance, carry out my standard UKF update equations, and then stick the resulting values back into the full covariance matrix. However, after a few updates, the UKF yells at me for trying to pass a matrix that isn't positive-definite into a Cholesky Decomposition function. Clearly the covariance is losing its positive-definite properties, and I'm guessing it has to do with my attempts to update subsets of the full covariance matrix.
As an example taken from an actual log file, the following matrix (after the UKF prediction step) is positive-definite:
1.1969 0 0 0 0 0 0.11567 0 0 0 0 0
0 1.9682 0 0 0 0 0 0.98395 0 0 0 0
0 0 1.9682 0 0 0 0 0 0.98395 0 0 0
0 0 0 1.9682 0 0 0 0 0 0.98395 0 0
0 0 0 0 1.9682 0 0 0 0 0 0.98395 0
0 0 0 0 0 1.9682 0 0 0 0 0 0.98395
0.11567 0 0 0 0 0 0.01468 0 0 0 0 0
0 0.98395 0 0 0 0 0 1 0 0 0 0
0 0 0.98395 0 0 0 0 0 1 0 0 0
0 0 0 0.98395 0 0 0 0 0 1 0 0
0 0 0 0 0.98395 0 0 0 0 0 1 0
0 0 0 0 0 0.98395 0 0 0 0 0 1
However, after processing the correction for one variable (in this case, linear X velocity), the matrix becomes:
1.1969 0 0 0 0 0 0.11567 0 0 0 0 0
0 1.9682 0 0 0 0 0 0.98395 0 0 0 0
0 0 1.9682 0 0 0 0 0 0.98395 0 0 0
0 0 0 1.9682 0 0 0 0 0 0.98395 0 0
0 0 0 0 1.9682 0 0 0 0 0 0.98395 0
0 0 0 0 0 1.9682 0 0 0 0 0 0.98395
0.11567 0 0 0 0 0 0.01 0 0 0 0 0
0 0.98395 0 0 0 0 0 1 0 0 0 0
0 0 0.98395 0 0 0 0 0 1 0 0 0
0 0 0 0.98395 0 0 0 0 0 1 0 0
0 0 0 0 0.98395 0 0 0 0 0 1 0
0 0 0 0 0 0.98395 0 0 0 0 0 1
The difference between the two matrices above is
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 -0.00468 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
As you can see, the only difference between the two is the value in the location of the variance of linear X velocity, which is the measurement I just processed. This difference is enough to "break" my covariance matrix.
I have two questions:
Updating a subset of the filter doesn't appear to be the right way to go about things. Is there a better solution?
Alternatively, am I missing a step that would keep my covariance matrix as positive-definite?
Thanks!
EDIT:
It looks like I'm not properly placing the values back into the original covariance matrix. Simply copying the values back isn't sufficient. I need to track the correlation coefficients for the covariance matrix, and make sure that when I update a variance value, I update all the values in its row/column to maintain the correlation coefficient value. I have to do some more testing to verify that this is my issue, but some initial analysis in Matlab suggests that it is. If I'm correct, I'll answer my own question.
EDIT 2:
Given the response below and after trying it, I can see that my original edit idea won't fly. However, I have one more question:
As this is a UKF, I don't actually have Jacobian matrices. I think I see how I would make it work within the UKF update equations, but even in an EKF - and I ask because I have one of those as well - my state-to-measurement function $h$ is going to end up being the identity matrix, as I am directly measuring my state variables. In the case, I take it my "Jacobian" would just be an $m \times n$ matrix with ones in the $(i, i)$ location, where $i$ is the index of the measured values in the measurement vector?