@wemap/positioning 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/.eslintrc.json +4 -2
  2. package/debug/absolute-attitude.html +16 -0
  3. package/debug/arcore.html +16 -0
  4. package/debug/gnss-wifi-pdr.html +16 -0
  5. package/debug/gnss-wifi.html +16 -0
  6. package/debug/imu.html +16 -0
  7. package/debug/inclination.html +16 -0
  8. package/debug/pdr.html +16 -0
  9. package/debug/pose.html +16 -0
  10. package/debug/positioning.html +16 -0
  11. package/debug/relative-attitude.html +16 -0
  12. package/package.json +7 -4
  13. package/src/PositioningHandler.js +96 -34
  14. package/src/components/AbsoluteAttitudeComponent.jsx +104 -0
  15. package/src/components/ArCoreComponent.jsx +74 -0
  16. package/src/components/GnssWifiComponent.jsx +58 -0
  17. package/src/components/GnssWifiPdrComponent.jsx +94 -0
  18. package/src/components/ImuComponent.jsx +100 -0
  19. package/src/components/InclinationComponent.jsx +53 -0
  20. package/src/components/MapComponent.jsx +226 -0
  21. package/src/components/PdrComponent.jsx +97 -0
  22. package/src/components/PoseComponent.jsx +81 -0
  23. package/src/components/PositioningComponent.jsx +26 -0
  24. package/src/components/PositioningInclinationComponent.jsx +76 -0
  25. package/src/components/PositioningPoseComponent.jsx +120 -0
  26. package/src/components/RelativeAttitudeComponent.jsx +82 -0
  27. package/src/components/StartStopComponent.jsx +50 -0
  28. package/src/components/Utils.js +92 -0
  29. package/src/components/index.js +32 -0
  30. package/src/errors/AskImuOnDesktopError.js +9 -0
  31. package/src/errors/GeolocationApiMissingError.js +9 -0
  32. package/src/errors/GeolocationPermissionDeniedError.js +9 -0
  33. package/src/errors/GeolocationPositionUnavailableError.js +9 -0
  34. package/src/errors/IpResolveServerError.js +9 -0
  35. package/src/errors/MissingAccelerometerError.js +11 -0
  36. package/src/errors/MissingArCoreError.js +9 -0
  37. package/src/errors/MissingGyroscopeError.js +11 -0
  38. package/src/errors/MissingMagnetometerError.js +9 -0
  39. package/src/errors/MissingNativeInterfaceError.js +9 -0
  40. package/src/errors/MissingSensorError.js +14 -0
  41. package/src/events/EventType.js +20 -0
  42. package/src/events/ProviderError.js +52 -0
  43. package/src/events/ProviderEvent.js +35 -0
  44. package/src/index.js +2 -2
  45. package/src/providers/Constants.js +5 -0
  46. package/src/providers/FakeAbsolutePositionProvider.js +56 -0
  47. package/src/providers/Provider.js +230 -0
  48. package/src/providers/ProviderOptions.js +28 -0
  49. package/{src.old → src}/providers/ProvidersLogger.js +2 -2
  50. package/src/providers/attitude/AbsoluteAttitudeProvider.js +207 -0
  51. package/src/providers/attitude/RelativeAttitudeProvider.js +129 -0
  52. package/src/providers/others/ImuProvider.js +186 -0
  53. package/src/providers/others/InclinationProvider.js +107 -0
  54. package/{src.old/providers/LocationSource.js → src/providers/others/MapMatchingProvider.js} +5 -148
  55. package/src/providers/pose/ArCoreProvider.js +127 -0
  56. package/src/providers/pose/GnssWifiPdrProvider.js +233 -0
  57. package/src/providers/pose/PoseProvider.js +90 -0
  58. package/{src.old/providers/PdrLocationSource.js → src/providers/pose/pdr/PdrProvider.js} +145 -113
  59. package/{src.old/providers/pdr → src/providers/pose/pdr/helpers}/Smoother.js +1 -1
  60. package/src/providers/position/GnssWifiProvider.js +129 -0
  61. package/src/providers/position/IpProvider.js +75 -0
  62. package/webpack/webpack.common.js +1 -1
  63. package/webpack/webpack.dev.js +1 -1
  64. package/debug/index.html +0 -15
  65. package/debug/index.old.html +0 -37
  66. package/scripts/release-github.js +0 -216
  67. package/src/providers/FakeLocationSource.js +0 -36
  68. package/src.old/Constants.js +0 -11
  69. package/src.old/NavigationHandler.js +0 -244
  70. package/src.old/Pose.js +0 -8
  71. package/src.old/attitude/AttitudeHandler.js +0 -342
  72. package/src.old/components/AbsoluteAttitude.jsx +0 -136
  73. package/src.old/components/Imu.jsx +0 -89
  74. package/src.old/components/LocationSource.jsx +0 -434
  75. package/src.old/components/Logger.jsx +0 -113
  76. package/src.old/components/NavigationDebugApp.jsx +0 -106
  77. package/src.old/components/Others.jsx +0 -121
  78. package/src.old/components/RelativeAttitude.jsx +0 -104
  79. package/src.old/components/Utils.js +0 -35
  80. package/src.old/components/index.js +0 -13
  81. package/src.old/index.js +0 -7
  82. package/src.old/providers/FixedLocationImuLocationSource.js +0 -66
  83. package/src.old/providers/GnssLocationSource.js +0 -118
  84. package/src.old/providers/GnssPdrLocationSource.js +0 -182
  85. package/src.old/providers/IPLocationSource.js +0 -96
  86. package/src.old/sensors/SensorsCompatibility.js +0 -486
  87. package/src.old/sensors/SensorsCompatibility.spec.js +0 -270
  88. package/src.old/sensors/SensorsLogger.js +0 -94
  89. package/src.old/sensors/SensorsLoggerUtils.js +0 -35
  90. /package/{src.old → src/providers}/attitude/EkfAttitude.js +0 -0
  91. /package/{src.old → src/providers}/attitude/EkfAttitude.spec.js +0 -0
  92. /package/{src.old/providers/pdr → src/providers/pose/pdr/helpers}/HeadingUnlocker.js +0 -0
  93. /package/{src.old/providers/pdr → src/providers/pose/pdr/helpers}/HeadingUnlocker.spec.js +0 -0
  94. /package/{src.old/providers/pdr → src/providers/pose/pdr/helpers}/Smoother.spec.js +0 -0
  95. /package/{src.old/providers/pdr → src/providers/pose/pdr/helpers}/ThugDetector.js +0 -0
  96. /package/{src.old/providers → src/providers/pose/pdr}/steps/StepDetection.js +0 -0
  97. /package/{src.old/providers → src/providers/pose/pdr}/steps/StepDetectionLadetto.js +0 -0
  98. /package/{src.old/providers → src/providers/pose/pdr}/steps/StepDetectionMinMaxPeaks.js +0 -0
  99. /package/{src.old/providers → src/providers/pose/pdr}/steps/StepDetectionMinMaxPeaks2.js +0 -0
