thank you for responding. However unfortunately the magnetometer won’t work for me. Since I believe it gives compass readings. (I tried it and it indeed only gives compass readings - though they seem a bit weird as well)
I actually need to know the (pitch,yaw,roll) of the device - hence the gyro.
I did realize a couple of things - since the subscription is in radians per sec - I have to divide the result by my subscription frequency - i.e. if my frequency is 20 millisecs - then the returned angular velocity should be divided by 50 (1000/20 = 50).
Doing this indeed gives me almost accurate results (I do have to clean up the data a bit - since there seems to be jitter in the result). As such I do a (unscientific) abs(x,…) < some threshold I throw away data - else I add it to my initial angle.
… here is the (modified) code from expo - again this almost works - but in the end - I think this is a dead end - since the data is too dirty to use - I guess i’m going to have to detach from expo to use native modules directly…that sucks…
import React from ‘react’;
import {
Gyroscope,
} from ‘expo’;
import {
StyleSheet,
Text,
TouchableOpacity,
View,
FlatList
} from ‘react-native’;
export default class GyroscopeSensor extends React.Component {
state = {
radData: {x:0,y:0,z:0},
}
componentDidMount() {
this._toggle();
}
componentWillUnmount() {
this._unsubscribe();
}
_toggle = () => {
if (this._subscription) {
this._unsubscribe();
} else {
this._subscribe();
}
}
_toDegress = (radData) => {
let { x, y, z } = radData;
x = radiansToDegrees(x);
y = radiansToDegrees(y);
z = radiansToDegrees(z);
return {x:round(x), y:round(y), z:round(z)};
}
_slow = () => {
Gyroscope.setUpdateInterval(1000);
}
_fast = () => {
Gyroscope.setUpdateInterval(20);
}
_cleanData = (result) => {
let x = result.x / 50;
let y = result.y / 50;
let z = result.z / 50;
if (Math.abs(x) < 0.0005)
x = 0;
if (Math.abs(y) < 0.0005)
y = 0;
if (Math.abs(z) < 0.0005)
z = 0;
return {x: x, y:y, z:z};
}
_subscribe = () => {
this._subscription = Gyroscope.addListener((result) => {
let cleanData = this._cleanData(result);
let radData = this.state.radData;
radData.x += cleanData.x;
radData.y += cleanData.y;
radData.z += cleanData.z;
this.setState({radData: radData});
});
this._fast();
}
_unsubscribe = () => {
this._subscription && this._subscription.remove();
this._subscription = null;
this.setState({radData: {x:0,y:0,z:0}});
}
render() {
let rad = this.state.radData;
let deg = this._toDegress(rad);
return (
<View style={styles.sensor}>
<Text>Gyroscope:</Text>
<Text>rad.x: {rad.x} rad.y: {rad.y} rad.z: {rad.z}</Text>
<Text>deg.x: {deg.x} deg.y: {deg.y} deg.z: {deg.z}</Text>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={this._toDegress} style={styles.button}>
<Text>To Degrees</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._toggle} style={styles.button}>
<Text>Toggle</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._slow} style={[styles.button, styles.middleButton]}>
<Text>Slow</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._fast} style={styles.button}>
<Text>Fast</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
function radiansToDegrees(radians) {
return radians * 180 / Math.PI;
};
function round(n) {
if (!n) {
return 0;
}
return Math.floor(n * 100) / 100;
}
const styles = StyleSheet.create({
container: {
flex: 1
},
buttonContainer: {
flexDirection: ‘row’,
alignItems: ‘stretch’,
marginTop: 15,
},
button: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘center’,
backgroundColor: ‘#eee’,
padding: 10,
},
middleButton: {
borderLeftWidth: 1,
borderRightWidth: 1,
borderColor: ‘#ccc’,
},
sensor: {
marginTop: 15,
paddingHorizontal: 10,
},
});