Пример #1
0
        private void ComputePace()
        {
            if (LastCompletedLap == null)
            {
                Pace = TimeSpan.Zero;
                return;
            }

            int      totalPaceLaps = 0;
            TimeSpan pace          = TimeSpan.Zero;

            for (int i = _lapsInfo.Count - 1; i >= 0 && totalPaceLaps < PaceLaps; i--)
            {
                LapInfo lap = _lapsInfo[i];
                if (!lap.Completed || (!lap.Valid && !Session.RetrieveAlsoInvalidLaps))
                {
                    continue;
                }

                pace = pace.Add(lap.LapTime);
                totalPaceLaps++;
            }

            Pace = totalPaceLaps == 0 ? TimeSpan.Zero : new TimeSpan(pace.Ticks / totalPaceLaps);
        }
Пример #2
0
        private void FinishLap(LapInfo lapToFinish, SimulatorDataSet dataSet)
        {
            lapToFinish.FinishLap(dataSet, DriverInfo);
            lapToFinish.SectorCompletedEvent -= LapSectorCompletedEvent;
            lapToFinish.LapCompletedEvent    -= LapCompletedHandler;
            lapToFinish.LapInvalidatedEvent  -= LapInvalidatedHandler;

            if (lapToFinish.LapTime == TimeSpan.Zero)
            {
                lapToFinish.Valid = false;
                RevertSectorChanges(lapToFinish);
            }

            if (ShouldLapBeDiscarded(lapToFinish, dataSet))
            {
                _lapsInfo.Remove(lapToFinish);
                return;
            }

            if (lapToFinish.Valid && lapToFinish.LapTime != TimeSpan.Zero && (BestLap == null || lapToFinish.LapTime < BestLap.LapTime))
            {
                BestLap = lapToFinish;
            }

            OnLapCompleted(new LapEventArgs(lapToFinish));

            ComputePace();
        }
Пример #3
0
 public LapPortionTimesComparatorViewModel(LapInfo referenceLap, LapInfo comparedLap)
 {
     ReferenceLap   = referenceLap;
     ComparedLap    = comparedLap;
     TimeDifference = TimeSpan.Zero;
     SubscribeToComparedLap();
 }
Пример #4
0
 public LapTelemetryInfo(DriverInfo driverInfo, SimulatorDataSet dataSet, LapInfo lapInfo, TimeSpan snapshotInterval, SimulatorSourceInfo simulatorSourceInfo)
 {
     LapStarSnapshot         = new TelemetrySnapshot(driverInfo, dataSet.SessionInfo.WeatherInfo, dataSet.InputInfo, simulatorSourceInfo);
     LapInfo                 = lapInfo;
     PortionTimes            = new LapPortionTimes(10, dataSet.SessionInfo.TrackInfo.LayoutLength.InMeters, lapInfo);
     TimedTelemetrySnapshots = new TimedTelemetrySnapshots(snapshotInterval);
 }
Пример #5
0
 public LapPortionTimes(int baseTrackPortionLength, double trackLength, LapInfo lap)
 {
     _lastTrackedPortion     = -1;
     _baseTrackPortionLength = baseTrackPortionLength;
     Lap            = lap;
     _trackPortions = new TimeSpan[(int)trackLength / baseTrackPortionLength + 1];
 }
Пример #6
0
        private void FinishLap(LapInfo lapToFinish, SimulatorDataSet dataSet)
        {
            if (lapToFinish.Completed)
            {
                return;
            }
            lapToFinish.FinishLap(dataSet, DriverInfo);
            lapToFinish.SectorCompletedEvent -= LapSectorCompletedEvent;
            lapToFinish.LapInvalidatedEvent  -= LapInvalidatedHandler;

            if (lapToFinish.LapTime == TimeSpan.Zero)
            {
                lapToFinish.InvalidateLap(LapInvalidationReasonKind.NoValidLapTime);
                RevertSectorChanges(lapToFinish);
            }

            if (ShouldLapBeDiscarded(lapToFinish, dataSet))
            {
                _lapsInfo.Remove(lapToFinish);
                return;
            }

            if (lapToFinish.Valid && lapToFinish.LapTime != TimeSpan.Zero && (BestLap == null || lapToFinish.LapTime < BestLap.LapTime))
            {
                BestLap = lapToFinish;
            }

            OnLapCompleted(new LapEventArgs(lapToFinish));
            Logger.Info($"Driver {DriverInfo.DriverName}, Lap {lapToFinish.LapNumber} finnished. REASON: {lapToFinish.LapCompletionMethod}");

            ComputePace();
            PurgeLapsTelemetry();
        }
Пример #7
0
 public PitStopInfo(SimulatorDataSet set, DriverTiming driver, LapInfo entryLap)
 {
     Driver          = driver;
     EntryLap        = entryLap;
     Phase           = PitPhase.Entry;
     PitEntry        = set.SessionInfo.SessionTime;
     PitStopDuration = TimeSpan.Zero;
     PitExit         = PitEntry;
     PitStopStart    = PitEntry;
     PitStopEnd      = PitEntry;
 }
Пример #8
0
        private bool ShouldFinishLap(SimulatorDataSet dataSet, LapInfo currentLap)
        {
            SessionInfo sessionInfo = dataSet.SessionInfo;

            // Use completed laps indication to end lap, when we use the sim provided lap times. This gives us the biggest assurance that lap time is already properly set. But wait for lap to be at least 5 seconds in
            if (dataSet.SimulatorSourceInfo.HasLapTimeInformation && (currentLap.LapNumber < DriverInfo.CompletedLaps + 1))
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByLapNumber;
                return(true);
            }


            // Crossed line at out lap
            if (dataSet.SessionInfo.SessionType != SessionType.Race && currentLap.PitLap && (DriverInfo.LapDistance - _previousTickLapDistance < sessionInfo.TrackInfo.LayoutLength.InMeters * -0.90))
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByCrossingTheLine;
                return(true);
            }

            if ((!dataSet.SimulatorSourceInfo.HasLapTimeInformation || dataSet.SimulatorSourceInfo.SimNotReportingEndOfOutLapCorrectly) && (DriverInfo.LapDistance - _previousTickLapDistance < sessionInfo.TrackInfo.LayoutLength.InMeters * -0.90))
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByCrossingTheLine;
                return(true);
            }

            if (!dataSet.SimulatorSourceInfo.OutLapIsValid && !currentLap.Valid && DriverInfo.CurrentLapValid && DriverInfo.IsPlayer && (currentLap.FirstLap && !InvalidateFirstLap))
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByChangingValidity;
                return(true);
            }

            if (!dataSet.SimulatorSourceInfo.OutLapIsValid && !currentLap.Valid && DriverInfo.CurrentLapValid && DriverInfo.IsPlayer && currentLap.PitLap && _previousTickLapDistance < DriverInfo.LapDistance && SessionType.Race != sessionInfo.SessionType && !DriverInfo.InPits)
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByChangingValidity2;
                return(true);
            }

            if (!currentLap.Valid && DriverInfo.CurrentLapValid && SessionType.Race == sessionInfo.SessionType && !DriverInfo.IsPlayer && (currentLap.FirstLap && !InvalidateFirstLap))
            {
                currentLap.LapCompletionMethod = LapCompletionMethod.ByChangingValidity3;
                return(true);
            }

            // Driver is DNF/DQ -> finish timed lap, and set it to invalid
            if (DriverInfo.FinishStatus != DriverFinishStatus.Na && DriverInfo.FinishStatus != DriverFinishStatus.None)
            {
                CurrentLap.InvalidateLap(LapInvalidationReasonKind.DriverDnf);
                return(true);
            }

            return(false);
        }
Пример #9
0
 public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, bool firstLap, LapInfo previousLapInfo)
 {
     Driver                  = driver;
     LapStart                = dataSet.SessionInfo.SessionTime;
     LapProgressTimeBySim    = TimeSpan.Zero;
     LapProgressTimeByTiming = TimeSpan.Zero;
     LapNumber               = lapNumber;
     Valid             = true;
     FirstLap          = firstLap;
     PitLap            = false;
     PreviousLap       = previousLapInfo;
     CompletedDistance = double.NaN;
     LapTelemetryInfo  = new LapTelemetryInfo(driver.DriverInfo, dataSet, this, TimeSpan.FromMilliseconds(Driver.Session.TimingDataViewModel.DisplaySettingsViewModel.TelemetrySettingsViewModel.LoggingInterval), dataSet.SimulatorSourceInfo);
 }
