예제 #1
0
        internal virtual void InternalPropertyChangedAsync(object sender, PropertyChangedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new MethodInvoker(() => { InternalPropertyChangedAsync(this, e); }));
            }
            else
            {
                switch (e.PropertyName)
                {
                case nameof(Session):
                {
                    _currentLap = Session?.TelemetrySessionData?.Laps?.FirstOrDefault();
                    int?lapNumber = Session?.TelemetrySessionData?.Laps?.FirstOrDefault().LapNumber;
                    _currentLapNumber  = lapNumber.HasValue ? lapNumber.Value : -1;
                    _currentFrameIndex = 0;
                    _laps = Session?.TelemetrySessionData?.Laps;
                    break;
                }

                case nameof(FormDisplayInfo):
                {
                    Text = FormDisplayInfo.Name;
                    break;
                }
                }

                ProtectedPropertyChangedHandlerAsync(this, e);
            }
        }
예제 #2
0
        private void FinishLap(ILapInfo 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();
        }
        private bool TrySaveLap(ILapInfo lapInfo)
        {
            try
            {
                LapSummaryDto lapSummaryDto = CreateLapSummary(lapInfo);

                TimedTelemetrySnapshot fistSnapshotsByDistance = lapInfo.LapTelemetryInfo.TimedTelemetrySnapshots.Snapshots.First(x => x.PlayerData.LapDistance < _sessionInfoDto.LayoutLength * 0.5);

                LapTelemetryDto lapTelemetryDto = new LapTelemetryDto()
                {
                    LapSummary = lapSummaryDto,
                    DataPoints = lapInfo.LapTelemetryInfo.TimedTelemetrySnapshots.Snapshots.Skip(lapInfo.LapTelemetryInfo.TimedTelemetrySnapshots.Snapshots.ToList().IndexOf(fistSnapshotsByDistance)).ToList()
                };


                Interpolate(lapTelemetryDto, lapTelemetryDto.DataPoints.First().SimulatorSourceInfo.TelemetryInfo.RequiresDistanceInterpolation, lapTelemetryDto.DataPoints.First().SimulatorSourceInfo.TelemetryInfo.RequiresPositionInterpolation);

                LapSummaryDto previousLapInfo = _sessionInfoDto.LapsSummary.FirstOrDefault(x => x.LapNumber == lapSummaryDto.LapNumber);
                if (previousLapInfo != null)
                {
                    _sessionInfoDto.LapsSummary.Remove(previousLapInfo);
                }

                _sessionInfoDto.LapsSummary.Add(lapSummaryDto);

                _telemetryRepository.SaveRecentSessionInformation(_sessionInfoDto, SessionIdentifier);
                _telemetryRepository.SaveRecentSessionLap(lapTelemetryDto, SessionIdentifier);
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Uanble to Save Telemetry");
                return(false);
            }
        }
예제 #4
0
        private void CheckAndOverrideBestLap(double layoutLength)
        {
            if (DriverInfo.Timing.BestLapTime == TimeSpan.Zero)
            {
                return;
            }

            if (BestLap == null)
            {
                ILapInfo newBestLap = new StaticLapInfo(Laps.Count + 1, DriverInfo.Timing.BestLapTime, false, Laps.LastOrDefault(), layoutLength, this);
                _lapsInfo.Insert(0, newBestLap);
                BestLap = newBestLap;
                LapCompleted?.Invoke(this, new LapEventArgs(newBestLap));
                return;
            }

            if (BestLap.LapTime == DriverInfo.Timing.BestLapTime)
            {
                return;
            }

            ILapInfo oldBestLap = BestLap;

            oldBestLap.OverrideTime(DriverInfo.Timing.BestLapTime);
            BestLap = Laps.Where(x => x.Completed && x.Valid && x.LapTime != TimeSpan.Zero).OrderBy(x => x.LapTime).FirstOrDefault();
            LapTimeReevaluated?.Invoke(this, new LapEventArgs(oldBestLap));
        }
예제 #5
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--)
            {
                ILapInfo 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);
        }
예제 #6
0
        private bool ShouldFinishLap(SimulatorDataSet dataSet, ILapInfo currentLap)
        {
            SessionInfo sessionInfo = dataSet.SessionInfo;

            if (currentLap.Completed)
            {
                return(true);
            }

            // 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);
        }
예제 #7
0
        private bool Evaluate(ILapInfo lapInfo, RecordEntryDto recordEntryDto)
        {
            if (recordEntryDto == null || recordEntryDto.LapTime > lapInfo.LapTime)
            {
                return(true);
            }

            return(false);
        }
        private bool SaveLapTelemetrySync(ILapInfo lapInfo)
        {
            if (_sessionInfoDto == null)
            {
                _sessionInfoDto = CreateSessionInfo(lapInfo);
            }

            return(TrySaveLap(lapInfo));
        }
예제 #9
0
 public PitStopInfo(SimulatorDataSet set, DriverTiming driver, ILapInfo entryLap)
 {
     Driver          = driver;
     EntryLap        = entryLap;
     Phase           = PitPhase.Entry;
     PitEntry        = set.SessionInfo.SessionTime;
     PitStopDuration = TimeSpan.Zero;
     PitExit         = PitEntry;
     PitStopStart    = PitEntry;
     PitStopEnd      = PitEntry;
 }
예제 #10
0
        protected virtual async Task HandleSessionChangedAsync()
        {
            CurrentFrameIndex = 0;

            if (Session != null)
            {
                var startLap = Session?.TelemetrySessionData?.Laps.Min(l => l.LapNumber);;
                CurrentLapNumber = startLap.HasValue ? startLap.Value : 0;
                CurrentLap       = Session?.TelemetrySessionData?.Laps.FirstOrDefault();
            }

            await NotifySessionChangedAsync();
        }
예제 #11
0
        private bool EvaluateAsClassRecord(ILapInfo lapInfo)
        {
            var sessionType = lapInfo.Driver.Session.SessionType;

            if (Evaluate(lapInfo, _currentClassRecordSet.GetProperEntry(sessionType)))
            {
                var newRecordEntry = FromLap(lapInfo);
                _currentClassRecordSet.SetProperEntry(sessionType, newRecordEntry);
                return(GetCurrentClassRecord() == newRecordEntry);
            }

            return(false);
        }
예제 #12
0
        protected virtual async Task HandleCurrentLapNumberChangedAsync()
        {
            if (Session != null)
            {
                CurrentLap = Session.TelemetrySessionData?.Laps.FirstOrDefault(l => l.LapNumber == CurrentLapNumber);
            }
            else
            {
                CurrentLap = null;
            }

            await NotifyCurrentLapNumberChangedAsync();
        }
예제 #13
0
 public StaticLapInfo(int lapNumber, TimeSpan lapTime, bool firstLap, ILapInfo previousLap, double completedDistance, DriverTiming driver)
 {
     LapNumber         = lapNumber;
     LapTime           = lapTime;
     FirstLap          = firstLap;
     PreviousLap       = previousLap;
     CompletedDistance = completedDistance;
     Driver            = driver;
     Sector1           = new SectorTiming(1, TimeSpan.Zero, this);
     Sector2           = new SectorTiming(2, TimeSpan.Zero, this);
     Sector3           = new SectorTiming(3, TimeSpan.Zero, this);
     LapTelemetryInfo  = null;
 }
예제 #14
0
        private void lvLapTimes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_suppressUpdate)
            {
                return;
            }

            if (lvLapTimes.SelectedItems.Count > 0)
            {
                ILapInfo selectedLap = (ILapInfo)lvLapTimes.SelectedItems[0].Tag;
                OnLapNumberChangeRequest(selectedLap.LapNumber);
            }
        }
예제 #15
0
 private RecordEntryDto FromLap(ILapInfo lapInfo)
 {
     return(new RecordEntryDto()
     {
         CarClass = lapInfo.Driver.CarClassName,
         CarName = lapInfo.Driver.CarName,
         IsPlayer = true,
         LapTime = lapInfo.LapTime,
         PlayerName = lapInfo.Driver.Name,
         RecordDate = DateTime.Now,
         SessionType = lapInfo.Driver.Session.SessionType
     });
 }
예제 #16
0
파일: LapInfo.cs 프로젝트: tsofron/trails
        public LapInfo(ILapInfo l)
        {
            this.TotalTime           = l.TotalTime;
            this.TotalDistanceMeters = l.TotalDistanceMeters;

            this.AverageCadencePerMinute   = l.AverageCadencePerMinute;
            this.AverageHeartRatePerMinute = l.AverageHeartRatePerMinute;
            this.AveragePowerWatts         = l.AveragePowerWatts;
            this.ElevationChangeMeters     = l.ElevationChangeMeters;
            this.m_PoolLengths             = l.PoolLengths;
            this.Rest          = l.Rest;
            this.StartTime     = l.StartTime;
            this.TotalCalories = l.TotalCalories;
        }
예제 #17
0
 public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, bool firstLap, ILapInfo 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);
 }
예제 #18
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));
     }
 }
        private static Lap ConvertToSummaryLap(Driver summaryDriver, ILapInfo lapInfo, int lapNumber, SessionType sessionType)
        {
            Lap summaryLap = new Lap(summaryDriver, lapInfo.Valid)
            {
                LapNumber        = lapNumber,
                LapTime          = lapInfo.LapTime,
                Sector1          = lapInfo.Sector1?.Duration ?? TimeSpan.Zero,
                Sector2          = lapInfo.Sector2?.Duration ?? TimeSpan.Zero,
                Sector3          = lapInfo.Sector3?.Duration ?? TimeSpan.Zero,
                LapEndSnapshot   = lapInfo.LapTelemetryInfo.LapEndSnapshot,
                LapStartSnapshot = lapInfo.LapTelemetryInfo.LapStarSnapshot,
                SessionType      = sessionType,
            };

            return(summaryLap);
        }
예제 #20
0
        private void RevertSectorChanges(ILapInfo 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);
            }
        }
예제 #21
0
 private void SetSelectedLap(int lapNumber)
 {
     if (this.InvokeRequired)
     {
         this.BeginInvoke(new MethodInvoker(() => { SetSelectedLap(lapNumber); }));
     }
     else
     {
         _suppressUpdate = true;
         foreach (ListViewItem item in lvLapTimes.Items)
         {
             ILapInfo lapInfo = (ILapInfo)item.Tag;
             item.Selected = (lapInfo.LapNumber == lapNumber);
         }
         _suppressUpdate = false;
     }
 }
        private SessionInfoDto CreateSessionInfo(ILapInfo lapInfo)
        {
            SessionInfoDto sessionInfoDto = new SessionInfoDto()
            {
                CarName            = lapInfo.Driver.CarName,
                Id                 = SessionIdentifier,
                TrackName          = lapInfo.Driver.Session.LastSet.SessionInfo.TrackInfo.TrackName,
                LayoutName         = lapInfo.Driver.Session.LastSet.SessionInfo.TrackInfo.TrackLayoutName,
                LayoutLength       = lapInfo.Driver.Session.LastSet.SessionInfo.TrackInfo.LayoutLength.InMeters,
                PlayerName         = lapInfo.Driver.Name,
                Simulator          = lapInfo.Driver.Session.LastSet.Source,
                SessionRunDateTime = DateTime.Now,
                LapsSummary        = new List <LapSummaryDto>(),
                SessionType        = lapInfo.Driver.Session.SessionType.ToString()
            };

            return(sessionInfoDto);
        }
        private LapSummaryDto CreateLapSummary(ILapInfo lapInfo)
        {
            int           stintNumber   = lapInfo.Driver.Laps.Count(x => x.PitLap);
            LapSummaryDto lapSummaryDto = new LapSummaryDto()
            {
                LapNumber         = lapInfo.LapNumber,
                LapTimeSeconds    = lapInfo.LapTime.TotalSeconds,
                Sector1Time       = lapInfo.Sector1?.Duration ?? TimeSpan.Zero,
                Sector2Time       = lapInfo.Sector2?.Duration ?? TimeSpan.Zero,
                Sector3Time       = lapInfo.Sector3?.Duration ?? TimeSpan.Zero,
                SessionIdentifier = SessionIdentifier,
                Simulator         = _sessionInfoDto.Simulator,
                TrackName         = _sessionInfoDto.TrackName,
                LayoutName        = _sessionInfoDto.LayoutName,
                Stint             = stintNumber,
            };

            return(lapSummaryDto);
        }
        public Task <bool> TrySaveLapTelemetry(ILapInfo lapInfo)
        {
            if (lapInfo?.LapTelemetryInfo == null)
            {
                return(Task.FromResult(false));
            }

            Logger.Info($"Saving Telemetry for Lap:{lapInfo.LapNumber}");
            if (lapInfo.LapTelemetryInfo.IsPurged)
            {
                Logger.Error("Lap Is PURGED! Cannot Save");
                return(Task.FromResult(false));
            }

            Task <bool> returnTask = Task.Run(() => SaveLapTelemetrySync(lapInfo));

            returnTask.ConfigureAwait(false);
            return(returnTask);
        }