@@ -0,0 +1,233 @@
1
+ /* eslint max-statements: ["error", 40]*/
2
+
3
+ import { WGS84UserPosition } from '@wemap/geo';
4
+
5
+ import MapMatchingProvider from '../others/MapMatchingProvider';
6
+ import PdrProvider from './pdr/PdrProvider';
7
+ import GnssWifiProvider from '../position/GnssWifiProvider';
8
+ import EventType from '../../events/EventType';
9
+ import AbsoluteAttitudeProvider from '../attitude/AbsoluteAttitudeProvider';
10
+ import Constants from '../Constants';
11
+ import ProviderError from '../../events/ProviderError';
12
+
13
+ const GPF_ACCURACY = 25;
14
+ const GPF_DISTANCE = 25;
15
+
16
+ const MM_GNSS_DIST = 20;
17
+ const MM_GNSS_ANGLE = 20;
18
+
19
+ class GnssWifiPdrProvider extends MapMatchingProvider {
20
+
21
+ /**
22
+ * @override
23
+ */
24
+ constructor(onEvent, onError, options) {
25
+ super(onEvent, onError, options);
26
+
27
+ this.pdrProvider = new PdrProvider(e => this.onPdrEvent(e), e => this.onProviderError(e), options);
28
+ this.gnssWifiProvider = new GnssWifiProvider(e => this.onGnssWifiEvent(e), e => this.onProviderError(e), options);
29
+ this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(
30
+ e => this.onAbsoluteAttitudeEvent(e),
31
+ e => this.onProviderError(e),
32
+ options
33
+ );
34
+
35
+ this.gpsLastUpdate = 0;
36
+ this.isFirstGnssUpdate = true;
37
+ this.isFirstAttitudeUpdate = true;
38
+ }
39
+
40
+
41
+ /**
42
+ * @override
43
+ */
44
+ static get displayName() {
45
+ return 'GnssWifiPdr';
46
+ }
47
+
48
+ /**
49
+ * @override
50
+ */
51
+ static get eventsType() {
52
+ return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
53
+ }
54
+
55
+ /**
56
+ * @override
57
+ */
58
+ static get requiredProviders() {
59
+ return [PdrProvider, GnssWifiProvider, AbsoluteAttitudeProvider];
60
+ }
61
+
62
+
63
+ /**
64
+ * @override
65
+ */
66
+ startInternal() {
67
+ this.pdrProvider.start();
68
+ this.gnssWifiProvider.start();
69
+ this.absoluteAttitudeProvider.start();
70
+ }
71
+
72
+ /**
73
+ * @override
74
+ */
75
+ stop() {
76
+ this.imuProvider.stop();
77
+ this.gnssWifiProvider.stop();
78
+ this.absoluteAttitudeProvider.stop();
79
+ }
80
+
81
+ /**
82
+ * @private
83
+ */
84
+ onPdrEvent(pdrEvent) {
85
+ pdrEvent.forEach(event => {
86
+ if (event.dataType === EventType.AbsolutePosition) {
87
+ this.location = event.data;
88
+ } else if (event.dataType === EventType.AbsoluteAttitude) {
89
+ this.attitude = event.data;
90
+ }
91
+ });
92
+ this.notify(...pdrEvent);
93
+ }
94
+
95
+ /**
96
+ * @private
97
+ */
98
+ onGnssWifiEvent(events) {
99
+
100
+ const gnssWifiEvent = events[0];
101
+ const location = gnssWifiEvent.data;
102
+
103
+ // This should be called to update True North / Magnetic North declination
104
+ this.absoluteAttitudeProvider.setLocation(location);
105
+
106
+ if (location.accuracy > GPF_ACCURACY) {
107
+ return;
108
+ }
109
+
110
+ this.gnssLocation = location.clone();
111
+ this.gnssLocation.alt = Constants.DEFAULT_ALTITUDE;
112
+
113
+ if (!this.location || this.location
114
+ && this.location.distanceTo(this.gnssLocation) > GPF_DISTANCE) {
115
+
116
+ if (!this.mapMatching || !this.attitude) {
117
+ this.pdrProvider.setLocation(this.gnssLocation);
118
+ } else {
119
+
120
+ this.gnssLocation.bearing = this.attitude.headingDegrees;
121
+ const projection = this.mapMatching.getProjection(this.gnssLocation);
122
+
123
+ if (projection && projection.projection) {
124
+
125
+ // Create a new location from projection and new GNSS location.
126
+ const projectedLocation = WGS84UserPosition.fromWGS84(projection.projection, this.gnssLocation);
127
+ this.pdrProvider.setLocation(projectedLocation);
128
+
129
+ // // If nearest element is an edge, use its orientation to set heading
130
+ // if (projection.nearestElement instanceof Edge) {
131
+ // const edgeBearing = projection.nearestElement.bearing;
132
+ // const diff1 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssLocation.bearing), edgeBearing);
133
+ // const diff2 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssLocation.bearing), edgeBearing + Math.PI);
134
+ // this.pdrProvider.setHeading(diff1 < diff2 ? edgeBearing : edgeBearing + Math.PI);
135
+ // }
136
+
137
+ if (this.lastAttitude) {
138
+ this.pdrProvider.setHeading(this.lastAttitude.heading);
139
+ }
140
+
141
+ } else {
142
+ this.pdrProvider.setLocation(this.gnssLocation);
143
+ }
144
+ }
145
+ }
146
+
147
+ }
148
+
149
+ onAbsoluteAttitudeEvent(events) {
150
+
151
+ const attitude = events[0].data;
152
+
153
+ if (this.isFirstAttitudeUpdate) {
154
+ this.pdrProvider.setHeading(attitude.heading);
155
+ this.isFirstAttitudeUpdate = false;
156
+ }
157
+
158
+ this.lastAttitude = attitude;
159
+ }
160
+
161
+ onProviderError(errors) {
162
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsoluteAttitude));
163
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsolutePosition));
164
+ }
165
+
166
+ /**
167
+ * @override
168
+ */
169
+ static checkAvailabilityErrors() {
170
+ const errors = super.checkAvailabilityErrors();
171
+ return ProviderError.modifyArrayDataType(
172
+ errors,
173
+ EventType.AbsolutePosition
174
+ ).concat(
175
+ ProviderError.modifyArrayDataType(
176
+ errors,
177
+ EventType.AbsoluteAttitude
178
+ )
179
+ );
180
+ }
181
+
182
+ /**
183
+ * MapMatching
184
+ */
185
+
186
+ enableMapMatching(network = null, maxDistance = MM_GNSS_DIST, maxAngleBearing = MM_GNSS_ANGLE) {
187
+ this.pdrProvider.enableMapMatching(network, maxDistance, maxAngleBearing);
188
+ super.enableMapMatching(network, maxDistance, maxAngleBearing);
189
+ }
190
+
191
+
192
+ setNetwork(network) {
193
+ this.pdrProvider.setNetwork(network);
194
+ super.setNetwork(network);
195
+ }
196
+
197
+ /**
198
+ * Itinerary
199
+ */
200
+
201
+ setItinerary(itinerary) {
202
+
203
+ const isFirstItinerary = !this.itinerary;
204
+
205
+ super.setItinerary(itinerary);
206
+
207
+ if (isFirstItinerary && itinerary.length > 0) {
208
+
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
+
211
+ if (!this.gnssLocation
212
+ || itinerary.length < 2
213
+ || !itinerary.points[0].equalsTo(this.gnssLocation)) {
214
+ console.warn('Itinerary has not been calculated from GnssWifiPdrProvider and these is not recommanded');
215
+ }
216
+
217
+ let startEdge;
218
+ if (itinerary.firstEdge.getLength() <= MM_GNSS_DIST) {
219
+ startEdge = itinerary.firstEdge;
220
+ } else {
221
+ startEdge = itinerary.secondEdge;
222
+ }
223
+ const startPoint = WGS84UserPosition.fromWGS84(startEdge.node1);
224
+ startPoint.alt = Constants.DEFAULT_ALTITUDE;
225
+ this.pdrProvider.setLocation(startPoint);
226
+ this.pdrProvider.setStepDetectionLockerOrientation(startEdge.getBearing());
227
+ }
228
+
229
+ }
230
+
231
+ }
232
+
233
+ export default GnssWifiPdrProvider;
@@ -0,0 +1,90 @@
1
+ import Provider from '../Provider';
2
+ import EventType from '../../events/EventType';
3
+
4
+ import GnssWifiProvider from '../position/GnssWifiProvider';
5
+ import AbsoluteAttitudeProvider from '../attitude/AbsoluteAttitudeProvider';
6
+ import ProviderError from '../../events/ProviderError';
7
+
8
+ /**
9
+ * Pose provider is the provider used by the PositioningHandler. It uses the best fusion
10
+ * of what he can and provides an AbsoluteAttitude and an AbsolutePosition as an output.
11
+ */
12
+ class PoseProvider extends Provider {
13
+
14
+ /**
15
+ * @override
16
+ */
17
+ constructor(onEvent, onError, options) {
18
+ super(onEvent, onError, options);
19
+
20
+ this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(onEvent, e => this.onAbsoluteAttitudeError(e));
21
+ this.gnssWifiProvider = new GnssWifiProvider((events) => {
22
+ this.absoluteAttitudeProvider.setLocation(events[0].data);
23
+ onEvent(events);
24
+ }, e => this.onGnssWifiError(e));
25
+ }
26
+
27
+ /**
28
+ * @override
29
+ */
30
+ static get displayName() {
31
+ return 'Pose provider';
32
+ }
33
+
34
+ /**
35
+ * @override
36
+ */
37
+ static get eventsType() {
38
+ return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
39
+ }
40
+
41
+ /**
42
+ * Return the list of required providers
43
+ */
44
+ static get requiredProviders() {
45
+ return [AbsoluteAttitudeProvider, GnssWifiProvider];
46
+ }
47
+
48
+ /**
49
+ * @override
50
+ */
51
+ startInternal() {
52
+ this.absoluteAttitudeProvider.start();
53
+ this.gnssWifiProvider.start();
54
+ }
55
+
56
+ /**
57
+ * @override
58
+ */
59
+ stopInternal() {
60
+ this.absoluteAttitudeProvider.stop();
61
+ this.gnssWifiProvider.stop();
62
+ }
63
+
64
+ onAbsoluteAttitudeError(errors) {
65
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsoluteAttitude));
66
+ }
67
+
68
+ onGnssWifiError(errors) {
69
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsolutePosition));
70
+ }
71
+
72
+ /**
73
+ * @override
74
+ */
75
+ static checkAvailabilityErrors() {
76
+ const errorsAttitude = AbsoluteAttitudeProvider.checkAvailabilityErrors();
77
+ const errorsGnssWifi = GnssWifiProvider.checkAvailabilityErrors();
78
+ return ProviderError.modifyArrayDataType(
79
+ errorsGnssWifi,
80
+ EventType.AbsolutePosition
81
+ ).concat(
82
+ ProviderError.modifyArrayDataType(
83
+ errorsAttitude,
84
+ EventType.AbsoluteAttitude
85
+ )
86
+ );
87
+ }
88
+ }
89
+
90
+ export default PoseProvider;
@@ -7,15 +7,15 @@ import {
7
7
  rad2deg, Quaternion
8
8
  } from '@wemap/maths';
