I am posting this in "Project Guidance" however it may also apply to the "Programming" topic. I hope chose the correct forum. I'm seeking direction for how to accomplish the following:
I'm attempting to prototype a device that will assist in defining braking points on a race track. I plan to use four LEDs that will each light up as I get closer to the apex of a corner.
For example, I know the apex of corner 5 is at 53.333017, -113.598626. I want my first LED to light up when I am approaching 100 meters of the apex, the second LED will light at 80 meters, the third at 60 meters and the fourth at 40 meters.
In layman's terms, I'm thinking the sketch needs to look something like:
Corner FIVE = 53.333017, -113.598626
LED1 HIGH = 53.333017, -113.598626 - 100 m
LED2 HIGH = 53.333017, -113.598626 - 80 m
LED3 HIGH = 53.333017, -113.598626 - 60 m
LED4 HIGH = 53.333017, -113.598626 - 40 m
All LED LOW = 53.333017, -113.598626
Corner SIX = 53.332372, -113.600113
LED1 HIGH = 53.332372, -113.600113 - 100 m
LED2 HIGH = 53.332372, -113.600113 - 80 m
LED3 HIGH = 53.332372, -113.600113 - 60 m
LED4 HIGH = 53.332372, -113.600113 - 40 m
All LED LOW = 53.332372, -113.600113
I am using an Arduino Nano and Ublox NEO-6M GPS module to retrieve my current location.
Questions:
Is my base thinking correct? Is there a better way to go about accomplishing my goal?
Can someone guide me in the coding of my IF statement to have an LED go on when I am within a certain distance (in meters or feet) of a GPS corrdinate?
How can I only have the LEDs light up as I am approaching the apex and remain off as I am leaving the apex?
Also plan on occasional, very large positional errors in GPS coordinates (50 meters or more), as well as possible complete failure of the GPS to determine position.
Now you have selected hardware, the next step is to select a library. TinyGPS is pretty good. I think it has functions for calculating distance. Or find a library that does.
Get the most-basic library example working, to demonstrate that the hardware is connected properly.
With that on board, you can start thinking about how to store and retrieve your corners.
@UKHeliBob, I am updating GPS coordinates at 5 hertz. I'd like more but I don't think the Ublox will allow it.
As a general note, this project is to help identify physical braking points. I am aware that there can be failures in the system and so this "tool" can't be trusted 100%. I'd like to see how close I can get to making it work. Maybe it won't be practical in the end.
void fCalDistance()
{
// if previous is zero then seed
if ( lGPS_Lat0 == 0 )
{
lGPS_Lat0 = fDegreeToDecimal( GPS.latitudeDegrees );
lGPS_Lon0 = fDegreeToDecimal( GPS.longitudeDegrees );
}
long tempLat = fDegreeToDecimal( GPS.latitudeDegrees );
long tempLon = fDegreeToDecimal( GPS.longitudeDegrees );
//
//add new distance to previous distance, meters to mile* 0.00062137
floatDistance = floatDistance + ( DistanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon) * 0.00062137 );
//reset to last used measuring point
lGPS_Lat0 = tempLat;
lGPS_Lon0 = tempLon;
// }
}// end void fCalDistance()
unsigned int CosFix (long angle)
{
long u = labs(angle) >> 16;
u = (u * u * 6086) >> 24;
return 246 - u;
} // unsigned int CosFix (long angle)
long Diff (long deg1, long deg2)
{
long result = deg2 - deg1;
if (result > 180 * DEGREE) return result - 360 * DEGREE;
else if (result < -180 * DEGREE) return result + 360 * DEGREE;
else return result;
} // long Diff (long deg1, long deg2)
//calculates distance between 2 points . using lat/lon. ignores earth curve, valid for distances of several 100K, returns meters
//www.technoblogy.com/show?LNQ
unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
{
long dx = (Diff(long2, long1) * CosFix((lat1 + lat2) / 2)) / 256;
long dy = Diff(lat2, lat1);
unsigned long adx = labs(dx);
unsigned long ady = labs(dy);
unsigned long b = max(adx, ady);
unsigned long a = min(adx, ady);
if (b == 0) return 0;
return 95 * (b + (110 * a / b * a + 128) / 256) / 512;
} // unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
long fDegreeToDecimal(long floatDegree)
{
return floatDegree * 60 * 10000;
} // long fDegreeToDecimal(long floatDegree)
//This returns 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, or 7=NW.
int Cardinal (unsigned int dir) {
return (((dir * 2 + 45) / 90) & 7);
}
//*****************************************************************************************
I used the code on a Mega, Due, STM32, and ESP32.
I now use the tinyGPS++ which has a calculate distance as a built in function.
bneuf: @UKHeliBob, I am updating GPS coordinates at 5 hertz. I'd like more but I don't think the Ublox will allow it.
At 60 mph or 88ft per second your car would travel 22ft between updates - that's about 7 metres. And the car might be going a lot faster.
Braking 7 metres too early or too late is not how you win races.
Concentrating within the cockpit waiting for an LED to light up is not how you win races.
(IMHO)
I'm not a great Grand Prix fan but there was a memorable race years ago (in S. America I think) where the race started using rain tyres on a very wet track. As the track dried out Schumacher was faster on every lap. How was he able to know how much extra grip he could get on the drying, but still very wet track.