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); } }
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); } }
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)); }
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); }
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); }
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)); }
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; }
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(); }
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); }
protected virtual async Task HandleCurrentLapNumberChangedAsync() { if (Session != null) { CurrentLap = Session.TelemetrySessionData?.Laps.FirstOrDefault(l => l.LapNumber == CurrentLapNumber); } else { CurrentLap = null; } await NotifyCurrentLapNumberChangedAsync(); }
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; }
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); } }
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 }); }
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; }
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); }
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); }
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); } }
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); }
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); }
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); }
public LapEventArgs(ILapInfo lapInfo) { Lap = lapInfo; }
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); } }
public LapInfo(SimulatorDataSet dataSet, int lapNumber, DriverTiming driver, ILapInfo previousLapInfo) : this(dataSet, lapNumber, driver, false, previousLapInfo) { }
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); }