Clustering working
parent
e42f9e094c
commit
4acc2fd32c
|
@ -0,0 +1,372 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &2209441373060073351
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 371620299618260830}
|
||||||
|
- component: {fileID: 6661103048554822104}
|
||||||
|
- component: {fileID: 8798706627460794869}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: ConeModel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &371620299618260830
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2209441373060073351}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: -1.79}
|
||||||
|
m_LocalScale: {x: 20, y: 20, z: 20}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 644108147276659055}
|
||||||
|
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
|
||||||
|
--- !u!33 &6661103048554822104
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2209441373060073351}
|
||||||
|
m_Mesh: {fileID: 4300000, guid: 36b72d5a34c22d94c88a068dfcbdf27a, type: 2}
|
||||||
|
--- !u!23 &8798706627460794869
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2209441373060073351}
|
||||||
|
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_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: f09133e0e18241045a6efe65c0415cae, 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 &3258882778433859900
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 5422129902450564486}
|
||||||
|
- component: {fileID: 5461165653410223278}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: TrailRenderer
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &5422129902450564486
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3258882778433859900}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 10, y: 10, z: 10}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 644108147276659055}
|
||||||
|
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
|
||||||
|
--- !u!96 &5461165653410223278
|
||||||
|
TrailRenderer:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3258882778433859900}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 0
|
||||||
|
m_ReceiveShadows: 1
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_StaticShadowCaster: 0
|
||||||
|
m_MotionVectors: 0
|
||||||
|
m_LightProbeUsage: 0
|
||||||
|
m_ReflectionProbeUsage: 0
|
||||||
|
m_RayTracingMode: 0
|
||||||
|
m_RayTraceProcedural: 0
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: 548fe8e516bc01e48a296f5b86c7aa18, 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: 1
|
||||||
|
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: 1, b: 1, 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: -1
|
||||||
|
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 &4605237398022313567
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3424325125878309675}
|
||||||
|
- component: {fileID: 6110744000869714338}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Collider
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &3424325125878309675
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4605237398022313567}
|
||||||
|
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: 644108147276659055}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!135 &6110744000869714338
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4605237398022313567}
|
||||||
|
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 &7084771228906499395
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 644108147276659055}
|
||||||
|
- component: {fileID: 8120612314902529408}
|
||||||
|
- component: {fileID: 3328180170527195603}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Hydra70
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &644108147276659055
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7084771228906499395}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 26.6, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 5422129902450564486}
|
||||||
|
- {fileID: 371620299618260830}
|
||||||
|
- {fileID: 3424325125878309675}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &8120612314902529408
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7084771228906499395}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 403a04456de34694a8946c6a5084a9cc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_flightPhase: 0
|
||||||
|
_target: {fileID: 0}
|
||||||
|
StaticConfig:
|
||||||
|
accelerationConfig:
|
||||||
|
maxReferenceAcceleration: 300
|
||||||
|
referenceSpeed: 1000
|
||||||
|
boostConfig:
|
||||||
|
boostTime: 0.3
|
||||||
|
boostAcceleration: 100
|
||||||
|
liftDragConfig:
|
||||||
|
liftCoefficient: 0.2
|
||||||
|
dragCoefficient: 1
|
||||||
|
liftDragRatio: 5
|
||||||
|
bodyConfig:
|
||||||
|
mass: 15.8
|
||||||
|
crossSectionalArea: 0.004
|
||||||
|
finArea: 0.007
|
||||||
|
bodyArea: 0.12
|
||||||
|
hitConfig:
|
||||||
|
hitRadius: 1
|
||||||
|
killProbability: 0.9
|
||||||
|
_showDebugVectors: 1
|
||||||
|
_boostAcceleration: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!54 &3328180170527195603
|
||||||
|
Rigidbody:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7084771228906499395}
|
||||||
|
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
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c4043eb46f764b044a7f744441e1e330
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -681,7 +681,7 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: 84f2990fd69b0284ca96912cbe968b62, type: 3}
|
m_Script: {fileID: 11500000, guid: 84f2990fd69b0284ca96912cbe968b62, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
simulationConfig: {fileID: 11400000, guid: b7e9e8f13e8db0f47a33344c45790f20, type: 2}
|
simulationConfig: {fileID: 11400000, guid: 6d7c61b7d025c9b49b3410fd1195a525, type: 2}
|
||||||
--- !u!4 &253946927
|
--- !u!4 &253946927
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -16,20 +16,34 @@ public abstract class Agent : MonoBehaviour
|
||||||
TERMINATED
|
TERMINATED
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double _elapsedTime = 0;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected FlightPhase _flightPhase = FlightPhase.INITIALIZED;
|
private FlightPhase _flightPhase = FlightPhase.INITIALIZED;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected Agent _target;
|
protected Agent _target;
|
||||||
protected bool _isHit = false;
|
protected bool _isHit = false;
|
||||||
protected bool _isMiss = false;
|
protected bool _isMiss = false;
|
||||||
|
|
||||||
protected DynamicConfig _dynamicConfig;
|
protected AgentConfig _agentConfig;
|
||||||
|
|
||||||
|
protected double _timeSinceLaunch = 0;
|
||||||
|
protected double _timeInPhase = 0;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
public StaticConfig StaticConfig;
|
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() {
|
public bool HasLaunched() {
|
||||||
return (_flightPhase != FlightPhase.INITIALIZED) && (_flightPhase != FlightPhase.READY);
|
return (_flightPhase != FlightPhase.INITIALIZED) && (_flightPhase != FlightPhase.READY);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +53,7 @@ public abstract class Agent : MonoBehaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SetAgentConfig(AgentConfig config) {
|
public virtual void SetAgentConfig(AgentConfig config) {
|
||||||
_dynamicConfig = config.dynamic_config;
|
_agentConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsAssignable() {
|
public virtual bool IsAssignable() {
|
||||||
|
@ -118,21 +132,28 @@ public abstract class Agent : MonoBehaviour
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
protected virtual void Start()
|
protected virtual void Start()
|
||||||
{
|
{
|
||||||
_elapsedTime = 0;
|
|
||||||
_flightPhase = FlightPhase.READY;
|
_flightPhase = FlightPhase.READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
protected virtual void Update()
|
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;
|
var boost_time = launch_time + StaticConfig.boostConfig.boostTime;
|
||||||
_elapsedTime += Time.deltaTime;
|
double elapsedSimulationTime = SimManager.Instance.GetElapsedSimulationTime();
|
||||||
if(_elapsedTime > launch_time) {
|
|
||||||
_flightPhase = FlightPhase.BOOST;
|
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();
|
AlignWithVelocity();
|
||||||
switch (_flightPhase) {
|
switch (_flightPhase) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
// The assignment class is an interface for assigning a target to each missile.
|
// The assignment class is an interface for assigning a target to each missile.
|
||||||
public abstract class Assignment
|
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 missile index, and the second element
|
||||||
|
@ -21,13 +21,9 @@ public abstract class Assignment
|
||||||
}
|
}
|
||||||
|
|
||||||
// A list containing the missile-target assignments.
|
// 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.
|
// 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.
|
// Get the list of assignable missile indices.
|
||||||
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles)
|
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles)
|
||||||
|
|
|
@ -5,24 +5,25 @@ using UnityEngine;
|
||||||
|
|
||||||
// The round-robin assignment class assigns missiles to the targets in a
|
// The round-robin assignment class assigns missiles to the targets in a
|
||||||
// round-robin order.
|
// round-robin order.
|
||||||
public class RoundRobinAssignment : Assignment
|
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 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)
|
if (assignableMissileIndices.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
|
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||||
if (activeTargetIndices.Count == 0)
|
if (activeTargetIndices.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (int missileIndex in assignableMissileIndices)
|
foreach (int missileIndex in assignableMissileIndices)
|
||||||
|
@ -36,8 +37,10 @@ public class RoundRobinAssignment : Assignment
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
|
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
|
||||||
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, nextTargetIndex));
|
assignments.Add(new IAssignment.AssignmentItem(missileIndex, nextTargetIndex));
|
||||||
prevTargetIndex = nextTargetIndex;
|
prevTargetIndex = nextTargetIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return assignments;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,44 +1,46 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Unity.VisualScripting;
|
||||||
using UnityEngine;
|
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 : Assignment
|
public class ThreatAssignment : IAssignment
|
||||||
{
|
{
|
||||||
// Assign a target to each missile that has not been assigned a target yet.
|
// 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)
|
if (assignableMissileIndices.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
|
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||||
if (activeTargetIndices.Count == 0)
|
if (activeTargetIndices.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 missilesMeanPosition = CalculateMeanPosition(missiles);
|
Vector3 positionToDefend = Vector3.zero;
|
||||||
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, missilesMeanPosition);
|
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, positionToDefend);
|
||||||
|
|
||||||
foreach (int missileIndex in assignableMissileIndices)
|
foreach (int missileIndex in assignableMissileIndices)
|
||||||
{
|
{
|
||||||
|
if (missiles[missileIndex].HasAssignedTarget()) continue;
|
||||||
if (threatInfos.Count == 0) break;
|
if (threatInfos.Count == 0) break;
|
||||||
|
|
||||||
ThreatInfo highestThreat = threatInfos[0];
|
ThreatInfo highestThreat = threatInfos[0];
|
||||||
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, highestThreat.TargetIndex));
|
assignments.Add(new IAssignment.AssignmentItem(missileIndex, highestThreat.TargetIndex));
|
||||||
threatInfos.RemoveAt(0);
|
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)
|
private List<ThreatInfo> CalculateThreatLevels(List<Agent> targets, List<int> activeTargetIndices, Vector3 missilesMeanPosition)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,22 @@ public class AgentConfig
|
||||||
public DynamicConfig dynamic_config;
|
public DynamicConfig dynamic_config;
|
||||||
public PlottingConfig plotting_config;
|
public PlottingConfig plotting_config;
|
||||||
public SubmunitionsConfig submunitions_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]
|
[System.Serializable]
|
||||||
|
@ -88,7 +103,6 @@ public class SubmunitionAgentConfig
|
||||||
public StandardDeviation standard_deviation;
|
public StandardDeviation standard_deviation;
|
||||||
public DynamicConfig dynamic_config;
|
public DynamicConfig dynamic_config;
|
||||||
public PlottingConfig plotting_config;
|
public PlottingConfig plotting_config;
|
||||||
public string prefabName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
@ -115,7 +129,8 @@ public enum MissileType
|
||||||
|
|
||||||
public enum TargetType
|
public enum TargetType
|
||||||
{
|
{
|
||||||
DRONE
|
DRONE,
|
||||||
|
MISSILE
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ConfigColor
|
public enum ConfigColor
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 403a04456de34694a8946c6a5084a9cc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -4,14 +4,15 @@ using UnityEngine;
|
||||||
|
|
||||||
public class Micromissile : Missile
|
public class Micromissile : Missile
|
||||||
{
|
{
|
||||||
[SerializeField] private float navigationGain = 5f; // Typically 3-5
|
[SerializeField] private float _navigationGain = 5f; // Typically 3-5
|
||||||
[SerializeField] private bool _showDebugVectors = true;
|
|
||||||
|
|
||||||
private Vector3 _previousLOS;
|
private Vector3 _previousLOS;
|
||||||
private Vector3 _accelerationCommand;
|
private Vector3 _accelerationCommand;
|
||||||
private float _lastUpdateTime;
|
private float _lastUpdateTime;
|
||||||
|
private double _elapsedTime = 0;
|
||||||
protected override void UpdateMidCourse(double deltaTime)
|
protected override void UpdateMidCourse(double deltaTime)
|
||||||
{
|
{
|
||||||
|
_elapsedTime += deltaTime;
|
||||||
Vector3 accelerationInput = Vector3.zero;
|
Vector3 accelerationInput = Vector3.zero;
|
||||||
if (HasAssignedTarget())
|
if (HasAssignedTarget())
|
||||||
{
|
{
|
||||||
|
@ -19,13 +20,14 @@ public class Micromissile : Missile
|
||||||
// TODO: Implement target model update logic
|
// TODO: Implement target model update logic
|
||||||
|
|
||||||
// Correct the state of the target model at the sensor frequency
|
// Correct the state of the target model at the sensor frequency
|
||||||
float sensorUpdatePeriod = 1f / _dynamicConfig.sensor_config.frequency;
|
float sensorUpdatePeriod = 1f / _agentConfig.dynamic_config.sensor_config.frequency;
|
||||||
if (_elapsedTime - _sensorUpdateTime >= sensorUpdatePeriod)
|
if (_elapsedTime - _lastUpdateTime >= sensorUpdatePeriod)
|
||||||
{
|
{
|
||||||
// TODO: Implement guidance filter to estimate state from sensor output
|
// TODO: Implement guidance filter to estimate state from sensor output
|
||||||
// For now, we'll use the target's actual state
|
// For now, we'll use the target's actual state
|
||||||
// targetModel.SetState(_target.GetState());
|
// targetModel.SetState(_target.GetState());
|
||||||
_sensorUpdateTime = (float)_elapsedTime;
|
_lastUpdateTime = (float)_elapsedTime;
|
||||||
|
_elapsedTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sense the target
|
// Sense the target
|
||||||
|
@ -43,11 +45,6 @@ public class Micromissile : Missile
|
||||||
Vector3 acceleration = CalculateAcceleration(accelerationInput, compensateForGravity: true);
|
Vector3 acceleration = CalculateAcceleration(accelerationInput, compensateForGravity: true);
|
||||||
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
|
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
|
||||||
|
|
||||||
if (_showDebugVectors)
|
|
||||||
{
|
|
||||||
DrawDebugVectors();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
private Vector3 CalculateAccelerationCommand(SensorOutput sensorOutput)
|
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
|
float closing_velocity = -sensorOutput.velocity.range; // Negative because closing velocity is opposite to range rate
|
||||||
|
|
||||||
// Navigation gain (adjust as needed)
|
// Navigation gain (adjust as needed)
|
||||||
float N = navigationGain;
|
float N = _navigationGain;
|
||||||
|
|
||||||
// Calculate acceleration commands in azimuth and elevation planes
|
// Calculate acceleration commands in azimuth and elevation planes
|
||||||
float acc_az = N * closing_velocity * los_rate_az;
|
float acc_az = N * closing_velocity * los_rate_az;
|
||||||
|
@ -78,27 +75,14 @@ public class Micromissile : Missile
|
||||||
_accelerationCommand = accelerationCommand;
|
_accelerationCommand = accelerationCommand;
|
||||||
return accelerationCommand;
|
return accelerationCommand;
|
||||||
}
|
}
|
||||||
private void DrawDebugVectors()
|
|
||||||
{
|
|
||||||
if (_target != null)
|
|
||||||
{
|
|
||||||
// Line of sight
|
|
||||||
Debug.DrawLine(transform.position, _target.transform.position, new Color(1, 1, 1, 0.15f));
|
|
||||||
|
|
||||||
// Velocity vector
|
protected override void DrawDebugVectors()
|
||||||
Debug.DrawRay(transform.position, GetVelocity()*0.01f, new Color(0, 0, 1, 0.15f));
|
{
|
||||||
|
base.DrawDebugVectors();
|
||||||
// Acceleration input
|
if (_accelerationCommand != null)
|
||||||
|
{
|
||||||
Debug.DrawRay(transform.position, _accelerationCommand * 1f, Color.green);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using UnityEngine;
|
||||||
public class Missile : Agent
|
public class Missile : Agent
|
||||||
{
|
{
|
||||||
|
|
||||||
protected double _sensorUpdateTime = 0.0;
|
[SerializeField] protected bool _showDebugVectors = true;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private Vector3 _boostAcceleration;
|
private Vector3 _boostAcceleration;
|
||||||
|
@ -32,6 +32,13 @@ public class Missile : Agent
|
||||||
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
|
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Update() {
|
||||||
|
base.Update();
|
||||||
|
if(_showDebugVectors) {
|
||||||
|
DrawDebugVectors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateBoost(double deltaTime)
|
protected override void UpdateBoost(double deltaTime)
|
||||||
{
|
{
|
||||||
// The missile only accelerates along its roll axis (forward in Unity)
|
// 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;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +1,126 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class SimManager : MonoBehaviour
|
public class SimManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Singleton instance
|
||||||
|
public static SimManager Instance { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
public SimulationConfig simulationConfig;
|
public SimulationConfig simulationConfig;
|
||||||
|
|
||||||
|
|
||||||
private List<Missile> missiles = new List<Missile>();
|
private List<Missile> _missiles = new List<Missile>();
|
||||||
private List<Target> targets = new List<Target>();
|
private HashSet<Target> _unassignedTargets = new HashSet<Target>();
|
||||||
private float currentTime = 0f;
|
private HashSet<Target> _targets = new HashSet<Target>();
|
||||||
|
private float _elapsedSimulationTime = 0f;
|
||||||
private float endTime = 100f; // Set an appropriate end time
|
private float endTime = 100f; // Set an appropriate end time
|
||||||
private bool simulationRunning = false;
|
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() {
|
void Start() {
|
||||||
// Slow down time by simulationConfig.timeScale
|
// Slow down time by simulationConfig.timeScale
|
||||||
|
if(Instance == this) {
|
||||||
Time.timeScale = simulationConfig.timeScale;
|
Time.timeScale = simulationConfig.timeScale;
|
||||||
Time.fixedDeltaTime = Time.timeScale * 0.02f;
|
Time.fixedDeltaTime = Time.timeScale * 0.02f;
|
||||||
Time.maximumDeltaTime = Time.timeScale * 0.15f;
|
Time.maximumDeltaTime = Time.timeScale * 0.15f;
|
||||||
InitializeSimulation();
|
InitializeSimulation();
|
||||||
simulationRunning = true;
|
simulationRunning = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void InitializeSimulation()
|
private void InitializeSimulation()
|
||||||
{
|
{
|
||||||
|
List<Missile> missiles = new List<Missile>();
|
||||||
// Create missiles based on config
|
// Create missiles based on config
|
||||||
foreach (var swarmConfig in simulationConfig.missile_swarm_configs)
|
foreach (var swarmConfig in simulationConfig.missile_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 missile = CreateMissile(swarmConfig.agent_config);
|
||||||
missiles.Add(missile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Target> targets = new List<Target>();
|
||||||
// Create targets based on config
|
// Create targets based on config
|
||||||
foreach (var swarmConfig in simulationConfig.target_swarm_configs)
|
foreach (var swarmConfig in simulationConfig.target_swarm_configs)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < swarmConfig.num_agents; i++) {
|
for (int i = 0; i < swarmConfig.num_agents; i++) {
|
||||||
var target = CreateTarget(swarmConfig.agent_config);
|
var target = CreateTarget(swarmConfig.agent_config);
|
||||||
targets.Add(target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_assignment = new ThreatAssignment();
|
_assignmentScheme = new ThreatAssignment();
|
||||||
// Perform initial assignment
|
// Perform initial assignment
|
||||||
AssignMissilesToTargets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AssignMissilesToTargets()
|
public void AssignMissilesToTargets()
|
||||||
{
|
{
|
||||||
|
AssignMissilesToTargets(_missiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssignMissilesToTargets(List<Missile> missilesToAssign)
|
||||||
|
{
|
||||||
|
|
||||||
// Convert Missile and Target lists to Agent lists
|
// Convert Missile and Target lists to Agent lists
|
||||||
List<Agent> missileAgents = new List<Agent>(missiles.ConvertAll(m => m as Agent));
|
List<Agent> missileAgents = new List<Agent>(missilesToAssign.ConvertAll(m => m as Agent));
|
||||||
List<Agent> targetAgents = new List<Agent>(targets.ConvertAll(t => t as Agent));
|
// Convert Target list to Agent list, excluding already assigned targets
|
||||||
|
List<Agent> targetAgents = _unassignedTargets.ToList<Agent>();
|
||||||
|
|
||||||
// Perform the assignment
|
// Perform the assignment
|
||||||
_assignment.Assign(missileAgents, targetAgents);
|
IEnumerable<IAssignment.AssignmentItem> assignments = _assignmentScheme.Assign(missileAgents, targetAgents);
|
||||||
|
|
||||||
// Apply the assignments to the missiles
|
// Apply the assignments to the missiles
|
||||||
foreach (var assignment in _assignment.Assignments)
|
foreach (var assignment in assignments)
|
||||||
{
|
{
|
||||||
Missile missile = missiles[assignment.MissileIndex];
|
if (assignment.MissileIndex < missilesToAssign.Count)
|
||||||
Target target = targets[assignment.TargetIndex];
|
{
|
||||||
|
Missile missile = missilesToAssign[assignment.MissileIndex];
|
||||||
|
Target target = _targets.ElementAt(assignment.TargetIndex);
|
||||||
missile.AssignTarget(target);
|
missile.AssignTarget(target);
|
||||||
Debug.Log($"Missile {missile.name} assigned to target {target.name}");
|
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
|
string prefabName = config.missile_type switch
|
||||||
GameObject missilePrefab = Resources.Load<GameObject>($"Prefabs/{config.prefabName}");
|
|
||||||
if (missilePrefab == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogError($"Missile prefab '{config.prefabName}' not found in Resources/Prefabs folder.");
|
MissileType.HYDRA_70 => "Hydra70",
|
||||||
return null;
|
MissileType.MICROMISSILE => "Micromissile",
|
||||||
}
|
_ => "Hydra70"
|
||||||
|
};
|
||||||
|
|
||||||
// Apply noise to the initial position
|
GameObject missileObject = CreateAgent(config, prefabName);
|
||||||
Vector3 noiseOffset = Utilities.GenerateRandomNoise(config.standard_deviation.position);
|
if (missileObject == null) return null;
|
||||||
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));
|
|
||||||
|
|
||||||
|
// Missile-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>();
|
||||||
|
@ -96,91 +130,100 @@ public class SimManager : MonoBehaviour
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set initial velocity
|
// Missile missile = missileObject.GetComponent<Missile>();
|
||||||
Rigidbody missileRigidbody = missileObject.GetComponent<Rigidbody>();
|
// if (missile == null)
|
||||||
// Apply noise to the initial velocity
|
// {
|
||||||
Vector3 velocityNoise = Utilities.GenerateRandomNoise(config.standard_deviation.velocity);
|
// Debug.LogError($"Missile component not found on prefab '{prefabName}'.");
|
||||||
Vector3 noisyVelocity = config.initial_state.velocity + velocityNoise;
|
// Destroy(missileObject);
|
||||||
missileRigidbody.velocity = noisyVelocity;
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// missile.SetAgentConfig(config);
|
||||||
Missile missile = missileObject.GetComponent<Missile>();
|
_missiles.Add(missileObject.GetComponent<Missile>());
|
||||||
missile.SetAgentConfig(config);
|
// Assign a unique and simple target ID
|
||||||
if (missile == null)
|
int missileId = _missiles.Count;
|
||||||
{
|
missileObject.name = $"{config.missile_type}_Missile_{missileId}";
|
||||||
Debug.LogError($"Missile component not found on prefab '{config.prefabName}'.");
|
return missileObject.GetComponent<Missile>();
|
||||||
Destroy(missileObject);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize missile properties
|
|
||||||
//missile.Initialize(config);
|
|
||||||
|
|
||||||
return missile;
|
|
||||||
}
|
|
||||||
private Target CreateTarget(AgentConfig config)
|
private Target CreateTarget(AgentConfig config)
|
||||||
{
|
{
|
||||||
// Load the target prefab from Resources
|
string prefabName = config.target_type switch
|
||||||
GameObject targetPrefab = Resources.Load<GameObject>($"Prefabs/{config.prefabName}");
|
|
||||||
if (targetPrefab == null)
|
|
||||||
{
|
{
|
||||||
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply noise to the initial position
|
|
||||||
Vector3 noiseOffset = Utilities.GenerateRandomNoise(config.standard_deviation.position);
|
Vector3 noiseOffset = Utilities.GenerateRandomNoise(config.standard_deviation.position);
|
||||||
Vector3 noisyPosition = config.initial_state.position + noiseOffset;
|
Vector3 noisyPosition = config.initial_state.position + noiseOffset;
|
||||||
|
|
||||||
// Instantiate the target with the noisy position
|
GameObject agentObject = Instantiate(prefab, noisyPosition, Quaternion.Euler(config.initial_state.rotation));
|
||||||
GameObject targetObject = Instantiate(targetPrefab, noisyPosition, Quaternion.Euler(config.initial_state.rotation));
|
|
||||||
|
|
||||||
// Set initial velocity with noise
|
Rigidbody agentRigidbody = agentObject.GetComponent<Rigidbody>();
|
||||||
Rigidbody targetRigidbody = targetObject.GetComponent<Rigidbody>();
|
|
||||||
Vector3 velocityNoise = Utilities.GenerateRandomNoise(config.standard_deviation.velocity);
|
Vector3 velocityNoise = Utilities.GenerateRandomNoise(config.standard_deviation.velocity);
|
||||||
Vector3 noisyVelocity = config.initial_state.velocity + velocityNoise;
|
Vector3 noisyVelocity = config.initial_state.velocity + velocityNoise;
|
||||||
targetRigidbody.velocity = noisyVelocity;
|
agentRigidbody.velocity = noisyVelocity;
|
||||||
|
|
||||||
Target target = targetObject.GetComponent<Target>();
|
agentObject.GetComponent<Agent>().SetAgentConfig(config);
|
||||||
target.SetAgentConfig(config);
|
|
||||||
|
|
||||||
if (target == null)
|
return agentObject;
|
||||||
{
|
|
||||||
Debug.LogError($"Target component not found on prefab '{config.prefabName}'.");
|
|
||||||
Destroy(targetObject);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize target properties
|
|
||||||
//target.Initialize(config);
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RestartSimulation()
|
private void RestartSimulation()
|
||||||
{
|
{
|
||||||
// Reset simulation time
|
// Reset simulation time
|
||||||
currentTime = 0f;
|
_elapsedSimulationTime = 0f;
|
||||||
simulationRunning = true;
|
simulationRunning = true;
|
||||||
|
|
||||||
// Clear existing missiles and targets
|
// Clear existing missiles and targets
|
||||||
foreach (var missile in missiles)
|
foreach (var missile in _missiles)
|
||||||
{
|
{
|
||||||
if (missile != null)
|
if (missile != null)
|
||||||
{
|
{
|
||||||
Destroy(missile.gameObject);
|
Destroy(missile.gameObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
missiles.Clear();
|
_missiles.Clear();
|
||||||
|
|
||||||
foreach (var target in targets)
|
foreach (var target in _targets)
|
||||||
{
|
{
|
||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
Destroy(target.gameObject);
|
Destroy(target.gameObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targets.Clear();
|
_targets.Clear();
|
||||||
|
|
||||||
InitializeSimulation();
|
InitializeSimulation();
|
||||||
}
|
}
|
||||||
|
@ -189,7 +232,7 @@ public class SimManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
// Check if all missiles have terminated
|
// Check if all missiles have terminated
|
||||||
bool allMissilesTerminated = true;
|
bool allMissilesTerminated = true;
|
||||||
foreach (var missile in missiles)
|
foreach (var missile in _missiles)
|
||||||
{
|
{
|
||||||
if (missile != null && !missile.IsHit() && !missile.IsMiss())
|
if (missile != null && !missile.IsHit() && !missile.IsMiss())
|
||||||
{
|
{
|
||||||
|
@ -203,11 +246,11 @@ public class SimManager : MonoBehaviour
|
||||||
RestartSimulation();
|
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;
|
simulationRunning = false;
|
||||||
Debug.Log("Simulation completed.");
|
Debug.Log("Simulation completed.");
|
||||||
|
|
|
@ -4,8 +4,6 @@ using UnityEngine;
|
||||||
|
|
||||||
public abstract class Target : Agent
|
public abstract class Target : Agent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public override bool IsAssignable() {
|
public override bool IsAssignable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 79f1fe138866d6a40b209a4edcf2ee06, type: 3}
|
||||||
|
m_Name: SimulationConfigHydra70
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
timeScale: 0.2
|
||||||
|
missile_swarm_configs:
|
||||||
|
- num_agents: 10
|
||||||
|
agent_config:
|
||||||
|
missile_type: 0
|
||||||
|
target_type: 0
|
||||||
|
initial_state:
|
||||||
|
position: {x: 0, y: 10, z: 0}
|
||||||
|
rotation: {x: -45, y: 0, z: 0}
|
||||||
|
velocity: {x: 0, y: 0, z: 10}
|
||||||
|
standard_deviation:
|
||||||
|
position: {x: 10, y: 10, z: 10}
|
||||||
|
velocity: {x: 0, y: 0, z: 0}
|
||||||
|
dynamic_config:
|
||||||
|
launch_config:
|
||||||
|
launch_time: 0
|
||||||
|
sensor_config:
|
||||||
|
type: 0
|
||||||
|
frequency: 0
|
||||||
|
plotting_config:
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
linestyle: 0
|
||||||
|
marker: 0
|
||||||
|
submunitions_config:
|
||||||
|
num_submunitions: 10
|
||||||
|
launch_config:
|
||||||
|
launch_time: 2
|
||||||
|
agent_config:
|
||||||
|
missile_type: 1
|
||||||
|
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: 0
|
||||||
|
frequency: 0
|
||||||
|
plotting_config:
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
linestyle: 0
|
||||||
|
marker: 0
|
||||||
|
target_swarm_configs:
|
||||||
|
- num_agents: 200
|
||||||
|
agent_config:
|
||||||
|
missile_type: 0
|
||||||
|
target_type: 0
|
||||||
|
initial_state:
|
||||||
|
position: {x: 0, y: 400, z: 3000}
|
||||||
|
rotation: {x: 90, y: 0, z: 0}
|
||||||
|
velocity: {x: 0, y: 0, z: -150}
|
||||||
|
standard_deviation:
|
||||||
|
position: {x: 500, y: 200, z: 100}
|
||||||
|
velocity: {x: 0, y: 0, z: 50}
|
||||||
|
dynamic_config:
|
||||||
|
launch_config:
|
||||||
|
launch_time: 0
|
||||||
|
sensor_config:
|
||||||
|
type: 0
|
||||||
|
frequency: 0
|
||||||
|
plotting_config:
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
linestyle: 0
|
||||||
|
marker: 0
|
||||||
|
submunitions_config:
|
||||||
|
num_submunitions: 0
|
||||||
|
launch_config:
|
||||||
|
launch_time: 0
|
||||||
|
agent_config:
|
||||||
|
missile_type: 0
|
||||||
|
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: 0, y: 0, z: 0}
|
||||||
|
velocity: {x: 0, y: 0, z: 0}
|
||||||
|
dynamic_config:
|
||||||
|
launch_config:
|
||||||
|
launch_time: 0
|
||||||
|
sensor_config:
|
||||||
|
type: 0
|
||||||
|
frequency: 0
|
||||||
|
plotting_config:
|
||||||
|
color: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
linestyle: 0
|
||||||
|
marker: 0
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6d7c61b7d025c9b49b3410fd1195a525
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue