One of the coolest things I learned in university was that you can just put rotation matrices inside the state of a Kalman filter if you just override the + operator to take a matrix and a change in vector space and the — operator to take two matrices. This allows you to estimate rotations without the fear of gimbal lock.