Clustering working

This commit is contained in:
Daniel Lovell
2024-09-12 15:44:55 -07:00
parent e42f9e094c
commit 4acc2fd32c
16 changed files with 819 additions and 161 deletions

View File

@@ -16,20 +16,34 @@ public abstract class Agent : MonoBehaviour
TERMINATED
}
protected double _elapsedTime = 0;
[SerializeField]
protected FlightPhase _flightPhase = FlightPhase.INITIALIZED;
private FlightPhase _flightPhase = FlightPhase.INITIALIZED;
[SerializeField]
protected Agent _target;
protected bool _isHit = false;
protected bool _isMiss = false;
protected DynamicConfig _dynamicConfig;
protected AgentConfig _agentConfig;
protected double _timeSinceLaunch = 0;
protected double _timeInPhase = 0;
[SerializeField]
public StaticConfig StaticConfig;
public void SetFlightPhase(FlightPhase flightPhase) {
Debug.Log($"Setting flight phase to {flightPhase} at time {SimManager.Instance.GetElapsedSimulationTime()}");
_timeInPhase = 0;
_flightPhase = flightPhase;
}
public FlightPhase GetFlightPhase() {
return _flightPhase;
}
public bool HasLaunched() {
return (_flightPhase != FlightPhase.INITIALIZED) && (_flightPhase != FlightPhase.READY);
}
@@ -39,7 +53,7 @@ public abstract class Agent : MonoBehaviour
}
public virtual void SetAgentConfig(AgentConfig config) {
_dynamicConfig = config.dynamic_config;
_agentConfig = config;
}
public virtual bool IsAssignable() {
@@ -118,21 +132,28 @@ public abstract class Agent : MonoBehaviour
// Start is called before the first frame update
protected virtual void Start()
{
_elapsedTime = 0;
_flightPhase = FlightPhase.READY;
}
// Update is called once per frame
protected virtual void Update()
{
var launch_time = _dynamicConfig.launch_config.launch_time;
_timeSinceLaunch += Time.deltaTime;
_timeInPhase += Time.deltaTime;
var launch_time = _agentConfig.dynamic_config.launch_config.launch_time;
var boost_time = launch_time + StaticConfig.boostConfig.boostTime;
_elapsedTime += Time.deltaTime;
if(_elapsedTime > launch_time) {
_flightPhase = FlightPhase.BOOST;
double elapsedSimulationTime = SimManager.Instance.GetElapsedSimulationTime();
if(_flightPhase == FlightPhase.TERMINATED) {
return;
}
if(_elapsedTime > boost_time) {
_flightPhase = FlightPhase.MIDCOURSE;
if(elapsedSimulationTime >= launch_time && _flightPhase == FlightPhase.READY) {
SetFlightPhase(FlightPhase.BOOST);
}
if(_timeSinceLaunch > boost_time && _flightPhase == FlightPhase.BOOST) {
SetFlightPhase(FlightPhase.MIDCOURSE);
}
AlignWithVelocity();
switch (_flightPhase) {

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using UnityEngine;
// The assignment class is an interface for assigning a target to each missile.
public abstract class Assignment
public interface IAssignment
{
// Assignment item type.
// The first element corresponds to the missile index, and the second element
@@ -21,13 +21,9 @@ public abstract class Assignment
}
// A list containing the missile-target assignments.
protected LinkedList<AssignmentItem> missileToTargetAssignments = new LinkedList<AssignmentItem>();
// Return the missile-target assignments.
public IEnumerable<AssignmentItem> Assignments => missileToTargetAssignments;
// Assign a target to each missile that has not been assigned a target yet.
public abstract void 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.
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles)

View File

@@ -5,24 +5,25 @@ using UnityEngine;
// The round-robin assignment class assigns missiles to the targets in a
// round-robin order.
public class RoundRobinAssignment : Assignment
public class RoundRobinAssignment : IAssignment
{
// Previous target index that was assigned.
private int prevTargetIndex = -1;
// Assign a target to each missile that has not been assigned a target yet.
public override void Assign(List<Agent> missiles, List<Agent> targets)
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
{
List<int> assignableMissileIndices = GetAssignableMissileIndices(missiles);
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
if (assignableMissileIndices.Count == 0)
{
return;
return assignments;
}
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
if (activeTargetIndices.Count == 0)
{
return;
return assignments;
}
foreach (int missileIndex in assignableMissileIndices)
@@ -36,8 +37,10 @@ public class RoundRobinAssignment : Assignment
}
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, nextTargetIndex));
assignments.Add(new IAssignment.AssignmentItem(missileIndex, nextTargetIndex));
prevTargetIndex = nextTargetIndex;
}
return assignments;
}
}

