поиск ориентации с помощью getRotationMatrix() и getOrientation()

Я пытаюсь получить направление вектора, указывающего из камеры, относительно магнитного севера. У меня сложилось впечатление, что мне нужно использовать значения, возвращаемые из getOrientation(), но я не уверен, что они представляют. Значения, которые я получаю от getOrientation(), не изменяются предсказуемо, когда я меняю ориентацию телефона (поворот на 90 градусов не меняет значения на 90 градусов). Мне нужно знать, что означают значения, возвращаемые getOrientation(). То, что у меня есть, написано ниже:

package com.example.orientation;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;

public class Orientation extends Activity{

 private SensorManager mSM;
 private mSensorEventListener mSEL;

    float[] inR = new float[16];
    float[] outR= new float[16];
    float[] I = new float[16];
    float[] gravity = new float[3];
    float[] geomag = new float[3];
    float[] orientVals = new float[3];

    final float pi = (float) Math.PI;
    final float rad2deg = 180/pi;    

 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSM = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSEL = new mSensorEventListener();  

        mSM.registerListener(mSEL, 
       mSM.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
       SensorManager.SENSOR_DELAY_NORMAL);

     mSM.registerListener(mSEL, 
       mSM.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), 
       SensorManager.SENSOR_DELAY_NORMAL);

 }



 private class mSensorEventListener implements SensorEventListener{

  @Override
  public void onAccuracyChanged(Sensor arg0, int arg1) {}

  @Override
  public void onSensorChanged(SensorEvent event) {

   // If the sensor data is unreliable return
   if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
    return;

   // Gets the value of the sensor that has been changed
   switch (event.sensor.getType()){  
   case Sensor.TYPE_ACCELEROMETER:
    gravity = event.values.clone();
    break;
   case Sensor.TYPE_MAGNETIC_FIELD:
    geomag = event.values.clone();
    break;
   }

   // If gravity and geomag have values then find rotation matrix
   if (gravity != null && geomag != null){

    // checks that the rotation matrix is found
    boolean success = SensorManager.getRotationMatrix(inR, I, gravity, geomag);
    if (success){

     // Re-map coordinates so y-axis comes out of camera
     SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, 
       SensorManager.AXIS_Z, outR);

     // Finds the Azimuth and Pitch angles of the y-axis with 
     // magnetic north and the horizon respectively
     SensorManager.getOrientation(outR, orientVals);
     float azimuth = orientVals[0]*rad2deg;
     float pitch = orientVals[1]*rad2deg;
     float roll = orientVals[2]*rad2deg;

     // Displays a pop up message with the azimuth and inclination angles
     String endl = System.getProperty("line.separator");
     Toast.makeText(getBaseContext(), 
       "Rotation:" +
       outR[0] + " " + outR[1] + " " + outR[2] + endl +
       outR[4] + " " + outR[5] + " " + outR[6] + endl +
       outR[8] + " " + outR[9] + " " + outR[10] + endl +endl +
       "Azimuth: " + azimuth + " degrees" + endl + 
       "Pitch: " + pitch + " degrees" + endl +
       "Roll: " + roll + " degrees", 
       Toast.LENGTH_LONG).show();
    } /*else
     Toast.makeText(getBaseContext(), 
       "Get Rotation Matrix Failed", Toast.LENGTH_LONG).show();*/
   }   
  }

    }

}

Я просмотрел документацию по классу sensorManager, но это не помогло решить эту проблему. Если бы кто-нибудь мог помочь мне понять смысл этого, я был бы очень признателен. Я тестирую Nexus One под управлением Android 2.1.


person pat    schedule 26.10.2010    source источник


Ответы (5)


Поскольку я был новичком в Android, я использовал тост для отображения информации на экране. Я изменил его, чтобы просто обновить текст в представлении, и это, похоже, исправило его. Я также понял, что то, что я предполагал, ориентвалы на самом деле были правильными. Для того, что мне нужно, рулон не используется. Также не знал, что есть встроенный способ преобразования рад в градус, поэтому я просто использовал его.

person pat    schedule 02.11.2010

вы можете проверить приложение для регистрации, которое отображает необработанные значения на экране. В его описании вы найдете ссылку на исходный код, чтобы узнать, как он обращается к датчикам.

ХТХ, Даниэле

person Daniele    schedule 19.03.2012

Вам нужно получить ориентацию вашего устройства (Пейзаж/Портрет) и сделать некоторую компенсацию.

SensorManager.getOrientation(R, values);  
mHeading = (int) Math.toDegrees(values[0]); 
Display display = 
((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int compensation = display.getRotation() * 90;                          
mHeading = mHeading+compensation;
person Will    schedule 22.03.2012

Я думаю, вам нужно использовать getInclination, чтобы получить направление, а не ориентацию. поскольку getRotationMatrix рассчитывается на основе как силы тяжести, так и геомагнитного поля, и вы получите инлинацию непосредственно из магнитного поля.

person Jibran Ahmed    schedule 14.01.2011

Я думаю, вам следует изменить outR на inR в строке getOrientation

boolean success = SensorManager.getRotationMatrix(inR, I, gravity, geomag);
if (success){
 // Re-map coordinates so y-axis comes out of camera
 SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, 
   SensorManager.AXIS_Z, outR);

 // Finds the Azimuth and Pitch angles of the y-axis with 
 // magnetic north and the horizon respectively
 **SensorManager.getOrientation(inR, orientVals);**
person user2873829    schedule 12.10.2013