Course Is Always 87

Hello, thanks for reading my post.

I am attempting to build a gps guided robot, this was my starting point: https://www.instructables.com/id/How-to-Build-a-GPS-Guided-Robot/

My project is almost entirely the same as this instructable except I am using a QMC magnetometer and a goouuutech GT-U7 GPS. It is essentially the same as U-blox7, or at least that's what goouuutech claims.

I am using tinyGPS++'s courseTo function, but for some reason it will only return 87. No matter where the waypoints, or the starting points, it only returns 87.

Attached you will find the code for the robot, if you want wiring diagrams or for me to upload the library I can do that as well.

My best guess as to what's causing the problem is the math behind courseTo, but it looks kosher to me. I haven't been able to find anyone else with a similar problem, and the tinyGPS++ documentation isn't very helpful.

I really appreciate any help, thank you.

Bluetooth.ino (4.34 KB)

Collision_Avoid.ino (1.22 KB)

Go_Waypoint.ino (4.01 KB)

GPS_Compass.ino (7.71 KB)

GPS_Guided_RobotWORKS.ino (8.37 KB)

Startup.ino (1.33 KB)

Steering.ino (14.6 KB)

Sweep.ino (1.05 KB)

The courseTo function works as advertised, if used correctly.

Get TinyGPS++ working on its own, and test the courseTo function with example data, before including ANY of the TinyGPS++ code in your robot project.

If you run into problems with getting TinyGPS++ to work, post again.

Thanks for your advice remington, but I am unsure of how to proceed.

I got it to work in the device example with just static numbers, but I do not understand why/how.

Here is the working example code:

#include <TinyGPS++.h>

int GPScourse;

// The TinyGPS++ object
TinyGPSPlus gps;

void setup()
{
  Serial.begin(115200);

}
int x = 15.850125;
int y = -93.762358;
void loop()
{
GPScourse = TinyGPSPlus::courseTo(44.843022, -93.760428, x, y);
Serial.println(GPScourse);
}

The only difference I see here are that I am using non-static variables in the one that doesn't work, but I feel like I am missing something obvious.
The one that doesn't work:

 GPS_Course = TinyGPSPlus::courseTo(
  gps.location.lat(),
  gps.location.lng(),
  Home_LATarray[ac],
  Home_LONarray[ac]);                               //Query Tiny GPS for Course to Destination

Thanks in advance for any help.

You need to be using float variables, not integers!

int x = 15.850125;
int y = -93.762358;

If you want help with your code, always post ALL of it. Snippets are useless.

Thanks for the tip, but I'm confused- that's the one that works, I guess I'll be looking into int vs float.
Just googled it- what a dumb mistake lol.
And I posted all of the code earlier, so I figured I would just snippet the part that I changed. Here it is in all of it's buggy glory.

"To make a float or floating-point number, a computer uses two integer numbers. It uses one integer as the mantissa and the other as the exponent. Computers use floats for calculations involving very large, very small or fractional values. In other words the set of real numbers. Computers can not count very well using floats. Computer can not even compare two floats very well. That is to say, you may get different results from different computers when testing if two different floats are the same or not. This is due to rounding error."
Just read this on stack-exchange, is this going to be a problem for finding a course/heading? It seems like it would be given that all it is is comparing a couple of floats.

Reading up on floating point arithmetic now- am I heading in the right direction or just on a tangent?
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Bluetooth.ino (4.34 KB)

Collision_Avoid.ino (1.22 KB)

Go_Waypoint.ino (4.02 KB)

GPS_Compass.ino (7.71 KB)

GPS_Guided_RobotWORKS.ino (8.37 KB)

Startup.ino (1.33 KB)

Steering.ino (14.6 KB)

Sweep.ino (1.05 KB)

Again, get the TinyGPS++ courseTo example working properly before worrying about the rest of your code.

Ok so I got another program to work, here it is.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample code demonstrates just about every built-in operation of TinyGPS++ (TinyGPSPlus).
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

// The TinyGPS++ object
TinyGPSPlus gps;


// For stats that happen every 5 seconds
unsigned long last = 0UL;

void setup()
{
  Serial.begin(115200);
  Serial3.begin(9600);
}

void loop()
{
  // Dispatch incoming characters
  while (Serial3.available() > 0)
    gps.encode(Serial3.read());


    Serial.println();
    if (gps.location.isValid())
    {
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
      double distanceToLondon =
        TinyGPSPlus::distanceBetween(
          gps.location.lat(),
          gps.location.lng(),
          LONDON_LAT, 
          LONDON_LON);
      double courseToLondon =
        TinyGPSPlus::courseTo(
          gps.location.lat(),
          gps.location.lng(),
          LONDON_LAT, 
          LONDON_LON);

      Serial.print(F("LONDON     Distance="));
      Serial.print(distanceToLondon/1000, 6);
      Serial.print(F(" km Course-to="));
      Serial.print(courseToLondon, 6);
      Serial.print(F(" degrees ["));
      Serial.print(TinyGPSPlus::cardinal(courseToLondon));
      Serial.println(F("]"));
    }


    if (gps.charsProcessed() < 10)
      Serial.println(F("WARNING: No GPS data.  Check wiring."));

    last = millis();
    Serial.println();
  
}

I'm not sure how this differs in a meaningful way from the program in my original post..

To understand the difference, you need to go through both programs line by line, understanding the purpose and effect of each line.

There are no shortcuts.

Ok, I can understand that, but I don't really see a difference between these two sections of code.

 double courseToLondon =
        TinyGPSPlus::courseTo(
          gps.location.lat(),
          gps.location.lng(),
          LONDON_LAT, 
          LONDON_LON);
GPS_Course = TinyGPSPlus::courseTo(
  gps.location.lat(),
  gps.location.lng(),
  Home_LATarray[ac],
  Home_LONarray[ac]);

I've already poured over the LATarray and LONarray section, and it seems to me that it should work fine, so I assume I am missing something obvious/something I've never heard of.

I assume the rest of the GPSrobot code wouldn't affect it unless it defines one of the variables or something like that, am I wrong there and need to look through seemingly(at least to me) unrelated code to find the issue?

And thanks for your quick reply- I really appreciate all the help so far.

One difference I see is that the variables in CourseToLondon are static constant doubles, where as in the GPSrobot it is an array, could that be it?

There is a huge difference between those two snippets, but since you did not post all of your current code, it is impossible to know what the consequences of those differences are.

What, exactly is the value of "ac" and what, exactly, is contained in the array element identified by "Home_LATarray[ac]"?