Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
9aff2bd
Implement all agent-related interfaces and base implementations
tryuan99 Oct 12, 2025
de1df58
Add unit tests for relative transformation
tryuan99 Oct 12, 2025
e53c687
Address comments
tryuan99 Oct 12, 2025
b5ff98b
Add interceptor and threat interfaces and base implementations
tryuan99 Oct 12, 2025
221e3ab
Maintain a list of pursuers in hierarchical object
tryuan99 Oct 12, 2025
072c1d3
Remove flight plan from attack behavior
tryuan99 Oct 12, 2025
c58ad6b
Rename existing Cluster to ClusterLegacy
tryuan99 Oct 12, 2025
6639b6f
Add clustering algorithm interface and base implementations
tryuan99 Oct 12, 2025
8d01173
Add legacy to PredictorState and IPredictor
tryuan99 Oct 12, 2025
cb8fc2b
Add argument annotations for FixedHierarchical
tryuan99 Oct 12, 2025
b12ba09
Add predictor interface and base implementation
tryuan99 Oct 12, 2025
66825e0
Add legacy to IAssignment and AssignmentItem
tryuan99 Oct 12, 2025
b7769df
Add assignment interface and base implementation
tryuan99 Oct 12, 2025
fde8285
Make algorithms state-less
tryuan99 Oct 13, 2025
cc574ba
Define all movement behaviors
tryuan99 Oct 13, 2025
3a23a66
Implement all movement behaviors
tryuan99 Oct 13, 2025
4d177bc
Add unit tests for movement behaviors
tryuan99 Oct 13, 2025
8d2dea3
Address comments
tryuan99 Oct 13, 2025
37ce457
Fix style of local constant variable
tryuan99 Oct 13, 2025
5b24122
Inherit from TestBase instead of AgentTestBase in movement tests
tryuan99 Oct 13, 2025
3055f72
Add legacy suffix to sensor classes
tryuan99 Oct 13, 2025
ccf32b0
Capitalize public struct attributes
tryuan99 Oct 13, 2025
74c81b8
Define sensor interface
tryuan99 Oct 13, 2025
d063df8
Add unit tests for ideal sensor
tryuan99 Oct 13, 2025
0e4794e
Clean up AgentBaseTests by using SetUp
tryuan99 Oct 13, 2025
37c8c70
Address comments
tryuan99 Oct 14, 2025
a55fe1c
Remove unused flight plan attribute
tryuan99 Oct 14, 2025
6829370
Clean up private properties
tryuan99 Oct 14, 2025
728b2c1
Implement evasion maneuvers
tryuan99 Oct 14, 2025
d68be39
Add evasion unit tests
tryuan99 Oct 14, 2025
a3d1a1a
Address comments
tryuan99 Oct 14, 2025
a4076a6
Set power table to IReadOnlyDictionary
tryuan99 Oct 14, 2025
51b36e0
Implement attack behaviors
tryuan99 Oct 14, 2025
1b6f999
Add unit tests for direct attack behavior
tryuan99 Oct 14, 2025
7936281
Address comments
tryuan99 Oct 14, 2025
32958ad
Add Legacy suffix to existing controller class names
tryuan99 Oct 15, 2025
2bc261c
Define all controllers
tryuan99 Oct 16, 2025
1c207ae
Add unit tests for all controllers
tryuan99 Oct 16, 2025
5e84fa5
Address comments
tryuan99 Oct 16, 2025
fe294d2
Add Legacy suffix to linear extrapolator
tryuan99 Oct 16, 2025
086ea47
Implement linear extrapolator
tryuan99 Oct 16, 2025
515e488
Refactor launch plan class
tryuan99 Oct 16, 2025
f9bdd9a
Clean up interpolator classes
tryuan99 Oct 16, 2025
f6ec3ea
Fix unit tests for interpolator classes
tryuan99 Oct 16, 2025
820eb7d
Add hierarchical as property of predictor clases
tryuan99 Oct 16, 2025
1a875cf
Clean up all predictor and planner classes
tryuan99 Oct 17, 2025
b69ca74
Address comments
tryuan99 Oct 17, 2025
78b20e1
Address comments
tryuan99 Oct 17, 2025
0097541
Add Legacy suffix to clusterer class names
tryuan99 Oct 17, 2025
8aa9a1b
Fix all clustering algorithm implementations
tryuan99 Oct 17, 2025
70c3f13
Add unit tests for clustering algorithms
tryuan99 Oct 17, 2025
3693e95
Address comments
tryuan99 Oct 17, 2025
db49203
Clean up coordinates classes and tests
tryuan99 Oct 17, 2025
2d858fa
Address comments
tryuan99 Oct 17, 2025
fa34391
Address comments
tryuan99 Oct 18, 2025
27309b6
Use explicit Vector3 type instead of var
tryuan99 Oct 18, 2025
5fdbce5
Merge branch 'titan/agent_interfaces' into titan/interceptor_threat_i…
tryuan99 Oct 18, 2025
82c9e5b
Merge branch 'titan/interceptor_threat_interfaces' into titan/algorit…
tryuan99 Oct 18, 2025
2b310cb
Use explicit types instead of var
tryuan99 Oct 18, 2025
e84b7b0
Merge branch 'titan/algorithm_interfaces' into titan/movements
tryuan99 Oct 18, 2025
12ef012
Merge branch 'titan/movements' into titan/sensor_interface
tryuan99 Oct 18, 2025
3abcb5e
Merge branch 'titan/sensor_interface' into titan/clean_up_getters_set…
tryuan99 Oct 18, 2025
202ce9c
Merge branch 'titan/clean_up_getters_setters' into titan/evasion
tryuan99 Oct 18, 2025
cabe6af
Use explicit types instead of var
tryuan99 Oct 18, 2025
60dda38
Merge branch 'titan/evasion' into titan/attack_behavior
tryuan99 Oct 18, 2025
ebb88f2
Use explicit types instead of var
tryuan99 Oct 18, 2025
bc90392
Merge branch 'titan/attack_behavior' into titan/controller
tryuan99 Oct 18, 2025
ac2c656
Use explicit types instead of var
tryuan99 Oct 18, 2025
1d79501
Merge branch 'titan/controller' into titan/predictor_planner
tryuan99 Oct 18, 2025
4fb28bf
Address comments
tryuan99 Oct 18, 2025
69c531b
Merge branch 'titan/predictor_planner' into titan/clustering
tryuan99 Oct 18, 2025
67eba59
Use explicit types instead of var
tryuan99 Oct 18, 2025
c5cb7f4
Merge branch 'titan/clustering' into titan/coordinates
tryuan99 Oct 18, 2025
9e37530
Use explicit types instead of var
tryuan99 Oct 18, 2025
7fbb745
Add argument annotations to FixedHierarchical constructor
tryuan99 Oct 18, 2025
a1c34d6
Fix private const capitalization
tryuan99 Oct 18, 2025
51e8d76
Clean up _maxNumIterations in k-means clusterer
tryuan99 Oct 18, 2025
e702f14
Address comments
tryuan99 Oct 24, 2025
5ca37ef
Merge branch 'titan/evasion' into titan/attack_behavior
tryuan99 Oct 24, 2025
59cab92
Address comments
tryuan99 Oct 24, 2025
8104ac6
Merge branch 'titan/attack_behavior' into titan/controller
tryuan99 Oct 24, 2025
040cd52
Address comments
tryuan99 Oct 24, 2025
64abe47
Merge branch 'titan/controller' into titan/predictor_planner
tryuan99 Oct 24, 2025
2b20b5d
Address comments
tryuan99 Oct 24, 2025
7732efe
Merge branch 'titan/predictor_planner' into titan/clustering
tryuan99 Oct 24, 2025
d4d26d8
Merge branch 'titan/clustering' into titan/coordinates
tryuan99 Oct 24, 2025
d786635
Address comments
tryuan99 Oct 24, 2025
1327336
Remove debug log statements from unit tests
tryuan99 Oct 24, 2025
b3d8d2d
Merge branch 'titan/clustering' into titan/coordinates
tryuan99 Oct 24, 2025
1a377ad
Address comments
tryuan99 Oct 28, 2025
7108370
Remove unnecessary newline
tryuan99 Oct 28, 2025
82bf5a9
Merge branch 'titan/clustering' into titan/coordinates
tryuan99 Oct 28, 2025
236d837
Merge branch 'titan/hierarchical' into titan/coordinates
tryuan99 Dec 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Assets/Scripts/Utils/Coordinates.cs.meta