9
9
 
10
- import LocationSource from './LocationSource';
11
- import AttitudeHandler from '../attitude/AttitudeHandler';
12
- import Constants from '../Constants';
13
- import SensorsLogger from '../sensors/SensorsLogger';
14
- import SensorsCompatibility from '../sensors/SensorsCompatibility';
15
10
  import StepDetection from './steps/StepDetection';
16
- import HeadingUnlocker from './pdr/HeadingUnlocker';
17
- import ThugDetector from './pdr/ThugDetector';
18
- import Smoother from './pdr/Smoother';
11
+ import HeadingUnlocker from './helpers/HeadingUnlocker';
12
+ import ThugDetector from './helpers/ThugDetector';
13
+ import Smoother from './helpers/Smoother';
14
+ import RelativeAttitudeProvider from '../../attitude/RelativeAttitudeProvider';
15
+ import ImuProvider from '../../others/ImuProvider';
16
+ import EventType from '../../../events/EventType';
17
+ import MapMatchingProvider from '../../others/MapMatchingProvider';
18
+ import ProviderError from '../../../events/ProviderError';
19
19
 
20
20
 
21
21
  const MM_PDR_ANGLE = 20;
@@ -30,138 +30,135 @@ const DEFAULT_OPTIONS = {
30
30
  onThugEvent: noop
31
31
  };
