@wemap/positioning 2.7.13 → 14.0.0-0

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 (104) hide show
  1. package/README.md +51 -0
  2. package/dist/index.d.ts +19 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +16582 -0
  5. package/dist/qr-scanner-worker.min-CdBZO1_x.js +2 -0
  6. package/dist/src/ILocationSource.d.ts +104 -0
  7. package/dist/src/ILocationSource.d.ts.map +1 -0
  8. package/dist/src/MapMatching.d.ts +83 -0
  9. package/dist/src/MapMatching.d.ts.map +1 -0
  10. package/dist/src/location-sources/GnssWifiLocationSource.d.ts +79 -0
  11. package/dist/src/location-sources/GnssWifiLocationSource.d.ts.map +1 -0
  12. package/dist/src/location-sources/LocationSource.d.ts +102 -0
  13. package/dist/src/location-sources/LocationSource.d.ts.map +1 -0
  14. package/dist/src/location-sources/VPSLocationSource.d.ts +107 -0
  15. package/dist/src/location-sources/VPSLocationSource.d.ts.map +1 -0
  16. package/dist/src/types.d.ts +65 -0
  17. package/dist/src/types.d.ts.map +1 -0
  18. package/dist/src/utils/permissions.d.ts +29 -0
  19. package/dist/src/utils/permissions.d.ts.map +1 -0
  20. package/dist/vitest.config.d.ts +3 -0
  21. package/dist/vitest.config.d.ts.map +1 -0
  22. package/package.json +23 -59
  23. package/babel.config.js +0 -11
  24. package/config.json +0 -4
  25. package/debug/absolute-attitude.html +0 -16
  26. package/debug/arcore-absolute.html +0 -16
  27. package/debug/arcore.html +0 -16
  28. package/debug/components/AbsoluteAttitudeComponent.jsx +0 -100
  29. package/debug/components/ArCoreAbsoluteComponent.jsx +0 -104
  30. package/debug/components/ArCoreComponent.jsx +0 -69
  31. package/debug/components/GnssWifiComponent.jsx +0 -56
  32. package/debug/components/GnssWifiPdrComponent.jsx +0 -76
  33. package/debug/components/ImuComponent.jsx +0 -95
  34. package/debug/components/InclinationComponent.jsx +0 -52
  35. package/debug/components/MapComponent.jsx +0 -228
  36. package/debug/components/NavigationConfig.js +0 -92
  37. package/debug/components/PdrComponent.jsx +0 -75
  38. package/debug/components/PoseComponent.jsx +0 -77
  39. package/debug/components/PositioningComponent.jsx +0 -29
  40. package/debug/components/PositioningInclinationComponent.jsx +0 -82
  41. package/debug/components/PositioningPoseComponent.jsx +0 -117
  42. package/debug/components/RelativeAttitudeComponent.jsx +0 -82
  43. package/debug/components/StartStopComponent.jsx +0 -50
  44. package/debug/components/Utils.js +0 -128
  45. package/debug/components/index.js +0 -34
  46. package/debug/gnss-wifi-pdr.html +0 -16
  47. package/debug/gnss-wifi.html +0 -16
  48. package/debug/imu.html +0 -16
  49. package/debug/inclination.html +0 -16
  50. package/debug/pdr.html +0 -16
  51. package/debug/pose.html +0 -16
  52. package/debug/positioning.html +0 -16
  53. package/debug/relative-attitude.html +0 -16
  54. package/dist/wemap-positioning.min.js +0 -1
  55. package/index.js +0 -8
  56. package/src/PositioningHandler.js +0 -237
  57. package/src/PositioningHandler.spec.js +0 -294
  58. package/src/PositioningOptions.js +0 -34
  59. package/src/errors/AskImuOnDesktopError.js +0 -9
  60. package/src/errors/ContainsIgnoredProviderError.js +0 -9
  61. package/src/errors/GeolocationApiMissingError.js +0 -9
  62. package/src/errors/GeolocationPermissionDeniedError.js +0 -9
  63. package/src/errors/GeolocationPositionUnavailableError.js +0 -9
  64. package/src/errors/IpResolveServerError.js +0 -9
  65. package/src/errors/MissingAccelerometerError.js +0 -11
  66. package/src/errors/MissingArCoreError.js +0 -9
  67. package/src/errors/MissingGyroscopeError.js +0 -11
  68. package/src/errors/MissingMagnetometerError.js +0 -9
  69. package/src/errors/MissingNativeInterfaceError.js +0 -9
  70. package/src/errors/MissingSensorError.js +0 -14
  71. package/src/errors/NoProviderFoundError.js +0 -9
  72. package/src/events/Availability.js +0 -30
  73. package/src/events/EventType.js +0 -22
  74. package/src/events/ProviderEvent.js +0 -35
  75. package/src/providers/Constants.js +0 -5
  76. package/src/providers/Provider.js +0 -247
  77. package/src/providers/ProvidersList.js +0 -44
  78. package/src/providers/ProvidersLogger.js +0 -75
  79. package/src/providers/attitude/AbsoluteAttitudeProvider.js +0 -199
  80. package/src/providers/attitude/EkfAttitude.js +0 -238
  81. package/src/providers/attitude/EkfAttitude.spec.js +0 -116
  82. package/src/providers/attitude/RelativeAttitudeProvider.js +0 -121
  83. package/src/providers/others/ImuProvider.js +0 -179
  84. package/src/providers/others/InclinationProvider.js +0 -99
  85. package/src/providers/others/MapMatchingProvider.js +0 -65
  86. package/src/providers/pose/ArCoreAbsoluteProvider.js +0 -235
  87. package/src/providers/pose/ArCoreProvider.js +0 -191
  88. package/src/providers/pose/GnssWifiPdrProvider.js +0 -219
  89. package/src/providers/pose/PoseProvider.js +0 -71
  90. package/src/providers/pose/pdr/PdrProvider.js +0 -364
  91. package/src/providers/pose/pdr/helpers/HeadingUnlocker.js +0 -41
  92. package/src/providers/pose/pdr/helpers/HeadingUnlocker.spec.js +0 -26
  93. package/src/providers/pose/pdr/helpers/Smoother.js +0 -92
  94. package/src/providers/pose/pdr/helpers/Smoother.spec.js +0 -426
  95. package/src/providers/pose/pdr/helpers/ThugDetector.js +0 -37
  96. package/src/providers/pose/pdr/steps/StepDetection.js +0 -7
  97. package/src/providers/pose/pdr/steps/StepDetectionLadetto.js +0 -67
  98. package/src/providers/pose/pdr/steps/StepDetectionMinMaxPeaks.js +0 -80
  99. package/src/providers/pose/pdr/steps/StepDetectionMinMaxPeaks2.js +0 -108
  100. package/src/providers/position/GnssWifiProvider.js +0 -130
  101. package/src/providers/position/IpProvider.js +0 -74
  102. package/webpack/webpack.common.js +0 -20
  103. package/webpack/webpack.dev.js +0 -24
  104. package/webpack/webpack.prod.js +0 -15