Пример #10
0
 public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, bool firstLap, LapInfo previousLapInfo)
 {
     Driver                  = driver;
     LapStart                = dataSet.SessionInfo.SessionTime;
     LapProgressTimeBySim    = TimeSpan.Zero;
     LapProgressTimeByTiming = TimeSpan.Zero;
     LapNumber               = lapNumber;
     Valid             = true;
     FirstLap          = firstLap;
     PitLap            = false;
     PreviousLap       = previousLapInfo;
     CompletedDistance = double.NaN;
     LapTelemetryInfo  = new LapTelemetryInfo(driver.DriverInfo, dataSet, this);
 }
Пример #11
0
 private void CreateNewLap(SimulatorDataSet dataSet, ILapInfo lapToCreateFrom)
 {
     if ((DriverInfo.FinishStatus == DriverFinishStatus.Na ||
          DriverInfo.FinishStatus == DriverFinishStatus.None) && dataSet.SessionInfo.SessionPhase != SessionPhase.Checkered)
     {
         var newLap = new LapInfo(
             dataSet,
             DriverInfo.CompletedLaps + 1,
             this,
             lapToCreateFrom);
         newLap.SectorCompletedEvent += LapSectorCompletedEvent;
         newLap.LapInvalidatedEvent  += LapInvalidatedHandler;
         _lapsInfo.Add(newLap);
         OnNewLapStarted(new LapEventArgs(newLap));
     }
 }
Пример #12
0
        private void RevertSectorChanges(LapInfo lap)
        {
            if (BestSector1 != null && BestSector1 == lap.Sector1)
            {
                BestSector1 = FindBestSector(LapInfo.Sector1SelFunc);
            }

            if (BestSector2 != null && BestSector2 == lap.Sector2)
            {
                BestSector2 = FindBestSector(LapInfo.Sector2SelFunc);
            }

            if (BestSector3 != null && BestSector3 == lap.Sector3)
            {
                BestSector3 = FindBestSector(LapInfo.Sector3SelFunc);
            }
        }
Пример #13
0
 public LapEventArgs(LapInfo lapInfo)
 {
     Lap = lapInfo;
 }
Пример #14
0
 public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, LapInfo previousLapInfo) :
     this(dataSet, lapNumber, driver, false, previousLapInfo)
 {
 }
Пример #15
0
 public SectorTiming(int sectorNumber, SimulatorDataSet simulatorData, LapInfo lap)
 {
     SectorNumber = sectorNumber;
     _startTime   = simulatorData.SessionInfo.SessionTime;
     Lap          = lap;
 }
Пример #16
0
 public CombinedLapPortionComparatorsVM(LapInfo playerLap)
 {
     _playerLap = playerLap;
     RecreatePlayerLapToPrevious();
     RecreatePlayerLapToPlayerBest();
 }