32
32
 
33
- class PdrLocationSource extends LocationSource {
33
+ class PdrProvider extends MapMatchingProvider {
34
34
 
35
- // pdrLocation can be different from this.pose.location
36
- // pdrLocation is raw location calculated by PdrLocationSource where
37
- // this.pose.location is smoothed location.
35
+ // pdrLocation can be different from this.location
36
+ // pdrLocation is raw location calculated by PdrProvider where
37
+ // this.location is smoothed location.
38
38
  pdrLocation = null;
39
39
 
40
- constructor(callback, options = DEFAULT_OPTIONS) {
41
- super(callback);
42
-
43
- // Assign params
44
- this.callback = callback;
45
- this.stepDetectionLockerEnabled = options.stepdetectionlocker !== null ? options.stepdetectionlocker : DEFAULT_OPTIONS.stepdetectionlocker;
46
- this.smootherEnabled = options.smoother !== null ? options.smoother : DEFAULT_OPTIONS.smoother;
47
- this.onThugEvent = options.onThugEvent !== null ? options.onThugEvent : DEFAULT_OPTIONS.onThugEvent;
40
+ /**
41
+ * @override
42
+ */
43
+ constructor(onEvent, onError, options) {
44
+ super(onEvent, onError, Object.assign(DEFAULT_OPTIONS, options || {}));
48
45
 
49
46
  // Input data providers
50
- this.attitudeHandler = new AttitudeHandler();
51
- this.sensorsCompatibility = new SensorsCompatibility();
47
+ this.relativeAttitudeProvider = new RelativeAttitudeProvider(
48
+ e => this.onRelativeAttitudeEvent(e),
49
+ e => this.onProviderError(e),
50
+ options
51
+ );
52
+ this.imuProvider = new ImuProvider(
53
+ e => this.onImuEvent(e),
54
+ e => this.onProviderError(e),
55
+ Object.assign(options || {}, { require: [EventType.Acceleration, EventType.AngularRate] })
56
+ );
52
57
 
53
58
  // Helpers for PDR
54
59
  this.stepDetection = new StepDetection();
55
60
  this.stepDetectionLocker = new HeadingUnlocker();
56
61
  this.smoother = new Smoother();
57
62
  this.thugDetector = new ThugDetector();
63
+
64
+ if (this.options.useMapMatching) {
65
+ this.enableMapMatching();
66
+ }
58
67
  }
59
68
 
69
+
60
70
  /**
61
- * Start the location source algorithm
62
- * @override
63
- */
64
- start() {
65
- super.start();
66
-
67
- return Promise.all([
68
- this.sensorsCompatibility.startImu(this.onNewMotion, {
69
- accelerometer: true,
70
- gyroscope: true
71
- }),
72
- this.attitudeHandler.startRelative(this.onNewAttitude, AttitudeHandler.RelativeMethod.INTERNAL_EKF)
73
- ]);
71
+ * @override
72
+ */
73
+ static get displayName() {
74
+ return 'PDR';
74
75
  }
75
76
 
76
77
  /**
77
- * Stop the location source algorithm
78
78
  * @override
79
79
  */
80
- stop() {
81
- super.stop();
82
-
83
- this.attitudeHandler.stopRelative();
84
- this.sensorsCompatibility.stopImu();
80
+ static get eventsType() {
81
+ return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
85
82
  }
86
83
 
87
84
  /**
88
- * Get provider name
89
85
  * @override
90
86
  */
91
- get providerNameWithOptions() {
92
- let name = this.providerName;
93
- name += ' (locker: ';
94
- name += this.stepDetectionLockerEnabled ? 'Y' : 'N';
95
- name += ', ';
96
- name += 'smoo: ';
97
- name += this.smootherEnabled ? 'Y' : 'N';
98
- name += ', ';
99
- name += 'mm: ';
100
- name += this.mapMatching ? 'Y' : 'N';
101
- name += ')';
102
- return name;
87
+ static get requiredProviders() {
88
+ return [ImuProvider, RelativeAttitudeProvider];
103
89
  }
104
90
 
91
+
105
92
  /**
106
- * Get provider name
107
93
  * @override
108
94
  */
109
- static get providerName() {
110
- return Constants.LOCATION_SOURCE_PROVIDERS.PDR;
95
+ startInternal() {
96
+ this.imuProvider.start();
97
+ this.relativeAttitudeProvider.start();
111
98
  }
112
99
 
113
100
  /**
114
101
  * @override
115
102
  */
116
- notify() {
117
- if (!this.pose.attitude) {
118
- return;
119
- }
120
- super.notify();
103
+ stopInternal() {
104
+ this.imuProvider.stop();
105
+ this.relativeAttitudeProvider.stop();
121
106
  }
122
107
 
123
- setLogger(logger) {
124
- super.setLogger(logger);
125
- this.sensorsCompatibility.setLogger(logger);
126
- this.attitudeHandler.setLogger(logger);
108
+ /**
109
+ * Get provider name
110
+ * @override
111
+ */
112
+ get nameWithOptions() {
113
+ let name = this.name;
114
+ name += ' (locker: ';
115
+ name += this.options.stepdetectionlocker ? 'Y' : 'N';
116
+ name += ', ';
117
+ name += 'smoo: ';
118
+ name += this.options.smoother ? 'Y' : 'N';
119
+ name += ', ';
120
+ name += 'mm: ';
121
+ name += this.options.useMapMatching ? 'Y' : 'N';
122
+ name += ')';
123
+ return name;
127
124
  }
128
125
 
129
126
  setHeading(heading) {
130
- this.attitudeHandler.setRelativeHeading(heading);
131
- if (this.logger) {
132
- this.logger.feedWithCurrentTime(SensorsLogger.DataType.USER_INPUT_HEADING, heading);
133
- }
127
+ this.relativeAttitudeProvider.setOffset(heading);
134
128
  }
135
129
 
136
130
  setLocation(location) {
137
131
  this.pdrLocation = location;
138
132
 
139
- if (this.smootherEnabled) {
133
+ if (this.options.smoother) {
140
134
  this.smoother.generateNextLocations(location, true);
141
135
  // this.smoother.pullLocation(location.time) should never return null
142
- this.pose.location = this.smoother.pullLocation(location.time);
136
+ this.location = this.smoother.pullLocation(location.time);
143
137
  } else {
144
- this.pose.location = location;
138
+ this.location = location.clone();
145
139
  }
146
140
 
147
- this.notify();
148
-
149
- if (this.logger) {
150
- const data = [location.lat, location.lng];
151
- if (location.altitude) {
152
- data.push(location.altitude);
153
- }
154
- this.logger.feedWithCurrentTime(SensorsLogger.DataType.USER_INPUT_POSITION, data);
155
- }
141
+ this.notify(this.createEvent(EventType.AbsolutePosition, this.location));
156
142
  }
157
143
 
158
- onNewAttitude = (attitude) => {
159
- this.pose.attitude = attitude;
144
+ /**
145
+ * @override
146
+ */
147
+ onRelativeAttitudeEvent = events => {
148
+ const attitudeEvent = events[0];
149
+ this.attitude = attitudeEvent.data;
150
+
151
+ const newEvent = attitudeEvent.clone();
152
+ newEvent.dataType = EventType.AbsoluteAttitude;
153
+ this.notify(newEvent);
160
154
  }
161
155
 
162
- onNewMotion = (motionEvent) => {
156
+ /**
157
+ * @private
158
+ */
159
+ onImuEvent = imuEvent => {
163
160
 
164
- if (!this.pose.attitude) {
161
+ if (!this.attitude) {
165
162
  // We should wait attitude for stepDetectionLocker and linear acceleration
166
163
  return;
167
164
  }
@@ -171,18 +168,25 @@ class PdrLocationSource extends LocationSource {
171
168
  return;
172
169
  }
173
170
 
174
- if (this.stepDetectionLockerEnabled
171
+ if (this.options.stepdetectionlocker
175
172
  && this.stepDetectionLocker.locked
176
- && this.stepDetectionLocker.feedHeading(this.pose.attitude.heading)) {
173
+ && this.stepDetectionLocker.feedHeading(this.attitude.heading)) {
177
174
  // Step detection is locked by stepDetectionLocker
178
- // We still need to notify for attitude
179
- this.notify();
180
175
  return;
181
176
  }
182
177
 
183
- const timestamp = motionEvent.timestamp;
184
- const heading = this.pose.attitude.heading;
185
- const acceleration = motionEvent.acc;
178
+
179
+ let timestamp, acceleration, angularRate;
180
+ imuEvent.forEach(event => {
181
+ if (event.dataType === EventType.Acceleration) {
182
+ acceleration = event.data;
183
+ timestamp = event.timestamp;
184
+ } else if (event.dataType === EventType.AngularRate) {
185
+ angularRate = event.data;
186
+ }
187
+ });
188
+
189
+ const heading = this.attitude.heading;
186
190
 
187
191
  if (this.onThugEvent && this.thugDetector.compute(timestamp, acceleration)) {
188
192
  this.onThugEvent();
@@ -191,35 +195,63 @@ class PdrLocationSource extends LocationSource {
191
195
  /**
192
196
  * Step Detection and Step Size Detection
193
197
  */
194
- const linearAcc = PdrLocationSource.computeLinearAcceleration(
195
- this.pose.attitude.quaternion, acceleration);
196
- const stepDetected = this.stepDetection.compute(timestamp, linearAcc, motionEvent.gyr);
198
+ const linearAcc = PdrProvider.computeLinearAcceleration(
199
+ this.attitude.quaternion, acceleration);
200
+ const stepDetected = this.stepDetection.compute(timestamp, linearAcc, angularRate);
197
201
 
198
202
  if (stepDetected) {
199
203
 
200
204
  this.pdrLocation = this.calculateNewLocation(this.pdrLocation, timestamp,
201
205
  heading, this.stepDetection.lastStepSize);
202
206
 
203
- if (this.smootherEnabled) {
207
+ /**
208
+ * Update current_position
209
+ */
210
+ if (this.options.smoother) {
204
211
  this.smoother.generateNextLocations(this.pdrLocation);
212
+ const newLocation = this.smoother.pullLocation(timestamp);
213
+ // At this time, newLocation can be null if a new step has been detected
214
+ // and smoother has not been completely consumed.
215
+ if (newLocation) {
216
+ this.location = newLocation;
217
+ }
218
+ } else {
219
+ this.location = this.pdrLocation;
205
220
  }
206
221
 
207
- /**
208
- * Update current_position
209
- */
210
- this.pose.location = this.smootherEnabled
211
- ? this.smoother.pullLocation(timestamp)
212
- : this.pdrLocation;
213
-
214
- } else if (this.smootherEnabled) {
222
+ } else if (this.options.smoother) {
215
223
  // If no step is detected, we pull last known location from smoother until now (timestamp).
216
224
  const smoothedLocation = this.smoother.pullLocation(timestamp);
217
- if (smoothedLocation) {
218
- this.pose.location = smoothedLocation;
225
+ if (!smoothedLocation) {
226
+ return;
219
227
  }
228
+ this.location = smoothedLocation;
229
+ } else {
230
+ return;
220
231
  }
221
232
 
222
- this.notify();
233
+ this.notify(this.createEvent(EventType.AbsolutePosition, this.location));
234
+ }
235
+
236
+ onProviderError(errors) {
237
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsoluteAttitude));
238
+ this.notifyError(...ProviderError.modifyArrayDataType(errors, EventType.AbsolutePosition));
239
+ }
240
+
241
+ /**
242
+ * @override
243
+ */
244
+ static checkAvailabilityErrors() {
245
+ const errors = super.checkAvailabilityErrors();
246
+ return ProviderError.modifyArrayDataType(
247
+ errors,
248
+ EventType.AbsolutePosition
249
+ ).concat(
250
+ ProviderError.modifyArrayDataType(
251
+ errors,
252
+ EventType.AbsoluteAttitude
253
+ )
254
+ );
223
255
  }
224
256
 
225
257
  calculateNewLocation(previousLocation, timestamp, heading, stepSize) {
@@ -262,8 +294,8 @@ class PdrLocationSource extends LocationSource {
262
294
  * MapMatching
263
295
  */
264
296
 
265
- enableMapMatching(network = [], maxDistance = MM_PDR_DIST, maxAngleBearing = MM_PDR_ANGLE) {
266
- super.enableMapMatching(network, maxDistance, maxAngleBearing);
297
+ enableMapMatching(network, maxDistance, maxAngleBearing) {
298
+ super.enableMapMatching(network, maxDistance || MM_PDR_DIST, maxAngleBearing || MM_PDR_ANGLE);
267
299
  }
268
300
 
269
301
 
@@ -274,9 +306,9 @@ class PdrLocationSource extends LocationSource {
274
306
  setItinerary(itinerary) {
275
307
  super.setItinerary(itinerary);
276
308
 
277
- if (this.stepDetectionLockerEnabled) {
309
+ if (this.options.stepdetectionlocker) {
278
310
  this.stepDetectionLocker.setWaitingOrientation(
279
- PdrLocationSource.retrieveWaitingOrientationFromItinerary(itinerary)
311
+ PdrProvider.retrieveWaitingOrientationFromItinerary(itinerary)
280
312
  );
281
313
  }
282
314
  }
@@ -317,4 +349,4 @@ class PdrLocationSource extends LocationSource {
317
349
  }
318
350
  }
319
351
 
320
- export default PdrLocationSource;
352
+ export default PdrProvider;