@wemap/providers 9.1.1 → 9.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.
package/index.js CHANGED
@@ -36,6 +36,7 @@ export { default as Inclination } from './src/providers/inclination/Inclination.
36
36
  export { default as StepDetector } from './src/providers/steps/StepDetector.js';
37
37
  export { default as StraightLineDetector } from './src/providers/steps/StraightLineDetector.js';
38
38
  export { default as StepDetectionMinMaxPeaks2 } from './src/providers/steps/StepDetectionMinMaxPeaks2.js';
39
+ export { default as StepDetectionMinMaxPeaks3 } from './src/providers/steps/StepDetectionMinMaxPeaks3.js';
39
40
 
40
41
  export { default as Pdr } from './src/providers/position/relative/Pdr.js';
41
42
  export { default as GeoRelativePositionFromArCore } from './src/providers/position/relative/GeoRelativePositionFromArCore.js';
package/package.json CHANGED
@@ -8,14 +8,14 @@
8
8
  "Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
9
9
  ],
10
10
  "dependencies": {
11
- "@wemap/camera": "^9.0.8",
12
- "@wemap/geo": "^9.1.1",
11
+ "@wemap/camera": "^9.2.0",
12
+ "@wemap/geo": "^9.2.0",
13
13
  "@wemap/geomagnetism": "^0.1.1",
14
- "@wemap/logger": "^9.0.0",
15
- "@wemap/map": "^9.1.1",
14
+ "@wemap/logger": "^9.2.0",
15
+ "@wemap/map": "^9.2.0",
16
16
  "@wemap/maths": "^9.0.0",
17
- "@wemap/osm": "^9.1.1",
18
- "@wemap/routers": "^9.1.1",
17
+ "@wemap/osm": "^9.2.0",
18
+ "@wemap/routers": "^9.2.0",
19
19
  "@wemap/utils": "^9.0.0"
20
20
  },
21
21
  "description": "A package using different geoloc systems",
@@ -42,6 +42,6 @@
42
42
  "url": "git+https://github.com/wemap/wemap-modules-js.git"
43
43
  },
44
44
  "type": "module",
45
- "version": "9.1.1",
46
- "gitHead": "bf6a54cf4f886ebac773549339ada8f98c0b7f7f"
45
+ "version": "9.2.0",
46
+ "gitHead": "9eee407fadd76fc5cbfbeeb13be0d74391ca5d9e"
47
47
  }
@@ -0,0 +1,201 @@
1
+ /* eslint-disable max-statements */
2
+ class StepDetectionMinMaxPeaks3 {
3
+
4
+ // in seconds
5
+ static WINDOW_TIME = 0.6;
6
+
7
+ // in seconds
8
+ static MIN_TIME_BETWEEN_STEPS = 0.6;
9
+
10
+ // in Hz
11
+ static MAX_FRENQUENCY = 4;
12
+ static MIN_FRENQUENCY = 1;
13
+
14
+ // in m.s-2
15
+ static VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD = 0.2;
16
+ static VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD = -0.1;
17
+
18
+
19
+ constructor() {
20
+ this.slidingWindow = [];
21
+
22
+ this.lastStepTimestamp = -StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS;
23
+ this.previousVerticalAcc = 0;
24
+ this.previousHorizontalAcc = 0;
25
+ this.influence = 0.05;
26
+ }
27
+
28
+
29
+ compute(timestamp, linearAcc) {
30
+
31
+ const verticalAcc = this.influence * linearAcc[2] + (1 - this.influence) * this.previousVerticalAcc;
32
+ this.previousVerticalAcc = verticalAcc;
33
+
34
+ // let horizontalAcc = Math.sqrt(linearAcc[0] ** 2 + linearAcc[1] ** 2);
35
+ // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;
36
+ // this.previousHorizontalAcc = horizontalAcc;
37
+
38
+ // const angularRateNorm = Math.sqrt(angularRate[0] ** 2 + angularRate[1] ** 2 + angularRate[2] ** 2);
39
+ // horizontalAcc = this.influence * horizontalAcc + (1 - this.influence) * this.previousHorizontalAcc;
40
+ // this.previousangularRateNorm = angularRateNorm;
41
+
42
+ // Update sliding window
43
+ this.slidingWindow = this.slidingWindow.filter(item =>
44
+ item.timestamp >= timestamp - StepDetectionMinMaxPeaks3.WINDOW_TIME
45
+ );
46
+ this.slidingWindow.push({ timestamp, verticalAcc });
47
+ // , horizontalAcc });
48
+
49
+ // this.horizontalAccStd = this.stddev(this.slidingWindow.map(el => el.horizontalAcc));
50
+ // this.verticalAccStd = this.stddev(this.slidingWindow.map(el => el.verticalAcc));
51
+
52
+
53
+ const isTooEarlyForANewStep = this.lastStepTimestamp
54
+ && this.lastStepTimestamp + StepDetectionMinMaxPeaks3.MIN_TIME_BETWEEN_STEPS > timestamp;
55
+ if (isTooEarlyForANewStep) {
56
+ return false;
57
+ }
58
+
59
+ // Looking for max peak
60
+ let maxValue = Number.MIN_VALUE;
61
+ let maxValueIdx = -1;
62
+ let foundMaxPeakHigherThanThreshold = false;
63
+ this.slidingWindow.forEach(function(item, idx) {
64
+ if (item.verticalAcc > maxValue
65
+ && item.verticalAcc >= StepDetectionMinMaxPeaks3.VERTICAL_ACC_POSITIVE_PEAK_THRESHOLD) {
66
+ maxValue = item.verticalAcc;
67
+ maxValueIdx = idx;
68
+ foundMaxPeakHigherThanThreshold = true;
69
+ }
70
+ });
71
+ if (!foundMaxPeakHigherThanThreshold) {
72
+ return false;
73
+ }
74
+
75
+ // Looking for a value lower than a threshold before the max peak
76
+ let hasLowNegativeValueBeforeMaxPeak = false;
77
+ let minValueBeforeMaxPeak = Number.MAX_VALUE;
78
+ for (let i = 0; i < maxValueIdx; i++) {
79
+ const curValue = this.slidingWindow[i].verticalAcc;
80
+ minValueBeforeMaxPeak = Math.min(minValueBeforeMaxPeak, curValue);
81
+ if (curValue < StepDetectionMinMaxPeaks3.VERTICAL_ACC_NEGATIVE_PEAK_THRESHOLD) {
82
+ hasLowNegativeValueBeforeMaxPeak = true;
83
+ break;
84
+ }
85
+ }
86
+ if (!hasLowNegativeValueBeforeMaxPeak) {
87
+ return false;
88
+ }
89
+
90
+ // looking for another minimum after max peak
91
+ const diffMinMax = maxValue - minValueBeforeMaxPeak;
92
+ const targetValue = maxValue - 0.5 * diffMinMax;
93
+ let targetValueFoundAfterMaxPeak = false;
94
+ for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {
95
+ if (this.slidingWindow[i].verticalAcc <= targetValue) {
96
+ targetValueFoundAfterMaxPeak = true;
97
+ break;
98
+ }
99
+ }
100
+ if (!targetValueFoundAfterMaxPeak) {
101
+ return false;
102
+ }
103
+
104
+ // // looking for another local minimum / maximum after 100ms
105
+ // let localMinimumFound = false;
106
+ // let localMaximumFound = false;
107
+ // let localMaxiumValue = Number.MIN_SAFE_INTEGER;
108
+ // let localMinimumVal = null;
109
+ // const maxPeakTimestamp = this.slidingWindow[maxValueIdx].timestamp;
110
+ // for (let i = maxValueIdx + 1; i < this.slidingWindow.length; i++) {
111
+ // const curVal = this.slidingWindow[i];
112
+ // const prevVal = this.slidingWindow[i - 1];
113
+
114
+ // if (curVal.timestamp > maxPeakTimestamp + 0.4) {
115
+ // break;
116
+ // }
117
+
118
+ // if (!localMinimumFound) {
119
+ // // if (curVal.timestamp < maxPeakTimestamp + 0.05) {
120
+ // // // too early
121
+ // // continue;
122
+ // // }
123
+
124
+ // if (curVal.verticalAcc > prevVal.verticalAcc) {
125
+ // localMinimumFound = true;
126
+ // localMinimumVal = prevVal;
127
+ // }
128
+ // continue;
129
+ // }
130
+
131
+ // if (!localMaximumFound) {
132
+
133
+ // // if (curVal.timestamp < localMinimumVal.timestamp + 0.05) {
134
+ // // // too early
135
+ // // continue;
136
+ // // }
137
+
138
+ // if (curVal.verticalAcc < prevVal.verticalAcc) {
139
+ // localMaximumFound = true;
140
+ // localMaxiumValue = prevVal.verticalAcc;
141
+ // break;
142
+ // }
143
+ // }
144
+ // }
145
+ // const localMinMaxFoundAfterPeak = localMinimumFound && localMaximumFound;
146
+ // // && localMaxiumValue / maxValue < 0.8;
147
+ // // if (!localMinMaxFoundAfterPeak) {
148
+ // // return false;
149
+ // // }
150
+
151
+
152
+ // const highRotationDetected = angularRateNorm > 0.75;
153
+ // // if (highRotationDetected) {
154
+ // // return false;
155
+ // // }
156
+
157
+ const timeInterval = this.lastStepTimestamp ? timestamp - this.lastStepTimestamp : 1;
158
+ this.frequency = Math.min(Math.max((1 / timeInterval), StepDetectionMinMaxPeaks3.MIN_FRENQUENCY), StepDetectionMinMaxPeaks3.MAX_FRENQUENCY);
159
+
160
+ this.lastStepTimestamp = timestamp;
161
+ return true;
162
+
163
+ }
164
+
165
+ get lastStepSize() {
166
+
167
+ if (!this.frequency) {
168
+ return 0;
169
+ }
170
+
171
+ const kParamA = 0.45;
172
+ const kParamB = 0.2;
173
+ return kParamA + kParamB * this.frequency;
174
+ }
175
+
176
+ get speed() {
177
+ return this.lastStepSize && this.frequency ? this.lastStepSize * this.frequency : 0;
178
+ }
179
+
180
+ mean(data) {
181
+ let sum = 0.0, mean = 0.0;
182
+
183
+ for (let i = 0; i < data.length; ++i) {
184
+ sum += data[i];
185
+ }
186
+ mean = sum / data.length;
187
+ return mean;
188
+ }
189
+
190
+ stddev(data) {
191
+ const theMean = this.mean(data);
192
+ let standardDeviation = 0;
193
+ for (let i = 0; i < data.length; ++i) {
194
+ standardDeviation += (data[i] - theMean) ** 2;
195
+ }
196
+
197
+ return Math.sqrt(standardDeviation / data.length);
198
+ }
199
+ }
200
+
201
+ export default StepDetectionMinMaxPeaks3;
@@ -6,7 +6,10 @@ import RelativeAttitudeFromInertial from '../attitude/relative/RelativeAttitudeF
6
6
  import Accelerometer from '../imu/Accelerometer.js';
