1 year ago

#341035

test-img

zokatramvaj

How can I use GeomagneticField with getDeclination () in my compass app to fix the true north problem?

How can I use GeomagneticField with getDeclination () in my compass app to fix the true north problem? I already made a compass app but the north is not correct, how could I fix this with getDeclination (), does anyone have an Idea? A compass is showing North something like +20 more degrees than it should be.

private SensorManager sensorManager;
private Sensor magnetometerSensor;
private Sensor accelerometerSensor;
private Sensor gravitySensor;
private Sensor rotationVectorSensor;

TextView azimuthTextView;
ImageView compassFrontImageView;

Window window;



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





    azimuthTextView = findViewById(R.id.azimuthTextVeiw);
    compassFrontImageView = findViewById(R.id.compassFrontImageView);



    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

    magnetometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
    rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);


    //keep screen on
    window = getWindow();
    WindowManager.LayoutParams layoutParams = window.getAttributes();
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);




}


@Override
protected void onResume() {
    super.onResume();

    if(rotationVectorSensor != null) {
        sensorManager.registerListener(this, rotationVectorSensor, SensorManager.SENSOR_DELAY_NORMAL);

        operationMode = 2;
    }
    else if(magnetometerSensor != null  &&  gravitySensor != null){
        sensorManager.registerListener(this, magnetometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, gravitySensor, SensorManager.SENSOR_DELAY_NORMAL);

        operationMode = 1;
    }
    else if(magnetometerSensor!= null && accelerometerSensor !=null) {
        sensorManager.registerListener(this, magnetometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);

        operationMode = 0;
    }

}
@Override
protected void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
}

int operationMode = 0;

int azimuth;
int oldAzimuth;




float[] magneticField = new float[3];
float[] acceleration  = new float[3];
float[] gravity  = new float[3];
float[] rotationVector  = new float[5];

float[] rotationMatrix  = new float[9];
float[] inclinationMatrix  = new float[9];

ObjectAnimator rotationAnimation;

float[] orientation  = new float[3];



@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    switch (sensorEvent.sensor.getType()) {
        case Sensor.TYPE_MAGNETIC_FIELD:
            System.arraycopy(sensorEvent.values, 0, magneticField, 0, sensorEvent.values.length);
            break;
        case Sensor.TYPE_ACCELEROMETER:
            System.arraycopy(sensorEvent.values, 0, acceleration, 0, sensorEvent.values.length);
            break;
        case Sensor.TYPE_GRAVITY:
            System.arraycopy(sensorEvent.values, 0, gravity, 0, sensorEvent.values.length);
            break;
        case Sensor.TYPE_ROTATION_VECTOR:
            System.arraycopy(sensorEvent.values, 0, rotationVector, 0, sensorEvent.values.length);
            break;



    }
    if (operationMode == 0 || operationMode == 1) {

        if (SensorManager.getRotationMatrix(rotationMatrix, inclinationMatrix, (operationMode == 0) ? acceleration : gravity, magneticField)) {

            float azimuthRad = SensorManager.getOrientation(rotationMatrix, orientation)[0];
            double azimuthDeg = Math.toDegrees(azimuthRad);

            




            azimuth = ((int) azimuthDeg + 360) % 360;


        }
    } else if (operationMode == 2) {

        SensorManager.getRotationMatrixFromVector(rotationMatrix, rotationVector);


        azimuth = (int) (Math.toDegrees(SensorManager.getOrientation(rotationMatrix, orientation)[0]) + 360) % 360;
    }






        
    azimuthTextView.setText(String.valueOf(azimuth) + "°");

    //compassFrontImageView.setRotation(-azimuth);










    float tempAzimuth;
    float tempCurrentazimuth;

    if (Math.abs(azimuth - oldAzimuth) > 180) {
        if (oldAzimuth < azimuth) {
            tempCurrentazimuth = oldAzimuth + 360;
            tempAzimuth = azimuth;
        } else {
            tempCurrentazimuth = oldAzimuth;
            tempAzimuth = azimuth + 360;
        }
        rotationAnimation = ObjectAnimator.ofFloat(compassFrontImageView, "rotation", -tempCurrentazimuth, -tempAzimuth);
        rotationAnimation.setDuration(250);
        rotationAnimation.start();
    } else {

    rotationAnimation = ObjectAnimator.ofFloat(compassFrontImageView, "rotation", -oldAzimuth, -azimuth);
    rotationAnimation.setDuration(250);
    rotationAnimation.start();
}



    oldAzimuth = azimuth;


}





@Override
public void onAccuracyChanged(Sensor sensor, int i) {


}


                 //Action bar
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.acionbar_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

java

android-studio

compass

0 Answers

Your Answer

Accepted video resources