Пример #17
0
        public bool UpdateLaps(SimulatorDataSet set)
        {
            SessionInfo sessionInfo = set.SessionInfo;

            if (!sessionInfo.IsActive)
            {
                return(false);
            }

            if (sessionInfo.SessionPhase == SessionPhase.Countdown)
            {
                return(false);
            }

            if (DriverInfo.FinishStatus != DriverFinishStatus.Na && DriverInfo.FinishStatus != DriverFinishStatus.None && CurrentLap != null && CurrentLap.Completed)
            {
                return(false);
            }

            if (TopSpeed < DriverInfo.Speed && DriverInfo.Speed < _maximumVelocity)
            {
                TopSpeed = DriverInfo.Speed;
            }


            UpdateInPitsProperty(set);
            if (_lapsInfo.Count == 0)
            {
                LapInfo firstLap = new LapInfo(set, DriverInfo.CompletedLaps + 1, this, true, null);
                if (InvalidateFirstLap)
                {
                    firstLap.InvalidateLap(LapInvalidationReasonKind.InvalidatedFirstLap);
                }
                firstLap.SectorCompletedEvent += LapSectorCompletedEvent;
                firstLap.LapInvalidatedEvent  += LapInvalidatedHandler;
                _lapsInfo.Add(firstLap);
                OnNewLapStarted(new LapEventArgs(firstLap));
            }

            if (LastLap != null && LastLap.IsPending && !LastLap.UpdatePendingState(set, DriverInfo))
            {
                FinishLap(LastLap, set);
            }

            ILapInfo currentLap = CurrentLap;

            if (!currentLap.Completed)
            {
                UpdateCurrentLap(set);
            }

            if (_refreshBestSectorIndicationWatch.ElapsedMilliseconds > 2000)
            {
                UpdateBestSectorProperties();
                _refreshBestSectorIndicationWatch.Restart();
            }

            if (ShouldFinishLap(set, currentLap))
            {
                if (!currentLap.SwitchToPendingIfNecessary(set, DriverInfo))
                {
                    FinishLap(currentLap, set);
                }
                CreateNewLap(set, currentLap);
                _previousTickLapDistance = DriverInfo.LapDistance;
                return(currentLap.Valid);
            }

            if (set.SimulatorSourceInfo.OverrideBestLap)
            {
                CheckAndOverrideBestLap(sessionInfo.TrackInfo.LayoutLength.InMeters);
            }

            _previousTickLapDistance = DriverInfo.LapDistance;
            return(false);
        }
Пример #18
0
 private bool ShouldLapBeDiscarded(LapInfo lap, SimulatorDataSet dataSet)
 {
     return(!lap.IsLapDataSane(dataSet));
 }
Пример #19
0
        public bool UpdateLaps(SimulatorDataSet set)
        {
            SessionInfo sessionInfo = set.SessionInfo;

            if (!sessionInfo.IsActive)
            {
                return(false);
            }

            if (sessionInfo.SessionPhase == SessionPhase.Countdown)
            {
                return(false);
            }

            if (DriverInfo.FinishStatus != DriverInfo.DriverFinishStatus.Na && DriverInfo.FinishStatus != DriverInfo.DriverFinishStatus.None && CurrentLap != null && CurrentLap.Completed)
            {
                return(false);
            }

            if (TopSpeed < DriverInfo.Speed && DriverInfo.Speed < _maximumVelocity)
            {
                TopSpeed = DriverInfo.Speed;
            }

            UpdateInPitsProperty(set);
            if (_lapsInfo.Count == 0)
            {
                LapInfo firstLap =
                    new LapInfo(set, DriverInfo.CompletedLaps + 1, this, true, null)
                {
                    Valid = !InvalidateFirstLap
                };
                firstLap.SectorCompletedEvent += LapSectorCompletedEvent;
                firstLap.LapInvalidatedEvent  += LapInvalidatedHandler;
                firstLap.LapCompletedEvent    += LapCompletedHandler;
                _lapsInfo.Add(firstLap);
                OnNewLapStarted(new LapEventArgs(firstLap));
            }

            if (LastLap != null && LastLap.IsPending && !LastLap.UpdatePendingState(set, DriverInfo))
            {
                FinishLap(LastLap, set);
            }

            LapInfo currentLap = CurrentLap;

            if (!currentLap.Completed)
            {
                UpdateCurrentLap(set);
            }

            if (ShouldFinishLap(set, currentLap))
            {
                if (!currentLap.SwitchToPendingIfNecessary(set, DriverInfo))
                {
                    FinishLap(currentLap, set);
                }
                CreateNewLap(set, currentLap);
                _previousTickLapDistance = DriverInfo.LapDistance;
                return(currentLap.Valid);
            }

            _previousTickLapDistance = DriverInfo.LapDistance;
            return(false);
        }
Пример #20
0
 public LapTelemetryInfo(DriverInfo driverInfo, SimulatorDataSet dataSet, LapInfo lapInfo)
 {
     LapStarSnapshot = new TelemetrySnapshot(driverInfo, dataSet.SessionInfo.WeatherInfo);
     LapInfo         = lapInfo;
     PortionTimes    = new LapPortionTimes(10, dataSet.SessionInfo.TrackInfo.LayoutLength, lapInfo);
 }