指南针 - 跟踪完整360度旋转的数量

时间:2017-06-12 00:31:01

标签: android android-sensors compass-geolocation

假设一个人正在使用这个指南针,从90度开始他们开始顺时针或逆时针旋转。什么是计算完成360度旋转的最佳方法?假设它们只是顺时针旋转,或者只是从开始到结束逆时针旋转。

我不断提出解决方案,如果开始轴承是例如90度,我会在传感器数据发生变化时继续检查下一个轴承,如果它始终朝一个方向移动,我知道它们正在旋转。如果它们继续沿那个方向旋转并使其回到90度,那就算是一个旋转。我的方式似乎非常复杂和低效,我很难想出一个更好的方法。

在这种情况下,我期待多次完整旋转。

我很感激任何帮助。谢谢!

我找到了this相关的答案,我正在尝试为此编写一个代码示例。如果某人已经做过类似的事情,请发布!

@Override
public void onSensorChanged(SensorEvent event)
{
    switch(event.sensor.getType())
    {
        case Sensor.TYPE_GRAVITY:
        {
            mValuesAccelerometer = lowPass(event.values.clone(), mValuesAccelerometer);
            break;
        }
        case Sensor.TYPE_MAGNETIC_FIELD:
        {
            mValuesMagneticField = lowPass(event.values.clone(), mValuesMagneticField);
            break;
        }
    }

    boolean success = SensorManager.getRotationMatrix(
            mMatrixR,
            mMatrixI,
            mValuesAccelerometer,
            mValuesMagneticField);

    if (success)
    {
        SensorManager.getOrientation(mMatrixR, mMatrixValues);

        float azimuth = toDegrees(mMatrixValues[0]);
        float pitch = toDegrees(mMatrixValues[1]);
        float roll = toDegrees(mMatrixValues[2]);

        if (azimuth < 0.0d)
        {
            //The bearing in degrees
            azimuth += 360.0d;
        }
    }
}

4 个答案:

答案 0 :(得分:1)

如果您确定它们只会向一个方向移动,为了优化您的代码,您可以拥有度数检查点,而不是连续监控它们是否仍然朝着正确的方向移动。

这是一个粗略的算法

//You noted 90 degree as starting point
// checkpoint 1 will be 180 keep it as a boolean 
// now you've reached 180 if the meter gets to 180 before going to next checkpoint 
// which is 270 then make 180 false. it means they turned back. 
// if they make it to 270 then wait for 0 degrees and do the same. 
// if they make it back to 90 like that. You got a rotation and hopefully 
// a bit of complexity is reduced as you're just checking for 4 checkpoints 

我目前没有任何代码方便。

答案 1 :(得分:0)

创建3个整数

int rotationCount=0
int currentDegrees=0
int previousDegrees=89

不是java程序员所以我不知道你是如何处理onSensorChanged事件但基本上在while循环中执行检查

while (currentDegrees + 90 < 360)
{
    if (currentDegrees + 90 == 0) 
    {
        if (previousDegrees == 359) 
        {
            rotationCount = rotationCount + 1
        }
    }
    else if (currentDegrees + 90 == 359) 
    {
        if (previousDegrees == 0) 
        {
            rotationCount = rotationCount - 1
        }  
    }
    previousDegrees = currentDegrees + 90
}

抱歉语法,这只是一个如何操作的例子..

答案 2 :(得分:0)

这是一个跟踪问题,读数溢出。你需要跟踪最后的阅读并希望用户在每次阅读之间不要超过半圈....(因为奈奎斯特定理)

这是基本的伪代码。

var totalChange = 0;
var lastAzimuth = -1000;

function CountTurns(az)
{
  if (az > 180) az -= 360;   // do this if your azimuth is always positive i.e. 0-360.

  if (lastAzimuth == -1000)
  {
    lastAzimuth = az;
  }

  diff = az - lastAzimuth;
  if (diff > 180)
     diff -= 360;
  if (diff < -180)
     diff += 360;

  lastAzimuth = az;
  totalChange += diff;
  return totalChange / 360;
}

答案 3 :(得分:0)

想象我会说什么,你肯定会立刻达到你的目标。 因为你不需要考虑完整的360度,但你可以采取一半,并使用符号差异对你有利。

看看这个数字: 360 Rotation

我们有一个圆圈,分为两侧(左侧和右侧)。

左侧将呈负180度。 (西区)。

右侧将取正180度。 (东区)。

当前位置将始终为0(北),正180为(南)。

如果指南针变为正(意思是朝向正确的方向)

然后每回合加+1。

如果罗盘变为负值(意思是向左方向)。

然后每回合减去-1

如果罗盘命中OR为0,那么它是当前位置(NORTH)。

如果指南针命中OR是90,那么它是(东)。

如果罗盘命中OR是180,那么它是(南)

如果罗盘命中OR是-90,那么它是(西)。

这将证明,无论何时该人进入东方,计数器将增加+1直到它达到180,然后它将从正变为负,这将在每一轮减去-1,直到它达到0。完全旋转360度。