Android: Problems calculating the Orientation of the Device

前端 未结 4 458
耶瑟儿~
耶瑟儿~ 2020-12-30 09:14

i\'am trying to build a simple Augmented Reality App, so I start working with sensor Data.

According to this thread (Android compass example) and ex

相关标签:
4条回答
  • 2020-12-30 09:42

    Answer from Tíbó is good, but if you log roll value, you will expect irregular numbers. (roll is important for AR Browsers)

    This is due to

    SensorManager.remapCoordinateSystem(mRotationMatrix,
                        SensorManager.AXIS_X, SensorManager.AXIS_Z,
                        mRotationMatrix);
    

    You have to use different matrix for in and out of remap. This following code works for me with a correct roll value:

    @Override
    public void onSensorChanged(SensorEvent event)
    {
        // It is good practice to check that we received the proper sensor event
        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
        {
            // Convert the rotation-vector to a 4x4 matrix.
            SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values);
            SensorManager.remapCoordinateSystem(mRotationMatrixFromVector,
                        SensorManager.AXIS_X, SensorManager.AXIS_Z,
                        mRotationMatrix);
            SensorManager.getOrientation(mRotationMatrix, orientationVals);
    
            // Optionally convert the result from radians to degrees
            orientationVals[0] = (float) Math.toDegrees(orientationVals[0]);
            orientationVals[1] = (float) Math.toDegrees(orientationVals[1]);
            orientationVals[2] = (float) Math.toDegrees(orientationVals[2]);
    
            tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: "
                    + orientationVals[1] + "\n Roll (not used): "
                    + orientationVals[2]);
    
        }
    }
    
    0 讨论(0)
  • 2020-12-30 09:51

    Probably late to the party. Anyway here is how I got the azimuth

    private final int sensorType =  Sensor.TYPE_ROTATION_VECTOR;
    float[] rotMat = new float[9];
    float[] vals = new float[3];
    
    @Override
    public void onSensorChanged(SensorEvent event) {
        sensorHasChanged = false;
        if (event.sensor.getType() == sensorType){
            SensorManager.getRotationMatrixFromVector(rotMat,
                    event.values);
            SensorManager
                    .remapCoordinateSystem(rotMat,
                            SensorManager.AXIS_X, SensorManager.AXIS_Y,
                            rotMat);
            SensorManager.getOrientation(rotMat, vals);
            azimuth = deg(vals[0]); // in degrees [-180, +180]
            pitch = deg(vals[1]);
            roll = deg(vals[2]);
            sensorHasChanged = true;
        }
    }
    

    Hope it helps

    0 讨论(0)
  • 2020-12-30 09:53

    Have you tried the combined (sensor-fusion) type Sensor.TYPE_ROTATION_VECTOR. This may give better results: Go to https://developer.android.com/reference/android/hardware/SensorEvent.html and search for 'rotation_vector'.

    0 讨论(0)
  • 2020-12-30 10:01

    In what kind of orientation do you use this sample app? From what is written is this code, the only orientation supported is Portrait or flat on the table, it depends on devices. What do you mean by "good"?

    It is normal that the value is not "good" when rotating the device, the device coordinate system is supposed to be working in Portrait, or flat i don't know (Y axis vertical along the screen pointing up, Z axis pointing out of the screen coming from the center of screen, X axis perpendicular to the Y axis going on the right along the screen). Having this, rotating the device will not rotate the device coordinate system, you'll have to remap it.

    But if you want the heading of the device in Portrait orientation, here is a piece of code that works good for me:

    @Override
    public void onSensorChanged(SensorEvent event)
    {
        // It is good practice to check that we received the proper sensor event
        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
        {
            // Convert the rotation-vector to a 4x4 matrix.
            SensorManager.getRotationMatrixFromVector(mRotationMatrix,
                    event.values);
            SensorManager
                    .remapCoordinateSystem(mRotationMatrix,
                            SensorManager.AXIS_X, SensorManager.AXIS_Z,
                            mRotationMatrix);
            SensorManager.getOrientation(mRotationMatrix, orientationVals);
    
            // Optionally convert the result from radians to degrees
            orientationVals[0] = (float) Math.toDegrees(orientationVals[0]);
            orientationVals[1] = (float) Math.toDegrees(orientationVals[1]);
            orientationVals[2] = (float) Math.toDegrees(orientationVals[2]);
    
            tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: "
                    + orientationVals[1] + "\n Roll (not used): "
                    + orientationVals[2]);
    
        }
    }
    

    You'll get the heading (or azimuth) in:

    orientationVals[0]
    
    0 讨论(0)
提交回复
热议问题