Android 获取用户';利用加速度计和磁强计测量航向

Android 获取用户';利用加速度计和磁强计测量航向,android,android-sensors,Android,Android Sensors,我试图在安卓手机上获取用户标题的值,只使用加速计和磁强计传感器。我一直在研究许多其他的解决方案,但在尝试实现自己的代码时遇到了一些问题 代码如下: if(event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){ Log.d("MAG_FIELD", "ITS A MAG FIELD"); //aX, aY, aZ are raw accelerometer values float aTheta =

我试图在安卓手机上获取用户标题的值,只使用加速计和磁强计传感器。我一直在研究许多其他的解决方案,但在尝试实现自己的代码时遇到了一些问题

代码如下:

if(event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){
    Log.d("MAG_FIELD", "ITS A MAG FIELD");

        //aX, aY, aZ are raw accelerometer values 
        float aTheta = (float) Math.atan2(-aX, aZ);
        float aPhi = (float) Math.atan2(-aY, aZ);

        //Obtaining the current magnetometer readings
        float mDegX = event.values[0];
        float mDegY = event.values[1];
        float mDegZ = event.values[2];

        float rotationVectorX = (float) ((mDegX * Math.cos(aPhi)) + (mDegY *Math.sin(aTheta) * Math.sin(aPhi)) - (mDegZ * Math.cos(aTheta) * Math.sin(aPhi)));
        float rotationVectorY = (float) ((mDegY * Math.cos(aTheta)) + (mDegZ * Math.sin(aTheta)));

        //HEADING calculation

        float heading = (float)  Math.abs(Math.toDegrees(Math.atan(rotationVectorY /rotationVectorX)));

        if(rotationVectorX >= 0.0f && rotationVectorY >=0.0f) {}
        else if(rotationVectorX < 0.0f && rotationVectorY >= 0.0f) {heading = 180 - heading ;}
        else if(rotationVectorX < 0.0f && rotationVectorY < 0.0f) {heading = 180 + heading;}
        else if(rotationVectorX >= 0.0f && rotationVectorY < 0.0f){heading = 360 - heading;}
if(event.sensor.getType()==sensor.TYPE\u磁场){
Log.d(“MAG_字段”,“它是MAG字段”);
//aX、aY、aZ是原始加速计值
浮点aTheta=(浮点)数学atan2(-aX,aZ);
浮动aPhi=(浮动)数学atan2(-aY,aZ);
//获取当前磁强计读数
float mDegX=event.values[0];
float mDegY=event.values[1];
float mDegZ=event.values[2];
float rotationvectrox=(float)((mDegX*Math.cos(aPhi))+(mDegY*Math.sin(aTheta)*Math.sin(aPhi))-(mDegZ*Math.cos(aTheta)*Math.sin(aPhi));
float rotationVectorY=(float)((mDegY*Math.cos(aTheta))+(mDegZ*Math.sin(aTheta));
//航向计算
float heading=(float)Math.abs(Math.toDegrees(Math.atan(rotationVectorY/rotationVectorX));
如果(rotationVectorX>=0.0f&&rotationVectorY>=0.0f){}
else如果(rotationVectorX<0.0f&&rotationVectorY>=0.0f){heading=180-heading;}
else如果(rotationVectorX<0.0f&&rotationVectorY<0.0f){heading=180+heading;}
如果(rotationVectorX>=0.0f&&rotationVectorY<0.0f){heading=360-heading;}
我的问题是:

  • 当设备启动时,航向持续偏离约90度 是平的
  • 当屏幕从平面变为平面时,标题会发生变化-我需要它保持不变

  • 使用磁强计和加速计,您可以实时找到设备的方向。即使您的设备不在平坦表面上,这也可以工作

     if (event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD) {
                geomag[0]=event.values[0];
                geomag[1]=event.values[1];
                geomag[2]=event.values[2];
            }
    
     if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER) {
                float alpha = 0.8f;
    
                gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
                gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
                gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];               
            }
    
                rotationMatrix = new float[16];
                SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomag);
                SensorManager.getOrientation(rotationMatrix,vals);
    
                double Heading=vals[0] * (180/Math.PI);