This file was deleted.

26 changes: 26 additions & 0 deletions Assets/Scripts/Utils/Coordinates2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using UnityEngine;

// Utility functions for 2D coordinates.
// In Cartesian coordinates, the x-axis points right, and the y-axis points up. The coordinates are
// given by (x, y).
// In polar coordinates, the angle is measured in degrees from the x-axis counterclockwise to the
// y-axis. The coordinates are given by (r, theta).
public static class Coordinates2 {
public static Vector2 ConvertCartesianToPolar(in Vector2 cartesian) {
float r = cartesian.magnitude;
float theta = Mathf.Atan2(cartesian.y, cartesian.x) * Mathf.Rad2Deg;
return new Vector2(r, theta);
}
public static Vector2 ConvertCartesianToPolar(float x, float y) {
return ConvertCartesianToPolar(new Vector2(x, y));
}

public static Vector2 ConvertPolarToCartesian(in Vector2 polar) {
float x = polar.x * Mathf.Cos(polar.y * Mathf.Deg2Rad);
float y = polar.x * Mathf.Sin(polar.y * Mathf.Deg2Rad);
return new Vector2(x, y);
}
public static Vector2 ConvertPolarToCartesian(float r, float theta) {
return ConvertPolarToCartesian(new Vector2(r, theta));
}
}
2 changes: 2 additions & 0 deletions Assets/Scripts/Utils/Coordinates2.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
using UnityEngine;

