2012-11-07 136 views
5

我試圖在Android中計算運行速度傳感器TYPE_LINEAR_ACCELEROMETER,但是我得到的結果非常不準確。計算的平均加速度總是正值,所以它不斷增加。這裏是我的程序和代碼,請向我建議從3軸加速度計數據計算出哪些方法是正確的,以及我的代碼出錯的地方。如何在android中使用加速計傳感器計算運行速度

我所做的是:

我在x獲得加速度值,yz方向

產生的加速度a1 = sqrt(x*x + y*y + z*z)平均的5

加速讀數:

Avg(4) = `(a0 + a1 + a2 + a3 + a4)/5` 

時間delta:

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> 

+0

hi @Gaurav你有沒有想過如何使用加速度計而不是使用gps來獲得速度。如果你有一些代碼或樣品只是我我在一些地方面臨同樣的問題當GPS無法使用時,我無法獲得速度 – prasanthMurugan

回答

1

你正與getAcceleration加速度的總大小和失去了所有方向的信息,所以它永遠是積極的。

您需要考慮方向,並且隨着手機的曲折變化,您必須使用陀螺儀。

即使您獲得的代碼正確,但傳統手機上的傳感器的準確性意味着您將很快失去任何準確性。

如果你想運行速度看看GPS ....

編輯。

忘了說你不重視考慮。你必須消除重力的影響。

+0

我已成功使用GPS獲得速度。但我想使用加速度計也計算GPS數據不可用的情況。 Sensor.TYPE_LINEAR_ACCELERATION給出不包括重力的加速度值。 當用手機運行時,傳感器會感覺到太多的衝擊和混亂。考慮到這些條件......是否可以計算實際運行速度。 傳感器。TYPE_GYROSCOPE給出了旋轉的速率。 我可以通過使用GYROSCOPE或ACCELEROMETER獲取任何示例代碼來獲取加速度的方向(正值或負值)。 – Gaurav