1

I want to use Android acceleration sensors to measure distances. I modified the code in stackoverflow. Street information is strange. Can you tell me what's wrong? The sensor is activated when the button is pressed and is calculated if the button is not pressed. I am Korean and I used Google Translator.

public class MainActivity extends AppCompatActivity {

SensorManager sm;
SensorEventListener acc;
Sensor accSensor;
TextView x,y,z,dist_total,time,dist_last,ax,az,ay;
float currentAcc, lastAcc=0.0f, effectiveAcc;
float distance = 0, totalDistance = 0;
long time_elapsed;
long tt;
long startTime;
long Endtime;
float xx;
float dX = 0;

public float accelXValue, accelYValue,accelZValue = 0.0f;
Button startButton,stopButton, resetButton;

Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    sm = (SensorManager)getSystemService(SENSOR_SERVICE);
    accSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

    acc = new accListener();


    stopButton = (Button) findViewById(R.id.stop);
    resetButton =(Button) findViewById(R.id.reset);

    x = (TextView)findViewById(R.id.x);
    y = (TextView)findViewById(R.id.y);
    z = (TextView)findViewById(R.id.z);

    ax = (TextView)findViewById(R.id.ax);
    ay = (TextView)findViewById(R.id.ay);
    az = (TextView)findViewById(R.id.az);


    dist_last = (TextView)findViewById(R.id.text_last_dist);
    time = (TextView)findViewById(R.id.text_time);



    findViewById(R.id.start).setOnTouchListener(new View.OnTouchListener(){

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getAction()){

                case MotionEvent.ACTION_DOWN:
                    sm.registerListener(acc, accSensor, SensorManager.SENSOR_DELAY_UI);
                    displayValues();
                    startTime = System.currentTimeMillis();

                    break;

                case MotionEvent.ACTION_UP:
                    sm.unregisterListener(acc);
                    calculate();
                    stopCalculation();
                    Endtime = System.currentTimeMillis();
                    System.out.println("**********Endtime**********"+(Endtime/1000));
                    break;

            }
            return false;
        }
    });

    stopButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {



        }

    });

    resetButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            resetFields();
            Toast.makeText(getApplicationContext(),"모든 정보를 초기화를 했습니다.",Toast.LENGTH_SHORT).show();
        }
    });
}


@Override
public void onPause(){
super.onPause();
Log.e("LOG", "onPause()");
sm.unregisterListener(acc);
}

@Override
public void onDestroy(){
    super.onDestroy();
    Log.e("LOG", "onDestroy()");
    sm.unregisterListener(acc);
}

@Override
protected void onResume() {
    super.onResume();
    sm.registerListener(acc,accSensor,SensorManager.SENSOR_DELAY_GAME);
}

private class accListener implements SensorEventListener {
    public void onSensorChanged(SensorEvent event){





        x.setText(Float.toString(event.values[0]));
        y.setText(Float.toString(event.values[1]));
        z.setText(Float.toString(event.values[2]));

   if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        accelXValue = event.values[0];
        accelYValue = event.values[1];
        accelZValue = event.values[2];

        Log.e("LOG", "ACCELOMETER           [X]:" + String.format("%.4f", event.values[0])
                + "           [Y]:" + String.format("%.4f", event.values[1])
                + "           [Z]:" + String.format("%.4f", event.values[2]));



    }
    public void onAccuracyChanged(Sensor sensor,int accuracy){

    }

}

public void calculate() {


        time_elapsed = (Endtime-startTime)/1000;
        tt = Math.abs(time_elapsed);
        currentAcc = (float) Math.sqrt(Math.pow(accelXValue,2)+Math.pow(accelZValue,2)+Math.pow(accelYValue,2));
        effectiveAcc = currentAcc - lastAcc;
        distance = Math.abs(effectiveAcc) * 0.5f * tt * tt ;
        totalDistance += distance;
        lastAcc = currentAcc;






    System.out.println("totalDistance : "+totalDistance);
    System.out.println("tt : "+tt);
    System.out.println("currentAcc : "  +currentAcc);
    System.out.println("effectiveAcc : "+effectiveAcc);
    System.out.println("distance : "+distance);
    System.out.println("lastAcc : "+lastAcc);

}

private void stopCalculation() {

    dist_last.setText(String.format("Distance: " + "%s" + " m", 
 Float.toString(distance)));

}

public void displayValues(){


    ax.setText(String.format("Acceleration X: " + "%s" , accelXValue));
    ay.setText(String.format("Acceleration Y: " + "%s" , accelYValue));
    az.setText(String.format("Acceleration Z: " + "%s" , accelZValue));


}

public void resetFields(){
    totalDistance = 0.0f;
    distance = 0.0f;
    tt =0;
    currentAcc = 0.0f;
    lastAcc = 0.0f;
    effectiveAcc =0.0f;

    dist_last.setText(String.format("Distance: " + "%s" + " m",Float.toString(distance)));

    System.out.println("TotalDistance"+totalDistance);
    System.out.println("distance"+distance);
    System.out.println("tt"+tt);
    System.out.println("currentAcc"+currentAcc);
    System.out.println("effectiveAcc"+effectiveAcc);
    System.out.println("lastAcc"+lastAcc);

}

}

Johan
  • 74,508
  • 24
  • 191
  • 319

1 Answers1

2

This isn't going to work very well, no matter what you do. The accelerometer has 2 problems:

1)Its noisy. Which means you'll have lots of little inaccuracies that will add up quickly

2)It can max out. If you accelerate too hard it will cap out and not report anything higher.

If you want to do distance, you're better off using GPS and a smoothing algorithm. The accelerometer will always give shitty results.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127