2012-11-07 43 views
5

Tôi đã cố gắng tính toán cảm biến tốc độ chạy TYPE_LINEAR_ACCELEROMETER trong Android, nhưng kết quả tôi nhận được là rất không chính xác. Tăng tốc trung bình được tính luôn luôn là giá trị dương, do đó nó tiếp tục tăng lên. Đây là thủ tục và mã của tôi, xin vui lòng cho tôi biết cách chính xác để tính toán từ dữ liệu gia tốc 3 trục và nơi mã của tôi đi sai.Cách tính tốc độ chạy bằng cảm biến gia tốc trong android

Những gì tôi đã làm là:

Tôi nhận được giá trị tăng tốc trong x, y, z hướng

Kết quả tăng tốc a1 = sqrt(x*x + y*y + z*z)

trung bình của 5 đọc tăng tốc:

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

Time delta:

Tdelta = (time of Avg(4)) - (time of Avg(0)) 

Ban đầu V(0)0 và sau đó V(0) là vận tốc tính toán trước đây, do đó:

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) 

Đây là cách tôi nhận được giá trị vận tốc, nhưng nó không phải là vận tốc chính xác. Xin vui lòng hướng dẫn cho tôi.

Đây là mã:

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 bạn đã tìm ra cách để có được tốc độ sử dụng gia tốc thay vì sử dụng gps. Nếu bạn có một số mã hoặc mẫu chỉ cho tôi tôi đang phải đối mặt với cùng một vấn đề ở một số nơi tôi không thể có được tốc độ khi gps không có sẵn – prasanthMurugan

Trả lời

1

của bạn làm việc ra tổng độ lớn của gia tốc với getAcceleration và mất tất cả thông tin hướng vì vậy nó sẽ luôn là số dương .

Bạn cần phải đi vào hướng acount và thay đổi khi điện thoại xoắn và biến vì vậy bạn phải sử dụng con quay hồi chuyển.

Ngay cả khi bạn nhận được mã ngay mặc dù độ chính xác của cảm biến trên điện thoại thông thường có nghĩa là bạn sẽ mất bất kỳ độ chính xác nào một cách nhanh chóng.

Nếu bạn muốn chạy tốc độ xem gps ...

Chỉnh sửa.

Quên để nói rằng trọng tâm của bạn không được tính đến. Bạn phải loại bỏ hiệu ứng của lực hấp dẫn.

+0

tôi đã thành công có tốc độ sử dụng GPS. nhưng tôi muốn tính toán sử dụng gia tốc kế để tính toán các điều kiện không có dữ liệu GPS. Bộ cảm biến.TYPE_LINEAR_ACCELERATION cho giá trị gia tốc không bao gồm lực hấp dẫn. khi chạy bằng điện thoại di động, cảm biến sẽ cảm nhận quá nhiều cú sốc và giật. kế toán các điều kiện này ... là có thể tính toán tốc độ chạy thực tế. Bộ cảm biến.TYPE_GYROSCOPE cho tốc độ quay. Tôi có thể lấy mã ví dụ để lấy hướng gia tốc (dương hoặc âm) bằng GYROSCOPE hoặc ACCELEROMETER. – Gaurav

Các vấn đề liên quan