private Penalty DistanceInfringementPenalty(double calcDistance, double pctInfringement, string description) { // Rule 13.3.5 Penalty penalty; if (pctInfringement <= 0) { penalty = null; } else if (pctInfringement <= 25) { penalty = new Penalty(string.Format("R13.3.5: {1} {0:0m} <= 25%", calcDistance, description), PenaltyType.TaskPoints, (int)(Math.Round(2 * pctInfringement / 0.1, 0))); } else //if (pctInfringement > 25) { penalty = new Penalty(Result.NewNoResult(string.Format("R13.3.5: {1} {0:0m} > 25%", calcDistance, description))); } return(penalty); }
public override void Process() { base.Process(); // parse and resolve pilot dependent values // the static values are already defined // syntax is already checked //TODO: apply globally instead of a per task basis switch (Definition.ObjectType) { default: throw new ArgumentException("Unknown penalty type '" + Definition.ObjectType + "'"); case "BPZ": { var sortedTasks = from obj in Engine.Heap.Values where obj is ScriptingTask orderby((ScriptingTask)obj).TaskOrder select obj as ScriptingTask; var firstPoint = Engine.Report.TakeOffPoint; var done = false; foreach (var task in sortedTasks) { if (done) { break; } var lastPoint = task.Result.LastUsedPoint; if (lastPoint == null) { lastPoint = Engine.Report.LandingPoint; done = true; } var currentTrack = new Track(Engine.Report.FlightTrack) .Filter(p => p.Time >= firstPoint.Time && p.Time <= lastPoint.Time); var penaltyPoints = area.BpzPenalty(currentTrack); if (penaltyPoints > 0) { var infringement = new Penalty("R7.3.6 " + description, PenaltyType.CompetitionPoints, penaltyPoints); infringement.InfringingTrack = area.FilterTrack(currentTrack); Infringements.Add(infringement); task.Penalties.Add(infringement); } firstPoint = lastPoint; } } break; case "RPZ": { var sortedTasks = from obj in Engine.Heap.Values where obj is ScriptingTask orderby((ScriptingTask)obj).TaskOrder select obj as ScriptingTask; var firstPoint = Engine.Report.TakeOffPoint; var done = false; foreach (var task in sortedTasks) { if (done) { break; } var lastPoint = task.Result.LastUsedPoint; if (lastPoint == null) { lastPoint = Engine.Report.LandingPoint; done = true; } var currentTrack = new Track(Engine.Report.FlightTrack) .Filter(p => p.Time >= firstPoint.Time && p.Time <= lastPoint.Time); var penaltyPoints = area.RpzPenalty(currentTrack); if (penaltyPoints > 0) { var infringement = new Penalty("R7.3.4 " + description, PenaltyType.CompetitionPoints, penaltyPoints); infringement.InfringingTrack = area.FilterTrack(currentTrack); Infringements.Add(infringement); task.Penalties.Add(infringement); } firstPoint = lastPoint; } } break; case "VSMAX": //TODO: implement VSMAX { var sortedTasks = from obj in Engine.Heap.Values where obj is ScriptingTask orderby((ScriptingTask)obj).TaskOrder select obj as ScriptingTask; var firstPoint = Engine.Report.TakeOffPoint; var done = false; foreach (var task in sortedTasks) { if (done) { break; } var lastPoint = task.Result.LastUsedPoint; if (lastPoint == null) { lastPoint = Engine.Report.LandingPoint; done = true; } var infringingTrack = new Track(Engine.Report.FlightTrack) .Filter(p => p.Time >= firstPoint.Time && p.Time <= lastPoint.Time) .FilterPairs((p1, p2) => Math.Abs(Physics.VerticalVelocity(p1, p2)) > maxSpeed) .FilterSegments((p1, p2) => (p2.Time - p1.Time).TotalSeconds > 15); foreach (var str in infringingTrack.ToStringList()) { task.AddNote("Max ascent/descent rate exceeded " + str, true); //task.AddNote( // string.Format("Max ascent/descent rate exceeded from {0} to {1}: {2:0} ft/min for {3} sec", // first.ToString(AXPointInfo.Time).TrimEnd(), // last.ToString(AXPointInfo.Time).TrimEnd(), // Physics.VerticalVelocity(first, last) * Physics.METERS2FEET * 60, // (last.Time - first.Time).TotalSeconds), true); } firstPoint = lastPoint; } } break; } if (Infringements.Count == 0) { AddNote("not infringed"); } }