diff --git a/Assets/Resources/Prefabs/MissileThreat.prefab b/Assets/Resources/Prefabs/MissileThreat.prefab new file mode 100644 index 0000000..b7469bf --- /dev/null +++ b/Assets/Resources/Prefabs/MissileThreat.prefab @@ -0,0 +1,361 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &295999596028346972 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9192475791974545516} + - component: {fileID: 3681380462727606042} + - component: {fileID: 5038767565634652910} + m_Layer: 0 + m_Name: Cone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &9192475791974545516 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 295999596028346972} + serializedVersion: 2 + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: -3.89} + m_LocalScale: {x: 20, y: 20, z: 20} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8462434346230391091} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &3681380462727606042 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 295999596028346972} + m_Mesh: {fileID: 4300000, guid: 36b72d5a34c22d94c88a068dfcbdf27a, type: 2} +--- !u!23 &5038767565634652910 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 295999596028346972} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 061083197c659dc44983633a84d39cea, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &4390675743535140416 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 585396986125101381} + - component: {fileID: 4620404264009677289} + m_Layer: 0 + m_Name: TrailRenderer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &585396986125101381 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4390675743535140416} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 10, z: 10} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8462434346230391091} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!96 &4620404264009677289 +TrailRenderer: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4390675743535140416} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 0e42500808910f24cb6626a81760c995, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Time: 5 + m_PreviewTimeScale: 1 + m_Parameters: + serializedVersion: 3 + widthMultiplier: 5 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 0, b: 0, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: 0 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 0 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MinVertexDistance: 0.1 + m_MaskInteraction: 0 + m_Autodestruct: 0 + m_Emitting: 1 + m_ApplyActiveColorSpace: 0 +--- !u!1 &4590233640347492898 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8315564871113561163} + - component: {fileID: 6203868598056538240} + m_Layer: 0 + m_Name: Collider + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8315564871113561163 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4590233640347492898} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8462434346230391091} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!135 &6203868598056538240 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4590233640347492898} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 1 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 10 + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &6438458936967544359 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8462434346230391091} + - component: {fileID: 4571646124809534626} + - component: {fileID: 4451965530778273955} + m_Layer: 0 + m_Name: MissileThreat + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8462434346230391091 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6438458936967544359} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 585396986125101381} + - {fileID: 8315564871113561163} + - {fileID: 9192475791974545516} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4571646124809534626 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6438458936967544359} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f532f6ee629e87643b7b75a50e83083f, type: 3} + m_Name: + m_EditorClassIdentifier: + _flightPhase: 0 + _velocity: {x: 0, y: 0, z: 0} + _acceleration: {x: 0, y: 0, z: 0} + _dragAcceleration: {x: 0, y: 0, z: 0} + _target: {fileID: 0} + staticConfigFile: drone.json +--- !u!54 &4451965530778273955 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6438458936967544359} + serializedVersion: 4 + m_Mass: 1 + m_Drag: 0 + m_AngularDrag: 0 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 + m_UseGravity: 0 + m_IsKinematic: 0 + m_Interpolate: 0 + m_Constraints: 0 + m_CollisionDetection: 0 diff --git a/Assets/Resources/Prefabs/MissileThreat.prefab.meta b/Assets/Resources/Prefabs/MissileThreat.prefab.meta new file mode 100644 index 0000000..7ae69c9 --- /dev/null +++ b/Assets/Resources/Prefabs/MissileThreat.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a4172237088e66b4190f0126eef67443 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Agent.cs b/Assets/Scripts/Agent.cs index 218dcad..3795137 100644 --- a/Assets/Scripts/Agent.cs +++ b/Assets/Scripts/Agent.cs @@ -42,7 +42,7 @@ public abstract class Agent : MonoBehaviour { public void SetFlightPhase(FlightPhase flightPhase) { Debug.Log( - $"Setting flight phase to {flightPhase} at time {SimManager.Instance.GetElapsedSimulationTime()}"); + $"Setting {name} flight phase to {flightPhase} at time {SimManager.Instance.GetElapsedSimulationTime()}"); _timeInPhase = 0; _flightPhase = flightPhase; } diff --git a/Assets/Scripts/Config/SimulationConfig.cs b/Assets/Scripts/Config/SimulationConfig.cs index 114cd0a..6ec3d6a 100644 --- a/Assets/Scripts/Config/SimulationConfig.cs +++ b/Assets/Scripts/Config/SimulationConfig.cs @@ -112,7 +112,7 @@ public class TargetConfig { [JsonConverter(typeof(StringEnumConverter))] public enum InterceptorType { HYDRA_70, MICROMISSILE } [JsonConverter(typeof(StringEnumConverter))] -public enum ThreatType { DRONE, ANTISHIP_MISSILE } +public enum ThreatType { DRONE, MISSILE } [JsonConverter(typeof(StringEnumConverter))] public enum ConfigColor { BLUE, GREEN, RED } [JsonConverter(typeof(StringEnumConverter))] diff --git a/Assets/Scripts/SimManager.cs b/Assets/Scripts/SimManager.cs index da97c7f..f781ea6 100644 --- a/Assets/Scripts/SimManager.cs +++ b/Assets/Scripts/SimManager.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -118,6 +119,10 @@ public class SimManager : MonoBehaviour { foreach (var swarmConfig in simulationConfig.threat_swarm_configs) { for (int i = 0; i < swarmConfig.num_agents; i++) { var threat = CreateThreat(swarmConfig.agent_config); + if (threat == null) { + Debug.LogError($"Failed to create threat: {swarmConfig.agent_config}"); + continue; + } threat.OnAgentHit += RegisterThreatHit; threat.OnAgentMiss += RegisterThreatMiss; } @@ -226,12 +231,14 @@ public class SimManager : MonoBehaviour { /// The created Threat instance, or null if creation failed. private Threat CreateThreat(AgentConfig config) { string prefabName = config.threat_type switch { - ThreatType.DRONE => "Drone", ThreatType.ANTISHIP_MISSILE => "AntishipMissile", + ThreatType.DRONE => "Drone", ThreatType.MISSILE => "MissileThreat", _ => throw new System.ArgumentException($"Unsupported threat type: {config.threat_type}") }; GameObject threatObject = CreateAgent(config, prefabName); - if (threatObject == null) + if (threatObject == null) { + Debug.LogError($"Failed to create threat for {prefabName}."); return null; + } _threats.Add(threatObject.GetComponent()); _activeThreats.Add(threatObject.GetComponent()); diff --git a/Assets/Scripts/Threats/AntishipMissile.cs b/Assets/Scripts/Threats/AntishipMissile.cs deleted file mode 100644 index e5cecf7..0000000 --- a/Assets/Scripts/Threats/AntishipMissile.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class AntishipMissile : MonoBehaviour { - // Start is called before the first frame update - void Start() {} - - // Update is called once per frame - void Update() {} -} diff --git a/Assets/Scripts/Threats/MissileThreat.cs b/Assets/Scripts/Threats/MissileThreat.cs new file mode 100644 index 0000000..6d3e04d --- /dev/null +++ b/Assets/Scripts/Threats/MissileThreat.cs @@ -0,0 +1,107 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// +/// Base class for missile targets. Uses same set of flight phases as base Hydra-70. +/// +public class MissileThreat : Threat +{ + protected float boostAcceleration = 20; + protected float midcourseAcceleration = 5; + + protected override void UpdateReady(double deltaTime) + { + // if in ready phase, just set to boost phase immediately + SetFlightPhase(FlightPhase.BOOST); + } + + protected override void UpdateBoost(double deltaTime) + { + // The interceptor only accelerates along its roll axis (forward in Unity) + Vector3 rollAxis = transform.forward; + + // Calculate boost acceleration + float boostAcceleration = + (float)(_staticConfig.boostConfig.boostAcceleration * Constants.kGravity); + Vector3 accelerationInput = boostAcceleration * rollAxis; + + // Calculate the total acceleration + Vector3 acceleration = CalculateAcceleration(accelerationInput); + + // Apply the acceleration force + GetComponent().AddForce(acceleration, ForceMode.Acceleration); + } + + protected override void UpdateMidCourse(double deltaTime) + { + Vector3 accelerationInput = Vector3.zero; + // Calculate and set the total acceleration + Vector3 acceleration = CalculateAcceleration(accelerationInput); + GetComponent().AddForce(acceleration, ForceMode.Acceleration); + } + + protected Vector3 CalculateAcceleration(Vector3 accelerationInput, + bool compensateForGravity = false) + { + Vector3 gravity = Physics.gravity; + if (compensateForGravity) + { + Vector3 gravityProjection = CalculateGravityProjectionOnPitchAndYaw(); + accelerationInput -= gravityProjection; + } + + float airDrag = CalculateDrag(); + float liftInducedDrag = CalculateLiftInducedDrag(accelerationInput); + float dragAcceleration = -(airDrag + liftInducedDrag); + + // Project the drag acceleration onto the forward direction + Vector3 dragAccelerationAlongRoll = dragAcceleration * transform.forward; + _dragAcceleration = dragAccelerationAlongRoll; + + return accelerationInput + gravity + dragAccelerationAlongRoll; + } + + protected float CalculateMaxAcceleration() + { + float maxReferenceAcceleration = + (float)(_staticConfig.accelerationConfig.maxReferenceAcceleration * Constants.kGravity); + float referenceSpeed = _staticConfig.accelerationConfig.referenceSpeed; + return Mathf.Pow(GetComponent().linearVelocity.magnitude / referenceSpeed, 2) * + maxReferenceAcceleration; + } + + protected Vector3 CalculateGravityProjectionOnPitchAndYaw() + { + Vector3 gravity = Physics.gravity; + Vector3 pitchAxis = transform.right; + Vector3 yawAxis = transform.up; + + // Project the gravity onto the pitch and yaw axes + float gravityProjectionPitchCoefficient = Vector3.Dot(gravity, pitchAxis); + float gravityProjectionYawCoefficient = Vector3.Dot(gravity, yawAxis); + + // Return the sum of the projections + return gravityProjectionPitchCoefficient * pitchAxis + + gravityProjectionYawCoefficient * yawAxis; + } + + private float CalculateDrag() + { + float dragCoefficient = _staticConfig.liftDragConfig.dragCoefficient; + float crossSectionalArea = _staticConfig.bodyConfig.crossSectionalArea; + float mass = _staticConfig.bodyConfig.mass; + float dynamicPressure = (float)GetDynamicPressure(); + float dragForce = dragCoefficient * dynamicPressure * crossSectionalArea; + return dragForce / mass; + } + + private float CalculateLiftInducedDrag(Vector3 accelerationInput) + { + float liftAcceleration = + (accelerationInput - Vector3.Dot(accelerationInput, transform.up) * transform.up).magnitude; + float liftDragRatio = _staticConfig.liftDragConfig.liftDragRatio; + return Mathf.Abs(liftAcceleration / liftDragRatio); + } + +} diff --git a/Assets/Scripts/Threats/AntishipMissile.cs.meta b/Assets/Scripts/Threats/MissileThreat.cs.meta similarity index 100% rename from Assets/Scripts/Threats/AntishipMissile.cs.meta rename to Assets/Scripts/Threats/MissileThreat.cs.meta diff --git a/Assets/StreamingAssets/Configs/1_salvo_1_hydra_7_tomahawks.json b/Assets/StreamingAssets/Configs/1_salvo_1_hydra_7_tomahawks.json new file mode 100644 index 0000000..e65320f --- /dev/null +++ b/Assets/StreamingAssets/Configs/1_salvo_1_hydra_7_tomahawks.json @@ -0,0 +1,150 @@ +{ + "timeScale": 1, + "interceptor_swarm_configs": [ + { + "num_agents": 1, + "agent_config": { + "interceptor_type": "HYDRA_70", + "threat_type": "DRONE", + "initial_state": { + "position": { + "x": 0, + "y": 20, + "z": 0 + }, + "rotation": { + "x": -45, + "y": 0, + "z": 0 + }, + "velocity": { + "x": 0, + "y": 10, + "z": 10 + } + }, + "standard_deviation": { + "position": { + "x": 10, + "y": 0, + "z": 10 + }, + "velocity": { + "x": 5, + "y": 0, + "z": 1 + } + }, + "dynamic_config": { + "launch_config": { + "launch_time": 0 + }, + "sensor_config": { + "type": "IDEAL", + "frequency": 100 + } + }, + "submunitions_config": { + "num_submunitions": 7, + "launch_config": { + "launch_time": 4 + }, + "agent_config": { + "interceptor_type": "MICROMISSILE", + "initial_state": { + "position": { + "x": 0, + "y": 0, + "z": 0 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "velocity": { + "x": 0, + "y": 0, + "z": 0 + } + }, + "standard_deviation": { + "position": { + "x": 5, + "y": 5, + "z": 5 + }, + "velocity": { + "x": 0, + "y": 0, + "z": 0 + } + }, + "dynamic_config": { + "launch_config": { + "launch_time": 0 + }, + "sensor_config": { + "type": "IDEAL", + "frequency": 100 + } + } + } + } + } + } + ], + "threat_swarm_configs": [ + { + "num_agents": 7, + "agent_config": { + "interceptor_type": "HYDRA_70", + "threat_type": "MISSILE", + "initial_state": { + "position": { + "x": 0, + "y": 600, + "z": 6000 + }, + "rotation": { + "x": 90, + "y": 0, + "z": 0 + }, + "velocity": { + "x": 0, + "y": 0, + "z": -200 + } + }, + "standard_deviation": { + "position": { + "x": 1000, + "y": 200, + "z": 100 + }, + "velocity": { + "x": 0, + "y": 0, + "z": 25 + } + }, + "dynamic_config": { + "launch_config": { + "launch_time": 0 + }, + "sensor_config": { + "type": "IDEAL", + "frequency": 0 + } + }, + "static_config": { + + }, + "submunitions_config": { + "num_submunitions": 0 + } + } + } + ] +} \ No newline at end of file