Saturday, June 24, 2017

Compass - Track number of full 360 degree rotations

Leave a Comment

Suppose a person is using this compass, and beginning from 90 degrees they start rotating either clockwise or counterclockwise. What's the best way to keep count of how many full 360 degree rotations they complete? Assuming they'll be rotating either only clockwise or only counterclockwise from beginning to end.

I kept coming up with solutions where if the beginning bearing is, for example, 90 degrees I keep checking the next bearing when the sensor data changes, and if it's consistently moving in one direction I know they're rotating. And if they keep rotating in that direction and make it back to 90 degrees, that counts as one rotation. My way seems very convoluted and inefficient and I'm having a hard time coming up with a better way.

In this scenario, I'd be expecting multiple full rotations.

I'd appreciate any help. Thank you!

I found this related answer and am trying to put together a code sample for that. If someone has already done something similar, please post it!

@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 Answers

Answers 1

If you're sure that they'll be moving in only 1 direction, to optimize your code you can have checkpoints for degrees instead of continuously monitoring if they're still moving in the right direction.

Here's a rough algo to do that

//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  

I don't have any code handy at the moment.

Answers 2

Create 3 integers

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

not a java programmer so i dont know how you handle the onSensorChanged event but basically perform a check within a while loop

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 } 

sorry about the syntax, this is just an example of how to do so..

Answers 3

This is a tracking problem with a reading that overflows. You need to keep track of the last reading and hope the user doesn't do more than a half turn between each reading.... (because of the Nyquist theorem)

Here is the basic pseudo code.

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; } 

Answers 4

Visualize what I will say and you'll definitely hit your goal in no time. As you don't need to think of the full 360 degree, but you can take half of that and use the signs differences to your advantage.

Take a look at this figure : 360 Rotation

We have a circle that is divided to two sides (left and right).

The left side will take negative 180 degree. (West Side).

The right side will take positive 180 degree. (East Side).

Current positing will be always 0 as (North) and positive 180 as (South).

IF the compass goes positive (meaning goes to the right direction)

Then add +1 on each turn.

IF the compass goes negative (meaning goes to the left direction).

Then subtract -1 on each turn

IF the compass hit OR is 0, then it's current position (NORTH).

IF the compass hit OR is 90, then it's (East).

IF the compass hit OR is 180, then it's (South)

IF the compass hit OR is -90, then it's (West).

This will turn out that whenever the person goes East, the counter will add +1 until it reaches 180, Then it'll change from positive to negative, which will subtract -1 on each turn until it reaches 0. That would be a full 360 rotation.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment