—— 高拟真蜂群无人机超视距空战推演平台
BVRSim 是一个基于开源飞行动力学库 JSBSim 构建,面向超视距蜂群无人机空战 策略验证 的高拟真推演平台。其设计目标并非直接服务于强化学习训练,而是用于检验已训练策略在复杂感知条件下的 泛化鲁棒性,以缩小仿真与现实的差距(Sim‑to‑Real Gap)。特别是经参数校准的 AIM-120C-5 空空导弹动力学模型,保留了高速度与有限转弯率之间的物理耦合,避免了强化学习训练环境中常见的过度理想化机动假设。
平台在物理层依托 JSBSim 保证气动与运动学可信;在感知层人为引入符合统计规律的测量噪声与数据链延迟,从而揭示理想仿真中不易察觉的 性能退化。同时集成 Tacview 兼容的 ACMI 日志,便于对交战全过程进行三维复盘。
本平台源于 第十九届“挑战杯”全国大学生课外学术科技作品竞赛“揭榜挂帅”擂台赛 ——中国航空工业集团沈阳飞机设计研究所发布的《复杂任务下无人机智能协同对抗算法》赛题。作者团队凭借稳定、高效的算法代码和严谨、规范的设计文档,荣获该赛题 一等奖。
赛后,作者基于开源飞行仿真软件与公开资料,独立重构了全部仿真代码,不包含任何赛事涉密代码或内部数据,并将其开放为可扩展的对抗仿真框架。
与现有平台的对比:
| 平台类型 | 典型代表 | 优势 | 面向策略验证的局限 |
|---|---|---|---|
| 军事级推演系统 | AFSim | 极高保真度、权威数据库 | 闭源,难以用 Python 灵活编排与控制无人机 |
| 通用无人机仿真器 | AirSim、RflySim | 视觉逼真、跨平台 | 缺乏空战专用的传感器噪声与制导链路模型 |
| RL 训练环境 | bvr-marl (github)、jsbgym (pypi) | 快速、理想化 | 智能体训练依赖完全可观测假设与无偏测量,导致策略过拟合于训练环境的简化特征,泛化能力存疑 |
BVRSim 的定位:提供 Python 可控接口,集成 JSBSim 高保真动力学引擎,并刻意引入 非理想感知特征(噪声、延迟、友伤判定),旨在回答:“在训练中表现优异的策略,置于更真实的环境中是否依然可靠?”
-
高拟真飞行动力学
- F-16 战斗机:调用 JSBSim 官方气动数据库,六自由度非线性求解,控制回路采用级联 PID(高度差→体轴 z 分量→俯仰角→升降舵),控制增益经人工整定以满足超视距机动需求。
- AIM-120C-5 导弹:基于公开资料重构
aircraft/aim120c.xml配置文件,包含无量纲气动系数、减面燃烧推力表、静不稳定系数$Cm\alpha$ = 0.25,及动压调度的角速率阻尼器;外部制导与过载控制由 Python 端 PID 实现,可用过载受外形、推力和动压等因素影响。
-
特化导弹制导与目标状态估计
- 高抛弹道:发射时在载机俯仰角上叠加初始爬升角,降低超音速飞行的高动压与气动阻力,延长射程。
- 中制导:比例导引(PN),利用剩余飞行时间(tgo)平滑控制指令,兼顾能量管理。
- 末制导:扩展比例导引(APN),在 PN 基础上补偿目标法向加速度,可对抗高机动目标。
- 绝对状态卡尔曼滤波器(9 状态 Singer 模型):采用 9 阶 Padé 矩阵指数精确离散化、Joseph 形式协方差更新与 PSD 强制正定,在 NED 绝对坐标系下直接估计目标坐标、速度、加速度,消除了本机机动与滤波的耦合,并在目标信息中断时自适应增大过程噪声,避免协方差过度收敛。
详细实现与创新点见后文《飞行器模型真实性设计》章节。
-
非理想感知与数据链建模
- 雷达测量噪声:目标距离与速度的标准差随距离平方增长,并利用钳位函数避免异常发散,迫使策略在非理想信息下完成决策。
- 数据链更新存在周期性(每 3 个仿真步更新一次雷达数据),模拟雷达扫描周期、实际链路延迟与带宽限制。
-
并行仿真与友伤判定
- 双方决策代码分配到对应的 子进程沙盒,既绕过Python全局GIL锁,支持并行计算提高效率,又能避免策略访问或修改主线程数据,预防作弊。
- 所有飞机及导弹均作为独立实体推进动力学解算,采用空间均匀网格加速邻近点检测。
- 任意实体间距离小于 15 米即判定为同归于尽,模拟了战场意外碰撞与误击风险。
- 任意实体超出战场范围立即销毁,并可设置红方飞机威胁区(禁区),模拟敌方防空范围。
-
Tacview 原生可视化
自动生成
.acmi日志,支持详细参数、雷达锁定与损毁事件的三维回放。下载 Tacview 免费版即可查看。example.mp4
-
依赖自动配置
用户只需安装 Python 3.10 以上,而
import bvrsim时自动检测并配置jsbsim、numpy等依赖。
BVRSim/
├── .gitignore
├── LICENSE
├── README.md
├── mySim.py # 示例仿真脚本(继承 bvrsim 类,重载策略函数)
├── tacview/ # 存放 ACMI 日志文件(自动在工作区生成)
├── aircraft/ # JSBSim 飞行器配置目录
│ └── aim120c.xml # AIM-120C-5 导弹气动/推进/飞控参数定义
└── bvrsim/ # 核心仿真代码包
├── __init__.py # 数据类(EnemyInfo, DroneInfo, SendData)定义与包入口
├── drone.py # 无人机基类(drone)与 F-16 子类,含级联 PID 控制与导弹数据链
├── missile.py # 导弹基类(missile)与 AIM-120C 子类,含中/末制导律
├── simulate.py # 仿真主循环、战场边界/威胁区检测、碰撞判定、多进程调度
├── utils.py # 工具模块:PID 控制器、9 状态 Kalman 滤波器、model 基类、坐标转换、矩阵指数等
└── visual.py # 可视化模块:Tacview ACMI 日志记录(初始化、轨迹、锁定、击毁事件)
git clone https://github.com/celestial-dew/BVRSim.git
cd BVRSim
python mySim.pyfrom bvrsim import bvrsim, DroneInfo, SendData
from bvrsim.drone import f16, aim120c
import numpy as np
class mySim(bvrsim):
def redstrategy(self, info: DroneInfo, step_num: int) -> SendData:
"""红方策略(需返回SendData指令)"""
cmd = SendData()
cmd.CmdSpd = 2
cmd.CmdAlt = 12000
cmd.CmdHeadingDeg = 180
cmd.EnemyID = 3 # 攻击/锁定ID=3的敌机
# 目标信息
enemy = next((x for x in info.FoundEnemyList if x.EnemyID == cmd.EnemyID), None)
if not step_num % 200:
cmd.engage = -1
elif (
step_num % 200 == 100
and enemy
and enemy.TargetDis < 5e4 # 保证发射距离
and 1 < np.rad2deg(info.Pitch) < 5 # 保证发射仰角
):
cmd.engage = 1
return cmd
def bluestrategy(self, info: DroneInfo, step_num: int) -> SendData:
"""蓝方策略(需返回SendData指令)"""
cmd = SendData()
cmd.CmdSpd = 1.2
cmd.CmdAlt = 11000
cmd.CmdHeadingDeg = 0
cmd.EnemyID = 1
enemy = next((x for x in info.FoundEnemyList if x.EnemyID == cmd.EnemyID), None)
if not step_num % 100:
cmd.engage = -1
elif (
step_num % 100 == 50
and enemy
and enemy.TargetDis < 6e4
and 1 < np.rad2deg(info.Pitch) < 5
):
cmd.engage = 1
return cmd
# 战场空间:[(纬度范围 deg), (经度范围 deg), (高度范围 m)]
field = [(23.0, 26.0), (118.0, 120.0), (2000, 15000)]
# 红方防空威胁区列表:[(中心纬度 deg, 中心经度 deg, 高度 m, 半径 m)]
threat = [(24.5, 119.0, 0, 50000)]
if __name__ == "__main__": # 多进程必须
sim = mySim(field=field, threat=threat)
data = dict(drone=f16, alt=1e4, mach=0.8, fuel=5e3) # 双方共同参数
# 覆盖双方默认初始兵力参数
sim.red.clear()
sim.blue.clear()
for i in range(2):
sim.red.append(data.copy())
sim.red[-1].update(
dict(lat=24.2, lon=118.2 + i / 5, head=180, mislist=4 * [aim120c])
)
sim.blue.append(data.copy())
sim.blue[-1].update(
dict(lat=23.2, lon=118.2 + i / 5, head=0, mislist=6 * [aim120c])
)
sim.main(time=10) # 仿真 10 分钟(游戏内时间)仿真每步会将本机状态打包为 DroneInfo 对象传递给策略函数。
class DroneInfo:
DroneID: int # 本机ID
Latitude: float # 纬度 (rad)
Longitude: float # 经度 (rad)
Altitude: float # 高度 (m)
Yaw: float # 航向角 (rad)
Pitch: float # 俯仰角 (rad)
Roll: float # 滚转角 (rad)
V_N, V_E, V_D: float # NED速度分量 (m/s)
A_N, A_E, A_D: float # NED运动加速度分量 (m/s²)
Mach_M: float # 马赫数
fuel: float # 剩余燃油 (lbs)
AlarmList: list # 告警列表 [(辐射源ID, 相对方位角, 类型), ...]
FoundEnemyList: list # 发现敌机列表 (EnemyInfo对象)
strike: list # 本机导弹已击中实体的ID列表(含敌机、友机或导弹,体现全体友伤设计)
MissileNowNum: int # 剩余导弹数量class EnemyInfo:
EnemyID: int # 敌机ID
isNTS: bool # 是否已被本机火控锁定
TargetDis: float # 距离 (m)
DisRate: float # 径向相对速度 (m/s)
TargetYaw: float # 水平视线角 (rad)
TargetPitch: float # 垂直视线角 (rad)
vNED: np.ndarray # NED速度向量
TargetMach_M: float # 估计马赫数
MissilePowerfulDis: float # 不可逃逸区距离 (动态计算)
MissileMaxDis: float # 最大射程 (动态计算)本接口基于赛题控制方式,移除冗余指令,保留必要的飞控难度。策略函数需返回 SendData 对象,指定期望航向、速度、高度及攻击指令等。
class SendData:
CmdSpd: float # 期望马赫数
CmdAlt: float # 期望高度 (m)
CmdHeadingDeg: float # 绝对方位角 (deg)
CmdPitchDeg: float # 最大允许俯仰角 (deg),较小值用于平稳飞行包线保护,较大值允许高G机动
CmdPhi: float # 最大允许滚转角 (deg),同上
TurnDirection: int # 0=就近转, 1=右转, -1=左转
ThrustLimit: float # 推力限制 (kN),默认129
engage: int # -1=火控锁定, 1=发射导弹 (仅在从0变为非0时触发一次)
EnemyID: int # 目标敌机ID本平台在 Python 代码层面严格遵循现代空战仿真对物理真实性的要求,所有模型均依据公开文献与飞行动力学原理实现,以增强仿真推演结果的工程可信度。
| 设计要素 | 实现方式 | 真实性体现 |
|---|---|---|
| 飞行动力学核心 | 调用 JSBSim 附带的 F-16 气动数据库 | 六自由度非线性运动方程求解器,气动系数由官方 F-16 模型查表提供 |
| 级联 PID 控制器 | 外环:高度差→体轴 z 分量→俯仰角(z2pitch)内环:俯仰角→升降舵( pitch2ele)滚转角→副翼( roll2ail)马赫数→油门( mach2thr) |
采用三回路级联控制架构,符合现代战斗机飞行控制系统的分层设计;控制增益经人工整定,在典型空战机动中响应平滑 |
| 控制指令限幅与保护 | 俯仰角、滚转角限幅(可解锁至 ±90°)、油门限幅 0.1~1.0 | 模拟了真实飞控的包线保护逻辑,防止指令超出飞行器物理极限;允许用户收紧限制保证平稳飞行,或放宽限制支持高G机动 |
| 雷达与探测模型 |
radarR 探测距离(蓝方优势 radarAngle 探测半角 |
距离与速度标准差呈非线性增长,模拟雷达回波信噪比随距离增加而衰减的效应,符合典型脉冲多普勒雷达的测距测速统计特性 |
| 设计要素 | 实现方式 | 真实性体现 |
|---|---|---|
| 高拟真气动引擎 | 加载 JSBSim 配置文件 aircraft/aim120c.xml,含完整气动力/力矩系数、推力表、质量特性 |
气动系数无量纲化,由 JSBSim 结合动压与参考面积(0.274 ft²)计算力与力矩;跨音速阻力峰值 CD0=0.45、升力斜率经马赫/攻角非线性校准、 |
| 固体燃料火箭发动机 |
<builduptime> 0.15 秒建压;推力表基于 112.4 lbs 推进剂、Isp 265 s、燃烧 7.75 s |
推力曲线呈现:0.15 s 建压 → 约 0.5 s 稳定高推力(3770 lbf)→ 随已燃质量平滑衰减至 7.75 s 耗尽,符合 HTPB 减面燃烧特性 |
| 高抛弹道 | 构造函数在载机俯仰角上叠加 5° 初始爬升角(min(90, 5 + pitch)),导弹发射后立即进入小角度爬升 |
将发动机能量转化为重力势能,降低超音速飞行的高动压与气动阻力,延长射程;末段俯冲释放势能,提升末端可用过载与拦截窗口 |
| 稳定增强与舵回路 | JSBSim 飞控配置三轴角速率阻尼(增益由 qbar-psf 调度);Python 端 roll2ail、az2ele 固定增益 PID 将过载指令转化为舵面指令 |
内回路阻尼增强短周期稳定性并抑制高频振荡;外部 PID 与阻尼器协同工作,避免全权自动驾驶仪在极限机动下指令饱和,更贴近真实导弹的“阻尼内回路 + 指令前置”架构 |
| 中制导:比例导引(PN) |
acmd = N * (v_rel - (v_rel·los)*los) / tgo(N=4) |
远距离通过最小机动消耗预测拦截点,控制指令平滑,符合能量管理原则 |
| 末制导:扩展比例导引(APN) | acmd += N/2 * min(1, tgo/2) * (a_rel - (a_rel·los)*los) |
在 PN 基础上补偿目标法向加速度,以对抗高G机动目标;系数 min(1, tgo/2) 避免末段指令过激 |
| 绝对状态卡尔曼滤波 |
Kalman 类实现 9 维(坐标、速度、加速度)Singer 模型,输出目标在 NED 绝对地理坐标系的平滑状态 |
见《绝对状态卡尔曼滤波器》章节 |
| 主动雷达导引头 |
radarR = 20 km,radarAngle = 20°,末制导(state==1)启用以截获目标 |
模拟“发射后不管”,末段自主搜索,参数基于公开资料 |
传统机载火控雷达的跟踪滤波器多建立在 弹体/载机相对坐标系 下,其缺陷明显:
- 相对状态随本机剧烈机动而快速变化,线性假设极易被破坏。
- 相对加速度难以精确计算和预测,非线性增强,容易发散。
- 预测步与本机姿态、速度高度耦合,小半径转弯时稳定性显著下降。
本滤波器直接在 NED 绝对地理坐标系 下估计目标的绝对坐标、绝对速度和绝对加速度,具有以下优点:
- 状态转移矩阵仅取决于目标自身的运动模型,与导弹/载机机动 完全解耦,线性度更好。
- 即使导弹进行急转弯等高过载机动,滤波器的预测步也不受影响,鲁棒性极高。
- 绝对状态便于融合与分发,可无缝支持数据链共享目标信息。
Singer 模型将目标运动加速度建模为一阶零均值马尔可夫过程。对于任一坐标轴,取状态
其中,
由于三个坐标轴在 Singer 模型下相互独立,完整 9 维状态转移矩阵与过程噪声协方差矩阵可通过 Kronecker 积 直接扩展:
其中,
使用 9 阶 Padé 近似 配合 缩放-平方(Scaling & Squaring) 技术计算矩阵指数,兼顾高精度与数值稳定性:
其中,k;通过 1-范数 自动确定缩放因子
由 Van Loan 定理,构造增广矩阵:
计算矩阵指数:
取出右上角分块,左乘
该方法无需数值积分,精度与
预测步完全独立于导弹运动,无需控制矩阵:
再调用 psd(P) 函数,保证
测量噪声协方差矩阵由距离和速度方差构成:
通过解线性方程组求卡尔曼增益,数值稳定性优于直接求逆:
更新后验状态,其中
Joseph 形式 协方差更新:
而非简化形式:psd(P) 函数,保证
Singer 模型的机动频率 seta(a) 方法动态调整
-
正常跟踪(雷达更新有效,数据链正常):保持
$\alpha$ = 0.1,目标加速度信息平滑可信。 -
信息缺失(雷达未更新或多帧数据链丢帧):
$\alpha$ 提高至 1.1,假定目标在丢失期间剧烈机动,历史加速度估计迅速衰减,防止滤波器过度依赖旧信息而导致发散。
该设计使滤波器在测量中断时仍能平稳过渡,保持稳健。
采用绝对状态卡尔曼滤波器后,制导系统可直接使用滤波器输出的目标平滑速度与加速度,带来以下增益:
- 基于平滑的速度信息,剩余飞行时间
tgo估计更准确。 - APN 的目标法向加速度补偿项更精确,对高G机动目标的拦截能力显著增强。
- 制导指令更平滑,避免噪声导致的导弹运动振荡,减少能量损耗。
综上,该滤波器在解耦性、数值精度、鲁棒性和制导协同性上均较传统相对坐标方案有本质提升。
- 学术研究:多智能体协同策略在感知受限条件下的 泛化性验证,环境非平稳性对博弈算法的影响分析。
- 学位论文研究:对比不同制导律或滤波算法在高拟真环境下的性能差异,飞行控制律的鲁棒性边界测试。
- 强化学习验证:检测策略是否过拟合于特定训练环境的“捷径特征”(shortcut features),也可改造为考虑观测不确定性的 高拟真 RL 训练 环境,在训练中学习应对非理想感知,提升鲁棒性。
- 教学演示:直观展示超视距空战中信息流传递与延迟的影响。
- 二次开发:允许修改气动与传感器模型,丰富飞行器选择,作为算法验证或空战游戏的底层基座。
本平台采用 MIT License。你可以自由使用、修改、分发代码,但需保留原作者版权声明。
本平台仅为学术研究与教育目的而开发,不包含任何国家秘密或受控数据。所有飞行器参数均来源于公开文献与开源社区推导,与真实装备可能存在差异,用户可自行校准。
- JSBSim 开发团队提供的强大飞行动力学引擎。
- 第十九届“挑战杯”竞赛组委会与中国航空工业集团沈阳飞机设计研究所提供的赛题启发。
- 社区公开的 AIM-120C 性能评估报告(AIM-120C-5 Performance Assessment for Digital Combat Simulation Enhancement, Rev 2)与 DCS World 相关气动研究,为本模型参数校准提供了关键参考。
如有问题或合作意向,欢迎通过 GitHub Issue 或邮件(15323122984@163.com)联系作者。