/// <summary> /// compare the new state to the last values and determine if a tack has occured /// if so, update the state with the new tack /// </summary> /// <param name="state"></param> private void CheckForTack(State state) { var latest = _history.Last(); var deltas = _history.Where(x=>x.Time > latest.Time - _tackThresholdTime).Select(x => Math.Abs(AngleUtilities.AngleDifference(latest.CourseOverGroundRadians, x.CourseOverGroundRadians))).Max(); if(deltas>_tackThreshold) { //tack detected _lastTackAt = latest.Time; var priorToTack = _history.Where(x => x.Time < latest.Time - _dataExclusionTime).OrderByDescending(x => x.Time).FirstOrDefault(); if (priorToTack != null) { _previousTackCourseOverGroundRadians = priorToTack.CourseOverGroundRadians; } else { _previousTackCourseOverGroundRadians = null; } _history.Clear(); _currentTackStartCourseOverGroundRadians = null; var difference = AngleUtilities.AngleDifference(_previousTackCourseOverGroundRadians.Value, latest.CourseOverGroundRadians); var differenceDegrees = AngleUtilities.RadiansToDegrees(difference); string message = string.Format("Tack: {0:0.0}°", differenceDegrees); _logger.Info(message); state.AddMessage(MessageCategory.Tactical, MessagePriority.Normal, 5, message); //record the tack in the state if (state.RaceStarted && _currentTack != null) { _currentTack.CourseOverGround = AngleUtilities.RadiansToDegrees (_previousTackCourseOverGroundRadians.Value); state.Tacks.Add (_currentTack); } _currentTack = new Tack (); _currentTack.At = latest.Time; } }
public void RecordTack (Tack tack) { //TODO: consider adding true wind angle or dir? _connection.Execute ("insert into Tack (start,endcourseoverground) values (@At,@CourseOverGround)", tack); //TODO: there has to be a better way to do this tack.Id = (long)_connection.ExecuteScalar ("select max(id) from Tack"); }