1 year ago
#341035
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