@wemap/providers 4.0.0 → 4.0.3

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 (66) hide show
  1. package/debug/dist/index.html +1 -0
  2. package/debug/dist/turn-detection.html +19 -0
  3. package/debug/index.js +2 -0
  4. package/debug/src/AbsoluteAttitudeComponent.jsx +3 -10
  5. package/debug/src/StepDetectionComponent.jsx +3 -3
  6. package/debug/src/TurnDetectionComponent.jsx +47 -0
  7. package/debug/src/Utils.js +20 -0
  8. package/package.json +7 -9
  9. package/src/Providers.js +26 -81
  10. package/src/ProvidersInterface.js +5 -6
  11. package/src/errors/AskImuOnDesktopError.js +4 -3
  12. package/src/errors/ContainsIgnoredProviderError.js +4 -3
  13. package/src/errors/GeolocationApiMissingError.js +4 -3
  14. package/src/errors/GeolocationPermissionDeniedError.js +4 -3
  15. package/src/errors/GeolocationPositionUnavailableError.js +4 -3
  16. package/src/errors/IpResolveServerError.js +4 -3
  17. package/src/errors/MissingAccelerometerError.js +3 -3
  18. package/src/errors/MissingArCoreError.js +4 -3
  19. package/src/errors/MissingGyroscopeError.js +3 -3
  20. package/src/errors/MissingNativeInterfaceError.js +4 -3
  21. package/src/errors/MissingSensorError.js +4 -3
  22. package/src/errors/NoProviderFoundError.js +4 -3
  23. package/src/events/EventType.js +5 -1
  24. package/src/events/ProviderEvent.js +7 -0
  25. package/src/events/ProvidersLoggerOld.js +35 -34
  26. package/src/mapmatching/MapMatchingHandler.js +335 -69
  27. package/src/providers/FakeProvider.spec.js +15 -15
  28. package/src/providers/Provider.js +44 -27
  29. package/src/providers/Provider.spec.js +18 -29
  30. package/src/providers/attitude/TurnDectector.js +71 -0
  31. package/src/providers/attitude/absolute/AbsoluteAttitude.js +232 -0
  32. package/src/providers/attitude/absolute/{AbsoluteAttitudeFromBrowserProvider.js → AbsoluteAttitudeFromBrowser.js} +4 -4
  33. package/src/providers/attitude/relative/{RelativeAttitudeProvider.js → RelativeAttitude.js} +5 -8
  34. package/src/providers/attitude/relative/{RelativeAttitudeFromBrowserProvider.js → RelativeAttitudeFromBrowser.js} +4 -5
  35. package/src/providers/attitude/relative/{RelativeAttitudeFromEkfProvider.js → RelativeAttitudeFromEkf.js} +7 -8
  36. package/src/providers/attitude/relative/{RelativeAttitudeFromInertialProvider.js → RelativeAttitudeFromInertial.js} +24 -7
  37. package/src/providers/imu/{AccelerometerProvider.js → Accelerometer.js} +3 -3
  38. package/src/providers/imu/{GyroscopeProvider.js → Gyroscope.js} +3 -3
  39. package/src/providers/imu/HighRotationsDetector.js +62 -0
  40. package/src/providers/imu/{ImuProvider.js → Imu.js} +3 -3
  41. package/src/providers/inclination/{InclinationProvider.js → Inclination.js} +5 -6
  42. package/src/providers/inclination/{InclinationFromAccProvider.js → InclinationFromAcc.js} +4 -3
  43. package/src/providers/inclination/{InclinationFromRelativeAttitudeProvider.js → InclinationFromRelativeAttitude.js} +4 -3
  44. package/src/providers/legacy/helpers/ThugDetector.js +7 -7
  45. package/src/providers/others/{BarcodeProvider.js → Barcode.js} +3 -3
  46. package/src/providers/others/{CameraNativeProvider.js → CameraNative.js} +3 -3
  47. package/src/providers/others/{CameraProjectionMatrixProvider.js → CameraProjectionMatrix.js} +4 -4
  48. package/src/providers/position/absolute/AbsolutePosition.js +217 -0
  49. package/src/providers/position/absolute/{GnssWifiProvider.js → GnssWifi.js} +9 -8
  50. package/src/providers/position/absolute/{IpProvider.js → Ip.js} +2 -2
  51. package/src/providers/position/relative/{ArCoreProvider.js → ArCore.js} +28 -30
  52. package/src/providers/position/relative/{GeoRelativePositionProvider.js → GeoRelativePosition.js} +6 -6
  53. package/src/providers/position/relative/{GeoRelativePositionFromArCoreProvider.js → GeoRelativePositionFromArCore.js} +4 -5
  54. package/src/providers/position/relative/{PdrProvider.js → Pdr.js} +8 -8
  55. package/src/providers/steps/StepDetectionLadetto.js +12 -13
  56. package/src/providers/steps/StepDetectionMinMaxPeaks.js +19 -17
  57. package/src/providers/steps/StepDetectionMinMaxPeaks2.js +17 -18
  58. package/src/providers/steps/{StepDetectionProvider.js → StepDetector.js} +8 -7
  59. package/src/providers/steps/StraightLineDetector.js +80 -0
  60. package/src/smoothers/AttitudeSmoother.js +94 -59
  61. package/src/providers/MetaProvider.js +0 -44
  62. package/src/providers/attitude/absolute/AbsoluteAttitudeFromRelAttProvider.js +0 -132
  63. package/src/providers/attitude/absolute/AbsoluteAttitudeFusedProvider.js +0 -166
  64. package/src/providers/attitude/absolute/AbsoluteAttitudeProvider.js +0 -175
  65. package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +0 -107
  66. package/src/providers/position/absolute/AbsolutePositionProvider.js +0 -189
