Pages: [1]   Go Down
 Author Topic: Help me break this mental block--degrees to heading  (Read 302 times) 0 Members and 1 Guest are viewing this topic.
Offline
Newbie
Karma: 0
Posts: 36
 « on: March 14, 2013, 12:51:04 am » Bigger Smaller Reset

For some reason I simply can't get past this simple problem. I'm using a compass to maintain  heading hold. When I press a button it reads the current value in degrees (int holdHeading) and then steers to maintain that heading. Since the compass output is degrees I need to convert each new reading (int currentHeading) into a servo position (int headingError) to steer back to the heading. Simple enough, but when you get in the vicinity of 360 degrees things get messy.

If holdHeading is 359 and currentHeading is 10 then headingError should be 11
if holdHeading is 10 and currentHeading is 359 then headingError should be -11

more simply:
is holdHeading is 180 and currentHeading is 170 then headingError should be -10
if holdHeading is 170 and currentHeading is 180 then headingError should be 10

I'm going to restrict the servo movement to some value like 60 to 120 with 90 being the centered position, but I know how to do that. It's this silly degrees thing that driving me nuts. I seem to have a mental block preventing me from solving something that seems pretty simple.
 Logged

Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
 « Reply #1 on: March 14, 2013, 01:23:32 am » Bigger Smaller Reset

If holdHeading is 359 and currentHeading is 10 then headingError should be 11
if holdHeading is 10 and currentHeading is 359 then headingError should be -11
The calculations are easier to deal with if you convert heading into the +/- 180 degree range. 359 (from your example) then becomes -1 and so headingError is a simple difference:

headingError = -1 - 10 = -11
headingError = 10 - (-1) = 11

For display and input however you may want to keep the 0-360 range and convert accordingly, but stick to -180 to 180 internally.
 Logged

Global Moderator
Dallas
Online
Shannon Member
Karma: 129
Posts: 10383
 « Reply #2 on: March 14, 2013, 01:30:46 am » Bigger Smaller Reset

Negative headingError means go right.

Positive headingError means go left.

Quote
If holdHeading is 359 and currentHeading is 10 then headingError should be 11

headingError = 10 - 359

From 10 degrees go right 349 degrees to get to 359.  This is correct.  Obviously, you'd prefer to take the shorter route.

Code:
if ( headingError < -180 )
{
}

headingError = 359 - 10

From 359 degrees go left 349 degrees to get to 10.  This is correct.  Obviously, you'd prefer to take the shorter route.

Code:
if ( headingError > +180 )
{
}
 Logged

Offline
Newbie
Karma: 0
Posts: 36
 « Reply #3 on: March 14, 2013, 02:32:43 am » Bigger Smaller Reset

Thank you, thank you. I was literally banging my head against the wall.
 Logged

UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
 « Reply #4 on: March 14, 2013, 09:39:28 am » Bigger Smaller Reset

Code:
if ( headingError > +180 )
{
}

Don't you mean headingError = headingError - 360?
 Logged

Global Moderator
Dallas
Online
Shannon Member
Karma: 129
Posts: 10383
 « Reply #5 on: March 14, 2013, 12:15:41 pm » Bigger Smaller Reset

Yup...

Code:
if ( headingError < -180 )
{
}

if ( headingError > +180 )
{
}
 Logged

UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
 « Reply #6 on: March 14, 2013, 07:43:08 pm » Bigger Smaller Reset

This feels like the sort of situation where expressions like this come in handy:

heading = ((heading + 360 + 180) % 360) -180;
 Logged

Offline
God Member
Karma: 3
Posts: 992
Arduino rocks
 « Reply #7 on: March 15, 2013, 02:58:24 pm » Bigger Smaller Reset

Yup...

Code:
if ( headingError < -180 )
{
}

if ( headingError > +180 )
{
}

Why insist on making this a lot more difficult than it is. Convert to -180 +180 and you're good to go.