예제 #25
0
파일: LapInfo.cs 프로젝트: tsofron/trails
        public LapInfo(ILapInfo k, ILapInfo l)
        {
            this.TotalTime           = k.TotalTime + l.TotalTime;
            this.TotalDistanceMeters = k.TotalDistanceMeters + l.TotalDistanceMeters;

            this.TotalCalories = k.TotalCalories + l.TotalCalories;

            this.AverageCadencePerMinute = (float)((k.AverageCadencePerMinute * k.TotalTime.TotalSeconds + l.AverageCadencePerMinute * l.TotalTime.TotalSeconds) /
                                                   this.TotalTime.TotalSeconds);
            this.AverageHeartRatePerMinute = (float)((k.AverageHeartRatePerMinute * k.TotalTime.TotalSeconds + l.AverageHeartRatePerMinute * l.TotalTime.TotalSeconds) /
                                                     this.TotalTime.TotalSeconds);
            this.AveragePowerWatts = (float)((k.AveragePowerWatts * k.TotalTime.TotalSeconds + l.AveragePowerWatts * l.TotalTime.TotalSeconds) /
                                             this.TotalTime.TotalSeconds);

            //The next fields are not really mergeable manually...
            this.Rest = k.Rest && l.Rest;
            this.ElevationChangeMeters = k.ElevationChangeMeters + l.ElevationChangeMeters;
            this.StartTime             = k.StartTime < l.StartTime ? k.StartTime : l.StartTime;
            //TBD - ILapPoolLengths not implemented, not a limitation
            //this.m_PoolLengths = new PoolLengthInfo(k.PoolLengths, l.PoolLengths);
        }
예제 #26
0
        public bool EvaluateFastestLapCandidate(ILapInfo lapInfo)
        {
            if (!lapInfo.Valid || !lapInfo.Driver.IsPlayer || !_isEnabled)
            {
                return(false);
            }

            bool isTrackRecord   = EvaluateAsTrackRecord(lapInfo);
            bool isClassRecord   = EvaluateAsClassRecord(lapInfo);
            bool isVehicleRecord = EvaluateAsVehicleRecord(lapInfo);

            TrackRecordsViewModel.TrackRecord.IsHighlighted   = isTrackRecord;
            TrackRecordsViewModel.ClassRecord.IsHighlighted   = isClassRecord;
            TrackRecordsViewModel.VehicleRecord.IsHighlighted = isVehicleRecord;

            if (isVehicleRecord || isClassRecord || isTrackRecord)
            {
                RefreshViewModel();
            }

            return(isVehicleRecord || isClassRecord || isTrackRecord);
        }
예제 #27
0
 public LapEventArgs(ILapInfo lapInfo)
 {
     Lap = lapInfo;
 }