7
7
  import Gyroscope from '../imu/Gyroscope.js';
8
8
  import Provider from '../Provider.js';
9
+ import StepDetectionLadetto from './StepDetectionLadetto.js';
10
+ import StepDetectionMinMaxPeaks from './StepDetectionMinMaxPeaks.js';
9
11
  import StepDetectionMinMaxPeaks2 from './StepDetectionMinMaxPeaks2.js';
12
+ import StepDetectionMinMaxPeaks3 from './StepDetectionMinMaxPeaks3.js';
10
13
 
11
14
 
12
15
  class StepDetector extends Provider {
@@ -14,11 +17,19 @@ class StepDetector extends Provider {
14
17
  /** @type {number} */
15
18
  static DEFAULT_STEP_SIZE_MULTIPLIER = 1;
16
19
 
20
+ // ladetto, minMaxPeaks, minMaxPeaks2, minMaxPeaks3
21
+ static DEFAULT_ALGORITHM = 'minMaxPeaks3';
22
+
17
23
  _stepSizeMultiplier = StepDetector.DEFAULT_STEP_SIZE_MULTIPLIER;
18
24
 
25
+ /** @type {string} */
26
+ _algorithm = StepDetector.DEFAULT_ALGORITHM;
27
+
28
+ _accValues = [];
29
+
19
30
  constructor() {
20
31
  super();
21
- this.stepDetector = new StepDetectionMinMaxPeaks2();
32
+ this.algorithm = this._algorithm;
22
33
  }
23
34
 
24
35
  /**
@@ -115,6 +126,26 @@ class StepDetector extends Provider {
115
126
  get stepSizeMultiplier() {
116
127
  return this._stepSizeMultiplier;
117
128
  }
129
+
130
+ set algorithm(algorithm) {
131
+ switch (algorithm) {
132
+ case 'ladetto':
133
+ this.stepDetector = new StepDetectionLadetto();
134
+ break;
135
+ case 'minMaxPeaks':
136
+ this.stepDetector = new StepDetectionMinMaxPeaks();
137
+ break;
138
+ case 'minMaxPeaks2':
139
+ this.stepDetector = new StepDetectionMinMaxPeaks2();
140
+ break;
141
+ case 'minMaxPeaks3':
142
+ default:
143
+ algorithm = 'minMaxPeaks3';
144
+ this.stepDetector = new StepDetectionMinMaxPeaks3();
145
+ break;
146
+ }
147
+ this._algorithm = algorithm;
148
+ }
118
149
  }
119
150
 
120
151
  export default new StepDetector();
@@ -0,0 +1,108 @@
1
+ import { Constants as GeoConstants } from '@wemap/geo';
2
+ import { Quaternion } from '@wemap/maths';
3
+
4
+ import EventType from '../../events/EventType.js';
5
+ import RelativeAttitudeFromInertial from '../attitude/relative/RelativeAttitudeFromInertial.js';
6
+ import Accelerometer from '../imu/Accelerometer.js';
7
+ import Gyroscope from '../imu/Gyroscope.js';
8
+ import Provider from '../Provider.js';
9
+ import StepDetectionLadetto from './StepDetectionLadetto.js';
10
+
11
+
12
+ class StepDetectorLadetto extends Provider {
13
+
14
+ constructor() {
15
+ super();
16
+ this.stepDetector = new StepDetectionLadetto();
17
+ }
18
+
19
+ /**
20
+ * @override
21
+ */
22
+ static get pname() {
23
+ return 'StepDetectorLadetto';
24
+ }
25
+
26
+ /**
27
+ * @override
28
+ */
29
+ get _availability() {
30
+ return Promise.all([
31
+ Accelerometer.availability,
32
+ Gyroscope.availability,
33
+ RelativeAttitudeFromInertial.availability
34
+ ]);
35
+ }
36
+
37
+ /**
38
+ * @override
39
+ */
40
+ start() {
41
+
42
+ this.numOfSteps = 0;
43
+
44
+ this.accelerometerProviderId = Accelerometer.addEventListener(
45
+ events => this.onAccelerometerEvent(events[0]),
46
+ error => this.notifyError(error)
47
+ );
48
+
49
+ this.gyroscopeProviderId = Gyroscope.addEventListener(
50
+ events => (this.angularRateEvent = events[0]),
51
+ error => this.notifyError(error)
52
+ );
53
+
54
+ this.attitudeProviderId = RelativeAttitudeFromInertial.addEventListener(
55
+ events => (this.attitudeEvent = events[0]),
56
+ error => this.notifyError(error)
57
+ );
58
+ }
59
+
60
+ /**
61
+ * @override
62
+ */
63
+ stop() {
64
+ Accelerometer.removeEventListener(this.accelerometerProviderId);
65
+ Gyroscope.removeEventListener(this.gyroscopeProviderId);
66
+ RelativeAttitudeFromInertial.removeEventListener(this.attitudeProviderId);
67
+ }
68
+
69
+ onAccelerometerEvent(accelerationEvent) {
70
+
71
+ if (!this.attitudeEvent || !this.angularRateEvent) {
72
+ return;
73
+ }
74
+
75
+ const {
76
+ values: acceleration, timestamp
77
+ } = accelerationEvent.data;
78
+
79
+ /**
80
+ * Step Detection and Step Size Detection
81
+ */
82
+ const linearAcc = this.constructor.computeLinearAcceleration(
83
+ this.attitudeEvent.data.quaternion, acceleration);
84
+ const stepDetected = this.stepDetector.compute(timestamp, linearAcc, this.angularRateEvent.data.values);
85
+
86
+ if (stepDetected) {
87
+ const size = this.stepDetector.lastStepSize;
88
+ this.numOfSteps++;
89
+ this.notify(this.createEvent(
90
+ EventType.Step, {
91
+ size,
92
+ number: this.numOfSteps
93
+ },
94
+ [accelerationEvent, this.angularRateEvent, this.attitudeEvent]
95
+ ));
96
+ }
97
+ }
98
+
99
+ // Linear acceleration in ENU
100
+ static computeLinearAcceleration(quaternion, acc) {
101
+ const linearAcc = Quaternion.rotateMatlab(Quaternion.inverse(quaternion), acc);
102
+ linearAcc[2] -= GeoConstants.EARTH_GRAVITY;
103
+ return linearAcc;
104
+ }
105
+
106
+ }
107
+
108
+ export default new StepDetectorLadetto();
@@ -0,0 +1,108 @@
1
+ import { Constants as GeoConstants } from '@wemap/geo';
2
+ import { Quaternion } from '@wemap/maths';
3
+
4
+ import EventType from '../../events/EventType.js';
5
+ import RelativeAttitudeFromInertial from '../attitude/relative/RelativeAttitudeFromInertial.js';
6
+ import Accelerometer from '../imu/Accelerometer.js';
7
+ import Gyroscope from '../imu/Gyroscope.js';
8
+ import Provider from '../Provider.js';
9
+ import StepDetectionMinMaxPeaks from './StepDetectionMinMaxPeaks.js';
10
+
11
+
12
+ class StepDetectorMinMaxPeaks extends Provider {
13
+
14
+ constructor() {
15
+ super();
16
+ this.stepDetector = new StepDetectionMinMaxPeaks();
17
+ }
18
+
19
+ /**
20
+ * @override
21
+ */
22
+ static get pname() {
23
+ return 'StepDetectorMinMaxPeaks';
24
+ }
25
+
26
+ /**
27
+ * @override
28
+ */
29
+ get _availability() {
30
+ return Promise.all([
31
+ Accelerometer.availability,
32
+ Gyroscope.availability,
33
+ RelativeAttitudeFromInertial.availability
34
+ ]);
35
+ }
36
+
37
+ /**
38
+ * @override
39
+ */
40
+ start() {
41
+
42
+ this.numOfSteps = 0;
43
+
44
+ this.accelerometerProviderId = Accelerometer.addEventListener(
45
+ events => this.onAccelerometerEvent(events[0]),
46
+ error => this.notifyError(error)
47
+ );
48
+
49
+ this.gyroscopeProviderId = Gyroscope.addEventListener(
50
+ events => (this.angularRateEvent = events[0]),
51
+ error => this.notifyError(error)
52
+ );
53
+
54
+ this.attitudeProviderId = RelativeAttitudeFromInertial.addEventListener(
55
+ events => (this.attitudeEvent = events[0]),
56
+ error => this.notifyError(error)
57
+ );
58
+ }
59
+
60
+ /**
61
+ * @override
62
+ */
63
+ stop() {
64
+ Accelerometer.removeEventListener(this.accelerometerProviderId);
65
+ Gyroscope.removeEventListener(this.gyroscopeProviderId);
66
+ RelativeAttitudeFromInertial.removeEventListener(this.attitudeProviderId);
67
+ }
68
+
69
+ onAccelerometerEvent(accelerationEvent) {
70
+
71
+ if (!this.attitudeEvent || !this.angularRateEvent) {
72
+ return;
73
+ }
74
+
75
+ const {
76
+ values: acceleration, timestamp
77
+ } = accelerationEvent.data;
78
+
79
+ /**
80
+ * Step Detection and Step Size Detection
81
+ */
82
+ const linearAcc = this.constructor.computeLinearAcceleration(
83
+ this.attitudeEvent.data.quaternion, acceleration);
84
+ const stepDetected = this.stepDetector.compute(timestamp, linearAcc, this.angularRateEvent.data.values);
85
+
86
+ if (stepDetected) {
87
+ const size = this.stepDetector.lastStepSize;
88
+ this.numOfSteps++;
89
+ this.notify(this.createEvent(
90
+ EventType.Step, {
91
+ size,
92
+ number: this.numOfSteps
93
+ },
94
+ [accelerationEvent, this.angularRateEvent, this.attitudeEvent]
95
+ ));
96
+ }
97
+ }
98
+
99
+ // Linear acceleration in ENU
100
+ static computeLinearAcceleration(quaternion, acc) {
101
+ const linearAcc = Quaternion.rotateMatlab(Quaternion.inverse(quaternion), acc);
102
+ linearAcc[2] -= GeoConstants.EARTH_GRAVITY;
103
+ return linearAcc;
104
+ }
105
+
106
+ }
107
+
108
+ export default new StepDetectorMinMaxPeaks();
@@ -0,0 +1,108 @@
1
+ import { Constants as GeoConstants } from '@wemap/geo';
2
+ import { Quaternion } from '@wemap/maths';
3
+
4
+ import EventType from '../../events/EventType.js';
5
+ import RelativeAttitudeFromInertial from '../attitude/relative/RelativeAttitudeFromInertial.js';
6
+ import Accelerometer from '../imu/Accelerometer.js';
7
+ import Gyroscope from '../imu/Gyroscope.js';
8
+ import Provider from '../Provider.js';
9
+ import StepDetectionMinMaxPeaks2 from './StepDetectionMinMaxPeaks2.js';
10
+
11
+
12
+ class StepDetectorMinMaxPeaks2 extends Provider {
13
+
14
+ constructor() {
15
+ super();
16
+ this.stepDetector = new StepDetectionMinMaxPeaks2();
17
+ }
18
+
19
+ /**
20
+ * @override
21
+ */
22
+ static get pname() {
23
+ return 'StepDetectorMinMaxPeaks2';
24
+ }
25
+
26
+ /**
27
+ * @override
28
+ */
29
+ get _availability() {
30
+ return Promise.all([
31
+ Accelerometer.availability,
32
+ Gyroscope.availability,
33
+ RelativeAttitudeFromInertial.availability
34
+ ]);
35
+ }
36
+
37
+ /**
38
+ * @override
39
+ */
40
+ start() {
41
+
42
+ this.numOfSteps = 0;
43
+
44
+ this.accelerometerProviderId = Accelerometer.addEventListener(
45
+ events => this.onAccelerometerEvent(events[0]),
46
+ error => this.notifyError(error)
47
+ );
48
+
49
+ this.gyroscopeProviderId = Gyroscope.addEventListener(
50
+ events => (this.angularRateEvent = events[0]),
51
+ error => this.notifyError(error)
52
+ );
53
+
54
+ this.attitudeProviderId = RelativeAttitudeFromInertial.addEventListener(
55
+ events => (this.attitudeEvent = events[0]),
56
+ error => this.notifyError(error)
57
+ );
58
+ }
59
+
60
+ /**
61
+ * @override
62
+ */
63
+ stop() {
64
+ Accelerometer.removeEventListener(this.accelerometerProviderId);
65
+ Gyroscope.removeEventListener(this.gyroscopeProviderId);
66
+ RelativeAttitudeFromInertial.removeEventListener(this.attitudeProviderId);
67
+ }
68
+
69
+ onAccelerometerEvent(accelerationEvent) {
70
+
71
+ if (!this.attitudeEvent || !this.angularRateEvent) {
72
+ return;
73
+ }
74
+
75
+ const {
76
+ values: acceleration, timestamp
77
+ } = accelerationEvent.data;
78
+
79
+ /**
80
+ * Step Detection and Step Size Detection
81
+ */
82
+ const linearAcc = this.constructor.computeLinearAcceleration(
83
+ this.attitudeEvent.data.quaternion, acceleration);
84
+ const stepDetected = this.stepDetector.compute(timestamp, linearAcc, this.angularRateEvent.data.values);
85
+
86
+ if (stepDetected) {
87
+ const size = this.stepDetector.lastStepSize;
88
+ this.numOfSteps++;
89
+ this.notify(this.createEvent(
90
+ EventType.Step, {
91
+ size,
92
+ number: this.numOfSteps
93
+ },
94
+ [accelerationEvent, this.angularRateEvent, this.attitudeEvent]
95
+ ));
96
+ }
97
+ }
98
+
99
+ // Linear acceleration in ENU
100
+ static computeLinearAcceleration(quaternion, acc) {
101
+ const linearAcc = Quaternion.rotateMatlab(Quaternion.inverse(quaternion), acc);
102
+ linearAcc[2] -= GeoConstants.EARTH_GRAVITY;
103
+ return linearAcc;
104
+ }
105
+
106
+ }
107
+
108
+ export default new StepDetectorMinMaxPeaks2();