orst
orst

Reputation: 23

How to develop to-point moving algorithm using Gps and compass

I am trying to develop an alghoritm for controlling the rudder of the boat... I got lost in geo algoritms... Function Does not work corectly.

direction WhereToMove(double CurrentLatitude, double CurrentLongitude, double TargetLatitude, double TargetLongitude, double azimuth) {
        double azimuthHysteresis = 5; //straight if the deviation is less than 5 degrees
        double pi = 2 * asin(1.0);
        double target = atan2(TargetLatitude - CurrentLatitude, TargetLongitude - CurrentLongitude) * 180 / pi;
        double delta = azimuth - target;
        if (delta > 180) delta -= 360;
        if (delta < -180) delta += 360;
        if (delta < -2) { 
            return right;
        }
        if (delta > 2) {
            return left;
        }
        return straight; // go straight
    }

Upvotes: 0

Views: 169

Answers (2)

orst
orst

Reputation: 23

Final version

direction WhereToMove(double CurrentLatitude, double CurrentLongitude, double TargetLatitude, double TargetLongitude, double azimuth) {
    double azimuthHysteresis = 2; //straight if the deviation is less than 2 degrees
    double target = atan2(remainder(TargetLongitude - CurrentLongitude, 360.0), remainder(TargetLatitude - CurrentLatitude, 360.0)) * 180 / M_PI;
    double delta = remainder(azimuth - target, 360.0);
    double deltaModule = sqrt(delta * delta);
    if (deltaModule <= azimuthHysteresis) //deviation is small go straight
    {
        return straight;
    }
    if (delta <= -azimuthHysteresis) {
        return right;
    }
    if (delta >= azimuthHysteresis) {
        return left;
    }
    return straight; // go straight
}

Upvotes: 1

dmuir
dmuir

Reputation: 4431

A few points:

You could use the constant M_PI for pi

I would imagine you want your angles to be measured clockwise from north. atan2 gives an angle counter clockwise from the x axis. This is simple to fix, use

atan2( dLon, dLat) 

instead of

atan2( dLat, dLon) 

The distance represented by a degree of longitude is, roughly, cos(lat) times the distance represented by a degree of latitude. So you should scale your dlon in the above by cos( M_PI/180.0 * lat). (cos, like all the math functions that deal in angles, takes radians as an argument).

You could simplify computing the difference of azimuth and target by using the math library function remainder, as in

delta = remainder( azimuth-target, 360.0)

this will give a delta between -180 and 180

I don't know if your code will ever be used near 180E. I'd say you should compute the difference in longitudes as if it might, ie use

remainder( TargetLongitude - CurrentLongitude, 360.0)

instead of

TargetLongitude - CurrentLongitude

This might seem OTT, but I've found (the hard way) that its much easier to get into the habit of always computing the difference of longitudes this way than to track down everywhere in the code that such differences are taken when your code is used across 180E.

Upvotes: 2

Related Questions