@wemap/providers 12.10.8 → 12.10.9
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/dist/helpers/CustomMapProvider.d.ts +10 -0
- package/{index.ts → dist/index.d.ts} +0 -14
- package/dist/index.js +1 -3446
- package/dist/index.js.map +1 -1
- package/{src/ProvidersOptions.ts → dist/src/ProvidersOptions.d.ts} +7 -16
- package/dist/src/errors/AskImuOnDesktopError.d.ts +5 -0
- package/dist/src/errors/ContainsIgnoredProviderError.d.ts +5 -0
- package/dist/src/errors/GeolocationApiMissingError.d.ts +5 -0
- package/dist/src/errors/GeolocationPermissionDeniedError.d.ts +5 -0
- package/dist/src/errors/GeolocationPositionUnavailableError.d.ts +5 -0
- package/dist/src/errors/IpResolveServerError.d.ts +5 -0
- package/dist/src/errors/MissingAccelerometerError.d.ts +6 -0
- package/dist/src/errors/MissingArCoreError.d.ts +5 -0
- package/dist/src/errors/MissingGyroscopeError.d.ts +6 -0
- package/dist/src/errors/MissingMagnetometerError.d.ts +5 -0
- package/dist/src/errors/MissingNativeInterfaceError.d.ts +5 -0
- package/dist/src/errors/MissingPoleStarError.d.ts +5 -0
- package/dist/src/errors/MissingSensorError.d.ts +6 -0
- package/dist/src/errors/NoProviderFoundError.d.ts +5 -0
- package/dist/src/events/AvailabilityHelper.d.ts +5 -0
- package/dist/src/events/ProvidersLoggerOld.d.ts +24 -0
- package/dist/src/events/Types.d.ts +34 -0
- package/dist/src/mapmatching/MapMatchingHandler.d.ts +93 -0
- package/dist/src/providers/Constants.d.ts +4 -0
- package/{src/providers/NativeProviders.ts → dist/src/providers/NativeProviders.d.ts} +2 -23
- package/dist/src/providers/Provider.d.ts +64 -0
- package/dist/src/providers/attitude/EkfAttitude.d.ts +41 -0
- package/dist/src/providers/attitude/TurnProvider.d.ts +17 -0
- package/dist/src/providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.d.ts +60 -0
- package/dist/src/providers/attitude/absolute/AbsoluteAttitudeProvider.d.ts +44 -0
- package/dist/src/providers/attitude/relative/RelativeAttitudeFromBrowserProvider.d.ts +31 -0
- package/dist/src/providers/attitude/relative/RelativeAttitudeFromEkfProvider.d.ts +26 -0
- package/dist/src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.d.ts +18 -0
- package/dist/src/providers/attitude/relative/RelativeAttitudeProvider.d.ts +25 -0
- package/dist/src/providers/imu/AccelerometerProvider.d.ts +11 -0
- package/dist/src/providers/imu/GyroscopeProvider.d.ts +11 -0
- package/dist/src/providers/imu/HighRotationsProvider.d.ts +15 -0
- package/dist/src/providers/imu/ImuProvider.d.ts +34 -0
- package/dist/src/providers/imu/MagnetometerCalibrationProvider.d.ts +11 -0
- package/dist/src/providers/inclination/InclinationFromAccProvider.d.ts +18 -0
- package/dist/src/providers/inclination/InclinationFromRelativeAttitudeProvider.d.ts +19 -0
- package/dist/src/providers/inclination/InclinationProvider.d.ts +18 -0
- package/dist/src/providers/legacy/helpers/HeadingUnlocker.d.ts +12 -0
- package/dist/src/providers/legacy/helpers/ThugDetector.d.ts +8 -0
- package/dist/src/providers/others/CameraNativeProvider.d.ts +11 -0
- package/dist/src/providers/others/CameraProjectionMatrixProvider.d.ts +11 -0
- package/dist/src/providers/position/absolute/AbsolutePositionProvider.d.ts +35 -0
- package/dist/src/providers/position/absolute/GnssWifiProvider.d.ts +28 -0
- package/dist/src/providers/position/absolute/IpProvider.d.ts +16 -0
- package/dist/src/providers/position/absolute/PoleStarProvider.d.ts +14 -0
- package/dist/src/providers/position/relative/GeoRelativePositionFromArCoreProvider.d.ts +17 -0
- package/dist/src/providers/position/relative/GeoRelativePositionProvider.d.ts +12 -0
- package/dist/src/providers/position/relative/PdrProvider.d.ts +15 -0
- package/dist/src/providers/steps/StepDetectionLadetto.d.ts +15 -0
- package/dist/src/providers/steps/StepDetectionMinMaxPeaks.d.ts +19 -0
- package/dist/src/providers/steps/StepDetectionMinMaxPeaks2.d.ts +27 -0
- package/dist/src/providers/steps/StepDetectionMinMaxPeaks3.d.ts +24 -0
- package/dist/src/providers/steps/StepProvider.d.ts +36 -0
- package/dist/src/providers/steps/StraightLineProvider.d.ts +21 -0
- package/dist/src/providers/vision/ArCoreProvider.d.ts +50 -0
- package/dist/src/providers/vision/BarcodeProvider.d.ts +11 -0
- package/dist/src/providers/vision/vps/ImageRelocalization.d.ts +11 -0
- package/dist/src/providers/vision/vps/RelativeRotationCalc.d.ts +10 -0
- package/dist/src/providers/vision/vps/VpsMetadata.d.ts +33 -0
- package/dist/src/providers/vision/vps/VpsProvider.d.ts +45 -0
- package/dist/src/providers/vision/vps/VpsRequest.d.ts +18 -0
- package/dist/src/providers/vision/vps/VpsResponse.d.ts +15 -0
- package/dist/src/smoothers/AttitudeSmoother.d.ts +23 -0
- package/dist/src/smoothers/PositionSmoother.d.ts +21 -0
- package/package.json +16 -12
- package/src/errors/AskImuOnDesktopError.ts +0 -10
- package/src/errors/ContainsIgnoredProviderError.ts +0 -10
- package/src/errors/GeolocationApiMissingError.ts +0 -10
- package/src/errors/GeolocationPermissionDeniedError.ts +0 -10
- package/src/errors/GeolocationPositionUnavailableError.ts +0 -10
- package/src/errors/IpResolveServerError.ts +0 -10
- package/src/errors/MissingAccelerometerError.ts +0 -11
- package/src/errors/MissingArCoreError.ts +0 -10
- package/src/errors/MissingGyroscopeError.ts +0 -11
- package/src/errors/MissingMagnetometerError.ts +0 -9
- package/src/errors/MissingNativeInterfaceError.ts +0 -11
- package/src/errors/MissingPoleStarError.ts +0 -10
- package/src/errors/MissingSensorError.ts +0 -15
- package/src/errors/NoProviderFoundError.ts +0 -10
- package/src/events/AvailabilityHelper.spec.ts +0 -30
- package/src/events/AvailabilityHelper.ts +0 -28
- package/src/events/ProvidersLoggerOld.ts +0 -87
- package/src/events/Types.ts +0 -18
- package/src/mapmatching/MapMatchingHandler.spec.ts +0 -142
- package/src/mapmatching/MapMatchingHandler.ts +0 -540
- package/src/providers/Constants.ts +0 -5
- package/src/providers/FakeProvider.spec.ts +0 -49
- package/src/providers/Provider.spec.ts +0 -113
- package/src/providers/Provider.ts +0 -244
- package/src/providers/attitude/EkfAttitude.spec.ts +0 -115
- package/src/providers/attitude/EkfAttitude.ts +0 -233
- package/src/providers/attitude/TurnProvider.ts +0 -58
- package/src/providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.ts +0 -267
- package/src/providers/attitude/absolute/AbsoluteAttitudeProvider.ts +0 -268
- package/src/providers/attitude/relative/RelativeAttitudeFromBrowserProvider.ts +0 -84
- package/src/providers/attitude/relative/RelativeAttitudeFromEkfProvider.ts +0 -89
- package/src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.ts +0 -66
- package/src/providers/attitude/relative/RelativeAttitudeProvider.ts +0 -70
- package/src/providers/imu/AccelerometerProvider.ts +0 -28
- package/src/providers/imu/GyroscopeProvider.ts +0 -27
- package/src/providers/imu/HighRotationsProvider.ts +0 -49
- package/src/providers/imu/ImuProvider.ts +0 -110
- package/src/providers/imu/MagnetometerCalibrationProvider.ts +0 -21
- package/src/providers/inclination/InclinationFromAccProvider.ts +0 -57
- package/src/providers/inclination/InclinationFromRelativeAttitudeProvider.ts +0 -51
- package/src/providers/inclination/InclinationProvider.ts +0 -59
- package/src/providers/legacy/helpers/HeadingUnlocker.spec.ts +0 -53
- package/src/providers/legacy/helpers/HeadingUnlocker.ts +0 -44
- package/src/providers/legacy/helpers/ThugDetector.ts +0 -30
- package/src/providers/others/CameraNativeProvider.ts +0 -29
- package/src/providers/others/CameraProjectionMatrixProvider.ts +0 -25
- package/src/providers/position/absolute/AbsolutePositionProvider.spec.ts +0 -31
- package/src/providers/position/absolute/AbsolutePositionProvider.ts +0 -277
- package/src/providers/position/absolute/GnssWifiProvider.ts +0 -126
- package/src/providers/position/absolute/GnssWifiProviders.spec.ts +0 -90
- package/src/providers/position/absolute/IpProvider.ts +0 -47
- package/src/providers/position/absolute/PoleStarProvider.ts +0 -88
- package/src/providers/position/relative/GeoRelativePositionFromArCoreProvider.ts +0 -82
- package/src/providers/position/relative/GeoRelativePositionProvider.ts +0 -35
- package/src/providers/position/relative/PdrProvider.ts +0 -107
- package/src/providers/steps/StepDetectionLadetto.ts +0 -67
- package/src/providers/steps/StepDetectionMinMaxPeaks.ts +0 -70
- package/src/providers/steps/StepDetectionMinMaxPeaks2.ts +0 -99
- package/src/providers/steps/StepDetectionMinMaxPeaks3.ts +0 -192
- package/src/providers/steps/StepProvider.ts +0 -151
- package/src/providers/steps/StraightLineProvider.ts +0 -69
- package/src/providers/vision/ArCoreProvider.ts +0 -184
- package/src/providers/vision/BarcodeProvider.ts +0 -28
- package/src/providers/vision/vps/ImageRelocalization.ts +0 -98
- package/src/providers/vision/vps/RelativeRotationCalc.ts +0 -58
- package/src/providers/vision/vps/VpsMetadata.ts +0 -63
- package/src/providers/vision/vps/VpsProvider.ts +0 -251
- package/src/providers/vision/vps/VpsRequest.ts +0 -29
- package/src/providers/vision/vps/VpsResponse.ts +0 -43
- package/src/providers/vision/vps/VpsSchema.json +0 -90
- package/src/smoothers/AttitudeSmoother.ts +0 -110
- package/src/smoothers/PositionSmoother.spec.ts +0 -53
- package/src/smoothers/PositionSmoother.ts +0 -96
- package/tsconfig.json +0 -3
- package/vite.config.ts +0 -4
- /package/{src/providers/ProviderState.ts → dist/src/providers/ProviderState.d.ts} +0 -0
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { Matrix_t } from '@wemap/maths';
|
|
2
|
-
import {
|
|
3
|
-
Matrix, Matrix3, Matrix3_t, Matrix4, Matrix4_t,
|
|
4
|
-
Quaternion, Quaternion_t, Vector, Vector3, Vector3_t,
|
|
5
|
-
Vector4_t
|
|
6
|
-
} from '@wemap/maths';
|
|
7
|
-
|
|
8
|
-
type RelativeNoises = { acc: number, gyr: number };
|
|
9
|
-
type AbsoluteNoises = { acc: number, gyr: number, yc: number };
|
|
10
|
-
|
|
11
|
-
type RelativeNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t };
|
|
12
|
-
type AbsoluteNoisesMat = { acc: Matrix3_t, gyr: Matrix3_t, yc: Matrix3_t };
|
|
13
|
-
|
|
14
|
-
const DEFAULT_RELATIVE_NOISES = {
|
|
15
|
-
acc: 0.5,
|
|
16
|
-
gyr: 0.3
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const DEFAULT_ABSOLUTE_NOISES = {
|
|
20
|
-
acc: 0.5,
|
|
21
|
-
gyr: 0.3,
|
|
22
|
-
yc: 2
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
class EkfAttitude {
|
|
26
|
-
P: Matrix4_t;
|
|
27
|
-
accRef: Vector3_t;
|
|
28
|
-
cRef: Vector3_t;
|
|
29
|
-
noises!: { relative: RelativeNoisesMat, absolute: AbsoluteNoisesMat };
|
|
30
|
-
quaternion: Quaternion_t | null;
|
|
31
|
-
|
|
32
|
-
constructor(accRef: Vector3_t = [0, 0, 1], ycRef: Vector3_t = [-1, 0, 0]) {
|
|
33
|
-
|
|
34
|
-
this.accRef = accRef;
|
|
35
|
-
this.cRef = ycRef;
|
|
36
|
-
|
|
37
|
-
this.P = Matrix4.fromDiagVector(Array(4).fill(0.1 ** 2) as Vector4_t);
|
|
38
|
-
|
|
39
|
-
this.quaternion = null;
|
|
40
|
-
|
|
41
|
-
this.noises = {} as never;
|
|
42
|
-
this.setRelativeNoises(DEFAULT_RELATIVE_NOISES);
|
|
43
|
-
this.setAbsoluteNoises(DEFAULT_ABSOLUTE_NOISES);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
setRelativeNoises(relativeNoises: RelativeNoises) {
|
|
47
|
-
this.noises.relative = {
|
|
48
|
-
acc: Matrix3.diag(Array(3).fill(relativeNoises.acc ** 2) as Vector3_t),
|
|
49
|
-
gyr: Matrix3.diag(Array(3).fill(relativeNoises.gyr ** 2) as Vector3_t)
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
setAbsoluteNoises(absoluteNoises: AbsoluteNoises) {
|
|
55
|
-
this.noises.absolute = {
|
|
56
|
-
acc: Matrix3.diag(Array(3).fill(absoluteNoises.acc ** 2) as Vector3_t),
|
|
57
|
-
gyr: Matrix3.diag(Array(3).fill(absoluteNoises.gyr ** 2) as Vector3_t),
|
|
58
|
-
yc: Matrix3.diag(Array(3).fill(absoluteNoises.yc ** 2) as Vector3_t)
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Try to initialize filter.
|
|
64
|
-
* To initialize, we need at least current acceleration (acc)
|
|
65
|
-
*/
|
|
66
|
-
tryInitialize(acc: Vector3_t, mag?: Vector3_t) {
|
|
67
|
-
|
|
68
|
-
const accNormalized = Vector3.normalize(acc);
|
|
69
|
-
|
|
70
|
-
if (mag) {
|
|
71
|
-
const magNormalized = Vector3.normalize(mag);
|
|
72
|
-
|
|
73
|
-
const H = Vector3.normalize(Vector3.cross(magNormalized, accNormalized));
|
|
74
|
-
const M = Vector3.cross(accNormalized, H);
|
|
75
|
-
|
|
76
|
-
const R: Matrix3_t = [
|
|
77
|
-
[H[0], M[0], accNormalized[0]],
|
|
78
|
-
[H[1], M[1], accNormalized[1]],
|
|
79
|
-
[H[2], M[2], accNormalized[2]]
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
this.quaternion = Quaternion.fromMatrix3Matlab(R);
|
|
83
|
-
|
|
84
|
-
} else {
|
|
85
|
-
|
|
86
|
-
const r = Vector3.dot(accNormalized, this.accRef) + 1;
|
|
87
|
-
const v = Vector3.cross(accNormalized, this.accRef);
|
|
88
|
-
|
|
89
|
-
let quaternion: Quaternion_t = [r, v[0], v[1], v[2]];
|
|
90
|
-
quaternion = Quaternion.normalize(quaternion);
|
|
91
|
-
|
|
92
|
-
this.quaternion = quaternion;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return this.quaternion;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
update(diffTime: number, acc: Vector3_t, gyr: Vector3_t, mag?: Vector3_t) {
|
|
99
|
-
|
|
100
|
-
if (!this.quaternion) {
|
|
101
|
-
return this.tryInitialize(acc, mag);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let q = this.quaternion;
|
|
105
|
-
|
|
106
|
-
/* ------------
|
|
107
|
-
* ESTIMATION
|
|
108
|
-
* ------------*/
|
|
109
|
-
|
|
110
|
-
const qArray = q;
|
|
111
|
-
const gyrInt = Vector3.multiplyScalar(gyr, 0.5 * diffTime);
|
|
112
|
-
const F = this.computeC([1, gyrInt[0], gyrInt[1], gyrInt[2]]);
|
|
113
|
-
const qAPriori = Matrix4.multiplyVector(F, q);
|
|
114
|
-
const E1 = Matrix3.diag([qArray[0], qArray[0], qArray[0]]);
|
|
115
|
-
const eSkew = Matrix3.skew([qArray[1], qArray[2], qArray[3]]);
|
|
116
|
-
|
|
117
|
-
const qPart = [-1 * qArray[1], -1 * qArray[2], -1 * qArray[3]];
|
|
118
|
-
const E = Matrix.concatRow([qPart], Matrix3.sum(eSkew, E1));
|
|
119
|
-
|
|
120
|
-
const Qk = Matrix4.multiplyScalar(
|
|
121
|
-
Matrix.multiply(
|
|
122
|
-
Matrix.multiply(E, this.noises[mag ? 'absolute' : 'relative'].gyr),
|
|
123
|
-
Matrix.transpose(E)
|
|
124
|
-
) as Matrix4_t,
|
|
125
|
-
(diffTime / 2) ** 2
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
const pAPriori = Matrix4.sum(
|
|
129
|
-
Matrix4.multiply(
|
|
130
|
-
Matrix4.multiply(F, this.P),
|
|
131
|
-
Matrix4.transpose(F)
|
|
132
|
-
),
|
|
133
|
-
Qk
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
/* ------------
|
|
137
|
-
* CORRECTION
|
|
138
|
-
* ------------*/
|
|
139
|
-
|
|
140
|
-
const accNormalized = Vector3.normalize(acc);
|
|
141
|
-
let dz, K: Matrix_t, H;
|
|
142
|
-
|
|
143
|
-
if (mag) {
|
|
144
|
-
|
|
145
|
-
const magNormalized = Vector3.normalize(mag);
|
|
146
|
-
const yc = Vector3.cross(accNormalized, magNormalized);
|
|
147
|
-
const ycNormalized = Vector3.normalize(yc);
|
|
148
|
-
|
|
149
|
-
const dzYc = Vector3.subtract(ycNormalized, Quaternion.rotateMatlab(qAPriori, this.cRef));
|
|
150
|
-
const dzAcc = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));
|
|
151
|
-
dz = Vector.concat(dzYc, dzAcc);
|
|
152
|
-
|
|
153
|
-
const HYc = this.jacobianES(qAPriori, this.cRef);
|
|
154
|
-
const HAcc = this.jacobianES(qAPriori, this.accRef);
|
|
155
|
-
H = Matrix.concatRow(HYc, HAcc);
|
|
156
|
-
|
|
157
|
-
const RYc = Matrix.concatLine(this.noises.absolute.yc, Matrix3.zeros);
|
|
158
|
-
const RAcc = Matrix.concatLine(Matrix3.zeros, this.noises.absolute.acc);
|
|
159
|
-
const R = Matrix.concatRow(RYc, RAcc);
|
|
160
|
-
|
|
161
|
-
K = Matrix.multiply(
|
|
162
|
-
Matrix.multiply(pAPriori, Matrix.transpose(H)),
|
|
163
|
-
Matrix.inverse(
|
|
164
|
-
Matrix.sum(
|
|
165
|
-
Matrix.multiply(
|
|
166
|
-
Matrix.multiply(H, pAPriori),
|
|
167
|
-
Matrix.transpose(H)
|
|
168
|
-
),
|
|
169
|
-
R
|
|
170
|
-
)
|
|
171
|
-
) as Matrix_t
|
|
172
|
-
);
|
|
173
|
-
} else {
|
|
174
|
-
dz = Vector3.subtract(accNormalized, Quaternion.rotateMatlab(qAPriori, this.accRef));
|
|
175
|
-
H = this.jacobianES(qAPriori, this.accRef);
|
|
176
|
-
const R = this.noises.relative.acc;
|
|
177
|
-
|
|
178
|
-
K = Matrix.multiply(
|
|
179
|
-
Matrix.multiply(pAPriori, Matrix.transpose(H)),
|
|
180
|
-
Matrix3.inverse(
|
|
181
|
-
Matrix3.sum(
|
|
182
|
-
Matrix.multiply(
|
|
183
|
-
Matrix.multiply(H, pAPriori),
|
|
184
|
-
Matrix.transpose(H)
|
|
185
|
-
) as Matrix3_t,
|
|
186
|
-
R
|
|
187
|
-
)
|
|
188
|
-
) as Matrix_t
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
q = Quaternion.sum(
|
|
193
|
-
qAPriori,
|
|
194
|
-
Matrix.multiplyVector(K, dz) as Quaternion_t
|
|
195
|
-
);
|
|
196
|
-
const P = Matrix4.multiply(
|
|
197
|
-
Matrix4.subtract(
|
|
198
|
-
Matrix4.identity,
|
|
199
|
-
Matrix.multiply(K, H) as Matrix4_t
|
|
200
|
-
),
|
|
201
|
-
pAPriori
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
q = Quaternion.normalize(q);
|
|
205
|
-
this.quaternion = q;
|
|
206
|
-
this.P = P;
|
|
207
|
-
|
|
208
|
-
return q;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
computeC(b: Vector4_t): Matrix4_t {
|
|
212
|
-
return [
|
|
213
|
-
[b[0], -b[1], -b[2], -b[3]],
|
|
214
|
-
[b[1], b[0], b[3], -b[2]],
|
|
215
|
-
[b[2], -b[3], b[0], b[1]],
|
|
216
|
-
[b[3], b[2], -b[1], b[0]]
|
|
217
|
-
];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
jacobianES(q: Quaternion_t, v: Vector3_t) {
|
|
221
|
-
|
|
222
|
-
const [qw, qx, qy, qz] = q;
|
|
223
|
-
const [vx, vy, vz] = v;
|
|
224
|
-
|
|
225
|
-
return [
|
|
226
|
-
[2 * qz * vy - 2 * qy * vz, 2 * qy * vy + 2 * qz * vz, 2 * qx * vy - 2 * qw * vz - 4 * qy * vx, 2 * qw * vy + 2 * qx * vz - 4 * qz * vx],
|
|
227
|
-
[2 * qx * vz - 2 * qz * vx, 2 * qw * vz - 4 * qx * vy + 2 * qy * vx, 2 * qx * vx + 2 * qz * vz, 2 * qy * vz - 2 * qw * vx - 4 * qz * vy],
|
|
228
|
-
[2 * qy * vx - 2 * qx * vy, 2 * qz * vx - 4 * qx * vz - 2 * qw * vy, 2 * qw * vx - 4 * qy * vz + 2 * qz * vy, 2 * qx * vx + 2 * qy * vy]
|
|
229
|
-
];
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export default EkfAttitude;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { std } from '@wemap/maths';
|
|
2
|
-
|
|
3
|
-
import Provider from '../Provider.js';
|
|
4
|
-
import RelativeAttitudeProvider from './relative/RelativeAttitudeProvider.js';
|
|
5
|
-
import { RelativeAttitude, Turn } from '../../events/Types.js';
|
|
6
|
-
|
|
7
|
-
class TurnProvider extends Provider<Turn> {
|
|
8
|
-
|
|
9
|
-
static SLIDING_WINDOW_TIME = 0.3; // in seconds
|
|
10
|
-
static STD_THRESHOLD = 0.075;
|
|
11
|
-
static CONSIDER_TURN_UNTIL = 1; // in seconds
|
|
12
|
-
|
|
13
|
-
providerId?: number;
|
|
14
|
-
|
|
15
|
-
slidingWindow: [number, number][] = [];
|
|
16
|
-
|
|
17
|
-
getName = () => 'Turn';
|
|
18
|
-
|
|
19
|
-
availability = () => RelativeAttitudeProvider.getAvailability();
|
|
20
|
-
|
|
21
|
-
start() {
|
|
22
|
-
this.providerId = RelativeAttitudeProvider.addEventListener(
|
|
23
|
-
this._parseRelativeAttitude,
|
|
24
|
-
this.notifyError
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
stop() {
|
|
29
|
-
RelativeAttitudeProvider.removeEventListener(this.providerId);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
isTurning() {
|
|
33
|
-
if (!this.lastEvent || !RelativeAttitudeProvider.lastEvent) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const diffTime = RelativeAttitudeProvider.lastEvent.time as number - this.lastEvent.timestamp;
|
|
38
|
-
return diffTime < TurnProvider.CONSIDER_TURN_UNTIL;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
private _parseRelativeAttitude = (relativeAttitudeEvent: RelativeAttitude) => {
|
|
43
|
-
|
|
44
|
-
const { heading } = relativeAttitudeEvent;
|
|
45
|
-
const timestamp = relativeAttitudeEvent.time as number;
|
|
46
|
-
|
|
47
|
-
this.slidingWindow = this.slidingWindow.filter(item => item[0] >= timestamp - TurnProvider.SLIDING_WINDOW_TIME);
|
|
48
|
-
this.slidingWindow.push([timestamp, heading]);
|
|
49
|
-
|
|
50
|
-
const stdVal = std(this.slidingWindow.map(item => item[1]));
|
|
51
|
-
if (stdVal > TurnProvider.STD_THRESHOLD) {
|
|
52
|
-
this.notify({ timestamp });
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export default new TurnProvider();
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import * as geomag from 'geomag';
|
|
2
|
-
|
|
3
|
-
import { deg2rad, rad2deg, Quaternion, Rotations, Quaternion_t } from '@wemap/maths';
|
|
4
|
-
import { Browser, BrowserUtils } from '@wemap/utils';
|
|
5
|
-
|
|
6
|
-
import Provider from '../../Provider.js';
|
|
7
|
-
import AskImuOnDesktopError from '../../../errors/AskImuOnDesktopError.js';
|
|
8
|
-
import MissingMagnetometerError from '../../../errors/MissingMagnetometerError.js';
|
|
9
|
-
import MissingSensorError from '../../../errors/MissingSensorError.js';
|
|
10
|
-
import AbsolutePositionProvider from '../../position/absolute/AbsolutePositionProvider.js';
|
|
11
|
-
import { AbsoluteAttitude, AbsolutePosition } from '../../../events/Types.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// https://stackoverflow.com/a/73369838/2239938
|
|
15
|
-
export interface DeviceOrientationEventiOS extends DeviceOrientationEvent {
|
|
16
|
-
webkitCompassHeading: number | null;
|
|
17
|
-
webkitCompassAccuracy: number | null;
|
|
18
|
-
requestPermission?: () => Promise<'granted' | 'denied'>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
declare global {
|
|
24
|
-
interface Window {
|
|
25
|
-
addEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;
|
|
26
|
-
addEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;
|
|
27
|
-
removeEventListener(evtName: 'deviceorientationabsolute', cb: (evt: DeviceOrientationEvent) => void, options?: boolean): void;
|
|
28
|
-
removeEventListener(evtName: 'deviceorientation', cb: (evt: DeviceOrientationEventiOS) => void, options?: boolean): void;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame using
|
|
36
|
-
* browser deviceorientation or deviceorientationabsolute
|
|
37
|
-
* The provider does not work until an AbsolutePosition is given. This is necessary to
|
|
38
|
-
* calculate declination.
|
|
39
|
-
*
|
|
40
|
-
* -----------------------------------
|
|
41
|
-
* Overview of compatibilities:
|
|
42
|
-
* -----------------------------------
|
|
43
|
-
*
|
|
44
|
-
* Chrome Android (v72.0.3626): YES (via deviceorientationabsolute)
|
|
45
|
-
* Safari iOS (v12.0): YES (via deviceorientation and event.webkitCompassHeading)
|
|
46
|
-
* Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}
|
|
47
|
-
* Firefox Android (v65.0.1): NO {@link https://www.fxsitecompat.com/en-CA/docs/2018/various-device-sensor-apis-are-now-deprecated/}
|
|
48
|
-
*
|
|
49
|
-
* -----------------------------------
|
|
50
|
-
*/
|
|
51
|
-
class AbsoluteAttitudeFromBrowser extends Provider<AbsoluteAttitude> {
|
|
52
|
-
|
|
53
|
-
// from http://tyrex.inria.fr/mobile/benchmarks-attitude/
|
|
54
|
-
DEFAULT_ACCURACY = deg2rad(15);
|
|
55
|
-
|
|
56
|
-
absolutePositionProviderId?: number;
|
|
57
|
-
absolutePositionEvent?: AbsolutePosition;
|
|
58
|
-
|
|
59
|
-
declinationQuaternion?: Quaternion_t;
|
|
60
|
-
magQuaternion?: Quaternion_t;
|
|
61
|
-
magQuaternionTimestamp?: number;
|
|
62
|
-
|
|
63
|
-
iosPreviousQuat?: Quaternion_t;
|
|
64
|
-
iosIsSkyMode: boolean | null = null;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
getName = () => 'AbsoluteAttitudeFromBrowser';
|
|
68
|
-
|
|
69
|
-
availability() {
|
|
70
|
-
return BrowserUtils.isMobile
|
|
71
|
-
? Promise.resolve()
|
|
72
|
-
: Promise.resolve(new AskImuOnDesktopError());
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
start() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const subscribe = () => {
|
|
79
|
-
switch (BrowserUtils.getName()) {
|
|
80
|
-
case Browser.CHROME:
|
|
81
|
-
window.addEventListener('deviceorientationabsolute',
|
|
82
|
-
this.onDeviceOrientationChromeEvent, true);
|
|
83
|
-
break;
|
|
84
|
-
|
|
85
|
-
case Browser.SAFARI:
|
|
86
|
-
case Browser.IOS_WEBVIEW:
|
|
87
|
-
window.addEventListener('deviceorientation',
|
|
88
|
-
this.onDeviceOrientationSafariEvent, true);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const requestPermission = (DeviceOrientationEvent as unknown as DeviceOrientationEventiOS).requestPermission || undefined;
|
|
94
|
-
|
|
95
|
-
if (requestPermission) {
|
|
96
|
-
requestPermission()
|
|
97
|
-
.then(response => {
|
|
98
|
-
if (response !== 'granted') {
|
|
99
|
-
throw new Error('Permission not granted');
|
|
100
|
-
}
|
|
101
|
-
subscribe();
|
|
102
|
-
})
|
|
103
|
-
.catch(this.notifyError);
|
|
104
|
-
} else {
|
|
105
|
-
subscribe();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const lastAbsolutePosition = AbsolutePositionProvider.lastEvent;
|
|
110
|
-
if (lastAbsolutePosition) {
|
|
111
|
-
this.onAbsolutePositionEvent(lastAbsolutePosition);
|
|
112
|
-
} else {
|
|
113
|
-
this.absolutePositionProviderId = AbsolutePositionProvider.addEventListener(
|
|
114
|
-
this.onAbsolutePositionEvent,
|
|
115
|
-
this.notifyError,
|
|
116
|
-
false
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
stop() {
|
|
123
|
-
switch (BrowserUtils.getName()) {
|
|
124
|
-
case Browser.CHROME:
|
|
125
|
-
window.removeEventListener('deviceorientationabsolute',
|
|
126
|
-
this.onDeviceOrientationChromeEvent, true);
|
|
127
|
-
break;
|
|
128
|
-
|
|
129
|
-
case Browser.SAFARI:
|
|
130
|
-
case Browser.IOS_WEBVIEW:
|
|
131
|
-
window.removeEventListener('deviceorientation',
|
|
132
|
-
this.onDeviceOrientationSafariEvent, true);
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
onDeviceOrientationChromeEvent = (e: DeviceOrientationEvent) => {
|
|
141
|
-
|
|
142
|
-
this.magQuaternionTimestamp = e.timeStamp / 1e3;
|
|
143
|
-
|
|
144
|
-
if (typeof e.alpha !== 'number' || typeof e.beta !== 'number' || typeof e.gamma !== 'number') {
|
|
145
|
-
this.notifyError(new MissingSensorError().from('deviceorientationabsolute'));
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees(
|
|
150
|
-
[e.alpha, e.beta, e.gamma]);
|
|
151
|
-
|
|
152
|
-
this.compute();
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
onDeviceOrientationSafariEvent = (e: DeviceOrientationEventiOS) => {
|
|
157
|
-
|
|
158
|
-
this.magQuaternionTimestamp = e.timeStamp / 1e3;
|
|
159
|
-
|
|
160
|
-
if (typeof e.beta !== 'number' || typeof e.gamma !== 'number') {
|
|
161
|
-
this.notifyError(new MissingSensorError().from('deviceorientation'));
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (typeof e.webkitCompassHeading !== 'number') {
|
|
166
|
-
this.notifyError(new MissingMagnetometerError().from('deviceorientation'));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Trying the best to retrieve a good quaternion from devicemotion event.
|
|
172
|
-
*/
|
|
173
|
-
|
|
174
|
-
let alpha;
|
|
175
|
-
const [qw, qx, qy, qz] = Rotations.eulerToQuaternionZXYDegrees([e.webkitCompassHeading, e.beta, e.gamma]);
|
|
176
|
-
const groundAngle = rad2deg(Math.acos(qw ** 2 - qx ** 2 - qy ** 2 + qz ** 2));
|
|
177
|
-
|
|
178
|
-
let isSkyMode = null;
|
|
179
|
-
if (groundAngle > 136) {
|
|
180
|
-
isSkyMode = true;
|
|
181
|
-
} else if (groundAngle < 134) {
|
|
182
|
-
isSkyMode = false;
|
|
183
|
-
} else if (this.iosPreviousQuat && this.iosIsSkyMode !== null) {
|
|
184
|
-
/**
|
|
185
|
-
* This condition is true only if :
|
|
186
|
-
* - we are in the [134°; 136°] ground angle range
|
|
187
|
-
* - we know the previous quaternion
|
|
188
|
-
* - one of the both previous condition has been reached during this session
|
|
189
|
-
*
|
|
190
|
-
* In this case, we define a threshold to detect if there is a "jump" in the quaternion calculation,
|
|
191
|
-
* then, the mode is switched.
|
|
192
|
-
*/
|
|
193
|
-
isSkyMode = Quaternion.distance([qw, qx, qy, qz], this.iosPreviousQuat) < 0.5
|
|
194
|
-
? this.iosIsSkyMode
|
|
195
|
-
: !this.iosIsSkyMode;
|
|
196
|
-
}
|
|
197
|
-
this.iosPreviousQuat = [qw, qx, qy, qz];
|
|
198
|
-
this.iosIsSkyMode = isSkyMode;
|
|
199
|
-
|
|
200
|
-
if (typeof (isSkyMode) === 'undefined') {
|
|
201
|
-
// Algorithm uncertainity
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (isSkyMode) {
|
|
206
|
-
alpha = 180 - e.webkitCompassHeading;
|
|
207
|
-
} else {
|
|
208
|
-
alpha = AbsoluteAttitudeFromBrowser.webkitCompassToHeading(
|
|
209
|
-
e.webkitCompassHeading, e.beta, e.gamma);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees([alpha, e.beta, e.gamma]);
|
|
213
|
-
|
|
214
|
-
this.compute();
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
compute() {
|
|
219
|
-
|
|
220
|
-
if (!this.declinationQuaternion || !this.magQuaternion || !this.absolutePositionEvent) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, this.magQuaternion);
|
|
225
|
-
const attitude = new AbsoluteAttitude(trueQuaternion, this.magQuaternionTimestamp, this.DEFAULT_ACCURACY);
|
|
226
|
-
this.notify(attitude);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Initialized declination quaternion using current position.
|
|
231
|
-
* This method should be theoretically called every time the user moves.
|
|
232
|
-
* But in reality declination does not change as much.
|
|
233
|
-
*/
|
|
234
|
-
onAbsolutePositionEvent = (position: AbsolutePosition) => {
|
|
235
|
-
|
|
236
|
-
this.absolutePositionEvent = position;
|
|
237
|
-
|
|
238
|
-
const wmmResult = geomag.field(position.lat, position.lng);
|
|
239
|
-
|
|
240
|
-
// Declination is given in NED frame and our code use ENU, that is why we have: "-declination"
|
|
241
|
-
this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.declination));
|
|
242
|
-
|
|
243
|
-
AbsolutePositionProvider.removeEventListener(this.absolutePositionProviderId);
|
|
244
|
-
delete this.absolutePositionProviderId;
|
|
245
|
-
this.compute();
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
static webkitCompassToHeading(_webkitCompassHeading: number, _beta: number, _gamma: number) {
|
|
249
|
-
const webkitCompassHeading = deg2rad(_webkitCompassHeading);
|
|
250
|
-
const beta = deg2rad(_beta);
|
|
251
|
-
const gamma = deg2rad(_gamma);
|
|
252
|
-
|
|
253
|
-
const c1 = Math.cos(webkitCompassHeading / 2);
|
|
254
|
-
const c2 = Math.cos(beta / 2);
|
|
255
|
-
const c3 = Math.cos(gamma / 2);
|
|
256
|
-
const s1 = Math.sin(webkitCompassHeading / 2);
|
|
257
|
-
const s2 = Math.sin(beta / 2);
|
|
258
|
-
const s3 = Math.sin(gamma / 2);
|
|
259
|
-
|
|
260
|
-
const qw = c1 * c2 * c3 - s1 * s2 * s3;
|
|
261
|
-
const qz = s1 * c2 * c3 + c1 * s2 * s3;
|
|
262
|
-
|
|
263
|
-
return rad2deg(-2 * Math.atan(qz / qw));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
export default new AbsoluteAttitudeFromBrowser();
|