/* If all waypoints are with a 20m radius of their centre consider there to be no movement */ private bool HaveWaypointsMoved() { float averageLat = Waypoints.Average(info => info.Lat); float averageLng = Waypoints.Average(info => info.Lng); foreach (var waypoint in Waypoints) { if (GPRMCInfo.Haversine(averageLat, averageLng, waypoint.Lat, waypoint.Lng) > 20) { return(true); } } return(false); }
/* Attempt to parse te NMEA message using regular expressions */ public static GPRMCInfo Parse(string gprmc) { Regex regex = new Regex(@"\$GPRMC,(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)"); Match match = regex.Match(gprmc); if (match.Success) { if (match.Groups.Count < 11) { return(null); } var time = match.Groups[1].Value; var status = match.Groups[2].Value; var lat = match.Groups[3].Value; var latDirection = match.Groups[4].Value; var lng = match.Groups[5].Value; var lngDirection = match.Groups[6].Value; var speed = match.Groups[7].Value; var trackAngle = match.Groups[8].Value; var date = match.Groups[9].Value; var magneticVariation = match.Groups[10].Value; var checksum = match.Groups[11].Value; GPRMCInfo result = new GPRMCInfo(); try { result.Date = DateTime.ParseExact(date + time, "ddMMyyHHmmss.ff", CultureInfo.InvariantCulture); result.Lat = ParseCoord(lat) * (latDirection == "N" ? 1 : -1); result.Lng = ParseCoord(lng) * (lngDirection == "E" ? 1 : -1); result.Speed = float.Parse(speed) * 0.514444f; } catch { return(null); } return(result); } return(null); }
public async void Run(IBackgroundTaskInstance taskInstance) { BackgroundTaskDeferral deferral = taskInstance.GetDeferral(); /* Look for the serial and create a data reader using it's input stream */ string deviceSelector = SerialDevice.GetDeviceSelector("UART0"); var devices = await DeviceInformation.FindAllAsync(deviceSelector); SerialDevice serialPort = await SerialDevice.FromIdAsync(devices[0].Id); var DataReader = new DataReader(serialPort.InputStream) { InputStreamOptions = InputStreamOptions.Partial }; bool quit = false; LineQueue lineQueue = new LineQueue(); while (!quit) { /* Read the GPS data from the serial device (the GPS model continously sends NMEA hence only reading is required) */ string gpsData = await ReadAsync(DataReader); lineQueue.AddChunk(gpsData); while (lineQueue.HasMore()) { string nmeaSentence = lineQueue.Next(); Debug.Write(nmeaSentence); /* Attempt to parse the NMEA sentence if valid add to waypoint list */ if (nmeaSentence.StartsWith("$GPRMC")) { GPRMCInfo info = GPRMCInfo.Parse(nmeaSentence); if (info != null) { TimeOfLastValidWaypoint = DateTime.Now; Waypoints.Add(info); } } /* If the waypoint list is full then check whether there has been any movement and start/end trip as appropriate */ if (Waypoints.Count == Waypoints.Capacity) { if (!HaveWaypointsMoved()) { EndTrip(); } else { if (!InTrip) { StartTrip(); } WriteWaypointsToFile(); } Waypoints.Clear(); } /* If there haven't been any valid GPRMC messages for 2min end the trip */ if ((TimeOfLastValidWaypoint - DateTime.Now).Minutes >= 2) { EndTrip(); } } } deferral.Complete(); }