View File

@@ -1,44 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
// The threat assignment class assigns missiles to the targets based
// on the threat level of the targets.
public class ThreatAssignment : Assignment
public class ThreatAssignment : IAssignment
{
// Assign a target to each missile that has not been assigned a target yet.
public override void Assign(List<Agent> missiles, List<Agent> targets)
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
{
List<int> assignableMissileIndices = GetAssignableMissileIndices(missiles);
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
if (assignableMissileIndices.Count == 0)
{
return;
return assignments;
}
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
if (activeTargetIndices.Count == 0)
{
return;
return assignments;
}
Vector3 missilesMeanPosition = CalculateMeanPosition(missiles);
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, missilesMeanPosition);
Vector3 positionToDefend = Vector3.zero;
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, positionToDefend);
foreach (int missileIndex in assignableMissileIndices)
{
if (missiles[missileIndex].HasAssignedTarget()) continue;
if (threatInfos.Count == 0) break;
ThreatInfo highestThreat = threatInfos[0];
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, highestThreat.TargetIndex));
assignments.Add(new IAssignment.AssignmentItem(missileIndex, highestThreat.TargetIndex));
threatInfos.RemoveAt(0);
}
return assignments;
}
private Vector3 CalculateMeanPosition(List<Agent> agents)
{
return agents.Aggregate(Vector3.zero, (sum, agent) => sum + agent.transform.position) / agents.Count;
}
private List<ThreatInfo> CalculateThreatLevels(List<Agent> targets, List<int> activeTargetIndices, Vector3 missilesMeanPosition)
{

View File

@@ -40,7 +40,22 @@ public class AgentConfig
public DynamicConfig dynamic_config;
public PlottingConfig plotting_config;
public SubmunitionsConfig submunitions_config;
public string prefabName;
public static AgentConfig FromSubmunitionAgentConfig(SubmunitionAgentConfig submunitionConfig)
{
return new AgentConfig
{
missile_type = submunitionConfig.missile_type,
initial_state = submunitionConfig.initial_state,
standard_deviation = submunitionConfig.standard_deviation,
dynamic_config = submunitionConfig.dynamic_config,
plotting_config = submunitionConfig.plotting_config,
// Set other fields as needed, using default values if not present in SubmunitionAgentConfig
target_type = TargetType.DRONE, // Or another default value
submunitions_config = null // Or a default value if needed
};
}
}
[System.Serializable]
@@ -88,7 +103,6 @@ public class SubmunitionAgentConfig
public StandardDeviation standard_deviation;
public DynamicConfig dynamic_config;
public PlottingConfig plotting_config;
public string prefabName;
}
[System.Serializable]
@@ -115,7 +129,8 @@ public enum MissileType
public enum TargetType
{
DRONE
DRONE,
MISSILE
}
public enum ConfigColor

View File

