@wemap/positioning 2.1.0 → 2.3.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.
- package/debug/arcore-absolute.html +16 -0
- package/debug/arcore.html +16 -0
- package/package.json +2 -1
- package/src/PositioningHandler.js +19 -5
- package/src/components/AbsoluteAttitudeComponent.jsx +2 -2
- package/src/components/ArCoreAbsoluteComponent.jsx +100 -0
- package/src/components/ArCoreComponent.jsx +74 -0
- package/src/components/GnssWifiComponent.jsx +14 -2
- package/src/components/GnssWifiPdrComponent.jsx +11 -2
- package/src/components/MapComponent.jsx +237 -0
- package/src/components/PdrComponent.jsx +12 -3
- package/src/components/PoseComponent.jsx +7 -0
- package/src/components/PositioningPoseComponent.jsx +12 -3
- package/src/components/Utils.js +18 -0
- package/src/components/index.js +4 -0
- package/src/errors/MissingArCoreError.js +9 -0
- package/src/errors/MissingNativeInterfaceError.js +9 -0
- package/src/providers/Provider.js +15 -3
- package/src/providers/ProviderOptions.js +1 -1
- package/src/providers/attitude/AbsoluteAttitudeProvider.js +6 -6
- package/src/providers/others/MapMatchingProvider.js +19 -19
- package/src/providers/pose/ArCoreAbsoluteProvider.js +186 -0
- package/src/providers/pose/ArCoreProvider.js +115 -0
- package/src/providers/pose/GnssWifiPdrProvider.js +20 -20
- package/src/providers/pose/PoseProvider.js +1 -1
- package/src/providers/pose/pdr/PdrProvider.js +39 -39
- package/src/providers/pose/pdr/helpers/Smoother.js +33 -33
- package/src/providers/pose/pdr/helpers/Smoother.spec.js +7 -7
- package/src/providers/position/GnssWifiProvider.js +5 -5
- package/src/providers/position/IpProvider.js +2 -2
- package/webpack/webpack.common.js +1 -1
- package/src.old/Constants.js +0 -11
- package/src.old/NavigationHandler.js +0 -244
- package/src.old/Pose.js +0 -8
- package/src.old/attitude/AttitudeHandler.js +0 -342
- package/src.old/attitude/EkfAttitude.js +0 -238
- package/src.old/attitude/EkfAttitude.spec.js +0 -116
- package/src.old/components/AbsoluteAttitude.jsx +0 -136
- package/src.old/components/Imu.jsx +0 -89
- package/src.old/components/LocationSource.jsx +0 -434
- package/src.old/components/Logger.jsx +0 -113
- package/src.old/components/NavigationDebugApp.jsx +0 -106
- package/src.old/components/Others.jsx +0 -121
- package/src.old/components/RelativeAttitude.jsx +0 -104
- package/src.old/components/Utils.js +0 -35
- package/src.old/components/index.js +0 -13
- package/src.old/index.js +0 -7
- package/src.old/providers/FixedLocationImuLocationSource.js +0 -66
- package/src.old/providers/GnssLocationSource.js +0 -118
- package/src.old/providers/GnssPdrLocationSource.js +0 -182
- package/src.old/providers/IPLocationSource.js +0 -96
- package/src.old/providers/LocationSource.js +0 -290
- package/src.old/providers/PdrLocationSource.js +0 -320
- package/src.old/providers/ProvidersLogger.js +0 -77
- package/src.old/providers/pdr/HeadingUnlocker.js +0 -41
- package/src.old/providers/pdr/HeadingUnlocker.spec.js +0 -26
- package/src.old/providers/pdr/Smoother.js +0 -90
- package/src.old/providers/pdr/Smoother.spec.js +0 -424
- package/src.old/providers/pdr/ThugDetector.js +0 -37
- package/src.old/providers/steps/StepDetection.js +0 -7
- package/src.old/providers/steps/StepDetectionLadetto.js +0 -67
- package/src.old/providers/steps/StepDetectionMinMaxPeaks.js +0 -80
- package/src.old/providers/steps/StepDetectionMinMaxPeaks2.js +0 -108
- package/src.old/sensors/SensorsCompatibility.js +0 -486
- package/src.old/sensors/SensorsCompatibility.spec.js +0 -270
- package/src.old/sensors/SensorsLogger.js +0 -94
- package/src.old/sensors/SensorsLoggerUtils.js +0 -35
|
@@ -19,7 +19,7 @@ class PoseProvider extends Provider {
|
|
|
19
19
|
|
|
20
20
|
this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(onEvent, e => this.onAbsoluteAttitudeError(e));
|
|
21
21
|
this.gnssWifiProvider = new GnssWifiProvider((events) => {
|
|
22
|
-
this.absoluteAttitudeProvider.
|
|
22
|
+
this.absoluteAttitudeProvider.setPosition(events[0].data);
|
|
23
23
|
onEvent(events);
|
|
24
24
|
}, e => this.onGnssWifiError(e));
|
|
25
25
|
}
|
|
@@ -32,10 +32,10 @@ const DEFAULT_OPTIONS = {
|
|
|
32
32
|
|
|
33
33
|
class PdrProvider extends MapMatchingProvider {
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// this.
|
|
38
|
-
|
|
35
|
+
// pdrPosition can be different from this.position
|
|
36
|
+
// pdrPosition is raw position calculated by PdrProvider where
|
|
37
|
+
// this.position is smoothed position.
|
|
38
|
+
pdrPosition = null;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* @override
|
|
@@ -61,7 +61,7 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
61
61
|
this.smoother = new Smoother();
|
|
62
62
|
this.thugDetector = new ThugDetector();
|
|
63
63
|
|
|
64
|
-
if (options.useMapMatching) {
|
|
64
|
+
if (this.options.useMapMatching) {
|
|
65
65
|
this.enableMapMatching();
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -127,18 +127,18 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
127
127
|
this.relativeAttitudeProvider.setOffset(heading);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
this.
|
|
130
|
+
setPosition(position) {
|
|
131
|
+
this.pdrPosition = position;
|
|
132
132
|
|
|
133
133
|
if (this.options.smoother) {
|
|
134
|
-
this.smoother.
|
|
135
|
-
// this.smoother.
|
|
136
|
-
this.
|
|
134
|
+
this.smoother.generateNextPositions(position, true);
|
|
135
|
+
// this.smoother.pullPosition(position.time) should never return null
|
|
136
|
+
this.position = this.smoother.pullPosition(position.time);
|
|
137
137
|
} else {
|
|
138
|
-
this.
|
|
138
|
+
this.position = position.clone();
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
this.notify(this.createEvent(EventType.AbsolutePosition, this.
|
|
141
|
+
this.notify(this.createEvent(EventType.AbsolutePosition, this.position));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
|
@@ -163,8 +163,8 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
if (!this.
|
|
167
|
-
// We should wait at least an input
|
|
166
|
+
if (!this.pdrPosition) {
|
|
167
|
+
// We should wait at least an input position for PDR
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -201,36 +201,36 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
201
201
|
|
|
202
202
|
if (stepDetected) {
|
|
203
203
|
|
|
204
|
-
this.
|
|
204
|
+
this.pdrPosition = this.calculateNewPosition(this.pdrPosition, timestamp,
|
|
205
205
|
heading, this.stepDetection.lastStepSize);
|
|
206
206
|
|
|
207
207
|
/**
|
|
208
208
|
* Update current_position
|
|
209
209
|
*/
|
|
210
210
|
if (this.options.smoother) {
|
|
211
|
-
this.smoother.
|
|
212
|
-
const
|
|
213
|
-
// At this time,
|
|
211
|
+
this.smoother.generateNextPositions(this.pdrPosition);
|
|
212
|
+
const newPosition = this.smoother.pullPosition(timestamp);
|
|
213
|
+
// At this time, newPosition can be null if a new step has been detected
|
|
214
214
|
// and smoother has not been completely consumed.
|
|
215
|
-
if (
|
|
216
|
-
this.
|
|
215
|
+
if (newPosition) {
|
|
216
|
+
this.position = newPosition;
|
|
217
217
|
}
|
|
218
218
|
} else {
|
|
219
|
-
this.
|
|
219
|
+
this.position = this.pdrPosition;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
} else if (this.options.smoother) {
|
|
223
|
-
// If no step is detected, we pull last known
|
|
224
|
-
const
|
|
225
|
-
if (!
|
|
223
|
+
// If no step is detected, we pull last known position from smoother until now (timestamp).
|
|
224
|
+
const smoothedPosition = this.smoother.pullPosition(timestamp);
|
|
225
|
+
if (!smoothedPosition) {
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
|
-
this.
|
|
228
|
+
this.position = smoothedPosition;
|
|
229
229
|
} else {
|
|
230
230
|
return;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
this.notify(this.createEvent(EventType.AbsolutePosition, this.
|
|
233
|
+
this.notify(this.createEvent(EventType.AbsolutePosition, this.position));
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
onProviderError(errors) {
|
|
@@ -254,39 +254,39 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
254
254
|
);
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
calculateNewPosition(previousPosition, timestamp, heading, stepSize) {
|
|
258
258
|
|
|
259
259
|
/**
|
|
260
260
|
* Compute new_position
|
|
261
261
|
*/
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
const newPositionWithoutMM = previousPosition.clone();
|
|
263
|
+
newPositionWithoutMM.move(stepSize, heading);
|
|
264
|
+
newPositionWithoutMM.bearing = rad2deg(heading);
|
|
265
|
+
newPositionWithoutMM.time = timestamp;
|
|
266
266
|
|
|
267
267
|
if (!this.mapMatching) {
|
|
268
|
-
return
|
|
268
|
+
return newPositionWithoutMM;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
const projection = this.mapMatching.getProjection(
|
|
271
|
+
const projection = this.mapMatching.getProjection(newPositionWithoutMM);
|
|
272
272
|
|
|
273
273
|
if (!projection || !projection.projection) {
|
|
274
|
-
return
|
|
274
|
+
return newPositionWithoutMM;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
if (projection.distanceFromNearestElement < stepSize) {
|
|
278
|
-
return WGS84UserPosition.fromWGS84(projection.projection,
|
|
278
|
+
return WGS84UserPosition.fromWGS84(projection.projection, newPositionWithoutMM);
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
/**
|
|
282
282
|
* Update new_position
|
|
283
283
|
*/
|
|
284
284
|
const smoothedDistance = projection.distanceFromNearestElement * MM_CONV_SPEED;
|
|
285
|
-
const smoothedBearing =
|
|
286
|
-
const
|
|
287
|
-
|
|
285
|
+
const smoothedBearing = previousPosition.bearingTo(projection.projection);
|
|
286
|
+
const smoothedPosition = previousPosition.clone();
|
|
287
|
+
smoothedPosition.move(smoothedDistance, smoothedBearing);
|
|
288
288
|
|
|
289
|
-
return WGS84UserPosition.fromWGS84(
|
|
289
|
+
return WGS84UserPosition.fromWGS84(smoothedPosition, newPositionWithoutMM);
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint max-statements: ["error", 27]*/
|
|
2
2
|
import { WGS84UserPosition } from '@wemap/geo';
|
|
3
3
|
|
|
4
|
-
// Generated
|
|
4
|
+
// Generated positions by second
|
|
5
5
|
const GEN_FREQUENCY = 60;
|
|
6
6
|
|
|
7
7
|
// Min and max time for flyby (in second)
|
|
@@ -11,40 +11,40 @@ const MAX_FLYBY_TIME = 1;
|
|
|
11
11
|
class Smoother {
|
|
12
12
|
|
|
13
13
|
constructor() {
|
|
14
|
-
this.
|
|
14
|
+
this.positionsQueue = [];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Calculate smoothed positions for the next milliseconds given a new
|
|
18
|
+
* Calculate smoothed positions for the next milliseconds given a new position
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
generateNextPositions(_newPosition, flyby = false) {
|
|
21
21
|
|
|
22
|
-
if (!(
|
|
23
|
-
throw new TypeError('
|
|
22
|
+
if (!(_newPosition instanceof WGS84UserPosition)) {
|
|
23
|
+
throw new TypeError('newPosition is not instance of WGS84UserPosition');
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
if (!
|
|
28
|
-
throw new Error('
|
|
26
|
+
const newPosition = _newPosition.clone();
|
|
27
|
+
if (!newPosition.hasOwnProperty('time')) {
|
|
28
|
+
throw new Error('newPosition does not have time property');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
if (!this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
31
|
+
if (!this.previousPosition) {
|
|
32
|
+
this.previousPosition = newPosition;
|
|
33
|
+
this.positionsQueue.push(this.previousPosition);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const distance = this.
|
|
38
|
-
const azimuth = this.
|
|
37
|
+
const distance = this.previousPosition.distanceTo(newPosition);
|
|
38
|
+
const azimuth = this.previousPosition.bearingTo(newPosition);
|
|
39
39
|
|
|
40
|
-
let refTimestamp =
|
|
40
|
+
let refTimestamp = newPosition.time;
|
|
41
41
|
|
|
42
|
-
const queueLength = this.
|
|
42
|
+
const queueLength = this.positionsQueue.length;
|
|
43
43
|
if (queueLength) {
|
|
44
|
-
refTimestamp = Math.max(refTimestamp, this.
|
|
44
|
+
refTimestamp = Math.max(refTimestamp, this.positionsQueue[queueLength - 1].time);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
let diffTime =
|
|
47
|
+
let diffTime = newPosition.time - this.previousPosition.time;
|
|
48
48
|
|
|
49
49
|
if (flyby) {
|
|
50
50
|
diffTime = MAX_FLYBY_TIME;
|
|
@@ -55,34 +55,34 @@ class Smoother {
|
|
|
55
55
|
let i = 1;
|
|
56
56
|
while (i < nSamples + 1) {
|
|
57
57
|
i = Math.min(i, nSamples);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
this.
|
|
58
|
+
const smoothedPosition = this.previousPosition.destinationPoint(distance * i / nSamples, azimuth);
|
|
59
|
+
smoothedPosition.time = refTimestamp + (i - 1) / GEN_FREQUENCY;
|
|
60
|
+
this.positionsQueue.push(smoothedPosition);
|
|
61
61
|
i++;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
this.
|
|
64
|
+
this.previousPosition = newPosition;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
* Pull
|
|
69
|
-
* @param {*} timestamp
|
|
70
|
-
* @returns last known
|
|
68
|
+
* Pull positions until timestamp and return the last one.
|
|
69
|
+
* @param {*} timestamp position returned is the last before this timestamp
|
|
70
|
+
* @returns last known position before timestamp, undefined otherwise
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
pullPosition(timestamp) {
|
|
73
73
|
|
|
74
74
|
if ((typeof timestamp === 'undefined' || !timestamp)
|
|
75
|
-
&& this.
|
|
76
|
-
const output = this.
|
|
77
|
-
this.
|
|
75
|
+
&& this.positionsQueue.length > 0) {
|
|
76
|
+
const output = this.positionsQueue[this.positionsQueue.length - 1];
|
|
77
|
+
this.positionsQueue = [];
|
|
78
78
|
return output;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
let
|
|
82
|
-
while (this.
|
|
83
|
-
|
|
81
|
+
let position;
|
|
82
|
+
while (this.positionsQueue.length && this.positionsQueue[0].time <= timestamp) {
|
|
83
|
+
position = this.positionsQueue.shift();
|
|
84
84
|
}
|
|
85
|
-
return
|
|
85
|
+
return position;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
}
|
|
@@ -388,10 +388,10 @@ describe('validSmoother', () => {
|
|
|
388
388
|
for (let i = 0; i < positions.length; i++) {
|
|
389
389
|
const pos = new WGS84UserPosition(positions[i][1], positions[i][2]);
|
|
390
390
|
pos.time = positions[i][0];
|
|
391
|
-
smoother.
|
|
391
|
+
smoother.generateNextPositions(pos, positions[i][3]);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
-
const predicted = smoother.
|
|
394
|
+
const predicted = smoother.positionsQueue;
|
|
395
395
|
expect(predicted.length).to.equal(expectations.length);
|
|
396
396
|
|
|
397
397
|
for (let i = 0; i < predicted.length; i++) {
|
|
@@ -401,8 +401,8 @@ describe('validSmoother', () => {
|
|
|
401
401
|
expect(timeDiff).to.almost.equal(0);
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
const
|
|
405
|
-
expect(
|
|
404
|
+
const positionAt10 = smoother.pullPosition(10);
|
|
405
|
+
expect(positionAt10.distanceTo(new WGS84(3.7669421260460435E-5, 2.5766995044818355E-5))).to.almost.equal(0);
|
|
406
406
|
});
|
|
407
407
|
});
|
|
408
408
|
|
|
@@ -413,12 +413,12 @@ describe('smoother return same value if unique', () => {
|
|
|
413
413
|
const smoother = new Smoother();
|
|
414
414
|
|
|
415
415
|
const pos = new WGS84UserPosition(positions[0][1], positions[0][2]);
|
|
416
|
-
smoother.
|
|
417
|
-
const posExpected = smoother.
|
|
416
|
+
smoother.generateNextPositions(pos);
|
|
417
|
+
const posExpected = smoother.pullPosition();
|
|
418
418
|
|
|
419
419
|
expect(posExpected).to.be.an.instanceof(WGS84UserPosition);
|
|
420
420
|
expect(posExpected.distanceTo(pos)).to.almost.equal(0);
|
|
421
|
-
expect(smoother.
|
|
421
|
+
expect(smoother.positionsQueue).to.be.an('array').that.is.empty;
|
|
422
422
|
});
|
|
423
423
|
});
|
|
424
424
|
|
|
@@ -78,8 +78,8 @@ class GnssWifiProvider extends Provider {
|
|
|
78
78
|
/**
|
|
79
79
|
* @private
|
|
80
80
|
*/
|
|
81
|
-
onNewPosition =
|
|
82
|
-
const { coords } =
|
|
81
|
+
onNewPosition = geolocation => {
|
|
82
|
+
const { coords } = geolocation;
|
|
83
83
|
if (!coords) {
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
@@ -89,9 +89,9 @@ class GnssWifiProvider extends Provider {
|
|
|
89
89
|
bearing = deg2rad(coords.heading);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
const timestamp = DateUtils.unixTimestampToPerformanceNow(
|
|
92
|
+
const timestamp = DateUtils.unixTimestampToPerformanceNow(geolocation.timestamp) / 1e3;
|
|
93
93
|
|
|
94
|
-
const
|
|
94
|
+
const position = new WGS84UserPosition(
|
|
95
95
|
coords.latitude,
|
|
96
96
|
coords.longitude,
|
|
97
97
|
coords.altitude,
|
|
@@ -101,7 +101,7 @@ class GnssWifiProvider extends Provider {
|
|
|
101
101
|
GnssWifiProvider.name);
|
|
102
102
|
|
|
103
103
|
this.notify(this.createEvent(
|
|
104
|
-
EventType.AbsolutePosition,
|
|
104
|
+
EventType.AbsolutePosition, position, timestamp
|
|
105
105
|
));
|
|
106
106
|
|
|
107
107
|
};
|
|
@@ -10,7 +10,7 @@ import IpResolveServerError from '../../errors/IpResolveServerError';
|
|
|
10
10
|
* by Wifi Fingerprinting algorithms or by GNSS. That is why the name is
|
|
11
11
|
* "GnssWifi".
|
|
12
12
|
*/
|
|
13
|
-
class
|
|
13
|
+
class IpProvider extends Provider {
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @override
|
|
@@ -72,4 +72,4 @@ class GnssWifiProvider extends Provider {
|
|
|
72
72
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export default
|
|
75
|
+
export default IpProvider;
|
package/src.old/Constants.js
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import noop from 'lodash.noop';
|
|
2
|
-
|
|
3
|
-
import { WGS84UserPosition, Itinerary } from '@wemap/geo';
|
|
4
|
-
|
|
5
|
-
import LocationSource from './providers/LocationSource';
|
|
6
|
-
import IPLocationSource from './providers/IPLocationSource';
|
|
7
|
-
import GnssLocationSource from './providers/GnssLocationSource';
|
|
8
|
-
import PdrLocationSource from './providers/PdrLocationSource';
|
|
9
|
-
import GnssPdrLocationSource from './providers/GnssPdrLocationSource';
|
|
10
|
-
import FixedLocationImuLocationSource from './providers/FixedLocationImuLocationSource';
|
|
11
|
-
import SensorsLogger from './sensors/SensorsLogger';
|
|
12
|
-
|
|
13
|
-
const DEFAULT_ALTITUDE = 1.6;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @private
|
|
17
|
-
*/
|
|
18
|
-
class NavigationHandler {
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Constructor of NavigationHandler
|
|
22
|
-
* @param {Function} callbackOnStart callback when navigation starts
|
|
23
|
-
* @param {Function} callbackOnStop callback when navigation stops
|
|
24
|
-
* @param {Function} callbackOnNewPose callback on new pose
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
constructor(callbackOnStart, callbackOnStop, callbackOnNewPose) {
|
|
28
|
-
this.callback = this.callback.bind(this);
|
|
29
|
-
|
|
30
|
-
this.callbackOnStart = callbackOnStart || noop;
|
|
31
|
-
this.callbackOnStop = callbackOnStop || noop;
|
|
32
|
-
this.callbackOnNewPose = callbackOnNewPose || noop;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Starts navigation from an initial position an initial heading
|
|
38
|
-
* @param {*} initialPosition initial position {lat: xx, lng: xx}
|
|
39
|
-
* @param {Number} initialHeading initial heading in radians and clockwise: north: 0, east = PI/2
|
|
40
|
-
* @param {Array} path an optional itinerary (list of 2D points [lng, lat])
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
startRelative(initialPosition, initialHeading, path = null) {
|
|
44
|
-
|
|
45
|
-
const initialPositionWgs84 = new WGS84UserPosition(
|
|
46
|
-
initialPosition.lat,
|
|
47
|
-
initialPosition.lng,
|
|
48
|
-
initialPosition.alt || DEFAULT_ALTITUDE
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// stop current location source if already started
|
|
52
|
-
if (this.locationSource) {
|
|
53
|
-
this.locationSource.stop();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
this.locationSource = new PdrLocationSource(this.callback, {
|
|
57
|
-
'stepdetectionlocker': true,
|
|
58
|
-
'smoother': true
|
|
59
|
-
});
|
|
60
|
-
this.locationSource.setLogger(this.logger);
|
|
61
|
-
|
|
62
|
-
if (path) {
|
|
63
|
-
const itinerary = Itinerary.fromPoints(path);
|
|
64
|
-
this.locationSource.enableMapMatching(itinerary);
|
|
65
|
-
this.locationSource.setItinerary(itinerary);
|
|
66
|
-
}
|
|
67
|
-
this.locationSource.setLocation(initialPositionWgs84);
|
|
68
|
-
this.locationSource.setHeading(initialHeading);
|
|
69
|
-
const promise = this.locationSource.start();
|
|
70
|
-
|
|
71
|
-
this.callbackOnStart();
|
|
72
|
-
return promise;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Starts navigation handler without any knowledge on starting point
|
|
77
|
-
* @param {Array} path an optional itinerary (list of 2D points [lng, lat])
|
|
78
|
-
* @public
|
|
79
|
-
*/
|
|
80
|
-
startAbsolute(path) {
|
|
81
|
-
// stop if already started
|
|
82
|
-
if (this.locationSource) {
|
|
83
|
-
this.locationSource.stop();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const itinerary = Itinerary.fromPoints(path);
|
|
87
|
-
this.locationSource = new GnssPdrLocationSource(this.callback);
|
|
88
|
-
this.locationSource.enableMapMatching(itinerary);
|
|
89
|
-
this.locationSource.setItinerary(itinerary);
|
|
90
|
-
this.locationSource.setLogger(this.logger);
|
|
91
|
-
|
|
92
|
-
const promise = this.locationSource.start();
|
|
93
|
-
this.callbackOnStart();
|
|
94
|
-
return promise;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
locateme(
|
|
98
|
-
options = {
|
|
99
|
-
ip: true,
|
|
100
|
-
browser: true,
|
|
101
|
-
attitude: true
|
|
102
|
-
}
|
|
103
|
-
) {
|
|
104
|
-
const useIPProvider = !options.hasOwnProperty('ip') || options.ip === true;
|
|
105
|
-
const useBrowserProvider = !options.hasOwnProperty('browser') || options.browser === true;
|
|
106
|
-
const useImu = !options.hasOwnProperty('attitude') || options.attitude === true;
|
|
107
|
-
|
|
108
|
-
return new Promise((resolve, reject) => {
|
|
109
|
-
const gnss = new GnssLocationSource(pose => {
|
|
110
|
-
resolve(pose);
|
|
111
|
-
this.callback(pose);
|
|
112
|
-
}, useImu);
|
|
113
|
-
|
|
114
|
-
const ip = new IPLocationSource(pose => {
|
|
115
|
-
resolve(pose);
|
|
116
|
-
this.callback(pose);
|
|
117
|
-
}, useImu);
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
this.locationSource
|
|
121
|
-
&& LocationSource.getMostAccurateLocationSource(this.locationSource, gnss) === this.locationSource
|
|
122
|
-
) {
|
|
123
|
-
resolve(this.locationSource.getPose());
|
|
124
|
-
} else {
|
|
125
|
-
if (this.locationSource) {
|
|
126
|
-
this.locationSource.stop();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (useBrowserProvider) {
|
|
130
|
-
this.locationSource = gnss;
|
|
131
|
-
gnss.start().catch(e => {
|
|
132
|
-
if (useIPProvider) {
|
|
133
|
-
this.locationSource = ip;
|
|
134
|
-
ip.start();
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
reject(e);
|
|
138
|
-
});
|
|
139
|
-
} else if (useIPProvider) {
|
|
140
|
-
this.locationSource = ip;
|
|
141
|
-
ip.start();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Stop relative, absolute or locateme navigation if started
|
|
150
|
-
* @public
|
|
151
|
-
*/
|
|
152
|
-
stop() {
|
|
153
|
-
if (
|
|
154
|
-
this.locationSource
|
|
155
|
-
) {
|
|
156
|
-
this.locationSource.stop();
|
|
157
|
-
this.locationSource = null;
|
|
158
|
-
}
|
|
159
|
-
this.callbackOnStop();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* @see LocationSource#getProjectionOnNetwork()
|
|
165
|
-
* @public
|
|
166
|
-
*/
|
|
167
|
-
getProjectionOnNetwork(location) {
|
|
168
|
-
return this.locationSource.getProjectionOnNetwork(location);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* @see LocationSource#getItineraryInfo()
|
|
173
|
-
* @public
|
|
174
|
-
*/
|
|
175
|
-
getItineraryInfo(location) {
|
|
176
|
-
return this.locationSource.getItineraryInfo(location);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
forceUserLocation(location) {
|
|
180
|
-
if (
|
|
181
|
-
this.locationSource
|
|
182
|
-
&& (!(this.locationSource instanceof FixedLocationImuLocationSource) || !location)
|
|
183
|
-
) {
|
|
184
|
-
this.locationSource.stop();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (location) {
|
|
188
|
-
if (
|
|
189
|
-
!this.locationSource
|
|
190
|
-
|| !(this.locationSource instanceof FixedLocationImuLocationSource)
|
|
191
|
-
) {
|
|
192
|
-
this.locationSource = new FixedLocationImuLocationSource(this.callback);
|
|
193
|
-
this.locationSource.start(location);
|
|
194
|
-
} else {
|
|
195
|
-
this.locationSource.setLocation(location);
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
this.locationSource = null;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* @private
|
|
204
|
-
*/
|
|
205
|
-
callback(pose) {
|
|
206
|
-
this.callbackOnNewPose(pose);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Assign a SensorsLogger to LocationSource and start recording.
|
|
211
|
-
* This logger will be fed with sensors output.
|
|
212
|
-
* Logger is not working on locateme()
|
|
213
|
-
* @param {SensorsLogger} logger An instance of SensorsLogger.
|
|
214
|
-
* @public
|
|
215
|
-
*/
|
|
216
|
-
startLogger(logger) {
|
|
217
|
-
if (!(logger instanceof SensorsLogger)) {
|
|
218
|
-
throw new Error('logger is not an instance of SensorsLogger');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
this.logger = logger;
|
|
222
|
-
|
|
223
|
-
if (this.locationSource) {
|
|
224
|
-
this.locationSource.setLogger(this.logger);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Stop recording sensors
|
|
230
|
-
* @public
|
|
231
|
-
*/
|
|
232
|
-
stopLogger() {
|
|
233
|
-
this.logger = null;
|
|
234
|
-
if (this.locationSource) {
|
|
235
|
-
this.locationSource.setLogger(this.logger);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
static get DEFAULT_ALTITUDE() {
|
|
240
|
-
return DEFAULT_ALTITUDE;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export default NavigationHandler;
|