@@ -1,26 +1,35 @@
1
1
  /* eslint-disable max-statements */
2
2
  import { Attitude } from '@wemap/geo';
3
- import { Quaternion } from '@wemap/maths';
3
+ import { deg2rad, diffAngle, Quaternion } from '@wemap/maths';
4
4
 
5
5
  class AttitudeSmoother {
6
6
 
7
- // Generated attitude by second
8
- static DEFAULT_FREQUENCY = 60;
7
+ /** @type {number} in radians/s */
8
+ static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(90);
9
9
 
10
- // In radians/s
11
- static MAX_ROTATE_SPEED = 0.5;
10
+ /** @type {number} in radians/s */
11
+ static ROTATION_SPEED_CONVERGENCE = deg2rad(10);
12
12
 
13
- /** @type {Attitude[]} */
14
- queue;
13
+ /** @type {number} in radians/s */
14
+ static HIGH_JUMP_THRESHOLD = deg2rad(20);
15
+
16
+ /** @type {number} in radians/s */
17
+ static ROTATION_SPEED_HIGH_JUMP_CONVERGENCE = deg2rad(100);
18
+
19
+ /** @type {number} in radians */
20
+ static PITCH_UNCERTAINITY_HEADING_THRESHOLD = deg2rad(5);
21
+
22
+ /** @type {Function} */
23
+ _callback;
24
+
25
+ /** @type {object?} */
26
+ _smoothing = null;
15
27
 
16
28
  /**
17
29
  * @param {Function} callback
18
- * @param {Number} frequency in Hz
19
30
  */
20
- constructor(callback, frequency = this.constructor.DEFAULT_FREQUENCY) {
21
- this.callback = callback;
22
- this.queue = [];
23
- this.frequency = frequency;
31
+ constructor(callback) {
32
+ this._callback = callback;
24
33
  }
25
34
 
26
35
  /**
@@ -36,65 +45,91 @@ class AttitudeSmoother {
36
45
  throw new Error('newAttitude does not have time property');
37
46
  }
38
47
 
39
- let previousAttitude;
40
- if (this.queue.length !== 0) {
41
- previousAttitude = this.queue[0];
42
- this.queue = [];
43
- } else {
44
- previousAttitude = this.previousAttitude;
48
+ const { _previousAttitude: previousAttitude } = this;
49
+ this._previousAttitude = newAttitude;
50
+
51
+ if (!previousAttitude) {
52
+ this._callback(newAttitude);
53
+ return;
45
54
  }
46
55
 
47
- if (previousAttitude) {
48
- const previousQuat = previousAttitude.quaternion;
49
- const nextQuat = newAttitude.quaternion;
50
- const quatAngle = Quaternion.distance(previousQuat, nextQuat);
51
-
52
- /** max rotation for the next value (radians) */
53
- const maxRotAtEpoch = this.constructor.MAX_ROTATE_SPEED / this.frequency;
54
-
55
- if (quatAngle > maxRotAtEpoch) {
56
- for (let i = 1; i <= Math.floor(quatAngle / maxRotAtEpoch); i++) {
57
-
58
- // coef is contained in [0; 1[
59
- const coef = i * maxRotAtEpoch / quatAngle;
60
-
61
- const smoothedAttitude = new Attitude(
62
- Quaternion.slerp(previousQuat, nextQuat, coef),
63
- newAttitude.time + i / this.frequency,
64
- Math.max(
65
- previousAttitude.accuracy + (newAttitude.accuracy - previousAttitude.accuracy) * coef,
66
- 0
67
- )
68
- );
69
- this.queue.push(smoothedAttitude);
56
+ /*
57
+ * Comparison between two successive Attitude from the "feed" function
58
+ */
59
+ if (AttitudeSmoother.isJump(previousAttitude, newAttitude)) {
60
+
61
+ const fromAttitude = this._smoothing === null
62
+ ? previousAttitude
63
+ : this._smoothing.interpAttitude(previousAttitude);
64
+
65
+ const fromHeading = fromAttitude.heading;
66
+ const toHeading = newAttitude.heading;
67
+ const diffAngleHeading = diffAngle(toHeading, fromHeading);
68
+
69
+ const isHighJump = Math.abs(diffAngleHeading) < AttitudeSmoother.HIGH_JUMP_THRESHOLD;
70
+ const rotationSpeedConvergence = isHighJump
71
+ ? AttitudeSmoother.ROTATION_SPEED_CONVERGENCE
72
+ : AttitudeSmoother.ROTATION_SPEED_HIGH_JUMP_CONVERGENCE;
73
+
74
+ const fromTime = fromAttitude.time;
75
+ const timeToConsume = Math.abs(diffAngleHeading) / rotationSpeedConvergence;
76
+ const multiplier = diffAngleHeading < 0 ? -1 : 1;
77
+
78
+ this._smoothing = {
79
+ toTime: fromTime + timeToConsume,
80
+
81
+ /**
82
+ * @param {Attitude} attitude
83
+ */
84
+ interpAttitude: attitude => {
85
+ const angle = rotationSpeedConvergence * (attitude.time - fromTime);
86
+ const interpHeading = fromHeading + angle * multiplier;
87
+ const offsetQuat = Quaternion.fromAxisAngle([0, 0, 1], toHeading - interpHeading);
88
+ const interpQuat = Quaternion.multiply(offsetQuat, attitude.quaternion);
89
+ return new Attitude(interpQuat, attitude.time, attitude.accuracy);
70
90
  }
91
+ };
92
+ }
71
93
 
94
+ if (this._smoothing !== null) {
95
+ if (newAttitude.time >= this._smoothing.toTime) {
96
+ // This means that is the last epoch for smoothing
97
+ this._smoothing = null;
98
+ } else {
99
+ const interpAttitude = this._smoothing.interpAttitude(newAttitude);
100
+ this._callback(interpAttitude);
101
+ return;
72
102
  }
73
103
  }
74
104
 
75
- this.queue.push(newAttitude.clone());
76
-
77
- this.previousAttitude = newAttitude;
78
-
79
- if (!this.timeoutNotify) {
80
- this._notifyNext();
81
- }
105
+ this._callback(newAttitude);
82
106
  }
83
107
 
84
- _notifyNext = () => {
85
- this.callback(this.queue.shift());
86
- if (this.queue.length !== 0) {
87
- this.timeoutNotify = setTimeout(this._notifyNext, 1e3 / this.frequency);
88
- } else {
89
- delete this.timeoutNotify;
108
+ /**
109
+ * @param {Attitude} previousAttitude
110
+ * @param {Attitude} newAttitude
111
+ * @returns {boolean}
112
+ */
113
+ static isJump(previousAttitude, newAttitude) {
114
+ const fromHeading = previousAttitude.heading;
115
+ const toHeading = newAttitude.heading;
116
+ const diffAngleHeading = diffAngle(toHeading, fromHeading);
117
+ const diffTime = newAttitude.time - previousAttitude.time;
118
+
119
+ /**
120
+ * Heading is calculated from two different formulas in function of the pitch angle.
121
+ * Do not consider a jump if attitude is close to the change of the methods
122
+ * @see MathsRotations#getHeadingFromQuaternion()
123
+ */
124
+ const [qw, qx, qy, qz] = newAttitude.quaternion;
125
+ const distToPitchThreshold = Math.abs(Math.asin(2 * (qw * qx + qy * qz)) - Math.PI / 4);
126
+ if (distToPitchThreshold < AttitudeSmoother.PITCH_UNCERTAINITY_HEADING_THRESHOLD) {
127
+ return false;
90
128
  }
91
- }
92
129
 
93
- clear() {
94
- clearTimeout(this.timeoutNotify);
95
- delete this.timeoutNotify;
96
- this.queue = [];
130
+ return Math.abs(diffAngleHeading) > AttitudeSmoother.ROTATION_SPEED_JUMP_THRESHOLD * diffTime;
97
131
  }
132
+
98
133
  }
99
134
 
100
135
  export default AttitudeSmoother;
@@ -1,44 +0,0 @@
1
- import EventType from '../events/EventType.js';
2
- import Provider from './Provider.js';
3
- import ProviderEvent from '../events/ProviderEvent.js';
4
-
5
- class MetaProvider extends Provider {
6
-
7
- _lastEvent = null;
8
-
9
- /**
10
- * Singleton pattern using reflection.
11
- * @returns {MetaProvider}
12
- */
13
- static get instance() {
14
- if (!this._instance) {
15
- this._instance = Reflect.construct(this, []);
16
- }
17
- return this._instance;
18
- }
19
-
20
- /**
21
- * @override
22
- * @param {ProviderEvent} event
23
- */
24
- notify(event) {
25
- super.notify(event);
26
- this._lastEvent = event;
27
- }
28
-
29
- get lastEvent() {
30
- return this._lastEvent;
31
- }
32
-
33
- /**
34
- * Input data from external interface
35
- * @param {ProviderEvent} event
36
- * @param {EventType} eventType
37
- */
38
- // eslint-disable-next-line no-unused-vars
39
- feed(event, eventType) {
40
- throw new Error('Not implemented');
41
- }
42
- }
43
-
44
- export default MetaProvider;
@@ -1,132 +0,0 @@
1
- import { Quaternion } from '@wemap/maths';
2
- import { Attitude } from '@wemap/geo';
3
-
4
- import Provider from '../../Provider.js';
5
- import EventType from '../../../events/EventType.js';
6
- import {
7
- RelativeAttitude, AbsoluteAttitude, AbsoluteAttitudeFromBrowser, AbsoluteAttitudeFused
8
- } from '../../../Providers.js';
9
-
10
- /**
11
- * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame
12
- */
13
- class AbsoluteAttitudeFromRelAttProvider extends Provider {
14
-
15
- accuracy = 0;
16
-
17
- /**
18
- * @override
19
- */
20
- static get pname() {
21
- return 'AbsoluteAttitudeFromRelAtt';
22
- }
23
-
24
- /**
25
- * @override
26
- */
27
- static get eventsType() {
28
- return [EventType.AbsoluteAttitude];
29
- }
30
-
31
- /**
32
- * @override
33
- */
34
- get _availability() {
35
- return RelativeAttitude.availability;
36
- }
37
-
38
- /**
39
- * @override
40
- */
41
- start() {
42
-
43
- this.relativeAttitudeProviderId = RelativeAttitude.addEventListener(
44
- events => this.onRelativeAttitudeEvent(events[0]),
45
- error => this.notifyError(error)
46
- );
47
-
48
-
49
- this.onAbsoluteAttitudeEvent(AbsoluteAttitude.lastEvent);
50
- this.absoluteAttitudeProviderId = AbsoluteAttitude.addEventListener(
51
- events => this.onAbsoluteAttitudeEvent(events[0]),
52
- error => this.notifyError(error),
53
- false
54
- );
55
- }
56
-
57
- /**
58
- * @override
59
- */
60
- stop() {
61
- RelativeAttitude.removeEventListener(this.relativeAttitudeProviderId);
62
- AbsoluteAttitude.removeEventListener(this.absoluteAttitudeProviderId);
63
- }
64
-
65
-
66
- onRelativeAttitudeEvent(relativeAttitudeEvent) {
67
-
68
- /**
69
- * Calculate relative accuracy
70
- */
71
- if (this.relativeAttitudeEvent) {
72
- const {
73
- accuracy, time
74
- } = relativeAttitudeEvent.data;
75
- const diffTime = time - this.relativeAttitudeEvent.data.time;
76
- this.accuracy += diffTime * accuracy;
77
- }
78
-
79
- this.relativeAttitudeEvent = relativeAttitudeEvent;
80
- this.compute();
81
- }
82
-
83
-
84
- onAbsoluteAttitudeEvent = absoluteAttitudeEvent => {
85
-
86
- if (!absoluteAttitudeEvent) {
87
- return;
88
- }
89
-
90
- /**
91
- * Use absolute attitude events only when they are not from this provider
92
- */
93
- if (absoluteAttitudeEvent.providersStack.includes(this.pname)
94
- || absoluteAttitudeEvent.providersStack.includes(AbsoluteAttitudeFromBrowser.pname)
95
- || absoluteAttitudeEvent.providersStack.includes(AbsoluteAttitudeFused.pname)) {
96
- return;
97
- }
98
- this.absoluteAttitudeEvent = absoluteAttitudeEvent;
99
- this.accuracy = 0;
100
-
101
- // preprocess zOffset for "compute" function
102
- const currentHeading = this.relativeAttitudeEvent ? this.relativeAttitudeEvent.data.heading : 0;
103
- this.zOffset = Quaternion.fromAxisAngle([0, 0, 1], -absoluteAttitudeEvent.data.heading + currentHeading);
104
- };
105
-
106
-
107
- compute() {
108
- if (!this.absoluteAttitudeEvent || !this.relativeAttitudeEvent) {
109
- return;
110
- }
111
-
112
- const {
113
- quaternion, time
114
- } = this.relativeAttitudeEvent.data;
115
-
116
- const absoluteAttitudeAccuracy = this.absoluteAttitudeEvent.data.accuracy;
117
-
118
- const absoluteQuat = Quaternion.multiply(this.zOffset, quaternion);
119
- const newAccuracy = Math.min(absoluteAttitudeAccuracy + this.accuracy, Math.PI);
120
- const attitude = new Attitude(absoluteQuat, time, newAccuracy, this.pname);
121
-
122
- this.notify(this.createEvent(
123
- EventType.AbsoluteAttitude,
124
- attitude,
125
- [this.relativeAttitudeEvent, this.absoluteAttitudeEvent]
126
- ));
127
-
128
- }
129
-
130
- }
131
-
132
- export default AbsoluteAttitudeFromRelAttProvider;
@@ -1,166 +0,0 @@
1
- import { Attitude, Edge } from '@wemap/geo';
2
- import {
3
- Quaternion, diffAngle
4
- } from '@wemap/maths';
5
-
6
- import Provider from '../../Provider.js';
7
- import EventType from '../../../events/EventType.js';
8
- import { RelativeAttitude } from '../../../Providers.js';
9
- import ProviderState from '../../ProviderState.js';
10
-
11
- /**
12
- * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame
13
- */
14
- class AbsoluteAttitudeFusedProvider extends Provider {
15
-
16
- accuracy = 0;
17
- isInitialized = false;
18
-
19
- /** @type {number[]} quaternion */
20
- zOffset = null;
21
-
22
- /**
23
- * @override
24
- */
25
- static get pname() {
26
- return 'AbsoluteAttitudeFused';
27
- }
28
-
29
- /**
30
- * @override
31
- */
32
- static get eventsType() {
33
- return [EventType.AbsoluteAttitude];
34
- }
35
-
36
- /**
37
- * @override
38
- */
39
- get _availability() {
40
- // TODO Enhance
41
- return RelativeAttitude.availability;
42
- }
43
-
44
- /**
45
- * @override
46
- */
47
- start() {
48
-
49
- this.relativeAttitudeProviderId = RelativeAttitude.addEventListener(
50
- events => this.onRelativeAttitudeEvent(events[0]),
51
- error => this.notifyError(error)
52
- );
53
-
54
-
55
- // this.onAbsoluteAttitudeEvent(AbsoluteAttitude.lastEvent);
56
- // this.absoluteAttitudeProviderId = AbsoluteAttitude.addEventListener(
57
- // events => this.onAbsoluteAttitudeEvent(events[0]),
58
- // error => this.notifyError(error),
59
- // false
60
- // );
61
- }
62
-
63
- /**
64
- * @override
65
- */
66
- stop() {
67
- RelativeAttitude.removeEventListener(this.relativeAttitudeProviderId);
68
- // AbsoluteAttitude.removeEventListener(this.absoluteAttitudeProviderId);
69
- }
70
-
71
- mapMatching(projection) {
72
-
73
- if (this.state !== ProviderState.STARTED) {
74
- return;
75
- }
76
-
77
- const {
78
- nearestElement, origin
79
- } = projection;
80
- if (!(nearestElement instanceof Edge)) {
81
- return;
82
- }
83
-
84
- let matchingDirection;
85
- const matchingDirectionAngle1 = diffAngle(nearestElement.bearing, origin.bearing);
86
- const matchingDirectionAngle2 = diffAngle(nearestElement.bearing + Math.PI, origin.bearing);
87
-
88
- if (Math.abs(matchingDirectionAngle1) < Math.abs(matchingDirectionAngle2)) {
89
- matchingDirection = nearestElement.bearing;
90
- } else {
91
- matchingDirection = (nearestElement.bearing + Math.PI) % (2 * Math.PI);
92
- }
93
-
94
- this.accuracy = 0;
95
-
96
- // preprocess zOffset for "compute" function
97
- const currentHeading = this.relativeAttitudeEvent ? this.relativeAttitudeEvent.data.heading : 0;
98
- this.zOffset = Quaternion.fromAxisAngle([0, 0, 1], -matchingDirection + currentHeading);
99
-
100
- this.compute();
101
- }
102
-
103
- onRelativeAttitudeEvent(relativeAttitudeEvent) {
104
-
105
- /**
106
- * Calculate relative accuracy
107
- */
108
- if (this.relativeAttitudeEvent) {
109
- const {
110
- accuracy, time
111
- } = relativeAttitudeEvent.data;
112
- const diffTime = time - this.relativeAttitudeEvent.data.time;
113
- this.accuracy += diffTime * accuracy;
114
- }
115
-
116
- this.relativeAttitudeEvent = relativeAttitudeEvent;
117
- this.compute();
118
- }
119
-
120
-
121
- // onAbsoluteAttitudeEvent = absoluteAttitudeEvent => {
122
-
123
- // if (!absoluteAttitudeEvent) {
124
- // return;
125
- // }
126
-
127
- // /**
128
- // * Use absolute attitude events only when they are not from this provider
129
- // */
130
- // if (absoluteAttitudeEvent.providersStack.includes(this.pname)
131
- // || absoluteAttitudeEvent.providersStack.includes(AbsoluteAttitudeFromBrowser.pname)) {
132
- // return;
133
- // }
134
- // this.absoluteAttitudeEvent = absoluteAttitudeEvent;
135
- // this.accuracy = 0;
136
-
137
- // // preprocess zOffset for "compute" function
138
- // const currentHeading = this.relativeAttitudeEvent ? this.relativeAttitudeEvent.data.heading : 0;
139
- // this.zOffset = Quaternion.fromAxisAngle([0, 0, 1], -absoluteAttitudeEvent.data.heading + currentHeading);
140
- // };
141
-
142
-
143
- compute() {
144
- if (!this.zOffset || !this.relativeAttitudeEvent) {
145
- return;
146
- }
147
-
148
- const {
149
- quaternion, time
150
- } = this.relativeAttitudeEvent.data;
151
-
152
- const absoluteQuat = Quaternion.multiply(this.zOffset, quaternion);
153
- const newAccuracy = Math.min(this.accuracy, Math.PI);
154
- const attitude = new Attitude(absoluteQuat, time, newAccuracy, this.pname);
155
-
156
- this.notify(this.createEvent(
157
- EventType.AbsoluteAttitude,
158
- attitude,
159
- [this.relativeAttitudeEvent]
160
- ));
161
-
162
- }
163
-
164
- }
165
-
166
- export default AbsoluteAttitudeFusedProvider;