Skip to content

Commit 6918a03

Browse files
authored
Merge pull request #156 from sparkfun/release_candidate
Create Example31_Great_Circle_Distance.ino
2 parents 9bf4b41 + 1d62a8e commit 6918a03

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
Calculating the Great Circle Distance and Course to a target position
3+
By: Paul Clark
4+
SparkFun Electronics
5+
Date: September 21st, 2022
6+
License: MIT. See license file for more information but you can
7+
basically do whatever you want with this code.
8+
9+
This example shows how to query a u-blox module for its latitude/longitude and then
10+
calculate the Great Circle Distance and Course to a target location.
11+
12+
Thanks! distanceBetween and courseTo were taken from Mikal Hart's TinyGPSPlus:
13+
https://github.com/mikalhart/TinyGPSPlus/blob/ca29434514a5c5172bd807af0608df7f296582a2/src/TinyGPS%2B%2B.cpp#L285-L328
14+
15+
Note: Lat/Long are large numbers because they are degrees * 10^-7. To convert lat/long
16+
to something google maps understands simply divide the numbers by 10,000,000. We
17+
do this so that we don't have to use floating point numbers.
18+
19+
Feel like supporting open source hardware?
20+
Buy a board from SparkFun!
21+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
22+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
23+
SAM-M8Q: https://www.sparkfun.com/products/15106
24+
25+
Hardware Connections:
26+
Plug a Qwiic cable into the GNSS and a BlackBoard
27+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
28+
Open the serial monitor at 115200 baud to see the output
29+
*/
30+
31+
#include <Wire.h> //Needed for I2C to GNSS
32+
33+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
34+
SFE_UBLOX_GNSS myGNSS;
35+
36+
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
37+
38+
//#include <math.h> //Uncomment if required. May be needed for sqrt, atan2, etc..
39+
40+
double distanceBetween(long lat1_l, long long1_l, long lat2_l, long long2_l)
41+
{
42+
// returns distance in meters between two positions, both specified
43+
// as signed decimal-degrees latitude and longitude. Uses great-circle
44+
// distance computation for hypothetical sphere of radius 6372795 meters.
45+
// Because Earth is no exact sphere, rounding errors may be up to 0.5%.
46+
// Courtesy of Maarten Lamers
47+
double lat1 = (double)lat1_l / 10000000.0; // Convert lat and long to degrees
48+
double long1 = (double)long1_l / 10000000.0;
49+
double lat2 = (double)lat2_l / 10000000.0;
50+
double long2 = (double)long2_l / 10000000.0;
51+
double delta = radians(long1-long2);
52+
double sdlong = sin(delta);
53+
double cdlong = cos(delta);
54+
lat1 = radians(lat1);
55+
lat2 = radians(lat2);
56+
double slat1 = sin(lat1);
57+
double clat1 = cos(lat1);
58+
double slat2 = sin(lat2);
59+
double clat2 = cos(lat2);
60+
delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
61+
delta = sq(delta);
62+
delta += sq(clat2 * sdlong);
63+
delta = sqrt(delta);
64+
double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
65+
delta = atan2(delta, denom);
66+
return delta * 6372795;
67+
}
68+
69+
double courseTo(long lat1_l, long long1_l, long lat2_l, long long2_l)
70+
{
71+
// returns course in degrees (North=0, West=270) from position 1 to position 2,
72+
// both specified as signed decimal-degrees latitude and longitude.
73+
// Because Earth is no exact sphere, calculated course may be off by a tiny fraction.
74+
// Courtesy of Maarten Lamers
75+
double lat1 = (double)lat1_l / 10000000.0; // Convert lat and long to degrees
76+
double long1 = (double)long1_l / 10000000.0;
77+
double lat2 = (double)lat2_l / 10000000.0;
78+
double long2 = (double)long2_l / 10000000.0;
79+
double dlon = radians(long2-long1);
80+
lat1 = radians(lat1);
81+
lat2 = radians(lat2);
82+
double a1 = sin(dlon) * cos(lat2);
83+
double a2 = sin(lat1) * cos(lat2) * cos(dlon);
84+
a2 = cos(lat1) * sin(lat2) - a2;
85+
a2 = atan2(a1, a2);
86+
if (a2 < 0.0)
87+
{
88+
a2 += TWO_PI;
89+
}
90+
return degrees(a2);
91+
}
92+
93+
void setup()
94+
{
95+
Serial.begin(115200);
96+
while (!Serial); //Wait for user to open terminal
97+
Serial.println("SparkFun u-blox Example");
98+
99+
Wire.begin();
100+
101+
//myGNSS.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
102+
103+
if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
104+
{
105+
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
106+
while (1);
107+
}
108+
109+
myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
110+
myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
111+
}
112+
113+
void loop()
114+
{
115+
//Query module only every second. Doing it more often will just cause I2C traffic.
116+
//The module only responds when a new position is available
117+
if (millis() - lastTime > 1000)
118+
{
119+
lastTime = millis(); //Update the timer
120+
121+
long latitude = myGNSS.getLatitude();
122+
Serial.print(F("Lat: "));
123+
Serial.print(latitude);
124+
125+
long longitude = myGNSS.getLongitude();
126+
Serial.print(F(" Long: "));
127+
Serial.print(longitude);
128+
Serial.println(F(" (degrees * 10^-7)"));
129+
130+
static const long TARGET_LAT = 400909142, TARGET_LON = -1051849833; // SparkFun's location: degrees * 10^-7 (40.091 N, 105.185 W)
131+
132+
double distanceToTarget = distanceBetween(
133+
latitude,
134+
longitude,
135+
TARGET_LAT,
136+
TARGET_LON);
137+
138+
Serial.print(F("Distance to target: "));
139+
Serial.print(distanceToTarget, 2);
140+
Serial.print(F(" (m) "));
141+
142+
double courseToTarget = courseTo(
143+
latitude,
144+
longitude,
145+
TARGET_LAT,
146+
TARGET_LON);
147+
148+
Serial.print(F("Course to target: "));
149+
Serial.print(courseToTarget, 1);
150+
Serial.println(F(" (degrees)"));
151+
}
152+
}

0 commit comments

Comments
 (0)