@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.
- package/debug/dist/index.html +1 -0
- package/debug/dist/turn-detection.html +19 -0
- package/debug/index.js +2 -0
- package/debug/src/AbsoluteAttitudeComponent.jsx +3 -10
- package/debug/src/StepDetectionComponent.jsx +3 -3
- package/debug/src/TurnDetectionComponent.jsx +47 -0
- package/debug/src/Utils.js +20 -0
- package/package.json +7 -9
- package/src/Providers.js +26 -81
- package/src/ProvidersInterface.js +5 -6
- package/src/errors/AskImuOnDesktopError.js +4 -3
- package/src/errors/ContainsIgnoredProviderError.js +4 -3
- package/src/errors/GeolocationApiMissingError.js +4 -3
- package/src/errors/GeolocationPermissionDeniedError.js +4 -3
- package/src/errors/GeolocationPositionUnavailableError.js +4 -3
- package/src/errors/IpResolveServerError.js +4 -3
- package/src/errors/MissingAccelerometerError.js +3 -3
- package/src/errors/MissingArCoreError.js +4 -3
- package/src/errors/MissingGyroscopeError.js +3 -3
- package/src/errors/MissingNativeInterfaceError.js +4 -3
- package/src/errors/MissingSensorError.js +4 -3
- package/src/errors/NoProviderFoundError.js +4 -3
- package/src/events/EventType.js +5 -1
- package/src/events/ProviderEvent.js +7 -0
- package/src/events/ProvidersLoggerOld.js +35 -34
- package/src/mapmatching/MapMatchingHandler.js +335 -69
- package/src/providers/FakeProvider.spec.js +15 -15
- package/src/providers/Provider.js +44 -27
- package/src/providers/Provider.spec.js +18 -29
- package/src/providers/attitude/TurnDectector.js +71 -0
- package/src/providers/attitude/absolute/AbsoluteAttitude.js +232 -0
- package/src/providers/attitude/absolute/{AbsoluteAttitudeFromBrowserProvider.js → AbsoluteAttitudeFromBrowser.js} +4 -4
- package/src/providers/attitude/relative/{RelativeAttitudeProvider.js → RelativeAttitude.js} +5 -8
- package/src/providers/attitude/relative/{RelativeAttitudeFromBrowserProvider.js → RelativeAttitudeFromBrowser.js} +4 -5
- package/src/providers/attitude/relative/{RelativeAttitudeFromEkfProvider.js → RelativeAttitudeFromEkf.js} +7 -8
- package/src/providers/attitude/relative/{RelativeAttitudeFromInertialProvider.js → RelativeAttitudeFromInertial.js} +24 -7
- package/src/providers/imu/{AccelerometerProvider.js → Accelerometer.js} +3 -3
- package/src/providers/imu/{GyroscopeProvider.js → Gyroscope.js} +3 -3
- package/src/providers/imu/HighRotationsDetector.js +62 -0
- package/src/providers/imu/{ImuProvider.js → Imu.js} +3 -3
- package/src/providers/inclination/{InclinationProvider.js → Inclination.js} +5 -6
- package/src/providers/inclination/{InclinationFromAccProvider.js → InclinationFromAcc.js} +4 -3
- package/src/providers/inclination/{InclinationFromRelativeAttitudeProvider.js → InclinationFromRelativeAttitude.js} +4 -3
- package/src/providers/legacy/helpers/ThugDetector.js +7 -7
- package/src/providers/others/{BarcodeProvider.js → Barcode.js} +3 -3
- package/src/providers/others/{CameraNativeProvider.js → CameraNative.js} +3 -3
- package/src/providers/others/{CameraProjectionMatrixProvider.js → CameraProjectionMatrix.js} +4 -4
- package/src/providers/position/absolute/AbsolutePosition.js +217 -0
- package/src/providers/position/absolute/{GnssWifiProvider.js → GnssWifi.js} +9 -8
- package/src/providers/position/absolute/{IpProvider.js → Ip.js} +2 -2
- package/src/providers/position/relative/{ArCoreProvider.js → ArCore.js} +28 -30
- package/src/providers/position/relative/{GeoRelativePositionProvider.js → GeoRelativePosition.js} +6 -6
- package/src/providers/position/relative/{GeoRelativePositionFromArCoreProvider.js → GeoRelativePositionFromArCore.js} +4 -5
- package/src/providers/position/relative/{PdrProvider.js → Pdr.js} +8 -8
- package/src/providers/steps/StepDetectionLadetto.js +12 -13
- package/src/providers/steps/StepDetectionMinMaxPeaks.js +19 -17
- package/src/providers/steps/StepDetectionMinMaxPeaks2.js +17 -18
- package/src/providers/steps/{StepDetectionProvider.js → StepDetector.js} +8 -7
- package/src/providers/steps/StraightLineDetector.js +80 -0
- package/src/smoothers/AttitudeSmoother.js +94 -59
- package/src/providers/MetaProvider.js +0 -44
- package/src/providers/attitude/absolute/AbsoluteAttitudeFromRelAttProvider.js +0 -132
- package/src/providers/attitude/absolute/AbsoluteAttitudeFusedProvider.js +0 -166
- package/src/providers/attitude/absolute/AbsoluteAttitudeProvider.js +0 -175
- package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +0 -107
- 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
|
-
|
|
8
|
-
static
|
|
7
|
+
/** @type {number} in radians/s */
|
|
8
|
+
static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(90);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
static
|
|
10
|
+
/** @type {number} in radians/s */
|
|
11
|
+
static ROTATION_SPEED_CONVERGENCE = deg2rad(10);
|
|
12
12
|
|
|
13
|
-
/** @type {
|
|
14
|
-
|
|
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
|
|
21
|
-
this.
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
const { _previousAttitude: previousAttitude } = this;
|
|
49
|
+
this._previousAttitude = newAttitude;
|
|
50
|
+
|
|
51
|
+
if (!previousAttitude) {
|
|
52
|
+
this._callback(newAttitude);
|
|
53
|
+
return;
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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.
|
|
76
|
-
|
|
77
|
-
this.previousAttitude = newAttitude;
|
|
78
|
-
|
|
79
|
-
if (!this.timeoutNotify) {
|
|
80
|
-
this._notifyNext();
|
|
81
|
-
}
|
|
105
|
+
this._callback(newAttitude);
|
|
82
106
|
}
|
|
83
107
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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;
|