finding orientation using getRotationMatrix() and

2019-02-07 00:46发布

Im trying to get the direction of the vector pointing out of the camera, with respect to magnetic north. I'm under the impression that I need to use the values returned from getOrientation(), but I'm not sure what they represent. The values I get from getOrientation() don't change predictably when I change the orientation of the phone (rotating 90 degrees does not change values by 90 degrees). I need to know what the values returned by getOrientation() mean. What I have so far is written below:

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();*/
   }   
  }

    }

}

I've looked at the documentation on the sensorManager class, but it hasn't helped solve this. If anyone could help me get meaning out of the this I would really appreciate it. I'm testing on a Nexus One running Android 2.1

5条回答
干净又极端
2楼-- · 2019-02-07 01:11

you can check out the logger application that displays raw values on the screen. In its description you'll find a link to the source code so that you can learn how it accesses the sensors.

HTH, Daniele

查看更多
Explosion°爆炸
3楼-- · 2019-02-07 01:14

Because I was new to android I was using toast to display the information on the screen. I changed it to just update text on a view and that seemed to fix it. I also figured out that what I assumed the orientVals actually were is correct. For what I need the roll is not used. Also didnt realize there was a way to convert from rad to deg built in so I just used that.

查看更多
Fickle 薄情
4楼-- · 2019-02-07 01:17

I Think you should change outR to inR in line 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);**
查看更多
甜甜的少女心
5楼-- · 2019-02-07 01:18

I think you should have to use getInclination to get the direction instead of get orientation. as getRotationMatrix is calculating based on both gravity and geomagnetic feild and you will get the inlination from the magnetic field directly.

查看更多
Evening l夕情丶
6楼-- · 2019-02-07 01:27

You need to get the orientation of your device (Landscape/Portrait) and make some compensation.

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;
查看更多
登录 后发表回答