我试图TYPE_LINEAR_ACCELEROMETER
在 Android 中计算运行速度传感器,但我得到的结果非常不准确。计算出的平均加速度总是正值,所以它不断增加。这是我的程序和代码,请建议我从 3 轴加速度计数据计算的正确方法是什么以及我的代码出错的地方。
我所做的是:
我在x
, y
,z
方向上得到加速度值
产生的加速度a1 = sqrt(x*x + y*y + z*z)
平均5
加速度读数:
Avg(4) = `(a0 + a1 + a2 + a3 + a4) / 5`
时间增量:
Tdelta = (time of Avg(4)) - (time of Avg(0))
最初V(0)
是0
,之后V(0)
是先前计算的速度,因此:
V(1) = V(0) + at = 0 + Avg(1)
V(2) = V(1) + at = V(1) + Avg(2)
V(n) = V(n-1) + at = V(n-1) + Avg(n)
这就是我获得速度值的方式,但这不是正确的速度。请指导我。
这是代码:
public class TestCalculateVelocityActivity extends Activity implements OnClickListener, SensorEventListener {
final String TAG = getClass().getName().toString();
SensorManager mSensorManager;
Sensor mAccelerometer;
TableLayout accTable;
TextView accl, spd, spd_kmph;
Button btnStart, btnStop, btnClear;
Timer updateTimer;
float []linearAcceleration = new float[3];
Velocity velocity;
Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initSensor();
accTable =(TableLayout)findViewById(R.id.country_table);
//accl = (TextView)findViewById(R.id.accl);
spd = (TextView)findViewById(R.id.spd);
spd_kmph = (TextView)findViewById(R.id.spd_kmph);
btnStart = (Button)findViewById(R.id.buttonStart);
btnStart.setOnClickListener(this);
btnStop = (Button)findViewById(R.id.buttonStop);
btnStop.setOnClickListener(this);
btnClear= (Button)findViewById(R.id.buttonClear);
btnClear.setOnClickListener(this);
}
private void initSensor() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
if(mAccelerometer == null) {
Toast.makeText(this, "Accelerometer sensor not available", Toast.LENGTH_SHORT).show();
finish();
}
}
void fillTable(float values[]) {
float[] val = values;
TableRow row;
TextView t1, t2, t3;
//Converting to dip unit
int dip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
(float) 1, getResources().getDisplayMetrics());
//for (int current = 0; current < CountriesList.abbreviations.length; current++) {
row = new TableRow(this);
t1 = new TextView(this);
t1.setTextColor(Color.WHITE);
t1.setBackgroundColor(Color.GRAY);
t2 = new TextView(this);
t2.setTextColor(Color.WHITE);
t2.setBackgroundColor(Color.LTGRAY);
t3 = new TextView(this);
t3.setTextColor(Color.WHITE);
t3.setBackgroundColor(Color.GRAY);
t1.setText(""+val[0]);
t2.setText(""+val[1]);
t3.setText(""+val[2]);
t1.setTypeface(null, 1);
t2.setTypeface(null, 1);
t3.setTypeface(null, 1);
t1.setTextSize(15);
t2.setTextSize(15);
t3.setTextSize(15);
t1.setWidth(150 * dip);
t2.setWidth(150 * dip);
t3.setWidth(150 * dip);
t1.setPadding(20*dip, 0, 0, 0);
row.addView(t1);
row.addView(t2);
row.addView(t3);
accTable.addView(row, new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
public void onClick(View v) {
if(v == btnStart) {
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
velocity = new Velocity();
updateTimer = new Timer("velocityUpdate");
handler = new Handler();
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
calculateAndUpdate();
}
}, 0, 1200);
}else if(v == btnStop) {
mSensorManager.unregisterListener(this);
displayVelocityValues();
displayVelocityTable();
velocity = null;
handler = null;
updateTimer.cancel();
} else if(v == btnClear) {
accTable.removeAllViews();
}
}
private void displayVelocityTable() {
try {
accTable.removeAllViews();
double[] vl = velocity.getVlArray();
for(int i = 0; i<vl.length; i++) {
/*Log.d(TAG, "v = " + vl[i] + "mps, "+(vl[i] * 3.6)+ " kmph");*/
//float[] val = values;
TableRow row;
TextView t1, t2;
//Converting to dip unit
int dip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
(float) 1, getResources().getDisplayMetrics());
//for (int current = 0; current < CountriesList.abbreviations.length; current++) {
row = new TableRow(this);
t1 = new TextView(this);
t1.setTextColor(Color.WHITE);
t1.setBackgroundColor(Color.GRAY);
t2 = new TextView(this);
t2.setTextColor(Color.WHITE);
t2.setBackgroundColor(Color.LTGRAY);
t1.setText(""+vl[i]);
t2.setText(""+(vl[i] * 3.6));
t1.setTypeface(null, 1);
t2.setTypeface(null, 1);
t1.setTextSize(15);
t2.setTextSize(15);
t1.setWidth(200 * dip);
t2.setWidth(200 * dip);
t1.setPadding(20*dip, 0, 0, 0);
row.addView(t1);
row.addView(t2);
accTable.addView(row, new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
} catch(NullPointerException e) {
e.printStackTrace();
}
}
public void displayVelocityValues() {
try {
double[] vl = velocity.getVlArray();
for(int i = 0; i<vl.length; i++) {
Log.d(TAG, "v = " + vl[i] + "mps, "+(vl[i] * 3.6)+ " kmph");
}
} catch(NullPointerException e) {
e.printStackTrace();
}
}
private void calculateAndUpdate() {
final double vel = velocity.getVelocity(linearAcceleration, System.currentTimeMillis());
final double velKmph = vel * 3.6;
//spd.setText("v = "+ velKmph + " kmph");
handler.post(new Runnable() {
public void run() {
//Log.d(getClass().getName().toString(), "Setting velocity = " + velKmph+ " kmph");
spd.setText("v = "+ vel + " mps");
spd_kmph.setText("v = "+ velKmph + " kmph");
}
});
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
linearAcceleration[0] = event.values[0];
linearAcceleration[1] = event.values[1];
linearAcceleration[2] = event.values[2];
fillTable(linearAcceleration);
}
}
public class Velocity {
private final String TAG = getClass().getName().toString();
int sampleCounter = 0;
final int totalSamples = 5;
long time0, nAccel;
static int i=0;
double aDelT0 = 0, v0 = 0, v = 0;
final int totalVelocityValues = 1000;
double []velocityValues = new double[totalVelocityValues];
//float []linearAcceleration = new float[3];
//final int totalAccl = 5;
double []accel = new double[totalSamples];
private double getAvg(double[] a) {
double total = 0;
for(int i = 0; i<a.length; i++)
total = total + a[i];
return (total / a.length);
}
private double getAcceleration(float[] linearAcceleration) {
return Math.sqrt(Math.pow(linearAcceleration[0], 2) + Math.pow(linearAcceleration[0], 2) + Math.pow(linearAcceleration[0], 2));
}
public double getVelocity(float[] linearAcceleration, long time1) {
//this.linearAcceleration = linearAcceleration;
try {
if(sampleCounter < (totalSamples-1)) {
if(sampleCounter == 0)
time0 = time1;
accel[sampleCounter] = getAcceleration(linearAcceleration);
sampleCounter++;
} else if(sampleCounter == (totalSamples-1)) {
accel[sampleCounter] = getAcceleration(linearAcceleration);
double avgAccel = getAvg(accel);
long timeDelta = ((time1 - time0) / 1000);
double aDelT1 = (avgAccel * timeDelta);
Log.d(TAG, "aDelT1 = "+avgAccel +" * "+timeDelta + " = "+aDelT1 );
v = calculateVelovity(aDelT1);
if(i !=totalVelocityValues) {
velocityValues[i]=v;
i++;
} else {
for(int j=0;j<(totalVelocityValues-1);j++)
velocityValues[j]=velocityValues[j+1];
velocityValues[totalVelocityValues -1]=v;
}
sampleCounter = 0;
}
} catch (Exception e) {
e.printStackTrace();
}
return v;
}
private double calculateVelovity(double aDelT1) {
double v = v0 + (aDelT1 - aDelT0);
Log.d(TAG, "v = "+v0+ "+ ("+aDelT1+" - "+aDelT0+") = "+v);
v0 = v;
aDelT0 = aDelT1;
return v;
}
public double[] getVlArray() {
return velocityValues;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/spd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_weight="1"
android:background="@android:color/darker_gray"
android:gravity="center_vertical|center_horizontal"
android:text="speed (kmph)"
android:textColor="@android:color/white"
android:textSize="20dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="@+id/spd_kmph"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_weight="1"
android:background="@android:color/darker_gray"
android:gravity="center_vertical|center_horizontal"
android:text="ooooo"
android:textColor="@android:color/white"
android:textSize="20dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:text="Acceleration Data"
android:textColor="@android:color/white"
android:gravity="center_vertical|center_horizontal"
android:textSize="20dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginBottom="5dip"
android:typeface="sans"
android:layout_weight="1"
android:background="@android:color/darker_gray"/>
</LinearLayout>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:text="Start" />
<Button android:id="@+id/buttonClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:text="Clear" />
<Button android:id="@+id/buttonStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:text="Stop" />
</LinearLayout>
<RelativeLayout android:id="@+id/rl_country_heading"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/darker_gray">
<TextView android:id="@+id/tv_11"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:gravity="center"
android:text="X"
android:textStyle="normal|bold"
android:textColor="@android:color/white"
android:textSize="18dip">
</TextView>
<TextView android:id="@+id/tv_12"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Y"
android:textStyle="normal|bold"
android:textColor="@android:color/white"
android:textSize="18dip"
android:layout_toRightOf="@+id/tv_11">
</TextView>
<TextView android:id="@+id/tv_13"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Z"
android:textStyle="normal|bold"
android:textColor="@android:color/white"
android:textSize="18dip"
android:layout_toRightOf="@+id/tv_12">
</TextView>
</RelativeLayout>
<LinearLayout android:id="@+id/ll_country"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<ScrollView android:id="@+id/ScrollView11"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip">
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="0,1"
android:id="@+id/country_table"
android:background="@android:color/black">
</TableLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>