0

I've been searching for a while but haven't found exactly what I'm looking for.

I'm working on an app that will go in a race car. It will give the driver the ability to press a button to mark a Start/Finish line. It will also have a button to allow a driver to set segment times.

Keep in mind a track can be an oval which I'm working on first. It could be a road course or it could be an auto cross where the start and finish line aren't the exact same location. They could be with 50 feet of each other or so but the car never crosses where it starts.

I have my gps data coming in and I convert the NMea messages to my classes and I store Lat, Lon, Speed, Course etc. In my research I've ran across this which is interesting. The GPS will be mounted outside the roof for better signal. It generates 10 hits per second. (Garmin Glo)

http://www.drdobbs.com/windows/gps-programming-net/184405690?pgno=1

It's old but it talks about UTM and the Cartesian coordinate system. So using the DecDeg2UTM, I convert Lat & Lon to X & coordinates as well.

I've also been trying to use the Intersect formula I found Here I took the intersect and tried to convert it to C# which I'll post at the end. However, feeding coordinates of an oval track, it doesn't seem to be working. Also, I'm not sure exactly what it's supposed to be doing. But the coordinates it returns when it does somethign like -35.xxx & 98.xxxx which out in an ocean somewhere 1000's of miles from where the track is.

I looking for answers to the following.

  1. I assume I need to take the location recorded when a button is pressed for Start/Finish or Segment and calculate a line perpendicular to the direction the car in able to be able to do some sort of Line Intersection calculation. The Cartesian coordinates seems to calculate the bearing fairly well. But the question here is how do you get the "left and right coordinates". Also, keep in mind, an oval track may be 60 feet wide. But as mentioned an auto cross track may only be 20 ft wide and part of the track may be with 50 ft. Note I'm fine with indicating to set the points, the car needs to be going slow or stopped at the points to get an accurate coordinate. Some tracks they will have to be set while walking the track.
  2. Based on this, should I be trying to use decimal lat lon or would utilizing the Cartesian coordinate system based on UTM be a more accurate method for what I'm trying to do?
  3. Either one is there a .Net library or C based library with source code that has methods for making these calculations?
  4. How can this be accurately handled. (Not that great with Math, links to code samples would help tremendously.)
  5. Next, after I have the lines or whatever is needed for start/finish and segments, as I get GPS sign from the car racing, I need to figure out the most accurate way to tell when a car has crossed those segments. again if I'm lucky I'll get 10 hits per second but it will probably be lower. Then the vehicle speeds could vary significantly depending on the type of track and vehicle. So the GPS hit could be many feet "left or right" of a segment. Also, it could be many feet before or after a segment.

Again, if there is a GIS library out there I can feed coordinates and all this is calculated, that's would work as well as long as it's performant. If not again I'm trying to decide if it's best to break down coordinates to X Y or some geometry formulas for coordinates in decimal format. Mods, I assume there is hard data to support an answer of either way and this isn't responses aren't fully subjective to opinions.

Here is the C# code I came up with from the Script page above. I'm starting to feel UTM and the Cartesian Coordinate system would be better for accuracy and performance. But again I'm open to evidence to the contrary if it exists.

Thanks

P.S. Note GeoCoordinate is from the .Net System.Device.Location assemble. GpsData is just a class I use to convert NMEA messages into Lat, Lon, Course, NumSats, DateTime etc.

The degree Radian methods are extensions as as follows.

