2012-11-07 75 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