// Utility functions for 2D coordinates.
// In Cartesian coordinates, the x-axis points right, and the y-axis points up. The coordinates are
// given by (x, y).
// In polar coordinates, the angle is measured in degrees from the x-axis counterclockwise to the
// y-axis. The coordinates are given by (r, theta).
public static class Coordinates2 {
public static Vector2 ConvertCartesianToPolar(in Vector2 cartesian) {
float r = cartesian.magnitude;
float theta = Mathf.Atan2(cartesian.y, cartesian.x) * Mathf.Rad2Deg;
return new Vector2(r, theta);
}
public static Vector2 ConvertCartesianToPolar(float x, float y) {
return ConvertCartesianToPolar(new Vector2(x, y));
}

public static Vector2 ConvertPolarToCartesian(in Vector2 polar) {
float x = polar.x * Mathf.Cos(polar.y * Mathf.Deg2Rad);
float y = polar.x * Mathf.Sin(polar.y * Mathf.Deg2Rad);
return new Vector2(x, y);
}
public static Vector2 ConvertPolarToCartesian(float r, float theta) {
return ConvertPolarToCartesian(new Vector2(r, theta));
}
}

// Utility functions for 3D coordinates.
// In Cartesian coordinates, the x-axis points right, the y-axis points up, and the z-axis points
// forward. The coordinates are given by (x, y, z).
Expand All @@ -37,11 +12,12 @@ public static class Coordinates3 {
public static Vector3 ConvertCartesianToSpherical(in Vector3 cartesian) {
float r = cartesian.magnitude;
float azimuth = Mathf.Atan2(cartesian.x, cartesian.z) * Mathf.Rad2Deg;
float elevation = Mathf.Atan(cartesian.y / Mathf.Sqrt(cartesian.x * cartesian.x +
float elevation = Mathf.Atan2(cartesian.y, Mathf.Sqrt(cartesian.x * cartesian.x +
cartesian.z * cartesian.z)) *
Mathf.Rad2Deg;
return new Vector3(r, azimuth, elevation);
}

public static Vector3 ConvertCartesianToSpherical(float x, float y, float z) {
return ConvertCartesianToSpherical(new Vector3(x, y, z));
}
Expand All @@ -54,6 +30,7 @@ public static Vector3 ConvertSphericalToCartesian(in Vector3 spherical) {
Mathf.Cos(spherical.y * Mathf.Deg2Rad);
return new Vector3(x, y, z);
}

public static Vector3 ConvertSphericalToCartesian(float r, float azimuth, float elevation) {
return ConvertSphericalToCartesian(new Vector3(r, azimuth, elevation));
}
Expand All @@ -64,6 +41,7 @@ public static Vector3 ConvertCartesianToCylindrical(in Vector3 cartesian) {
float height = cartesian.y;
return new Vector3(r, azimuth, height);
}

public static Vector3 ConvertCartesianToCylindrical(float x, float y, float z) {
return ConvertCartesianToCylindrical(new Vector3(x, y, z));
}
Expand All @@ -74,6 +52,7 @@ public static Vector3 ConvertCylindricalToCartesian(in Vector3 cylindrical) {
float z = cylindrical.x * Mathf.Cos(cylindrical.y * Mathf.Deg2Rad);
return new Vector3(x, y, z);
}

public static Vector3 ConvertCylindricalToCartesian(float r, float azimuth, float height) {
return ConvertCylindricalToCartesian(new Vector3(r, azimuth, height));
}
Expand Down
2 changes: 2 additions & 0 deletions Assets/Scripts/Utils/Coordinates3.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions Assets/Tests/EditMode/Coordinates2Tests.cs
Comment thread
tryuan99 marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools.Utils;

public class Coordinates2Tests {
private const float _epsilon = 1e-4f;

[Test]
public void ConvertCartesianToPolar_Origin_ReturnsZeroDistance() {
var cartesian = Vector2.zero;
Vector2 polar = Coordinates2.ConvertCartesianToPolar(cartesian);
Assert.AreEqual(0, polar.x, _epsilon);
Assert.IsFalse(float.IsNaN(polar.y));
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved

[Test]
public void ConvertCartesianToPolar_OnXAxis_ReturnsZeroTheta() {
var cartesian = new Vector2(5, 0);
var expectedPolar = new Vector2(5.0f, 0.0f);
Vector2 actualPolar = Coordinates2.ConvertCartesianToPolar(cartesian);
Assert.That(actualPolar, Is.EqualTo(expectedPolar).Using(Vector2EqualityComparer.Instance));
}

[Test]
public void ConvertCartesianToPolar_OnYAxis_ReturnsNinetyTheta() {
var cartesian = new Vector2(0, 5);
var expectedPolar = new Vector2(5.0f, 90.0f);
Vector2 actualPolar = Coordinates2.ConvertCartesianToPolar(cartesian);
Assert.That(actualPolar, Is.EqualTo(expectedPolar).Using(Vector2EqualityComparer.Instance));
}

[Test]
[TestCase(0f)]
[TestCase(45f)]
[TestCase(90f)]
[TestCase(180f)]
[TestCase(360f)]
public void ConvertPolarToCartesian_ZeroDistance_ReturnsOrigin(float theta) {
var polar = new Vector2(0, theta);
var expectedCartesian = Vector2.zero;
Vector2 actualCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector2EqualityComparer.Instance));
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved

[Test]
public void ConvertPolarToCartesian_ZeroTheta_ReturnsOnXAxis() {
var polar = new Vector2(10, 0);
var expectedCartesian = new Vector2(10.0f, 0.0f);
Vector2 actualCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector2EqualityComparer.Instance));
}

[Test]
public void ConvertPolarToCartesian_NinetyTheta_ReturnsOnYAxis() {
Vector2 polar = new Vector2(10, 90);
Vector2 expectedCartesian = new Vector2(0.0f, 10.0f);
Vector2 actualCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector2EqualityComparer.Instance));
}

