< Summary

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
IterativeLaunchPlanner(...)0%110100%
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 : LaunchPlannerBase {
 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)
 4227      : base(launchAnglePlanner, predictor) {}
 28
 29  // Plan the launch by finding the convergence point between the launch angle planner and the
 30  // predictor.
 031  public override LaunchPlan Plan() {
 032    PredictorState initialState = Predictor.Predict(time: 0f);
 033    Vector3 targetPosition = initialState.Position;
 34
 035    LaunchAngleOutput launchAngleOutput = new LaunchAngleOutput();
 036    Vector3 interceptPosition = new Vector3();
 037    for (int i = 0; i < _maxNumIterations; ++i) {
 38      // Estimate the time-to-intercept.
 039      launchAngleOutput = LaunchAnglePlanner.Plan(targetPosition);
 040      float timeToIntercept = launchAngleOutput.TimeToPosition;
 41
 42      // Estimate the target position.
 043      PredictorState predictedState = Predictor.Predict(timeToIntercept);
 044      targetPosition = predictedState.Position;
 45
 46      // Check whether the intercept direction has changed, in which case the algorithm has
 47      // converged.
 048      Vector3 newInterceptPosition = LaunchAnglePlanner.InterceptPosition(targetPosition);
 049      if ((interceptPosition - newInterceptPosition).magnitude < _convergenceThreshold) {
 050        interceptPosition = newInterceptPosition;
 051        break;
 52      }
 053      interceptPosition = newInterceptPosition;
 54
 55      // Check that the target is moving towards the intercept position. Otherwise, the interceptor
 56      // should wait to be launched.
 057      Vector3 targetToInterceptPosition = interceptPosition - initialState.Position;
 058      Vector3 targetToPredictedPosition = targetPosition - initialState.Position;
 059      if (Vector3.Dot(targetToInterceptPosition, targetToPredictedPosition) < 0) {
 060        return LaunchPlan.NoLaunch();
 61      }
 062    }
 63
 64    // Check that the interceptor is moving towards the target. If the target is moving too fast,
 65    // the interceptor might be launched backwards because the intercept position and the predicted
 66    // position are behind the asset. In this case, the interceptor should wait to be launched.
 067    Vector3 interceptorToInterceptPosition = interceptPosition - LaunchAnglePlanner.Agent.Position;
 068    Vector3 targetToPredictedTargetPosition = targetPosition - initialState.Position;
 069    if (Vector3.Dot(interceptorToInterceptPosition, targetToPredictedTargetPosition) > 0) {
 070      return LaunchPlan.NoLaunch();
 71    }
 72
 73    // Check that the intercept position and the predicted position are within some threshold
 74    // distance of each other.
 075    if (Vector3.Distance(interceptPosition, targetPosition) < _interceptPositionThreshold) {
 076      return new LaunchPlan {
 77        ShouldLaunch = true,
 78        LaunchAngle = launchAngleOutput.LaunchAngle,
 79        InterceptPosition = targetPosition,
 80      };
 81    }
 082    return LaunchPlan.NoLaunch();
 083  }
 84}