7

最近我做了一些研究,使用加速度计和陀螺仪来使用这些传感器在没有 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;
 }
}

在这里,我试图从我的加速度计(俯仰)角度(仅用于测试),从集成 gyroscope_X 通过时间用互补滤波器过滤它

filters_angle[0] = (0.98f) * (filtered_angle[0] + gyro_x * dT) + (0.02f)* (pitch)

dT 开始或多或少 0.009 秒

但我不知道为什么,但我的角度不是很准确......当设备平放在桌子上时(屏幕朝上)

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 共享相同的方法....所以当我计算过滤角度时,我将在 0.009 秒前采用加速度测量的俯仰,不是吗?这可能是我问题的根源吗?

谢谢 !

4

4 回答 4

5

我只能重复我自己。

您可以通过两次积分线性加速度来获得位置,但误差很可怕。在实践中是没有用的。换句话说,您正在尝试解决不可能的问题。

您实际上可以做的是仅跟踪方向。

滚动、俯仰和偏航是邪恶的,不要使用它们。在 38:25查看我已经推荐的视频。

这是一个关于如何使用陀螺仪和加速度计跟踪方向的优秀教程。

您可能会发现有帮助的类似问题:

在没有 GPS 的情况下跟踪 iphone
的小动作 当用于定位时,手机加速度计的真实世界精度是多少?
如何计算手机从静止垂直方向的运动?
iOS:3D 空间中的运动精度
如何使用加速度计测量 Android 应用程序开发
的距离 加速度计移动的距离
如何找到陀螺仪和加速度计移动的距离?

于 2011-09-26T10:53:29.033 回答
3

我写了一篇关于使用互补滤波器使用陀螺仪和加速度计进行方向跟踪的教程: http ://www.pieter-jan.com/node/11也许它可以帮助你。

于 2013-05-15T10:59:41.140 回答
0

我测试了您的代码,发现比例因子可能不一致。将音高转换为 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);
于 2013-09-05T01:00:17.133 回答
-1

我试过了,这会给你90的角度......

filtered_angle = (filtered_angle / 83) * 90;
于 2014-08-09T10:19:22.400 回答