简体   繁体   English

如何使用android中的加速计传感器计算运行速度

[英]How to calculate running speed using accelerometer sensor in android

I tried to calculate running speed sensor TYPE_LINEAR_ACCELEROMETER in Android, but the results I am getting is highly inaccurate. 我尝试在Android中计算运行速度传感器TYPE_LINEAR_ACCELEROMETER ,但我得到的结果非常不准确。 Calculated average acceleration is always positive value, so it keeps on increasing. 计算的平均加速度总是正值,因此它继续增加。 Here is my procedure and code, please suggest me what is the correct way to calculate from 3-axis accelerometer data and where my code goes wrong. 这是我的程序和代码,请建议我从3轴加速度计数据计算的正确方法是什么,以及我的代码出错的地方。

What I did is: 我做的是:

I am getting acceleration values in x , y , z directions 我在xyz方向上获得加速度值

Resulting acceleration a1 = sqrt(x*x + y*y + z*z) 产生的加速度a1 = sqrt(x*x + y*y + z*z)

Average of 5 acceleration readings: 平均5加速度读数:

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

Time delta: 时间增量:

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

Initially V(0) is 0 and after that V(0) is the previously calculated velocity, hence: 最初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)

This is how I am getting the velocity value, but it is not the correct velocity. 这就是我获取速度值的方法,但它不是正确的速度。 Please guide me. 请指导我。

This is the 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>

Your working out the total magnitude of the acceleration with getAcceleration and loosing all direction information so it will always be positive. 使用getAcceleration计算加速度的总幅度并丢失所有方向信息,这样它总是正的。

You need to take into acount direction and that changes as the phone twists and turns so you have to use the gyro. 你需要考虑到方向,并随着手机曲折而改变,所以你必须使用陀螺仪。

Even if you get the code right though the accuracy of the sensors on a typical phone means you will looses any accuracy very quickly. 即使您获得正确的代码,虽然典型手机上传感器的准确性意味着您将很快失去任何准确性。

If you want running speed look at the gps.... 如果你想要跑步速度,请看gps ....

Edit. 编辑。

Forgot to say your not takeing gravity into account. 忘了说你不考虑重力。 You have to remove the effect of gravity. 你必须消除重力的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用加速度计计算车辆速度? - how to calculate the speed of the vehicle using the accelerometer? 使用Android的接近传感器计算速度 - Calculate speed using proximitiy sensor of Android 如何在Android中使用重力或加速度传感器计算离心力 - How to calculate centrifugal force with gravity or accelerometer sensor in android 如何从加速度计和磁力计传感器计算android中的旋转矩阵 - How to calculate Rotation Matrix in android from accelerometer and magnetometer sensor 如何在Android智能手机中使用加速计传感器找到位移距离? - How to find distance of displacement using accelerometer sensor in android smartphone? 如何使用加速计传感器移动形状? Android java - How to move a shape using the accelerometer sensor? Android java 如何以编程方式在android设备中设置模拟传感器(加速度计) - How to set a mock sensor (accelerometer) in android device using programmatically 使用加速度传感器时Android应用程序崩溃 - Android app crashes when using accelerometer sensor 如何在Android中绘制加速度传感器值的图形? - How to plot graph for accelerometer sensor values in Android? 如何使用手机的加速度传感器计算振动频率(Hz或G或等效值)? - How to calculate Vibration Frequency (Hz or G or Equivalent) using Accelerometer Sensor of Mobile phone?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM