Open calcmogul opened 11 months ago
Thanks for the heads up! May swap this in if we end up leaning heavily on this again. I don't think that DARE solving has been the bottleneck on anything recently, although discretization definitely has been, so this'll be helpful.
I thought you may be interested that I contributed a new DARE solver to WPILib that's 2.8x faster than SLICOT, the solver you use now, based on roboRIO benchmarking on a 5 state, 2 input differential drive LQR problem.
The gist of the algorithm from DOI 10.1080/00207170410001714988 is:
The preconditions necessary for convergence are:
The paper proves convergence under weaker conditions, but it seems to involve solving a generalized eigenvalue problem with the QZ algorithm. SLICOT and Drake use that to solve the whole problem, so it seemed too expensive to bother attempting.
The precondition checks turned out to be 50-60% of the total algorithm runtime, so WPILib exposed a function that skips them if the user knows they'll be satisfied. This would be a good candidate for your Kalman filter error covariance init code, since a comment in there mentioned it didn't use the DARE solver because it had unnecessary checks.
Here's WPILib's impl, which supports static sizing (for performance) and dynamic sizing (for JNI) and throws exceptions on precondition violations. https://github.com/wpilibsuite/allwpilib/blob/main/wpimath/src/main/native/include/frc/DARE.h
I'd recommend std::expected instead of exceptions for your use case.