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.
- package/CapacitorMotionCal.podspec +23 -0
- package/README.md +126 -0
- package/android/build.gradle +67 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/denizak/motioncalibration/MotionCalibrationPlugin.java +248 -0
- package/android/src/main/jniLibs/arm64-v8a/libmotioncalibration.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libmotioncalibration.so +0 -0
- package/android/src/main/jniLibs/x86/libmotioncalibration.so +0 -0
- package/android/src/main/jniLibs/x86_64/libmotioncalibration.so +0 -0
- package/common/imuread.h +156 -0
- package/common/magcal.c +602 -0
- package/common/mahony.c +330 -0
- package/common/matrix.c +446 -0
- package/common/motioncalibration.c +7 -0
- package/common/motioncalibration.h +12 -0
- package/common/quality.c +257 -0
- package/common/rawdata.c +349 -0
- package/common/serialdata.c +501 -0
- package/common/visualize.c +131 -0
- package/dist/docs.json +292 -0
- package/dist/esm/definitions.d.ts +122 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +54 -0
- package/dist/esm/web.js +58 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +72 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +75 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/MotionCalibrationPlugin/MotionCalibration-Bridging-Header.h +26 -0
- package/ios/Sources/MotionCalibrationPlugin/MotionCalibrationPlugin.swift +200 -0
- 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,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
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/common/imuread.h
ADDED
|
@@ -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
|