我想创建一个跟踪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) {
}
}
但我无法理解值的输出。他们变化非常迅速。此外,如果我的手机处于静止状态,那么这些值也会改变。 当我的手机在我的桌面上休息时,这些值的一个例子是 x:-0.1278 y:0.2968 z:9.6323 他们变化非常迅速。我正在使用Nexus 5.
答案 0 :(得分:3)
智能手机中的加速度计非常便宜且非常小巧。这意味着它们的输出质量很差。
你会注意到的第一件事是你已经注意到的,那就是值非常嘈杂。这意味着值将随机且非常快速地上下反弹。这只是典型的信号噪声或白噪声,廉价的传感器有很多,特别是当它们被包装在一个包含大量数字电子设备和天线的小型封装中时(wifi,cell freq。,等等..)。找出消除噪音的方法是它自己的整个科学领域(称为信号处理),它比你想象的要复杂得多。一个基本想法是使用某种low-pass filter。
你现在不会注意到的第二件事,但如果你试图对信号做更多的事情(特别是如果整合它),你将会这样做。这个问题与传感器中的偏差有关。基本上,这个问题是关于零加速度而不是在传感器上记录为零。为了使问题复杂化,这种“偏差”通常会随着时间的推移而浮动和变化(并且随着温度的变化也会发生变化,就像电池变热或电话在手掌中一样)。再一次,正确摆脱这种偏见并不容易(可能就像应用high-pass filter一样简单,但首选的方法是使用增强的Kalman filter)。
第三个问题是非线性。大多数便宜的加速度计远不是加速度和测量值之间的线性关系。它们通常被设计成在0附近相对线性,并且朝向它们可以测量的加速度范围的上限和下限变得更差。所以,如果你不太猛烈地移动,这不会是一个问题。
所有这些问题的结果在于,智能手机内部的加速度计根本不足以产生任何精确的东西,就像电话的运动路径一样。要实际生成此路径,您需要对信号进行两次数字积分(一次获得速度,再一次获得位置)。数值积分通常会使上述每个问题都变得更糟,而两次这样做将会是灾难性的。大多数可用于消除噪声和/或偏置的滤波器在集成信号时会增加其他问题。无论如何,你正在与一些不可破坏的自然力量作斗争,信号处理是一个非常无情的领域,最重要的是你需要更好的信号开始,如果你希望最后得到除垃圾之外的任何东西,或者正如我们所说,垃圾进去,垃圾出来。
这就是为什么智能手机中的加速度计很少用于检测手机的方向(这是基于一段时间内平均加速度计值的简单计算)以及检测相当猛烈的手势(检测大/长)的原因飙升的价值观)。甚至像具有更好传感器的Wii-mote之类的东西甚至无法用于重建路径,信号仍然太嘈杂而且偏向于此。