[英]Complementary filter (Gyro + accel) with Android
最近我做了一些研究,使用加速度計+陀螺儀來使用那些傳感器在沒有GPS幫助的情況下跟蹤智能手機(參見這篇文章) 基於陀螺儀和加速度計的室內定位系統
為此我需要我的方向(角度(俯仰,滾動等))所以這里到目前為止我所做的:
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;
}
}
在這里,我試圖從我的加速度計(音高)角度(僅用於測試),從陀螺儀_X的集成通過時間過濾它與互補濾波器
filtered_angle [0] =(0.98f)*(filtered_angle [0] + gyro_x * dT)+(0.02f)*(音高)
與dT開始或多或少0.009 secondes
但我不知道為什么,但我的角度不是很准確......當設備平放在桌子上時(屏幕朝上)
Pitch (angle fromm accel) = 1.5 (average)
Integrate gyro = 0 to growing (normal it's drifting)
filtered gyro angle = 1.2
當我拿起90°的手機時(看到屏幕朝向我面前的牆壁)
Pitch (angle fromm accel) = 86 (MAXIMUM)
Integrate gyro = he is out ok its normal
filtered gyro angle = 83 (MAXIMUM)
所以角度永遠不會達到90 ??? 即使我嘗試將手機抬得多一點......為什么直到90°才行? 我的計算錯了嗎? 或傳感器垃圾的質量?
我想知道的另一件事是:使用Android我不會“讀出”傳感器的值,但是當它們發生變化時我會收到通知。 問題在於,正如您在代碼中看到的那樣,Accel和Gyro共享相同的方法....因此,當我計算濾波后的角度時,我會在之前的幾秒鍾內采取加速度測量的間距,不是嗎? 這可能是我問題的根源嗎?
謝謝 !
我只能重復自己。
通過將線性加速度積分兩次得到位置,但誤差很大。 它在實踐中毫無用處。 換句話說,你正試圖解決不可能的問題。
你實際上可以做的是跟蹤方向。
滾動,俯仰和偏航是邪惡的,不要使用它們。 請查看我已經推薦的視頻 ,時間是38:25。
這是一個關於如何使用陀螺儀和加速度計跟蹤方向的優秀教程 。
您可能會發現有用的類似問題:
跟蹤沒有GPS的iPhone的小動作
用於定位的手機加速度計的真實世界准確度是多少?
如何計算手機在休息時垂直方向的運動?
iOS:3D空間中的移動精度
如何使用Accelerometer測量Android應用程序開發的距離
加速度計移動的距離
如何找到陀螺儀和加速度計的距離?
我寫了一個關於使用互補濾波器進行軌道跟蹤的陀螺儀和加速度計的教程: http ://www.pieter-jan.com/node/11也許它可以幫到你。
我測試你的代碼,發現可能比例因子不一致。 將音高轉換為0-pi可獲得更好的效果。 在我的測試中,過濾結果是~90度。
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);
我試過,這會給你角度90 ...
filtered_angle = (filtered_angle / 83) * 90;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.