예제 #28
0
        public override string GetText(object element, TreeList.Column column)
        {
            Data.TrailResult row = (element as TrailResultWrapper).Result;

            //Some special for Summary
            if (row is SummaryTrailResult)
            {
                switch (column.Id)
                {
                case TrailResultColumnIds.AveragePowerBalance:
                case TrailResultColumnIds.AverageTemperature:
                case TrailResultColumnIds.AverageGroundContactTime:
                case TrailResultColumnIds.AverageVerticalOscillation:
                case TrailResultColumnIds.AverageSaturatedHemoglobin:
                case TrailResultColumnIds.AverageTotalHemoglobinConcentration:
                    //No implementation, ignore
                    return(null);

                default:
                    if (!Controller.TrailController.Instance.ExplicitSelection &&
                        TrailResultColumnIds.ClimbFields.Contains(column.Id) && !row.ClimbCalculated)
                    {
                        //Potentially many selections (of Ascent etc), no value set
                        return(null);
                    }
                    break;
                }

                if (TrailsPlugin.Data.Settings.ResultSummaryStdDev)
                {
                    SummaryTrailResult row2 = row as SummaryTrailResult;
                    if (!row2.IsTotal && row2.Results.Count > 1)
                    {
                        switch (column.Id)
                        {
                        case TrailResultColumnIds.StartTime:
                            //Not interesting to average time when only one activity. Other multi may be interesting.
                            if (row2.Activities.Count <= 1)
                            {
                                return(null);
                            }
                            //Only time of day, averaged
                            return(row.StartTime.ToLocalTime().ToString("T"));

                        case TrailResultColumnIds.Duration:
                        {
                            SummaryValue <TimeSpan> a = row2.DurationStdDev();
                            return(UnitUtil.Time.ToString(a.Value, "") + " σ" + UnitUtil.Time.ToString(a.StdDev, ""));
                        }

                        case TrailResultColumnIds.Distance:
                        {
                            SummaryValue <double> a = row2.DistanceStdDev();
                            string d;
                            if (row.PoolLengthInfo != null)
                            {
                                d = UnitUtil.Distance.ToString(a.Value, row.PoolLengthInfo.DistanceUnits, "F0");
                            }
                            else
                            {
                                d = UnitUtil.Distance.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "");
                            }
                            return(d + " σ" + UnitUtil.Elevation.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""));
                        }

                        case TrailResultColumnIds.AvgPace:
                        {
                            SummaryValue <double> a = row2.AvgPaceStdDev();
                            return(UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""));
                        }

                        case TrailResultColumnIds.AvgSpeed:
                        {
                            SummaryValue <double> a = row2.AvgSpeedStdDev();
                            return(UnitUtil.Speed.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Speed.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""));
                        }

                        case TrailResultColumnIds.AvgSpeedPace:
                        {
                            SummaryValue <double> a;
                            if (UnitUtil.PaceOrSpeed.IsPace(Controller.TrailController.Instance.ReferenceActivity))
                            {
                                a = row2.AvgPaceStdDev();
                                return(UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""));
                            }
                            else
                            {
                                a = row2.AvgSpeedStdDev();
                                return(UnitUtil.Speed.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Speed.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""));
                            }
                        }

                        //case TrailResultColumnIds.GradeRunAdjustedTime:
                        //    {
                        //        SummaryValue<double> a = row2.GradeRunAdjustedTimeStdDev();
                        //        return UnitUtil.Time.ToString(a.Value, "") + " σ" + UnitUtil.Time.ToString(a.StdDev, "");
                        //    }
                        //case TrailResultColumnIds.GradeRunAdjustedPace:
                        //    {
                        //        SummaryValue<TimeSpan> a = row2.GradeRunAdjustedPaceStdDev();
                        //        return UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "");
                        //    }
                        //case TrailResultColumnIds.Diff:
                        //    {
                        //        SummaryValue<double> a = row2.DiffStdDev();
                        //        return UnitUtil.Elevation.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Elevation.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "");
                        //    }
                        default:
                            break;
                        }
                    }
                }
            }

            if (row is PausedChildTrailResult)
            {
                switch (column.Id)
                {
                //Some paused fields should not be visible
                case TrailResultColumnIds.Order:
                    return(null);

                default:
                    break;
                }
            }

            if (row is SubChildTrailResult)
            {
                switch (column.Id)
                {
                //Ignore wildly inaccurate data, few points for Pool swimming, can be lower than Avg
                //(not always good on lap level too)
                case TrailResultColumnIds.FastestSpeed:
                case TrailResultColumnIds.FastestPace:
                    return(null);

                default:
                    break;
                }
            }

            switch (column.Id)
            {
            case TrailResultColumnIds.ResultColor:
                return(null);

            //String output without formatting
            case TrailResultColumnIds.Order:
            case TrailResultColumnIds.Name:
            case TrailResultColumnIds.TrailName:
                return(base.GetText(row, column));

            case TrailResultColumnIds.StartTime:
                if (row.Activity == null)
                {
                    return(null);
                }
                string date = "";
                if (m_multiple)
                {
                    date = row.StartTime.ToLocalTime().ToShortDateString() + " ";
                }
                return(date + row.StartTime.ToLocalTime().ToString("T"));

            case TrailResultColumnIds.StartDistance:
                if (row.PoolLengthInfo != null)
                {
                    return(UnitUtil.Distance.ToString(row.StartDistance, row.PoolLengthInfo.DistanceUnits, "F0u"));
                }
                else
                {
                    return(UnitUtil.Distance.ToString(row.StartDistance, Controller.TrailController.Instance.ReferenceActivity, ""));
                }

            case TrailResultColumnIds.EndTime:
                if (row.Activity == null)
                {
                    return(null);
                }
                return(row.EndTime.ToLocalTime().ToString("T"));

            case TrailResultColumnIds.Duration:
                return(UnitUtil.Time.ToString(row.Duration, ""));

            case TrailResultColumnIds.Distance:
                if (row.PoolLengthInfo != null)
                {
                    return(UnitUtil.Distance.ToString(row.Distance, row.PoolLengthInfo.DistanceUnits, "F0u"));
                }
                else
                {
                    return(UnitUtil.Distance.ToString(row.Distance, Controller.TrailController.Instance.ReferenceActivity, ""));
                }

            case TrailResultColumnIds.AvgCadence:
                return(UnitUtil.Cadence.ToString(row.AvgCadence));

            case TrailResultColumnIds.AvgHR:
                return(UnitUtil.HeartRate.ToString(row.AvgHR));

            case TrailResultColumnIds.MaxHR:
                return(UnitUtil.HeartRate.ToString(row.MaxHR));

            case TrailResultColumnIds.Ascent:
                return(UnitUtil.Elevation.ToString(row.Ascent));

            case TrailResultColumnIds.Descent:
                return(UnitUtil.Elevation.ToString(row.Descent));

            case TrailResultColumnIds.ElevChg:
                return((row.ElevChg > 0 ? "+" : "") + UnitUtil.Elevation.ToString(row.ElevChg, ""));

            case TrailResultColumnIds.AvgPower:
                return(UnitUtil.Power.ToString(row.AvgPower));

            case TrailResultColumnIds.AscAvgGrade:
                return((row.AscAvgGrade).ToString("0.0%"));

            case TrailResultColumnIds.AscMaxAvgGrade:
                return((row.AscMaxAvgGrade).ToString("0.0%"));

            case TrailResultColumnIds.DescAvgGrade:
                return((row.DescAvgGrade).ToString("0.0%"));

            case TrailResultColumnIds.AvgSpeed:
                return(UnitUtil.Speed.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.FastestSpeed:
                return(UnitUtil.Speed.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.AvgPace:
                return(UnitUtil.Pace.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.FastestPace:
                return(UnitUtil.Pace.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.AvgSpeedPace:
                return(UnitUtil.PaceOrSpeed.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.FastestSpeedPace:
                return(UnitUtil.PaceOrSpeed.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.PredictDistance:
                return(UnitUtil.Time.ToString(row.PredictDistance, ""));

            case TrailResultColumnIds.IdealTime:
                return(UnitUtil.Time.ToString(row.IdealTime, ""));

            case TrailResultColumnIds.GradeRunAdjustedTime:
                return(UnitUtil.Time.ToString(row.GradeRunAdjustedTime, ""));

            case TrailResultColumnIds.GradeRunAdjustedPace:
                return(UnitUtil.Pace.ToString(row.GradeRunAdjustedSpeed, Controller.TrailController.Instance.ReferenceActivity, ""));

            case TrailResultColumnIds.Diff:
                return(UnitUtil.Elevation.ToString(row.Diff, ""));

            case TrailResultColumnIds.AscendingSpeed_VAM:
                return(UnitUtil.Elevation.ToString(row.AscendingSpeed_VAM, ""));

            case TrailResultColumnIds.AveragePowerBalance:
                return((row.AveragePowerBalance / 100).ToString("0.0%"));

            case TrailResultColumnIds.AverageTemperature:
                return((row.AverageTemperature).ToString("0.0"));

            case TrailResultColumnIds.AverageGroundContactTime:
                return((row.AverageGroundContactTime).ToString("0"));

            case TrailResultColumnIds.AverageVerticalOscillation:
                return((row.AverageVerticalOscillation).ToString("0.0"));

            case TrailResultColumnIds.AverageSaturatedHemoglobin:
                return((row.AverageSaturatedHemoglobin / 100).ToString("0.0%"));

            case TrailResultColumnIds.AverageTotalHemoglobinConcentration:
                return((row.AverageTotalHemoglobinConcentration).ToString("0.0"));

            default:

                if (TrailResultColumns.IsLapField(column.Id))
                {
                    ILapInfo lap = row.LapInfo;
                    if (lap != null)
                    {
                        //The column Id is faked to not clash with the internal ids
                        TreeList.Column c = new TreeList.Column(TrailResultColumns.LapId(column.Id));
                        return(base.GetText(lap, c));
                    }
                    //Not Splits trail
                    return(null);
                }
                else if (TrailResultColumns.IsSwimLapField(column.Id))
                {
                    IPoolLengthInfo lap = row.PoolLengthInfo;
                    if (lap != null)
                    {
                        //The column Id is faked to not clash with the internal ids
                        TreeList.Column c = new TreeList.Column(TrailResultColumns.SwimLapId(column.Id));
                        return(base.GetText(lap, c));
                    }
                    //Not Splits trail
                    return(null);
                }
                else if (TrailResultColumns.IsActivityField(column.Id))
                {
                    if (row is ParentTrailResult)
                    {
                        if (row.Activity == null)
                        {
                            return(null);
                        }
                        if (column.Id == TrailResultColumnIds.MetaData_Source)
                        {
                            return(row.Activity.Metadata.Source);
                        }
                        return(base.GetText(row.Activity, column));
                    }
                    return(null);
                }
                else
                {
                    if (row.Activity == null)
                    {
                        return(null);
                    }
                    ICustomDataFieldDefinition cust = TrailResultColumns.CustomDef(column.Id);
                    if (cust != null)
                    {
                        if (row is ParentTrailResult)
                        {
                            return(row.Activity.GetCustomDataValue(TrailResultColumns.CustomDef(column.Id)).ToString());
                        }
                        return(null);
                    }
                }

                System.Diagnostics.Debug.Assert(false, string.Format("No label info for id {0}", column.Id));
                return(null);
            }
        }
예제 #29
0
 public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, ILapInfo previousLapInfo) :
     this(dataSet, lapNumber, driver, false, previousLapInfo)
 {
 }
예제 #30
0
파일: Trail.cs 프로젝트: tsofron/trails
        public static TrailResultInfo TrailResultInfoFromSplits(IActivity activity, bool onlyActiveLaps)
        {
            TrailResultInfo results = new TrailResultInfo(activity, false);

            if (activity == null)
            {
                //summary result
                return(results);
            }

            //Get around a problem with only Rest laps
            if (onlyActiveLaps)
            {
                onlyActiveLaps = false;
                for (int j = 0; j < activity.Laps.Count; j++)
                {
                    if (!activity.Laps[j].Rest)
                    {
                        onlyActiveLaps = true;
                        break;
                    }
                }
            }

            bool lastIsRestlap = false;

            if (null == activity.Laps || 0 == activity.Laps.Count)
            {
                //Use MovingDistanceMetersTrack rather than ActualDistanceMetersTrack, assume similar activities have similar pauses/slow parts
                IDistanceDataTrack track = ActivityInfoCache.Instance.GetInfo(activity).MovingDistanceMetersTrack;
                if (track != null && track.Max > 0)
                {
                    //Create some kind of points - could be dependent on length
                    const float cDist = 1000;
                    float       dist  = 0;
                    while (dist < track.Max)
                    {
                        DateTime  time = track.GetTimeAtDistanceMeters(dist);
                        IGPSPoint p    = Utils.TrackUtil.getGpsLoc(activity, time);
                        if (p != null)
                        {
                            results.Points.Add(new TrailResultPoint(new TrailGPSLocation(p), time));
                        }
                        else
                        {
                            if (activity.GPSRoute == null || activity.GPSRoute.Count == 0)
                            {
                                results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), time, track.TotalElapsedSeconds));
                            }
                            else
                            {
                                System.Diagnostics.Debug.Assert(false, "out of GPS");
                                if (results.Points.Count > 0)
                                {
                                    //end insert
                                    break;
                                }
                            }
                        }
                        dist = Math.Min(track.Max, dist + cDist);
                    }
                }
                else
                {
                    DateTime  time = ActivityInfoCache.Instance.GetInfo(activity).ActualTrackStart;
                    IGPSPoint p    = Utils.TrackUtil.getGpsLoc(activity, time);
                    if (p != null)
                    {
                        results.Points.Add(new TrailResultPoint(new TrailGPSLocation(p), time));
                    }
                }
            }
            else
            {
                int subresultIndex = 1;
                for (int j = 0; j < activity.Laps.Count; j++)
                {
                    ILapInfo l = activity.Laps[j];
                    if (!onlyActiveLaps || !l.Rest || j > 0 && !activity.Laps[j - 1].Rest)
                    {
                        string name = l.Notes;
                        if (string.IsNullOrEmpty(name))
                        {
                            name = "#" + (results.Points.Count + 1);
                        }
                        DateTime d = l.StartTime;
                        if (activity.GPSRoute == null || activity.GPSRoute.Count == 0)
                        {
                            results.Points.Add(new TrailResultPoint(new TrailGPSLocation(name, !l.Rest), d, l.TotalTime, l));
                        }
                        else
                        {
                            IGPSPoint t = Utils.TrackUtil.getGpsLoc(activity, d);
                            if (t != null)
                            {
                                results.Points.Add(new TrailResultPoint(new TrailGPSLocation(t, name, !l.Rest), d, l.TotalTime, l));
                            }
                        }
                        if (//All swim related have at least one PoolLength for each lap
                            l.PoolLengths != null && (l.PoolLengths.Count > 0))
                        {
                            TrailResultPoint tp = results.Points[results.Points.Count - 1];
                            foreach (IPoolLengthInfo p in l.PoolLengths)
                            {
                                DateTime        d2 = p.StartTime;
                                IPoolLengthInfo p1 = PoolLengthInfo.GetPoolLength(p);
                                tp.SubPoints.Add(new TrailResultPoint(new TrailGPSLocation(null, !l.Rest), d2, p.TotalTime, p1, subresultIndex++));
                            }
                            //Need (dummy) last point
                            IPoolLengthInfo p2 = tp.SubPoints[tp.SubPoints.Count - 1].PoolLengthInfo;
                            tp.SubPoints.Add(new TrailResultPoint(new TrailGPSLocation(null, !l.Rest), p2.StartTime + p2.TotalTime, TimeSpan.Zero, p2, subresultIndex));
                        }
                    }
                }
                lastIsRestlap = activity.Laps[activity.Laps.Count - 1].Rest;
            }

            //Add end point, except if last is a rest lap (where last already is added)
            if (!onlyActiveLaps || !lastIsRestlap)
            {
                DateTime d = ActivityInfoCache.Instance.GetInfo(activity).ActualTrackEnd;
                if (activity.GPSRoute == null || activity.GPSRoute.Count == 0)
                {
                    results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, !lastIsRestlap), d));
                }
                else
                {
                    IGPSPoint t = Utils.TrackUtil.getGpsLoc(activity, d);
                    if (t != null)
                    {
                        results.Points.Add(new TrailResultPoint(new TrailGPSLocation(t, activity.Name, !lastIsRestlap), d));
                    }
                }
            }

            //Special for activities without any GPS info
            if (results.Count == 0 && activity.HasStartTime)
            {
                results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), activity.StartTime));
                results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), activity.StartTime + activity.TotalTimeEntered));
            }

            //A trail created from splits should not define elevation points
            foreach (TrailGPSLocation t in results.Points)
            {
                t.SetElevation(float.NaN);
            }

            return(results);
        }