예제 #1
0
        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"));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }