capacitor-motioncal 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CapacitorMotionCal.podspec +23 -0
  2. package/README.md +126 -0
  3. package/android/build.gradle +67 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/java/com/denizak/motioncalibration/MotionCalibrationPlugin.java +248 -0
  6. package/android/src/main/jniLibs/arm64-v8a/libmotioncalibration.so +0 -0
  7. package/android/src/main/jniLibs/armeabi-v7a/libmotioncalibration.so +0 -0
  8. package/android/src/main/jniLibs/x86/libmotioncalibration.so +0 -0
  9. package/android/src/main/jniLibs/x86_64/libmotioncalibration.so +0 -0
  10. package/common/imuread.h +156 -0
  11. package/common/magcal.c +602 -0
  12. package/common/mahony.c +330 -0
  13. package/common/matrix.c +446 -0
  14. package/common/motioncalibration.c +7 -0
  15. package/common/motioncalibration.h +12 -0
  16. package/common/quality.c +257 -0
  17. package/common/rawdata.c +349 -0
  18. package/common/serialdata.c +501 -0
  19. package/common/visualize.c +131 -0
  20. package/dist/docs.json +292 -0
  21. package/dist/esm/definitions.d.ts +122 -0
  22. package/dist/esm/definitions.js +2 -0
  23. package/dist/esm/definitions.js.map +1 -0
  24. package/dist/esm/index.d.ts +4 -0
  25. package/dist/esm/index.js +7 -0
  26. package/dist/esm/index.js.map +1 -0
  27. package/dist/esm/web.d.ts +54 -0
  28. package/dist/esm/web.js +58 -0
  29. package/dist/esm/web.js.map +1 -0
  30. package/dist/plugin.cjs.js +72 -0
  31. package/dist/plugin.cjs.js.map +1 -0
  32. package/dist/plugin.js +75 -0
  33. package/dist/plugin.js.map +1 -0
  34. package/ios/Sources/MotionCalibrationPlugin/MotionCalibration-Bridging-Header.h +26 -0
  35. package/ios/Sources/MotionCalibrationPlugin/MotionCalibrationPlugin.swift +200 -0
  36. package/package.json +83 -0
