I finally got all the steps for a matrix inversion working in C. It hasn't been verified yet and I don't have any new data to work with, but so far things seem promising. In regards to inverting a matrix, which had me stuck for some time, the solution is apparently an LU decomposition and then an inversion:
int signum;
gsl_permutation *permut = gsl_permutation_calloc(DIMS);
gsl_matrix *Scratch = gsl_matrix_calloc(DIMS, DIMS);
gsl_matrix *Scratch2 = gsl_matrix_calloc(DIMS, DIMS);
gsl_linalg_LU_decomp(Scratch, permut, &signum);
gsl_linalg_LU_invert(Scratch, permut, Scratch2);
Currently, `Scratch` and `Scratch2` are actually statically allocated in order to reduce dynamic memory. Requires a little bit of indirection between `gsl_matrix_view` and `gsl_matrix`, but I prefer it overall.
The new filter output is in green here, overlaid on the sensor data (blue) and the octave version of the filter (red).

Velocity data is still not being used here, which is a big TODO. Without it, the filter is basically just a running average. I still need to collect more data to evaluate, and also integrate this filter into a CoreFlight app.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
In the code shown you are dynamically allocating storage for the matrix with the calls to gsl_matrix_calloc(). Scratch and Scratch2 are pointers to the matrix and themselves only take up a couple of pointers worth of space, either local or global. This is probably how the library is intended to be used.
Curious why you want to avoid dynamic storage allocation. If the RPi is running Linux, dynamic allocation in programs is commonplace and unremarkable.
Are you sure? yes | no
Correct - apologies for the confusion, I wrote callocs here so that it wouldn't just look like dangling pointers.
In the actual code, I have:
```
double Scratch_data[] = {0....};
gsl_matrix_view Scratch_view = gsl_matrix_view_array(Scratch_data);
gsl_matrix *Scratch = &Scratch_view.matrix;
```
It's definitely more roundabout than a calloc, but I'm trying to write "flight-like" software, which prefers a static memory footprint. No real requirements on this other than my own preference.
Are you sure? yes | no
Unless Scratch_data has to be initialised to something non-zero, I would leave out the initialisation as that will cause the variable to be put in the DATA section increasing executable size and load time, while leaving it out will put it in the BSS section which will be zeroed on program startup anyway.
Are you sure? yes | no