< Summary

Class:IterativeLaunchPlanner
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Algorithms/Planning/IterativeLaunchPlanner.cs
Covered lines:29
Uncovered lines:0
Coverable lines:29
Total lines:79
Line coverage:100% (29 of 29)
Covered branches:0
Total branches:0
Covered methods:2
Total methods:2
Method coverage:100% (2 of 2)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
IterativeLaunchPlanner(...)0%110100%
Plan()0%660100%

File(s)

/github/workspace/Assets/Scripts/Algorithms/Planning/IterativeLaunchPlanner.cs

#LineLine coverage
 1using UnityEngine;
 2
 3// The iterative launch planner class is a launch planner that performs an iterative process to
 4// determine the intercept point. The algorithm continuously performs the following 2-step iterative
 5// process:
 6//  1. Time-to-intercept estimation: The algorithm determines the time it takes the interceptor to
 7//  reach the target at the predicted intercept position, which is initialized to the target's
 8//  current position.
 9//  2. Intercept position estimation: The algorithm predicts the target position at the estimated
 10//  time-to-intercept.
 11public class IterativeLaunchPlanner : ILaunchPlanner {
 12  // Maximum number of iterations before declaring failure. In certain cases, the predictor and
 13  // planner do not converge, so we need to limit the number of iterations.
 14  private const int MaxNumIterations = 10;
 15
 16  // Convergence threshold in meters for the difference vector magnitude. Convergence is declared
 17  // when the intercept position has not changed by more than this threshold between iterations.
 18  private const float ConvergenceThreshold = 10f;
 19
 20  // Maximum intercept position threshold in meters to declare convergence. This threshold is used
 21  // as a final sanity check to ensure that the predicted target position and intercept position do
 22  // not differ by more than this threshold. This threshold should be set depending on the
 23  // granularity of the possible intercept positions.
 24  private const float InterceptPositionThreshold = 1000f;
 25
 26  public IterativeLaunchPlanner(ILaunchAnglePlanner launchAnglePlanner, IPredictor predictor)
 1827      : base(launchAnglePlanner, predictor) {}
 28
 29  // Plan the launch.
 630  public override LaunchPlan Plan() {
 631    PredictorState initialState = _predictor.Predict(time: 0);
 632    Vector3 targetPosition = initialState.Position;
 33
 634    LaunchAngleOutput launchAngleOutput = new LaunchAngleOutput();
 635    Vector3 interceptPosition = new Vector3();
 3336    for (int i = 0; i < MaxNumIterations; ++i) {
 37      // Estimate the time-to-intercept.
 1138      launchAngleOutput = _launchAnglePlanner.Plan(targetPosition);
 1139      float timeToIntercept = launchAngleOutput.TimeToPosition;
 40
 41      // Estimate the target position.
 1142      PredictorState predictedState = _predictor.Predict(timeToIntercept);
 1143      targetPosition = predictedState.Position;
 44
 45      // Check whether the intercept direction has changed, in which case the algorithm has
 46      // converged.
 1147      Vector3 newInterceptPosition = _launchAnglePlanner.GetInterceptPosition(targetPosition);
 1648      if ((interceptPosition - newInterceptPosition).magnitude < ConvergenceThreshold) {
 549        interceptPosition = newInterceptPosition;
 550        break;
 51      }
 652      interceptPosition = newInterceptPosition;
 53
 54      // Check that the target is moving towards the intercept position. Otherwise, the interceptor
 55      // should wait to be launched.
 656      Vector3 targetToInterceptPosition = interceptPosition - initialState.Position;
 657      Vector3 targetToPredictedPosition = targetPosition - initialState.Position;
 758      if (Vector3.Dot(targetToInterceptPosition, targetToPredictedPosition) < 0) {
 159        return LaunchPlan.NoLaunch;
 60      }
 561    }
 62
 63    // Check that the interceptor is moving towards the target. If the target is moving too fast,
 64    // the interceptor might be launched backwards because the intercept position and the predicted
 65    // position are behind the asset. In this case, the interceptor should wait to be launched.
 566    Vector3 interceptorToInterceptPosition = interceptPosition;
 567    Vector3 threatToPredictedPosition = targetPosition - initialState.Position;
 668    if (Vector3.Dot(interceptorToInterceptPosition, threatToPredictedPosition) > 0) {
 169      return LaunchPlan.NoLaunch;
 70    }
 71
 72    // Check that the intercept position and the predicted position are within some threshold
 73    // distance of each other.
 774    if (Vector3.Distance(interceptPosition, targetPosition) < InterceptPositionThreshold) {
 375      return new LaunchPlan(launchAngleOutput.LaunchAngle, targetPosition);
 76    }
 177    return LaunchPlan.NoLaunch;
 678  }
 79}