Reputation: 5739
This few lines of C# code calculate the phone's rotation around the y axis using the accelerometer:
private float GetRoll() {
/*
* Sum up the accelerometer events
*/
Vector3 accelerationVector = Vector3.zero;
for (int i=0; i < Input.accelerationEventCount; i++) {
AccelerationEvent accEvent = Input.GetAccelerationEvent(i);
accelerationVector += accEvent.acceleration * accEvent.deltaTime;
}
accelerationVector.Normalize();
int inclination = (int) Mathf.Round(Mathf.Rad2Deg * Mathf.Acos(accelerationVector.z));
float roll = 0;
if (inclination < 25 || inclination > 155) {
/*
* How to calculate the rotation here?
*/
} else {
roll = Mathf.Round(Mathf.Rad2Deg * Mathf.Atan2(accelerationVector.x, accelerationVector.y));
}
return roll;
}
Do you know the math to make it work if the phone is laying flat on the table? I.e. if inclination
is less than 25 or more than 155 degree?
The code originates from this SO post which mentions that the compass can be used. Unfortunately I don't know how, so your advise is very appreciated. Also, if possible, I'd like to avoid using the gyroscope and rather stick with the accelerometer.
Any advise is welcome. Thank you.
Upvotes: 9
Views: 1522
Reputation: 405
You're request is practically impossible
It boils down to gyroscopes measure absolute orientation in space while accelerometers measure change of velocity (acceleration). When you use calculus to go from acceleration (m/s^2) to location (m), you get distance displaced - this makes sense intuitively, too. Because accelerometers are triggered on change of velocity, it won't even trigger 400mph constant velocity while on an airplane.
Not only would you need entire accelerometer history, you would also need original location and orientation Not to mention all the error extrapolated over such an error, a 1% sensor error becomes much greater in this calculation.
To get some type of sensor data about orientation, gyroscope (or maybe compass) must be used. In fact, to directly answer your question, no accelerometer is needed, since it is a question of finding position. However, your actual needs may benefit from accelerometer, if you want to react to user gestures, or something.
Input.gyro.attitude should give you your absolute orientation values. Get these values for when it's laying flat with no roll, then get these values again with some amount of roll. After this, you should have some data on what range of values meet your criteria and some error margin on that condition.
https://docs.unity3d.com/ScriptReference/Gyroscope.html
Upvotes: 1
Reputation: 1486
You can use
onSensorChanged(SensorEvent event)
In this event you can detect the type of sensor and calculate Roll, Azimut and Pitch as in given example
float azimuthVal = event.values[0];
float pitchVal = event.values[1];
float rollVal = event.values[2];
Which Sensor values you have to read you can get from
event.sensor.getType()
And the orientation in order to find the tilt you can get from method
SensorManager.getOrientation
and can get angles as
azimutOrt = orientation[0];
pitchOrt = orientation[1];
rollOrt = orientation[2];
For Unity the below three can be used
Input.acceleration: Accelerometer
Input.gyro.rotationRate:
Input.gyro.attitude
Input.gyro.gravity:
Upvotes: 0
Reputation: 319
Why don't you use the gyroscope?
If you think it over it seems physically impossible to get any kind of rotation info from acceleration vectors if the axis of the rotation is completely parallel with the sum of accelerations.
(Maybe you can get it's speed from the centripetal force but nothing else.)
Upvotes: 4