如何在android中使用加速度计跟踪路径?

Utk*_*tav 3 c++ java android accelerometer

我想创建一个跟踪 android 中路径的应用程序。我使用以下代码来计算不同方向的加速度。

package com.example.usrivast.accelerometer;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;


public class MainActivity extends Activity implements SensorEventListener{

Sensor accelerometer = null;
SensorManager sm = null;
TextView acceleration = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    sm = (SensorManager)getSystemService(SENSOR_SERVICE);
    accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    acceleration = (TextView)findViewById(R.id.acceleration);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onSensorChanged(SensorEvent event) {

    acceleration.setText("x: " + event.values[0] + "\ny: " + event.values[1] + "\nz: " + event.values[2]);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
   }
}
Run Code Online (Sandbox Code Playgroud)

但我无法理解这些值的输出。它们变化得非常快。此外,如果我的手机处于静止状态,这些值也会发生变化。当我的手机放在桌子上时,这些值的一个示例是 x: -0.1278 y: 0.2968 z: 9.6323 它们变化非常快。我正在使用 Nexus 5。

Mik*_*son 5

智能手机中的加速计极其便宜且体积很小。这意味着他们的产出质量非常差。

您会注意到的第一件事是您已经注意到的,即这些值将非常嘈杂。这意味着这些值将始终随机且非常快速地上下波动。这只是典型的信号噪声或白噪声,廉价的传感器有很多这样的噪声,特别是当它们装在一个有大量数字电子设备和天线(wifi、手机频率等)的小封装内时。找出消除噪音的方法本身就是一个完整的科学领域(称为信号处理),而且它比您想象的要复杂得多。一个基本想法是使用某种低通滤波器

第二件事你现在不会注意到,但如果你尝试对信号做更多的事情(特别是集成它),你就会注意到。这个问题与传感器的偏差有关。基本上,这个问题是关于零加速度在传感器上未记录为零。使问题变得复杂的是,这种“偏差”通常会随着时间的推移而浮动和变化(也会随着温度而变化,例如当电池变热或手机放在手掌上时)。同样,正确消除这种偏差并不容易(可能就像应用高通滤波器一样简单,但首选方法是使用增强卡尔曼滤波器)。

第三个问题是非线性。大多数廉价的加速度计在加速度和测量值之间远没有线性关系。它们通常被设计为在 0 附近相对线性,并且在它们可以测量的加速度范围的上限和下限附近变得更差。所以,如果你动作不太剧烈的话,这不会有问题。

所有这些问题加在一起的结果是,智能手机内部的加速计根本不足以产生任何精确的东西,比如手机运动路径的痕迹。要实际产生这条路径,您需要对信号进行两次数值积分(一次获得速度,再次获得位置)。数值积分通常会使上述每个问题变得更糟,并且进行两次将是灾难性的。大多数可用于消除噪声和/或偏差的滤波器在集成信号时都会增加其他问题。不管怎样,你正在与一些牢不可破的自然力量作斗争,信号处理是一个非常无情的领域,最重要的是,如果你希望最终得到除了垃圾之外的任何东西,你需要更好的信号,或者正如我们所说,垃圾进,垃圾出。

这就是为什么智能手机中的加速计除了检测手机握持方向(这是基于一段时间内平均加速计值的简单计算)和检测相当暴力的手势(检测手机上的大/长尖峰)之外很少用于其他用途的原因。值)。即使像 Wii-mote 这样具有更好传感器的东西也无法用于重新创建路径,信号仍然太嘈杂且有偏差。