1.4 加速度传感器
加速度传感器是为了检测物体的加速度的传感器。物体运动加速度也跟着变化,如果能取到加速度,物体受到什么样的作用力或则物体进行什么样的运动,我们就可以知道。使用加速度,我们就能做模拟计步器、物体运动的应用程序。
1.4.1 通过加速度传感器能取到的值
我们可以通过Android的加速度传感器可以取得x,y,z三个轴的加速度(如图1-4)。
加速度值受地球重力的影响值也不一样。这就涉及到物理知识了,我就不细阐述了。也不是一句两句能说清楚的。在SensorManager类中定义了很多星体的重力加速度值。如表1-7
表1-7 SensorManager 类被定义的各新星体的重力加速度值
常量名
|
说明
|
实际的值
|
GRAVITY_DEATH_STAR_1 |
死亡星
|
3.5303614E-7 |
GRAVITY_EARTH
|
地球
|
9.80665 |
GRAVITY_JUPITER
| 木星 |
23.12 |
GRAVITY_MARS
| 火星 |
3.71 |
GRAVITY_MERCURY
| 水星 |
3.7 |
GRAVITY_MOON
| 月亮 |
1.6 |
GRAVITY_NEPTUNE
| 海王星 |
11.0 |
GRAVITY_PLUTO
| 冥王星 |
0.6 |
GRAVITY_SATURN
| 土星 |
8.96 |
GRAVITY_SUN
| 太阳 |
275.0 |
GRAVITY_THE_ISLAND
| 岛屿星 |
4.815162 |
GRAVITY_URANUS
| 天王星 |
8.69 |
GRAVITY_VENUS
| 金星 |
8.87 |
1.4.2 只想保留重力的影响的时候
通常,从加速度传感器取得的值,拿手机手机设备的人的手震动或则放在摇晃的场所的时候,受震动影响设备的值增幅变化是存在的。手的摇动、轻微震动的影响是属于长波形式,去掉这种长波干扰的影响,可以取得高精度的值。去掉这种长波这种过滤机能叫 Low-Pass Filter。
Low-Pass Filter的封装方法如下面所述。
・从抽样数据中取得中间的值的方法
・ 最近取得的加速度的值每个很少变化的方法
●从抽样数据中取得中间的值的方法
从抽样数据取得中间值的抽样代码如下 列表1-3所示。并且,抽样数为30来做的,根据封装的程序的用途和传感器的感度进行调整。
列表1-3 从抽样数据中取得中间值
package androidegg.stu.sensor;
import java.util.Arrays;
import java.util.List;
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.widget.TextView;
public class AndroidEggSensorGetValueActivity extends Activity implements SensorEventListener{
/** Called when the activity is first created. */
private SensorManager sensorManager;
private static final int ELEMENT_COUNT = 30;
//Data
private float[] samplingX = new float[ELEMENT_COUNT]; //..................①
private float[] samplingY = new float[ELEMENT_COUNT];
private float[] samplingZ = new float[ELEMENT_COUNT];
private int position;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//SensorManagerのインスタンスを取得
sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main);
}
@Override
protected void onResume(){
super.onResume();
List sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
//sensor1
for (Sensor s : sensors){
sensorManager.registerListener(this,s,SensorManager.SENSOR_DELAY_NORMAL);
}
}
//
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent e) {
if (position == ELEMENT_COUNT - 1){ //..................②
position =0;
}else{
position++;
}
float x = e.values[sensorManager.DATA_X];
float y = e.values[sensorManager.DATA_Y];
float z = e.values[sensorManager.DATA_Z];
samplingX[position] = x;
samplingY[position] = y;
samplingZ[position] = z;
TextView textX = (TextView)findViewById(R.id.x);
textX.setText("x:" + String.valueOf(getMedian(samplingX)));
TextView textY = (TextView)findViewById(R.id.y);
textY.setText("y:" + String.valueOf(getMedian(samplingY)));
TextView textZ = (TextView)findViewById(R.id.z);
textZ.setText("Z:" + String.valueOf(getMedian(samplingZ)));
}
private float getMedian(float[] values) { //..................③
// TODO Auto-generated method stub
float[] tmp = values.clone();
Arrays.sort(tmp);
int len = tmp.length;
int first = 0;
for (int i =0;i
first =i;
}
return tmp[(len - first)/2 + first];
}
//
@Override
protected void onStop(){
super.onStop();
sensorManager.unregisterListener(this);
}
}
运行结果如图1-5
重要注意点如下所示
①x,y,z 轴的各个保存用的数组定义
②抽样用的数据从数组的0开始的顺序保存,到第29个的时候再从0开始保存
③数组保存的值的中间值取得
1.4.3 瞬间加速度值的取得
例如类似计步器、作用力测定的应用开发的时候,很想检测出加速度急剧的变化。这个时候,和Low-Pass Filter处理相反,去掉短周波的影响,这样可以取得数据。像这种去掉短周波的影响的过滤器叫做High-pass filter。
High-pass filter的处理方法,如下面的例程列表1-5 代码所示:
列表1-5 瞬间加速度值的取得
package androidegg.stu.sensor;
import java.util.Arrays;
import java.util.List;
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.widget.TextView;
public class AndroidEggSensorGetValueActivity extends Activity implements SensorEventListener{
/** Called when the activity is first created. */
private SensorManager sensorManager;
//
private final float FILTERING_VALAUE = 0.1f;
private float lowX,lowY,lowZ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//SensorManager
sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main);
}
@Override
protected void onResume(){
super.onResume();
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
//sensor1
for (Sensor s : sensors){
sensorManager.registerListener(this,s,SensorManager.SENSOR_DELAY_NORMAL);
}
}
//
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent e) {
float x = e.values[sensorManager.DATA_X];
float y = e.values[sensorManager.DATA_Y];
float z = e.values[sensorManager.DATA_Z];
//Low-Pass Filter
lowX = x * FILTERING_VALAUE + lowX * (1.0f - FILTERING_VALAUE);
lowY = y * FILTERING_VALAUE + lowY * (1.0f - FILTERING_VALAUE);
lowZ = z * FILTERING_VALAUE + lowZ * (1.0f - FILTERING_VALAUE);
//High-pass filter
float highX = x - lowX;
float highY = y - lowY;
float highZ = z - lowZ;
//output
TextView textX = (TextView)findViewById(R.id.x);
textX.setText("x:" + String.valueOf(highX));
TextView textY = (TextView)findViewById(R.id.y);
textY.setText("y:" + String.valueOf(highY));
TextView textZ = (TextView)findViewById(R.id.z);
textZ.setText("Z:" + String.valueOf(highZ));
}
//
@Override
protected void onStop(){
super.onStop();
sensorManager.unregisterListener(this);
}
}
运行结果如图1-5-2