Page 1 of 1

Algorithm for calculating relative compass heading

Posted: 12 Dec 2010, 06:48
by loopymech
Does anyone have a good code example for calculating the relative compass heading in NXC or pseudo-code? I am looking for a clean function or driver that provides the equivalent to the Relative Heading output available with the NXT-G HT compass block.

Here's is a working bit of code that I have made in NXC to do pivot turns (heading corrections), but I am sure much smarter people have come up with a simpler, cleaner way to do this. Please feel free to provide critique and/or other feedback.

Cheers!
-Loopy

Code: Select all


task move()
{
  while (true){
// calculate relative heading and use Proportional correction to pivot
// towards target heading..."relative_heading" is equal to the angle
// difference between "target_heading" and current compass heading
    while (abs(target_heading - Compass_val) > 1){
     if (target_heading - Compass_val < -179){
        relative_heading = target_heading - Compass_val + 360;
     }
     else{
        relative_heading = target_heading - Compass_val;
     }
// calculate pivot direction, always taking shortest CW or CCW path
     if (relative_heading < 0){
        steer = -100;
     }
     else{
        steer = 100;
     }
// set pwr for use in OnFwdSync
     pwr = abs(relative_heading);
// limit min/max pwr (to prevent stalls and whirling dervish spins)
     if (pwr > 35)
     {
        pwr=35;
     }
          if (pwr < 15)
     {
        pwr=15;
     }
// do the needful (make the pivot turn)
     OnFwdSync(OUT_BC, pwr, steer);
    }
// stop, wait and set new "target_heading" (new target heading)
    Off(OUT_BC);
    Wait(3000);
    target_heading=target_heading+90;
// limit target heading to 0->359 deg
    if (target_heading > 359)
    {
      target_heading = 0;
    }
  }
}


Re: Algorithm for calculating relative compass heading

Posted: 13 Dec 2010, 01:50
by hassenplug
There are a couple things about your code that may (or may not) be desirable. Mainly, that the robot is either turning 100%, or driving straight. Smaller turns may be a good idea. Here's some psudo-code:

rel = target - compass
// rel = -360 to +360
if (rel < -180) rel += 360
if (rel > 180) rel -= 360
// rel = -180 to +180
steer = rel * 50 / 180
// steer = -50 to +50
// changing the 50 will adjust how sharp it tries to correct.

How's that?
Steve

Re: Algorithm for calculating relative compass heading

Posted: 14 Dec 2010, 02:06
by loopymech
Thanks, Steve. That looks really clean and straightforward. I'll give it a try.

For this bit of code, I was intending to do pivot turns with steering at +/-100, as this will likely go into a larger program to trace a square path as accurately as possible.

-Loopy

Re: Algorithm for calculating relative compass heading

Posted: 14 Dec 2010, 16:52
by hassenplug
hassenplug wrote:rel = target - compass
// rel = -360 to +360
if (rel < -180) rel += 360
if (rel > 180) rel -= 360
// rel = -180 to +180
steer = rel * 50 / 180
// steer = -50 to +50
// changing the 50 will adjust how sharp it tries to correct.
To make it turn sharper, try this:
turnspeed = 200 // increasing this will speed up the adjustment
rel = target - compass
// rel = -360 to +360
if (rel < -180) rel += 360
if (rel > 180) rel -= 360
// rel = -180 to +180
steer = rel * turnstpeed / 180
if (steer<-100) steer = -100
if (steer>100) steer = 100

with turnspeed = 200, the robot should spin (pivot) until it's about 90 degrees away, then it will start to slow down. At about 45 degrees, one wheel will be stopped, while the other is turning 100%

Steve