Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓手机倾斜时会受到污染_Android_Math_Augmented Reality_Compass Geolocation - Fatal编程技术网

Android 安卓手机倾斜时会受到污染

Android 安卓手机倾斜时会受到污染,android,math,augmented-reality,compass-geolocation,Android,Math,Augmented Reality,Compass Geolocation,我有一个非常恼人的问题,AR视图就像一个指南针。因此,当我以纵向方式握住手机(这样屏幕就指向我的脸),然后我调用remapCoordinateSystem,当我以纵向方式握住手机时,音高为0。方位角(指南针功能)是完美的,但一旦我倾斜手机,方位角就会被破坏,如果我向前弯曲,方位角就会增加,如果我向后弯曲,方位角就会减少 我使用两个传感器获取读数,Sensor.TYPE\u MAGNETIC\u FIELD和Sensor.TYPE\u GRAVITY 我使用了一个非常基本的低通滤波器,它是用alp

我有一个非常恼人的问题,AR视图就像一个指南针。因此,当我以纵向方式握住手机(这样屏幕就指向我的脸),然后我调用
remapCoordinateSystem
,当我以纵向方式握住手机时,音高为0。方位角(指南针功能)是完美的,但一旦我倾斜手机,方位角就会被破坏,如果我向前弯曲,方位角就会增加,如果我向后弯曲,方位角就会减少

我使用两个传感器获取读数,
Sensor.TYPE\u MAGNETIC\u FIELD
Sensor.TYPE\u GRAVITY

我使用了一个非常基本的低通滤波器,它是用alpha常量实现的,直接用于从传感器读取的值

这是我的密码:

float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrix(rotationMatrix, null, gravitymeterValues,
    magnetometerValues);

float[] remappedRotationMatrix = new float[9];

SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X,
    SensorManager.AXIS_Z, remappedRotationMatrix);

float results[] = new float[3];
SensorManager.getOrientation(remappedRotationMatrix, results);

float azimuth = (float) (results[0] * 180 / Math.PI);
if (azimuth < 0) {
    azimuth += 360;
}

float pitch = (float) (results[1] * 180 / Math.PI);
float roll = (float) (results[2] * 180 / Math.PI);
float[]旋转矩阵=新浮点[9];
SensorManager.getRotationMatrix(rotationMatrix,null,重力测量值,
磁强计值);
float[]remappedRotationMatrix=新float[9];
SensorManager.剩余协调系统(旋转矩阵、SensorManager.AXIS_X、,
SensorManager.AXIS_Z,重新映射到Matrix);
浮动结果[]=新浮动[3];
SensorManager.getOrientation(重新显示运动矩阵,结果);
浮动方位=(浮动)(结果[0]*180/Math.PI);
中频(方位角<0){
方位+=360;
}
浮动节距=(浮动)(结果[1]*180/Math.PI);
浮动辊=(浮动)(结果[2]*180/Math.PI);
正如你所看到的,这里没有魔法。当重力仪值和磁力仪值准备好使用时,我调用这段代码

我的问题是,当我倾斜手机时,如何防止方位角变得疯狂

我在谷歌Play商店Compass上查看了一个免费应用程序,但它并没有解决这个问题,但我希望有一个解决方案

我有两个解决方案:

  • 使AR视图仅在非常受限的俯仰角度下工作,现在我有一些类似于
    pitch>=-5&&pitch的内容,有关完整的代码,请参见
    保留历史记录和平均值,我不知道俯仰和横滚的正确解释,因此以下代码仅用于方位角

    班级成员

    private List<float[]> mRotHist = new ArrayList<float[]>();
    private int mRotHistIndex;
    // Change the value so that the azimuth is stable and fit your requirement
    private int mHistoryMaxLength = 40;
    float[] mGravity;
    float[] mMagnetic;
    float[] mRotationMatrix = new float[9];
    // the direction of the back camera, only valid if the device is tilted up by
    // at least 25 degrees.
    private float mFacing = Float.NAN;
    
    public static final float TWENTY_FIVE_DEGREE_IN_RADIAN = 0.436332313f;
    public static final float ONE_FIFTY_FIVE_DEGREE_IN_RADIAN = 2.7052603f;
    
    private List mRotHist=new ArrayList();
    私人国际贸易指数;
    //更改该值,使方位角稳定并符合您的要求
    私有int mHistoryMaxLength=40;
    浮动利率;
    浮磁;
    浮动[]mRotationMatrix=新浮动[9];
    //背面摄像头的方向,仅当设备向上倾斜
    //至少25度。
    私人浮动汇率=float.NAN;
    公共静态最终浮动二十五度弧度=0.436332313f;
    公共静态最终浮动1度50度5度弧度=2.7052603f;
    
    onSensorChanged

    @Override
    public void onSensorChanged(SensorEvent event)
    {
         if (event.sensor.getType() == Sensor.TYPE_GRAVITY)
         {
             mGravity = event.values.clone();
         }
         else
         {
            mMagnetic = event.values.clone();
         }
    
         if (mGravity != null && mMagnetic != null)
         {
              if (SensorManager.getRotationMatrix(mRotationMatrix, null, mGravity, mMagnetic))
              {
                  // inclination is the degree of tilt by the device independent of orientation (portrait or landscape)
                  // if less than 25 or more than 155 degrees the device is considered lying flat
                  float inclination = (float) Math.acos(mRotationMatrix[8]);
                  if (inclination < TWENTY_FIVE_DEGREE_IN_RADIAN 
                          || inclination > ONE_FIFTY_FIVE_DEGREE_IN_RADIAN)
                  {
                      // mFacing is undefined, so we need to clear the history
                      clearRotHist();
                      mFacing = Float.NaN;
                  }
                  else
                  {
                      setRotHist();
                      // mFacing = azimuth is in radian
                      mFacing = findFacing(); 
                  }
              }
         }
    }
    
    private void clearRotHist()
    {
        if (DEBUG) {Log.d(TAG, "clearRotHist()");}
        mRotHist.clear();
        mRotHistIndex = 0;
    }
    
    private void setRotHist()
    {
        if (DEBUG) {Log.d(TAG, "setRotHist()");}
        float[] hist = mRotationMatrix.clone();
        if (mRotHist.size() == mHistoryMaxLength)
        {
            mRotHist.remove(mRotHistIndex);
        }   
        mRotHist.add(mRotHistIndex++, hist);
        mRotHistIndex %= mHistoryMaxLength;
    }
    
    private float findFacing()
    {
        if (DEBUG) {Log.d(TAG, "findFacing()");}
        float[] averageRotHist = average(mRotHist);
        return (float) Math.atan2(-averageRotHist[2], -averageRotHist[5]);
    }
    
    public float[] average(List<float[]> values)
    {
        float[] result = new float[9];
        for (float[] value : values)
        {
            for (int i = 0; i < 9; i++)
            {
                result[i] += value[i];
            }
        }
    
        for (int i = 0; i < 9; i++)
        {
            result[i] = result[i] / values.size();
        }
    
        return result;
    }
    
    @覆盖
    传感器更改时的公共无效(传感器事件)
    {
    if(event.sensor.getType()==sensor.TYPE\u重力)
    {
    mGravity=event.values.clone();
    }
    其他的
    {
    mmamagnetic=event.values.clone();
    }
    if(mGravity!=null和&mmamagnetic!=null)
    {
    if(SensorManager.getRotationMatrix(mRotationMatrix,null,mRavity,mMagnetic))
    {
    //倾斜度是装置的倾斜度,与方向无关(纵向或横向)
    //如果小于25度或大于155度,则该装置被视为平放
    浮动倾角=(浮动)数学.acos(mRotationMatrix[8]);
    如果(倾斜度<二十五度
    ||倾角>一度五十度五度弧度)
    {
    //制造业尚未定义,因此我们需要清除历史记录
    clearRotHist();
    mFacing=Float.NaN;
    }
    其他的
    {
    setRotHist();
    //mFacing=方位角以弧度为单位
    mFacing=findFacing();
    }
    }
    }
    }
    私有无效清除列表()
    {
    if(DEBUG){Log.d(标记,“clearRotHist()”);}
    mRotHist.clear();
    mRotHistIndex=0;
    }
    私有无效设置列表()
    {
    if(DEBUG){Log.d(标记,“setRotHist()”);}
    float[]hist=mRotationMatrix.clone();
    if(mRotHist.size()=mHistoryMaxLength)
    {
    mRotHist.remove(mRotHistIndex);
    }   
    添加(mRotHistIndex++,hist);
    mRotHistIndex%=mHistoryMaxLength;
    }
    私人浮动findFacing()
    {
    if(DEBUG){Log.d(标记,“findFacing()”);}
    float[]averageRotHist=平均值(mRotHist);
    return(float)Math.atan2(-averageRotHist[2],-averageRotHist[5]);
    }
    公共浮动[]平均值(列表值)
    {
    浮点[]结果=新浮点[9];
    for(float[]值:值)
    {
    对于(int i=0;i<9;i++)
    {
    结果[i]+=值[i];
    }
    }
    对于(int i=0;i<9;i++)
    {
    结果[i]=结果[i]/values.size();
    }
    返回结果;
    }
    
    低通滤波器是什么?使用类型\重力时不需要过滤。@HoanNguyen我是否需要低通
    传感器。类型\磁场
    ?现在我同时使用了低通
    传感器。输入\u磁场
    传感器。输入\u重力
    。不,使用低通滤波器是为了消除x和y方向的加速度。getRotationMatrix要求第三个参数近似于z方向上的加速度。如果您使用类型\重力,则不需要低通滤波器,但许多设备没有类型\重力,因此您需要为没有类型\重力的设备使用类型\加速度计和低通滤波器。好的,谢谢。但当我倾斜手机时,我的方位角值不好,你知道怎么解决吗?我会保存一段历史记录,并将结果平均。我可以前后弯曲,方位角当然可以改变,但不能超过2或3度。很棒的东西!现在我的方位角好多了,唯一的问题是在快速移动时,它会跳很多,但我想你必须接受这一点。非常感谢您的代码。还有一个问题:你的更新率是多少