@@ -0,0 +1,446 @@
1
+ // Copyright (c) 2014, Freescale Semiconductor, Inc.
2
+ // All rights reserved.
3
+ // vim: set ts=4:
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are met:
7
+ // * Redistributions of source code must retain the above copyright
8
+ // notice, this list of conditions and the following disclaimer.
9
+ // * Redistributions in binary form must reproduce the above copyright
10
+ // notice, this list of conditions and the following disclaimer in the
11
+ // documentation and/or other materials provided with the distribution.
12
+ // * Neither the name of Freescale Semiconductor, Inc. nor the
13
+ // names of its contributors may be used to endorse or promote products
14
+ // derived from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ // DISCLAIMED. IN NO EVENT SHALL FREESCALE SEMICONDUCTOR, INC. BE LIABLE FOR ANY
20
+ // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ //
27
+ // This file contains matrix manipulation functions.
28
+ //
29
+ #include "imuread.h"
30
+
31
+ // compile time constants that are private to this file
32
+ #define CORRUPTMATRIX 0.001F // column vector modulus limit for rotation matrix
33
+
34
+ // vector components
35
+ #define X 0
36
+ #define Y 1
37
+ #define Z 2
38
+
39
+ // function sets the 3x3 matrix A to the identity matrix
40
+ void f3x3matrixAeqI(float A[][3])
41
+ {
42
+ float *pAij; // pointer to A[i][j]
43
+ int8_t i, j; // loop counters
44
+
45
+ for (i = 0; i < 3; i++) {
46
+ // set pAij to &A[i][j=0]
47
+ pAij = A[i];
48
+ for (j = 0; j < 3; j++) {
49
+ *(pAij++) = 0.0F;
50
+ }
51
+ A[i][i] = 1.0F;
52
+ }
53
+ }
54
+
55
+ // function sets the matrix A to the identity matrix
56
+ void fmatrixAeqI(float *A[], int16_t rc)
57
+ {
58
+ // rc = rows and columns in A
59
+
60
+ float *pAij; // pointer to A[i][j]
61
+ int8_t i, j; // loop counters
62
+
63
+ for (i = 0; i < rc; i++) {
64
+ // set pAij to &A[i][j=0]
65
+ pAij = A[i];
66
+ for (j = 0; j < rc; j++) {
67
+ *(pAij++) = 0.0F;
68
+ }
69
+ A[i][i] = 1.0F;
70
+ }
71
+ }
72
+
73
+ // function sets every entry in the 3x3 matrix A to a constant scalar
74
+ void f3x3matrixAeqScalar(float A[][3], float Scalar)
75
+ {
76
+ float *pAij; // pointer to A[i][j]
77
+ int8_t i, j; // counters
78
+
79
+ for (i = 0; i < 3; i++) {
80
+ // set pAij to &A[i][j=0]
81
+ pAij = A[i];
82
+ for (j = 0; j < 3; j++) {
83
+ *(pAij++) = Scalar;
84
+ }
85
+ }
86
+ }
87
+
88
+ // function multiplies all elements of 3x3 matrix A by the specified scalar
89
+ void f3x3matrixAeqAxScalar(float A[][3], float Scalar)
90
+ {
91
+ float *pAij; // pointer to A[i][j]
92
+ int8_t i, j; // loop counters
93
+
94
+ for (i = 0; i < 3; i++) {
95
+ // set pAij to &A[i][j=0]
96
+ pAij = A[i];
97
+ for (j = 0; j < 3; j++) {
98
+ *(pAij++) *= Scalar;
99
+ }
100
+ }
101
+ }
102
+
103
+ // function negates all elements of 3x3 matrix A
104
+ void f3x3matrixAeqMinusA(float A[][3])
105
+ {
106
+ float *pAij; // pointer to A[i][j]
107
+ int8_t i, j; // loop counters
108
+
109
+ for (i = 0; i < 3; i++) {
110
+ // set pAij to &A[i][j=0]
111
+ pAij = A[i];
112
+ for (j = 0; j < 3; j++) {
113
+ *pAij = -*pAij;
114
+ pAij++;
115
+ }
116
+ }
117
+ }
118
+
119
+ // function directly calculates the symmetric inverse of a symmetric 3x3 matrix
120
+ // only the on and above diagonal terms in B are used and need to be specified
121
+ void f3x3matrixAeqInvSymB(float A[][3], float B[][3])
122
+ {
123
+ float fB11B22mB12B12; // B[1][1] * B[2][2] - B[1][2] * B[1][2]
124
+ float fB12B02mB01B22; // B[1][2] * B[0][2] - B[0][1] * B[2][2]
125
+ float fB01B12mB11B02; // B[0][1] * B[1][2] - B[1][1] * B[0][2]
126
+ float ftmp; // determinant and then reciprocal
127
+
128
+ // calculate useful products
129
+ fB11B22mB12B12 = B[1][1] * B[2][2] - B[1][2] * B[1][2];
130
+ fB12B02mB01B22 = B[1][2] * B[0][2] - B[0][1] * B[2][2];
131
+ fB01B12mB11B02 = B[0][1] * B[1][2] - B[1][1] * B[0][2];
132
+
133
+ // set ftmp to the determinant of the input matrix B
134
+ ftmp = B[0][0] * fB11B22mB12B12 + B[0][1] * fB12B02mB01B22 + B[0][2] * fB01B12mB11B02;
135
+
136
+ // set A to the inverse of B for any determinant except zero
137
+ if (ftmp != 0.0F) {
138
+ ftmp = 1.0F / ftmp;
139
+ A[0][0] = fB11B22mB12B12 * ftmp;
140
+ A[1][0] = A[0][1] = fB12B02mB01B22 * ftmp;
141
+ A[2][0] = A[0][2] = fB01B12mB11B02 * ftmp;
142
+ A[1][1] = (B[0][0] * B[2][2] - B[0][2] * B[0][2]) * ftmp;
143
+ A[2][1] = A[1][2] = (B[0][2] * B[0][1] - B[0][0] * B[1][2]) * ftmp;
144
+ A[2][2] = (B[0][0] * B[1][1] - B[0][1] * B[0][1]) * ftmp;
145
+ } else {
146
+ // provide the identity matrix if the determinant is zero
147
+ f3x3matrixAeqI(A);
148
+ }
149
+ }
150
+
151
+ // function calculates the determinant of a 3x3 matrix
152
+ float f3x3matrixDetA(float A[][3])
153
+ {
154
+ return (A[X][X] * (A[Y][Y] * A[Z][Z] - A[Y][Z] * A[Z][Y]) +
155
+ A[X][Y] * (A[Y][Z] * A[Z][X] - A[Y][X] * A[Z][Z]) +
156
+ A[X][Z] * (A[Y][X] * A[Z][Y] - A[Y][Y] * A[Z][X]));
157
+ }
158
+
159
+ // function computes all eigenvalues and eigenvectors of a real symmetric matrix A[0..n-1][0..n-1]
160
+ // stored in the top left of a 10x10 array A[10][10]
161
+ // A[][] is changed on output.
162
+ // eigval[0..n-1] returns the eigenvalues of A[][].
163
+ // eigvec[0..n-1][0..n-1] returns the normalized eigenvectors of A[][]
164
+ // the eigenvectors are not sorted by value
165
+ void eigencompute(float A[][10], float eigval[], float eigvec[][10], int8_t n)
166
+ {
167
+ // maximum number of iterations to achieve convergence: in practice 6 is typical
168
+ #define NITERATIONS 15
169
+
170
+ // various trig functions of the jacobi rotation angle phi
171
+ float cot2phi, tanhalfphi, tanphi, sinphi, cosphi;
172
+ // scratch variable to prevent over-writing during rotations
173
+ float ftmp;
174
+ // residue from remaining non-zero above diagonal terms
175
+ float residue;
176
+ // matrix row and column indices
177
+ int8_t ir, ic;
178
+ // general loop counter
179
+ int8_t j;
180
+ // timeout ctr for number of passes of the algorithm
181
+ int8_t ctr;
182
+
183
+ // initialize eigenvectors matrix and eigenvalues array
184
+ for (ir = 0; ir < n; ir++) {
185
+ // loop over all columns
186
+ for (ic = 0; ic < n; ic++) {
187
+ // set on diagonal and off-diagonal elements to zero
188
+ eigvec[ir][ic] = 0.0F;
189
+ }
190
+
191
+ // correct the diagonal elements to 1.0
192
+ eigvec[ir][ir] = 1.0F;
193
+
194
+ // initialize the array of eigenvalues to the diagonal elements of m
195
+ eigval[ir] = A[ir][ir];
196
+ }
197
+
198
+ // initialize the counter and loop until converged or NITERATIONS reached
199
+ ctr = 0;
200
+ do {
201
+ // compute the absolute value of the above diagonal elements as exit criterion
202
+ residue = 0.0F;
203
+ // loop over rows excluding last row
204
+ for (ir = 0; ir < n - 1; ir++) {
205
+ // loop over above diagonal columns
206
+ for (ic = ir + 1; ic < n; ic++) {
207
+ // accumulate the residual off diagonal terms which are being driven to zero
208
+ residue += fabs(A[ir][ic]);
209
+ }
210
+ }
211
+
212
+ // check if we still have work to do
213
+ if (residue > 0.0F) {
214
+ // loop over all rows with the exception of the last row (since only rotating above diagonal elements)
215
+ for (ir = 0; ir < n - 1; ir++) {
216
+ // loop over columns ic (where ic is always greater than ir since above diagonal)
217
+ for (ic = ir + 1; ic < n; ic++) {
218
+ // only continue with this element if the element is non-zero
219
+ if (fabs(A[ir][ic]) > 0.0F) {
220
+ // calculate cot(2*phi) where phi is the Jacobi rotation angle
221
+ cot2phi = 0.5F * (eigval[ic] - eigval[ir]) / (A[ir][ic]);
222
+
223
+ // calculate tan(phi) correcting sign to ensure the smaller solution is used
224
+ tanphi = 1.0F / (fabs(cot2phi) + sqrtf(1.0F + cot2phi * cot2phi));
225
+ if (cot2phi < 0.0F) {
226
+ tanphi = -tanphi;
227
+ }
228
+
229
+ // calculate the sine and cosine of the Jacobi rotation angle phi
230
+ cosphi = 1.0F / sqrtf(1.0F + tanphi * tanphi);
231
+ sinphi = tanphi * cosphi;
232
+
233
+ // calculate tan(phi/2)
234
+ tanhalfphi = sinphi / (1.0F + cosphi);
235
+
236
+ // set tmp = tan(phi) times current matrix element used in update of leading diagonal elements
237
+ ftmp = tanphi * A[ir][ic];
238
+
239
+ // apply the jacobi rotation to diagonal elements [ir][ir] and [ic][ic] stored in the eigenvalue array
240
+ // eigval[ir] = eigval[ir] - tan(phi) * A[ir][ic]
241
+ eigval[ir] -= ftmp;
242
+ // eigval[ic] = eigval[ic] + tan(phi) * A[ir][ic]
243
+ eigval[ic] += ftmp;
244
+
245
+ // by definition, applying the jacobi rotation on element ir, ic results in 0.0
246
+ A[ir][ic] = 0.0F;
247
+
248
+ // apply the jacobi rotation to all elements of the eigenvector matrix
249
+ for (j = 0; j < n; j++) {
250
+ // store eigvec[j][ir]
251
+ ftmp = eigvec[j][ir];
252
+ // eigvec[j][ir] = eigvec[j][ir] - sin(phi) * (eigvec[j][ic] + tan(phi/2) * eigvec[j][ir])
253
+ eigvec[j][ir] = ftmp - sinphi * (eigvec[j][ic] + tanhalfphi * ftmp);
254
+ // eigvec[j][ic] = eigvec[j][ic] + sin(phi) * (eigvec[j][ir] - tan(phi/2) * eigvec[j][ic])
255
+ eigvec[j][ic] = eigvec[j][ic] + sinphi * (ftmp - tanhalfphi * eigvec[j][ic]);
256
+ }
257
+
258
+ // apply the jacobi rotation only to those elements of matrix m that can change
259
+ for (j = 0; j <= ir - 1; j++) {
260
+ // store A[j][ir]
261
+ ftmp = A[j][ir];
262
+ // A[j][ir] = A[j][ir] - sin(phi) * (A[j][ic] + tan(phi/2) * A[j][ir])
263
+ A[j][ir] = ftmp - sinphi * (A[j][ic] + tanhalfphi * ftmp);
264
+ // A[j][ic] = A[j][ic] + sin(phi) * (A[j][ir] - tan(phi/2) * A[j][ic])
265
+ A[j][ic] = A[j][ic] + sinphi * (ftmp - tanhalfphi * A[j][ic]);
266
+ }
267
+ for (j = ir + 1; j <= ic - 1; j++) {
268
+ // store A[ir][j]
269
+ ftmp = A[ir][j];
270
+ // A[ir][j] = A[ir][j] - sin(phi) * (A[j][ic] + tan(phi/2) * A[ir][j])
271
+ A[ir][j] = ftmp - sinphi * (A[j][ic] + tanhalfphi * ftmp);
272
+ // A[j][ic] = A[j][ic] + sin(phi) * (A[ir][j] - tan(phi/2) * A[j][ic])
273
+ A[j][ic] = A[j][ic] + sinphi * (ftmp - tanhalfphi * A[j][ic]);
274
+ }
275
+ for (j = ic + 1; j < n; j++) {
276
+ // store A[ir][j]
277
+ ftmp = A[ir][j];
278
+ // A[ir][j] = A[ir][j] - sin(phi) * (A[ic][j] + tan(phi/2) * A[ir][j])
279
+ A[ir][j] = ftmp - sinphi * (A[ic][j] + tanhalfphi * ftmp);
280
+ // A[ic][j] = A[ic][j] + sin(phi) * (A[ir][j] - tan(phi/2) * A[ic][j])
281
+ A[ic][j] = A[ic][j] + sinphi * (ftmp - tanhalfphi * A[ic][j]);
282
+ }
283
+ } // end of test for matrix element already zero
284
+ } // end of loop over columns
285
+ } // end of loop over rows
286
+ } // end of test for non-zero residue
287
+ } while ((residue > 0.0F) && (ctr++ < NITERATIONS)); // end of main loop
288
+ }
289
+
290
+ // function uses Gauss-Jordan elimination to compute the inverse of matrix A in situ
291
+ // on exit, A is replaced with its inverse
292
+ void fmatrixAeqInvA(float *A[], int8_t iColInd[], int8_t iRowInd[], int8_t iPivot[], int8_t isize)
293
+ {
294
+ float largest; // largest element used for pivoting
295
+ float scaling; // scaling factor in pivoting
296
+ float recippiv; // reciprocal of pivot element
297
+ float ftmp; // temporary variable used in swaps
298
+ int8_t i, j, k, l, m; // index counters
299
+ int8_t iPivotRow, iPivotCol; // row and column of pivot element
300
+
301
+ // to avoid compiler warnings
302
+ iPivotRow = iPivotCol = 0;
303
+
304
+ // initialize the pivot array to 0
305
+ for (j = 0; j < isize; j++) {
306
+ iPivot[j] = 0;
307
+ }
308
+
309
+ // main loop i over the dimensions of the square matrix A
310
+ for (i = 0; i < isize; i++) {
311
+ // zero the largest element found for pivoting
312
+ largest = 0.0F;
313
+ // loop over candidate rows j
314
+ for (j = 0; j < isize; j++) {
315
+ // check if row j has been previously pivoted
316
+ if (iPivot[j] != 1) {
317
+ // loop over candidate columns k
318
+ for (k = 0; k < isize; k++) {
319
+ // check if column k has previously been pivoted
320
+ if (iPivot[k] == 0) {
321
+ // check if the pivot element is the largest found so far
322
+ if (fabs(A[j][k]) >= largest) {
323
+ // and store this location as the current best candidate for pivoting
324
+ iPivotRow = j;
325
+ iPivotCol = k;
326
+ largest = (float) fabs(A[iPivotRow][iPivotCol]);
327
+ }
328
+ } else if (iPivot[k] > 1) {
329
+ // zero determinant situation: exit with identity matrix
330
+ fmatrixAeqI(A, isize);
331
+ return;
332
+ }
333
+ }
334
+ }
335
+ }
336
+ // increment the entry in iPivot to denote it has been selected for pivoting
337
+ iPivot[iPivotCol]++;
338
+
339
+ // check the pivot rows iPivotRow and iPivotCol are not the same before swapping
340
+ if (iPivotRow != iPivotCol) {
341
+ // loop over columns l
342
+ for (l = 0; l < isize; l++) {
343
+ // and swap all elements of rows iPivotRow and iPivotCol
344
+ ftmp = A[iPivotRow][l];
345
+ A[iPivotRow][l] = A[iPivotCol][l];
346
+ A[iPivotCol][l] = ftmp;
347
+ }
348
+ }
349
+
350
+ // record that on the i-th iteration rows iPivotRow and iPivotCol were swapped
351
+ iRowInd[i] = iPivotRow;
352
+ iColInd[i] = iPivotCol;
353
+
354
+ // check for zero on-diagonal element (singular matrix) and return with identity matrix if detected
355
+ if (A[iPivotCol][iPivotCol] == 0.0F) {
356
+ // zero determinant situation: exit with identity matrix
357
+ fmatrixAeqI(A, isize);
358
+ return;
359
+ }
360
+
361
+ // calculate the reciprocal of the pivot element knowing it's non-zero
362
+ recippiv = 1.0F / A[iPivotCol][iPivotCol];
363
+ // by definition, the diagonal element normalizes to 1
364
+ A[iPivotCol][iPivotCol] = 1.0F;
365
+ // multiply all of row iPivotCol by the reciprocal of the pivot element including the diagonal element
366
+ // the diagonal element A[iPivotCol][iPivotCol] now has value equal to the reciprocal of its previous value
367
+ for (l = 0; l < isize; l++) {
368
+ A[iPivotCol][l] *= recippiv;
369
+ }
370
+ // loop over all rows m of A
371
+ for (m = 0; m < isize; m++) {
372
+ if (m != iPivotCol) {
373
+ // scaling factor for this row m is in column iPivotCol
374
+ scaling = A[m][iPivotCol];
375
+ // zero this element
376
+ A[m][iPivotCol] = 0.0F;
377
+ // loop over all columns l of A and perform elimination
378
+ for (l = 0; l < isize; l++) {
379
+ A[m][l] -= A[iPivotCol][l] * scaling;
380
+ }
381
+ }
382
+ }
383
+ } // end of loop i over the matrix dimensions
384
+
385
+ // finally, loop in inverse order to apply the missing column swaps
386
+ for (l = isize - 1; l >= 0; l--) {
387
+ // set i and j to the two columns to be swapped
388
+ i = iRowInd[l];
389
+ j = iColInd[l];
390
+
391
+ // check that the two columns i and j to be swapped are not the same
392
+ if (i != j) {
393
+ // loop over all rows k to swap columns i and j of A
394
+ for (k = 0; k < isize; k++) {
395
+ ftmp = A[k][i];
396
+ A[k][i] = A[k][j];
397
+ A[k][j] = ftmp;
398
+ }
399
+ }
400
+ }
401
+ }
402
+
403
+ // function re-orthonormalizes a 3x3 rotation matrix
404
+ void fmatrixAeqRenormRotA(float A[][3])
405
+ {
406
+ float ftmp; // scratch variable
407
+
408
+ // normalize the X column of the low pass filtered orientation matrix
409
+ ftmp = sqrtf(A[X][X] * A[X][X] + A[Y][X] * A[Y][X] + A[Z][X] * A[Z][X]);
410
+ if (ftmp > CORRUPTMATRIX) {
411
+ // normalize the x column vector
412
+ ftmp = 1.0F / ftmp;
413
+ A[X][X] *= ftmp;
414
+ A[Y][X] *= ftmp;
415
+ A[Z][X] *= ftmp;
416
+ } else {
417
+ // set x column vector to {1, 0, 0}
418
+ A[X][X] = 1.0F;
419
+ A[Y][X] = A[Z][X] = 0.0F;
420
+ }
421
+
422
+ // force the y column vector to be orthogonal to x using y = y-(x.y)x
423
+ ftmp = A[X][X] * A[X][Y] + A[Y][X] * A[Y][Y] + A[Z][X] * A[Z][Y];
424
+ A[X][Y] -= ftmp * A[X][X];
425
+ A[Y][Y] -= ftmp * A[Y][X];
426
+ A[Z][Y] -= ftmp * A[Z][X];
427
+
428
+ // normalize the y column vector
429
+ ftmp = sqrtf(A[X][Y] * A[X][Y] + A[Y][Y] * A[Y][Y] + A[Z][Y] * A[Z][Y]);
430
+ if (ftmp > CORRUPTMATRIX) {
431
+ // normalize the y column vector
432
+ ftmp = 1.0F / ftmp;
433
+ A[X][Y] *= ftmp;
434
+ A[Y][Y] *= ftmp;
435
+ A[Z][Y] *= ftmp;
436
+ } else {
437
+ // set y column vector to {0, 1, 0}
438
+ A[Y][Y] = 1.0F;
439
+ A[X][Y] = A[Z][Y] = 0.0F;
440
+ }
441
+
442
+ // finally set the z column vector to x vector cross y vector (automatically normalized)
443
+ A[X][Z] = A[Y][X] * A[Z][Y] - A[Z][X] * A[Y][Y];
444
+ A[Y][Z] = A[Z][X] * A[X][Y] - A[X][X] * A[Z][Y];
445
+ A[Z][Z] = A[X][X] * A[Y][Y] - A[Y][X] * A[X][Y];
446
+ }
@@ -0,0 +1,7 @@
1
+ #include "motioncalibration.h"
2
+
3
+ MotionCalibration_t motioncal;
4
+
5
+ void updateBValue(float B) {
6
+ motioncal.B = B * 2;
7
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef MOTION_CALIBRATION_H
2
+ #define MOTION_CALIBRATION_H
3
+
4
+ typedef struct {
5
+ float B;
6
+ } MotionCalibration_t;
7
+
8
+ extern MotionCalibration_t motioncal;
9
+
10
+ void updateBValue(float B);
11
+
12
+ #endif