2024-09-12 00:17:21 -07:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
|
2024-09-24 19:59:25 -07:00
|
|
|
public class Micromissile : Interceptor {
|
2024-09-13 22:45:25 -07:00
|
|
|
[SerializeField]
|
2024-09-14 11:45:50 -07:00
|
|
|
private float _navigationGain = 3f; // Typically 3-5
|
2024-09-13 22:45:25 -07:00
|
|
|
|
|
|
|
private SensorOutput _sensorOutput;
|
|
|
|
private Vector3 _accelerationCommand;
|
|
|
|
private double _elapsedTime = 0;
|
|
|
|
protected override void UpdateMidCourse(double deltaTime) {
|
|
|
|
_elapsedTime += deltaTime;
|
|
|
|
Vector3 accelerationInput = Vector3.zero;
|
|
|
|
if (HasAssignedTarget()) {
|
2024-09-24 19:24:50 -07:00
|
|
|
// Update the threat model (assuming we have a threat model)
|
|
|
|
// TODO: Implement threat model update logic
|
2024-09-13 22:45:25 -07:00
|
|
|
|
2024-09-24 19:24:50 -07:00
|
|
|
// Correct the state of the threat model at the sensor frequency
|
2024-09-13 22:45:25 -07:00
|
|
|
float sensorUpdatePeriod = 1f / _agentConfig.dynamic_config.sensor_config.frequency;
|
|
|
|
if (_elapsedTime >= sensorUpdatePeriod) {
|
|
|
|
// TODO: Implement guidance filter to estimate state from sensor output
|
2024-09-24 19:24:50 -07:00
|
|
|
// For now, we'll use the threat's actual state
|
2024-09-13 22:45:25 -07:00
|
|
|
_sensorOutput = GetComponent<Sensor>().Sense(_target);
|
|
|
|
_elapsedTime = 0;
|
|
|
|
}
|
|
|
|
|
2024-09-24 19:24:50 -07:00
|
|
|
// Check whether the threat should be considered a miss
|
2024-09-13 22:45:25 -07:00
|
|
|
SensorOutput sensorOutput = GetComponent<Sensor>().Sense(_target);
|
|
|
|
if (sensorOutput.velocity.range > 1000f) {
|
2024-09-29 23:18:40 -07:00
|
|
|
this.HandleInterceptMiss();
|
2024-09-13 22:45:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the acceleration input
|
|
|
|
accelerationInput = CalculateAccelerationCommand(_sensorOutput);
|
2024-09-12 00:17:21 -07:00
|
|
|
}
|
|
|
|
|
2024-09-13 22:45:25 -07:00
|
|
|
// Calculate and set the total acceleration
|
|
|
|
Vector3 acceleration = CalculateAcceleration(accelerationInput, compensateForGravity: true);
|
|
|
|
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
|
|
|
|
}
|
|
|
|
private Vector3 CalculateAccelerationCommand(SensorOutput sensorOutput) {
|
|
|
|
// Implement Proportional Navigation guidance law
|
|
|
|
Vector3 accelerationCommand = Vector3.zero;
|
|
|
|
|
|
|
|
// Extract relevant information from sensor output
|
|
|
|
float los_rate_az = sensorOutput.velocity.azimuth;
|
|
|
|
float los_rate_el = sensorOutput.velocity.elevation;
|
|
|
|
float closing_velocity =
|
|
|
|
-sensorOutput.velocity
|
|
|
|
.range; // Negative because closing velocity is opposite to range rate
|
|
|
|
|
|
|
|
// Navigation gain (adjust as needed)
|
|
|
|
float N = _navigationGain;
|
|
|
|
|
|
|
|
// Calculate acceleration commands in azimuth and elevation planes
|
|
|
|
float acc_az = N * closing_velocity * los_rate_az;
|
|
|
|
float acc_el = N * closing_velocity * los_rate_el;
|
|
|
|
|
2024-09-24 19:59:25 -07:00
|
|
|
// Convert acceleration commands to craft body frame
|
2024-09-13 22:45:25 -07:00
|
|
|
accelerationCommand = transform.right * acc_az + transform.up * acc_el;
|
|
|
|
|
|
|
|
// Clamp the acceleration command to the maximum acceleration
|
|
|
|
float maxAcceleration = CalculateMaxAcceleration();
|
|
|
|
accelerationCommand = Vector3.ClampMagnitude(accelerationCommand, maxAcceleration);
|
|
|
|
|
|
|
|
// Update the stored acceleration command for debugging
|
|
|
|
_accelerationCommand = accelerationCommand;
|
|
|
|
return accelerationCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void DrawDebugVectors() {
|
|
|
|
base.DrawDebugVectors();
|
|
|
|
if (_accelerationCommand != null) {
|
|
|
|
Debug.DrawRay(transform.position, _accelerationCommand * 1f, Color.green);
|
2024-09-12 00:17:21 -07:00
|
|
|
}
|
2024-09-13 22:45:25 -07:00
|
|
|
}
|
2024-09-12 00:17:21 -07:00
|
|
|
}
|