コード例 #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
ファイル: LapInfo.cs プロジェクト: smetronic/SecondMonitor
 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
ファイル: LapInfo.cs プロジェクト: ckuepker/SecondMonitor
 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
ファイル: DriverTiming.cs プロジェクト: plkumar/SecondMonitor
 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
ファイル: LapInfo.cs プロジェクト: smetronic/SecondMonitor
 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
ファイル: DriverTiming.cs プロジェクト: plkumar/SecondMonitor
        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);
 }