public uint AverageLaptimeBySplit(DateTime lapStart, MsgCarUpdate tminus1, MsgCarUpdate t0) { // We need to remove the failure that the 1s interval brings. Basically we want to know // (or calculate) when the driver exactly was at the spline-split // Difference of the Splines var splineDiff = t0.NormalizedSplinePosition - tminus1.NormalizedSplinePosition; // Split float splineSplit = (int)(t0.NormalizedSplinePosition * 10); splineSplit /= 10; // Ratio: var ratio = (t0.NormalizedSplinePosition - splineSplit) / splineDiff; // Timediff in MS var timeDiff = 1000 - t0.CreationDate.Subtract(tminus1.CreationDate).TotalMilliseconds; var timeOff = timeDiff * (1 - ratio); var result = (uint)Math.Round(t0.CreationDate.Subtract(lapStart).TotalMilliseconds - timeOff); string.Format("Spline={0:F3}, TimeOff={1:N0}ms, Result={2:N0}", t0.NormalizedSplinePosition, timeOff, result); return(result); }
// Returns true if car just crossed starting line during the race public bool OnCarUpdate(MsgCarUpdate msg) { // Logging.Debug("Car update: " + msg.CarId + ", pos: " + msg.NormalizedSplinePosition); if (msg.CarId >= Leaderboard.Count) { return(false); } var item = Leaderboard[msg.CarId]; item.CurrentLapProgress = msg.NormalizedSplinePosition; _positionHelperList.Sort(_lapProgressComparer); item.CurrentRacePosition = _positionHelperList.IndexOf(item) + 1; item.Location = new AcDriverLocation(msg.WorldPosition.X, msg.WorldPosition.Z); // Trying to register first lap if (!item.CurrentLapValid && _inRaceSession && msg.NormalizedSplinePosition < 0.1d && msg.Velocity.Length() > 0.5f) { item.CurrentLapValid = true; item.CurrentLapStart = DateTime.Now; return(true); } return(false); }
// That cache<MsgCarUpdate> should be replaced by a cache<CarUpdateThing> that also stores // the timestamp, otherwise calculations are always squishy (and e.g. dependent on the interval) public void UpdatePosition(MsgCarUpdate msg, TimeSpan realtimeUpdateInterval) { UpdatePosition(msg.WorldPosition, msg.Velocity, msg.NormalizedSplinePosition, realtimeUpdateInterval); if (MsgCarUpdateCacheSize > 0) { // We have to protect this cache from higher realtimeUpdateIntervals as requested if (_carUpdateCache.Count == 0 || (msg.CreationDate - _carUpdateCache.Last.Value.CreationDate).TotalMilliseconds >= realtimeUpdateInterval.TotalMilliseconds * 0.9991) { var node = _carUpdateCache.AddLast(msg); if (_carUpdateCache.Count > MsgCarUpdateCacheSize) { _carUpdateCache.RemoveFirst(); } if (_carUpdateCache.Count > 1) { // We could easily do car-specifc stuff here, e.g. calculate the distance driven between the intervals, // or a python-app like delta - maybe even a loss of control } } } }
protected override void OnCarUpdate(MsgCarUpdate msg) { base.OnCarUpdate(msg); }
public virtual void OnCarUpdate(MsgCarUpdate msg) { }
protected internal virtual void OnCarUpdate(MsgCarUpdate msg) { }