[Test]
public void ConvertPolarToCartesian_ThirtyTheta() {
var polar = new Vector2(20, 30);
var expectedCartesian = new Vector2(10 * Mathf.Sqrt(3), 10);
Vector2 actualCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector2EqualityComparer.Instance));
}

[Test]
public void ConvertPolarToCartesian_FortyFiveTheta() {
var polar = new Vector2(10 * Mathf.Sqrt(2), 45);
var expectedCartesian = new Vector2(10.0f, 10.0f);
Vector2 actualCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector2EqualityComparer.Instance));
}

[Test]
public void RoundTrip_CartesianToPolarToCartesian_ReturnsOriginal() {
var originalCartesian = new Vector2(3.5f, 7.2f);
Vector2 polar = Coordinates2.ConvertCartesianToPolar(originalCartesian);
Vector2 resultCartesian = Coordinates2.ConvertPolarToCartesian(polar);
Assert.That(resultCartesian,
Is.EqualTo(originalCartesian).Using(Vector2EqualityComparer.Instance));
}
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved
2 changes: 2 additions & 0 deletions Assets/Tests/EditMode/Coordinates2Tests.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

120 changes: 120 additions & 0 deletions Assets/Tests/EditMode/Coordinates3Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools.Utils;

public class Coordinates3Tests {
private const float _epsilon = 1e-4f;

[Test]
public void ConvertCartesianToSpherical_Origin_ReturnsZeroDistance() {
var cartesian = Vector3.zero;
Vector3 spherical = Coordinates3.ConvertCartesianToSpherical(cartesian);
Assert.AreEqual(0, spherical.x, _epsilon);
Assert.IsFalse(float.IsNaN(spherical.y));
Assert.IsFalse(float.IsNaN(spherical.z));
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved

[Test]
public void ConvertCartesianToSpherical_ReturnsCorrectly() {
var cartesian = new Vector3(2, -1, 3);
var expectedSpherical = new Vector3(Mathf.Sqrt(14), 33.690068f, -15.501360f);
Vector3 actualSpherical = Coordinates3.ConvertCartesianToSpherical(cartesian);
Assert.That(actualSpherical,
Is.EqualTo(expectedSpherical).Using(Vector3EqualityComparer.Instance));
}

[Test]
[TestCase(0f, 0f)]
[TestCase(45f, 0f)]
[TestCase(90f, 0f)]
[TestCase(180f, 0f)]
[TestCase(360f, 0f)]
[TestCase(45f, 45f)]
[TestCase(45f, 90f)]
[TestCase(45f, 180f)]
[TestCase(45f, 360f)]
public void ConvertSphericalToCartesian_ZeroDistance_ReturnsOrigin(float theta, float phi) {
var spherical = new Vector3(0, theta, phi);
var expectedCartesian = Vector3.zero;
Vector3 actualCartesian = Coordinates3.ConvertSphericalToCartesian(spherical);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector3EqualityComparer.Instance));
}

