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,23 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapacitorMotionCal'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c}', 'common/**/*.{h,c}'
14
+ s.public_header_files = 'common/*.h'
15
+ s.ios.deployment_target = '13.0'
16
+ s.dependency 'Capacitor'
17
+ s.swift_version = '5.1'
18
+
19
+ s.pod_target_xcconfig = {
20
+ 'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}/common"',
21
+ 'SWIFT_OBJC_BRIDGING_HEADER' => '${PODS_TARGET_SRCROOT}/ios/Sources/MotionCalibrationPlugin/MotionCalibration-Bridging-Header.h'
22
+ }
23
+ end
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Capacitor MotionCal Plugin
2
+
3
+ A Capacitor plugin for motion/magnetometer calibration using native C libraries.
4
+
5
+ ## Installation
6
+
7
+ Install directly from GitHub:
8
+
9
+ ```bash
10
+ npm install github:denizak/motioncal-capacitor
11
+ npx cap sync
12
+ ```
13
+
14
+ Or clone and install locally:
15
+
16
+ ```bash
17
+ git clone https://github.com/denizak/motioncal-capacitor.git capacitor-motioncal
18
+ npm install ./capacitor-motioncal
19
+ npx cap sync
20
+ ```
21
+
22
+ ## API
23
+
24
+ ### updateBValue(options)
25
+
26
+ Update the B (magnetic field magnitude) value.
27
+
28
+ ```typescript
29
+ import { MotionCalibration } from 'capacitor-motioncal';
30
+
31
+ await MotionCalibration.updateBValue({ value: 45.0 });
32
+ ```
33
+
34
+ ### getBValue()
35
+
36
+ Get the current B value.
37
+
38
+ ```typescript
39
+ const result = await MotionCalibration.getBValue();
40
+ console.log('B value:', result.value);
41
+ ```
42
+
43
+ ### readDataFromFile(options)
44
+
45
+ Read calibration data from a file.
46
+
47
+ ```typescript
48
+ const result = await MotionCalibration.readDataFromFile({ filename: 'magdata.bin' });
49
+ console.log('Read result:', result.result);
50
+ ```
51
+
52
+ ### sendCalibration()
53
+
54
+ Send/process the calibration data.
55
+
56
+ ```typescript
57
+ const result = await MotionCalibration.sendCalibration();
58
+ console.log('Calibration result:', result.result);
59
+ ```
60
+
61
+ ### Quality Metrics
62
+
63
+ ```typescript
64
+ const gapError = await MotionCalibration.getQualitySurfaceGapError();
65
+ const varianceError = await MotionCalibration.getQualityMagnitudeVarianceError();
66
+ const wobbleError = await MotionCalibration.getQualityWobbleError();
67
+ const fitError = await MotionCalibration.getQualitySphericalFitError();
68
+ ```
69
+
70
+ ### Calibration Results
71
+
72
+ ```typescript
73
+ // Get hard iron offset [x, y, z]
74
+ const offset = await MotionCalibration.getHardIronOffset();
75
+ console.log('Hard iron offset:', offset.offset);
76
+
77
+ // Get soft iron matrix (3x3)
78
+ const matrix = await MotionCalibration.getSoftIronMatrix();
79
+ console.log('Soft iron matrix:', matrix.matrix);
80
+
81
+ // Get geomagnetic field magnitude
82
+ const magnitude = await MotionCalibration.getGeomagneticFieldMagnitude();
83
+ console.log('Field magnitude:', magnitude.magnitude);
84
+ ```
85
+
86
+ ### Visualization
87
+
88
+ ```typescript
89
+ // Get points for 3D visualization
90
+ const points = await MotionCalibration.getDrawPoints();
91
+ console.log('Draw points:', points.points);
92
+
93
+ // Clear points
94
+ await MotionCalibration.clearDrawPoints();
95
+ ```
96
+
97
+ ### Reset
98
+
99
+ ```typescript
100
+ await MotionCalibration.resetRawData();
101
+ ```
102
+
103
+ ## Full API Reference
104
+
105
+ | Method | Parameters | Returns |
106
+ |--------|------------|---------|
107
+ | `updateBValue` | `{ value: number }` | `Promise<void>` |
108
+ | `getBValue` | - | `Promise<{ value: number }>` |
109
+ | `isSendCalAvailable` | - | `Promise<{ available: number }>` |
110
+ | `readDataFromFile` | `{ filename: string }` | `Promise<{ result: number }>` |
111
+ | `setResultFilename` | `{ filename: string }` | `Promise<void>` |
112
+ | `sendCalibration` | - | `Promise<{ result: number }>` |
113
+ | `getQualitySurfaceGapError` | - | `Promise<{ error: number }>` |
114
+ | `getQualityMagnitudeVarianceError` | - | `Promise<{ error: number }>` |
115
+ | `getQualityWobbleError` | - | `Promise<{ error: number }>` |
116
+ | `getQualitySphericalFitError` | - | `Promise<{ error: number }>` |
117
+ | `displayCallback` | - | `Promise<void>` |
118
+ | `getCalibrationData` | - | `Promise<{ data: string }>` |
119
+ | `getDrawPoints` | - | `Promise<{ points: number[][] }>` |
120
+ | `resetRawData` | - | `Promise<void>` |
121
+ | `getHardIronOffset` | - | `Promise<{ offset: number[] }>` |
122
+ | `getSoftIronMatrix` | - | `Promise<{ matrix: number[][] }>` |
123
+ | `getGeomagneticFieldMagnitude` | - | `Promise<{ magnitude: number }>` |
124
+ | `clearDrawPoints` | - | `Promise<void>` |
125
+
126
+
@@ -0,0 +1,67 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.2.1'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace "com.denizak.motioncalibration"
22
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
26
+ versionCode 1
27
+ versionName "0.0.1"
28
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
29
+
30
+ ndk {
31
+ abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
32
+ }
33
+ }
34
+ buildTypes {
35
+ release {
36
+ minifyEnabled false
37
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
38
+ }
39
+ }
40
+ lintOptions {
41
+ abortOnError false
42
+ }
43
+ compileOptions {
44
+ sourceCompatibility JavaVersion.VERSION_17
45
+ targetCompatibility JavaVersion.VERSION_17
46
+ }
47
+
48
+ sourceSets {
49
+ main {
50
+ jniLibs.srcDirs = ['src/main/jniLibs']
51
+ }
52
+ }
53
+ }
54
+
55
+ repositories {
56
+ google()
57
+ mavenCentral()
58
+ }
59
+
60
+ dependencies {
61
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
62
+ implementation project(':capacitor-android')
63
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
64
+ testImplementation "junit:junit:$junitVersion"
65
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
66
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
67
+ }
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+ </manifest>
@@ -0,0 +1,248 @@
1
+ package com.denizak.motioncalibration;
2
+
3
+ import android.util.Base64;
4
+
5
+ import com.getcapacitor.JSArray;
6
+ import com.getcapacitor.JSObject;
7
+ import com.getcapacitor.Plugin;
8
+ import com.getcapacitor.PluginCall;
9
+ import com.getcapacitor.PluginMethod;
10
+ import com.getcapacitor.annotation.CapacitorPlugin;
11
+
12
+ import org.json.JSONArray;
13
+ import org.json.JSONException;
14
+
15
+ @CapacitorPlugin(name = "MotionCalibration")
16
+ public class MotionCalibrationPlugin extends Plugin {
17
+
18
+ // Load the native library
19
+ static {
20
+ System.loadLibrary("motioncalibration");
21
+ }
22
+
23
+ // Native method declarations
24
+ private native void updateBValueNative(float bValue);
25
+ private native float getBValueNative();
26
+ private native short isSendCalAvailableNative();
27
+ private native int readDataFromFileNative(String filename);
28
+ private native void setResultFilenameNative(String filename);
29
+ private native int sendCalibrationNative();
30
+ private native float getQualitySurfaceGapErrorNative();
31
+ private native float getQualityMagnitudeVarianceErrorNative();
32
+ private native float getQualityWobbleErrorNative();
33
+ private native float getQualitySphericalFitErrorNative();
34
+ private native void displayCallbackNative();
35
+ private native byte[] getCalibrationDataNative();
36
+ private native float[][] convertDrawPoints();
37
+ private native void resetRawDataNative();
38
+ private native float[] getHardIronOffsetNative();
39
+ private native float[][] getSoftIronMatrixNative();
40
+ private native float getGeomagneticFieldMagnitudeNative();
41
+ private native void clearDrawPointsNative();
42
+
43
+ @PluginMethod
44
+ public void updateBValue(PluginCall call) {
45
+ Float value = call.getFloat("value");
46
+ if (value == null) {
47
+ call.reject("Value is required");
48
+ return;
49
+ }
50
+ updateBValueNative(value);
51
+ call.resolve();
52
+ }
53
+
54
+ @PluginMethod
55
+ public void getBValue(PluginCall call) {
56
+ float result = getBValueNative();
57
+ JSObject ret = new JSObject();
58
+ ret.put("value", result);
59
+ call.resolve(ret);
60
+ }
61
+
62
+ @PluginMethod
63
+ public void isSendCalAvailable(PluginCall call) {
64
+ short isAvailable = isSendCalAvailableNative();
65
+ JSObject ret = new JSObject();
66
+ ret.put("available", (int) isAvailable);
67
+ call.resolve(ret);
68
+ }
69
+
70
+ @PluginMethod
71
+ public void readDataFromFile(PluginCall call) {
72
+ String filename = call.getString("filename");
73
+ if (filename == null) {
74
+ call.reject("Filename is required");
75
+ return;
76
+ }
77
+ String fullPath = getContext().getFilesDir().getAbsolutePath() + "/" + filename;
78
+ int result = readDataFromFileNative(fullPath);
79
+ JSObject ret = new JSObject();
80
+ ret.put("result", result);
81
+ call.resolve(ret);
82
+ }
83
+
84
+ @PluginMethod
85
+ public void setResultFilename(PluginCall call) {
86
+ String filename = call.getString("filename");
87
+ if (filename == null) {
88
+ call.reject("Filename is required");
89
+ return;
90
+ }
91
+ String fullPath = getContext().getFilesDir().getAbsolutePath() + "/" + filename;
92
+ setResultFilenameNative(fullPath);
93
+ call.resolve();
94
+ }
95
+
96
+ @PluginMethod
97
+ public void sendCalibration(PluginCall call) {
98
+ getActivity().runOnUiThread(() -> {
99
+ new Thread(() -> {
100
+ int result = sendCalibrationNative();
101
+ JSObject ret = new JSObject();
102
+ ret.put("result", result);
103
+ call.resolve(ret);
104
+ }).start();
105
+ });
106
+ }
107
+
108
+ @PluginMethod
109
+ public void getQualitySurfaceGapError(PluginCall call) {
110
+ float error = getQualitySurfaceGapErrorNative();
111
+ if (Float.isNaN(error)) {
112
+ error = 100.0f;
113
+ }
114
+ JSObject ret = new JSObject();
115
+ ret.put("error", error);
116
+ call.resolve(ret);
117
+ }
118
+
119
+ @PluginMethod
120
+ public void getQualityMagnitudeVarianceError(PluginCall call) {
121
+ float error = getQualityMagnitudeVarianceErrorNative();
122
+ if (Float.isNaN(error)) {
123
+ error = 100.0f;
124
+ }
125
+ JSObject ret = new JSObject();
126
+ ret.put("error", error);
127
+ call.resolve(ret);
128
+ }
129
+
130
+ @PluginMethod
131
+ public void getQualityWobbleError(PluginCall call) {
132
+ float error = getQualityWobbleErrorNative();
133
+ if (Float.isNaN(error)) {
134
+ error = 100.0f;
135
+ }
136
+ JSObject ret = new JSObject();
137
+ ret.put("error", error);
138
+ call.resolve(ret);
139
+ }
140
+
141
+ @PluginMethod
142
+ public void getQualitySphericalFitError(PluginCall call) {
143
+ float error = getQualitySphericalFitErrorNative();
144
+ if (Float.isNaN(error)) {
145
+ error = 100.0f;
146
+ }
147
+ JSObject ret = new JSObject();
148
+ ret.put("error", error);
149
+ call.resolve(ret);
150
+ }
151
+
152
+ @PluginMethod
153
+ public void displayCallback(PluginCall call) {
154
+ displayCallbackNative();
155
+ call.resolve();
156
+ }
157
+
158
+ @PluginMethod
159
+ public void getCalibrationData(PluginCall call) {
160
+ byte[] calibrationData = getCalibrationDataNative();
161
+ if (calibrationData != null) {
162
+ String base64Data = Base64.encodeToString(calibrationData, Base64.DEFAULT);
163
+ JSObject ret = new JSObject();
164
+ ret.put("data", base64Data);
165
+ call.resolve(ret);
166
+ } else {
167
+ call.reject("No calibration data available");
168
+ }
169
+ }
170
+
171
+ @PluginMethod
172
+ public void getDrawPoints(PluginCall call) {
173
+ new Thread(() -> {
174
+ try {
175
+ float[][] points = convertDrawPoints();
176
+ JSArray jsonPoints = new JSArray();
177
+ for (float[] point : points) {
178
+ JSArray jsonPoint = new JSArray();
179
+ for (float coord : point) {
180
+ jsonPoint.put(coord);
181
+ }
182
+ jsonPoints.put(jsonPoint);
183
+ }
184
+ JSObject ret = new JSObject();
185
+ ret.put("points", jsonPoints);
186
+ call.resolve(ret);
187
+ } catch (Exception e) {
188
+ call.reject("Failed to get draw points: " + e.getMessage());
189
+ }
190
+ }).start();
191
+ }
192
+
193
+ @PluginMethod
194
+ public void resetRawData(PluginCall call) {
195
+ resetRawDataNative();
196
+ call.resolve();
197
+ }
198
+
199
+ @PluginMethod
200
+ public void getHardIronOffset(PluginCall call) {
201
+ try {
202
+ float[] offset = getHardIronOffsetNative();
203
+ JSArray jsonOffset = new JSArray();
204
+ for (float val : offset) {
205
+ jsonOffset.put(val);
206
+ }
207
+ JSObject ret = new JSObject();
208
+ ret.put("offset", jsonOffset);
209
+ call.resolve(ret);
210
+ } catch (Exception e) {
211
+ call.reject("Failed to get hard iron offset: " + e.getMessage());
212
+ }
213
+ }
214
+
215
+ @PluginMethod
216
+ public void getSoftIronMatrix(PluginCall call) {
217
+ try {
218
+ float[][] matrix = getSoftIronMatrixNative();
219
+ JSArray jsonMatrix = new JSArray();
220
+ for (float[] row : matrix) {
221
+ JSArray jsonRow = new JSArray();
222
+ for (float val : row) {
223
+ jsonRow.put(val);
224
+ }
225
+ jsonMatrix.put(jsonRow);
226
+ }
227
+ JSObject ret = new JSObject();
228
+ ret.put("matrix", jsonMatrix);
229
+ call.resolve(ret);
230
+ } catch (Exception e) {
231
+ call.reject("Failed to get soft iron matrix: " + e.getMessage());
232
+ }
233
+ }
234
+
235
+ @PluginMethod
236
+ public void getGeomagneticFieldMagnitude(PluginCall call) {
237
+ float magnitude = getGeomagneticFieldMagnitudeNative();
238
+ JSObject ret = new JSObject();
239
+ ret.put("magnitude", magnitude);
240
+ call.resolve(ret);
241
+ }
242
+
243
+ @PluginMethod
244
+ public void clearDrawPoints(PluginCall call) {
245
+ clearDrawPointsNative();
246
+ call.resolve();
247
+ }
248
+ }
@@ -0,0 +1,156 @@
1
+ #ifndef IMUread_h_
2
+ #define IMUread_h_
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <stdint.h>
7
+ #include <stdarg.h>
8
+ #include <string.h>
9
+ #include <ctype.h>
10
+ #include <math.h>
11
+ #include <errno.h>
12
+ #include <sys/types.h>
13
+ #include <sys/stat.h>
14
+ #include <fcntl.h>
15
+ #include <termios.h>
16
+ #include <unistd.h>
17
+
18
+ #define TIMEOUT_MSEC 14
19
+
20
+ #define MAGBUFFSIZE 650 // Freescale's lib needs at least 392
21
+
22
+ #ifdef __cplusplus
23
+ extern "C"{
24
+ #endif
25
+
26
+ typedef struct {
27
+ float x;
28
+ float y;
29
+ float z;
30
+ //int valid;
31
+ } Point_t;
32
+
33
+ typedef struct {
34
+ float q0; // w
35
+ float q1; // x
36
+ float q2; // y
37
+ float q3; // z
38
+ } Quaternion_t;
39
+ extern Quaternion_t current_orientation;
40
+
41
+ extern int port_is_open(void);
42
+ extern int open_port(const char *name);
43
+ extern int read_serial_data(void);
44
+ extern int write_serial_data(const void *ptr, int len);
45
+ extern void close_port(void);
46
+ void raw_data_reset(void);
47
+ void cal1_data(const float *data);
48
+ void cal2_data(const float *data);
49
+ void calibration_confirmed(void);
50
+ void raw_data(const int16_t *data);
51
+ extern int send_calibration(void);
52
+ void visualize_init(void);
53
+ void apply_calibration(int16_t rawx, int16_t rawy, int16_t rawz, Point_t *out);
54
+ extern void display_callback(void);
55
+ void resize_callback(int width, int height);
56
+ int MagCal_Run(void);
57
+ void quality_reset(void);
58
+ void quality_update(const Point_t *point);
59
+ extern float quality_surface_gap_error(void);
60
+ extern float quality_magnitude_variance_error(void);
61
+ extern float quality_wobble_error(void);
62
+ extern float quality_spherical_fit_error(void);
63
+ extern short is_send_cal_available(void);
64
+ extern void set_result_filename(const char *filename);
65
+
66
+ // PhiEs start ==
67
+ extern void clear_file(const char *filename);
68
+ extern int read_ipc_file_data(const char *filename);
69
+ extern int write_ipc_file_data(const void *ptr, int len);
70
+ extern const uint8_t* get_calibration_data(void);
71
+ extern float* get_draw_points(void);
72
+ extern int get_draw_points_count(void);
73
+ extern void clear_draw_points(void); // <-- Added function declaration here
74
+ // PhiEs end ======
75
+
76
+ // Expose MagCalibration_t properties
77
+ extern void get_hard_iron_offset(float V[3]);
78
+ extern void get_soft_iron_matrix(float invW[3][3]);
79
+ extern float get_geomagnetic_field_magnitude(void);
80
+
81
+ // magnetic calibration & buffer structure
82
+ typedef struct {
83
+ float V[3]; // current hard iron offset x, y, z, (uT)
84
+ float invW[3][3]; // current inverse soft iron matrix
85
+ float B; // current geomagnetic field magnitude (uT)
86
+ float FourBsq; // current 4*B*B (uT^2)
87
+ float FitError; // current fit error %
88
+ float FitErrorAge; // current fit error % (grows automatically with age)
89
+ float trV[3]; // trial value of hard iron offset z, y, z (uT)
90
+ float trinvW[3][3]; // trial inverse soft iron matrix size
91
+ float trB; // trial value of geomagnetic field magnitude in uT
92
+ float trFitErrorpc; // trial value of fit error %
93
+ float A[3][3]; // ellipsoid matrix A
94
+ float invA[3][3]; // inverse of ellipsoid matrix A
95
+ float matA[10][10]; // scratch 10x10 matrix used by calibration algorithms
96
+ float matB[10][10]; // scratch 10x10 matrix used by calibration algorithms
97
+ float vecA[10]; // scratch 10x1 vector used by calibration algorithms
98
+ float vecB[4]; // scratch 4x1 vector used by calibration algorithms
99
+ int8_t ValidMagCal; // integer value 0, 4, 7, 10 denoting both valid calibration and solver used
100
+ int16_t BpFast[3][MAGBUFFSIZE]; // uncalibrated magnetometer readings
101
+ int8_t valid[MAGBUFFSIZE]; // 1=has data, 0=empty slot
102
+ int16_t MagBufferCount; // number of magnetometer readings
103
+ } MagCalibration_t;
104
+
105
+ extern MagCalibration_t magcal;
106
+
107
+ void f3x3matrixAeqI(float A[][3]);
108
+ void fmatrixAeqI(float *A[], int16_t rc);
109
+ void f3x3matrixAeqScalar(float A[][3], float Scalar);
110
+ void f3x3matrixAeqInvSymB(float A[][3], float B[][3]);
111
+ void f3x3matrixAeqAxScalar(float A[][3], float Scalar);
112
+ void f3x3matrixAeqMinusA(float A[][3]);
113
+ float f3x3matrixDetA(float A[][3]);
114
+ void eigencompute(float A[][10], float eigval[], float eigvec[][10], int8_t n);
115
+ void fmatrixAeqInvA(float *A[], int8_t iColInd[], int8_t iRowInd[], int8_t iPivot[], int8_t isize);
116
+ void fmatrixAeqRenormRotA(float A[][3]);
117
+
118
+ #define SENSORFS 100
119
+ #define OVERSAMPLE_RATIO 4
120
+
121
+ // accelerometer sensor structure definition
122
+ #define G_PER_COUNT 0.0001220703125F // = 1/8192
123
+ typedef struct
124
+ {
125
+ float Gp[3]; // slow (typically 25Hz) averaged readings (g)
126
+ float GpFast[3]; // fast (typically 200Hz) readings (g)
127
+ } AccelSensor_t;
128
+
129
+ // magnetometer sensor structure definition
130
+ #define UT_PER_COUNT 0.1F
131
+ typedef struct
132
+ {
133
+ float Bc[3]; // slow (typically 25Hz) averaged calibrated readings (uT)
134
+ float BcFast[3]; // fast (typically 200Hz) calibrated readings (uT)
135
+ } MagSensor_t;
136
+
137
+ // gyro sensor structure definition
138
+ #define DEG_PER_SEC_PER_COUNT 0.0625F // = 1/16
139
+ typedef struct
140
+ {
141
+ float Yp[3]; // raw gyro sensor output (deg/s)
142
+ float YpFast[OVERSAMPLE_RATIO][3]; // fast (typically 200Hz) readings
143
+ } GyroSensor_t;
144
+
145
+ #define USE_MAHONY_FUSION
146
+
147
+ void fusion_init(void);
148
+ void fusion_update(const AccelSensor_t *Accel, const MagSensor_t *Mag, const GyroSensor_t *Gyro,
149
+ const MagCalibration_t *MagCal);
150
+ void fusion_read(Quaternion_t *q);
151
+
152
+ #ifdef __cplusplus
153
+ } // extern "C"
154
+ #endif
155
+
156
+ #endif