2012-11-07 3 views
5

J'ai essayé de calculer le capteur de vitesse de course TYPE_LINEAR_ACCELEROMETER dans Android, mais les résultats que je reçois est très inexact. L'accélération moyenne calculée est toujours une valeur positive, donc elle continue à augmenter. Voici ma procédure et le code, s'il vous plaît me suggérer quelle est la bonne façon de calculer à partir des données de l'accéléromètre 3 axes et où mon code va mal.Comment calculer la vitesse de course en utilisant le capteur accéléromètre dans Android

Ce que je fait est:

Je reçois des valeurs d'accélération dans x, y, z directions

résultant accélération a1 = sqrt(x*x + y*y + z*z)

moyenne de 5 lectures d'accélération:

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

Temps delta:

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

Dans un premier temps V(0) est 0 et après que V(0) est la vitesse calculée précédemment, donc:

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) 

Voilà comment je reçois la valeur de la vitesse, mais ce n'est pas la vitesse correcte. Guidez-moi s'il-vous-plaît.

Voici le code:

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

salut @Gaurav avez-vous trouvé comment obtenir la vitesse en utilisant l'accéléromètre plutôt que d'utiliser le GPS. Si vous avez un code ou un échantillon juste moi je suis confronté au même problème dans certains endroits que je ne peux pas obtenir la vitesse lorsque le GPS ne sont pas disponibles – prasanthMurugan

Répondre

1

Votre travail sur l'ampleur totale de l'accélération avec getAcceleration et perdre toutes les informations de direction de sorte qu'il sera toujours positif .

Vous devez prendre en compte la direction et cela change au fur et à mesure que le téléphone tourne et que vous devez utiliser le gyro.

Même si vous obtenez le code correct, bien que la précision des capteurs sur un téléphone typique signifie que vous perdrez toute précision très rapidement.

Si vous voulez courir look vitesse au GPS ....

Modifier.

Oublié de dire que vous ne tenez pas compte de la gravité. Vous devez supprimer l'effet de la gravité.

+0

j'ai réussi à la vitesse en utilisant le GPS. mais je veux calculer en utilisant l'accéléromètre également pour comptabiliser les conditions où les données GPS sont indisponibles. Le capteur.TYPE_LINEAR_ACCELERATION donne des valeurs d'accélération excluant la gravité. lors de l'exécution avec un téléphone mobile, le capteur détecte trop de chocs et secousses. Compte tenu de ces conditions ... est-il possible de calculer la vitesse de fonctionnement réelle. capteur.TYPE_GYROSCOPE donne le taux de rotation. Puis-je obtenir un exemple de code pour obtenir la direction de l'accélération (positive ou négative) en utilisant GYROSCOPE ou ACCELEROMETER. – Gaurav

Questions connexes