[Test]
public void ConvertSphericalToCartesian_ReturnsCorrectly() {
var spherical = new Vector3(10, 60, 30);
var expectedCartesian = new Vector3(7.5f, 5.0f, 4.3301270189221945f);
Vector3 actualCartesian = Coordinates3.ConvertSphericalToCartesian(spherical);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector3EqualityComparer.Instance));
}

[TestCase(1.5f, 2.5f, 3.5f)]
[TestCase(-1, 2, 3)]
[TestCase(-12, 0, 0)]
[TestCase(0, 5, 0)]
[TestCase(0, 0, -10)]
public void RoundTrip_CartesianToSphericalToCartesian_ReturnsOriginal(float x, float y, float z) {
var originalCartesian = new Vector3(x, y, z);
Vector3 spherical = Coordinates3.ConvertCartesianToSpherical(originalCartesian);
Vector3 resultCartesian = Coordinates3.ConvertSphericalToCartesian(spherical);
Assert.That(resultCartesian,
Is.EqualTo(originalCartesian).Using(Vector3EqualityComparer.Instance));
}

[Test]
public void ConvertCartesianToCylindrical_Origin_ReturnsZeroDistanceZeroHeight() {
var cartesian = Vector3.zero;
Vector3 cylindrical = Coordinates3.ConvertCartesianToCylindrical(cartesian);
Assert.AreEqual(0, cylindrical.x, _epsilon);
Assert.IsFalse(float.IsNaN(cylindrical.y));
Assert.AreEqual(0, cylindrical.z, _epsilon);
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved

[Test]
public void ConvertCartesianToCylindrical_ReturnsCorrectly() {
var cartesian = new Vector3(2, -1, 3);
var expectedCylindrical = new Vector3(Mathf.Sqrt(13), 33.6900675f, -1);
Vector3 actualCylindrical = Coordinates3.ConvertCartesianToCylindrical(cartesian);
Assert.That(actualCylindrical,
Is.EqualTo(expectedCylindrical).Using(Vector3EqualityComparer.Instance));
}

[Test]
[TestCase(0f)]
[TestCase(45f)]
[TestCase(90f)]
[TestCase(180f)]
[TestCase(360f)]
public void ConvertCylindricalToCartesian_ZeroDistance_ZeroHeight_ReturnsOrigin(float theta) {
var cylindrical = new Vector3(0, theta, 0);
var expectedCartesian = Vector3.zero;
Vector3 actualCartesian = Coordinates3.ConvertCylindricalToCartesian(cylindrical);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector3EqualityComparer.Instance));
}

[Test]
public void ConvertCylindricalToCartesian_ReturnsCorrectly() {
var cylindrical = new Vector3(10, 60, 2);
var expectedCartesian = new Vector3(8.660254f, 2.0f, 5.0f);
Vector3 actualCartesian = Coordinates3.ConvertCylindricalToCartesian(cylindrical);
Assert.That(actualCartesian,
Is.EqualTo(expectedCartesian).Using(Vector3EqualityComparer.Instance));
}

[TestCase(1.5f, 2.5f, 3.5f)]
[TestCase(-1, 2, 3)]
[TestCase(-12, 0, 0)]
[TestCase(0, 5, 0)]
[TestCase(0, 0, -10)]
public void RoundTrip_CartesianToCylindricalToCartesian_ReturnsOriginal(float x, float y,
float z) {
var originalCartesian = new Vector3(x, y, z);
Vector3 cylindrical = Coordinates3.ConvertCartesianToCylindrical(originalCartesian);
Vector3 resultCartesian = Coordinates3.ConvertCylindricalToCartesian(cylindrical);
Assert.That(resultCartesian,
Is.EqualTo(originalCartesian).Using(Vector3EqualityComparer.Instance));
}
}
Comment thread
tryuan99 marked this conversation as resolved.
Resolved
2 changes: 2 additions & 0 deletions Assets/Tests/EditMode/Coordinates3Tests.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading