@wemap/positioning 2.2.0 → 2.3.1
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/package.json +1 -1
- package/src/PositioningHandler.js +45 -14
- package/src/PositioningHandler.spec.js +218 -0
- package/src/components/AbsoluteAttitudeComponent.jsx +2 -2
- package/src/components/ArCoreAbsoluteComponent.jsx +100 -0
- package/src/components/ArCoreComponent.jsx +3 -3
- package/src/components/GnssWifiPdrComponent.jsx +2 -2
- package/src/components/MapComponent.jsx +29 -18
- package/src/components/PdrComponent.jsx +3 -3
- package/src/components/PositioningPoseComponent.jsx +3 -3
- package/src/components/index.js +2 -0
- package/src/index.js +2 -1
- package/src/providers/Provider.js +2 -2
- package/src/providers/ProviderOptions.js +8 -2
- 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 +31 -43
- package/src/providers/pose/GnssWifiPdrProvider.js +20 -20
- package/src/providers/pose/PoseProvider.js +1 -1
- package/src/providers/pose/pdr/PdrProvider.js +38 -38
- 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/src/components/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
|
|
|
3
3
|
|
|
4
4
|
import AbsoluteAttitudeComponent from './AbsoluteAttitudeComponent';
|
|
5
5
|
import ArCoreComponent from './ArCoreComponent';
|
|
6
|
+
import ArCoreAbsoluteComponent from './ArCoreAbsoluteComponent';
|
|
6
7
|
import GnssWifiComponent from './GnssWifiComponent';
|
|
7
8
|
import GnssWifiPdrComponent from './GnssWifiPdrComponent';
|
|
8
9
|
import ImuComponent from './ImuComponent';
|
|
@@ -20,6 +21,7 @@ const createReactElement = (component, container) => ReactDOM.render(
|
|
|
20
21
|
export {
|
|
21
22
|
AbsoluteAttitudeComponent,
|
|
22
23
|
ArCoreComponent,
|
|
24
|
+
ArCoreAbsoluteComponent,
|
|
23
25
|
ImuComponent,
|
|
24
26
|
InclinationComponent,
|
|
25
27
|
GnssWifiComponent,
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import InclinationProvider from './providers/computed/InclinationProvider';
|
|
2
2
|
import PositioningHandler from './PositioningHandler';
|
|
3
|
+
import EventType from './events/EventType';
|
|
3
4
|
|
|
4
5
|
export {
|
|
5
|
-
InclinationProvider, PositioningHandler
|
|
6
|
+
InclinationProvider, PositioningHandler, EventType
|
|
6
7
|
};
|
|
@@ -215,10 +215,10 @@ class Provider {
|
|
|
215
215
|
|
|
216
216
|
|
|
217
217
|
static hasNativeInterface() {
|
|
218
|
-
return Boolean(Provider.
|
|
218
|
+
return Boolean(Provider.nativeInterface);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
static
|
|
221
|
+
static get nativeInterface() {
|
|
222
222
|
return global.WemapProvidersAndroid;
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -2,7 +2,7 @@ const ProviderOptions = {
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Does provider have to wait an input position to start
|
|
5
|
-
* @see PositioningHandler#
|
|
5
|
+
* @see PositioningHandler#setPosition()
|
|
6
6
|
*/
|
|
7
7
|
waitInputPosition: false,
|
|
8
8
|
|
|
@@ -22,7 +22,13 @@ const ProviderOptions = {
|
|
|
22
22
|
* Providers listed here will not be used by PositioningHandler
|
|
23
23
|
* List of {@link Provider}
|
|
24
24
|
*/
|
|
25
|
-
ignoreProviders: []
|
|
25
|
+
ignoreProviders: [],
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Define the list of EventType that are optionals
|
|
29
|
+
* List of {@link EventType}
|
|
30
|
+
*/
|
|
31
|
+
optionalEvents: []
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
export default ProviderOptions;
|
|
@@ -162,8 +162,8 @@ class AbsoluteAttitudeProvider extends Provider {
|
|
|
162
162
|
onDeviceOrientationCommonEvent = (timestamp, quaternion) => {
|
|
163
163
|
|
|
164
164
|
if (!this.declinationQuaternion) {
|
|
165
|
-
Logger.warn('
|
|
166
|
-
+ 'Please call
|
|
165
|
+
Logger.warn('Position of AbsoluteAttitude provider is not set yet. '
|
|
166
|
+
+ 'Please call setPosition() before.');
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
169
|
const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, quaternion);
|
|
@@ -178,13 +178,13 @@ class AbsoluteAttitudeProvider extends Provider {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
|
-
* Initialized declination quaternion using current
|
|
181
|
+
* Initialized declination quaternion using current position.
|
|
182
182
|
* This method should be theoretically called every time the user moves.
|
|
183
183
|
* But in reality declination does not change as much.
|
|
184
|
-
* @param {WGS84}
|
|
184
|
+
* @param {WGS84} position user position
|
|
185
185
|
*/
|
|
186
|
-
|
|
187
|
-
const wmmResult = geomagnetism.model().point([
|
|
186
|
+
setPosition(position) {
|
|
187
|
+
const wmmResult = geomagnetism.model().point([position.lat, position.lng]);
|
|
188
188
|
// Declination is given in NED frame and our code use ENU, that is why we have: "-decl"
|
|
189
189
|
this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.decl));
|
|
190
190
|
}
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
class MapMatchingProvider extends Provider {
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Enable
|
|
9
|
+
* Enable mapmatching
|
|
10
10
|
* @param {*} network a network which will be used for map matching
|
|
11
|
-
* @param {*} maxDistance max distance between
|
|
12
|
-
* @param {*} maxAngleBearing threshold to match a parallel segment for angle between
|
|
11
|
+
* @param {*} maxDistance max distance between position and network to match. null disables maxDistance (default: null)
|
|
12
|
+
* @param {*} maxAngleBearing threshold to match a parallel segment for angle between position bearing and segment. null disables this threshold (default: null)
|
|
13
13
|
* @public
|
|
14
14
|
*/
|
|
15
15
|
enableMapMatching(network, maxDistance, maxAngleBearing) {
|
|
@@ -23,7 +23,7 @@ class MapMatchingProvider extends Provider {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Update the
|
|
26
|
+
* Update the network for mapmatching
|
|
27
27
|
* @param {Network} network a network instance
|
|
28
28
|
* @public
|
|
29
29
|
*/
|
|
@@ -47,26 +47,26 @@ class MapMatchingProvider extends Provider {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Returns projection of a
|
|
51
|
-
* @param {WGS84}
|
|
52
|
-
* @returns The projected
|
|
50
|
+
* Returns projection of a position on network
|
|
51
|
+
* @param {WGS84} position if position is null, projection of this.position is used
|
|
52
|
+
* @returns The projected position {WGS84} or null.
|
|
53
53
|
* @public
|
|
54
54
|
*/
|
|
55
|
-
getProjectionOnNetwork(
|
|
55
|
+
getProjectionOnNetwork(position = null) {
|
|
56
56
|
|
|
57
57
|
if (!this.mapMatching) {
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
let
|
|
62
|
-
if (!
|
|
63
|
-
|
|
61
|
+
let positionToProject = position;
|
|
62
|
+
if (!position) {
|
|
63
|
+
positionToProject = this.position;
|
|
64
64
|
}
|
|
65
|
-
if (!
|
|
65
|
+
if (!positionToProject) {
|
|
66
66
|
return null;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
return this.mapMatching.getProjection(
|
|
69
|
+
return this.mapMatching.getProjection(positionToProject, false, false);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
@@ -75,7 +75,7 @@ class MapMatchingProvider extends Provider {
|
|
|
75
75
|
*/
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
* Update itinerary
|
|
78
|
+
* Update itinerary.
|
|
79
79
|
* Itinerary is different from network, it is not used for mapmatching. It can be used for others tricks like HeadingUnlocker
|
|
80
80
|
* @param {Itinerary} itinerary a given itinerary
|
|
81
81
|
* @public
|
|
@@ -89,17 +89,17 @@ class MapMatchingProvider extends Provider {
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Returns projection and itinerary info of a
|
|
93
|
-
* @param {WGS84}
|
|
94
|
-
* @returns An object of the projected
|
|
92
|
+
* Returns projection and itinerary info of a position on network
|
|
93
|
+
* @param {WGS84} position if position is null, projection of this.position is used
|
|
94
|
+
* @returns An object of the projected position and itinerary info or null.
|
|
95
95
|
* @public
|
|
96
96
|
*/
|
|
97
|
-
getItineraryInfo(
|
|
97
|
+
getItineraryInfo(position = null) {
|
|
98
98
|
|
|
99
99
|
if (!this.itinerary) {
|
|
100
100
|
throw new Error('No itinerary found');
|
|
101
101
|
}
|
|
102
|
-
const projection = this.getProjectionOnNetwork(
|
|
102
|
+
const projection = this.getProjectionOnNetwork(position);
|
|
103
103
|
if (!projection) {
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
|
+
import { Attitude } from '@wemap/geo';
|
|
3
|
+
|
|
4
|
+
import Provider from '../Provider';
|
|
5
|
+
import EventType from '../../events/EventType';
|
|
6
|
+
import ArCoreProvider from './ArCoreProvider';
|
|
7
|
+
import {
|
|
8
|
+
Quaternion, Vector3
|
|
9
|
+
} from '@wemap/maths';
|
|
10
|
+
import ImuProvider from '../others/ImuProvider';
|
|
11
|
+
import ProviderError from '../../events/ProviderError';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Pose provider is the provider used by the PositioningHandler. It uses the best fusion
|
|
15
|
+
* of what he can and provides an AbsoluteAttitude and an AbsolutePosition as an output.
|
|
16
|
+
*/
|
|
17
|
+
class ArCoreAbsoluteProvider extends Provider {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @override
|
|
21
|
+
*/
|
|
22
|
+
constructor(onEvent, onError, options) {
|
|
23
|
+
super(onEvent, onError, options);
|
|
24
|
+
|
|
25
|
+
this.arCoreProvider = new ArCoreProvider(
|
|
26
|
+
e => this.onArCoreEvent(e),
|
|
27
|
+
e => this.onArCoreError(e),
|
|
28
|
+
options);
|
|
29
|
+
|
|
30
|
+
this.imuProvider = new ImuProvider(
|
|
31
|
+
this.onImuEvent,
|
|
32
|
+
this.onImuError,
|
|
33
|
+
Object.assign(options || {}, { require: [EventType.AngularRate] })
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @override
|
|
39
|
+
*/
|
|
40
|
+
static get displayName() {
|
|
41
|
+
return 'ArCore absolute provider';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @override
|
|
46
|
+
*/
|
|
47
|
+
static get eventsType() {
|
|
48
|
+
return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Return the list of required providers
|
|
53
|
+
*/
|
|
54
|
+
static get requiredProviders() {
|
|
55
|
+
return [ArCoreProvider, ImuProvider];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @override
|
|
60
|
+
*/
|
|
61
|
+
startInternal() {
|
|
62
|
+
this.arCoreProvider.start();
|
|
63
|
+
this.imuProvider.start();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @override
|
|
68
|
+
*/
|
|
69
|
+
stopInternal() {
|
|
70
|
+
this.arCoreProvider.stop();
|
|
71
|
+
this.imuProvider.stop();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @override
|
|
76
|
+
*/
|
|
77
|
+
static checkAvailabilityErrors() {
|
|
78
|
+
return ArCoreProvider.checkAvailabilityErrors().concat(
|
|
79
|
+
ImuProvider.checkAvailabilityErrors()
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
onArCoreEvent = events => {
|
|
84
|
+
events.forEach(event => {
|
|
85
|
+
if (event.dataType === EventType.RelativeAttitude) {
|
|
86
|
+
|
|
87
|
+
// const previousAttitude = this.relativeAttitude;
|
|
88
|
+
this.relativeAttitude = event.data;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The two following blocks cannot be called in the same call because this.waitingForceHeading
|
|
92
|
+
* if exists, is called before the first this.relativeAttitude assigment. So, this.waitingForceHeading
|
|
93
|
+
* and previousAttitude should not be defined in the same time.
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
if (typeof this.waitingForceHeading !== 'undefined') {
|
|
97
|
+
/**
|
|
98
|
+
* waitingForceHeading is set by setHeading() if this.relativeAttitude does not exist
|
|
99
|
+
* At this moment, this.relativeAttitude is defined, so we can call setHeading again
|
|
100
|
+
*/
|
|
101
|
+
this.setHeading(this.waitingForceHeading);
|
|
102
|
+
delete this.waitingForceHeading;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// if (previousAttitude && this.absoluteAttitude) {
|
|
107
|
+
// /**
|
|
108
|
+
// * Sometimes ArCore has "orientation jumps" around z-axis.
|
|
109
|
+
// * Here we try to detect and remove them.
|
|
110
|
+
// */
|
|
111
|
+
// const dist = Quaternion.distance(event.data.quaternion, previousAttitude.quaternion);
|
|
112
|
+
// if (typeof this.angularRate !== 'undefined') {
|
|
113
|
+
// const velocity = Vector3.norm(this.angularRate);
|
|
114
|
+
// if (dist > deg2rad(10) && velocity < deg2rad(4)) {
|
|
115
|
+
// this.setHeading(this.absoluteAttitude.heading);
|
|
116
|
+
// }
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
if (this.offsetQuat) {
|
|
121
|
+
const absoluteQuaternion = Quaternion.multiply(this.offsetQuat, this.relativeAttitude.quaternion);
|
|
122
|
+
this.absoluteAttitude = new Attitude(absoluteQuaternion);
|
|
123
|
+
this.notify(this.createEvent(EventType.AbsoluteAttitude, this.absoluteAttitude, event.timestamp));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (event.dataType === EventType.RelativePosition) {
|
|
128
|
+
|
|
129
|
+
if (this.oldRelativePos && this.offsetAngle
|
|
130
|
+
&& !ArCoreAbsoluteProvider.positionEquals(this.oldRelativePos, event.data)) {
|
|
131
|
+
|
|
132
|
+
const diffPos = Vector3.subtract(event.data, this.oldRelativePos);
|
|
133
|
+
const dist = Math.sqrt(diffPos[0] ** 2 + diffPos[2] ** 2);
|
|
134
|
+
const bearing = Math.atan2(diffPos[0], -diffPos[2]) - this.offsetAngle;
|
|
135
|
+
this.position = this.position.destinationPoint(dist, bearing, diffPos[1]);
|
|
136
|
+
this.notify(this.createEvent(EventType.AbsolutePosition, this.position, event.timestamp));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.oldRelativePos = event.data;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static positionEquals(pos1, pos2) {
|
|
145
|
+
return pos1[0] === pos2[0] && pos1[1] === pos2[1] && pos1[2] === pos2[2];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
onArCoreError = arCoreErrors => {
|
|
149
|
+
this.notifyError(...(
|
|
150
|
+
ProviderError.modifyArrayDataType(arCoreErrors, EventType.AbsoluteAttitude).concat(
|
|
151
|
+
ProviderError.modifyArrayDataType(arCoreErrors, EventType.AbsolutePosition)
|
|
152
|
+
))
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
onImuEvent = events => {
|
|
157
|
+
this.angularRate = events[0].data;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
onImuError = imuErrors => {
|
|
161
|
+
this.notifyError(...(
|
|
162
|
+
ProviderError.modifyArrayDataType(imuErrors, EventType.AbsoluteAttitude).concat(
|
|
163
|
+
ProviderError.modifyArrayDataType(imuErrors, EventType.AbsolutePosition)
|
|
164
|
+
))
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
setHeading(heading) {
|
|
169
|
+
|
|
170
|
+
if (!this.relativeAttitude) {
|
|
171
|
+
this.waitingForceHeading = heading;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this.offsetAngle = this.relativeAttitude.heading - heading;
|
|
176
|
+
this.offsetQuat = Quaternion.fromAxisAngle([0, 0, 1], this.offsetAngle);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setPosition(position) {
|
|
180
|
+
this.position = position.clone();
|
|
181
|
+
this.position.provider = this.constructor.name;
|
|
182
|
+
this.notify(this.createEvent(EventType.AbsolutePosition, this.position));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export default ArCoreAbsoluteProvider;
|
|
@@ -3,6 +3,7 @@ import { Attitude } from '@wemap/geo';
|
|
|
3
3
|
import Provider from '../Provider';
|
|
4
4
|
import EventType from '../../events/EventType';
|
|
5
5
|
import MissingArCoreError from '../../errors/MissingArCoreError';
|
|
6
|
+
import MissingNativeInterfaceError from '../../errors/MissingNativeInterfaceError';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Pose provider is the provider used by the PositioningHandler. It uses the best fusion
|
|
@@ -10,14 +11,6 @@ import MissingArCoreError from '../../errors/MissingArCoreError';
|
|
|
10
11
|
*/
|
|
11
12
|
class ArCoreProvider extends Provider {
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* @override
|
|
15
|
-
*/
|
|
16
|
-
constructor(onEvent, onError, options) {
|
|
17
|
-
super(onEvent, onError, options);
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
14
|
/**
|
|
22
15
|
* @override
|
|
23
16
|
*/
|
|
@@ -43,12 +36,9 @@ class ArCoreProvider extends Provider {
|
|
|
43
36
|
* @override
|
|
44
37
|
*/
|
|
45
38
|
startInternal() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.notifyError(nativeProvider);
|
|
49
|
-
return;
|
|
39
|
+
if (ArCoreProvider.nativeProvider) {
|
|
40
|
+
ArCoreProvider.nativeProvider.start();
|
|
50
41
|
}
|
|
51
|
-
nativeProvider.start();
|
|
52
42
|
|
|
53
43
|
this.pullDataLoop();
|
|
54
44
|
}
|
|
@@ -57,12 +47,9 @@ class ArCoreProvider extends Provider {
|
|
|
57
47
|
* @override
|
|
58
48
|
*/
|
|
59
49
|
stopInternal() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.notifyError(nativeProvider);
|
|
63
|
-
return;
|
|
50
|
+
if (ArCoreProvider.nativeProvider) {
|
|
51
|
+
ArCoreProvider.nativeProvider.stop();
|
|
64
52
|
}
|
|
65
|
-
nativeProvider.stop();
|
|
66
53
|
}
|
|
67
54
|
|
|
68
55
|
pullDataLoop = () => {
|
|
@@ -71,13 +58,7 @@ class ArCoreProvider extends Provider {
|
|
|
71
58
|
return;
|
|
72
59
|
}
|
|
73
60
|
|
|
74
|
-
const
|
|
75
|
-
if (Array.isArray(nativeProvider)) {
|
|
76
|
-
this.notifyError(...nativeProvider);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const pose = JSON.parse(nativeProvider.getInfo());
|
|
61
|
+
const pose = JSON.parse(ArCoreProvider.nativeProvider.getInfo());
|
|
81
62
|
if (pose.length !== 0) {
|
|
82
63
|
const attitude = new Attitude(pose.slice(0, 4));
|
|
83
64
|
const position = pose.slice(4, 7);
|
|
@@ -90,17 +71,22 @@ class ArCoreProvider extends Provider {
|
|
|
90
71
|
requestAnimationFrame(this.pullDataLoop);
|
|
91
72
|
}
|
|
92
73
|
|
|
93
|
-
static
|
|
94
|
-
|
|
74
|
+
static get nativeProvider() {
|
|
75
|
+
|
|
76
|
+
if (!this._nativeProvider) {
|
|
77
|
+
|
|
78
|
+
if (!this.nativeInterface) {
|
|
79
|
+
throw new MissingNativeInterfaceError();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this._nativeProvider = this.nativeInterface.getArCoreProvider();
|
|
83
|
+
if (!this._nativeProvider) {
|
|
84
|
+
throw new MissingArCoreError();
|
|
85
|
+
}
|
|
95
86
|
|
|
96
|
-
if (!nativeInterface) {
|
|
97
|
-
return [
|
|
98
|
-
this.createMissingNativeInterfaceError(EventType.RelativeAttitude),
|
|
99
|
-
this.createMissingNativeInterfaceError(EventType.RelativePosition)
|
|
100
|
-
];
|
|
101
87
|
}
|
|
102
88
|
|
|
103
|
-
return
|
|
89
|
+
return this._nativeProvider;
|
|
104
90
|
}
|
|
105
91
|
|
|
106
92
|
/**
|
|
@@ -108,19 +94,21 @@ class ArCoreProvider extends Provider {
|
|
|
108
94
|
*/
|
|
109
95
|
static checkAvailabilityErrors() {
|
|
110
96
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
97
|
+
try {
|
|
98
|
+
const nativeProvider = this.nativeProvider;
|
|
99
|
+
|
|
100
|
+
if (!nativeProvider.checkAvailability()) {
|
|
101
|
+
throw new MissingArCoreError();
|
|
102
|
+
}
|
|
115
103
|
|
|
116
|
-
|
|
117
|
-
return [
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return [
|
|
106
|
+
this.createError(EventType.RelativeAttitude, e),
|
|
107
|
+
this.createError(EventType.RelativePosition, e)
|
|
108
|
+
];
|
|
118
109
|
}
|
|
119
110
|
|
|
120
|
-
return [
|
|
121
|
-
this.createError(EventType.RelativeAttitude, new MissingArCoreError()),
|
|
122
|
-
this.createError(EventType.RelativePosition, new MissingArCoreError())
|
|
123
|
-
];
|
|
111
|
+
return [];
|
|
124
112
|
}
|
|
125
113
|
}
|
|
126
114
|
|
|
@@ -84,7 +84,7 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
84
84
|
onPdrEvent(pdrEvent) {
|
|
85
85
|
pdrEvent.forEach(event => {
|
|
86
86
|
if (event.dataType === EventType.AbsolutePosition) {
|
|
87
|
-
this.
|
|
87
|
+
this.position = event.data;
|
|
88
88
|
} else if (event.dataType === EventType.AbsoluteAttitude) {
|
|
89
89
|
this.attitude = event.data;
|
|
90
90
|
}
|
|
@@ -98,39 +98,39 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
98
98
|
onGnssWifiEvent(events) {
|
|
99
99
|
|
|
100
100
|
const gnssWifiEvent = events[0];
|
|
101
|
-
const
|
|
101
|
+
const position = gnssWifiEvent.data;
|
|
102
102
|
|
|
103
103
|
// This should be called to update True North / Magnetic North declination
|
|
104
|
-
this.absoluteAttitudeProvider.
|
|
104
|
+
this.absoluteAttitudeProvider.setPosition(position);
|
|
105
105
|
|
|
106
|
-
if (
|
|
106
|
+
if (position.accuracy > GPF_ACCURACY) {
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
110
|
+
this.gnssPosition = position.clone();
|
|
111
|
+
this.gnssPosition.alt = Constants.DEFAULT_ALTITUDE;
|
|
112
112
|
|
|
113
|
-
if (!this.
|
|
114
|
-
&& this.
|
|
113
|
+
if (!this.position || this.position
|
|
114
|
+
&& this.position.distanceTo(this.gnssPosition) > GPF_DISTANCE) {
|
|
115
115
|
|
|
116
116
|
if (!this.mapMatching || !this.attitude) {
|
|
117
|
-
this.pdrProvider.
|
|
117
|
+
this.pdrProvider.setPosition(this.gnssPosition);
|
|
118
118
|
} else {
|
|
119
119
|
|
|
120
|
-
this.
|
|
121
|
-
const projection = this.mapMatching.getProjection(this.
|
|
120
|
+
this.gnssPosition.bearing = this.attitude.headingDegrees;
|
|
121
|
+
const projection = this.mapMatching.getProjection(this.gnssPosition);
|
|
122
122
|
|
|
123
123
|
if (projection && projection.projection) {
|
|
124
124
|
|
|
125
|
-
// Create a new
|
|
126
|
-
const
|
|
127
|
-
this.pdrProvider.
|
|
125
|
+
// Create a new position from projection and new GNSS position.
|
|
126
|
+
const projectedPosition = WGS84UserPosition.fromWGS84(projection.projection, this.gnssPosition);
|
|
127
|
+
this.pdrProvider.setPosition(projectedPosition);
|
|
128
128
|
|
|
129
129
|
// // If nearest element is an edge, use its orientation to set heading
|
|
130
130
|
// if (projection.nearestElement instanceof Edge) {
|
|
131
131
|
// const edgeBearing = projection.nearestElement.bearing;
|
|
132
|
-
// const diff1 = MathUtils.diffAngle(MathUtils.deg2rad(this.
|
|
133
|
-
// const diff2 = MathUtils.diffAngle(MathUtils.deg2rad(this.
|
|
132
|
+
// const diff1 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssPosition.bearing), edgeBearing);
|
|
133
|
+
// const diff2 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssPosition.bearing), edgeBearing + Math.PI);
|
|
134
134
|
// this.pdrProvider.setHeading(diff1 < diff2 ? edgeBearing : edgeBearing + Math.PI);
|
|
135
135
|
// }
|
|
136
136
|
|
|
@@ -139,7 +139,7 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
} else {
|
|
142
|
-
this.pdrProvider.
|
|
142
|
+
this.pdrProvider.setPosition(this.gnssPosition);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -208,9 +208,9 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
208
208
|
|
|
209
209
|
// When the first itinerary is received, first or second node (depending on MM_GNSS_DIST) is used as a starting point. No map-matching is needed here as router already provide the projection in the itinerary (node2 is node1 projection on OSRM network).
|
|
210
210
|
|
|
211
|
-
if (!this.
|
|
211
|
+
if (!this.gnssPosition
|
|
212
212
|
|| itinerary.length < 2
|
|
213
|
-
|| !itinerary.points[0].equalsTo(this.
|
|
213
|
+
|| !itinerary.points[0].equalsTo(this.gnssPosition)) {
|
|
214
214
|
console.warn('Itinerary has not been calculated from GnssWifiPdrProvider and these is not recommanded');
|
|
215
215
|
}
|
|
216
216
|
|
|
@@ -222,7 +222,7 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
222
222
|
}
|
|
223
223
|
const startPoint = WGS84UserPosition.fromWGS84(startEdge.node1);
|
|
224
224
|
startPoint.alt = Constants.DEFAULT_ALTITUDE;
|
|
225
|
-
this.pdrProvider.
|
|
225
|
+
this.pdrProvider.setPosition(startPoint);
|
|
226
226
|
this.pdrProvider.setStepDetectionLockerOrientation(startEdge.getBearing());
|
|
227
227
|
}
|
|
228
228
|
|
|
@@ -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
|
}
|