@@ -0,0 +1,65 @@
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEngine;
public class Hydra70 : Missile
{
private Vector3 _acceleration;
private bool _submunitionsLaunched = false;
protected override void Update() {
base.Update();
// Check if it's time to launch submunitions
if (!_submunitionsLaunched && (GetFlightPhase() == FlightPhase.MIDCOURSE || GetFlightPhase() == FlightPhase.BOOST) &&
SimManager.Instance.GetElapsedSimulationTime() >= _agentConfig.submunitions_config.launch_config.launch_time)
{
SpawnSubmunitions();
_submunitionsLaunched = true;
}
}
protected override void UpdateMidCourse(double deltaTime)
{
Vector3 accelerationInput = Vector3.zero;
// Calculate and set the total acceleration
Vector3 acceleration = CalculateAcceleration(accelerationInput, compensateForGravity: true);
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
_acceleration = acceleration;
}
protected override void DrawDebugVectors()
{
base.DrawDebugVectors();
if (_acceleration != null)
{
Debug.DrawRay(transform.position, _acceleration * 1f, Color.green);
}
}
public void SpawnSubmunitions() {
Debug.Log("Spawning submunitions");
// print the callstack
Debug.Log(new System.Diagnostics.StackTrace().ToString());
List<Missile> submunitions = new List<Missile>();
switch(_agentConfig.submunitions_config.agent_config.missile_type) {
case MissileType.MICROMISSILE:
for (int i = 0; i < _agentConfig.submunitions_config.num_submunitions; i++) {
AgentConfig convertedConfig = AgentConfig.FromSubmunitionAgentConfig(_agentConfig.submunitions_config.agent_config);
convertedConfig.initial_state.position = transform.position;
convertedConfig.initial_state.velocity = GetComponent<Rigidbody>().velocity;
Missile submunition = SimManager.Instance.CreateMissile(convertedConfig);
submunitions.Add(submunition);
Debug.Log("Created submunition");
}
break;
}
SimManager.Instance.AssignMissilesToTargets(submunitions);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 403a04456de34694a8946c6a5084a9cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -4,14 +4,15 @@ using UnityEngine;
public class Micromissile : Missile
{
[SerializeField] private float navigationGain = 5f; // Typically 3-5
[SerializeField] private bool _showDebugVectors = true;
[SerializeField] private float _navigationGain = 5f; // Typically 3-5
private Vector3 _previousLOS;
private Vector3 _accelerationCommand;
private float _lastUpdateTime;
private double _elapsedTime = 0;
protected override void UpdateMidCourse(double deltaTime)
{
_elapsedTime += deltaTime;
Vector3 accelerationInput = Vector3.zero;
if (HasAssignedTarget())
{
@@ -19,13 +20,14 @@ public class Micromissile : Missile
// TODO: Implement target model update logic
// Correct the state of the target model at the sensor frequency
float sensorUpdatePeriod = 1f / _dynamicConfig.sensor_config.frequency;
if (_elapsedTime - _sensorUpdateTime >= sensorUpdatePeriod)
float sensorUpdatePeriod = 1f / _agentConfig.dynamic_config.sensor_config.frequency;
if (_elapsedTime - _lastUpdateTime >= sensorUpdatePeriod)
{
// TODO: Implement guidance filter to estimate state from sensor output
// For now, we'll use the target's actual state
// targetModel.SetState(_target.GetState());
_sensorUpdateTime = (float)_elapsedTime;
_lastUpdateTime = (float)_elapsedTime;
_elapsedTime = 0;
}
// Sense the target
@@ -43,11 +45,6 @@ public class Micromissile : Missile
Vector3 acceleration = CalculateAcceleration(accelerationInput, compensateForGravity: true);
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
if (_showDebugVectors)
{
DrawDebugVectors();
}
}
private Vector3 CalculateAccelerationCommand(SensorOutput sensorOutput)
@@ -61,7 +58,7 @@ public class Micromissile : Missile
float closing_velocity = -sensorOutput.velocity.range; // Negative because closing velocity is opposite to range rate
// Navigation gain (adjust as needed)
float N = navigationGain;
float N = _navigationGain;
// Calculate acceleration commands in azimuth and elevation planes
float acc_az = N * closing_velocity * los_rate_az;
@@ -78,27 +75,14 @@ public class Micromissile : Missile
_accelerationCommand = accelerationCommand;
return accelerationCommand;
}
private void DrawDebugVectors()
protected override void DrawDebugVectors()
{
if (_target != null)
base.DrawDebugVectors();
if (_accelerationCommand != null)
{
// Line of sight
Debug.DrawLine(transform.position, _target.transform.position, new Color(1, 1, 1, 0.15f));
// Velocity vector
Debug.DrawRay(transform.position, GetVelocity()*0.01f, new Color(0, 0, 1, 0.15f));
// Acceleration input
Debug.DrawRay(transform.position, _accelerationCommand*1f, Color.green);
// Current forward direction
Debug.DrawRay(transform.position, transform.forward * 5f, Color.yellow);
// Pitch axis (right)
Debug.DrawRay(transform.position, transform.right * 5f, Color.red);
// Yaw axis (up)
Debug.DrawRay(transform.position, transform.up * 5f, Color.magenta);
Debug.DrawRay(transform.position, _accelerationCommand * 1f, Color.green);
}
}
}

View File

@@ -5,7 +5,7 @@ using UnityEngine;
public class Missile : Agent
{
protected double _sensorUpdateTime = 0.0;
[SerializeField] protected bool _showDebugVectors = true;
[SerializeField]
private Vector3 _boostAcceleration;
@@ -32,6 +32,13 @@ public class Missile : Agent
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
}
protected override void Update() {
base.Update();
if(_showDebugVectors) {
DrawDebugVectors();
}
}
protected override void UpdateBoost(double deltaTime)
{
// The missile only accelerates along its roll axis (forward in Unity)
@@ -142,4 +149,25 @@ public class Missile : Agent
return Mathf.Abs(liftAcceleration / liftDragRatio) * Vector3.one;
}
protected virtual void DrawDebugVectors()
{
if (_target != null)
{
// Line of sight
Debug.DrawLine(transform.position, _target.transform.position, new Color(1, 1, 1, 0.15f));
// Velocity vector
Debug.DrawRay(transform.position, GetVelocity()*0.01f, new Color(0, 0, 1, 0.15f));
// Current forward direction
Debug.DrawRay(transform.position, transform.forward * 5f, Color.yellow);
// Pitch axis (right)
Debug.DrawRay(transform.position, transform.right * 5f, Color.red);
// Yaw axis (up)
Debug.DrawRay(transform.position, transform.up * 5f, Color.magenta);
}
}
}

View File

@@ -1,92 +1,126 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SimManager : MonoBehaviour
{
// Singleton instance
public static SimManager Instance { get; private set; }
[SerializeField]
public SimulationConfig simulationConfig;
private List<Missile> missiles = new List<Missile>();
private List<Target> targets = new List<Target>();
private float currentTime = 0f;
private List<Missile> _missiles = new List<Missile>();
private HashSet<Target> _unassignedTargets = new HashSet<Target>();
private HashSet<Target> _targets = new HashSet<Target>();
private float _elapsedSimulationTime = 0f;
private float endTime = 100f; // Set an appropriate end time
private bool simulationRunning = false;
private Assignment _assignment;
private IAssignment _assignmentScheme;
public double GetElapsedSimulationTime()
{
return _elapsedSimulationTime;
}
void Awake()
{
// Ensure only one instance of SimManager exists
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
void Start() {
// Slow down time by simulationConfig.timeScale
Time.timeScale = simulationConfig.timeScale;
Time.fixedDeltaTime = Time.timeScale * 0.02f;
Time.maximumDeltaTime = Time.timeScale * 0.15f;
InitializeSimulation();
simulationRunning = true;
if(Instance == this) {
Time.timeScale = simulationConfig.timeScale;
Time.fixedDeltaTime = Time.timeScale * 0.02f;
Time.maximumDeltaTime = Time.timeScale * 0.15f;
InitializeSimulation();
simulationRunning = true;
}
}
private void InitializeSimulation()
{
List<Missile> missiles = new List<Missile>();
// Create missiles based on config
foreach (var swarmConfig in simulationConfig.missile_swarm_configs)
{
for (int i = 0; i < swarmConfig.num_agents; i++) {
var missile = CreateMissile(swarmConfig.agent_config);
missiles.Add(missile);
}
}
List<Target> targets = new List<Target>();
// Create targets based on config
foreach (var swarmConfig in simulationConfig.target_swarm_configs)
{
for (int i = 0; i < swarmConfig.num_agents; i++) {
var target = CreateTarget(swarmConfig.agent_config);
targets.Add(target);
}
}
_assignment = new ThreatAssignment();
_assignmentScheme = new ThreatAssignment();
// Perform initial assignment
AssignMissilesToTargets();
}
private void AssignMissilesToTargets()
public void AssignMissilesToTargets()
{
// Convert Missile and Target lists to Agent lists
List<Agent> missileAgents = new List<Agent>(missiles.ConvertAll(m => m as Agent));
List<Agent> targetAgents = new List<Agent>(targets.ConvertAll(t => t as Agent));
AssignMissilesToTargets(_missiles);
}
public void AssignMissilesToTargets(List<Missile> missilesToAssign)
{
// Convert Missile and Target lists to Agent lists
List<Agent> missileAgents = new List<Agent>(missilesToAssign.ConvertAll(m => m as Agent));
// Convert Target list to Agent list, excluding already assigned targets
List<Agent> targetAgents = _unassignedTargets.ToList<Agent>();
// Perform the assignment
_assignment.Assign(missileAgents, targetAgents);
IEnumerable<IAssignment.AssignmentItem> assignments = _assignmentScheme.Assign(missileAgents, targetAgents);
// Apply the assignments to the missiles
foreach (var assignment in _assignment.Assignments)
foreach (var assignment in assignments)
{
Missile missile = missiles[assignment.MissileIndex];
Target target = targets[assignment.TargetIndex];
missile.AssignTarget(target);
Debug.Log($"Missile {missile.name} assigned to target {target.name}");
if (assignment.MissileIndex < missilesToAssign.Count)
{
Missile missile = missilesToAssign[assignment.MissileIndex];
Target target = _targets.ElementAt(assignment.TargetIndex);
missile.AssignTarget(target);
Debug.Log($"Missile {missile.name} assigned to target {target.name}");
_unassignedTargets.Remove(target);
}
}
}
private Missile CreateMissile(AgentConfig config)
public Missile CreateMissile(AgentConfig config)
{
// Load the missile prefab from Resources
GameObject missilePrefab = Resources.Load<GameObject>($"Prefabs/{config.prefabName}");
if (missilePrefab == null)
string prefabName = config.missile_type switch
{
Debug.LogError($"Missile prefab '{config.prefabName}' not found in Resources/Prefabs folder.");
return null;
}
MissileType.HYDRA_70 => "Hydra70",
MissileType.MICROMISSILE => "Micromissile",
_ => "Hydra70"
};
// Apply noise to the initial position
Vector3 noiseOffset = Utilities.GenerateRandomNoise(config.standard_deviation.position);
Vector3 noisyPosition = config.initial_state.position + noiseOffset;
// Instantiate the missile with the noisy position
GameObject missileObject = Instantiate(missilePrefab, noisyPosition, Quaternion.Euler(config.initial_state.rotation));
GameObject missileObject = CreateAgent(config, prefabName);
if (missileObject == null) return null;
// Missile-specific logic
switch(config.dynamic_config.sensor_config.type) {
case SensorType.IDEAL:
missileObject.AddComponent<IdealSensor>();
@@ -96,91 +130,100 @@ public class SimManager : MonoBehaviour
break;
}
// Set initial velocity
Rigidbody missileRigidbody = missileObject.GetComponent<Rigidbody>();
// Apply noise to the initial velocity
Vector3 velocityNoise = Utilities.GenerateRandomNoise(config.standard_deviation.velocity);
Vector3 noisyVelocity = config.initial_state.velocity + velocityNoise;
missileRigidbody.velocity = noisyVelocity;
// Missile missile = missileObject.GetComponent<Missile>();
// if (missile == null)
// {
// Debug.LogError($"Missile component not found on prefab '{prefabName}'.");
// Destroy(missileObject);
// return null;
// }
Missile missile = missileObject.GetComponent<Missile>();
missile.SetAgentConfig(config);
if (missile == null)
{
Debug.LogError($"Missile component not found on prefab '{config.prefabName}'.");
Destroy(missileObject);
return null;
}
// Initialize missile properties
//missile.Initialize(config);
return missile;
// missile.SetAgentConfig(config);
_missiles.Add(missileObject.GetComponent<Missile>());
// Assign a unique and simple target ID
int missileId = _missiles.Count;
missileObject.name = $"{config.missile_type}_Missile_{missileId}";
return missileObject.GetComponent<Missile>();
}
private Target CreateTarget(AgentConfig config)
{
// Load the target prefab from Resources
GameObject targetPrefab = Resources.Load<GameObject>($"Prefabs/{config.prefabName}");
if (targetPrefab == null)
string prefabName = config.target_type switch
{
Debug.LogError($"Target prefab '{config.prefabName}' not found in Resources/Prefabs folder.");
TargetType.DRONE => "DroneTarget",
TargetType.MISSILE => "MissileTarget",
_ => throw new System.ArgumentException($"Unsupported target type: {config.target_type}")
};
GameObject targetObject = CreateAgent(config, prefabName);
if (targetObject == null) return null;
// Target target = targetObject.GetComponent<Target>();
// if (target == null)
// {
// Debug.LogError($"Target component not found on prefab '{config.prefabName}'.");
// Destroy(targetObject);
// return null;
// }
// target.SetAgentConfig(config);
_targets.Add(targetObject.GetComponent<Target>());
_unassignedTargets.Add(targetObject.GetComponent<Target>());
// Assign a unique and simple target ID
int targetId = _targets.Count;
targetObject.name = $"{config.target_type}_Target_{targetId}";
return targetObject.GetComponent<Target>();
}
public GameObject CreateAgent(AgentConfig config, string prefabName)
{
GameObject prefab = Resources.Load<GameObject>($"Prefabs/{prefabName}");
if (prefab == null)
{
Debug.LogError($"Prefab '{prefabName}' not found in Resources/Prefabs folder.");
return null;
}
// Apply noise to the initial position
Vector3 noiseOffset = Utilities.GenerateRandomNoise(config.standard_deviation.position);
Vector3 noisyPosition = config.initial_state.position + noiseOffset;
// Instantiate the target with the noisy position
GameObject targetObject = Instantiate(targetPrefab, noisyPosition, Quaternion.Euler(config.initial_state.rotation));
GameObject agentObject = Instantiate(prefab, noisyPosition, Quaternion.Euler(config.initial_state.rotation));
// Set initial velocity with noise
Rigidbody targetRigidbody = targetObject.GetComponent<Rigidbody>();
Rigidbody agentRigidbody = agentObject.GetComponent<Rigidbody>();
Vector3 velocityNoise = Utilities.GenerateRandomNoise(config.standard_deviation.velocity);
Vector3 noisyVelocity = config.initial_state.velocity + velocityNoise;
targetRigidbody.velocity = noisyVelocity;
agentRigidbody.velocity = noisyVelocity;
Target target = targetObject.GetComponent<Target>();
target.SetAgentConfig(config);
agentObject.GetComponent<Agent>().SetAgentConfig(config);
if (target == null)
{
Debug.LogError($"Target component not found on prefab '{config.prefabName}'.");
Destroy(targetObject);
return null;
}
return agentObject;
}
// Initialize target properties
//target.Initialize(config);
return target;
}
private void RestartSimulation()
{
// Reset simulation time
currentTime = 0f;
_elapsedSimulationTime = 0f;
simulationRunning = true;
// Clear existing missiles and targets
foreach (var missile in missiles)
foreach (var missile in _missiles)
{
if (missile != null)
{
Destroy(missile.gameObject);
}
}
missiles.Clear();
_missiles.Clear();
foreach (var target in targets)
foreach (var target in _targets)
{
if (target != null)
{
Destroy(target.gameObject);
}
}
targets.Clear();
_targets.Clear();
InitializeSimulation();
}
@@ -189,7 +232,7 @@ public class SimManager : MonoBehaviour
{
// Check if all missiles have terminated
bool allMissilesTerminated = true;
foreach (var missile in missiles)
foreach (var missile in _missiles)
{
if (missile != null && !missile.IsHit() && !missile.IsMiss())
{
@@ -203,11 +246,11 @@ public class SimManager : MonoBehaviour
RestartSimulation();
}
if (simulationRunning && currentTime < endTime)
if (simulationRunning && _elapsedSimulationTime < endTime)
{
currentTime += Time.deltaTime;
_elapsedSimulationTime += Time.deltaTime;
}
else if (currentTime >= endTime)
else if (_elapsedSimulationTime >= endTime)
{
simulationRunning = false;
Debug.Log("Simulation completed.");

View File

@@ -4,8 +4,6 @@ using UnityEngine;
public abstract class Target : Agent
{
public override bool IsAssignable() {
return false;
}