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

5
假设一个人使用这个指南针,从90度开始,他们可以顺时针或逆时针旋转。如何最好地计算他们完成了多少个完整的360度旋转?假设他们从头到尾只会顺时针或逆时针旋转。
我想出的解决方案是,如果起始角度为90度,则当传感器数据发生变化时,持续检查下一个角度,如果一直往一个方向移动,就知道他们正在旋转。如果他们一直朝着同一个方向旋转,并回到了90度,那就算作完成了一次旋转。我的方法看起来非常复杂和低效,我很难想出更好的方法。
在这种情况下,我期望有多次完整的旋转。
我将会感激任何帮助。谢谢!
我找到了相关答案这里,并试图为此编写代码示例。如果有人已经做出类似的事情,请发布!
@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个回答

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
这是一个跟踪问题,读数会溢出。您需要跟踪最后一次读数,并希望用户在每次读数之间不要转动超过半圈...(因为Nyquist定理的原因)。
以下是基本的伪代码。
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;
}

没错。没有花哨的嵌入式代码。我会把我的生命托付给它。 - Michaël Roy

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
}

抱歉语法有误,这只是一个如何操作的示例。


0

想象一下我要说的话,你肯定很快就能达到目标。因为你不需要考虑整个360度,只需考虑其中的一半,并利用符号差异来获得优势。

看看这张图:

360 Rotation

我们有一个被分成两个部分(左边和右边)的圆。

左边将取负180度。(西侧)

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

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

如果指南针向正方向转动(即向右转动),

则每次转动时加上+1。

如果指南针向负方向转动(即向左转动),

则每次转动时减去-1。

如果指南针命中或为0,则它是当前位置(北)。

如果指南针命中或为90,则它是(东)。

如果指南针指向或达到180度,则为(南)。

如果指南针指向或达到-90度,则为(西)。

这将导致每当人向东走时,计数器将加1,直到达到180度。然后它将从正数变为负数,在每次转弯时减去1,直到达到0。那将是一个完整的360度旋转。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接