Optional filter (Gyro + accel) with Android

I recently did some research to use as an accelerometer + gyroscope to use these sensors to track a smartphone without GPS (see this post) Internal positioning system based on a gyroscope and accelerometer

To do this, I need my orientation (angle (step, roll, etc.)), so here is what I have done so far:

public void onSensorChanged(SensorEvent arg0) { if (arg0.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { accel[0] = arg0.values[0]; accel[1] = arg0.values[1]; accel[2] = arg0.values[2]; pitch = Math.toDegrees(Math.atan2(accel[1], Math.sqrt(Math.pow(accel[2], 2) + Math.pow(accel[0], 2)))); tv2.setText("Pitch: " + pitch + "\n" + "Roll: " + roll); } else if (arg0.sensor.getType() == Sensor.TYPE_GYROSCOPE ) { if (timestamp != 0) { final float dT = (arg0.timestamp - timestamp) * NS2S; angle[0] += arg0.values[0] * dT; filtered_angle[0] = (0.98f) * (filtered_angle[0] + arg0.values[0] * dT) + (0.02f)* (pitch); } timestamp = arg0.timestamp; } } 

Here I try to correct (for testing only) from my accelerometer (step), from integrating gyroscope_X over time, filtering it with an additional filter

filter_angle [0] = (0.98f) * (filter_angle [0] + gyro_x * dT) + (0.02f) * (step)

with dT start more or less 0.009 seconds

But I don’t know why, but my angle is not very accurate ... when the device is positioned on the table (screen up)

 Pitch (angle fromm accel) = 1.5 (average) Integrate gyro = 0 to growing (normal it drifting) filtered gyro angle = 1.2 

and when I raise the phone 90 ° (see screen facing the wall in front of me)

 Pitch (angle fromm accel) = 86 (MAXIMUM) Integrate gyro = he is out ok its normal filtered gyro angle = 83 (MAXIMUM) 

So, the angles never reach 90? Even if I try to raise the phone a little more ... Why doesn’t this happen up to 90 °? Am I mistaken? or is it the quality of sensory crap?

Another thing that I'm interested in is that: with Android, I do not “read” the sensor value, but they notify me when they change. The problem is that, as you see in the code, Accel and Gyro use the same method ... so when I calculate the filtered angle, I will take the acceleration step 0.009 seconds before, no? Perhaps this is the source of my problem?

Thanks!

+6
source share
4 answers

I can only repeat it myself.

You gain a position by integrating linear acceleration twice, but the error is terrible. In practice, this is useless. In other words, you are trying to solve the impossible.

In fact, you can only track orientation.

Roll, serve and yaw are evil, do not use them. Check out the video I already recommended at 38:25.

Here's a great tutorial on how to track orientation with gyroscopes and accelerometers.

Related questions you might find helpful:

track small iphone movements without GPS
What is the real accuracy of telephone accelerometers when used for positioning?
How to calculate the movement of the phone in the vertical direction from rest?
iOS: accuracy of movement in 3D space
How to use an accelerometer to measure distance to develop Android applications
Accelerometer distance
How to find the distance traveled by the gyroscope and accelerometer?

+5
source

I wrote a tutorial on using an additional filter to track ori -ntation with a gyroscope and accelerometer: http://www.pieter-jan.com/node/11 , maybe this can help you.

+3
source

I am testing your code and found that the scaling factor is probably not compatible. Converting the pitch to 0-pi gives the best result. In my test, the filtering result is ~ 90 degrees.

 pitch = (float) Math.toDegrees(Math.atan2(accel[1], Math.sqrt(Math.pow(accel[2], 2) + Math.pow(accel[0], 2)))); pitch = pitch*PI/180.f; filtered_angle = weight * (filtered_angle + event.values[0] * dT) + (1.0f-weight)* (pitch); 
0
source

I tried and it will give you an angle of 90 ...

 filtered_angle = (filtered_angle / 83) * 90; 
-1
source

Source: https://habr.com/ru/post/898052/


All Articles