< Summary

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
IterativeLaunchPlanner(...)0%2100%
Plan()0%42600%

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)
 027      : base(launchAnglePlanner, predictor) {}
 28
 29  // Plan the launch.
 030  public override LaunchPlan Plan() {
 031    PredictorState initialState = _predictor.Predict(time: 0);
 032    Vector3 targetPosition = initialState.Position;
 33
 034    LaunchAngleOutput launchAngleOutput = new LaunchAngleOutput();
 035    Vector3 interceptPosition = new Vector3();
 036    for (int i = 0; i < MaxNumIterations; ++i) {
 37      // Estimate the time-to-intercept.
 038      launchAngleOutput = _launchAnglePlanner.Plan(targetPosition);
 039      float timeToIntercept = launchAngleOutput.TimeToPosition;
 40
 41      // Estimate the target position.
 042      PredictorState predictedState = _predictor.Predict(timeToIntercept);
 043      targetPosition = predictedState.Position;
 44
 45      // Check whether the intercept direction has changed, in which case the algorithm has
 46      // converged.
 047      Vector3 newInterceptPosition = _launchAnglePlanner.GetInterceptPosition(targetPosition);
 048      if ((interceptPosition - newInterceptPosition).magnitude < ConvergenceThreshold) {
 049        interceptPosition = newInterceptPosition;
 050        break;
 51      }
 052      interceptPosition = newInterceptPosition;
 53
 54      // Check that the target is moving towards the intercept position. Otherwise, the interceptor
 55      // should wait to be launched.
 056      Vector3 targetToInterceptPosition = interceptPosition - initialState.Position;
 057      Vector3 targetToPredictedPosition = targetPosition - initialState.Position;
 058      if (Vector3.Dot(targetToInterceptPosition, targetToPredictedPosition) < 0) {
 059        return LaunchPlan.NoLaunch;
 60      }
 061    }
 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.
 066    Vector3 interceptorToInterceptPosition = interceptPosition;
 067    Vector3 threatToPredictedPosition = targetPosition - initialState.Position;
 068    if (Vector3.Dot(interceptorToInterceptPosition, threatToPredictedPosition) > 0) {
 069      return LaunchPlan.NoLaunch;
 70    }
 71
 72    // Check that the intercept position and the predicted position are within some threshold
 73    // distance of each other.
 074    if (Vector3.Distance(interceptPosition, targetPosition) < InterceptPositionThreshold) {
 075      return new LaunchPlan(launchAngleOutput.LaunchAngle, targetPosition);
 76    }
 077    return LaunchPlan.NoLaunch;
 078  }
 79}