feyris-tan ef86554f9a Import
2025-05-12 22:09:16 +02:00

166 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NmeaParser;
using NmeaParser.Messages;
using skyscraper5.Skyscraper.Gps;
namespace skyscraper5.NmeaSharpWrapper
{
abstract class NmeaSharpWrapper : IGpsReceiver
{
public bool ProvidesAdditionalNmeaData => additionalNmeaData != null;
public bool HasLock => seenLock && seenLonLat;
private bool seenLock, seenLonLat;
private GpsCoordinate receivedCoordinate;
public GpsCoordinate Coordinate => receivedCoordinate;
public AdditionalNmeaData AdditionalNmeaData => additionalNmeaData;
public void Stop()
{
CancelRequest = true;
}
public void Start()
{
_thread = new Thread(ProcessorThread);
_thread.Priority = ThreadPriority.Lowest;
_thread.Name = String.Format("GPS Receiver: {0}", this.GetType().Name);
_thread.Start();
}
protected Thread _thread;
protected abstract void ProcessorThread();
protected bool CancelRequest { get; set; }
private AdditionalNmeaData additionalNmeaData;
protected void HandleNmeaMessage(object? sender, NmeaMessageReceivedEventArgs e)
{
HandleNmeaMessage(e.Message);
}
protected void HandleNmeaMessage(string s)
{
NmeaMessage nmeaMessage = NmeaMessage.Parse(s);
HandleNmeaMessage(nmeaMessage);
}
protected void HandleNmeaMessage(NmeaMessage message)
{
string messageMessageType = message.MessageType;
switch (messageMessageType)
{
case "GPGLL":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Gll gll = (Gll)message;
additionalNmeaData.ModeIndicator = gll.ModeIndicator.ToString();
additionalNmeaData.DataActive = gll.DataActive;
additionalNmeaData.FixTime = gll.FixTime;
receivedCoordinate = new GpsCoordinate((float)gll.Latitude, (float)gll.Longitude);
seenLonLat = true;
break;
case "GPVTG":
Vtg vtg = (Vtg)message;
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
additionalNmeaData.CourseMagnetic = vtg.CourseMagnetic;
additionalNmeaData.CourseTrue = vtg.CourseTrue;
additionalNmeaData.SpeedKnots = vtg.SpeedKnots;
additionalNmeaData.SpeedKph = vtg.SpeedKph;
break;
case "GPZDA":
Zda zda = (Zda)message;
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
additionalNmeaData.FixDateTime = zda.FixDateTime;
break;
case "GPGGA":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Gga gga = (Gga)message;
additionalNmeaData.Quality = gga.Quality.ToString();
additionalNmeaData.Altitude = gga.Altitude;
additionalNmeaData.AltitudeUnits = gga.AltitudeUnits;
additionalNmeaData.DpgsStationId = gga.DgpsStationId;
additionalNmeaData.FixTime = gga.FixTime;
additionalNmeaData.GeoidalSeparation = gga.GeoidalSeparation;
additionalNmeaData.GeoidalSeparationUnits = gga.GeoidalSeparationUnits;
additionalNmeaData.Hdop = gga.Hdop;
additionalNmeaData.NumberOfSatellites = gga.NumberOfSatellites;
additionalNmeaData.TimeSinceLastDgpsUpdate = gga.TimeSinceLastDgpsUpdate;
if (gga.Quality == Gga.FixQuality.GpsFix || gga.Quality == Gga.FixQuality.DgpsFix)
{
receivedCoordinate = new GpsCoordinate((float)gga.Latitude, (float)gga.Longitude);
seenLonLat = true;
seenLock = true;
}
break;
case "GPGSA":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Gsa gsa = (Gsa)message;
additionalNmeaData.Hdop = gsa.Hdop;
additionalNmeaData.Fix = gsa.Fix.ToString();
additionalNmeaData.Mode = gsa.Mode.ToString();
additionalNmeaData.Pdop = gsa.Pdop;
additionalNmeaData.SatelliteIDs = gsa.SatelliteIDs;
additionalNmeaData.Vdop = gsa.Vdop;
if (gsa.Fix == Gsa.FixType.Fix2D || gsa.Fix == Gsa.FixType.Fix3D)
seenLock = true;
break;
case "GPRMC":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Rmc rmc = (Rmc)message;
receivedCoordinate = new GpsCoordinate((float)rmc.Latitude, (float)rmc.Longitude);
seenLonLat = true;
additionalNmeaData.Active = rmc.Active;
additionalNmeaData.CourseTrue = rmc.Course;
additionalNmeaData.FixTime = rmc.FixTime.TimeOfDay;
additionalNmeaData.MagneticVariation = rmc.MagneticVariation;
additionalNmeaData.SpeedKnots = rmc.Speed;
break;
case "GPGSV":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Gsv gsv = (Gsv)message;
additionalNmeaData.GnssSignalId = gsv.GnssSignalId;
additionalNmeaData.SatellitesInView = gsv.SatellitesInView;
foreach (SatelliteVehicle vehicle in gsv.SVs)
additionalNmeaData.AddSatellite(vehicle.Id, vehicle.GnssSignalId, vehicle.Azimuth,
vehicle.Elevation, vehicle.SignalToNoiseRatio, vehicle.System.ToString(),
vehicle.TalkerId.ToString());
break;
case "GPGBS":
if (additionalNmeaData == null)
additionalNmeaData = new AdditionalNmeaData();
Gbs gbs = (Gbs)message;
additionalNmeaData.LatitudeError = gbs.LatitudeError;
additionalNmeaData.LongitudeError = gbs.LongitudeError;
additionalNmeaData.AltitudeError = gbs.AltitudeError;
additionalNmeaData.SatelliteId = gbs.SatelliteId;
additionalNmeaData.MissedDetectionProbability = gbs.MissedDetectionProbability;
additionalNmeaData.BiasEstimate = gbs.BiasEstimate;
additionalNmeaData.StandardDeviation = gbs.StandardDeviation;
break;
case "GSGPG":
case "GPG":
case "GPTXT":
//does not seem to contain anything?
break;
default:
throw new NotImplementedException(messageMessageType);
}
}
}
}