Refactor "Missile" -> "Interceptor"

more-targets
Daniel Lovell 2024-09-24 19:59:25 -07:00
parent bbb2dba1ed
commit a29efbb4ca
23 changed files with 155 additions and 158 deletions

View File

@ -284,7 +284,7 @@ GameObject:
- component: {fileID: 4571646124809534626} - component: {fileID: 4571646124809534626}
- component: {fileID: 4451965530778273955} - component: {fileID: 4451965530778273955}
m_Layer: 0 m_Layer: 0
m_Name: DroneTarget m_Name: Drone
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0

View File

@ -2,35 +2,35 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
// The assignment class is an interface for assigning a threat to each missile. // The assignment class is an interface for assigning a threat to each interceptor.
public interface IAssignment { public interface IAssignment {
// Assignment item type. // Assignment item type.
// The first element corresponds to the missile index, and the second element // The first element corresponds to the interceptor index, and the second element
// corresponds to the threat index. // corresponds to the threat index.
public struct AssignmentItem { public struct AssignmentItem {
public int MissileIndex; public int InterceptorIndex;
public int ThreatIndex; public int ThreatIndex;
public AssignmentItem(int missileIndex, int threatIndex) { public AssignmentItem(int missileIndex, int threatIndex) {
MissileIndex = missileIndex; InterceptorIndex = missileIndex;
ThreatIndex = threatIndex; ThreatIndex = threatIndex;
} }
} }
// A list containing the missile-target assignments. // A list containing the interceptor-target assignments.
// Assign a target to each missile that has not been assigned a target yet. // Assign a target to each interceptor that has not been assigned a target yet.
public abstract IEnumerable<AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets); public abstract IEnumerable<AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets);
// Get the list of assignable missile indices. // Get the list of assignable interceptor indices.
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles) { protected static List<int> GetAssignableInterceptorIndices(List<Agent> missiles) {
List<int> assignableMissileIndices = new List<int>(); List<int> assignableInterceptorIndices = new List<int>();
for (int missileIndex = 0; missileIndex < missiles.Count; missileIndex++) { for (int missileIndex = 0; missileIndex < missiles.Count; missileIndex++) {
if (missiles[missileIndex].IsAssignable()) { if (missiles[missileIndex].IsAssignable()) {
assignableMissileIndices.Add(missileIndex); assignableInterceptorIndices.Add(missileIndex);
} }
} }
return assignableMissileIndices; return assignableInterceptorIndices;
} }
// Get the list of active target indices. // Get the list of active target indices.

View File

@ -9,11 +9,11 @@ public class RoundRobinAssignment : IAssignment {
// Previous target index that was assigned. // Previous target index that was assigned.
private int prevTargetIndex = -1; private int prevTargetIndex = -1;
// Assign a target to each missile that has not been assigned a target yet. // Assign a target to each interceptor that has not been assigned a target yet.
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) { public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) {
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>(); List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles); List<int> assignableInterceptorIndices = IAssignment.GetAssignableInterceptorIndices(missiles);
if (assignableMissileIndices.Count == 0) { if (assignableInterceptorIndices.Count == 0) {
return assignments; return assignments;
} }
@ -22,7 +22,7 @@ public class RoundRobinAssignment : IAssignment {
return assignments; return assignments;
} }
foreach (int missileIndex in assignableMissileIndices) { foreach (int missileIndex in assignableInterceptorIndices) {
int nextActiveTargetIndex = activeThreatIndices.FindIndex(index => index > prevTargetIndex); int nextActiveTargetIndex = activeThreatIndices.FindIndex(index => index > prevTargetIndex);
if (nextActiveTargetIndex == -1) { if (nextActiveTargetIndex == -1) {

View File

@ -7,12 +7,12 @@ using UnityEngine;
// The threat assignment class assigns missiles to the targets based // The threat assignment class assigns missiles to the targets based
// on the threat level of the targets. // on the threat level of the targets.
public class ThreatAssignment : IAssignment { public class ThreatAssignment : IAssignment {
// Assign a target to each missile that has not been assigned a target yet. // Assign a target to each interceptor that has not been assigned a target yet.
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) { public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) {
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>(); List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles); List<int> assignableInterceptorIndices = IAssignment.GetAssignableInterceptorIndices(missiles);
if (assignableMissileIndices.Count == 0) { if (assignableInterceptorIndices.Count == 0) {
return assignments; return assignments;
} }
@ -25,13 +25,13 @@ public class ThreatAssignment : IAssignment {
List<ThreatInfo> threatInfos = List<ThreatInfo> threatInfos =
CalculateThreatLevels(targets, activeThreatIndices, positionToDefend); CalculateThreatLevels(targets, activeThreatIndices, positionToDefend);
foreach (int missileIndex in assignableMissileIndices) { foreach (int missileIndex in assignableInterceptorIndices) {
if (missiles[missileIndex].HasAssignedTarget()) if (missiles[missileIndex].HasAssignedTarget())
continue; continue;
if (threatInfos.Count == 0) if (threatInfos.Count == 0)
break; break;
// Find the optimal target for this missile based on distance and threat // Find the optimal target for this interceptor based on distance and threat
ThreatInfo optimalTarget = null; ThreatInfo optimalTarget = null;
float optimalScore = float.MinValue; float optimalScore = float.MinValue;

View File

@ -42,16 +42,16 @@ public static class ConfigLoader {
Debug.Log("SimulationConfig:"); Debug.Log("SimulationConfig:");
Debug.Log($"Time Scale: {config.timeScale}"); Debug.Log($"Time Scale: {config.timeScale}");
Debug.Log("Missile Swarm Configurations:"); Debug.Log("Interceptor Swarm Configurations:");
for (int i = 0; i < config.missile_swarm_configs.Count; i++) for (int i = 0; i < config.interceptor_swarm_configs.Count; i++)
{ {
PrintSwarmConfig(config.missile_swarm_configs[i], $"Missile Swarm {i + 1}"); PrintSwarmConfig(config.interceptor_swarm_configs[i], $"Interceptor Swarm {i + 1}");
} }
Debug.Log("Threat Swarm Configurations:"); Debug.Log("Threat Swarm Configurations:");
for (int i = 0; i < config.target_swarm_configs.Count; i++) for (int i = 0; i < config.threat_swarm_configs.Count; i++)
{ {
PrintSwarmConfig(config.target_swarm_configs[i], $"Threat Swarm {i + 1}"); PrintSwarmConfig(config.threat_swarm_configs[i], $"Threat Swarm {i + 1}");
} }
} }
@ -65,7 +65,7 @@ public static class ConfigLoader {
private static void PrintAgentConfig(AgentConfig agentConfig) private static void PrintAgentConfig(AgentConfig agentConfig)
{ {
Debug.Log(" Agent Configuration:"); Debug.Log(" Agent Configuration:");
Debug.Log($" Missile Type: {agentConfig.missile_type}"); Debug.Log($" Interceptor Type: {agentConfig.interceptor_type}");
Debug.Log($" Threat Type: {agentConfig.target_type}"); Debug.Log($" Threat Type: {agentConfig.target_type}");
PrintInitialState(agentConfig.initial_state); PrintInitialState(agentConfig.initial_state);
PrintStandardDeviation(agentConfig.standard_deviation); PrintStandardDeviation(agentConfig.standard_deviation);
@ -122,7 +122,7 @@ public static class ConfigLoader {
private static void PrintSubmunitionAgentConfig(SubmunitionAgentConfig agentConfig) private static void PrintSubmunitionAgentConfig(SubmunitionAgentConfig agentConfig)
{ {
Debug.Log(" Submunition Agent Configuration:"); Debug.Log(" Submunition Agent Configuration:");
Debug.Log($" Missile Type: {agentConfig.missile_type}"); Debug.Log($" Interceptor Type: {agentConfig.interceptor_type}");
PrintInitialState(agentConfig.initial_state); PrintInitialState(agentConfig.initial_state);
PrintStandardDeviation(agentConfig.standard_deviation); PrintStandardDeviation(agentConfig.standard_deviation);
PrintDynamicConfig(agentConfig.dynamic_config); PrintDynamicConfig(agentConfig.dynamic_config);

View File

@ -10,11 +10,11 @@ public class SimulationConfig {
[Header("Simulation Settings")] [Header("Simulation Settings")]
public float timeScale = 0.05f; public float timeScale = 0.05f;
[Header("Missile Swarm Configurations")] [Header("Interceptor Swarm Configurations")]
public List<SwarmConfig> missile_swarm_configs = new List<SwarmConfig>(); public List<SwarmConfig> interceptor_swarm_configs = new List<SwarmConfig>();
[Header("Threat Swarm Configurations")] [Header("Threat Swarm Configurations")]
public List<SwarmConfig> target_swarm_configs = new List<SwarmConfig>(); public List<SwarmConfig> threat_swarm_configs = new List<SwarmConfig>();
} }
[Serializable] [Serializable]
@ -31,7 +31,7 @@ public class SwarmConfig {
[Serializable] [Serializable]
public class AgentConfig { public class AgentConfig {
public MissileType missile_type; public InterceptorType interceptor_type;
public ThreatType target_type; public ThreatType target_type;
public InitialState initial_state; public InitialState initial_state;
public StandardDeviation standard_deviation; public StandardDeviation standard_deviation;
@ -41,7 +41,7 @@ public class AgentConfig {
public static AgentConfig FromSubmunitionAgentConfig(SubmunitionAgentConfig submunitionConfig) { public static AgentConfig FromSubmunitionAgentConfig(SubmunitionAgentConfig submunitionConfig) {
return new AgentConfig { return new AgentConfig {
missile_type = submunitionConfig.missile_type, interceptor_type = submunitionConfig.interceptor_type,
initial_state = submunitionConfig.initial_state, initial_state = submunitionConfig.initial_state,
standard_deviation = submunitionConfig.standard_deviation, standard_deviation = submunitionConfig.standard_deviation,
dynamic_config = submunitionConfig.dynamic_config, dynamic_config = submunitionConfig.dynamic_config,
@ -87,7 +87,7 @@ public class SubmunitionsConfig {
[Serializable] [Serializable]
public class SubmunitionAgentConfig { public class SubmunitionAgentConfig {
public MissileType missile_type; public InterceptorType interceptor_type;
public InitialState initial_state; public InitialState initial_state;
public StandardDeviation standard_deviation; public StandardDeviation standard_deviation;
public DynamicConfig dynamic_config; public DynamicConfig dynamic_config;
@ -110,9 +110,9 @@ public class TargetConfig {
// Enums // Enums
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum MissileType { HYDRA_70, MICROMISSILE } public enum InterceptorType { HYDRA_70, MICROMISSILE }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum ThreatType { DRONE, MISSILE } public enum ThreatType { DRONE, ANTISHIP_MISSILE }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum ConfigColor { BLUE, GREEN, RED } public enum ConfigColor { BLUE, GREEN, RED }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]

View File

@ -12,19 +12,19 @@ public class IADS : MonoBehaviour {
private List<Threat> _threats; private List<Threat> _threats;
private List<Missile> _missiles; private List<Interceptor> _interceptors;
private List<Vessel> _vessels; private List<Vessel> _vessels;
public delegate void RegisterNewTargetDelegate(Threat threat); public delegate void RegisterNewThreatDelegate(Threat threat);
public event RegisterNewTargetDelegate OnRegisterNewTarget; public event RegisterNewThreatDelegate OnRegisterNewThreat;
void Start() { void Start() {
_threats = new List<Threat>(); _threats = new List<Threat>();
} }
public void RegisterNewTarget(Threat threat) { public void RegisterNewThreat(Threat threat) {
_threats.Add(threat); _threats.Add(threat);
OnRegisterNewTarget?.Invoke(threat); OnRegisterNewThreat?.Invoke(threat);
} }
} }

View File

@ -3,23 +3,23 @@ using System.Collections.Generic;
public class Vessel : MonoBehaviour { public class Vessel : MonoBehaviour {
[SerializeField] [SerializeField]
private List<Missile> missileInventory = new List<Missile>(); private List<Interceptor> missileInventory = new List<Interceptor>();
public void AddMissile(Missile missile) { public void AddInterceptor(Interceptor interceptor) {
if (missile != null) { if (interceptor != null) {
missileInventory.Add(missile); missileInventory.Add(interceptor);
} }
} }
public void RemoveMissile(Missile missile) { public void RemoveInterceptor(Interceptor interceptor) {
missileInventory.Remove(missile); missileInventory.Remove(interceptor);
} }
public List<Missile> GetMissileInventory() { public List<Interceptor> GetInterceptorInventory() {
return new List<Missile>(missileInventory); return new List<Interceptor>(missileInventory);
} }
public int GetMissileCount() { public int GetInterceptorCount() {
return missileInventory.Count; return missileInventory.Count;
} }

View File

@ -2,22 +2,22 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class Missile : Agent { public class Interceptor : Agent {
[SerializeField] [SerializeField]
protected bool _showDebugVectors = true; protected bool _showDebugVectors = true;
// Return whether a target can be assigned to the missile. // Return whether a target can be assigned to the interceptor.
public override bool IsAssignable() { public override bool IsAssignable() {
bool assignable = !HasLaunched() && !HasAssignedTarget(); bool assignable = !HasLaunched() && !HasAssignedTarget();
return assignable; return assignable;
} }
// Assign the given target to the missile. // Assign the given target to the interceptor.
public override void AssignTarget(Agent target) { public override void AssignTarget(Agent target) {
base.AssignTarget(target); base.AssignTarget(target);
} }
// Unassign the target from the missile. // Unassign the target from the interceptor.
public override void UnassignTarget() { public override void UnassignTarget() {
base.UnassignTarget(); base.UnassignTarget();
} }
@ -36,7 +36,7 @@ public class Missile : Agent {
} }
protected override void UpdateBoost(double deltaTime) { protected override void UpdateBoost(double deltaTime) {
// The missile only accelerates along its roll axis (forward in Unity) // The interceptor only accelerates along its roll axis (forward in Unity)
Vector3 rollAxis = transform.forward; Vector3 rollAxis = transform.forward;
// Calculate boost acceleration // Calculate boost acceleration

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
using UnityEngine; using UnityEngine;
public class Hydra70 : Missile { public class Hydra70 : Interceptor {
private bool _submunitionsLaunched = false; private bool _submunitionsLaunched = false;
protected override void FixedUpdate() { protected override void FixedUpdate() {
@ -34,20 +34,20 @@ public class Hydra70 : Missile {
} }
public void SpawnSubmunitions() { public void SpawnSubmunitions() {
List<Missile> submunitions = new List<Missile>(); List<Interceptor> submunitions = new List<Interceptor>();
switch (_agentConfig.submunitions_config.agent_config.missile_type) { switch (_agentConfig.submunitions_config.agent_config.interceptor_type) {
case MissileType.MICROMISSILE: case InterceptorType.MICROMISSILE:
for (int i = 0; i < _agentConfig.submunitions_config.num_submunitions; i++) { for (int i = 0; i < _agentConfig.submunitions_config.num_submunitions; i++) {
AgentConfig convertedConfig = AgentConfig convertedConfig =
AgentConfig.FromSubmunitionAgentConfig(_agentConfig.submunitions_config.agent_config); AgentConfig.FromSubmunitionAgentConfig(_agentConfig.submunitions_config.agent_config);
convertedConfig.initial_state.position = transform.position; convertedConfig.initial_state.position = transform.position;
convertedConfig.initial_state.velocity = GetComponent<Rigidbody>().velocity; convertedConfig.initial_state.velocity = GetComponent<Rigidbody>().velocity;
Missile submunition = SimManager.Instance.CreateMissile(convertedConfig); Interceptor submunition = SimManager.Instance.CreateInterceptor(convertedConfig);
submunitions.Add(submunition); submunitions.Add(submunition);
} }
break; break;
} }
SimManager.Instance.AssignMissilesToThreats(submunitions); SimManager.Instance.AssignInterceptorsToThreats(submunitions);
} }
} }

View File

@ -2,7 +2,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class Micromissile : Missile { public class Micromissile : Interceptor {
[SerializeField] [SerializeField]
private float _navigationGain = 3f; // Typically 3-5 private float _navigationGain = 3f; // Typically 3-5
@ -57,7 +57,7 @@ public class Micromissile : Missile {
float acc_az = N * closing_velocity * los_rate_az; float acc_az = N * closing_velocity * los_rate_az;
float acc_el = N * closing_velocity * los_rate_el; float acc_el = N * closing_velocity * los_rate_el;
// Convert acceleration commands to missile body frame // Convert acceleration commands to craft body frame
accelerationCommand = transform.right * acc_az + transform.up * acc_el; accelerationCommand = transform.right * acc_az + transform.up * acc_el;
// Clamp the acceleration command to the maximum acceleration // Clamp the acceleration command to the maximum acceleration

View File

@ -41,7 +41,7 @@ public class SimMonitor : MonoBehaviour
private void ExportTelemetry() private void ExportTelemetry()
{ {
float time = (float)SimManager.Instance.GetElapsedSimulationTime(); float time = (float)SimManager.Instance.GetElapsedSimulationTime();
foreach (var agent in SimManager.Instance.GetActiveThreats().Cast<Agent>().Concat(SimManager.Instance.GetActiveMissiles().Cast<Agent>())) foreach (var agent in SimManager.Instance.GetActiveThreats().Cast<Agent>().Concat(SimManager.Instance.GetActiveInterceptors().Cast<Agent>()))
{ {
Vector3 pos = agent.transform.position; Vector3 pos = agent.transform.position;
if(pos == Vector3.zero) { if(pos == Vector3.zero) {

View File

@ -19,8 +19,8 @@ public class SimManager : MonoBehaviour {
[SerializeField] [SerializeField]
public SimulationConfig simulationConfig; public SimulationConfig simulationConfig;
private List<Missile> _missiles = new List<Missile>(); private List<Interceptor> _interceptors = new List<Interceptor>();
private List<Missile> _activeMissiles = new List<Missile>(); private List<Interceptor> _activeInterceptors = new List<Interceptor>();
private List<Threat> _unassignedThreats = new List<Threat>(); private List<Threat> _unassignedThreats = new List<Threat>();
private List<Threat> _threats = new List<Threat>(); private List<Threat> _threats = new List<Threat>();
private List<Threat> _activeThreats = new List<Threat>(); private List<Threat> _activeThreats = new List<Threat>();
@ -42,8 +42,8 @@ public class SimManager : MonoBehaviour {
return _elapsedSimulationTime; return _elapsedSimulationTime;
} }
public List<Missile> GetActiveMissiles() { public List<Interceptor> GetActiveInterceptors() {
return _activeMissiles; return _activeInterceptors;
} }
public List<Threat> GetActiveThreats() { public List<Threat> GetActiveThreats() {
@ -51,7 +51,7 @@ public class SimManager : MonoBehaviour {
} }
public List<Agent> GetActiveAgents() { public List<Agent> GetActiveAgents() {
return _activeMissiles.ConvertAll(missile => missile as Agent) return _activeInterceptors.ConvertAll(interceptor => interceptor as Agent)
.Concat(_activeThreats.ConvertAll(threat => threat as Agent)) .Concat(_activeThreats.ConvertAll(threat => threat as Agent))
.ToList(); .ToList();
} }
@ -102,19 +102,19 @@ public class SimManager : MonoBehaviour {
} }
private void InitializeSimulation() { private void InitializeSimulation() {
List<Missile> missiles = new List<Missile>(); List<Interceptor> missiles = new List<Interceptor>();
// Create missiles based on config // Create missiles based on config
foreach (var swarmConfig in simulationConfig.missile_swarm_configs) { foreach (var swarmConfig in simulationConfig.interceptor_swarm_configs) {
for (int i = 0; i < swarmConfig.num_agents; i++) { for (int i = 0; i < swarmConfig.num_agents; i++) {
var missile = CreateMissile(swarmConfig.agent_config); var interceptor = CreateInterceptor(swarmConfig.agent_config);
missile.OnAgentHit += RegisterMissileHit; interceptor.OnAgentHit += RegisterInterceptorHit;
missile.OnAgentMiss += RegisterMissileMiss; interceptor.OnAgentMiss += RegisterInterceptorMiss;
} }
} }
List<Threat> targets = new List<Threat>(); List<Threat> targets = new List<Threat>();
// Create targets based on config // Create targets based on config
foreach (var swarmConfig in simulationConfig.target_swarm_configs) { foreach (var swarmConfig in simulationConfig.threat_swarm_configs) {
for (int i = 0; i < swarmConfig.num_agents; i++) { for (int i = 0; i < swarmConfig.num_agents; i++) {
var threat = CreateThreat(swarmConfig.agent_config); var threat = CreateThreat(swarmConfig.agent_config);
threat.OnAgentHit += RegisterThreatHit; threat.OnAgentHit += RegisterThreatHit;
@ -129,19 +129,19 @@ public class SimManager : MonoBehaviour {
OnSimulationStarted?.Invoke(); OnSimulationStarted?.Invoke();
} }
public void AssignMissilesToThreats() { public void AssignInterceptorsToThreats() {
AssignMissilesToThreats(_missiles); AssignInterceptorsToThreats(_interceptors);
} }
public void RegisterMissileHit(Agent missile) { public void RegisterInterceptorHit(Agent interceptor) {
if (missile is Missile missileComponent) { if (interceptor is Interceptor missileComponent) {
_activeMissiles.Remove(missileComponent); _activeInterceptors.Remove(missileComponent);
} }
} }
public void RegisterMissileMiss(Agent missile) { public void RegisterInterceptorMiss(Agent interceptor) {
if (missile is Missile missileComponent) { if (interceptor is Interceptor missileComponent) {
_activeMissiles.Remove(missileComponent); _activeInterceptors.Remove(missileComponent);
} }
} }
@ -161,8 +161,8 @@ public class SimManager : MonoBehaviour {
/// Assigns the specified list of missiles to available targets based on the assignment scheme. /// Assigns the specified list of missiles to available targets based on the assignment scheme.
/// </summary> /// </summary>
/// <param name="missilesToAssign">The list of missiles to assign.</param> /// <param name="missilesToAssign">The list of missiles to assign.</param>
public void AssignMissilesToThreats(List<Missile> missilesToAssign) { public void AssignInterceptorsToThreats(List<Interceptor> missilesToAssign) {
// Convert Missile and Threat lists to Agent lists // Convert Interceptor and Threat lists to Agent lists
List<Agent> missileAgents = new List<Agent>(missilesToAssign.ConvertAll(m => m as Agent)); List<Agent> missileAgents = new List<Agent>(missilesToAssign.ConvertAll(m => m as Agent));
// Convert Threat list to Agent list, excluding already assigned targets // Convert Threat list to Agent list, excluding already assigned targets
List<Agent> targetAgents = _unassignedThreats.ToList<Agent>(); List<Agent> targetAgents = _unassignedThreats.ToList<Agent>();
@ -173,33 +173,33 @@ public class SimManager : MonoBehaviour {
// Apply the assignments to the missiles // Apply the assignments to the missiles
foreach (var assignment in assignments) { foreach (var assignment in assignments) {
if (assignment.MissileIndex < missilesToAssign.Count) { if (assignment.InterceptorIndex < missilesToAssign.Count) {
Missile missile = missilesToAssign[assignment.MissileIndex]; Interceptor interceptor = missilesToAssign[assignment.InterceptorIndex];
Threat threat = _unassignedThreats[assignment.ThreatIndex]; Threat threat = _unassignedThreats[assignment.ThreatIndex];
missile.AssignTarget(threat); interceptor.AssignTarget(threat);
Debug.Log($"Missile {missile.name} assigned to threat {threat.name}"); Debug.Log($"Interceptor {interceptor.name} assigned to threat {threat.name}");
} }
} }
// TODO this whole function should be optimized // TODO this whole function should be optimized
_unassignedThreats.RemoveAll( _unassignedThreats.RemoveAll(
threat => missilesToAssign.Any(missile => missile.GetAssignedTarget() == threat)); threat => missilesToAssign.Any(interceptor => interceptor.GetAssignedTarget() == threat));
} }
/// <summary> /// <summary>
/// Creates a missile based on the provided configuration. /// Creates a interceptor based on the provided configuration.
/// </summary> /// </summary>
/// <param name="config">Configuration settings for the missile.</param> /// <param name="config">Configuration settings for the interceptor.</param>
/// <returns>The created Missile instance, or null if creation failed.</returns> /// <returns>The created Interceptor instance, or null if creation failed.</returns>
public Missile CreateMissile(AgentConfig config) { public Interceptor CreateInterceptor(AgentConfig config) {
string prefabName = config.missile_type switch { MissileType.HYDRA_70 => "Hydra70", string prefabName = config.interceptor_type switch { InterceptorType.HYDRA_70 => "Hydra70",
MissileType.MICROMISSILE => "Micromissile", InterceptorType.MICROMISSILE => "Micromissile",
_ => "Hydra70" }; _ => "Hydra70" };
GameObject missileObject = CreateAgent(config, prefabName); GameObject missileObject = CreateAgent(config, prefabName);
if (missileObject == null) if (missileObject == null)
return null; return null;
// Missile-specific logic // Interceptor-specific logic
switch (config.dynamic_config.sensor_config.type) { switch (config.dynamic_config.sensor_config.type) {
case SensorType.IDEAL: case SensorType.IDEAL:
missileObject.AddComponent<IdealSensor>(); missileObject.AddComponent<IdealSensor>();
@ -209,13 +209,13 @@ public class SimManager : MonoBehaviour {
break; break;
} }
_missiles.Add(missileObject.GetComponent<Missile>()); _interceptors.Add(missileObject.GetComponent<Interceptor>());
_activeMissiles.Add(missileObject.GetComponent<Missile>()); _activeInterceptors.Add(missileObject.GetComponent<Interceptor>());
// Assign a unique and simple ID // Assign a unique and simple ID
int missileId = _missiles.Count; int missileId = _interceptors.Count;
missileObject.name = $"{config.missile_type}_Missile_{missileId}"; missileObject.name = $"{config.interceptor_type}_Interceptor_{missileId}";
return missileObject.GetComponent<Missile>(); return missileObject.GetComponent<Interceptor>();
} }
/// <summary> /// <summary>
@ -225,7 +225,7 @@ public class SimManager : MonoBehaviour {
/// <returns>The created Threat instance, or null if creation failed.</returns> /// <returns>The created Threat instance, or null if creation failed.</returns>
private Threat CreateThreat(AgentConfig config) { private Threat CreateThreat(AgentConfig config) {
string prefabName = config.target_type switch { string prefabName = config.target_type switch {
ThreatType.DRONE => "DroneTarget", ThreatType.MISSILE => "MissileTarget", ThreatType.DRONE => "Drone", ThreatType.ANTISHIP_MISSILE => "AntishipMissile",
_ => throw new System.ArgumentException($"Unsupported threat type: {config.target_type}") _ => throw new System.ArgumentException($"Unsupported threat type: {config.target_type}")
}; };
GameObject threatObject = CreateAgent(config, prefabName); GameObject threatObject = CreateAgent(config, prefabName);
@ -243,7 +243,7 @@ public class SimManager : MonoBehaviour {
} }
/// <summary> /// <summary>
/// Creates an agent (missile or threat) based on the provided configuration and prefab name. /// Creates an agent (interceptor or threat) based on the provided configuration and prefab name.
/// </summary> /// </summary>
/// <param name="config">Configuration settings for the agent.</param> /// <param name="config">Configuration settings for the agent.</param>
/// <param name="prefabName">Name of the prefab to instantiate.</param> /// <param name="prefabName">Name of the prefab to instantiate.</param>
@ -289,9 +289,9 @@ public class SimManager : MonoBehaviour {
simulationRunning = true; simulationRunning = true;
// Clear existing missiles and targets // Clear existing missiles and targets
foreach (var missile in _missiles) { foreach (var interceptor in _interceptors) {
if (missile != null) { if (interceptor != null) {
Destroy(missile.gameObject); Destroy(interceptor.gameObject);
} }
} }
@ -301,7 +301,7 @@ public class SimManager : MonoBehaviour {
} }
} }
_missiles.Clear(); _interceptors.Clear();
_threats.Clear(); _threats.Clear();
_unassignedThreats.Clear(); _unassignedThreats.Clear();
@ -310,15 +310,15 @@ public class SimManager : MonoBehaviour {
void Update() { void Update() {
// Check if all missiles have terminated // Check if all missiles have terminated
bool allMissilesTerminated = true; bool allInterceptorsTerminated = true;
foreach (var missile in _missiles) { foreach (var interceptor in _interceptors) {
if (missile != null && !missile.IsHit() && !missile.IsMiss()) { if (interceptor != null && !interceptor.IsHit() && !interceptor.IsMiss()) {
allMissilesTerminated = false; allInterceptorsTerminated = false;
break; break;
} }
} }
// If all missiles have terminated, restart the simulation // If all missiles have terminated, restart the simulation
if (allMissilesTerminated) { if (allInterceptorsTerminated) {
RestartSimulation(); RestartSimulation();
} }

View File

@ -2,7 +2,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class MissileTarget : MonoBehaviour { public class AntishipMissile : MonoBehaviour {
// Start is called before the first frame update // Start is called before the first frame update
void Start() {} void Start() {}

View File

@ -11,7 +11,7 @@ public class BotStatusDialog : UIDialog
UISelectableEntry missiles = CreateSelectableEntry(); UISelectableEntry missiles = CreateSelectableEntry();
missiles.SetTextContent(new List<string>(new string[] { "Missiles" })); missiles.SetTextContent(new List<string>(new string[] { "Interceptors" }));
missiles.SetIsSelectable(false); missiles.SetIsSelectable(false);
UISelectableEntry submunitions = CreateSelectableEntry(); UISelectableEntry submunitions = CreateSelectableEntry();

View File

@ -5,18 +5,15 @@ using UnityEngine.EventSystems;
public class UIElementMouseCapturer : EventTrigger public class UIElementMouseCapturer : EventTrigger
{ {
private bool _hasPointerEntered = false;
public override void OnPointerEnter(PointerEventData eventData) public override void OnPointerEnter(PointerEventData eventData)
{ {
InputManager.Instance.mouseActive = false; InputManager.Instance.mouseActive = false;
_hasPointerEntered = true;
base.OnPointerEnter(eventData); base.OnPointerEnter(eventData);
} }
public override void OnPointerExit(PointerEventData eventData) public override void OnPointerExit(PointerEventData eventData)
{ {
InputManager.Instance.mouseActive = true; InputManager.Instance.mouseActive = true;
_hasPointerEntered = false;
base.OnPointerExit(eventData); base.OnPointerExit(eventData);
} }

View File

@ -1,10 +1,10 @@
{ {
"timeScale": 1, "timeScale": 1,
"missile_swarm_configs": [ "interceptor_swarm_configs": [
{ {
"num_agents": 1, "num_agents": 1,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 20, "z": 0 }, "position": { "x": 0, "y": 20, "z": 0 },
@ -26,7 +26,7 @@
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 4 }, "launch_config": { "launch_time": 4 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 0, "z": 0 }, "position": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },
@ -48,11 +48,11 @@
} }
} }
], ],
"target_swarm_configs": [ "threat_swarm_configs": [
{ {
"num_agents": 7, "num_agents": 7,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 600, "z": 6000 }, "position": { "x": 0, "y": 600, "z": 6000 },
@ -74,7 +74,7 @@
"num_submunitions": 0, "num_submunitions": 0,
"launch_config": { "launch_time": 0 }, "launch_config": { "launch_time": 0 },
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 0, "z": 0 }, "position": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },

View File

@ -1,10 +1,10 @@
{ {
"timeScale": 1, "timeScale": 1,
"missile_swarm_configs": [ "interceptor_swarm_configs": [
{ {
"num_agents": 10, "num_agents": 10,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 20, "z": 0 }, "position": { "x": 0, "y": 20, "z": 0 },
@ -26,7 +26,7 @@
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 4 }, "launch_config": { "launch_time": 4 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
"initial_state": { "initial_state": {
"position": { "x": -171.3253, "y": 683.85236, "z": 846.74677 }, "position": { "x": -171.3253, "y": 683.85236, "z": 846.74677 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },
@ -50,7 +50,7 @@
{ {
"num_agents": 10, "num_agents": 10,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": 200, "y": 20, "z": 0 }, "position": { "x": 200, "y": 20, "z": 0 },
@ -72,7 +72,7 @@
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 12 }, "launch_config": { "launch_time": 12 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
"initial_state": { "initial_state": {
"position": { "x": -3.2042065, "y": 781.2401, "z": 1043.2384 }, "position": { "x": -3.2042065, "y": 781.2401, "z": 1043.2384 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },
@ -96,7 +96,7 @@
{ {
"num_agents": 10, "num_agents": 10,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": -100, "y": 20, "z": 0 }, "position": { "x": -100, "y": 20, "z": 0 },
@ -118,7 +118,7 @@
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 23 }, "launch_config": { "launch_time": 23 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
"initial_state": { "initial_state": {
"position": { "x": -246.4463, "y": 976.02924, "z": 1081.1262 }, "position": { "x": -246.4463, "y": 976.02924, "z": 1081.1262 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },
@ -140,11 +140,11 @@
} }
} }
], ],
"target_swarm_configs": [ "threat_swarm_configs": [
{ {
"num_agents": 200, "num_agents": 200,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"target_type": "DRONE", "target_type": "DRONE",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 600, "z": 6000 }, "position": { "x": 0, "y": 600, "z": 6000 },
@ -166,7 +166,7 @@
"num_submunitions": 0, "num_submunitions": 0,
"launch_config": { "launch_time": 0 }, "launch_config": { "launch_time": 0 },
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 0, "z": 0 }, "position": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 },

View File

@ -61,7 +61,7 @@ def plot_telemetry(file_path):
plt.title('Agents Trajectories (X: Right, Z: Forward, Y: Up)') plt.title('Agents Trajectories (X: Right, Z: Forward, Y: Up)')
legend = [ legend = [
plt.Line2D([0], [0], color='red', lw=2, label='Threat'), plt.Line2D([0], [0], color='red', lw=2, label='Threat'),
plt.Line2D([0], [0], color='blue', lw=2, label='Missile') plt.Line2D([0], [0], color='blue', lw=2, label='Interceptor')
] ]
plt.legend(handles=legend) plt.legend(handles=legend)
plt.tight_layout() plt.tight_layout()

View File

@ -1,6 +1,6 @@
# Simulation Configuration Guide # Simulation Configuration Guide
This guide provides instructions on how to configure the simulation by editing the configuration files. You can customize missile and threat behaviors, simulation parameters, and more to suit your needs. This guide provides instructions on how to configure the simulation by editing the configuration files. You can customize interceptor and threat behaviors, simulation parameters, and more to suit your needs.
## Configuration Files ## Configuration Files
@ -35,16 +35,16 @@ The simulation configurations are defined in JSON files that specify the initial
#### `1_salvo_1_hydra_7_drones.json` #### `1_salvo_1_hydra_7_drones.json`
This is a basic configuration featuring a single salvo with one missile type (`HYDRA_70`) and seven threat drones. This is a basic configuration featuring a single salvo with one interceptor type (`HYDRA_70`) and seven threat drones.
```json:Assets/StreamingAssets/Configs/1_salvo_1_hydra_7_drones.json ```json:Assets/StreamingAssets/Configs/1_salvo_1_hydra_7_drones.json
{ {
"timeScale": 1, "timeScale": 1,
"missile_swarm_configs": [ "interceptor_swarm_configs": [
{ {
"num_agents": 1, "num_agents": 1,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 20, "z": 0 }, "position": { "x": 0, "y": 20, "z": 0 },
"rotation": { "x": -45, "y": 0, "z": 0 }, "rotation": { "x": -45, "y": 0, "z": 0 },
@ -61,14 +61,14 @@ This is a basic configuration featuring a single salvo with one missile type (`H
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 4 }, "launch_config": { "launch_time": 4 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
// Submunition configuration... // Submunition configuration...
} }
} }
} }
} }
], ],
"target_swarm_configs": [ "threat_swarm_configs": [
{ {
"num_agents": 7, "num_agents": 7,
"agent_config": { "agent_config": {
@ -92,11 +92,11 @@ This configuration demonstrates a more complex scenario with three salvos, each
```json:Assets/StreamingAssets/Configs/3_salvo_10_hydra_200_drones.json ```json:Assets/StreamingAssets/Configs/3_salvo_10_hydra_200_drones.json
{ {
"timeScale": 1, "timeScale": 1,
"missile_swarm_configs": [ "interceptor_swarm_configs": [
{ {
"num_agents": 10, "num_agents": 10,
"agent_config": { "agent_config": {
"missile_type": "HYDRA_70", "interceptor_type": "HYDRA_70",
"initial_state": { "initial_state": {
"position": { "x": 0, "y": 20, "z": 0 }, "position": { "x": 0, "y": 20, "z": 0 },
"rotation": { "x": -45, "y": 0, "z": 0 }, "rotation": { "x": -45, "y": 0, "z": 0 },
@ -113,15 +113,15 @@ This configuration demonstrates a more complex scenario with three salvos, each
"num_submunitions": 7, "num_submunitions": 7,
"launch_config": { "launch_time": 4 }, "launch_config": { "launch_time": 4 },
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
// Submunition configuration... // Submunition configuration...
} }
} }
} }
}, },
// Two more similar missile_swarm_configs with different launch times... // Two more similar interceptor_swarm_configs with different launch times...
], ],
"target_swarm_configs": [ "threat_swarm_configs": [
{ {
"num_agents": 200, "num_agents": 200,
"agent_config": { "agent_config": {
@ -140,43 +140,43 @@ This configuration demonstrates a more complex scenario with three salvos, each
**Key Differences Between the Examples**: **Key Differences Between the Examples**:
The key difference between the examples is that the **Number of Salvos** in `3_salvo_10_hydra_200_drones.json` file includes multiple salvos by adding multiple entries in the `missile_swarm_configs` array, each with its own `launch_time`. The key difference between the examples is that the **Number of Salvos** in `3_salvo_10_hydra_200_drones.json` file includes multiple salvos by adding multiple entries in the `interceptor_swarm_configs` array, each with its own `launch_time`.
**Achieving Multiple Salvos**: **Achieving Multiple Salvos**:
Multiple salvos are achieved by: Multiple salvos are achieved by:
- Adding multiple configurations in the `missile_swarm_configs` array. - Adding multiple configurations in the `interceptor_swarm_configs` array.
- Specifying different `launch_time` values in the `dynamic_config` for each salvo to control when they launch. - Specifying different `launch_time` values in the `dynamic_config` for each salvo to control when they launch.
### Key Configuration Parameters ### Key Configuration Parameters
- **`timeScale`**: Adjusts the speed of the simulation. - **`timeScale`**: Adjusts the speed of the simulation.
- **`missile_swarm_configs`**: Contains settings for missile swarms. Each entry represents a salvo. - **`interceptor_swarm_configs`**: Contains settings for interceptor swarms. Each entry represents a salvo.
- **`target_swarm_configs`**: Contains settings for threat swarms. - **`threat_swarm_configs`**: Contains settings for threat swarms.
#### Within Each Swarm Configuration #### Within Each Swarm Configuration
- **`num_agents`**: Number of agents (missiles or targets) in the swarm. - **`num_agents`**: Number of agents (missiles or targets) in the swarm.
- **`agent_config`**: Settings for each agent, including: - **`agent_config`**: Settings for each agent, including:
- **`missile_type`** / **`target_type`**: Defines the type of missile or threat. - **`interceptor_type`** / **`target_type`**: Defines the type of interceptor or threat.
- **`initial_state`**: Sets the starting position, rotation, and velocity. - **`initial_state`**: Sets the starting position, rotation, and velocity.
- **`standard_deviation`**: Adds random noise to initial states for variability. - **`standard_deviation`**: Adds random noise to initial states for variability.
- **`dynamic_config`**: Time-dependent settings like `launch_time` and sensor configurations. - **`dynamic_config`**: Time-dependent settings like `launch_time` and sensor configurations.
- **`submunitions_config`**: Details for any submunitions (e.g., micromissiles deployed by a larger missile). - **`submunitions_config`**: Details for any submunitions (e.g., micromissiles deployed by a larger interceptor).
### Adding or Modifying Agents ### Adding or Modifying Agents
1. **Add a New Swarm Configuration**: 1. **Add a New Swarm Configuration**:
To introduce a new missile or threat swarm (or an additional salvo), create a new entry in `missile_swarm_configs` or `target_swarm_configs`. To introduce a new interceptor or threat swarm (or an additional salvo), create a new entry in `interceptor_swarm_configs` or `threat_swarm_configs`.
```json ```json
{ {
"num_agents": 5, "num_agents": 5,
"agent_config": { "agent_config": {
"missile_type": "MICROMISSILE", "interceptor_type": "MICROMISSILE",
// Additional configurations... // Additional configurations...
"dynamic_config": { "dynamic_config": {
"launch_config": { "launch_time": 15 }, "launch_config": { "launch_time": 15 },
@ -194,7 +194,7 @@ Multiple salvos are achieved by:
## Model Configurations ## Model Configurations
The model configurations define the physical and performance characteristics of missile and threat models. The default models provided can be customized to suit your research needs. The model configurations define the physical and performance characteristics of interceptor and threat models. The default models provided can be customized to suit your research needs.
### Available Models ### Available Models
@ -234,7 +234,7 @@ This file defines parameters for the micromissile model.
**Configurable Parameters**: **Configurable Parameters**:
- **`accelerationConfig`**: Controls acceleration characteristics. - **`accelerationConfig`**: Controls acceleration characteristics.
- **`boostConfig`**: Settings for the boost phase of the missile. - **`boostConfig`**: Settings for the boost phase of the craft.
- **`liftDragConfig`**: Aerodynamic properties. - **`liftDragConfig`**: Aerodynamic properties.
- **`bodyConfig`**: Physical attributes like mass and area. - **`bodyConfig`**: Physical attributes like mass and area.
- **`hitConfig`**: Collision detection and damage properties. - **`hitConfig`**: Collision detection and damage properties.
@ -249,7 +249,7 @@ You can tweak the parameters in these model files to adjust performance. For exa
### Adding New Models ### Adding New Models
To define a new missile or threat model: To define a new inte or threat model:
1. **Create a New JSON File** in `Assets/StreamingAssets/Configs/Models/`. 1. **Create a New JSON File** in `Assets/StreamingAssets/Configs/Models/`.
@ -275,7 +275,7 @@ This script defines the data structures used to interpret the JSON simulation co
**Enums**: **Enums**:
- `MissileType`, `ThreatType`, and `SensorType` define available types. - `InterceptorType`, `ThreatType`, and `SensorType` define available types.
### `StaticConfig.cs` ### `StaticConfig.cs`