< Summary

Class:SpeedEscapeDetector
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Escape/SpeedEscapeDetector.cs
Covered lines:18
Uncovered lines:0
Coverable lines:18
Total lines:45
Line coverage:100% (18 of 18)
Covered branches:0
Total branches:0
Covered methods:3
Total methods:3
Method coverage:100% (3 of 3)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
SpeedEscapeDetector(...)0%110100%
IsEscaping(...)0%220100%
CalculatePredictedAgentSpeed(...)0%990100%

File(s)

/github/workspace/Assets/Scripts/Escape/SpeedEscapeDetector.cs

#LineLine coverage
 1using UnityEngine;
 2
 3// Speed escape detector.
 4//
 5// The speed escape detector checks whether the agent has a speed greater than the threat's when it
 6// has navigated to the threat's current position.
 7public class SpeedEscapeDetector : EscapeDetectorBase {
 8  // Minimum fractional speed to prevent division by zero.
 9  private const float _minFractionalSpeed = 1e-6f;
 10
 1211  public SpeedEscapeDetector(IAgent agent) : base(agent) {}
 12
 413  public override bool IsEscaping(IHierarchical target) {
 514    if (target == null) {
 115      return false;
 16    }
 17
 318    float predictedAgentSpeed = CalculatePredictedAgentSpeed(target.Position);
 319    return predictedAgentSpeed <= target.Speed;
 420  }
 21
 22  // Calculate the predicted agent speed when it has reached the target's current position.
 323  private float CalculatePredictedAgentSpeed(in Vector3 targetPosition) {
 24    // The speed decays exponentially with the traveled distance and with the bearing change.
 325    float distanceTimeConstant = 2 * (Agent.StaticConfig.BodyConfig?.Mass ?? 0) /
 26                                 (Constants.CalculateAirDensityAtAltitude(Agent.Position.y) *
 27                                  (Agent.StaticConfig.LiftDragConfig?.DragCoefficient ?? 0) *
 28                                  (Agent.StaticConfig.BodyConfig?.CrossSectionalArea ?? 0));
 329    float angleTimeConstant = Agent.StaticConfig.LiftDragConfig?.LiftDragRatio ?? 1;
 30    // During the turn, the minimum radius dictates the minimum distance needed to make the turn.
 331    float minTurningRadius = Agent.Velocity.sqrMagnitude / Agent.MaxNormalAcceleration();
 32
 333    Vector3 directionToTarget = targetPosition - Agent.Position;
 334    float distanceToTarget = directionToTarget.magnitude;
 335    float angleToTarget = Vector3.Angle(Agent.Velocity, directionToTarget) * Mathf.Deg2Rad;
 36    // The fractional speed is the product of the fractional speed after traveling the distance and
 37    // of the fractional speed after turning.
 338    float fractionalSpeed =
 39        Mathf.Exp(-((distanceToTarget + angleToTarget * minTurningRadius) / distanceTimeConstant +
 40                    angleToTarget / angleTimeConstant));
 41    // Prevent division by zero.
 342    fractionalSpeed = Mathf.Max(fractionalSpeed, _minFractionalSpeed);
 343    return fractionalSpeed * Agent.Speed;
 344  }
 45}