@@ -1,238 +0,0 @@
1
- import {
2
- Matrix, Matrix3, Matrix4, Quaternion, Vector, Vector3
3
- } from '@wemap/maths';
4
-
5
-
6
- const DEFAULT_RELATIVE_NOISES = {
7
- acc: 0.5,
8
- gyr: 0.3
9
- };
10
-
11
- const DEFAULT_ABSOLUTE_NOISES = {
12
- acc: 0.5,
13
- gyr: 0.3,
14
- yc: 2
15
- };
16
-
17
- class EkfAttitude {
18
-
19
- constructor(accRef = [0, 0, 1], ycRef = [-1, 0, 0]) {
20
-
21
- this.accRef = accRef;
22
- this.cRef = ycRef;
23
-
24
- this.P = Matrix.diag(Array(4).fill(0.1 ** 2));
25
-
26
- this.quaternion = null;
27
-
28
-
29
- this.noises = {
30
- relative: null,
31
- absolute: null
32
- };
33
- this.setRelativeNoises(DEFAULT_RELATIVE_NOISES);
34
- this.setAbsoluteNoises(DEFAULT_ABSOLUTE_NOISES);
35
- }
36
-
37
- setRelativeNoises(relativeNoises) {
38
- this.noises.relative = {
39
- accelerometer: Matrix.diag(Array(3).fill(relativeNoises.acc ** 2)),
40
- gyroscope: Matrix.diag(Array(3).fill(relativeNoises.gyr ** 2))
41
- };
42
- }
43
-
44
-
45
- setAbsoluteNoises(absoluteNoises) {
46
- this.noises.absolute = {
47
- accelerometer: Matrix.diag(Array(3).fill(absoluteNoises.acc ** 2)),
48
- gyroscope: Matrix.diag(Array(3).fill(absoluteNoises.gyr ** 2)),
49
- yc: Matrix.diag(Array(3).fill(absoluteNoises.yc ** 2))
50
- };
51
- }
52
-
53
- /**
54
- *
55
- * Set yaw offset, this value will be used if the filter does not use magnetometer
56
- * @param {Number} yaw yaw offset in radians and clockwise
57
- */
58
- setOrientationYaw(yaw) {
59
- this.offsetYawQuaternion = Quaternion.fromAxisAngle(this.accRef, yaw);
60
- this.quaternion = null;
61
- }
62
-
63
- /**
64
- * Try to initialize filter.
65
- * To initialize, we need two information: current acceleration (acc) and offset on yaw angle (given by the quaternion: this.offsetYawQuaternion)
66
- */
67
- tryInitialize(acc, mag) {
68
-
69
- const accNormalized = Vector3.normalize(acc);
70
-
71
- if (mag) {
72
- const magNormalized = Vector3.normalize(mag);
73
-
74
- const H = Vector3.normalize(Vector3.cross(magNormalized, accNormalized));
75
- const M = Vector3.cross(accNormalized, H);
76
-
77
- const R = [
78
- [H[0], M[0], accNormalized[0]],
79
- [H[1], M[1], accNormalized[1]],
80
- [H[2], M[2], accNormalized[2]]
81
- ];
82
-
83
- this.quaternion = Quaternion.fromMatrix3(R);
84
-
85
- } else {
86
-
87
- if (!this.offsetYawQuaternion) {
88
- return null;
89
- }
90
-
91
- const r = Vector3.dot(accNormalized, this.accRef) + 1;
92
- const v = Vector3.cross(accNormalized, this.accRef);
93
-
94
- let quaternionWithoutYaw = [r, v[0], v[1], v[2]];
95
- quaternionWithoutYaw = Quaternion.normalize(quaternionWithoutYaw);
96
-
97
- this.quaternion = Quaternion.multiply(this.offsetYawQuaternion, quaternionWithoutYaw);
98
- }
99
-
100
- return this.quaternion;
101
- }
102
-
103
- update(diffTime, acc, gyr, mag) {
104
-
105
- if (!this.quaternion) {
106
- return this.tryInitialize(acc, mag);
107
- }
108
-
109
- let q = this.quaternion;
110
-
111
- /* ------------
112
- * ESTIMATION
113
- * ------------*/
114
-
115
- const qArray = q;
116
- const gyrInt = Vector3.multiplyScalar(gyr, 0.5 * diffTime);
117
- const F = this.computeC([1, gyrInt[0], gyrInt[1], gyrInt[2]]);
118
- const qAPriori = Matrix.multiplyVector(F, q);
119
- const E1 = Matrix.diag([qArray[0], qArray[0], qArray[0]]);
120
- const eSkew = Matrix3.skew([qArray[1], qArray[2], qArray[3]]);
121
-
122
- const qPart = [-1 * qArray[1], -1 * qArray[2], -1 * qArray[3]];
123
- const E = Matrix.concatRow([qPart], Matrix3.add(eSkew, E1));
124
-
125
- const Qk = Matrix.multiplyScalar(
126
- Matrix.multiply(
127
- Matrix.multiply(E, this.noises[mag ? 'absolute' : 'relative'].gyroscope),
128
- Matrix.transpose(E)
129
- ),
130
- (diffTime / 2) ** 2
131
- );
132
-
133
- const pAPriori = Matrix4.add(
134
- Matrix.multiply(
135
- Matrix.multiply(F, this.P),
136
- Matrix.transpose(F)
137
- ),
138
- Qk
139
- );
140
-
141
- /* ------------
142
- * CORRECTION
143
- * ------------*/
144
-
145
- const accNormalized = Vector3.normalize(acc);
146
- let dz, K, H;
147
-
148
- if (mag) {
149
-
150
- const magNormalized = Vector3.normalize(mag);
151
- const yc = Vector3.cross(accNormalized, magNormalized);
152
- const ycNormalized = Vector3.normalize(yc);
153
-
154
- const dzYc = Vector3.subtract(ycNormalized, Quaternion.rotate(qAPriori, this.cRef));
155
- const dzAcc = Vector3.subtract(accNormalized, Quaternion.rotate(qAPriori, this.accRef));
156
- dz = Vector.concat(dzYc, dzAcc);
157
-
158
- const HYc = this.jacobianES(qAPriori, this.cRef);
159
- const HAcc = this.jacobianES(qAPriori, this.accRef);
160
- H = Matrix.concatRow(HYc, HAcc);
161
-
162
- const RYc = Matrix.concatLine(this.noises.absolute.yc, Matrix3.zeros);
163
- const RAcc = Matrix.concatLine(Matrix3.zeros, this.noises.absolute.accelerometer);
164
- const R = Matrix.concatRow(RYc, RAcc);
165
-
166
- K = Matrix.multiply(
167
- Matrix.multiply(pAPriori, Matrix.transpose(H)),
168
- Matrix.inverse(
169
- Matrix.add(
170
- Matrix.multiply(
171
- Matrix.multiply(H, pAPriori),
172
- Matrix.transpose(H)
173
- ),
174
- R
175
- )
176
- )
177
- );
178
- } else {
179
- dz = Vector3.subtract(accNormalized, Quaternion.rotate(qAPriori, this.accRef));
180
- H = this.jacobianES(qAPriori, this.accRef);
181
- const R = this.noises.relative.accelerometer;
182
-
183
- K = Matrix.multiply(
184
- Matrix.multiply(pAPriori, Matrix.transpose(H)),
185
- Matrix3.inverse(
186
- Matrix3.add(
187
- Matrix.multiply(
188
- Matrix.multiply(H, pAPriori),
189
- Matrix.transpose(H)
190
- ),
191
- R
192
- )
193
- )
194
- );
195
- }
196
-
197
- q = Quaternion.add(
198
- qAPriori,
199
- Matrix.multiplyVector(K, dz)
200
- );
201
- const P = Matrix.multiply(
202
- Matrix4.subtract(
203
- Matrix4.identity,
204
- Matrix.multiply(K, H)
205
- ),
206
- pAPriori
207
- );
208
-
209
- q = Quaternion.normalize(q);
210
- this.quaternion = q;
211
- this.P = P;
212
-
213
- return q;
214
- }
215
-
216
- computeC(b) {
217
- return [
218
- [b[0], -b[1], -b[2], -b[3]],
219
- [b[1], b[0], b[3], -b[2]],
220
- [b[2], -b[3], b[0], b[1]],
221
- [b[3], b[2], -b[1], b[0]]
222
- ];
223
- }
224
-
225
- jacobianES(q, v) {
226
-
227
- const [qw, qx, qy, qz] = q;
228
- const [vx, vy, vz] = v;
229
-
230
- return [
231
- [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],
232
- [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],
233
- [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]
234
- ];
235
- }
236
- }
237
-
238
- export default EkfAttitude;
@@ -1,116 +0,0 @@
1
- import chai from 'chai';
2
-
3
- import { Quaternion } from '@wemap/maths';
4
-
5
- import EkfAttitude from './EkfAttitude';
6
-
7
- const expect = chai.expect;
8
-
9
- const dt = [
10
- 0.02, 0.02, 0.02, 0.02, 0.02
11
- ];
12
- const accData = [
13
- [-0.034561157, 3.81073, 8.860977],
14
- [-0.030700684, 3.814499, 8.818954],
15
- [-0.018234253, 3.8023376, 8.85762],
16
- [-0.020080566, 3.8205414, 8.8676605],
17
- [-0.054519653, 3.8456726, 8.810287]
18
- ];
19
-
20
- const gyrData = [
21
- [0.0047454834, 0.0028076172, 0.0022888184],
22
- [0.005218506, 0.0020446777, 0.0012207031],
23
- [0.0044555664, 0.0023040771, 4.4250488E-4],
24
- [0.0044555664, 0.0027618408, 0.0011444092],
25
- [0.0040893555, 0.0020446777, 0.0025787354]
26
- ];
27
-
28
- const magData = [
29
- [-7.260132, -29.21753, -30.532837],
30
- [-8.378601, -29.589844, -29.684448],
31
- [-8.784485, -29.97284, -29.86145],
32
- [-8.784485, -30.06134, -30.036926],
33
- [-8.917236, -29.666138, -28.616333]
34
- ];
35
-
36
- const expectationsAbsolute = [
37
- [0.22501367907095468, 0.048112975227173178, -0.19586497565981961, -0.95325279813673824],
38
- [0.22521836492577899, 0.048187611771482071, -0.19604062637627487, -0.953164579168738],
39
- [0.22546875479675244, 0.048146964451479861, -0.19603487950732199, -0.95310861733648156],
40
- [0.22571872218138991, 0.04816067876157637, -0.19609909097002176, -0.95303554708035731],
41
- [0.22598409746972753, 0.048415228863568645, -0.1963289784536566, -0.95291242279877153]
42
- ];
43
-
44
- const expectationsRelative = [
45
- [0.979449872594084, 0.201679452107589, 0.001829118097573, 0],
46
- [0.979412310855378, 0.201861876976980, 0.001818648953412, 0.000022005516141],
47
- [0.979416707676713, 0.201841237873455, 0.001739180982152, 0.000051642340567],
48
- [0.979405268570585, 0.201897124314688, 0.001692389320913, 0.000083114532679],
49
- [0.979351148979101, 0.202158360999907, 0.001821014027950, 0.000089325563504]
50
- ];
51
-
52
- describe('initAbsolute', () => {
53
- it('Should return the good value', () => {
54
- const ekf = new EkfAttitude();
55
- ekf.setAbsoluteNoises({
56
- acc: 0.5,
57
- gyr: 0.3,
58
- yc: 2
59
- });
60
- const result = ekf.update(dt[0], accData[0], gyrData[0], magData[0]);
61
- const distance = Quaternion.distance(result, expectationsAbsolute[0]);
62
- expect(distance).to.below(0.000001);
63
- });
64
- });
65
-
66
- describe('updateAbsolute', () => {
67
- it('Should return the good value', () => {
68
- const ekf = new EkfAttitude();
69
- ekf.setAbsoluteNoises({
70
- acc: 0.5,
71
- gyr: 0.3,
72
- yc: 2
73
- });
74
- let result;
75
- let distance;
76
-
77
- for (let i = 0; i < accData.length; i++) {
78
- result = ekf.update(dt[i], accData[i], gyrData[i], magData[i]);
79
- distance = Quaternion.distance(result, expectationsAbsolute[i]);
80
- expect(distance).to.below(0.000001);
81
- }
82
- });
83
- });
84
-
85
- describe('initRelative', () => {
86
- it('Should return the good value', () => {
87
- const ekf = new EkfAttitude();
88
- ekf.setOrientationYaw(0);
89
- ekf.setRelativeNoises({
90
- acc: 0.5,
91
- gyr: 0.3
92
- });
93
- const result = ekf.update(dt[0], accData[0], gyrData[0]);
94
- const distance = Quaternion.distance(result, expectationsRelative[0]);
95
- expect(distance).to.below(0.000001);
96
- });
97
- });
98
-
99
- describe('updateRelative', () => {
100
- it('Should return the good value', () => {
101
- const ekf = new EkfAttitude();
102
- ekf.setOrientationYaw(0);
103
- ekf.setRelativeNoises({
104
- acc: 0.5,
105
- gyr: 0.3
106
- });
107
- let result;
108
- let distance;
109
-
110
- for (let i = 0; i < accData.length; i++) {
111
- result = ekf.update(dt[i], accData[i], gyrData[i]);
112
- distance = Quaternion.distance(result, expectationsRelative[i]);
113
- expect(distance).to.below(0.000001);
114
- }
115
- });
116
- });
@@ -1,121 +0,0 @@
1
- import Provider from '../Provider';
2
- import EventType from '../../events/EventType';
3
- import EkfAttitude from './EkfAttitude';
4
- import ImuProvider from '../others/ImuProvider';
5
- import { Attitude } from '@wemap/geo';
6
- import { deg2rad } from '@wemap/maths';
7
-
8
-
9
- /**
10
- * Relative attitude provider gives the device attitude in East-North-Up (ENU) frame using
11
- * browser deviceorientation
12
- * The provider does not work until an offset is given.
13
- */
14
- class RelativeAttitudeProvider extends Provider {
15
-
16
- lastTimestamp = 0;
17
-
18
- /**
19
- * @override
20
- */
21
- constructor(onEvent, onError, options) {
22
- super(onEvent, onError, options);
23
-
24
- this.ekfAttitude = new EkfAttitude();
25
- this.relativeOffsetQuaternion = [1, 0, 0, 0];
26
-
27
- this.imuProvider = new ImuProvider(this.onImuEvent,
28
- onError, { require: [EventType.Acceleration, EventType.AngularRate] });
29
-
30
- }
31
-
32
- /**
33
- * @override
34
- */
35
- static get name() {
36
- return 'RelativeAttitude';
37
- }
38
-
39
- /**
40
- * @override
41
- */
42
- static get displayName() {
43
- return 'Relative Attitude from Ekf';
44
- }
45
-
46
- /**
47
- * @override
48
- */
49
- static get eventsType() {
50
- return [EventType.RelativeAttitude];
51
- }
52
-
53
- /**
54
- * @override
55
- */
56
- static getRequiredProviders() {
57
- return [ImuProvider];
58
- }
59
-
60
- /**
61
- * @override
62
- */
63
- startInternal() {
64
- this.imuProvider.start();
65
- }
66
-
67
- /**
68
- * @override
69
- */
70
- stopInternal() {
71
- this.imuProvider.stop();
72
- }
73
-
74
- /**
75
- * @private
76
- */
77
- onImuEvent = imuEvent => {
78
-
79
- let timestamp, acceleration, angularRate;
80
- imuEvent.forEach(event => {
81
- if (event.dataType === EventType.Acceleration) {
82
- acceleration = event.data;
83
- timestamp = event.timestamp;
84
- } else if (event.dataType === EventType.AngularRate) {
85
- angularRate = event.data;
86
- }
87
- });
88
-
89
- // Handle timestamps and dt
90
- if (this.lastTimestamp === 0) {
91
- this.lastTimestamp = timestamp;
92
- return;
93
- }
94
- const diffTime = timestamp - this.lastTimestamp;
95
- this.lastTimestamp = timestamp;
96
-
97
- const quaternion = this.ekfAttitude.update(diffTime, acceleration, angularRate);
98
-
99
- if (quaternion) {
100
- this.notify(this.createEvent(EventType.RelativeAttitude, new Attitude(quaternion), timestamp));
101
- }
102
- };
103
-
104
- /**
105
- *
106
- * Set yaw offset, this value will be used as the filter does not use magnetometer
107
- * @param {Number} heading heading offset in radians and clockwise
108
- */
109
- setOffset(_heading) {
110
-
111
- // Minus before "heading" is here because ENU attitude is counter-clockwise whereas WGS84 heading is clockwise.
112
- let heading = -_heading;
113
-
114
- // Offset from window orientation
115
- heading += deg2rad(window.orientation || 0);
116
-
117
- this.ekfAttitude.setOrientationYaw(heading);
118
- }
119
- }
120
-
121
- export default RelativeAttitudeProvider;
@@ -1,179 +0,0 @@
1
- import { deg2rad } from '@wemap/maths';
2
- import {
3
- Browser, BrowserUtils
4
- } from '@wemap/utils';
5
-
6
- import isnumber from 'lodash.isnumber';
7
- import Provider from '../Provider';
8
- import EventType from '../../events/EventType';
9
- import MissingAccelerometerError from '../../errors/MissingAccelerometerError';
10
- import MissingGyroscopeError from '../../errors/MissingGyroscopeError';
11
- import AskImuOnDesktopError from '../../errors/AskImuOnDesktopError';
12
- import Availability from '../../events/Availability';
13
-
14
- /**
15
- * Imu (Inertial Measurement Unit) provider retrieve acceleration data
16
- * and/or angular rate data from inertial sensors.
17
- * opions.require has to be defined in order to work
18
- *
19
- * -----------------------------------
20
- * Overview of compatibilities:
21
- * -----------------------------------
22
- *
23
- * Chrome Android (v72.0.3626): YES (via devicemotion)
24
- * Safari iOS (v12.0): YES (via devicemotion)
25
- * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent}
26
- * Firefox Android (v65.0.1): YES (via devicemotion)
27
- *
28
- * -----------------------------------
29
- */
30
- class ImuProvider extends Provider {
31
-
32
- requiredSensors = [];
33
-
34
- /**
35
- * Constructor of ImuProvider
36
- * options.require has to be filled by a list of EventType
37
- * @example options = {require: [EventType.Acceleration, EventType.AngularRate]};
38
- * @example options = {require: [EventType.Acceleration]};
39
- *
40
- * @param {Function} onEvent @see Provider#constructor
41
- * @param {Function} onError @see Provider#constructor
42
- * @param {Object} options @see Provider#constructor
43
- */
44
- constructor(onEvent, onError, options) {
45
- super(onEvent, onError, options);
46
-
47
- if (!options.hasOwnProperty('require')) {
48
- throw new Error('options.require is missing in ImuProvider constructor');
49
- }
50
-
51
- if (options.require.length === 0) {
52
- throw new Error('option.require is empty');
53
- }
54
-
55
- options.require.forEach(elem => {
56
- if (!ImuProvider.eventsType.includes(elem)) {
57
- throw new Error(elem + ' is not recognised in options.require');
58
- }
59
- });
60
-
61
- this.requiredSensors = options.require;
62
- }
63
-
64
- /**
65
- * @override
66
- */
67
- static get name() {
68
- return 'Imu';
69
- }
70
-
71
- /**
72
- * @override
73
- */
74
- static get displayName() {
75
- return 'Inertial Measurement Unit';
76
- }
77
-
78
- /**
79
- * @override
80
- */
81
- static get eventsType() {
82
- return [EventType.AngularRate, EventType.Acceleration];
83
- }
84
-
85
- /**
86
- * @override
87
- */
88
- static checkAvailability(options) {
89
- return Availability.merge(
90
- super.checkAvailability(options),
91
- BrowserUtils.isMobile
92
- ? Availability.yes()
93
- : Availability.no(new AskImuOnDesktopError())
94
- );
95
- }
96
-
97
- /**
98
- * @override
99
- */
100
- startInternal() {
101
- window.addEventListener('devicemotion', this.parseDeviceMotionEvent, true);
102
- }
103
-
104
- /**
105
- * @override
106
- */
107
- stopInternal() {
108
- window.removeEventListener('devicemotion', this.parseDeviceMotionEvent, true);
109
- }
110
-
111
- /**
112
- * devicemotion callback
113
- * @param {DeviceMotionEvent} e device motion event
114
- * @returns {ProviderEvent[]} an array of provider events
115
- * @private
116
- */
117
- parseDeviceMotionEvent = e => {
118
-
119
- const events = [];
120
-
121
- const timestamp = e.timeStamp / 1e3;
122
-
123
- if (this.requiredSensors.includes(EventType.Acceleration)) {
124
-
125
- let acc;
126
- if (e.accelerationIncludingGravity) {
127
- const {
128
- x, y, z
129
- } = e.accelerationIncludingGravity;
130
-
131
- if (isnumber(x) && isnumber(y) && isnumber(z)) {
132
- acc = [x, y, z];
133
-
134
- if (BrowserUtils.name === Browser.SAFARI) {
135
- acc[0] *= -1;
136
- acc[1] *= -1;
137
- acc[2] *= -1;
138
- }
139
- }
140
- }
141
-
142
- if (!acc) {
143
- this.notifyError(new MissingAccelerometerError().from('devicemotion'));
144
- return;
145
- }
146
-
147
- events.push(this.createEvent(EventType.Acceleration, acc, timestamp));
148
- }
149
-
150
-
151
- if (this.requiredSensors.includes(EventType.AngularRate)) {
152
-
153
- let gyr;
154
- if (e.rotationRate) {
155
- const {
156
- alpha, beta, gamma
157
- } = e.rotationRate;
158
-
159
- if (isnumber(alpha) && isnumber(beta) && isnumber(gamma)) {
160
- gyr = [deg2rad(alpha), deg2rad(beta), deg2rad(gamma)];
161
- }
162
- }
163
-
164
- if (!gyr) {
165
- this.notifyError(new MissingGyroscopeError().from('devicemotion'));
166
- return;
167
- }
168
-
169
- events.push(this.createEvent(EventType.AngularRate, gyr, timestamp));
170
- }
171
-
172
- if (events.length !== 0) {
173
- this.notify(...events);
174
- }
175
- }
176
-
177
- }
178
-
179
- export default ImuProvider;