@wemap/positioning 1.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/.eslintrc.json +479 -0
- package/.nvmrc +1 -0
- package/babel.config.js +11 -0
- package/config.json +7 -0
- package/debug/index.html +15 -0
- package/debug/index.old.html +37 -0
- package/package.json +82 -0
- package/scripts/release-github.js +216 -0
- package/src/Constants.js +11 -0
- package/src/NavigationHandler.js +244 -0
- package/src/Pose.js +8 -0
- package/src/attitude/Attitude.js +65 -0
- package/src/attitude/AttitudeHandler.js +343 -0
- package/src/attitude/EkfAttitude.js +238 -0
- package/src/attitude/EkfAttitude.spec.js +116 -0
- package/src/components/AbsoluteAttitude.jsx +136 -0
- package/src/components/Imu.jsx +89 -0
- package/src/components/LocationSource.jsx +434 -0
- package/src/components/Logger.jsx +113 -0
- package/src/components/NavigationDebugApp.jsx +106 -0
- package/src/components/Others.jsx +121 -0
- package/src/components/RelativeAttitude.jsx +104 -0
- package/src/components/Utils.js +35 -0
- package/src/components/index.js +13 -0
- package/src/index.js +9 -0
- package/src/providers/FixedLocationImuLocationSource.js +66 -0
- package/src/providers/GnssLocationSource.js +118 -0
- package/src/providers/GnssPdrLocationSource.js +182 -0
- package/src/providers/IPLocationSource.js +96 -0
- package/src/providers/LocationSource.js +290 -0
- package/src/providers/PdrLocationSource.js +312 -0
- package/src/providers/ProvidersLogger.js +77 -0
- package/src/providers/pdr/HeadingUnlocker.js +41 -0
- package/src/providers/pdr/HeadingUnlocker.spec.js +26 -0
- package/src/providers/pdr/Smoother.js +90 -0
- package/src/providers/pdr/Smoother.spec.js +424 -0
- package/src/providers/pdr/ThugDetector.js +37 -0
- package/src/providers/steps/StepDetection.js +7 -0
- package/src/providers/steps/StepDetectionLadetto.js +67 -0
- package/src/providers/steps/StepDetectionMinMaxPeaks.js +80 -0
- package/src/providers/steps/StepDetectionMinMaxPeaks2.js +108 -0
- package/src/sensors/SensorsCompatibility.js +484 -0
- package/src/sensors/SensorsCompatibility.spec.js +270 -0
- package/src/sensors/SensorsLogger.js +94 -0
- package/src/sensors/SensorsLoggerUtils.js +35 -0
- package/src.new/NavigationHandler.js +62 -0
- package/src.new/index.js +3 -0
- package/src.new/providers/FakeLocationSource.js +39 -0
- package/webpack/webpack.common.js +20 -0
- package/webpack/webpack.dev.js +24 -0
- package/webpack/webpack.prod.js +15 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import NavigationHandler from '../NavigationHandler';
|
|
4
|
+
import SensorsLogger from '../sensors/SensorsLogger';
|
|
5
|
+
import SensorsLoggerUtils from '../sensors/SensorsLoggerUtils';
|
|
6
|
+
|
|
7
|
+
// import ArCamera from 'ar/DebugArCamera';
|
|
8
|
+
|
|
9
|
+
class Logger extends React.Component {
|
|
10
|
+
|
|
11
|
+
constructor(props, context) {
|
|
12
|
+
super(props, context);
|
|
13
|
+
|
|
14
|
+
this.navigationHandler = new NavigationHandler();
|
|
15
|
+
|
|
16
|
+
// Create a SensorsLogger instance
|
|
17
|
+
this.sensorsLogger = new SensorsLogger();
|
|
18
|
+
|
|
19
|
+
this.state = {
|
|
20
|
+
logsNumber: 0,
|
|
21
|
+
videoSize: 0,
|
|
22
|
+
isStarted: false
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
start() {
|
|
27
|
+
|
|
28
|
+
this.setState({ isStarted: true });
|
|
29
|
+
this.navigationHandler.startAbsolute([]).then(() => {
|
|
30
|
+
this.messagesInterval = setInterval(() => {
|
|
31
|
+
this.setState({
|
|
32
|
+
logsNumber: this.sensorsLogger.dataset.length,
|
|
33
|
+
videoSize: this.sensorsLogger.getVideoSize()
|
|
34
|
+
});
|
|
35
|
+
}, 1000);
|
|
36
|
+
}).catch(() => console.log('Nothing to log'));
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Send the SensorsLogger to NavigationHandler and Camera View
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
this.navigationHandler.startLogger(this.sensorsLogger);
|
|
43
|
+
|
|
44
|
+
// ArCamera is a custom Camera view which can handle the SensorsLogger
|
|
45
|
+
// this.arCamera.startLogger(this.sensorsLogger);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
stop() {
|
|
49
|
+
this.setState({ isStarted: false });
|
|
50
|
+
|
|
51
|
+
if (this.messagesInterval) {
|
|
52
|
+
clearInterval(this.messagesInterval);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.navigationHandler.stop();
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Stop SensorsLogger
|
|
59
|
+
*/
|
|
60
|
+
this.navigationHandler.stopLogger();
|
|
61
|
+
// this.arCamera.stopLogger();
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
download() {
|
|
66
|
+
SensorsLoggerUtils.download(this.sensorsLogger);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
render() {
|
|
70
|
+
const logsNumber = this.state.logsNumber;
|
|
71
|
+
const videoSize = this.state.videoSize;
|
|
72
|
+
|
|
73
|
+
let startStopButton;
|
|
74
|
+
if (this.state.isStarted) {
|
|
75
|
+
startStopButton = <button onClick={() => this.stop()}>Stop</button>;
|
|
76
|
+
} else {
|
|
77
|
+
startStopButton = <button onClick={() => this.start()}>Start</button>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let downloadButton;
|
|
81
|
+
if (!this.state.isStarted && this.state.logsNumber > 0) {
|
|
82
|
+
downloadButton = <button onClick={() => this.download()}>Download</button>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div>
|
|
87
|
+
<p>{startStopButton} {downloadButton ? downloadButton : ''}</p>
|
|
88
|
+
<p>Logs: {logsNumber}</p>
|
|
89
|
+
<p>Video size: {videoSize}</p>
|
|
90
|
+
|
|
91
|
+
<div style={{
|
|
92
|
+
position: 'absolute',
|
|
93
|
+
width: '200px',
|
|
94
|
+
height: '100px',
|
|
95
|
+
left: 0,
|
|
96
|
+
right: 0,
|
|
97
|
+
margin: 'auto'
|
|
98
|
+
}}>
|
|
99
|
+
{
|
|
100
|
+
|
|
101
|
+
/* <ArCamera ref={(arCamera) => {
|
|
102
|
+
this.arCamera = arCamera;
|
|
103
|
+
}} /> */
|
|
104
|
+
}
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default Logger;
|
|
113
|
+
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import parse from 'url-parse';
|
|
3
|
+
import {
|
|
4
|
+
AppBar, Tabs, Tab
|
|
5
|
+
} from '@material-ui/core';
|
|
6
|
+
import {
|
|
7
|
+
Link, Route, HashRouter, Switch
|
|
8
|
+
} from 'react-router-dom';
|
|
9
|
+
|
|
10
|
+
import Imu from './Imu';
|
|
11
|
+
import Others from './Others';
|
|
12
|
+
import RelativeAttitude from './RelativeAttitude';
|
|
13
|
+
import AbsoluteAttitude from './AbsoluteAttitude';
|
|
14
|
+
import LocationSource from './LocationSource';
|
|
15
|
+
import Logger from './Logger';
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NavigationDebugApp extends React.Component {
|
|
19
|
+
|
|
20
|
+
state = { value: 0 };
|
|
21
|
+
|
|
22
|
+
handleChange = (event, value) => {
|
|
23
|
+
this.setState({ value });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
componentDidMount() {
|
|
27
|
+
let hash = parse(window.location.href).hash;
|
|
28
|
+
if (hash) {
|
|
29
|
+
hash = hash.substring(1);
|
|
30
|
+
switch (hash) {
|
|
31
|
+
case 'imu':
|
|
32
|
+
this.setState({ value: 0 });
|
|
33
|
+
break;
|
|
34
|
+
case 'relative-attitude':
|
|
35
|
+
this.setState({ value: 1 });
|
|
36
|
+
break;
|
|
37
|
+
case 'absolute-attitude':
|
|
38
|
+
this.setState({ value: 2 });
|
|
39
|
+
break;
|
|
40
|
+
case 'location-source':
|
|
41
|
+
this.setState({ value: 3 });
|
|
42
|
+
break;
|
|
43
|
+
case 'others':
|
|
44
|
+
this.setState({ value: 4 });
|
|
45
|
+
break;
|
|
46
|
+
case 'logger':
|
|
47
|
+
this.setState({ value: 5 });
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render() {
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<HashRouter hashType='noslash'>
|
|
57
|
+
<div>
|
|
58
|
+
<AppBar position="static">
|
|
59
|
+
<Tabs value={this.state.value}
|
|
60
|
+
variant="scrollable"
|
|
61
|
+
scrollButtons="auto"
|
|
62
|
+
onChange={this.handleChange}>
|
|
63
|
+
<Tab label="IMU"
|
|
64
|
+
to="/imu"
|
|
65
|
+
component={Link} />
|
|
66
|
+
<Tab label="Relative Attitude"
|
|
67
|
+
to="/relative-attitude"
|
|
68
|
+
component={Link} />
|
|
69
|
+
<Tab label="Absolute Attitude"
|
|
70
|
+
to="/absolute-attitude"
|
|
71
|
+
component={Link} />
|
|
72
|
+
<Tab label="Location Source"
|
|
73
|
+
to="/location-source"
|
|
74
|
+
component={Link} />
|
|
75
|
+
<Tab label="Others"
|
|
76
|
+
to="/others"
|
|
77
|
+
component={Link} />
|
|
78
|
+
<Tab label="Logger"
|
|
79
|
+
to="/logger"
|
|
80
|
+
component={Link} />
|
|
81
|
+
</Tabs>
|
|
82
|
+
</AppBar>
|
|
83
|
+
|
|
84
|
+
<Switch>
|
|
85
|
+
<Route path="/imu"
|
|
86
|
+
component={Imu} />
|
|
87
|
+
<Route path="/relative-attitude"
|
|
88
|
+
component={RelativeAttitude} />
|
|
89
|
+
<Route path="/absolute-attitude"
|
|
90
|
+
component={AbsoluteAttitude} />
|
|
91
|
+
<Route path="/location-source"
|
|
92
|
+
component={LocationSource} />
|
|
93
|
+
<Route path="/others"
|
|
94
|
+
component={Others} />
|
|
95
|
+
<Route path="/logger"
|
|
96
|
+
component={Logger} />
|
|
97
|
+
<Route path="/"
|
|
98
|
+
component={Imu} />
|
|
99
|
+
</Switch>
|
|
100
|
+
</div>
|
|
101
|
+
</HashRouter>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default NavigationDebugApp;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Constants as GeoConstants } from '@wemap/geo';
|
|
4
|
+
import {
|
|
5
|
+
Quaternion, Vector3, Utils as MathUtils
|
|
6
|
+
} from '@wemap/maths';
|
|
7
|
+
|
|
8
|
+
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
9
|
+
import SensorsCompatibility from '../sensors/SensorsCompatibility';
|
|
10
|
+
import StepDetectionLadetto from '../providers/steps/StepDetectionLadetto';
|
|
11
|
+
import StepDetectionMinMaxPeaks from '../providers/steps/StepDetectionMinMaxPeaks';
|
|
12
|
+
import StepDetectionMinMaxPeaks2 from '../providers/steps/StepDetectionMinMaxPeaks2';
|
|
13
|
+
|
|
14
|
+
class Others extends React.Component {
|
|
15
|
+
|
|
16
|
+
constructor(props, context) {
|
|
17
|
+
super(props, context);
|
|
18
|
+
|
|
19
|
+
this.attitudeHandlerInclination = new AttitudeHandler();
|
|
20
|
+
this.brAccGyr = new SensorsCompatibility();
|
|
21
|
+
this.attitudeHandler = new AttitudeHandler();
|
|
22
|
+
this.ladettoStepDetector = new StepDetectionLadetto();
|
|
23
|
+
this.minMaxStepDetector = new StepDetectionMinMaxPeaks();
|
|
24
|
+
this.minMaxStepDetector2 = new StepDetectionMinMaxPeaks2();
|
|
25
|
+
|
|
26
|
+
this.AccRef = [0, 0, GeoConstants.EARTH_GRAVITY];
|
|
27
|
+
|
|
28
|
+
this.state = {
|
|
29
|
+
inclination: null,
|
|
30
|
+
stepCounterLadetto: 0,
|
|
31
|
+
stepCounterMinMax: 0,
|
|
32
|
+
stepCounterMinMax2: 0,
|
|
33
|
+
displayMode: null,
|
|
34
|
+
mag: null
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
componentDidMount() {
|
|
39
|
+
this.attitudeHandlerInclination.startMonitoringInclination(inclination => {
|
|
40
|
+
this.setState({ inclination: inclination });
|
|
41
|
+
}).catch(() => this.setState({ inclination: -1 }));
|
|
42
|
+
|
|
43
|
+
Promise.all([
|
|
44
|
+
this.attitudeHandler.startRelative(
|
|
45
|
+
attitude => {
|
|
46
|
+
this.attitude = attitude;
|
|
47
|
+
},
|
|
48
|
+
AttitudeHandler.RelativeMethod.INTERNAL_EKF),
|
|
49
|
+
this.attitudeHandler.setRelativeHeading(0),
|
|
50
|
+
this.brAccGyr.startImu(imu => {
|
|
51
|
+
|
|
52
|
+
if (!this.attitude) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let linearAcc = Quaternion.rotate(Quaternion.inverse(this.attitude.quaternion), imu.acc);
|
|
57
|
+
linearAcc = Vector3.subtract(linearAcc, this.AccRef);
|
|
58
|
+
|
|
59
|
+
const stepDetectedLadetto = this.ladettoStepDetector.compute(imu.timestamp, linearAcc);
|
|
60
|
+
if (stepDetectedLadetto) {
|
|
61
|
+
this.setState(({ stepCounterLadetto }) => ({ stepCounterLadetto: stepCounterLadetto + 1 }));
|
|
62
|
+
}
|
|
63
|
+
const stepDetectedMinMax = this.minMaxStepDetector.compute(imu.timestamp, linearAcc);
|
|
64
|
+
if (stepDetectedMinMax) {
|
|
65
|
+
this.setState(({ stepCounterMinMax }) => ({ stepCounterMinMax: stepCounterMinMax + 1 }));
|
|
66
|
+
}
|
|
67
|
+
const stepDetectedMinMax2 = this.minMaxStepDetector2.compute(imu.timestamp, linearAcc, imu.gyr);
|
|
68
|
+
if (stepDetectedMinMax2) {
|
|
69
|
+
this.setState(({ stepCounterMinMax2 }) => ({ stepCounterMinMax2: stepCounterMinMax2 + 1 }));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}, {
|
|
73
|
+
accelerometer: true,
|
|
74
|
+
gyroscope: true
|
|
75
|
+
}, 60)
|
|
76
|
+
]).catch(() => this.setState({ stepCounter: -1 }));
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
componentWillUnmount() {
|
|
81
|
+
this.attitudeHandlerInclination.stopMonitoringInclination();
|
|
82
|
+
|
|
83
|
+
this.attitudeHandler.stopRelative();
|
|
84
|
+
this.brAccGyr.stopImu();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
render() {
|
|
88
|
+
|
|
89
|
+
let inclinationString = 'Inclination: ';
|
|
90
|
+
const inclination = this.state.inclination;
|
|
91
|
+
if (!inclination) {
|
|
92
|
+
inclinationString += 'Waiting';
|
|
93
|
+
} else if (inclination === -1) {
|
|
94
|
+
inclinationString += 'Not available';
|
|
95
|
+
} else {
|
|
96
|
+
inclinationString += MathUtils.rad2deg(inclination).toFixed(2);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let stepCounterLadetto = 'StepCounter Ladetto: ';
|
|
100
|
+
stepCounterLadetto += this.state.stepCounterLadetto;
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
let stepCounterMinMax = 'StepCounter MinMax: ';
|
|
104
|
+
stepCounterMinMax += this.state.stepCounterMinMax;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
let stepCounterMinMax2 = 'StepCounter MinMax2: ';
|
|
108
|
+
stepCounterMinMax2 += this.state.stepCounterMinMax2;
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
return (<p>
|
|
112
|
+
{inclinationString}<br />
|
|
113
|
+
{stepCounterLadetto}<br />
|
|
114
|
+
{stepCounterMinMax}<br />
|
|
115
|
+
{stepCounterMinMax2}
|
|
116
|
+
</p>);
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default Others;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
4
|
+
import Utils from './Utils';
|
|
5
|
+
|
|
6
|
+
class RelativeAttitude extends React.Component {
|
|
7
|
+
|
|
8
|
+
constructor(props, context) {
|
|
9
|
+
super(props, context);
|
|
10
|
+
|
|
11
|
+
this.attitudeHandlerBrowser = new AttitudeHandler();
|
|
12
|
+
this.attitudeHandlerEkf = new AttitudeHandler();
|
|
13
|
+
// this.attitudeHandlerAutomatic = new AttitudeHandler();
|
|
14
|
+
|
|
15
|
+
this.state = {
|
|
16
|
+
attitudeBrowser: null,
|
|
17
|
+
attitudeEkf: null,
|
|
18
|
+
// attitudeAuto: null,
|
|
19
|
+
deviceorientation: null
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
componentDidMount() {
|
|
25
|
+
const browserPromise = Promise.all([
|
|
26
|
+
this.attitudeHandlerBrowser.startRelative(
|
|
27
|
+
attitude => this.setState({ attitudeBrowser: attitude }),
|
|
28
|
+
AttitudeHandler.RelativeMethod.BROWSER),
|
|
29
|
+
this.attitudeHandlerBrowser.setRelativeHeading(0)]);
|
|
30
|
+
browserPromise.catch(() =>
|
|
31
|
+
this.setState({ attitudeBrowser: -1 })
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const ekfPromise = Promise.all([
|
|
35
|
+
this.attitudeHandlerEkf.startRelative(
|
|
36
|
+
attitude => this.setState({ attitudeEkf: attitude }),
|
|
37
|
+
AttitudeHandler.RelativeMethod.INTERNAL_EKF),
|
|
38
|
+
this.attitudeHandlerEkf.setRelativeHeading(0)]);
|
|
39
|
+
ekfPromise.catch(() =>
|
|
40
|
+
this.setState({ attitudeEkf: -1 })
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// const autoPromise = Promise.all([
|
|
44
|
+
// this.attitudeHandlerAutomatic.startRelative(
|
|
45
|
+
// attitude => this.setState({ attitudeAuto: attitude }),
|
|
46
|
+
// AttitudeHandler.RelativeMethod.AUTOMATIC),
|
|
47
|
+
// this.attitudeHandlerAutomatic.setRelativeHeading(0)]);
|
|
48
|
+
// autoPromise.catch(() =>
|
|
49
|
+
// this.setState({ attitudeAuto: -1 })
|
|
50
|
+
// );
|
|
51
|
+
|
|
52
|
+
this.onDeviceOrientationEventListener = (e) => this.setState({ deviceorientation: e });
|
|
53
|
+
window.addEventListener('deviceorientation', this.onDeviceOrientationEventListener, true);
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
componentWillUnmount() {
|
|
58
|
+
this.attitudeHandlerBrowser.stopRelative();
|
|
59
|
+
this.attitudeHandlerEkf.stopRelative();
|
|
60
|
+
// this.attitudeHandlerAutomatic.stopRelative();
|
|
61
|
+
window.removeEventListener('deviceorientation', this.onDeviceOrientationEventListener, true);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
render() {
|
|
65
|
+
|
|
66
|
+
let rawRender = <p>Waiting</p>;
|
|
67
|
+
|
|
68
|
+
if (this.state.deviceorientation) {
|
|
69
|
+
const alpha = this.state.deviceorientation.alpha;
|
|
70
|
+
const beta = this.state.deviceorientation.beta;
|
|
71
|
+
const gamma = this.state.deviceorientation.gamma;
|
|
72
|
+
|
|
73
|
+
if (alpha && beta && gamma) {
|
|
74
|
+
rawRender = <p>alpha: {alpha.toFixed(2)}, <br />
|
|
75
|
+
beta: {beta.toFixed(2)}, <br />
|
|
76
|
+
gamma: {gamma.toFixed(2)}</p>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const browserRender = Utils.renderAttitude(this.state.attitudeBrowser);
|
|
82
|
+
const ekfRender = Utils.renderAttitude(this.state.attitudeEkf);
|
|
83
|
+
// const autoRender = Utils.renderAttitude(this.state.attitudeAuto);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div>
|
|
87
|
+
<h3>Raw:</h3>
|
|
88
|
+
{rawRender}
|
|
89
|
+
<h3>From browser:</h3>
|
|
90
|
+
{browserRender}
|
|
91
|
+
<h3>From Ekf:</h3>
|
|
92
|
+
{ekfRender}
|
|
93
|
+
{
|
|
94
|
+
|
|
95
|
+
/* <h3>From Automatic:</h3>
|
|
96
|
+
{autoRender} */
|
|
97
|
+
}
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default RelativeAttitude;
|
|
104
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
|
2
|
+
|
|
3
|
+
class Utils {
|
|
4
|
+
|
|
5
|
+
static renderAttitude(attitude) {
|
|
6
|
+
|
|
7
|
+
if (!attitude) {
|
|
8
|
+
return <p>Waiting</p>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (attitude === -1) {
|
|
12
|
+
return <p>Not available</p>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const quaternion = attitude.quaternion;
|
|
16
|
+
|
|
17
|
+
const w = quaternion[0].toFixed(3);
|
|
18
|
+
const x = quaternion[1].toFixed(3);
|
|
19
|
+
const y = quaternion[2].toFixed(3);
|
|
20
|
+
const z = quaternion[3].toFixed(3);
|
|
21
|
+
|
|
22
|
+
const euler = attitude.eulerAnglesDegrees;
|
|
23
|
+
const yaw = euler[0].toFixed(2);
|
|
24
|
+
const pitch = euler[1].toFixed(2);
|
|
25
|
+
const roll = euler[2].toFixed(2);
|
|
26
|
+
const heading = attitude.headingDegrees.toFixed(2);
|
|
27
|
+
|
|
28
|
+
return <p>Quaternion: [{w}, {x}, {y}, {z}]<br />
|
|
29
|
+
Eulers: [{yaw}, {pitch}, {roll}]<br />
|
|
30
|
+
Heading: {heading}</p>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default Utils;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import NavigationDebugApp from './NavigationDebugApp';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom';
|
|
4
|
+
|
|
5
|
+
const createReactElement = (component, container) => ReactDOM.render(
|
|
6
|
+
React.createElement(component, {}, null),
|
|
7
|
+
container
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
NavigationDebugApp,
|
|
12
|
+
createReactElement
|
|
13
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import LocationSource from './LocationSource';
|
|
2
|
+
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
3
|
+
import Constants from '../Constants';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FixedLocationImuLocationSource extends LocationSource {
|
|
7
|
+
|
|
8
|
+
constructor(callback) {
|
|
9
|
+
super(callback);
|
|
10
|
+
this.attitudeHandler = new AttitudeHandler();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Start the location source algorithm
|
|
15
|
+
* @override
|
|
16
|
+
*/
|
|
17
|
+
start(fixedLocation) {
|
|
18
|
+
super.start();
|
|
19
|
+
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
this.pose.location = fixedLocation;
|
|
22
|
+
if (fixedLocation && this.attitudeHandler) {
|
|
23
|
+
this.attitudeHandler.setUserLocationForAbsolute(fixedLocation);
|
|
24
|
+
this.attitudeHandler.startAbsolute(
|
|
25
|
+
attitude => {
|
|
26
|
+
this.pose.attitude = attitude;
|
|
27
|
+
this.notify();
|
|
28
|
+
})
|
|
29
|
+
.catch(reject);
|
|
30
|
+
}
|
|
31
|
+
resolve();
|
|
32
|
+
this.notify();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Stop the location source algorithm
|
|
38
|
+
* @override
|
|
39
|
+
*/
|
|
40
|
+
stop() {
|
|
41
|
+
super.stop();
|
|
42
|
+
|
|
43
|
+
if (this.attitudeHandler) {
|
|
44
|
+
this.attitudeHandler.stopAbsolute();
|
|
45
|
+
this.attitudeHandler = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setLocation(location) {
|
|
50
|
+
this.pose.location = location;
|
|
51
|
+
if (this.attitudeHandler) {
|
|
52
|
+
this.attitudeHandler.setUserLocationForAbsolute(location);
|
|
53
|
+
}
|
|
54
|
+
this.notify();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get provider name
|
|
59
|
+
* @override
|
|
60
|
+
*/
|
|
61
|
+
static get providerName() {
|
|
62
|
+
return Constants.LOCATION_SOURCE_PROVIDERS.FIXED_LOCATION;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default FixedLocationImuLocationSource;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { WGS84UserPosition } from '@wemap/geo';
|
|
2
|
+
import { Utils as MathUtils } from '@wemap/maths';
|
|
3
|
+
|
|
4
|
+
import LocationSource from './LocationSource';
|
|
5
|
+
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
6
|
+
import Constants from '../Constants';
|
|
7
|
+
import SensorsLogger from '../sensors/SensorsLogger';
|
|
8
|
+
import SensorsLoggerUtils from '../sensors/SensorsLoggerUtils';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const GNSS_OPTIONS = {
|
|
12
|
+
enableHighAccuracy: false,
|
|
13
|
+
timeout: Infinity,
|
|
14
|
+
maximumAge: 0
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
class GnssLocationSource extends LocationSource {
|
|
18
|
+
|
|
19
|
+
geoLocationId = -1;
|
|
20
|
+
|
|
21
|
+
constructor(callback, imuEnabled = true) {
|
|
22
|
+
super(callback);
|
|
23
|
+
this.initialized = false;
|
|
24
|
+
if (imuEnabled) {
|
|
25
|
+
this.attitudeHandler = new AttitudeHandler();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Start the location source algorithm
|
|
31
|
+
* @override
|
|
32
|
+
*/
|
|
33
|
+
start() {
|
|
34
|
+
super.start();
|
|
35
|
+
|
|
36
|
+
if (!navigator || !navigator.geolocation) {
|
|
37
|
+
return Promise.reject();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this.attitudeHandler) {
|
|
41
|
+
this.attitudeHandler.startAbsolute(
|
|
42
|
+
attitude => {
|
|
43
|
+
this.pose.attitude = attitude;
|
|
44
|
+
this.notify();
|
|
45
|
+
})
|
|
46
|
+
// Attitude is optionnal here, do not throw an error if it not works.
|
|
47
|
+
.catch(() => { });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
this.geoLocationId = navigator.geolocation.watchPosition(
|
|
52
|
+
position => {
|
|
53
|
+
|
|
54
|
+
const coords = position.coords;
|
|
55
|
+
if (!coords) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let bearing;
|
|
60
|
+
if (coords.heading) {
|
|
61
|
+
bearing = MathUtils.deg2rad(coords.heading);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const timestamp = SensorsLoggerUtils.unixTimestampToPerformanceNow(position.timestamp) / 1e3;
|
|
65
|
+
|
|
66
|
+
this.pose.location = new WGS84UserPosition(
|
|
67
|
+
coords.latitude,
|
|
68
|
+
coords.longitude,
|
|
69
|
+
coords.altitude,
|
|
70
|
+
timestamp,
|
|
71
|
+
coords.accuracy,
|
|
72
|
+
bearing,
|
|
73
|
+
this.providerName);
|
|
74
|
+
|
|
75
|
+
if (!this.initialized) {
|
|
76
|
+
if (this.attitudeHandler) {
|
|
77
|
+
this.attitudeHandler.setUserLocationForAbsolute(this.pose.location);
|
|
78
|
+
}
|
|
79
|
+
resolve();
|
|
80
|
+
this.initialized = true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.notify();
|
|
84
|
+
|
|
85
|
+
if (this.logger) {
|
|
86
|
+
const data = [coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading];
|
|
87
|
+
this.logger.feed(SensorsLogger.DataType.WATCH_POSITION, timestamp, data);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
reject,
|
|
91
|
+
GNSS_OPTIONS);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Stop the location source algorithm
|
|
97
|
+
* @override
|
|
98
|
+
*/
|
|
99
|
+
stop() {
|
|
100
|
+
super.stop();
|
|
101
|
+
|
|
102
|
+
navigator.geolocation.clearWatch(this.geoLocationId);
|
|
103
|
+
if (this.attitudeHandler) {
|
|
104
|
+
this.attitudeHandler.stopAbsolute();
|
|
105
|
+
this.attitudeHandler = null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get provider name
|
|
111
|
+
* @override
|
|
112
|
+
*/
|
|
113
|
+
static get providerName() {
|
|
114
|
+
return Constants.LOCATION_SOURCE_PROVIDERS.GNSS;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export default GnssLocationSource;
|