public static double DegreeToRadians(this double angle)
    {
        return Math.PI * angle / 180.0;
    }

    public static double RadianToDegree(this double angle)
    {
        return angle * (180.0 / Math.PI);
    }
}

 public static GeoCoordinate CalculateIntersection(GpsData p1, double brng1, GpsData p2, double brng2)
    {
        // see http://williams.best.vwh.net/avform.htm#Intersection

        // Not sure I need to use Cosine
        double _p1LatRadians = p1.Latitude.DegreeToRadians();
        double _p1LonToRadians = p1.Longitude.DegreeToRadians();
        double _p2LatToRadians = p2.Latitude.DegreeToRadians();
        double _p2LonToRadians = p2.Longitude.DegreeToRadians();
        double _brng1ToRadians = brng1.DegreeToRadians();
        double _brng2ToRadians = brng2.DegreeToRadians();
        double _deltaLat = _p2LatToRadians - _p1LatRadians;
        double _deltaLon = _p2LonToRadians - _p1LonToRadians;

            var _var1 = 2 * Math.Asin(Math.Sqrt(Math.Sin(_deltaLat / 2) * Math.Sin(_deltaLat / 2)
                + Math.Cos(_p1LatRadians) * Math.Cos(_p2LatToRadians) * Math.Sin(_deltaLon / 2) * Math.Sin(_deltaLon / 2)));

            if (_var1 == 0) return null;

            // initial/final bearings between points
            var _finalBrng = Math.Acos((Math.Sin(_p2LatToRadians) - Math.Sin(_p1LatRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p1LatRadians)));
            //if (isNaN(θa)) θa = 0; // protect against rounding

            var θb = Math.Acos((Math.Sin(_p1LatRadians) - Math.Sin(_p2LatToRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p2LatToRadians)));

            var θ12 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? _finalBrng : 2 * Math.PI - _finalBrng;
            var θ21 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? 2 * Math.PI - θb : θb;

            var α1 = (_brng1ToRadians - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3
            var α2 = (θ21 - _brng2ToRadians + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3

            if (Math.Sin(α1) == 0 && Math.Sin(α2) == 0) return null; // infinite intersections
            if (Math.Sin(α1) * Math.Sin(α2) < 0) return null;      // ambiguous intersection

            α1 = Math.Abs(α1);
            α2 = Math.Abs(α2);
            // ... Ed Williams takes abs of α1/α2, but seems to break calculation?

            var α3 = Math.Acos(-Math.Cos(α1) * Math.Cos(α2) + Math.Sin(α1) * Math.Sin(α2) * Math.Cos(_var1));
            var δ13 = Math.Atan2(Math.Sin(_var1) * Math.Sin(α1) * Math.Sin(α2), Math.Cos(α2) + Math.Cos(α1) * Math.Cos(α3));
            var _finalLatRadians = Math.Asin(Math.Sin(_p1LatRadians) * Math.Cos(δ13) + Math.Cos(_p1LatRadians) * Math.Sin(δ13) * Math.Cos(_brng1ToRadians));
            var _lonBearing = Math.Atan2(Math.Sin(_brng1ToRadians) * Math.Sin(δ13) * Math.Cos(_p1LatRadians), Math.Cos(δ13) - Math.Sin(_p1LatRadians) * Math.Sin(_finalLatRadians));
            var _finalLon = _p1LonToRadians + _lonBearing;

        var _returnLat = _finalLatRadians.RadianToDegree();

        var _latToDegree = _finalLon.RadianToDegree();
        var _returnLon = ( _latToDegree + 540) % 360 - 180;

        return new GeoCoordinate(_returnLat, _returnLon);
        //return new LatLon(φ3.toDegrees(), (λ3.toDegrees() + 540) % 360 - 180); // normalise to −180..+180°

    }
kfrosty
  • 805
  • 1
  • 8
  • 14
  • GPS latitude is +/-162000000 where the min/max is 90 degrees (north and south poles). GPS longitude is +/- 324000000 where zero is GMT and min/max is 180 degrees. You can get location by a simple fraction. I think the complex formula you are using is to correction for poles being flat. – jdweng Sep 12 '17 at 14:09
  • Not sure what you're trying to say. The values you list appear to be easting and northing. Are you trying to say using Cartesian's coordinate would be more performant and better to calculate than the decimal based formula I posted. (Not mine just found it online in javascript and tried converting it.) Also, what are the simple formulas creating a line out of a point making sure that the line is perpendicular with the direction of the track? Also, is there a simple line intersection formula as well? – kfrosty Sep 12 '17 at 15:10
  • Just saying it is simpler. You still would need the direction component from GPS or compass. – jdweng Sep 12 '17 at 15:24
  • Ok, I welcome simpler but can't sacrifice accuracy. With the Cartesian coordinates, direction seems to be easy with bearing. I have that. (GPS provides course but I've heard that can be inconsistent. The bearing code in http://www.drdobbs.com/windows/gps-programming-net/184405690?pgno=1 seems to be accurrate. Even the distance method seems to work. I say that because I took a dirt track, Cherokee Speedway, SC and google maps. I went and manually took 34 coordinates around the track, verified heading via google earth and everything looks to be real close. So now I need to do: – kfrosty Sep 12 '17 at 16:38
  • A car pushes the finish line button at 35.107330, -81.597926 I will know they are traveling 137 degrees. So easting = 445509.26634695457 northing = 3885109.1815783232 bearing 139 car is traveling on the track at the finish line. The bearing from inside wall to outside wall at these coordinates is approx 225. So what's the formula for coming up with a line that can be used when a car crosses. – kfrosty Sep 12 '17 at 17:34
  • Then when a car is traveling on track, you get a hit before the finish line of say 35.107449, -81.598128 bearing 138 then you get the next hit after the finish line which is 35.107224, -81.597847 – kfrosty Sep 12 '17 at 17:35
  • What angle is the finish line and length? I guess you have a geometry problem? You are trying to find where two lines intersect. The car traveling vector and the finish line. – jdweng Sep 12 '17 at 17:37
  • Above are actually track coordinates that can be viewed in Google Maps. https://www.google.com/maps/place/35%C2%B006'26.0%22N+81%C2%B035'52.3%22W/@35.107224,-81.5983942,211m/data=!3m2!1e3!4b1!4m6!3m5!1s0x0:0x0!7e2!8m2!3d35.1072239!4d-81.597846935.107330, -81.597926 is the finish line, cars will be traveling bearing 137 degrees. – kfrosty Sep 12 '17 at 17:46
  • Does that mean the finish line is perpendicular at 47 degrees (137 - 90)? So you have two intersecting lines to determine when the race ends? – jdweng Sep 12 '17 at 18:07
  • The car is traveling at 137, if you measure from the inside wall to the outside wall, the bearing is 235ish. So the line could be running 47 or 237 just depending if the car is straight or setting up for the first turn. just depending on how you want to look at it. But the concept if you pull up the coordinates in google maps, imagine a car driving around the track, it sets a finish line then any other segments it want's timed. You have X Y & bearing. Then I'll track XY on every gps hit storing the previous 1 or 2 to easily form a line then how to calculate the precise intersection – kfrosty Sep 12 '17 at 19:56
  • It is an intersection of two vectors (two lines). One vector is the the end line and direction. Second vector is car position and direction. – jdweng Sep 12 '17 at 21:54
  • so where are the simple calculations. You haven't stated anything I don't know but the reason for this post, I see all these it's simple this or that but no constructive responses. That's the reason for this post so hopefully when this is figured out, and there are .Net endpoints to calculate a line from a coordinate and heading and then line intersection code, this will be easier for anybody else with ideas that don't want to waste a ton of time on the math and get on to the problems the apps can solve. Thanks – kfrosty Sep 12 '17 at 22:49

0 Answers0