修改.gitignore, 重新跟踪代码
This commit is contained in:
parent
7834e5c7a8
commit
813700e6b0
65
.cursorrules
65
.cursorrules
@ -1,65 +0,0 @@
|
||||
|
||||
# Cursor Rules
|
||||
|
||||
You are an expert in C#, Unity, and scalable game development.
|
||||
|
||||
Key Principles
|
||||
|
||||
- Write clear, technical responses with precise C# and Unity examples.
|
||||
- Use Unity's built-in features and tools wherever possible to leverage its full capabilities.
|
||||
- Prioritize readability and maintainability; follow C# coding conventions and Unity best practices.
|
||||
- Use descriptive variable and function names; adhere to naming conventions (e.g., PascalCase for public members, camelCase for private members).
|
||||
- Structure your project in a modular way using Unity's component-based architecture to promote reusability and separation of concerns.
|
||||
|
||||
C#/Unity
|
||||
|
||||
- Use MonoBehaviour for script components attached to GameObjects; prefer ScriptableObjects for data containers and shared resources.
|
||||
- Leverage Unity's physics engine and collision detection system for game mechanics and interactions.
|
||||
- Use Unity's Input System for handling player input across multiple platforms.
|
||||
- Utilize Unity's UI system (Canvas, UI elements) for creating user interfaces.
|
||||
- Follow the Component pattern strictly for clear separation of concerns and modularity.
|
||||
- Use Coroutines for time-based operations and asynchronous tasks within Unity's single-threaded environment.
|
||||
- Use System.Console for logging and debugging in the console.
|
||||
- Using C# 9.0 features.
|
||||
|
||||
Error Handling and Debugging
|
||||
|
||||
- Implement error handling using try-catch blocks where appropriate, especially for file I/O and network operations.
|
||||
- Use Unity's Debug class for logging and debugging (e.g., Debug.Log, Debug.LogWarning, Debug.LogError).
|
||||
- Utilize Unity's profiler and frame debugger to identify and resolve performance issues.
|
||||
- Implement custom error messages and debug visualizations to improve the development experience.
|
||||
- Use Unity's assertion system (Debug.Assert) to catch logical errors during development.
|
||||
|
||||
Dependencies
|
||||
|
||||
- Unity Engine
|
||||
- .NET Framework (version compatible with your Unity version)
|
||||
- Unity Asset Store packages (as needed for specific functionality)
|
||||
- Third-party plugins (carefully vetted for compatibility and performance)
|
||||
|
||||
Unity-Specific Guidelines
|
||||
|
||||
- Use Prefabs for reusable game objects and UI elements.
|
||||
- Keep game logic in scripts; use the Unity Editor for scene composition and initial setup.
|
||||
- Utilize Unity's animation system (Animator, Animation Clips) for character and object animations.
|
||||
- Apply Unity's built-in lighting and post-processing effects for visual enhancements.
|
||||
- Use Unity's built-in testing framework for unit testing and integration testing.
|
||||
- Leverage Unity's asset bundle system for efficient resource management and loading.
|
||||
- Use Unity's tag and layer system for object categorization and collision filtering.
|
||||
|
||||
Performance Optimization
|
||||
|
||||
- Use object pooling for frequently instantiated and destroyed objects.
|
||||
- Optimize draw calls by batching materials and using atlases for sprites and UI elements.
|
||||
- Implement level of detail (LOD) systems for complex 3D models to improve rendering performance.
|
||||
- Use Unity's Job System and Burst Compiler for CPU-intensive operations.
|
||||
- Optimize physics performance by using simplified collision meshes and adjusting fixed timestep.
|
||||
|
||||
Key Conventions
|
||||
|
||||
1. Follow Unity's component-based architecture for modular and reusable game elements.
|
||||
2. Prioritize performance optimization and memory management in every stage of development.
|
||||
3. Maintain a clear and logical project structure to enhance readability and asset management.
|
||||
|
||||
Refer to Unity documentation and C# programming guides for best practices in scripting, game architecture, and performance optimization.
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
build/
|
||||
.vscode/
|
||||
@ -1,11 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,29 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActiveProtect", "ActiveProtect.csproj", "{7F47A2C7-1087-440B-82F7-A1BF50D30A1B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7F47A2C7-1087-440B-82F7-A1BF50D30A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F47A2C7-1087-440B-82F7-A1BF50D30A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F47A2C7-1087-440B-82F7-A1BF50D30A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F47A2C7-1087-440B-82F7-A1BF50D30A1B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{644AFA6F-7DEE-4438-85C3-1D380B052E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{644AFA6F-7DEE-4438-85C3-1D380B052E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{644AFA6F-7DEE-4438-85C3-1D380B052E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{644AFA6F-7DEE-4438-85C3-1D380B052E3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73773200-50D4-40ED-803B-FC16B131FFD2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
150
Design.md
150
Design.md
@ -1,150 +0,0 @@
|
||||
# 导弹仿真系统设计文档
|
||||
|
||||
## 系统架构设计思路
|
||||
|
||||
在处理导弹、坦克、告警设备、干扰设备等复杂交互关系时,我们采用了以下几种程序架构和设计模式的组合:
|
||||
|
||||
### 1. 事件驱动架构(Event-Driven Architecture)
|
||||
|
||||
事件驱动架构非常适合处理复杂的交互关系。每个实体(如导弹、坦克等)可以发布事件,其他实体可以订阅这些事件并作出反应。
|
||||
|
||||
``csharp
|
||||
public class EventManager
|
||||
{
|
||||
private Dictionary<string, List<Action<object>>> eventSubscribers = new Dictionary<string, List<Action<object>>>();
|
||||
public void Subscribe(string eventName, Action<object> listener) { ... }
|
||||
public void Publish(string eventName, object eventData) { ... }
|
||||
}
|
||||
``
|
||||
|
||||
### 2. 组件系统(Component System)
|
||||
|
||||
将每个实体分解为多个组件,每个组件负责特定的功能。这样可以更灵活地组合不同的功能。
|
||||
|
||||
``csharp
|
||||
public class Entity
|
||||
{
|
||||
public PositionComponent Position { get; set; }
|
||||
public VelocityComponent Velocity { get; set; }
|
||||
public HealthComponent Health { get; set; }
|
||||
}
|
||||
``
|
||||
|
||||
### 3. 观察者模式(Observer Pattern)
|
||||
|
||||
类似于事件驱动架构,但更加面向对象。每个实体可以作为观察者或被观察者。
|
||||
|
||||
``csharp
|
||||
public interface IObserver
|
||||
{
|
||||
void Update(ISubject subject);
|
||||
}
|
||||
|
||||
public interface ISubject
|
||||
{
|
||||
void Attach(IObserver observer);
|
||||
void Detach(IObserver observer);
|
||||
void Notify();
|
||||
}
|
||||
``
|
||||
|
||||
### 4. 状态机(State Machine)
|
||||
|
||||
对于有明确状态转换的实体(如导弹的飞行阶段),使用状态机可以更清晰地管理状态转换。
|
||||
|
||||
``csharp
|
||||
public enum MissileState
|
||||
{
|
||||
Idle,
|
||||
Tracking,
|
||||
Locking,
|
||||
Firing,
|
||||
Exploding
|
||||
}
|
||||
|
||||
public class Missile
|
||||
{
|
||||
public MissileState State { get; set; }
|
||||
public void ChangeState(MissileState newState) { ... }
|
||||
}
|
||||
|
||||
``csharp
|
||||
public interface IState
|
||||
{
|
||||
void Enter();
|
||||
void Update();
|
||||
void Exit();
|
||||
}
|
||||
public class MissileStateMachine
|
||||
{
|
||||
private IState currentState;
|
||||
public void ChangeState(IState newState) { ... }
|
||||
public void Update() { ... }
|
||||
}
|
||||
``
|
||||
|
||||
### 5. 命令模式(Command Pattern)
|
||||
|
||||
用于封装各种操作,使得可以轻松地添加新的交互行为。
|
||||
|
||||
``csharp
|
||||
public interface ICommand
|
||||
{
|
||||
void Execute();
|
||||
}
|
||||
|
||||
public class FireMissileCommand : ICommand
|
||||
{
|
||||
public void Execute() { ... }
|
||||
}
|
||||
``
|
||||
|
||||
## 架构组合使用
|
||||
|
||||
在实际应用中,我们将这些模式组合使用:
|
||||
|
||||
1. 使用事件驱动架构作为整体框架,处理系统中的各种事件。
|
||||
2. 采用组件系统来构建各个实体(如导弹、坦克、告警设备等)。
|
||||
3. 使用状态机来管理导弹的飞行阶段。
|
||||
4. 应用观察者模式来处理告警设备的通知机制。
|
||||
5. 使用命令模式来封装各种交互操作,如发射导弹、激活干扰设备等。
|
||||
|
||||
这种组合架构允许我们灵活地处理复杂的交互关系,同时保持代码的可维护性和可扩展性。
|
||||
|
||||
## 下一步计划
|
||||
|
||||
- 实现核心实体(导弹、坦克、告警设备、干扰设备)的基本功能。
|
||||
- 设计并实现事件系统,处理实体间的交互。
|
||||
- 开发状态机,管理导弹的飞行阶段。
|
||||
- 实现观察者模式,处理告警通知。
|
||||
- 使用命令模式封装关键操作。
|
||||
- 进行单元测试和集成测试,确保系统的正确性和稳定性。
|
||||
|
||||
## 数据库访问架构
|
||||
|
||||
在Unity3D环境中,考虑到兼容性和易用性,我推荐使用第二种方法:值对象模式。这种方式有以下几个优点:
|
||||
|
||||
1. 分离关注点:数据库实体(MissileConfigEntity)和游戏中使用的配置对象(MissileConfig)是分开的,这样可以避免 ORM 相关的属性和特性污染游戏逻辑。
|
||||
2. 灵活性:可以轻松地在数据库实体和游戏配置对象之间进行转换,而不影响现有的游戏逻辑。
|
||||
3. 序列化友好:Unity 经常需要序列化对象,使用纯粹的 C# 对象(如 MissileConfig)更容易进行序列化和反序列化。
|
||||
4. 兼容性好:这种方法不依赖于特定的 ORM 框架,如果将来需要更换数据库或 ORM 系统,影响会较小。
|
||||
|
||||
数据访问层使用了 Dapper(一个轻量级的 ORM),它在 Unity 中使用较为简单。
|
||||
|
||||
数据库设计
|
||||
|
||||
### 1. 导弹数据库设计
|
||||
|
||||
导弹数据库设计需要考虑导弹的属性、状态、行为等。
|
||||
|
||||
#### 1.1 导弹属性
|
||||
|
||||
导弹属性包括导弹的初始位置、初始速度、最大速度、目标索引、最大飞行时间、最大飞行距离、飞行阶段配置、推力加速度、最大发动机燃烧时间、最大加速度、距离参数、比例导引系数、类型等。
|
||||
|
||||
#### 1.2 导弹状态
|
||||
|
||||
导弹状态包括导弹的当前位置、当前速度、当前加速度、当前飞行阶段、当前目标索引、当前最大速度、当前最大加速度、当前最大飞行距离、当前最大飞行时间、当前比例导引系数等。
|
||||
|
||||
#### 1.3 导弹行为
|
||||
|
||||
导弹行为包括导弹的飞行行为、攻击行为、躲避行为、跟踪行为、锁定行为、发射行为、爆炸行为等。
|
||||
105
DesignMissile.md
105
DesignMissile.md
@ -1,105 +0,0 @@
|
||||
|
||||
# 实体设计
|
||||
|
||||
在仿真环境中,每个实体(如导弹)有几类参数:
|
||||
|
||||
1. 固有属性参数:如弹长、弹径、质量,最大速度、最大飞行距离、发动机推力等
|
||||
2. 运行时状态参数:如当前位置、速度、朝向、加速度,接收的辐射能量、导引头视野中目标角度等
|
||||
|
||||
为了设计一个结构清晰的实体类,我们采用组合模式和接口分离原则。这样可以将不同类型的参数和状态分开管理,同时保持良好的扩展性。
|
||||
|
||||
## 基础接口
|
||||
|
||||
首先,我们定义几个基础接口来表示不同类型的参数:
|
||||
|
||||
```csharp
|
||||
|
||||
public interface IProperties
|
||||
{
|
||||
double Length { get; }
|
||||
double Diameter { get; }
|
||||
double Mass { get; }
|
||||
}
|
||||
|
||||
public interface IState
|
||||
{
|
||||
Vector3 Position { get; set; }
|
||||
Vector3 Velocity { get; set; }
|
||||
Vector3 Acceleration { get; set; }
|
||||
double Heading { get; set; }
|
||||
double ReceivedRadiation { get; set; }
|
||||
double TargetDeviation { get; set; }
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 实现类
|
||||
|
||||
然后,我们为每个接口创建实现类:
|
||||
|
||||
public class MissileProperties : IProperties
|
||||
{
|
||||
public double Length { get; }
|
||||
public double Diameter { get; }
|
||||
public double Mass { get; }
|
||||
}
|
||||
|
||||
public class MissileState : IState
|
||||
{
|
||||
public Vector3 Position { get; set; }
|
||||
public Vector3 Velocity { get; set; }
|
||||
public Vector3 Acceleration { get; set; }
|
||||
public double Heading { get; set; }
|
||||
public double ReceivedRadiation { get; set; }
|
||||
public double TargetDeviation { get; set; }
|
||||
}
|
||||
|
||||
## 导弹实体类
|
||||
|
||||
接下来,我们创建一个导弹实体类,它将实现上述接口:
|
||||
|
||||
```csharp
|
||||
public class Missile : IProperties, IState
|
||||
{
|
||||
public MissileProperties Properties { get; set; }
|
||||
public MissileState State { get; set; }
|
||||
|
||||
public Missile()
|
||||
{
|
||||
Properties = new MissileProperties();
|
||||
State = new MissileState();
|
||||
}
|
||||
|
||||
// 其他方法,如更新状态、执行导航等
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
// 更新运行时状态和导引参数
|
||||
}
|
||||
public void Navigate()
|
||||
{
|
||||
// 执行导航逻辑
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 设计优点
|
||||
|
||||
1. 清晰的结构:每种类型的参数或状态都有自己的接口和实现类,使得结构非常清晰。
|
||||
2. 高度的模块化:可以轻松地替换或修改某一类参数,而不影响其他部分。
|
||||
3. 易于扩展:如果需要添加新的参数类型,只需创建新的接口和实现类,然后在 Missile 类中添加相应的属性。
|
||||
4. 符合单一职责原则:每个类都只负责一种类型的参数。
|
||||
5. 便于测试:可以轻松地为每种参数类型创建模拟对象,便于单元测试。
|
||||
6. 灵活性:可以为不同类型的导弹创建不同的参数实现,而保持相同的接口。
|
||||
|
||||
## 在激光驾束制导中, 为了实现更平滑的控制,同时将加速度控制在25 m/s²以下,并保持偏移在1.5米以内,我们可以采用以下几种方法
|
||||
|
||||
1. 使用PID控制器:
|
||||
PID(比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
|
||||
2. 非线性增益:
|
||||
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
|
||||
3. 低通滤波:
|
||||
对计算出的加速度进行低通滤波,以减少高频振荡。
|
||||
4. 预测控制:
|
||||
基于当前状态预测未来的位置,提前做出调整。
|
||||
BIN
Models/.DS_Store
vendored
BIN
Models/.DS_Store
vendored
Binary file not shown.
@ -1,10 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "../../ActiveProtect.Tests"
|
||||
},
|
||||
{
|
||||
"path": ".."
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class BasicGuidanceSystem : IGuidanceSystem
|
||||
{
|
||||
public bool HasGuidance { get; protected set; }
|
||||
protected double ProportionalNavigationCoefficient { get; set; }
|
||||
protected Vector3D Position { get; set; }
|
||||
protected Vector3D Velocity { get; set; }
|
||||
protected Vector3D GuidanceCommand { get; set; }
|
||||
|
||||
public BasicGuidanceSystem(double proportionalNavigationCoefficient)
|
||||
{
|
||||
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
|
||||
HasGuidance = false;
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
Position = Vector3D.Zero;
|
||||
Velocity = Vector3D.Zero;
|
||||
}
|
||||
|
||||
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
Position = missilePosition;
|
||||
Velocity = missileVelocity;
|
||||
}
|
||||
|
||||
public Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return GuidanceCommand;
|
||||
}
|
||||
|
||||
protected virtual void CalculateGuidanceCommand(double deltaTime)
|
||||
{
|
||||
// 基础制导系统不计算制导指令
|
||||
// 派生类应该重写这个方法来实现特定的制导逻辑
|
||||
}
|
||||
|
||||
protected Vector3D CalculateProportionalNavigation(Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
{
|
||||
// 预测时间(可以根据实际情况调整)
|
||||
double predictionTime = 2.0;
|
||||
|
||||
// 预测目标位置
|
||||
Vector3D predictedTargetPosition = targetPosition + targetVelocity * predictionTime;
|
||||
|
||||
Vector3D r = predictedTargetPosition - missilePosition;
|
||||
Vector3D v = targetVelocity - missileVelocity;
|
||||
|
||||
Vector3D LOS = r.Normalize();
|
||||
Vector3D LOSRate = (v - (LOS * Vector3D.DotProduct(v, LOS))) / r.Magnitude();
|
||||
|
||||
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * ProportionalNavigationCoefficient * missileVelocity.Magnitude();
|
||||
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
public static (Vector3D newPosition, Vector3D newVelocity) RungeKutta4(double deltaTime, Vector3D position, Vector3D velocity, Vector3D acceleration)
|
||||
{
|
||||
// 定义一个局部函数来计算加速度
|
||||
Vector3D AccelerationFunction(Vector3D pos, Vector3D vel)
|
||||
{
|
||||
// 这里可以添加更复杂的加速度计算,比如考虑空气阻力等
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
// 第一步
|
||||
Vector3D k1v = AccelerationFunction(position, velocity) * deltaTime;
|
||||
Vector3D k1r = velocity * deltaTime;
|
||||
|
||||
// 第二步
|
||||
Vector3D k2v = AccelerationFunction(position + k1r * 0.5, velocity + k1v * 0.5) * deltaTime;
|
||||
Vector3D k2r = (velocity + k1v * 0.5) * deltaTime;
|
||||
|
||||
// 第三步
|
||||
Vector3D k3v = AccelerationFunction(position + k2r * 0.5, velocity + k2v * 0.5) * deltaTime;
|
||||
Vector3D k3r = (velocity + k2v * 0.5) * deltaTime;
|
||||
|
||||
// 第四步
|
||||
Vector3D k4v = AccelerationFunction(position + k3r, velocity + k3v) * deltaTime;
|
||||
Vector3D k4r = (velocity + k3v) * deltaTime;
|
||||
|
||||
// 计算新的位置和速度
|
||||
Vector3D newPosition = position + (k1r + k2r * 2 + k3r * 2 + k4r) / 6;
|
||||
Vector3D newVelocity = velocity + (k1v + k2v * 2 + k3v * 2 + k4v) / 6;
|
||||
|
||||
return (newPosition, newVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
297
Models/Common.cs
297
Models/Common.cs
@ -1,297 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示三维空间中的向量
|
||||
/// </summary>
|
||||
public class Vector3D
|
||||
{
|
||||
// 添加静态单位向量属性
|
||||
public static Vector3D UnitX => new Vector3D(1, 0, 0);
|
||||
public static Vector3D UnitY => new Vector3D(0, 1, 0);
|
||||
public static Vector3D UnitZ => new Vector3D(0, 0, 1);
|
||||
public static Vector3D Zero => new Vector3D(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// X 坐标
|
||||
/// </summary>
|
||||
public double X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Y 坐标
|
||||
/// </summary>
|
||||
public double Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Z 坐标
|
||||
/// </summary>
|
||||
public double Z { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public Vector3D(double x, double y, double z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算两个向量之间的距离
|
||||
/// </summary>
|
||||
/// <param name="v1">第一个向量</param>
|
||||
/// <param name="v2">第二个向量</param>
|
||||
/// <returns>两个向量之间的距离</returns>
|
||||
public static double Distance(Vector3D v1, Vector3D v2)
|
||||
{
|
||||
return Math.Sqrt(Math.Pow(v1.X - v2.X, 2) + Math.Pow(v1.Y - v2.Y, 2) + Math.Pow(v1.Z - v2.Z, 2));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将向量转换为字符串表示
|
||||
/// </summary>
|
||||
/// <returns>向量的字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({X:F2}, {Y:F2}, {Z:F2})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量减法运算符重载
|
||||
/// </summary>
|
||||
public static Vector3D operator -(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量加法运算符重载
|
||||
/// </summary>
|
||||
public static Vector3D operator +(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量与标量乘法运算符重载
|
||||
/// </summary>
|
||||
public static Vector3D operator *(Vector3D a, double scalar)
|
||||
{
|
||||
return new Vector3D(a.X * scalar, a.Y * scalar, a.Z * scalar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量与标量除法运算符重载
|
||||
/// </summary>
|
||||
public static Vector3D operator /(Vector3D a, double scalar)
|
||||
{
|
||||
return new Vector3D(a.X / scalar, a.Y / scalar, a.Z / scalar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量反向
|
||||
/// </summary>
|
||||
public static Vector3D operator -(Vector3D a)
|
||||
{
|
||||
return new Vector3D(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算向量的模长
|
||||
/// </summary>
|
||||
/// <returns>向量的模长</returns>
|
||||
public double Magnitude()
|
||||
{
|
||||
return Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算向量模长的平方
|
||||
/// </summary>
|
||||
/// <returns>向量模长的平方</returns>
|
||||
public double MagnitudeSquared()
|
||||
{
|
||||
return X * X + Y * Y + Z * Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量归一化
|
||||
/// </summary>
|
||||
/// <returns>归一化后的向量</returns>
|
||||
public Vector3D Normalize()
|
||||
{
|
||||
double mag = Magnitude();
|
||||
if (mag > 0)
|
||||
{
|
||||
return new Vector3D(X / mag, Y / mag, Z / mag);
|
||||
}
|
||||
return new Vector3D(0, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算两个向量的叉积
|
||||
/// </summary>
|
||||
/// <param name="a">第一个向量</param>
|
||||
/// <param name="b">第二个向量</param>
|
||||
/// <returns>叉积结果</returns>
|
||||
public static Vector3D CrossProduct(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(
|
||||
a.Y * b.Z - a.Z * b.Y,
|
||||
a.Z * b.X - a.X * b.Z,
|
||||
a.X * b.Y - a.Y * b.X
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算两个向量的点积
|
||||
/// </summary>
|
||||
/// <param name="a">第一个向量</param>
|
||||
/// <param name="b">第二个向量</param>
|
||||
/// <returns>点积结果</returns>
|
||||
public static double DotProduct(Vector3D a, Vector3D b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量取反
|
||||
/// </summary>
|
||||
/// <param name="a">输入向量</param>
|
||||
/// <returns>取反后的向量</returns>
|
||||
public static Vector3D Negate(Vector3D a)
|
||||
{
|
||||
return new Vector3D(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表示三维空间中的方向
|
||||
/// </summary>
|
||||
public struct Orientation
|
||||
{
|
||||
/// <summary>
|
||||
/// 偏航角(绕Y轴旋转)
|
||||
/// </summary>
|
||||
public double Yaw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 俯仰角(绕X轴旋转)
|
||||
/// </summary>
|
||||
public double Pitch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 滚转角(绕Z轴旋转)
|
||||
/// </summary>
|
||||
public double Roll { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public Orientation(double yaw, double pitch, double roll)
|
||||
{
|
||||
Yaw = yaw;
|
||||
Pitch = pitch;
|
||||
Roll = roll;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将方向转换为字符串表示
|
||||
/// </summary>
|
||||
/// <returns>方向的字符串表示</returns>
|
||||
public override readonly string ToString()
|
||||
{
|
||||
return $"(Yaw: {Yaw:F2}, Pitch: {Pitch:F2}, Roll: {Roll:F2})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将角度归一化到 [-π, π] 范围内
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
Yaw = NormalizeAngle(Yaw);
|
||||
Pitch = NormalizeAngle(Pitch);
|
||||
Roll = NormalizeAngle(Roll);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将单个角度归一化到 [-π, π] 范围内
|
||||
/// </summary>
|
||||
/// <param name="angle">输入角度</param>
|
||||
/// <returns>归一化后的角度</returns>
|
||||
private static double NormalizeAngle(double angle)
|
||||
{
|
||||
while (angle > Math.PI) angle -= 2 * Math.PI;
|
||||
while (angle <= -Math.PI) angle += 2 * Math.PI;
|
||||
return angle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据给定的方向向量创建方向
|
||||
/// </summary>
|
||||
/// <param name="direction">方向向量</param>
|
||||
/// <returns>对应的方向</returns>
|
||||
public static Orientation LookAt(Vector3D direction)
|
||||
{
|
||||
double yaw = Math.Atan2(direction.Z, direction.X);
|
||||
double pitch = Math.Atan2(direction.Y, Math.Sqrt(direction.X * direction.X + direction.Z * direction.Z));
|
||||
return new Orientation(yaw, pitch, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将方向转换为单位向量
|
||||
/// </summary>
|
||||
/// <returns>对应的单位向量</returns>
|
||||
public readonly Vector3D ToVector()
|
||||
{
|
||||
double cosYaw = Math.Cos(Yaw);
|
||||
double sinYaw = Math.Sin(Yaw);
|
||||
double cosPitch = Math.Cos(Pitch);
|
||||
double sinPitch = Math.Sin(Pitch);
|
||||
|
||||
return new Vector3D(
|
||||
cosYaw * cosPitch,
|
||||
sinPitch,
|
||||
sinYaw * cosPitch
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从向量创建方向
|
||||
/// </summary>
|
||||
/// <param name="vector">输入向量</param>
|
||||
/// <returns>对应的方向</returns>
|
||||
public static Orientation FromVector(Vector3D vector)
|
||||
{
|
||||
Vector3D normalized = vector.Normalize();
|
||||
double pitch = Math.Asin(normalized.Y);
|
||||
double yaw;
|
||||
if (Math.Abs(normalized.Y) > 0.9999) // 接近垂直
|
||||
{
|
||||
yaw = 0; // 或者保持之前的偏航角
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = Math.Atan2(normalized.Z, normalized.X);
|
||||
}
|
||||
return new Orientation(yaw, pitch, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public struct Vector2D
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
|
||||
public Vector2D(double x, double y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public static Vector2D Zero => new Vector2D(0, 0);
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceCommand();
|
||||
}
|
||||
}
|
||||
@ -1,157 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserBeamRider : SimulationElement
|
||||
{
|
||||
// 激光功率(瓦特)
|
||||
public double LaserPower { get; private set; }
|
||||
|
||||
// 激光发散角(毫弧度)
|
||||
public double BeamDivergence { get; private set; } = 0.0;
|
||||
|
||||
// 控制场直径(米)
|
||||
public double ControlFieldDiameter { get; private set; }
|
||||
|
||||
// 激光方向
|
||||
public Vector3D LaserDirection { get; private set; }
|
||||
|
||||
// 最大导引距离(米)
|
||||
public double MaxGuidanceDistance { get; private set; }
|
||||
|
||||
// 激光束是否开启
|
||||
public bool IsBeamOn { get; private set; }
|
||||
|
||||
// 导弹
|
||||
public string MissileId { get; private set; }
|
||||
|
||||
// 目标
|
||||
public string TargetId { get; private set; }
|
||||
|
||||
public LaserBeamRider(string id, string missileId, string targetId, LaserBeamRiderConfig config, ISimulationManager simulationManager)
|
||||
: base(id, config.InitialPosition, new Orientation(0, 0, 0), simulationManager)
|
||||
{
|
||||
LaserPower = config.LaserPower;
|
||||
ControlFieldDiameter = config.ControlFieldDiameter;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
MaxGuidanceDistance = config.MaxGuidanceDistance;
|
||||
IsActive = false; // 初始状态为非激活
|
||||
IsBeamOn = false;
|
||||
MissileId = missileId;
|
||||
TargetId = targetId;
|
||||
SimulationManager = simulationManager;
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (IsActive && IsBeamOn)
|
||||
{
|
||||
// 更新驾束仪的激光指向
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
LaserDirection = (targetPosition - Position).Normalize();
|
||||
|
||||
Console.WriteLine($"激光驾束仪 {Id} 更新激光指向: {LaserDirection}");
|
||||
|
||||
PublishLaserBeamUpdateEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 激活激光驾束仪
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
IsActive = true;
|
||||
Console.WriteLine($"激光驾束仪 {Id} 已激活");
|
||||
}
|
||||
base.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用激光驾束仪
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
IsActive = false;
|
||||
if (IsBeamOn)
|
||||
{
|
||||
StopBeamIllumination();
|
||||
}
|
||||
Console.WriteLine($"激光驾束仪 {Id} 已停用");
|
||||
}
|
||||
base.Deactivate();
|
||||
}
|
||||
|
||||
public void StartBeamIllumination()
|
||||
{
|
||||
if (!IsBeamOn)
|
||||
{
|
||||
LaserDirection = (SimulationManager.GetEntityById(TargetId).Position - Position).Normalize();
|
||||
IsBeamOn = true;
|
||||
PublishLaserBeamStartEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopBeamIllumination()
|
||||
{
|
||||
if (IsBeamOn)
|
||||
{
|
||||
IsBeamOn = false;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
PublishLaserBeamStopEvent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光束开始事件
|
||||
/// </summary>
|
||||
private void PublishLaserBeamStartEvent()
|
||||
{
|
||||
PublishEvent(new LaserBeamStartEvent
|
||||
{
|
||||
LaserBeamRider = this
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光束更新事件
|
||||
/// </summary>
|
||||
private void PublishLaserBeamUpdateEvent()
|
||||
{
|
||||
PublishEvent(new LaserBeamUpdateEvent
|
||||
{
|
||||
LaserBeamRider = this
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光束停止事件
|
||||
/// </summary>
|
||||
private void PublishLaserBeamStopEvent()
|
||||
{
|
||||
PublishEvent(new LaserBeamStopEvent
|
||||
{
|
||||
LaserBeamRider = this
|
||||
});
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"激光驾束仪 {Id}:\n" +
|
||||
$" 位置: {Position}\n" +
|
||||
$" 方向: {LaserDirection}\n" +
|
||||
$" 激活状态: {(IsActive ? "激活" : "未激活")}\n" +
|
||||
$" 激光功率: {LaserPower} W\n" +
|
||||
$" 发散角: {BeamDivergence} rad\n" +
|
||||
$" 控制场直径: {ControlFieldDiameter} m\n" +
|
||||
$" 最大导引距离: {MaxGuidanceDistance} m\n" +
|
||||
$" 激光束状态: {(IsBeamOn ? "开启" : "关闭")}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,193 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserBeamRiderGuidanceSystem : BasicGuidanceSystem
|
||||
{
|
||||
private Vector3D LaserSourcePosition { get; set; }
|
||||
private Vector3D LaserDirection { get; set; }
|
||||
public double LaserPower { get; set; }
|
||||
private const double MinDetectablePower = 1e-3; // 假设最小可探测功率为1毫瓦
|
||||
private const double DetectorDiameter = 0.1; // 假设探测器直径为10厘米
|
||||
private const double ControlFieldDiameter = 20.0; // 控制场直径(米)
|
||||
|
||||
private Vector3D LastError = Vector3D.Zero;
|
||||
|
||||
public Vector3D LastGuidanceCommand { get; private set; }
|
||||
|
||||
private Vector3D IntegralError = Vector3D.Zero;
|
||||
|
||||
|
||||
public LaserBeamRiderGuidanceSystem(double proportionalNavigationCoefficient)
|
||||
: base(proportionalNavigationCoefficient)
|
||||
{
|
||||
LaserSourcePosition = Vector3D.Zero;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
HasGuidance = false;
|
||||
LastGuidanceCommand = Vector3D.Zero;
|
||||
}
|
||||
|
||||
public void ActivateLaserBeam(Vector3D sourcePosition, Vector3D direction, double laserPower)
|
||||
{
|
||||
LaserSourcePosition = sourcePosition;
|
||||
LaserDirection = direction.Normalize();
|
||||
LaserPower = laserPower;
|
||||
HasGuidance = true;
|
||||
}
|
||||
|
||||
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction, double laserPower)
|
||||
{
|
||||
LaserSourcePosition = sourcePosition;
|
||||
LaserDirection = direction.Normalize();
|
||||
LaserPower = laserPower;
|
||||
}
|
||||
|
||||
public void DeactivateLaserBeam(Vector3D sourcePosition, Vector3D direction)
|
||||
{
|
||||
LaserSourcePosition = Vector3D.Zero;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
HasGuidance = false;
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
|
||||
UpdateGuidanceStatus();
|
||||
|
||||
if (HasGuidance)
|
||||
{
|
||||
CalculateGuidanceCommand(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateGuidanceStatus()
|
||||
{
|
||||
// 计算导弹到激光束的最短距离
|
||||
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
|
||||
double shortestDistance = shortestDistanceVector.Magnitude();
|
||||
|
||||
// 检查导弹是否在控制场内
|
||||
if (shortestDistance > ControlFieldDiameter / 2)
|
||||
{
|
||||
HasGuidance = false;
|
||||
Console.WriteLine($"激光驾束引导系统: 失去引导, 原因: 超出控制场范围, 距离: {shortestDistance}");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
|
||||
|
||||
// 计算接收到的激光功率
|
||||
double beamArea = Math.PI * Math.Pow(ControlFieldDiameter / 2, 2);
|
||||
double powerDensity = LaserPower / beamArea;
|
||||
double receivedPower = powerDensity * (Math.PI * Math.Pow(DetectorDiameter / 2, 2));
|
||||
|
||||
if(HasGuidance = receivedPower >= MinDetectablePower)
|
||||
{
|
||||
HasGuidance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HasGuidance = false;
|
||||
Console.WriteLine($"激光驾束引导系统: 失去引导, 原因: 接收到的激光功率低于最小可探测功率,{LaserPower:E} W/{receivedPower:E} W");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CalculateGuidanceCommand(double deltaTime)
|
||||
{
|
||||
if (!HasGuidance)
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算导弹到激光束的最短距离
|
||||
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
|
||||
|
||||
// PID控制
|
||||
double Kp = 30; // 增加比例系数,使系统对误差更敏感,反应更快 30
|
||||
double Ki = 0.05; // 减小积分系数,减少长期误差累积的影响 0.05
|
||||
double Kd = 5; // 增加微分系数,减少系统的超调量,提高稳定性 5
|
||||
double Kc = 0.5; // 减小非线性增益系数, 控制偏移量, 使得在更小的误差范围内有更大的修正 0.5
|
||||
|
||||
// 计算误差
|
||||
Vector3D error = shortestDistanceVector;
|
||||
|
||||
// 积分项
|
||||
IntegralError += error * deltaTime;
|
||||
|
||||
// 微分项
|
||||
Vector3D derivativeError = (error - LastError) / deltaTime;
|
||||
|
||||
// 计算PID输出
|
||||
Vector3D pidOutput = error * Kp + IntegralError * Ki + derivativeError * Kd;
|
||||
|
||||
// 非线性增益
|
||||
double distance = shortestDistanceVector.Magnitude();
|
||||
double nonLinearGain = Math.Tanh(distance / Kc);
|
||||
|
||||
// 计算横向加速度
|
||||
Vector3D lateralAcceleration = pidOutput * nonLinearGain;
|
||||
|
||||
// 限制最大加速度
|
||||
double maxAcceleration = 50; // 稍微增加最大加速度 50
|
||||
if (lateralAcceleration.Magnitude() > maxAcceleration)
|
||||
{
|
||||
lateralAcceleration = lateralAcceleration.Normalize() * maxAcceleration;
|
||||
}
|
||||
|
||||
// 计算前向加速度
|
||||
Vector3D forwardDirection = LaserDirection;
|
||||
Vector3D currentDirection = Velocity.Normalize();
|
||||
Vector3D rotationAxis = Vector3D.CrossProduct(currentDirection, forwardDirection);
|
||||
double rotationAngle = Math.Acos(Vector3D.DotProduct(currentDirection, forwardDirection));
|
||||
Vector3D forwardAcceleration = Vector3D.CrossProduct(rotationAxis, Velocity) * rotationAngle * ProportionalNavigationCoefficient;
|
||||
|
||||
// 合并横向和前向加速度
|
||||
GuidanceCommand = lateralAcceleration + forwardAcceleration;
|
||||
|
||||
// 低通滤波
|
||||
const double alpha = 0.2;
|
||||
GuidanceCommand = GuidanceCommand * alpha + LastGuidanceCommand * (1 - alpha);
|
||||
|
||||
// 更新上一次的误差和制导命令
|
||||
LastError = error;
|
||||
LastGuidanceCommand = GuidanceCommand;
|
||||
|
||||
Console.WriteLine($"Current Position: {Position}");
|
||||
Console.WriteLine($"Laser Source Position: {LaserSourcePosition}");
|
||||
Console.WriteLine($"Laser Direction: {LaserDirection}");
|
||||
Console.WriteLine($"Shortest Distance Vector: {shortestDistanceVector}");
|
||||
|
||||
//Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceCommand={GuidanceCommand}";
|
||||
}
|
||||
|
||||
private Vector3D CalculateShortestDistanceToLaserBeam()
|
||||
{
|
||||
// 计算导弹到激光源的向量
|
||||
Vector3D missileToSource = LaserSourcePosition - Position;
|
||||
|
||||
// 计算导弹在激光方向上的投影长度
|
||||
double projectionLength = Vector3D.DotProduct(missileToSource, LaserDirection);
|
||||
|
||||
// 计算激光束上最接近导弹的点
|
||||
Vector3D closestPointOnBeam = LaserSourcePosition - LaserDirection * projectionLength;
|
||||
|
||||
// 计算导弹到激光束最近点的向量(即最短距离向量)
|
||||
Vector3D shortestDistanceVector = closestPointOnBeam - Position;
|
||||
|
||||
return shortestDistanceVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserBeamRiderMissile : MissileBase
|
||||
{
|
||||
private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
|
||||
|
||||
|
||||
public LaserBeamRiderMissile(string id, string targetId, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(missileConfig.ProportionalNavigationCoefficient);
|
||||
TargetId = targetId;
|
||||
}
|
||||
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return LaserBeamRiderGuidanceSystem.GetGuidanceCommand();
|
||||
}
|
||||
|
||||
private void OnLaserBeamStart(LaserBeamStartEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem?.ActivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLaserBeamUpdate(LaserBeamUpdateEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem?.UpdateLaserBeamRider(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLaserBeamStop(LaserBeamStopEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem?.DeactivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (LaserBeamRiderGuidanceSystem.HasGuidance)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
this.HasGuidance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.HasGuidance = false;
|
||||
}
|
||||
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
string baseStatus = base.GetStatus().Replace("导弹", "激光驾束制导导弹");
|
||||
string additionalStatus = $"\n 激光引导: {(LaserBeamRiderGuidanceSystem.HasGuidance ? "有效" : "无效")}";
|
||||
return baseStatus + additionalStatus;
|
||||
}
|
||||
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
SimulationManager.SubscribeToEvent<LaserBeamStartEvent>(OnLaserBeamStart);
|
||||
SimulationManager.SubscribeToEvent<LaserBeamStopEvent>(OnLaserBeamStop);
|
||||
SimulationManager.SubscribeToEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
|
||||
}
|
||||
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
SimulationManager.UnsubscribeFromEvent<LaserBeamStartEvent>(OnLaserBeamStart);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserBeamStopEvent>(OnLaserBeamStop);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,235 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光指示器类,用于对目标进行激光照射
|
||||
/// </summary>
|
||||
public class LaserDesignator : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string TargetId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹ID
|
||||
/// </summary>
|
||||
public string MissileId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰阈值(分贝)
|
||||
/// </summary>
|
||||
public double JammingThreshold { get; private set; } = 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// 是否被干扰
|
||||
/// </summary>
|
||||
public bool IsJammed { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在照射
|
||||
/// </summary>
|
||||
public bool IlluminationOn { get; private set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 激光功率
|
||||
/// </summary>
|
||||
public double LaserPower { get; private set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 激光发散角
|
||||
/// </summary>
|
||||
public double LaserDivergenceAngle { get; private set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">激光指示器ID</param>
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="config">激光指示器配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, ISimulationManager simulationManager)
|
||||
: base(id, config.InitialPosition, new Orientation(), simulationManager)
|
||||
{
|
||||
TargetId = targetId;
|
||||
MissileId = missileId;
|
||||
IsActive = false;
|
||||
IlluminationOn = false;
|
||||
LaserPower = config.LaserPower;
|
||||
LaserDivergenceAngle = config.LaserDivergenceAngle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光指示器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (IsActive && !IsJammed)
|
||||
{
|
||||
if (IlluminationOn)
|
||||
{
|
||||
PublishIlluminationUpdateEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始激光照射
|
||||
/// </summary>
|
||||
private void StartLaserIllumination()
|
||||
{
|
||||
if (!IlluminationOn)
|
||||
{
|
||||
IlluminationOn = true;
|
||||
Console.WriteLine($"激光目标指示器 {Id} 开始照射目标 {TargetId}");
|
||||
PublishIlluminationStartEvent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止激光照射
|
||||
/// </summary>
|
||||
private void StopLaserIllumination()
|
||||
{
|
||||
if (IlluminationOn)
|
||||
{
|
||||
IlluminationOn = false;
|
||||
Console.WriteLine($"激光目标指示器 {Id} 停止照射目标 {TargetId}");
|
||||
PublishIlluminationStopEvent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光干扰事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光干扰事件</param>
|
||||
private void OnLaserJamming(LaserJammingEvent evt)
|
||||
{
|
||||
if (evt.TargetId == TargetId)
|
||||
{
|
||||
var tank = SimulationManager.GetEntityById(TargetId) as Tank;
|
||||
if (tank != null)
|
||||
{
|
||||
double distanceToTarget = Vector3D.Distance(Position, tank.Position);
|
||||
double jammingEffectiveness = 20 * Math.Log10(evt.JammingPower) - 20 * Math.Log10(distanceToTarget) - 20 * Math.Log10(4 * Math.PI);
|
||||
|
||||
Console.WriteLine($"激光目标指示器 {Id} 收到干扰事件,干扰功率: {evt.JammingPower:F2}, 距离: {distanceToTarget:F2}, 干扰效果: {jammingEffectiveness:F2} dB, 阈值: {JammingThreshold:F2} dB");
|
||||
|
||||
if (jammingEffectiveness > JammingThreshold)
|
||||
{
|
||||
if (!IsJammed)
|
||||
{
|
||||
Console.WriteLine($"激光目标指示器 {Id} 被干扰,停止工作");
|
||||
IsJammed = true;
|
||||
StopLaserIllumination();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsJammed)
|
||||
{
|
||||
Console.WriteLine($"激光目标指示器 {Id} 干扰解除,恢复工作");
|
||||
IsJammed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活激光指示器
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
IsActive = true;
|
||||
IsJammed = false;
|
||||
Console.WriteLine($"激光目标指示器 {Id} 已激活");
|
||||
StartLaserIllumination();
|
||||
SimulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
|
||||
SimulationManager.SubscribeToEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
|
||||
}
|
||||
base.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用激光指示器
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
IsActive = false;
|
||||
StopLaserIllumination();
|
||||
Console.WriteLine($"激光目标指示器 {Id} 已停用");
|
||||
SimulationManager.UnsubscribeFromEvent<LaserJammingEvent>(OnLaserJamming);
|
||||
SimulationManager.UnsubscribeFromEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
|
||||
}
|
||||
base.Deactivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光照射事件
|
||||
/// </summary>
|
||||
private void PublishIlluminationStartEvent()
|
||||
{
|
||||
var evt = new LaserIlluminationStartEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
|
||||
PublishEvent(evt);
|
||||
Console.WriteLine($"激光指示器 {Id} 发布激光照射事件");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光照射更新事件
|
||||
/// </summary>
|
||||
private void PublishIlluminationUpdateEvent()
|
||||
{
|
||||
var evt = new LaserIlluminationUpdateEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
|
||||
PublishEvent(evt);
|
||||
Console.WriteLine($"激光指示器 {Id} 发布激光照射更新事件");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布激光照射停止事件
|
||||
/// </summary>
|
||||
private void PublishIlluminationStopEvent()
|
||||
{
|
||||
var evt = new LaserIlluminationStopEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
|
||||
PublishEvent(evt);
|
||||
Console.WriteLine($"激光指示器 {Id} 发布激光照射停止事件");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理实体停用事件
|
||||
/// </summary>
|
||||
/// <param name="evt">实体停用事件</param>
|
||||
private void OnEntityDeactivatedEvent(EntityDeactivatedEvent evt)
|
||||
{
|
||||
if (evt.DeactivatedEntityId == TargetId || evt.DeactivatedEntityId == MissileId)
|
||||
{
|
||||
StopLaserIllumination();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光指示器状态信息
|
||||
/// </summary>
|
||||
/// <returns>状态信息字符串</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"激光目标指示器 {Id}:\n" +
|
||||
$" 位置: {Position}\n" +
|
||||
$" 目标: {TargetId}\n" +
|
||||
$" 导弹: {MissileId}\n" +
|
||||
$" 激活状态: {(IsActive ? "激活" : "未激活")}\n" +
|
||||
$" 照射状态: {(IlluminationOn ? "正在照射" : "未照射")}\n" +
|
||||
$" 干扰状态: {(IsJammed ? "被干扰" : "正常")}\n" +
|
||||
$" 激光功率: {LaserPower:E} W";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,196 +0,0 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光干扰器类,用于对抗激光制导武器
|
||||
/// </summary>
|
||||
public class LaserJammer : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在进行干扰
|
||||
/// </summary>
|
||||
public bool IsJamming { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double JammingPower { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前冷却时间(秒)
|
||||
/// </summary>
|
||||
private double jammingCooldown = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 最大冷却时间(秒)
|
||||
/// </summary>
|
||||
private readonly double maxJammingCooldown;
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰功率(瓦特)
|
||||
/// </summary>
|
||||
private readonly double maxJammingPower;
|
||||
|
||||
/// <summary>
|
||||
/// 初始干扰功率(瓦特)
|
||||
/// </summary>
|
||||
private readonly double initialJammingPower;
|
||||
|
||||
/// <summary>
|
||||
/// 功率增加速率(瓦特/秒)
|
||||
/// </summary>
|
||||
private readonly double powerIncreaseRate;
|
||||
|
||||
/// <summary>
|
||||
/// 被监视实体的ID
|
||||
/// </summary>
|
||||
public string MonitoredEntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">激光干扰器ID</param>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
/// <param name="monitoredEntityId">被监视实体的ID</param>
|
||||
/// <param name="config">激光干扰器配置</param>
|
||||
public LaserJammer(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserJammerConfig config)
|
||||
: base(id, position, orientation, simulationManager)
|
||||
{
|
||||
MonitoredEntityId = monitoredEntityId;
|
||||
IsJamming = false;
|
||||
JammingPower = 0;
|
||||
maxJammingCooldown = config.MaxJammingCooldown;
|
||||
maxJammingPower = config.MaxJammingPower;
|
||||
initialJammingPower = config.InitialJammingPower;
|
||||
powerIncreaseRate = config.PowerIncreaseRate;
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光干扰器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (SimulationManager.GetEntityById(MonitoredEntityId) is Tank tank)
|
||||
{
|
||||
Position = tank.Position;
|
||||
Orientation = tank.Orientation;
|
||||
}
|
||||
|
||||
if (IsJamming)
|
||||
{
|
||||
JammingPower = Math.Min(JammingPower + powerIncreaseRate * deltaTime, maxJammingPower);
|
||||
|
||||
jammingCooldown += deltaTime;
|
||||
if (jammingCooldown >= maxJammingCooldown)
|
||||
{
|
||||
StopJamming();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 发布干扰事件
|
||||
PublishEvent(new LaserJammingEvent
|
||||
{
|
||||
TargetId = MonitoredEntityId,
|
||||
JammingPower = JammingPower
|
||||
});
|
||||
}
|
||||
|
||||
Console.WriteLine($"激光干扰器 {Id} 正在工作,当前功率: {JammingPower:F2}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光告警器警报事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光告警器警报事件</param>
|
||||
private void OnLaserWarnerAlarmEvent(LaserWarnerAlarmEvent evt)
|
||||
{
|
||||
if (evt.TargetId == MonitoredEntityId)
|
||||
{
|
||||
StartJamming();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光告警器警报停止事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光告警器警报停止事件</param>
|
||||
private void OnLaserWarnerAlarmStopEvent(LaserWarnerAlarmStopEvent evt)
|
||||
{
|
||||
if (evt.TargetId == MonitoredEntityId)
|
||||
{
|
||||
StopJamming();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始干扰
|
||||
/// </summary>
|
||||
private void StartJamming()
|
||||
{
|
||||
if (!IsJamming)
|
||||
{
|
||||
IsJamming = true;
|
||||
JammingPower = initialJammingPower;
|
||||
jammingCooldown = 0;
|
||||
Console.WriteLine($"激光干扰器 {Id} 开始工作,初始功率: {JammingPower:F2}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止干扰
|
||||
/// </summary>
|
||||
private void StopJamming()
|
||||
{
|
||||
if (IsJamming)
|
||||
{
|
||||
IsJamming = false;
|
||||
JammingPower = 0;
|
||||
jammingCooldown = 0;
|
||||
Console.WriteLine($"激光干扰器 {Id} 停止工作");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光干扰器状态信息
|
||||
/// </summary>
|
||||
/// <returns>状态信息字符串</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"激光干扰器 {Id}:\n" +
|
||||
$" 监视实体: {MonitoredEntityId}\n" +
|
||||
$" 干扰状态: {(IsJamming ? "干扰中" : "未干扰")}\n" +
|
||||
$" 当前功率: {JammingPower:F2}/{maxJammingPower:F2}\n" +
|
||||
$" 冷却时间: {jammingCooldown:F2}/{maxJammingCooldown:F2}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活激光干扰器
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用激光干扰器
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
SimulationManager.UnsubscribeFromEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserSemiActiveGuidanceSystem : BasicGuidanceSystem
|
||||
{
|
||||
private const double FieldOfViewAngle = Math.PI / 6; // 30度视场角
|
||||
private const double DetectorDiameter = 0.1; // 探测器直径(米)
|
||||
private const double FocusedSpotDiameter = 0.003; // 聚焦后光斑直径(米)
|
||||
private const double ReflectionCoefficient = 0.2; // 反射系数
|
||||
private const double LockThreshold = 1e-12; // 锁定阈值(瓦特)
|
||||
private const double TargetReflectiveArea = 1.0; // 目标有效反射面积(平方米)
|
||||
private Vector3D TargetPosition { get; set; }
|
||||
private Vector3D TargetVelocity { get; set; }
|
||||
private Vector3D LaserDesignatorPosition { get; set; }
|
||||
private double LaserPower { get; set; }
|
||||
private double LaserDivergenceAngle { get; set; }
|
||||
public LaserSemiActiveGuidanceSystem(double proportionalNavigationCoefficient, Vector3D initialMissilePosition, Vector3D initialTargetPosition, Vector3D initialTargetVelocity)
|
||||
: base(proportionalNavigationCoefficient)
|
||||
{
|
||||
Position = initialMissilePosition;
|
||||
TargetPosition = initialTargetPosition;
|
||||
TargetVelocity = initialTargetVelocity;
|
||||
LaserDesignatorPosition = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
}
|
||||
|
||||
public void ActivateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
|
||||
{
|
||||
HasGuidance = true;
|
||||
LaserDesignatorPosition = sourcePosition;
|
||||
TargetPosition = targetPosition;
|
||||
TargetVelocity = targetVelocity;
|
||||
LaserPower = laserPower;
|
||||
LaserDivergenceAngle = laserDivergenceAngle;
|
||||
}
|
||||
|
||||
public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
|
||||
{
|
||||
LaserDesignatorPosition = sourcePosition;
|
||||
TargetPosition = targetPosition;
|
||||
TargetVelocity = targetVelocity;
|
||||
LaserPower = laserPower;
|
||||
LaserDivergenceAngle = laserDivergenceAngle;
|
||||
}
|
||||
|
||||
public void DeactivateLaserDesignator()
|
||||
{
|
||||
HasGuidance = false;
|
||||
LaserDesignatorPosition = Vector3D.Zero;
|
||||
TargetPosition = Vector3D.Zero;
|
||||
TargetVelocity = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
LaserDivergenceAngle = 0;
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
|
||||
HasGuidance = CalculateReceivedLaserPower() > LockThreshold;
|
||||
if (HasGuidance)
|
||||
{
|
||||
CalculateGuidanceCommand(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
}
|
||||
|
||||
PrintGuidanceInfo();
|
||||
}
|
||||
|
||||
private double CalculateReceivedLaserPower()
|
||||
{
|
||||
double distanceToTarget = (TargetPosition - LaserDesignatorPosition).Magnitude();
|
||||
double distanceToMissile = (Position - TargetPosition).Magnitude();
|
||||
|
||||
// 计算目标处的光斑面积
|
||||
double spotAreaAtTarget = Math.PI * Math.Pow(distanceToTarget * Math.Tan(LaserDivergenceAngle), 2);
|
||||
|
||||
// 计算目标处的激光功率密度
|
||||
double powerDensityAtTarget = LaserPower / spotAreaAtTarget;
|
||||
|
||||
// 计算从目标反射的总功率
|
||||
double reflectedPower = powerDensityAtTarget * TargetReflectiveArea * ReflectionCoefficient;
|
||||
|
||||
// 计算反射光在导弹处的扩散面积(假设漫反射)
|
||||
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceToMissile, 2);
|
||||
|
||||
// 计算导弹接收到的功率
|
||||
double receivedPower = reflectedPower / reflectedSpotArea;
|
||||
|
||||
// 计算探测器接收到的功率比例
|
||||
double detectorArea = Math.PI * Math.Pow(DetectorDiameter / 2, 2);
|
||||
double illuminatedArea = Math.PI * Math.Pow(distanceToMissile * Math.Tan(FieldOfViewAngle / 2), 2);
|
||||
double powerRatio = Math.Min(1, detectorArea / illuminatedArea);
|
||||
|
||||
// 计算聚焦后的功率密度增加
|
||||
double focusedArea = Math.PI * Math.Pow(FocusedSpotDiameter / 2, 2);
|
||||
double focusingFactor = detectorArea / focusedArea;
|
||||
|
||||
// 计算最终接收到的功率
|
||||
double finalReceivedPower = receivedPower * powerRatio * focusingFactor;
|
||||
|
||||
return finalReceivedPower;
|
||||
}
|
||||
|
||||
protected override void CalculateGuidanceCommand(double deltaTime)
|
||||
{
|
||||
if (!HasGuidance)
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算比例导引加速度
|
||||
GuidanceCommand = CalculateProportionalNavigation(Position, Velocity, TargetPosition, TargetVelocity);
|
||||
|
||||
// 限制最大加速度
|
||||
double maxAcceleration = 100; // 根据实际情况调整
|
||||
if (GuidanceCommand.Magnitude() > maxAcceleration)
|
||||
{
|
||||
GuidanceCommand = GuidanceCommand.Normalize() * maxAcceleration;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintGuidanceInfo()
|
||||
{
|
||||
Console.WriteLine($"激光半主动导弹引导信息:");
|
||||
Console.WriteLine($" 位置: {Position}");
|
||||
Console.WriteLine($" 速度: {Velocity}");
|
||||
Console.WriteLine($" 速度大小: {Velocity.Magnitude():F2} m/s");
|
||||
Console.WriteLine($" 是否有引导: {HasGuidance}");
|
||||
Console.WriteLine($" 目标位置: {TargetPosition}");
|
||||
Console.WriteLine($" 制导指令: {GuidanceCommand}");
|
||||
Console.WriteLine($" 接收到的激光功率: {CalculateReceivedLaserPower():E} W");
|
||||
Console.WriteLine($" 锁定阈值: {LockThreshold:E} W");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,126 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光半主动制导导弹类,继承自基础导弹类
|
||||
/// </summary>
|
||||
public class LaserSemiActiveGuidedMissile : MissileBase
|
||||
{
|
||||
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
|
||||
private string LaserDesignatorId;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">导弹ID</param>
|
||||
/// <param name="laserDesignatorId">激光指示器ID</param>
|
||||
/// <param name="missileConfig">导弹配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, string laserDesignatorId, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
Vector3D initialTargetPosition = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Position;
|
||||
Vector3D initialTargetVelocity = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Velocity;
|
||||
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(
|
||||
missileConfig.ProportionalNavigationCoefficient,
|
||||
missileConfig.InitialPosition,
|
||||
initialTargetPosition,
|
||||
initialTargetVelocity
|
||||
);
|
||||
LaserDesignatorId = laserDesignatorId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光照射事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光照射事件</param>
|
||||
private void OnLaserIlluminationStart(LaserIlluminationStartEvent evt)
|
||||
{
|
||||
if (evt?.LaserDesignator != null && evt?.Target != null)
|
||||
{
|
||||
LaserGuidanceSystem.ActivateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
|
||||
evt.LaserDesignator.LaserPower, evt.LaserDesignator.LaserDivergenceAngle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光照射更新事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光照射更新事件</param>
|
||||
private void OnLaserIlluminationUpdate(LaserIlluminationUpdateEvent evt)
|
||||
{
|
||||
if (evt?.LaserDesignator != null && evt?.Target != null)
|
||||
{
|
||||
LaserGuidanceSystem.UpdateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
|
||||
evt.LaserDesignator.LaserPower, evt.LaserDesignator.LaserDivergenceAngle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光照射停止事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光照射停止事件</param>
|
||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||
{
|
||||
LaserGuidanceSystem.DeactivateLaserDesignator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态信息
|
||||
/// </summary>
|
||||
/// <returns>状态信息字符串</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
|
||||
string additionalStatus = $"\n 激光引导: {(LaserGuidanceSystem.HasGuidance ? "有效" : "无效")}";
|
||||
return baseStatus + additionalStatus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活导弹
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationUpdateEvent>(OnLaserIlluminationUpdate);
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用导弹
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserIlluminationUpdateEvent>(OnLaserIlluminationUpdate);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (LaserGuidanceSystem.HasGuidance)
|
||||
{
|
||||
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
this.HasGuidance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.HasGuidance = false;
|
||||
}
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导命令
|
||||
/// </summary>
|
||||
/// <returns>制导命令</returns>
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return LaserGuidanceSystem.GetGuidanceCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,159 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光告警器类,用于检测激光照射并发出警报
|
||||
/// </summary>
|
||||
public class LaserWarner : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在发出警报
|
||||
/// </summary>
|
||||
public bool IsAlarming { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 警报持续时间(秒)
|
||||
/// </summary>
|
||||
private readonly double alarmDuration;
|
||||
|
||||
/// <summary>
|
||||
/// 当前警报计时器
|
||||
/// </summary>
|
||||
private double alarmTimer = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 被监视实体的ID
|
||||
/// </summary>
|
||||
public string MonitoredEntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">激光告警器ID</param>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
/// <param name="monitoredEntityId">被监视实体的ID</param>
|
||||
/// <param name="config">激光告警器配置</param>
|
||||
public LaserWarner(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserWarnerConfig config)
|
||||
: base(id, position, orientation, simulationManager)
|
||||
{
|
||||
MonitoredEntityId = monitoredEntityId;
|
||||
IsAlarming = false;
|
||||
alarmDuration = config.AlarmDuration;
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光告警器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
var tank = SimulationManager.GetEntityById(MonitoredEntityId) as Tank;
|
||||
if (tank != null)
|
||||
{
|
||||
Position = tank.Position;
|
||||
Orientation = tank.Orientation;
|
||||
}
|
||||
|
||||
if (IsAlarming)
|
||||
{
|
||||
alarmTimer += deltaTime;
|
||||
if (alarmTimer >= alarmDuration)
|
||||
{
|
||||
StopAlarm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光照射事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光照射事件</param>
|
||||
private void OnLaserIlluminationStart(LaserIlluminationStartEvent evt)
|
||||
{
|
||||
if (evt?.Target != null && evt.Target.Id == MonitoredEntityId)
|
||||
{
|
||||
TriggerAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理激光照射停止事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光照射停止事件</param>
|
||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||
{
|
||||
if (evt?.Target != null && evt.Target.Id == MonitoredEntityId)
|
||||
{
|
||||
StopAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发警报
|
||||
/// </summary>
|
||||
public void TriggerAlarm()
|
||||
{
|
||||
if (!IsAlarming)
|
||||
{
|
||||
IsAlarming = true;
|
||||
alarmTimer = 0;
|
||||
PublishEvent(new LaserWarnerAlarmEvent() { TargetId = MonitoredEntityId });
|
||||
Console.WriteLine($"激光告警器 {Id} 发出警报!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止警报
|
||||
/// </summary>
|
||||
public void StopAlarm()
|
||||
{
|
||||
if (IsAlarming)
|
||||
{
|
||||
IsAlarming = false;
|
||||
alarmTimer = 0;
|
||||
PublishEvent(new LaserWarnerAlarmStopEvent() { TargetId = MonitoredEntityId });
|
||||
Console.WriteLine($"激光告警器 {Id} 停止警报");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光告警器状态信息
|
||||
/// </summary>
|
||||
/// <returns>状态信息字符串</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"激光告警器 {Id}:\n" +
|
||||
$" 监视实体: {MonitoredEntityId}\n" +
|
||||
$" 警报状态: {(IsAlarming ? "警报中" : "正常")}\n" +
|
||||
$" 警报持续时间: {(IsAlarming ? alarmTimer : 0):F2}/{alarmDuration:F2}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活激光告警器
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用激光告警器
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,675 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using Model;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示仿真中的导弹
|
||||
/// </summary>
|
||||
public class MissileBase : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹类型
|
||||
/// </summary>
|
||||
public MissileType Type { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前速度(米/秒)
|
||||
/// </summary>
|
||||
public double Speed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大速度(米/秒)
|
||||
/// </summary>
|
||||
public double MaxSpeed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string TargetId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行时间(秒)
|
||||
/// </summary>
|
||||
public double MaxFlightTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行距离(米)
|
||||
/// </summary>
|
||||
public double MaxFlightDistance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行时间(秒)
|
||||
/// </summary>
|
||||
public double FlightTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行距离(米)
|
||||
/// </summary>
|
||||
public double FlightDistance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 与目标的距离(米)
|
||||
/// </summary>
|
||||
public double DistanceToTarget { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹距离参数
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 飞行阶段配置
|
||||
/// </summary>
|
||||
public FlightStageConfig StageConfig { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
public FlightStage CurrentStage { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一帧目标位置
|
||||
/// </summary>
|
||||
private Vector3D LastTargetPosition;
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
private const double N = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double ThrustAcceleration { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double EngineBurnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double MaxEngineBurnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; protected set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; protected set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 失去制导的时间(秒)
|
||||
/// </summary>
|
||||
protected double LostGuidanceTime { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 最后已知的速度向量
|
||||
/// </summary>
|
||||
protected Vector3D LastKnownVelocity = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 发射速度(米/秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_SPEED = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 发射阶段持续时间(秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_DURATION = 0.5;
|
||||
|
||||
protected IMissileStageStrategy currentStage;
|
||||
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
|
||||
|
||||
/// <summary>
|
||||
/// 导弹质量(千克)
|
||||
/// </summary>
|
||||
public double Mass { get; protected set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
|
||||
{
|
||||
// 初始化导弹属性
|
||||
Speed = missileConfig.InitialSpeed;
|
||||
MaxSpeed = missileConfig.MaxSpeed;
|
||||
MaxFlightTime = missileConfig.MaxFlightTime;
|
||||
MaxFlightDistance = missileConfig.MaxFlightDistance;
|
||||
DistanceParams = missileConfig.DistanceParams;
|
||||
StageConfig = missileConfig.StageConfig;
|
||||
IsActive = true;
|
||||
FlightTime = 0;
|
||||
FlightDistance = 0;
|
||||
SimulationManager = simulationManager;
|
||||
ThrustAcceleration = missileConfig.ThrustAcceleration;
|
||||
EngineBurnTime = 0;
|
||||
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
|
||||
MaxAcceleration = missileConfig.MaxAcceleration;
|
||||
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
|
||||
TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
|
||||
Vector3D horizontalDirection = new Vector3D(Orientation.ToVector().X, 0, Orientation.ToVector().Z).Normalize();
|
||||
Velocity = horizontalDirection * missileConfig.InitialSpeed;
|
||||
|
||||
// 初始化策略字典
|
||||
stageStrategies = new Dictionary<FlightStage, IMissileStageStrategy>
|
||||
{
|
||||
{ FlightStage.Launch, new LaunchStageStrategy(this) },
|
||||
{ FlightStage.Acceleration, new AccelerationStageStrategy(this) },
|
||||
{ FlightStage.Cruise, new CruiseStageStrategy(this) },
|
||||
{ FlightStage.TerminalGuidance, new TerminalGuidanceStageStrategy(this) },
|
||||
{ FlightStage.Attack, new AttackStageStrategy(this) }
|
||||
};
|
||||
|
||||
// 设置初始阶段
|
||||
SetInitialStage();
|
||||
|
||||
currentStage = stageStrategies[CurrentStage];
|
||||
|
||||
LastTargetPosition = Position;
|
||||
|
||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置导弹的初始飞行阶段
|
||||
/// </summary>
|
||||
private void SetInitialStage()
|
||||
{
|
||||
if (StageConfig.EnableLaunch) CurrentStage = FlightStage.Launch;
|
||||
else if (StageConfig.EnableAcceleration) CurrentStage = FlightStage.Acceleration;
|
||||
else if (StageConfig.EnableCruise) CurrentStage = FlightStage.Cruise;
|
||||
else if (StageConfig.EnableTerminalGuidance) CurrentStage = FlightStage.TerminalGuidance;
|
||||
else if (StageConfig.EnableAttack) CurrentStage = FlightStage.Attack;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的初始阶段: {CurrentStage}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹状态
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (ShouldSelfDestruct())
|
||||
{
|
||||
SelfDestruct();
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEngineBurnTime(deltaTime);
|
||||
|
||||
Vector3D guidanceCommand = GetGuidanceCommand();
|
||||
|
||||
UpdateMotionState(deltaTime, guidanceCommand);
|
||||
|
||||
if (CheckHit())
|
||||
{
|
||||
Explode();
|
||||
return;
|
||||
}
|
||||
|
||||
currentStage.Update(deltaTime);
|
||||
}
|
||||
|
||||
protected virtual Vector3D GetGuidanceCommand()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void UpdateMotionState(double deltaTime, Vector3D guidanceCommand)
|
||||
{
|
||||
Vector3D acceleration = CalculateAcceleration(Velocity, guidanceCommand);
|
||||
|
||||
// 使用四阶龙格-库塔方法更新导弹的位置和速度
|
||||
(Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, acceleration);
|
||||
|
||||
// 限制速度不超过最大速度
|
||||
if (Velocity.Magnitude() > MaxSpeed)
|
||||
{
|
||||
Velocity = Velocity.Normalize() * MaxSpeed;
|
||||
}
|
||||
|
||||
UpdateMotionStatus(deltaTime);
|
||||
}
|
||||
|
||||
protected virtual void UpdateMotionStatus(double deltaTime)
|
||||
{
|
||||
Speed = Velocity.Magnitude();
|
||||
Orientation = Orientation.FromVector(Velocity);
|
||||
FlightTime += deltaTime;
|
||||
FlightDistance += Speed * deltaTime;
|
||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算导弹的加速度
|
||||
/// </summary>
|
||||
private Vector3D CalculateAcceleration(Vector3D velocity, Vector3D guidanceCommand)
|
||||
{
|
||||
Vector3D thrustAcceleration = Vector3D.Zero;
|
||||
Vector3D guidanceAcceleration = Vector3D.Zero;
|
||||
|
||||
switch (CurrentStage)
|
||||
{
|
||||
case FlightStage.Launch:
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
break;
|
||||
case FlightStage.Acceleration:
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
guidanceAcceleration = guidanceCommand;
|
||||
break;
|
||||
case FlightStage.Cruise:
|
||||
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
case FlightStage.TerminalGuidance:
|
||||
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
case FlightStage.Attack:
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!HasGuidance)
|
||||
{
|
||||
if (velocity.Magnitude() > 0)
|
||||
{
|
||||
thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
|
||||
}
|
||||
else
|
||||
{
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
}
|
||||
}
|
||||
|
||||
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
|
||||
//Vector3D gravityCompensation = new(0, 9.81, 0);
|
||||
Vector3D gravityAcceleration = new(0, -9.81, 0);
|
||||
|
||||
// 计算空气阻力的影响
|
||||
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
|
||||
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration +dragAcceleration;
|
||||
//Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration +dragAcceleration;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
|
||||
if (totalAcceleration.Magnitude() > MaxAcceleration)
|
||||
{
|
||||
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
|
||||
}
|
||||
|
||||
return totalAcceleration;
|
||||
}
|
||||
/// <summary>
|
||||
/// 切换导弹飞行阶段
|
||||
/// </summary>
|
||||
public void ChangeStage(FlightStage newStage)
|
||||
{
|
||||
if (stageStrategies.TryGetValue(newStage, out var strategy))
|
||||
{
|
||||
if (IsStageEnabled(newStage))
|
||||
{
|
||||
CurrentStage = newStage;
|
||||
currentStage = strategy;
|
||||
Console.WriteLine($"导弹 {Id} 切换到 {newStage} 阶段");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果目标阶段不可用,尝试切换到下一个可用阶段
|
||||
TryChangeToNextAvailableStage(newStage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 无法切换到未知阶段 {newStage}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定飞行阶段是否启用
|
||||
/// </summary>
|
||||
private bool IsStageEnabled(FlightStage stage)
|
||||
{
|
||||
return stage switch
|
||||
{
|
||||
FlightStage.Launch => StageConfig.EnableLaunch,
|
||||
FlightStage.Acceleration => StageConfig.EnableAcceleration,
|
||||
FlightStage.Cruise => StageConfig.EnableCruise,
|
||||
FlightStage.TerminalGuidance => StageConfig.EnableTerminalGuidance,
|
||||
FlightStage.Attack => StageConfig.EnableAttack,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试切换到下一个可用的飞行阶段
|
||||
/// </summary>
|
||||
private void TryChangeToNextAvailableStage(FlightStage startStage)
|
||||
{
|
||||
FlightStage[] stageOrder = new FlightStage[] {FlightStage.Launch, FlightStage.Acceleration, FlightStage.Cruise, FlightStage.TerminalGuidance, FlightStage.Attack};
|
||||
int startIndex = Array.IndexOf(stageOrder, startStage);
|
||||
|
||||
for (int i = startIndex + 1; i < stageOrder.Length; i++)
|
||||
{
|
||||
if (IsStageEnabled(stageOrder[i]))
|
||||
{
|
||||
ChangeStage(stageOrder[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有可用的下一个阶段,导弹自毁
|
||||
Console.WriteLine($"导弹 {Id} 没有可用的下一个阶段,准备自毁");
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算导弹的加速度
|
||||
/// </summary>
|
||||
// private (Vector3D, Vector3D) CalculateDerivatives_RK4(Vector3D position, Vector3D velocity, double deltaTime)
|
||||
// {
|
||||
// Vector3D guidanceAcceleration = Vector3D.Zero;
|
||||
// Vector3D thrustAcceleration = Vector3D.Zero;
|
||||
|
||||
// switch (CurrentStage)
|
||||
// {
|
||||
// case FlightStage.Launch:
|
||||
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
// break;
|
||||
// case FlightStage.Acceleration:
|
||||
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
// guidanceAcceleration = CalculateProportionalNavigation(position);
|
||||
// break;
|
||||
// case FlightStage.Cruise:
|
||||
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
|
||||
// guidanceAcceleration = CalculateProportionalNavigation(position) * 0.5;
|
||||
// break;
|
||||
// case FlightStage.TerminalGuidance:
|
||||
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
|
||||
// guidanceAcceleration = CalculateProportionalNavigation(position) * 1.5;
|
||||
// break;
|
||||
// case FlightStage.Attack:
|
||||
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
// guidanceAcceleration = CalculateProportionalNavigation(position) * 2;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// if (!HasGuidance)
|
||||
// {
|
||||
// guidanceAcceleration = Vector3D.Zero;
|
||||
// if (velocity.Magnitude() > 0)
|
||||
// {
|
||||
// thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 计算空气阻力的影响
|
||||
// Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
|
||||
|
||||
// // 计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
|
||||
// //Vector3D gravityCompensation = new(0, 9.81, 0);
|
||||
// Vector3D gravityAcceleration = new(0, -9.81, 0);
|
||||
|
||||
// Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration + dragAcceleration;
|
||||
|
||||
// if (totalAcceleration.Magnitude() > MaxAcceleration)
|
||||
// {
|
||||
// totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
|
||||
// }
|
||||
|
||||
// return (velocity, totalAcceleration);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 计算空气阻力
|
||||
/// </summary>
|
||||
private static double CalculateDrag(double speed)
|
||||
{
|
||||
const double dragCoefficient = 0.1; // 减小阻力系数
|
||||
const double airDensity = 1.225; // 海平面空气密度,kg/m^3
|
||||
const double referenceArea = 0.01; // 减小导弹的参考面积,m^2
|
||||
|
||||
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否命中目标
|
||||
/// </summary>
|
||||
protected bool CheckHit()
|
||||
{
|
||||
return DistanceToTarget <= DistanceParams.ExplosionDistance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否应该自毁
|
||||
/// </summary>
|
||||
protected bool ShouldSelfDestruct()
|
||||
{
|
||||
if (FlightTime >= MaxFlightTime)
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MaxFlightTime:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
if (FlightDistance >= MaxFlightDistance)
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
if (Position.Y <= -1.0) // 数字略小于0
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 高度小于等于0 ({Position.Y:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新发动机燃烧时间
|
||||
/// </summary>
|
||||
private void UpdateEngineBurnTime(double deltaTime)
|
||||
{
|
||||
if (CurrentStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
|
||||
{
|
||||
EngineBurnTime += deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
private Vector3D CalculateProportionalNavigation(Vector3D position)
|
||||
{
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D LOS = targetPosition - position;
|
||||
Vector3D LOSRate = (targetPosition - LastTargetPosition) / FlightTime - Velocity;
|
||||
LastTargetPosition = targetPosition;
|
||||
|
||||
return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
|
||||
* ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹爆炸
|
||||
/// </summary>
|
||||
public void Explode()
|
||||
{
|
||||
Deactivate();
|
||||
SimulationManager.HandleTargetHit(TargetId, Id);
|
||||
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹自毁
|
||||
/// </summary>
|
||||
public void SelfDestruct()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
|
||||
FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
|
||||
Position.Y <= 0 ? "高度小于等于0" :
|
||||
!HasGuidance ? "失去引导" : "未知原因";
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置比例导引系数
|
||||
/// </summary>
|
||||
public void SetProportionalNavigationCoefficient(double newCoefficient)
|
||||
{
|
||||
ProportionalNavigationCoefficient = newCoefficient;
|
||||
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态
|
||||
/// </summary>
|
||||
public override string GetStatus()
|
||||
{
|
||||
MissileRunningState missileRunningState = GetState();
|
||||
return $"导弹 {missileRunningState.Id}:\n" +
|
||||
$" 位置: {missileRunningState.Position}\n" +
|
||||
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
|
||||
$" 当前状态: {missileRunningState.CurrentStage}\n" +
|
||||
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MaxFlightTime:F2}\n" +
|
||||
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
|
||||
$" 距离目标: {missileRunningState.DistanceToTarget:F2}\n" +
|
||||
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
|
||||
$" 有引导: {(missileRunningState.HasGuidance ? "是" : "否")}\n" +
|
||||
$" 失去引导时间: {missileRunningState.LostGuidanceTime:F2}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹的制导状态
|
||||
/// </summary>
|
||||
protected virtual void UpdateGuidanceStatus()
|
||||
{
|
||||
// 基类中的默认实现
|
||||
}
|
||||
|
||||
public MissileRunningState GetState()
|
||||
{
|
||||
return new MissileRunningState
|
||||
{
|
||||
Id = Id,
|
||||
Type = Type,
|
||||
Position = Position,
|
||||
Velocity = Velocity,
|
||||
Orientation = Orientation,
|
||||
Speed = Speed,
|
||||
TargetId = TargetId,
|
||||
FlightTime = FlightTime,
|
||||
FlightDistance = FlightDistance,
|
||||
DistanceToTarget = DistanceToTarget,
|
||||
CurrentStage = CurrentStage,
|
||||
HasGuidance = HasGuidance,
|
||||
LostGuidanceTime = LostGuidanceTime,
|
||||
EngineBurnTime = EngineBurnTime,
|
||||
IsActive = IsActive
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表示导弹的运行状态信息
|
||||
/// </summary>
|
||||
public struct MissileRunningState
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹类型
|
||||
/// </summary>
|
||||
public MissileType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前位置
|
||||
/// </summary>
|
||||
public Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前速度向量
|
||||
/// </summary>
|
||||
public Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前朝向
|
||||
/// </summary>
|
||||
public Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前速度(米/秒)
|
||||
/// </summary>
|
||||
public double Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行时间(秒)
|
||||
/// </summary>
|
||||
public double FlightTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行距离(米)
|
||||
/// </summary>
|
||||
public double FlightDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 与目标的距离(米)
|
||||
/// </summary>
|
||||
public double DistanceToTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
public FlightStage CurrentStage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 失去制导时间(秒)
|
||||
/// </summary>
|
||||
public double LostGuidanceTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double EngineBurnTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于活动状态
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,351 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 坦克消息结构
|
||||
/// </summary>
|
||||
public struct TankInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 坦克编号
|
||||
/// </summary>
|
||||
public int TankID { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克类型编号
|
||||
/// </summary>
|
||||
public int TankType { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克X坐标
|
||||
/// </summary>
|
||||
public double xp { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克Y坐标
|
||||
/// </summary>
|
||||
public double yp { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克Z坐标
|
||||
/// </summary>
|
||||
public double zp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 烟幕标记
|
||||
/// </summary>
|
||||
public double fYMFlag { get; set; }
|
||||
/// <summary>
|
||||
/// 烟幕SNR
|
||||
/// </summary>
|
||||
public double fYMSNR { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光致盲标记,1-导弹;2-制导站;3-两者都不是
|
||||
/// </summary>
|
||||
public double fZMJGFlag { get; set; }
|
||||
/// <summary>
|
||||
/// 致盲能量
|
||||
/// </summary>
|
||||
public double fZMJGPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光诱骗假目标X坐标
|
||||
/// </summary>
|
||||
public double fFalseX { get; set; }
|
||||
/// <summary>
|
||||
/// 激光诱骗假目标Y坐标
|
||||
/// </summary>
|
||||
public double fFalseY { get; set; }
|
||||
/// <summary>
|
||||
/// 激光诱骗假目标Z坐标
|
||||
/// </summary>
|
||||
public double fFalseZ { get; set; }
|
||||
/// <summary>
|
||||
/// 红外诱骗能量值
|
||||
/// </summary>
|
||||
public double fFalseIRPower { get; set; }
|
||||
/// <summary>
|
||||
/// 激光诱骗能量值
|
||||
/// </summary>
|
||||
public double fFalseJGPower { get; set; }
|
||||
/// <summary>
|
||||
/// 毫米波补偿//1为开启
|
||||
/// </summary>
|
||||
public double fHMBBCFlag { get; set; }
|
||||
/// <summary>
|
||||
/// 毫米波干扰能量
|
||||
/// </summary>
|
||||
public double fHMBGRPower { get; set; }
|
||||
/// <summary>
|
||||
/// 红外干扰能量
|
||||
/// </summary>
|
||||
public double fHWGRPower { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克辐射红外能量
|
||||
/// </summary>
|
||||
public double fTankIRPower { get; set; }
|
||||
/// <summary>
|
||||
/// 坦克辐射激光能量
|
||||
/// </summary>
|
||||
public double fTankJGPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 坦克辐射毫米波能量
|
||||
/// </summary>
|
||||
public double fTankHMBPower { get; set; }
|
||||
/// <summary>
|
||||
/// 毫米波补偿特征值//大于导弹补偿成功,末敏弹子弹爆炸
|
||||
/// </summary>
|
||||
public double fFeature { get; set; }
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 威胁源初始化信息结构
|
||||
/// </summary>
|
||||
public struct MIniInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹ID
|
||||
/// </summary>
|
||||
public int nMisID;
|
||||
/// <summary>
|
||||
/// 导弹X坐标
|
||||
/// </summary>
|
||||
public double xm;
|
||||
/// <summary>
|
||||
/// 导弹Y坐标
|
||||
/// </summary>
|
||||
public double ym;
|
||||
/// <summary>
|
||||
/// 导弹Z坐标
|
||||
/// </summary>
|
||||
public double zm;
|
||||
/// <summary>
|
||||
/// 导弹方位角
|
||||
/// </summary>
|
||||
public double psi_m;
|
||||
/// <summary>
|
||||
/// 导弹俯仰角
|
||||
/// </summary>
|
||||
public double theta_m;
|
||||
/// <summary>
|
||||
/// 导弹飞行速度
|
||||
/// </summary>
|
||||
public double vm;
|
||||
/// <summary>
|
||||
/// 坦克X坐标
|
||||
/// </summary>
|
||||
public double xt;
|
||||
/// <summary>
|
||||
/// 坦克Y坐标
|
||||
/// </summary>
|
||||
public double yt;
|
||||
/// <summary>
|
||||
/// 坦克Z坐标
|
||||
/// </summary>
|
||||
public double zt;
|
||||
/// <summary>
|
||||
/// 光斑X坐标
|
||||
/// </summary>
|
||||
public double xd;
|
||||
/// <summary>
|
||||
/// 光斑Y坐标
|
||||
/// </summary>
|
||||
public double yd;
|
||||
/// <summary>
|
||||
/// 光斑Z坐标
|
||||
/// </summary>
|
||||
public double zd;
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 威胁源运行信息结构
|
||||
/// </summary>
|
||||
public struct MRunInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 杀伤半径
|
||||
/// </summary>
|
||||
public double Rx;
|
||||
/// <summary>
|
||||
/// 仿真时间
|
||||
/// </summary>
|
||||
public double fSimTime;
|
||||
/// <summary>
|
||||
/// x坐标
|
||||
/// </summary>
|
||||
public double fMisX;
|
||||
/// <summary>
|
||||
/// y坐标
|
||||
/// </summary>
|
||||
public double fMisY;
|
||||
/// <summary>
|
||||
/// z坐标
|
||||
/// </summary>
|
||||
public double fMisZ;
|
||||
/// <summary>
|
||||
/// 导弹弹道倾角
|
||||
/// </summary>
|
||||
public double fMisDeltCw;
|
||||
/// <summary>
|
||||
/// 滚转角
|
||||
/// </summary>
|
||||
public double fMisRoll;
|
||||
/// <summary>
|
||||
/// 导弹弹道偏角
|
||||
/// </summary>
|
||||
public double fMisPitch;
|
||||
/// <summary>
|
||||
/// 导弹速度
|
||||
/// </summary>
|
||||
public double fMisV;
|
||||
/// <summary>
|
||||
/// 导弹辐射红外能量
|
||||
/// </summary>
|
||||
public double fIRPower;
|
||||
/// <summary>
|
||||
/// 导弹辐射红外波长
|
||||
/// </summary>
|
||||
public double fIRWaveLen;
|
||||
/// <summary>
|
||||
/// 导弹紫外能量
|
||||
/// </summary>
|
||||
public double fUVPower;
|
||||
/// <summary>
|
||||
/// 导弹紫外波长
|
||||
/// </summary>
|
||||
public double fUVWaveLen;
|
||||
/// <summary>
|
||||
/// 导弹激光能量
|
||||
/// </summary>
|
||||
public double fJGPower;
|
||||
// 导弹激光波长
|
||||
public double fJGWaveLen;
|
||||
/// <summary>
|
||||
/// 导弹毫米波能量
|
||||
/// </summary>
|
||||
public double fHMBPower;
|
||||
/// <summary>
|
||||
/// 导弹毫米波波长
|
||||
/// </summary>
|
||||
public double fHMBWaveLen;
|
||||
/// <summary>
|
||||
/// 制导站批号
|
||||
/// </summary>
|
||||
public double nZDZID;
|
||||
/// <summary>
|
||||
/// 架束仪位置x
|
||||
/// </summary>
|
||||
public double fZDZX;
|
||||
/// <summary>
|
||||
/// 架束仪位置Y
|
||||
/// </summary>
|
||||
public double fZDZY;
|
||||
/// <summary>
|
||||
/// 架束仪位置Z
|
||||
/// </summary>
|
||||
public double fZDZZ;
|
||||
/// <summary>
|
||||
/// 制导站辐射激光能量
|
||||
/// </summary>
|
||||
public double fZDZJGPower;
|
||||
/// <summary>
|
||||
/// 制导站辐射激光波长
|
||||
/// </summary>
|
||||
public double fZDZJGWaveLen;
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public double nZDZCode;
|
||||
/// <summary>
|
||||
/// 脉冲重复频率
|
||||
/// </summary>
|
||||
public double fZDZReFre;
|
||||
/// <summary>
|
||||
/// 脉宽
|
||||
/// </summary>
|
||||
public double fZDZPulse;
|
||||
/// <summary>
|
||||
/// 末敏弹状态 1:母弹,2:子弹,3:子弹扫描状态
|
||||
/// </summary>
|
||||
public double nMMDState;
|
||||
/// <summary>
|
||||
/// 子弹数量
|
||||
/// </summary>
|
||||
public double nSubNum;
|
||||
/// <summary>
|
||||
/// 子弹1批号
|
||||
/// </summary>
|
||||
public double nSub1ID;
|
||||
/// <summary>
|
||||
/// 子弹1坐标X
|
||||
/// </summary>
|
||||
public double fSub1X;
|
||||
// 子弹1坐标Y
|
||||
public double fSub1Y;
|
||||
/// <summary>
|
||||
/// 子弹1坐标Z
|
||||
/// </summary>
|
||||
public double fSub1Z;
|
||||
/// <summary>
|
||||
/// 子弹1辐射毫米波能量
|
||||
/// </summary>
|
||||
public double fSub1HMBPower;
|
||||
/// <summary>
|
||||
/// 子弹1辐射毫米波波长
|
||||
/// </summary>
|
||||
public double fSub1HMBWaveLen;
|
||||
/// <summary>
|
||||
/// 子弹1扫描坐标X
|
||||
/// </summary>
|
||||
public double fSub1ScanX;
|
||||
/// <summary>
|
||||
/// 子弹1扫描坐标Y
|
||||
/// </summary>
|
||||
public double fSub1ScanY;
|
||||
/// <summary>
|
||||
/// 子弹1扫描坐标Z
|
||||
/// </summary>
|
||||
public double fSub1ScanZ;
|
||||
/// <summary>
|
||||
/// 防护手段 1:激光致盲;2:激光诱骗;3:红外干扰;4:红外诱骗;5:毫米波干扰;6:毫米波补偿;7:烟幕防护;8:致盲制导站
|
||||
/// </summary>
|
||||
public double nDisType;
|
||||
/// <summary>
|
||||
/// 0代表失败 1代表成功
|
||||
/// </summary>
|
||||
public double nDisRes;
|
||||
/// <summary>
|
||||
/// 后续进一步处理
|
||||
/// </summary>
|
||||
public double k1;
|
||||
/// <summary>
|
||||
/// 弹道偏角和倾角改变角度当亲步骤数
|
||||
/// </summary>
|
||||
public int Xi;
|
||||
|
||||
public int JG_GR_success;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 炮弹状态标志,0:正常,1:炸毁目标,2:自爆
|
||||
/// </summary>
|
||||
public int bombFlag;
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 激光诱骗假目标X坐标
|
||||
///// </summary>
|
||||
//public double fFalseX;
|
||||
///// <summary>
|
||||
///// 激光诱骗假目标Y坐标
|
||||
///// </summary>
|
||||
//public double fFalseY;
|
||||
///// <summary>
|
||||
///// 激光诱骗假目标Z坐标
|
||||
///// </summary>
|
||||
//public double fFalseZ;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@ -1,168 +0,0 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹飞行阶段枚举
|
||||
/// </summary>
|
||||
public enum FlightStage
|
||||
{
|
||||
Launch, // 发射阶段
|
||||
Acceleration, // 加速阶段
|
||||
Cruise, // 巡航阶段
|
||||
TerminalGuidance, // 终端制导阶段
|
||||
Attack, // 攻击阶段
|
||||
Explosion, // 爆炸阶段
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹飞行阶段策略接口
|
||||
/// </summary>
|
||||
public interface IMissileStageStrategy
|
||||
{
|
||||
void Update(double deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发射阶段策略
|
||||
/// </summary>
|
||||
public class LaunchStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
private double launchTime = 0;
|
||||
|
||||
public LaunchStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
launchTime += deltaTime;
|
||||
if (launchTime >= MissileBase.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Acceleration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// 加速阶段策略
|
||||
/// </summary>
|
||||
public class AccelerationStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public AccelerationStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.EngineBurnTime >= missile.MaxEngineBurnTime || missile.Speed >= missile.MaxSpeed)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Cruise);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 巡航阶段策略
|
||||
/// </summary>
|
||||
public class CruiseStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public CruiseStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.TerminalGuidance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终端制导阶段策略
|
||||
/// </summary>
|
||||
public class TerminalGuidanceStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public TerminalGuidanceStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Attack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 攻击阶段策略
|
||||
/// </summary>
|
||||
public class AttackStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public AttackStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.ExplosionDistance)
|
||||
{
|
||||
missile.Explode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无制导阶段策略
|
||||
/// </summary>
|
||||
public class UnguidedStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public UnguidedStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
// 检查是否重新获得引导
|
||||
if (missile.HasGuidance)
|
||||
{
|
||||
Console.WriteLine($"导弹 {missile.Id} 重新获得引导,退出无制导阶段");
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Attack);
|
||||
}
|
||||
else if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.TerminalGuidance);
|
||||
}
|
||||
else
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Cruise);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
100
Models/Tank.cs
100
Models/Tank.cs
@ -1,100 +0,0 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示仿真中的坦克
|
||||
/// </summary>
|
||||
public class Tank : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前速度(米/秒)
|
||||
/// </summary>
|
||||
public double Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大速度(米/秒)
|
||||
/// </summary>
|
||||
public double MaxSpeed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大装甲值
|
||||
/// </summary>
|
||||
public double MaxArmor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前装甲值
|
||||
/// </summary>
|
||||
public double CurrentArmor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">坦克ID</param>
|
||||
/// <param name="tankConfig">坦克配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
|
||||
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager)
|
||||
{
|
||||
Speed = tankConfig.InitialSpeed;
|
||||
MaxSpeed = tankConfig.MaxSpeed;
|
||||
MaxArmor = tankConfig.MaxArmor;
|
||||
CurrentArmor = tankConfig.MaxArmor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新坦克状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长(秒)</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
UpdatePosition(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新坦克位置
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长(秒)</param>
|
||||
private void UpdatePosition(double deltaTime)
|
||||
{
|
||||
Vector3D direction = Orientation.ToVector();
|
||||
Vector3D movement = direction * Speed * deltaTime;
|
||||
Position += movement;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坦克受到伤害
|
||||
/// </summary>
|
||||
/// <param name="damage">伤害值</param>
|
||||
/// <param name="isMissileDamage">是否为导弹造成的伤害</param>
|
||||
public void TakeDamage(double damage, bool isMissileDamage = false)
|
||||
{
|
||||
if (isMissileDamage)
|
||||
{
|
||||
damage = CurrentArmor * 0.5;
|
||||
}
|
||||
|
||||
CurrentArmor = Math.Max(0, CurrentArmor - damage);
|
||||
if (CurrentArmor <= 0)
|
||||
{
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取坦克状态信息
|
||||
/// </summary>
|
||||
/// <returns>坦克状态字符串</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"坦克 {Id}:\n" +
|
||||
$" 位置: {Position}\n" +
|
||||
$" 速度: {Speed:F2}/{MaxSpeed:F2}\n" +
|
||||
$" 装甲: {CurrentArmor:F2}/{MaxArmor:F2}\n" +
|
||||
$" 状态: {(IsActive ? "活动" : "已销毁")}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
138
Program.cs
138
Program.cs
@ -1,138 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Models;
|
||||
using Model;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ActiveProtect
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
TankInfo tankinfo = new()
|
||||
{
|
||||
xp = 100,
|
||||
yp = 0,
|
||||
zp = 100
|
||||
};
|
||||
|
||||
MIniInfo mIniInfo = new()
|
||||
{
|
||||
xm = 1500,
|
||||
ym = 200,
|
||||
zm = 100,
|
||||
psi_m = Math.PI,
|
||||
theta_m = -0.1,
|
||||
vm = 0
|
||||
};
|
||||
|
||||
// 创建仿真配置
|
||||
var config = new SimulationConfig
|
||||
{
|
||||
// 配置坦克
|
||||
TankConfigs = new List<TankConfig>
|
||||
{
|
||||
new TankConfig(tankinfo)
|
||||
{
|
||||
InitialOrientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 15,
|
||||
MaxSpeed = 20,
|
||||
MaxArmor = 100,
|
||||
HasLaserWarner = false,
|
||||
HasLaserJammer = true
|
||||
}
|
||||
},
|
||||
// 配置激光指示器
|
||||
LaserDesignatorConfig = new LaserDesignatorConfig
|
||||
{
|
||||
InitialPosition = new Vector3D(2000, 150, 100),
|
||||
LaserPower = 1e6,
|
||||
LaserDivergenceAngle = 0.01
|
||||
},
|
||||
// 配置激光告警器
|
||||
LaserWarnerConfig = new LaserWarnerConfig
|
||||
{
|
||||
AlarmDuration = 5.0
|
||||
},
|
||||
// 配置激光干扰器
|
||||
LaserJammerConfig = new LaserJammerConfig
|
||||
{
|
||||
MaxJammingCooldown = 5.0,
|
||||
MaxJammingPower = 10000.0,
|
||||
InitialJammingPower = 4000.0,
|
||||
PowerIncreaseRate = 2000.0
|
||||
},
|
||||
// 配置激光驾束仪
|
||||
LaserBeamRiderConfig = new LaserBeamRiderConfig
|
||||
{
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
LaserPower = 1000,
|
||||
ControlFieldDiameter = 6
|
||||
},
|
||||
// 配置导弹
|
||||
MissileConfigs = new List<MissileConfig>
|
||||
{
|
||||
// 激光半主动制导导弹配置
|
||||
new MissileConfig
|
||||
{
|
||||
InitialPosition = new Vector3D(2000, 100, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
|
||||
InitialSpeed = 700,
|
||||
MaxSpeed = 800,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 0.05,
|
||||
MaxFlightDistance = 5000,
|
||||
ThrustAcceleration = 50,
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
|
||||
DistanceParams = new MissileDistanceParams(500, 200, 20),
|
||||
Mass = 50,
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
},
|
||||
// 激光驾束制导导弹配置
|
||||
new MissileConfig
|
||||
{
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, 0.1, 0.0),
|
||||
InitialSpeed = 300,
|
||||
MaxSpeed = 400,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 0.05,
|
||||
MaxFlightDistance = 3000,
|
||||
ThrustAcceleration = 50,
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.LaserBeamRiderGuidance,
|
||||
DistanceParams = new MissileDistanceParams(500, 200, 10),
|
||||
Mass = 50,
|
||||
Type = MissileType.LaserBeamRiderGuidance
|
||||
}
|
||||
},
|
||||
|
||||
SimulationTimeStep = 0.025
|
||||
};
|
||||
|
||||
// 创建仿真管理器
|
||||
var simulationManager = new SimulationManager(config);
|
||||
|
||||
// 运行仿真
|
||||
int maxIterations = 1000;
|
||||
int iteration = 0;
|
||||
while (!simulationManager.IsSimulationEnded && iteration < maxIterations)
|
||||
{
|
||||
simulationManager.Update();
|
||||
simulationManager.PrintStatus();
|
||||
Thread.Sleep(100); // 暂停100毫秒,使输出更易读
|
||||
iteration++;
|
||||
}
|
||||
|
||||
Console.WriteLine("仿真结束");
|
||||
}
|
||||
}
|
||||
}
|
||||
171
README.md
171
README.md
@ -1,171 +0,0 @@
|
||||
# ActiveProtect 仿真系统
|
||||
|
||||
ActiveProtect 是一个用于模拟激光制导导弹和防御系统的仿真环境。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 激光半主动制导导弹仿真
|
||||
- 激光驾束制导导弹仿真
|
||||
- 坦克和激光告警器仿真
|
||||
- 激光干扰器仿真
|
||||
- 可扩展的仿真框架
|
||||
|
||||
## Unity 兼容性
|
||||
|
||||
本项目设计时考虑了与 Unity 游戏引擎的兼容性, 使用C# 9.0 语法。以下是在 Unity 中使用本项目的注意事项:
|
||||
|
||||
1. 向量和数学运算:本项目使用自定义的 `Vector3D` 类。在 Unity 中,您可以将其替换为 Unity 的 `Vector3` 类。
|
||||
|
||||
2. 仿真更新:Unity 使用 `MonoBehaviour` 的 `Update` 方法进行每帧更新。您可以创建一个 `SimulationManager` 脚本,并在其 `Update` 方法中调用仿真系统的更新逻辑。
|
||||
|
||||
3. 可视化:Unity 提供了强大的 3D 渲染能力。您可以为每个仿真元素(如导弹、坦克等)创建相应的 Unity 游戏对象,并在每帧更新其位置和旋转。
|
||||
|
||||
4. 输入处理:将键盘/鼠标输入处理逻辑替换为 Unity 的输入系统(如 `Input.GetKey()` 等)。
|
||||
|
||||
5. 协程:Unity 支持协程,可用于实现某些异步操作或时间相关的功能。
|
||||
|
||||
6. 物理系统:如果需要更复杂的物理模拟,可以考虑使用 Unity 的物理引擎替代当前的简化物理模型。
|
||||
|
||||
7. 事件系统:Unity 有自己的事件系统,您可能需要调整当前的事件处理机制以更好地与 Unity 集成。
|
||||
|
||||
8. 性能优化:在 Unity 中,您可以使用 Unity Profiler 来监控和优化性能。
|
||||
|
||||
通过这些调整,您应该能够将 ActiveProtect 仿真系统顺利集成到 Unity 项目中,从而获得更好的可视化效果和交互体验。
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. 克隆仓库到本地
|
||||
2. 使用 Visual Studio 或其他 C# IDE 打开解决方案
|
||||
3. 编译并运行项目
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎提交 Pull Requests 来改进这个项目。在提交之前,请确保您的代码符合项目的编码规范,并且通过了所有的单元测试。
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目采用 MIT 许可证。详情请见 [LICENSE](LICENSE) 文件。
|
||||
|
||||
## 仿真运行流程(这个 Mermaid 图表会在支持 Mermaid 的 Markdown 查看器中渲染为一个流程图)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[开始仿真] --> B[初始化SimulationManager]
|
||||
B --> C[加载SimulationConfig]
|
||||
C --> D[创建仿真元素]
|
||||
D --> E[开始仿真循环]
|
||||
E --> F{是否结束仿真?}
|
||||
F -->|否| G[更新所有元素]
|
||||
G --> H[收集数据]
|
||||
H --> I[处理事件]
|
||||
I --> E
|
||||
F -->|是| J[结束仿真]
|
||||
J --> K[评估结果]
|
||||
K --> L[生成报告]
|
||||
L --> M[结束]
|
||||
```
|
||||
|
||||
## 反坦克导弹仿真系统
|
||||
|
||||
本项目旨在模拟反坦克导弹的飞行过程和攻击效果。
|
||||
|
||||
### 反坦克导弹飞行阶段
|
||||
|
||||
反坦克导弹的飞行过程通常可以分为以下几个主要阶段:
|
||||
|
||||
1. 发射阶段
|
||||
- 导弹从发射装置或发射管中被推出
|
||||
- 火箭发动机点火,提供初始推力
|
||||
|
||||
2. 加速阶段
|
||||
- 导弹迅速加速到巡航速度
|
||||
- 可能会抛掉一些辅助推进装置(如有)
|
||||
|
||||
3. 巡航阶段
|
||||
- 导弹保持相对稳定的速度飞向<E9A39E><E59091>标
|
||||
- 根据导引系统类型,可能会进行中途修正
|
||||
|
||||
4. 终端制导阶段
|
||||
- 导弹接近目标,进入最后的制导阶段
|
||||
- 可能会启动终端制导系统,如毫米波雷达或红外成像系统
|
||||
|
||||
5. 攻击阶段
|
||||
- 导弹进行最后的机动,以最佳角度接近目标
|
||||
- 可能会启动穿甲弹头或预制破片
|
||||
|
||||
6. 爆炸阶段
|
||||
- 导弹击中目标并引爆
|
||||
- 根据弹头类型,可能是穿甲、破片或破片-燃烧等效果
|
||||
|
||||
在仿真中,这些阶段被纳入计算,每个阶段可能有不同的物理特性和行为模式。例如,加速阶段可能有较大的加速度,而巡航阶段则保持恒定速度。终端制导阶段可能会有更频繁的方向调整。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```csharp
|
||||
ActiveProtect/
|
||||
│
|
||||
├── Models/ # 仿真模型目录
|
||||
│ ├── BasicGuidanceSystem.cs # 基础制导系统类
|
||||
│ ├── ILaserIlluminatable.cs # 可被激光照射的接口定义
|
||||
│ ├── LaserBeamRider.cs # 激光驾束仪类
|
||||
│ ├── LaserBeamRiderGuidanceSystem.cs # 激光驾束制导系统类
|
||||
│ ├── LaserBeamRiderMissile.cs # 激光驾束导弹类
|
||||
│ ├── LaserDesignator.cs # 激光指示器类
|
||||
│ ├── LaserJammer.cs # 激光干扰器类
|
||||
│ ├── LaserSemiActiveGuidedMissile.cs # 激光半主动制导导弹类
|
||||
│ ├── LaserWarner.cs # 激光告警器类
|
||||
│ ├── MissileClass.cs # 导弹基类
|
||||
│ └── Tank.cs # 坦克模型类
|
||||
│
|
||||
├── SimulationEnvironment/ # 仿真环境目录
|
||||
│ ├── SimulationConfig.cs # 仿真配置类
|
||||
│ ├── SimulationElement.cs # 仿真元素基类
|
||||
│ ├── SimulationEvents.cs # 仿真事件定义类
|
||||
│ └── SimulationManager.cs # 仿真管理器类
|
||||
│
|
||||
├── Program.cs # 程序入口点
|
||||
├── README.md # 项目说明文档
|
||||
└── Design.md # 设计文档
|
||||
```
|
||||
|
||||
## 如何运行
|
||||
|
||||
1. 确保你的系统已安装 .NET 6.0。
|
||||
2. 在终端中导航到项目根目录。
|
||||
3. 运行以下命令来构建项目:
|
||||
|
||||
```shell
|
||||
dotnet build
|
||||
```
|
||||
|
||||
4. 运行以下命令来启动仿真:
|
||||
|
||||
```shell
|
||||
dotnet run
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 当前仿真使用简化模型,可能无法完全反映真实世界的复杂性。
|
||||
- 仿真结果仅供参考,不应用于实际军事决策。
|
||||
|
||||
## 比例导引系数(N)的选择
|
||||
|
||||
在导弹制导系统中,比例导引系数(N)是一个关键参数,它直接影响导弹的性能和行为。在我们的仿真系统中,用户可以根据不同的场景需求调整这个参数。
|
||||
|
||||
### N 值的影响
|
||||
|
||||
- **N = 3**:这是一个较为保守的选择,适合大多数情况。它提供了良好的稳定性和能源效率,但可能在应对高机动性目标时表现不佳。
|
||||
- **N = 4**:这个值提供了更积极的制导,适合需要更高机动性的场景。它能更快地响应目标的变化,但可能会增加能源消耗。
|
||||
- **N = 5**:这是一个更激进的选择,提供最高的机动性,但也带来了更大的能源消耗和可能的过度修正。
|
||||
|
||||
### 选择 N 值的考虑因素
|
||||
|
||||
1. **导弹类型**:大型、长程导弹通常使用较小的 N 值,而小型、短程导弹可以使用较大的 N 值。
|
||||
2. **目标特性**:对付高速、高机动性目标时,可能需要较大的 N 值。
|
||||
3. **作战环境**:在复杂环境中,可能需要更大的 N 值来应对突发情况。
|
||||
4. **能源限制**:如果导弹燃料有限,较小的 N 值可以帮助节省能源。
|
||||
5. **制导系统精度**:精度较高的系统可以使用较小的 N 值,而精度较低的系统可能需要较大的 N 值来补偿误差。
|
||||
6. **任务要求**:精确打击任务可能需要较大的 N 值,而区域防御任务可能使用较小的 N 值。
|
||||
|
||||
在我们的仿真系统中,用户可以通过调整 `ProportionalNavigationCoefficient` 参数来设置不同的 N 值,以模拟各种实际情况下的导弹行为。我们建议用户尝试不同的 N 值,观察其对导弹性能的影响,以找到最适合特定场景的设置。
|
||||
@ -1,474 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using ActiveProtect.Models;
|
||||
using Model;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真配置类,包含整个仿真所需的所有配置信息
|
||||
/// </summary>
|
||||
public class SimulationConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 坦克配置列表
|
||||
/// </summary>
|
||||
public List<TankConfig> TankConfigs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹配置列表
|
||||
/// </summary>
|
||||
public List<MissileConfig> MissileConfigs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光指示器配置列表
|
||||
/// </summary>
|
||||
public LaserDesignatorConfig LaserDesignatorConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光驾束仪配置列表
|
||||
/// </summary>
|
||||
public LaserBeamRiderConfig LaserBeamRiderConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器配置
|
||||
/// </summary>
|
||||
public LaserWarnerConfig LaserWarnerConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光干扰器配置
|
||||
/// </summary>
|
||||
public LaserJammerConfig LaserJammerConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真时间步长(秒)
|
||||
/// </summary>
|
||||
public double SimulationTimeStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,初始化默认配置
|
||||
/// </summary>
|
||||
public SimulationConfig()
|
||||
{
|
||||
TankConfigs = new List<TankConfig>();
|
||||
MissileConfigs = new List<MissileConfig>();
|
||||
LaserDesignatorConfig = new LaserDesignatorConfig();
|
||||
LaserBeamRiderConfig = new LaserBeamRiderConfig();
|
||||
LaserWarnerConfig = new LaserWarnerConfig();
|
||||
LaserJammerConfig = new LaserJammerConfig();
|
||||
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坦克配置类
|
||||
/// </summary>
|
||||
public class TankConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
public Vector3D InitialPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始朝向
|
||||
/// </summary>
|
||||
public Orientation InitialOrientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始速度(米/秒)
|
||||
/// </summary>
|
||||
public double InitialSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大速度(米/秒)
|
||||
/// </summary>
|
||||
public double MaxSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大装甲值
|
||||
/// </summary>
|
||||
public double MaxArmor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否装备激光告警器
|
||||
/// </summary>
|
||||
public bool HasLaserWarner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否装备激光干扰器
|
||||
/// </summary>
|
||||
public bool HasLaserJammer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public TankConfig()
|
||||
{
|
||||
SetDefaultValues();
|
||||
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
|
||||
public TankConfig(TankInfo tankInfo){
|
||||
SetDefaultValues();
|
||||
|
||||
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
|
||||
public void SetDefaultValues(){
|
||||
InitialSpeed = 0;
|
||||
MaxSpeed = 0;
|
||||
MaxArmor = 0;
|
||||
HasLaserWarner = false;
|
||||
HasLaserJammer = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹配置类
|
||||
/// </summary>
|
||||
public class MissileConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
public Vector3D InitialPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始朝向
|
||||
/// </summary>
|
||||
public Orientation InitialOrientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始速度(米/秒)
|
||||
/// </summary>
|
||||
public double InitialSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大速度(米/秒)
|
||||
/// </summary>
|
||||
public double MaxSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标索引
|
||||
/// </summary>
|
||||
public int TargetIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行时间(秒)
|
||||
/// </summary>
|
||||
public double MaxFlightTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行距离(米)
|
||||
/// </summary>
|
||||
public double MaxFlightDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 飞行阶段配置
|
||||
/// </summary>
|
||||
public FlightStageConfig StageConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离参数
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double ThrustAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double MaxEngineBurnTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹质量(千克)
|
||||
/// </summary>
|
||||
public double Mass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹类型
|
||||
/// </summary>
|
||||
public MissileType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public MissileConfig()
|
||||
{
|
||||
SetDefaultValues();
|
||||
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
|
||||
public MissileConfig(MIniInfo mIniInfo){
|
||||
SetDefaultValues();
|
||||
|
||||
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
|
||||
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
|
||||
InitialSpeed = mIniInfo.vm;
|
||||
}
|
||||
|
||||
public void SetDefaultValues(){
|
||||
InitialSpeed = 0;
|
||||
MaxSpeed = 0;
|
||||
TargetIndex = 0;
|
||||
MaxFlightTime = 0;
|
||||
MaxFlightDistance = 0;
|
||||
StageConfig = FlightStageConfig.StandardMissile;
|
||||
ThrustAcceleration = 0;
|
||||
MaxEngineBurnTime = 0;
|
||||
MaxAcceleration = 0;
|
||||
DistanceParams = new MissileDistanceParams(0, 0, 0);
|
||||
ProportionalNavigationCoefficient = 0;
|
||||
Type = MissileType.StandardMissile;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光指示器配置类
|
||||
/// </summary>
|
||||
public class LaserDesignatorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
public Vector3D InitialPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光功率(瓦特)
|
||||
/// </summary>
|
||||
public double LaserPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光发散角
|
||||
/// </summary>
|
||||
public double LaserDivergenceAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public LaserDesignatorConfig()
|
||||
{
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
LaserPower = 0;
|
||||
LaserDivergenceAngle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光驾束仪配置类
|
||||
/// </summary>
|
||||
public class LaserBeamRiderConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
public Vector3D InitialPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光功率(瓦特)
|
||||
/// </summary>
|
||||
public double LaserPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制场直径(米)
|
||||
/// </summary>
|
||||
public double ControlFieldDiameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大导引距离(米)
|
||||
/// </summary>
|
||||
public double MaxGuidanceDistance { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public LaserBeamRiderConfig()
|
||||
{
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
LaserPower = 0;
|
||||
ControlFieldDiameter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹类型枚举
|
||||
/// </summary>
|
||||
public enum MissileType
|
||||
{
|
||||
StandardMissile, // 标准导弹
|
||||
LaserSemiActiveGuidance, // 激光半主动制导
|
||||
LaserBeamRiderGuidance, // 激光驾束制导
|
||||
InfraredCommandGuidance, // 红外指令制导
|
||||
InfraredImagingTerminalGuidance, // 红外成像末制导
|
||||
MillimeterWaveTerminalGuidance // 毫米波末制导
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹距离参数结构
|
||||
/// </summary>
|
||||
public struct MissileDistanceParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 终端制导距离(米)
|
||||
/// </summary>
|
||||
public double TerminalGuidanceDistance;
|
||||
/// <summary>
|
||||
/// 攻击距离(米)
|
||||
/// </summary>
|
||||
public double AttackDistance;
|
||||
/// <summary>
|
||||
/// 爆炸距离(米)
|
||||
/// </summary>
|
||||
public double ExplosionDistance;
|
||||
|
||||
public MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
|
||||
{
|
||||
TerminalGuidanceDistance = terminalGuidanceDistance;
|
||||
AttackDistance = attackDistance;
|
||||
ExplosionDistance = explosionDistance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// 导弹飞行阶段配置结构
|
||||
/// </summary>
|
||||
public struct FlightStageConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用发射阶段
|
||||
/// </summary>
|
||||
public bool EnableLaunch;
|
||||
/// <summary>
|
||||
/// 启用加速阶段
|
||||
/// </summary>
|
||||
public bool EnableAcceleration;
|
||||
/// <summary>
|
||||
/// 启用巡航阶段
|
||||
/// </summary>
|
||||
public bool EnableCruise;
|
||||
/// <summary>
|
||||
/// 启用终端制导阶段
|
||||
/// </summary>
|
||||
public bool EnableTerminalGuidance;
|
||||
/// <summary>
|
||||
/// 启用攻击阶段
|
||||
/// </summary>
|
||||
public bool EnableAttack;
|
||||
|
||||
/// <summary>
|
||||
/// 标准导弹的预设配置, 所有阶段都启用
|
||||
/// </summary>
|
||||
public static FlightStageConfig StandardMissile => new(true, true, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 激光半主动制导导弹的预设配置, 没有加速阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig LaserSemiActiveGuidedMissile => new(true, false, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 激光驾束制导导弹的预设配置,没有巡航阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig LaserBeamRiderGuidance => new(true, true, false, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 红外指令制导导弹的预设配置,没有巡航阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig InfraredCommandGuidance => new(true, true, false, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 红外成像末制导导弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig InfraredImagingTerminalGuidance => new(true, true, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波末制导导弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
|
||||
|
||||
public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack)
|
||||
{
|
||||
EnableLaunch = enableLaunch;
|
||||
EnableAcceleration = enableAcceleration;
|
||||
EnableCruise = enableCruise;
|
||||
EnableTerminalGuidance = enableTerminalGuidance;
|
||||
EnableAttack = enableAttack;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器配置类
|
||||
/// </summary>
|
||||
public class LaserWarnerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 警报持续时间(秒)
|
||||
/// </summary>
|
||||
public double AlarmDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public LaserWarnerConfig()
|
||||
{
|
||||
AlarmDuration = 5.0; // 默认警报持续5秒
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光干扰器配置类
|
||||
/// </summary>
|
||||
public class LaserJammerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大干扰冷却时间(秒)
|
||||
/// </summary>
|
||||
public double MaxJammingCooldown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double MaxJammingPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double InitialJammingPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功率增加速率(瓦特/秒)
|
||||
/// </summary>
|
||||
public double PowerIncreaseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
public LaserJammerConfig()
|
||||
{
|
||||
MaxJammingCooldown = 5.0;
|
||||
MaxJammingPower = 10000.0;
|
||||
InitialJammingPower = 4000.0;
|
||||
PowerIncreaseRate = 2000.0; // 每秒增加的功率
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,101 +0,0 @@
|
||||
using ActiveProtect.Models;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真元素的抽象基类,所有仿真中的实体都继承自此类
|
||||
/// </summary>
|
||||
public abstract class SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真元素的唯一标识符
|
||||
/// </summary>
|
||||
public virtual string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前位置
|
||||
/// </summary>
|
||||
public virtual Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前速度
|
||||
/// </summary>
|
||||
public virtual Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前朝向
|
||||
/// </summary>
|
||||
public virtual Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素是否处于活动状态
|
||||
/// </summary>
|
||||
public virtual bool IsActive { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真管理器的引用
|
||||
/// </summary>
|
||||
public ISimulationManager SimulationManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">仿真元素的唯一标识符</param>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
protected SimulationElement(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager)
|
||||
{
|
||||
Id = id;
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
SimulationManager = simulationManager;
|
||||
Velocity = Vector3D.Zero;
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新仿真元素的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public abstract void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取仿真元素的状态信息
|
||||
/// </summary>
|
||||
/// <returns>状态信息字符串</returns>
|
||||
public virtual string GetStatus()
|
||||
{
|
||||
return $"{GetType().Name} {Id} at {Position}, Orientation: {Orientation}, Active: {IsActive}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布仿真事件
|
||||
/// </summary>
|
||||
/// <param name="evt">要发布的事件</param>
|
||||
protected void PublishEvent(SimulationEvent evt)
|
||||
{
|
||||
evt.SenderId = Id;
|
||||
evt.Timestamp = SimulationManager.CurrentTime;
|
||||
SimulationManager.PublishEvent(evt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活仿真元素
|
||||
/// </summary>
|
||||
public virtual void Activate()
|
||||
{
|
||||
IsActive = true;
|
||||
PublishEvent(new EntityActivatedEvent { ActivatedEntityId = Id });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用仿真元素
|
||||
/// </summary>
|
||||
public virtual void Deactivate()
|
||||
{
|
||||
IsActive = false;
|
||||
PublishEvent(new EntityDeactivatedEvent { DeactivatedEntityId = Id });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,171 +0,0 @@
|
||||
using ActiveProtect.Models;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真事件的基类
|
||||
/// </summary>
|
||||
public class SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件发送者的ID
|
||||
/// </summary>
|
||||
public string? SenderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件发生的时间戳
|
||||
/// </summary>
|
||||
public double Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹发射事件
|
||||
/// </summary>
|
||||
public class MissileFireEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光照射事件
|
||||
/// </summary>
|
||||
public class LaserIlluminationStartEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光定位器
|
||||
/// </summary>
|
||||
public LaserDesignator? LaserDesignator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标元素
|
||||
/// </summary>
|
||||
public SimulationElement? Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary
|
||||
/// <summary>
|
||||
/// 激光照射更新事件
|
||||
/// </summary>
|
||||
public class LaserIlluminationUpdateEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光定位器
|
||||
/// </summary>
|
||||
public LaserDesignator? LaserDesignator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标元素
|
||||
/// </summary>
|
||||
public SimulationElement? Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary
|
||||
/// 激光照射停止事件
|
||||
/// </summary>
|
||||
public class LaserIlluminationStopEvent : SimulationEvent
|
||||
{
|
||||
public LaserDesignator? LaserDesignator { get; set; }
|
||||
public SimulationElement? Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光干扰事件
|
||||
/// </summary>
|
||||
public class LaserJammingEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰功率
|
||||
/// </summary>
|
||||
public double JammingPower { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体销毁事件
|
||||
/// </summary>
|
||||
public class EntityDestroyedEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 被销毁实体的ID
|
||||
/// </summary>
|
||||
public string? DestroyedEntityId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器警报事件
|
||||
/// </summary>
|
||||
public class LaserWarnerAlarmEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器警报停止事件
|
||||
/// </summary>
|
||||
public class LaserWarnerAlarmStopEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体激活事件
|
||||
/// </summary>
|
||||
public class EntityActivatedEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 被激活实体的ID
|
||||
/// </summary>
|
||||
public string? ActivatedEntityId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体停用事件
|
||||
/// </summary>
|
||||
public class EntityDeactivatedEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 被停用实体的ID
|
||||
/// </summary>
|
||||
public string? DeactivatedEntityId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 激光开始事件
|
||||
/// </summary>
|
||||
public class LaserBeamStartEvent : SimulationEvent
|
||||
{
|
||||
public LaserBeamRider? LaserBeamRider { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光更新事件
|
||||
/// </summary>
|
||||
public class LaserBeamUpdateEvent : SimulationEvent
|
||||
{
|
||||
public LaserBeamRider? LaserBeamRider { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光停止事件
|
||||
/// </summary>
|
||||
public class LaserBeamStopEvent : SimulationEvent
|
||||
{
|
||||
public LaserBeamRider? LaserBeamRider { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,399 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ActiveProtect.Models;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真管理器接口,定义了仿真管理器的基本功能
|
||||
/// </summary>
|
||||
public interface ISimulationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前仿真时间
|
||||
/// </summary>
|
||||
double CurrentTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加仿真元素
|
||||
/// </summary>
|
||||
void AddElement(SimulationElement element);
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取仿真实体
|
||||
/// </summary>
|
||||
SimulationElement GetEntityById(string id);
|
||||
|
||||
/// <summary>
|
||||
/// 处理目标被击中事件
|
||||
/// </summary>
|
||||
void HandleTargetHit(string targetId, string missileId);
|
||||
|
||||
/// <summary>
|
||||
/// 发布仿真事件
|
||||
/// </summary>
|
||||
void PublishEvent(SimulationEvent evt);
|
||||
|
||||
/// <summary>
|
||||
/// 订阅仿真事件
|
||||
/// </summary>
|
||||
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅仿真事件
|
||||
/// </summary>
|
||||
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 取消所有事件订阅
|
||||
/// </summary>
|
||||
void UnsubscribeAllEvents(SimulationElement element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仿真管理器类,负责管理整个仿真过程
|
||||
/// </summary>
|
||||
public class SimulationManager : ISimulationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真元素列表
|
||||
/// </summary>
|
||||
public List<SimulationElement> Elements { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前仿真时间
|
||||
/// </summary>
|
||||
public double CurrentTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真是否结束
|
||||
/// </summary>
|
||||
public bool IsSimulationEnded { get; private set; }
|
||||
|
||||
private readonly SimulationConfig config;
|
||||
private Dictionary<Type, List<Delegate>> eventHandlers = new Dictionary<Type, List<Delegate>>();
|
||||
private Dictionary<SimulationElement, List<(Type, Delegate)>> elementSubscriptions = new Dictionary<SimulationElement, List<(Type, Delegate)>>();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public SimulationManager(SimulationConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
Elements = new List<SimulationElement>();
|
||||
CurrentTime = 0;
|
||||
IsSimulationEnded = false;
|
||||
InitializeSimulation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真
|
||||
/// </summary>
|
||||
private void InitializeSimulation()
|
||||
{
|
||||
// 创建坦克
|
||||
for (int i = 0; i < config.TankConfigs.Count; i++)
|
||||
{
|
||||
var tankConfig = config.TankConfigs[i];
|
||||
var tank = new Tank($"Tank_{i + 1}", tankConfig, this);
|
||||
Elements.Add(tank);
|
||||
|
||||
// // 为坦克创建激光告警器
|
||||
// if (tankConfig.HasLaserWarner)
|
||||
// {
|
||||
// var laserWarner = new LaserWarner(
|
||||
// $"LaserWarner_{tank.Id}",
|
||||
// tank.Position,
|
||||
// tank.Orientation,
|
||||
// this,
|
||||
// tank.Id,
|
||||
// config.LaserWarnerConfig
|
||||
// );
|
||||
// Elements.Add(laserWarner);
|
||||
// }
|
||||
|
||||
// // 为坦克创建激光干扰机
|
||||
// if (tankConfig.HasLaserJammer)
|
||||
// {
|
||||
// var laserJammer = new LaserJammer(
|
||||
// $"LaserJammer_{tank.Id}",
|
||||
// tank.Position,
|
||||
// tank.Orientation,
|
||||
// this,
|
||||
// tank.Id,
|
||||
// config.LaserJammerConfig
|
||||
// );
|
||||
// Elements.Add(laserJammer);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 创建导弹
|
||||
for (int i = 0; i < config.MissileConfigs.Count; i++)
|
||||
{
|
||||
var missileConfig = config.MissileConfigs[i];
|
||||
|
||||
// 确保 MaxFlightTime 设置合理
|
||||
if (missileConfig.MaxFlightTime <= 0)
|
||||
{
|
||||
missileConfig.MaxFlightTime = 300; // 设置一个默认值,比如 300 秒
|
||||
Console.WriteLine($"警告:导弹配置 {i} 的 MaxFlightTime 无效,已设置为默认值 300 秒");
|
||||
}
|
||||
|
||||
MissileBase missile = missileConfig.Type switch
|
||||
{
|
||||
MissileType.LaserSemiActiveGuidance => new LaserSemiActiveGuidedMissile(
|
||||
$"LSGM_{i + 1}",
|
||||
missileConfig,
|
||||
"LD_1",
|
||||
this
|
||||
),
|
||||
MissileType.LaserBeamRiderGuidance => new LaserBeamRiderMissile(
|
||||
$"LBRM_{i + 1}",
|
||||
"Tank_1",
|
||||
missileConfig,
|
||||
this
|
||||
),
|
||||
_ => new MissileBase(
|
||||
$"NM_{i + 1}",
|
||||
missileConfig,
|
||||
this
|
||||
),
|
||||
};
|
||||
Elements.Add(missile);
|
||||
}
|
||||
|
||||
// 创建激光目标指示器
|
||||
var laserDesignatorConfig = config.LaserDesignatorConfig;
|
||||
var laserDesignator = new LaserDesignator(
|
||||
$"LD_1",
|
||||
"Tank_1",
|
||||
"LSGM_1",
|
||||
laserDesignatorConfig,
|
||||
this
|
||||
);
|
||||
Elements.Add(laserDesignator);
|
||||
|
||||
// 创建激光驾束仪
|
||||
var laserBeamRiderConfig = config.LaserBeamRiderConfig;
|
||||
var laserBeamRider = new LaserBeamRider(
|
||||
"LBR_1",
|
||||
"LBRM_2",
|
||||
"Tank_1",
|
||||
laserBeamRiderConfig,
|
||||
this
|
||||
);
|
||||
Elements.Add(laserBeamRider);
|
||||
|
||||
|
||||
// 激活所有元素
|
||||
ActivateAllElements();
|
||||
|
||||
// 启动激光驾束仪
|
||||
laserBeamRider.StartBeamIllumination();
|
||||
}
|
||||
|
||||
//激活所有元素
|
||||
private void ActivateAllElements()
|
||||
{
|
||||
foreach (var element in Elements)
|
||||
{
|
||||
element.Activate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布仿真事件
|
||||
/// </summary>
|
||||
public void PublishEvent(SimulationEvent evt)
|
||||
{
|
||||
var eventType = evt.GetType();
|
||||
//Console.WriteLine($"发布事件: {eventType.Name}, 发送者: {evt.SenderId}");
|
||||
if (eventHandlers.TryGetValue(eventType, out var handlers))
|
||||
{
|
||||
foreach (var handler in handlers)
|
||||
{
|
||||
handler.DynamicInvoke(evt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"没有找到事件 {eventType.Name} 的处理程序");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订阅仿真事件
|
||||
/// </summary>
|
||||
public void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent
|
||||
{
|
||||
var eventType = typeof(T);
|
||||
if (!eventHandlers.TryGetValue(eventType, out List<Delegate>? value))
|
||||
{
|
||||
value = new List<Delegate>();
|
||||
eventHandlers[eventType] = value;
|
||||
}
|
||||
|
||||
value.Add(handler);
|
||||
|
||||
// 记录订阅关系
|
||||
var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name));
|
||||
if (element != null)
|
||||
{
|
||||
if (!elementSubscriptions.TryGetValue(element, out List<(Type, Delegate)>? subscriptions))
|
||||
{
|
||||
subscriptions = new List<(Type, Delegate)>();
|
||||
elementSubscriptions[element] = subscriptions;
|
||||
}
|
||||
|
||||
subscriptions.Add((eventType, handler as Delegate));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅仿真事件
|
||||
/// </summary>
|
||||
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
||||
{
|
||||
var eventType = typeof(T);
|
||||
if (eventHandlers.TryGetValue(eventType, out List<Delegate>? value))
|
||||
{
|
||||
value.Remove(handler);
|
||||
}
|
||||
|
||||
// 移除订阅关系记录
|
||||
var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name));
|
||||
if (element != null && elementSubscriptions.TryGetValue(element, out List<(Type, Delegate)>? subscriptions))
|
||||
{
|
||||
subscriptions.RemoveAll(s => Delegate.Equals(s.Item2, handler));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消所有事件订阅
|
||||
/// </summary>
|
||||
public void UnsubscribeAllEvents(SimulationElement element)
|
||||
{
|
||||
if (elementSubscriptions.ContainsKey(element))
|
||||
{
|
||||
foreach (var subscription in elementSubscriptions[element])
|
||||
{
|
||||
if (eventHandlers.TryGetValue(subscription.Item1, out List<Delegate>? value))
|
||||
{
|
||||
value.Remove(subscription.Item2);
|
||||
}
|
||||
}
|
||||
elementSubscriptions.Remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新仿真状态
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (IsSimulationEnded) return;
|
||||
|
||||
CurrentTime += config.SimulationTimeStep;
|
||||
|
||||
foreach (var element in Elements.ToList())
|
||||
{
|
||||
if (element.IsActive)
|
||||
{
|
||||
element.Update(config.SimulationTimeStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnsubscribeAllEvents(element);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除不活跃的元素
|
||||
Elements.RemoveAll(e => !e.IsActive);
|
||||
|
||||
// 检查是否所有导弹都结束飞行
|
||||
if (!Elements.Any(e => e is MissileBase && e.IsActive))
|
||||
{
|
||||
EndSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打印仿真状态
|
||||
/// </summary>
|
||||
public void PrintStatus()
|
||||
{
|
||||
Console.WriteLine($"仿真时间: {CurrentTime:F2}");
|
||||
foreach (var element in Elements)
|
||||
{
|
||||
Console.WriteLine(element.GetStatus());
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 结束仿真
|
||||
/// </summary>
|
||||
private void EndSimulation()
|
||||
{
|
||||
IsSimulationEnded = true;
|
||||
Console.WriteLine("仿真结束");
|
||||
Console.WriteLine($"总仿真时间: {CurrentTime:F2} 秒");
|
||||
Console.WriteLine($"剩余坦克数量: {Elements.Count(e => e is Tank)}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取仿真实体
|
||||
/// </summary>
|
||||
public SimulationElement GetEntityById(string id)
|
||||
{
|
||||
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理目标被击中事件
|
||||
/// </summary>
|
||||
public void HandleTargetHit(string targetId, string missileId)
|
||||
{
|
||||
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is MissileBase missile)
|
||||
{
|
||||
// 计算导弹造成的伤害
|
||||
double damage = CalculateMissileDamage(missile);
|
||||
|
||||
// 对坦克造成伤害
|
||||
tank.TakeDamage(damage, true);
|
||||
|
||||
// 记录击中事件
|
||||
LogHitEvent(targetId, missileId, damage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算导弹造成的伤害
|
||||
/// </summary>
|
||||
private double CalculateMissileDamage(MissileBase missile)
|
||||
{
|
||||
// 这里可以根据导弹类型、速度等因素计算伤害
|
||||
// 现在我们简单地返回一个固定值
|
||||
return 50;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录击中事件
|
||||
/// </summary>
|
||||
private static void LogHitEvent(string targetId, string missileId, double damage)
|
||||
{
|
||||
Console.WriteLine($"目标 {targetId} 被导弹 {missileId} 击中,造成 {damage} 点伤害");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加仿真元素
|
||||
/// </summary>
|
||||
public void AddElement(SimulationElement element)
|
||||
{
|
||||
Elements.Add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -1,23 +0,0 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"ActiveProtect/1.0.0": {
|
||||
"runtime": {
|
||||
"ActiveProtect.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"ActiveProtect/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -1,9 +0,0 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net6.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user