简体   繁体   中英

determining angle of device with horizon as axis -android

I have an interesting problem. I am trying to trace out the angle of a users phone regardless of whether they are holding it in landscape or portrait or any where in between..

I am currently using SENSOR_ORIENTATION and getting YAW, ROLL, and Pitch. I was also trying to get the angle of the users view port on the zaxis using yaw, and to correct for the users roll (landscape, portrait, or in between) i did some simple math..:

double roll = phoneOri.getRoll();
double yaw = phoneOri.getYaw()+roll;

     if (yaw>=360){
                yaw = (yaw - 360);
            }
            if (yaw<0){
                yaw = (yaw+360);    
            }

this code corrects the yaw and gives me the proper angle no matter what the roll position is..
but this sort of math doesn't correct for pitch it seems. if i hold my phone perpendicular to the floor i want to always get a pitch of 0 regardless of roll or yaw, if i face the back of the phone straight up to the sky and parallel to the ground i want to get 90, back to the ground -90;

here is how i am getting pitch roll and yaw:

    double yaw;
    double pitch;
    double roll;

public void onSensorChanged(SensorEvent evt) {
            int type=evt.sensor.getType();
            if(type == Sensor.TYPE_ORIENTATION){
                yaw = evt.values[0];
                pitch = evt.values[1];
                roll = evt.values[2];
            }
            if (type == Sensor.TYPE_MAGNETIC_FIELD) {
                orientation[0]=(orientation[0]*1+evt.values[0])*0.5f;
                orientation[1]=(orientation[1]*1+evt.values[1])*0.5f;
                orientation[2]=(orientation[2]*1+evt.values[2])*0.5f;
            } else if (type == Sensor.TYPE_ACCELEROMETER) {
                acceleration[0]=(acceleration[0]*2+evt.values[0])*0.33334f;
                acceleration[1]=(acceleration[1]*2+evt.values[1])*0.33334f;
                acceleration[2]=(acceleration[2]*2+evt.values[2])*0.33334f;
            }
            if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) {
                float newMat[]=new float[16];

                //Toast toast = Toast.makeText(ctx.getApplicationContext(), "accel", Toast.LENGTH_SHORT);
                //toast.show();
                SensorManager.getRotationMatrix(newMat, null, acceleration, orientation);
                if(displayOri==0||displayOri==2){
                    SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_X*-1, SensorManager.AXIS_MINUS_Y*-1,newMat);
                }else{
                    SensorManager.remapCoordinateSystem(newMat,SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X,newMat);
                }

                matrix=newMat;
                SensorManager.getOrientation (newMat, orientationValues); 
            }
        }

currently i get the following results:

pitch = -90 roll = 0 ;

在此处输入图片说明

pitch = 0 roll = 90 ;

在此处输入图片说明

pitch = 90 roll = -20 ;

在此处输入图片说明

pitch = 0 roll = -90 ;

I am trying to get a pitch of 0 in any of these positions and then get a pitch between -90 and 90 respectively as the user tilts the phone on the HORIZON axis?

any ideas? oh and i should add that my application is locked to landscape mode..

Those constants probably have cumlative errors. Try using the Math functions instead...

Interesting problem,

have you tried getting the absolute x,y and z values (irrespective of the orientation of the phone) as mentioned here , using that, you should get the absolute y values that you are looking for

public abstract void onSensorChanged (int sensor, float[] values)

> IMPORTANT NOTE: The axis are swapped when the device's screen orientation changes. To access the unswapped values, use indices 3, 4 and 5 in values[].

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM