private void UpdateDeviation() { if (AnyStale(new IQuantityWithMetaData[] { Sog, Cog, Heading })) { return; } if (Sog < MINIMUM_SPEED_FOR_VALID_CALCULATIONS) { return; } _compassCorrection.AddSample(Heading.Value, Cog.Value); _compassCorrectionPersister.Write(_compassCorrection); CorrectedHeading = new QuantityWithMetadata <IMessageCompassValue>(_compassCorrection.CorrectHeading(Heading.Value)); if (PropertyChanged == null) { return; } PropertyChanged(this, new PropertyChangedEventArgs("MeanDeviation")); PropertyChanged(this, new PropertyChangedEventArgs("SampleCount")); PropertyChanged(this, new PropertyChangedEventArgs("CorrectedHeading")); }
private void OnIncomingMessage(MessageBase message, DateTime messagetime) { // ReSharper disable once SwitchStatementMissingSomeCases switch (message.Name) { case MessageName.RMC: { var rmc = (RMC)message; if (rmc.SOG > MINIMUM_SPEED_FOR_VALID_CALCULATIONS) { Cog = rmc.TMG; Cog.Source = SourceType.External; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Cog")); Sog = rmc.SOG; Sog.Source = SourceType.External; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Sog")); OnUpdateCog(); } } break; case MessageName.HDG: { var hdg = (HDG)message; if (null != hdg.MagneticContext) { _magneticContext = hdg.MagneticContext; } } break; } if (message is IHaveHeading) { Heading = new QuantityWithMetadata <IMessageCompassValue>(_magneticContext.Magnetic((message as IHaveHeading).Heading)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Heading")); } if (message is IHasPosition) { QuantityWithMetadata <Coordinate> c = (Coordinate)(message as IHasPosition).Position; c.Source = SourceType.External; c.Updated = messagetime; OnUpdatePosition(c); } UpdateLastMessageDictionary(message); }
private void OnUpdatePosition(QuantityWithMetadata <Coordinate> coordinate) { if (null == Sog || Sog.Source != SourceType.External || Sog.IsStale) { // Try to calculate Sog from position data if (null != _lastposition && !_lastposition.IsStale) { var angulardistance = ((Coordinate)coordinate).Distance(_lastposition); var distance = Ball.EarthSurfaceApproximation.Distance(angulardistance).NauticalMiles(); if (distance >= _minimumDistanceForCalculations.NauticalMiles()) { var elapsed = DateTime.UtcNow - _lastposition.Updated; if (elapsed.HasValue && elapsed.Value >= _minimumElapsedtimeForCalculations) { Sog = distance / elapsed.Value.TotalHours; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Sog")); } } } } if (null == Cog || Cog.Source != SourceType.External || Cog.IsStale) { // Try to calculate Cog from position data if (null != _lastposition && !_lastposition.IsStale) { var angulardistance = ((Coordinate)coordinate).Distance(_lastposition); var distance = Ball.EarthSurfaceApproximation.Distance(angulardistance).NauticalMiles(); if (distance >= _minimumDistanceForCalculations.NauticalMiles()) { if (null != Sog && Sog > MINIMUM_SPEED_FOR_VALID_CALCULATIONS) { var truecog = _lastposition.Value.InitialCourse(coordinate); Cog = new TrueMessageCompassValue(truecog.Degrees); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Cog")); OnUpdateCog(); } } } } _lastposition = coordinate; }