< Summary

Class:OrthogonalEvasion
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Evasion/OrthogonalEvasion.cs
Covered lines:1
Uncovered lines:34
Coverable lines:35
Total lines:78
Line coverage:2.8% (1 of 35)
Covered branches:0
Total branches:0
Covered methods:1
Total methods:3
Method coverage:33.3% (1 of 3)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
OrthogonalEvasion(...)0%110100%
ShouldEvade(...)0%1321100%
Evade(...)0%56700%

File(s)

/github/workspace/Assets/Scripts/Evasion/OrthogonalEvasion.cs

#LineLine coverage
 1using UnityEngine;
 2
 3// The agent will try to evade its pursuer by turning its velocity vector to be orthogonal to the
 4// pursuer's velocity vector.
 5//
 6// Turning orthogonal to the pursuer means that the pursuer needs to apply a normal acceleration to
 7// intercept the agent, incurring the maximum possible lift-induced drag.
 8public class OrthogonalEvasion : EvasionBase {
 28659  public OrthogonalEvasion(IAgent agent) : base(agent) {}
 10
 11  // Determine whether to perform any evasive maneuvers.
 012  public override bool ShouldEvade(IAgent pursuer) {
 013    if (!(Agent.AgentConfig?.DynamicConfig?.FlightConfig?.EvasionConfig?.Enabled ?? false)) {
 014      return false;
 15    }
 16
 017    SensorOutput sensorOutput = Agent.Sensor.Sense(pursuer);
 018    float evasionRangeThreshold =
 19        Agent.AgentConfig.DynamicConfig.FlightConfig.EvasionConfig.RangeThreshold;
 020    return sensorOutput.Position.Range <= evasionRangeThreshold && sensorOutput.Velocity.Range < 0;
 021  }
 22
 23  // Calculate the acceleration input to evade the pursuer.
 024  public override Vector3 Evade(IAgent pursuer) {
 25    const float epsilon = 1e-6f;
 26    const float groundProximityThresholdFactor = 5f;
 27    const float groundAvoidanceUpFactor = 5f;
 28
 029    Vector3 agentPosition = Agent.Position;
 030    Vector3 agentVelocity = Agent.Velocity;
 031    Vector3 pursuerPosition = pursuer.Position;
 032    Vector3 pursuerVelocity = pursuer.Velocity;
 33
 34    // Evade the pursuer by turning the velocity to be orthogonal to the pursuer's velocity.
 035    Vector3 normalVelocity = Vector3.ProjectOnPlane(agentVelocity, pursuerVelocity);
 036    if (normalVelocity.sqrMagnitude < epsilon) {
 37      // If the agent's velocity is aligned with the pursuer's velocity, choose a random normal
 38      // direction in which to evade.
 039      normalVelocity = pursuer.Right;
 040    }
 41    // If the agent's velocity is aligned with the normal velocity, i.e., orthogonal to the
 42    // pursuer's velocity, then the normal acceleration should be zero as the agent should continue
 43    // in the same direction.
 044    Vector3 normalAccelerationDirection =
 45        Vector3.ProjectOnPlane(normalVelocity, agentVelocity).normalized;
 46
 47    // Turn away from the pursuer.
 048    Vector3 relativePosition = pursuerPosition - agentPosition;
 049    if (Vector3.Dot(relativePosition, normalAccelerationDirection) > 0) {
 050      normalAccelerationDirection *= -1;
 051    }
 52
 53    // Avoid evading straight down when near the ground.
 054    float altitude = agentPosition.y;
 055    float groundProximityThreshold = Mathf.Abs(agentVelocity.y) * groundProximityThresholdFactor;
 056    if (agentVelocity.y < 0 && altitude < groundProximityThreshold) {
 57      // Determine the evasion direction based on the angle to pursuer.
 058      float angle = Vector3.SignedAngle(Agent.Forward, relativePosition, Vector3.up);
 59
 60      // Choose the direction that leads away from the pursuer.
 061      Vector3 rightDirection = Agent.Right;
 062      Vector3 bestHorizontalDirection = angle > 0 ? -rightDirection : rightDirection;
 63
 64      // Blend between horizontal evasion and slight upward movement.
 065      float blendFactor = 1 - (altitude / groundProximityThreshold);
 066      normalAccelerationDirection =
 67          Vector3
 68              .Lerp(normalAccelerationDirection,
 69                    bestHorizontalDirection + Agent.Up * groundAvoidanceUpFactor, blendFactor)
 70              .normalized;
 071    }
 072    Vector3 normalAcceleration = normalAccelerationDirection * Agent.MaxNormalAcceleration();
 73
 74    // Apply the maximum forward acceleration.
 075    Vector3 forwardAcceleration = Agent.Forward * Agent.MaxForwardAcceleration();
 076    return normalAcceleration + forwardAcceleration;
 077  }
 78}