【RL+空战】学习记录03:基于JSBSim构造简易空空导弹模型,并结合python接口调用测试

JSBSim 导弹气动模型 xml 文件

xml 复制代码
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="http://jsbsim.sourceforge.net/JSBSim.xsl"?>

<!--
    JSBSim 飞行动力学模型配置文件
    模型名称: AIM-9
    用途: 高机动红外制导空空导弹的标准物理基线模型
    特点:
      - 无机翼气动布局 (小展弦比)
      - 高过载、高舵效
      - 火箭发动机推进
    注意: 所用数据并非真实数据,部分数据是接合 DeepSeek 生成的假数据,仅用于模拟学习
-->
<fdm_config name="AIM-9X" version="2.0" release="BETA"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd">

    <!-- ================= 文件头信息 ================= -->
    <fileheader>
        <!-- UP -->
        <author>昵称已被吞噬QAQ</author>

        <!-- 模型描述,JSBSim GUI / 日志中可见 -->
        <description>AIM-9X Standard Physics Baseline</description>
    </fileheader>

    <!-- ================= 几何与参考面积 ================= -->
    <!--
        metrics 定义的是"等效气动几何参数"
        并不一定是真实几何,而是用于气动力计算的参考量
    -->
    <metrics>
        <!-- 等效参考面积 Sw,用于升力 / 阻力 / 侧力 -->
        <wingarea  unit="FT2"> 0.85 </wingarea>

        <!-- 等效翼展 b,用于滚转 / 偏航力矩 -->
        <wingspan  unit="FT" > 0.92 </wingspan>

        <!-- 等效平均气动弦长 c̄,用于俯仰力矩 -->
        <chord     unit="FT" > 3.0  </chord>

        <!-- 等效水平尾翼面积(主要影响俯仰稳定) -->
        <htailarea unit="FT2"> 0.25 </htailarea>

        <!-- 等效垂直尾翼面积(主要影响偏航稳定) -->
        <vtailarea unit="FT2"> 0.25 </vtailarea>
    </metrics>

    <!-- ================= 质量与惯性 ================= -->
    <!--
        mass_balance 决定刚体动力学行为
        对导弹而言:
          - 转动惯量远比飞机重要
          - Iyy / Izz 决定过载能力和转弯半径
    -->
    <mass_balance>
        <!-- 空重 (不含燃料变化),单位磅 -->
        <emptywt unit="LBS" > 175.0 </emptywt>

        <!--
           转动惯量估算说明:
           - Ixx: 沿弹体轴线(滚转)
                  导弹细长,对滚转不敏感
           - Iyy/Izz: 俯仰 / 偏航惯量
                  决定最大角加速度和瞬态响应
           注意: 这部分是瞎给的,为了平衡一些东西进行了调整
        -->
        <ixx unit="SLUG*FT2"> 1600.0 </ixx>
        <iyy unit="SLUG*FT2"> 1600.0 </iyy>
        <izz unit="SLUG*FT2"> 1600.0 </izz>

        <!--
            质心位置
            这里设在机体系原点
            对导弹建模是常见简化
        -->
        <location name="CG" unit="IN">
            <x> 0 </x>
            <y> 0 </y>
            <z> 0 </z>
        </location>
    </mass_balance>

    <!-- ================= 地面接触模型 ================= -->
    <!--
        ground_reactions 仅用于:
          - 发射前
          - 地面测试
        对空中飞行基本无影响
    -->
    <ground_reactions>
        <contact type="STRUCTURE" name="Belly">

            <!-- 接触点位置(机腹) -->
            <location unit="IN">
                <x>60</x>
                <y>0</y>
                <z>-3</z>
            </location>

            <!-- 导弹无滑跑需求,摩擦设为 0 -->
            <static_friction> 0.0 </static_friction>
            <dynamic_friction> 0.0 </dynamic_friction>

            <!-- 接触弹簧刚度 -->
            <spring_coeff unit="LBS/FT"> 1000.0 </spring_coeff>

            <!-- 接触阻尼,防止数值震荡 -->
            <damping_coeff unit="LBS/FT/SEC"> 100.0 </damping_coeff>
        </contact>
    </ground_reactions>

    <!-- ================= 外部作用力 ================= -->
    <!--
        external_reactions 用于:
          - 火箭发动机
          - 推进器
          - 非气动外力
    -->
    <external_reactions>

        <!-- 火箭推力 -->
        <force name="RocketThrust" frame="BODY">

            <!-- 推力作用点,靠近尾部 -->
            <location unit="IN">
                <x>118</x>
                <y>0</y>
                <z>0</z>
            </location>

            <!-- 推力方向:沿机体 X 正方向 -->
            <direction>
                <x>1</x>
                <y>0</y>
                <z>0</z>
            </direction>

            <!--
                推力时间函数:
                  - 恒定推力
                  - 5 秒后自动归零
            -->
            <function>
                <product>
                    <!-- 推力大小 (lbs) -->
                    <value> 2500.0 </value>

                    <!-- 燃烧时间限制 -->
                    <lt>
                        <property>simulation/sim-time-sec</property>
                        <value> 5.0 </value>
                    </lt>
                </product>
            </function>
        </force>
    </external_reactions>

    <!-- ================= 飞控系统 (FCS) ================= -->
    <!--
        飞控系统职责:
          - 将归一化指令 (-1 ~ 1)
          - 映射为真实舵面偏转角 (rad)
    -->
    <flight_control name="FCS">

        <!-- 俯仰控制通道 -->
        <channel name="Pitch">
            <pure_gain name="Elevator Control">
                <input> fcs/elevator-cmd-norm </input>
                <gain> 0.2 </gain>
                <output> fcs/elevator-pos-rad </output>
            </pure_gain>
        </channel>

        <!-- 滚转控制通道 -->
        <channel name="Roll">
            <pure_gain name="Aileron Control">
                <input> fcs/aileron-cmd-norm </input>
                <gain> 0.01 </gain>
                <output> fcs/left-aileron-pos-rad </output>
            </pure_gain>
        </channel>

        <!-- 偏航控制通道 -->
        <channel name="Yaw">
            <pure_gain name="Rudder Control">
                <input> fcs/rudder-cmd-norm </input>
                <gain> 0.2 </gain>
                <output> fcs/rudder-pos-rad </output>
            </pure_gain>
        </channel>
    </flight_control>

    <!-- ================= 气动力模型 ================= -->
    <!--
        aerodynamics:
          - 所有气动力/力矩均通过 q̄*S*(...) 构造
          - 系数已"物理化",避免纯数值炸飞
    -->
    <aerodynamics>

        <!-- ========== 升力轴 ========== -->
        <axis name="LIFT">

            <!-- α 升力 -->
            <function name="aero/coefficient/CLalpha">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>aero/alpha-rad</property>
                    <!-- 高升力斜率,适配高迎角导弹 -->
                    <value> 12.0 </value>
                </product>
            </function>

            <!-- 升降舵升力 -->
            <function name="aero/coefficient/CLde">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>fcs/elevator-pos-rad</property>
                    <value> 3.0 </value>
                </product>
            </function>
        </axis>

        <!-- ========== 阻力轴 ========== -->
        <axis name="DRAG">

            <!-- 基础阻力,随马赫数变化 -->
            <function name="aero/coefficient/CD0">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <table>
                        <independentVar lookup="row">velocities/mach</independentVar>
                        <!--
                            体现跨音阻力突增
                        -->
                        <tableData>
                            0.00  0.04
                            0.80  0.04
                            0.95  0.09
                            1.05  0.10
                            1.20  0.08
                            2.00  0.06
                            4.00  0.05
                        </tableData>
                    </table>
                </product>
            </function>

            <!-- 诱导阻力 ~ α² -->
            <function name="aero/coefficient/CDi">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>aero/alpha-rad</property>
                    <property>aero/alpha-rad</property>
                    <value> 3.0 </value>
                </product>
            </function>
        </axis>

        <!-- ========== 侧向力 ========== -->
        <axis name="SIDE">

            <!-- 侧滑稳定 -->
            <function name="aero/coefficient/CYbeta">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>aero/beta-rad</property>
                    <value> -12.0 </value>
                </product>
            </function>

            <!-- 偏航舵侧力 -->
            <function name="aero/coefficient/CYdr">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>fcs/rudder-pos-rad</property>
                    <value> 3.0 </value>
                </product>
            </function>
        </axis>

        <!-- ========== 滚转力矩 ========== -->
        <axis name="ROLL">

            <!-- 滚转阻尼 -->
            <function name="aero/coefficient/Clp">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/bw-ft</property>
                    <property>aero/bi2vel</property>
                    <property>velocities/p-aero-rad_sec</property>
                    <value> -20.0 </value>
                </product>
            </function>

            <!-- 副翼滚转 -->
            <function name="aero/coefficient/Clda">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/bw-ft</property>
                    <property>fcs/left-aileron-pos-rad</property>
                    <value> 10.0 </value>
                </product>
            </function>
        </axis>

        <!-- ========== 俯仰力矩(核心) ========== -->
        <axis name="PITCH">

            <!-- 静稳定 -->
            <function name="aero/coefficient/Cmalpha">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/cbarw-ft</property>
                    <property>aero/alpha-rad</property>
                    <value> -8.0 </value>
                </product>
            </function>

            <!-- 升降舵俯仰 -->
            <function name="aero/coefficient/Cmde">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/cbarw-ft</property>
                    <property>fcs/elevator-pos-rad</property>
                    <value> -15.0 </value>
                </product>
            </function>

            <!-- 俯仰阻尼 -->
            <function name="aero/coefficient/Cmq">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/cbarw-ft</property>
                    <property>aero/ci2vel</property>
                    <property>velocities/q-aero-rad_sec</property>
                    <value> -100.0 </value>
                </product>
            </function>
        </axis>

        <!-- ========== 偏航力矩 ========== -->
        <axis name="YAW">

            <!-- 方向稳定 -->
            <function name="aero/coefficient/Cnbeta">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/bw-ft</property>
                    <property>aero/beta-rad</property>
                    <value> 8.0 </value>
                </product>
            </function>

            <!-- 偏航舵 -->
            <function name="aero/coefficient/Cndr">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/bw-ft</property>
                    <property>fcs/rudder-pos-rad</property>
                    <value> -15.0 </value>
                </product>
            </function>

            <!-- 偏航阻尼 -->
            <function name="aero/coefficient/Cnr">
                <product>
                    <property>aero/qbar-psf</property>
                    <property>metrics/Sw-sqft</property>
                    <property>metrics/bw-ft</property>
                    <property>aero/bi2vel</property>
                    <property>velocities/r-aero-rad_sec</property>
                    <value> -100.0 </value>
                </product>
            </function>
        </axis>

    </aerodynamics>
</fdm_config>

测试用 Python 代码

python 复制代码
import jsbsim
import os
import math
import numpy as np

def run_straight_test():
    root_dir = os.path.abspath(os.getcwd())
    fdm = jsbsim.FGFDMExec(root_dir)
    fdm.set_aircraft_path(os.path.join(root_dir, "aircraft"))

    fdm.load_model("aim9x")

    fdm['ic/lat-gc-deg'] = 37.2
    fdm['ic/long-gc-deg'] = -115.8
    fdm['ic/h-sl-ft'] = 15000.0
    fdm['ic/psi-true-deg'] = 90.0
    fdm['ic/theta-deg'] = 0.0
    
    target_init_vel = 928.0 
    fdm['ic/u-fps'] = target_init_vel
    
    fdm.run_ic()

    # ACMI
    acmi_file = open("straight_test.acmi", "w", encoding="utf-8")
    acmi_file.write("FileType=text/acmi/tacview\n")
    acmi_file.write("FileVersion=2.1\n")
    acmi_file.write("0,ReferenceTime=2023-10-27T12:00:00Z\n")
    acmi_file.write("1,Name=AIM-9X-Basic,Type=Missile,Color=White\n")
    
    dt = 1 / 60
    fdm.set_dt(dt)
    total_times = 180

    print(
        f"{'Time':>5} | {'Mach':>4} | {'Alt':>6} | "
        f"{'Pitch':>6} | {'AoA':>6} | "
        f"{'Nx':>6} | {'Ny':>6} | {'Nz':>6} | {'NT':>6}"
    )
    print("-" * 80)

    for i in range(int(total_times / dt)): 
        t = fdm['simulation/sim-time-sec']

        # === 测试逻辑 ===
        if t < 5.0:
            cmd = [0.0, 0.0, 0.0] # 平飞(发动机点火加速阶段)
        elif t < 10.0:
            cmd = [-0.2, 0.0, 1.0]  # 测试偏航(左)
        elif t < 15.0:
            cmd = [-0.2, 0.0, -1.0] # 测试偏航(右)
        elif t < 24.0:
            cmd = [-0.2, 0.0, 0.0] # 测试俯仰(上)
        elif t < 40.0:
            cmd = [0.2, 0.0, 0.0] # 测试俯仰(下,拉平)
        elif t < 68:
            cmd = [-0.2, 0.0, 1.0] # 测试偏航(左)
        elif t < 78:
            cmd = [-0.2, 0.0, -1.0] # 测试偏航(右)
        elif t < 120:
            cmd = [0.2, 0.0, 0.0] # 测试俯仰(拉平)
        elif t < 150:
            cmd = [1.0, 1.0, -1.0] # 测试滚转
        else:
            cmd = [-1.0, 0.0, 0.0]  # 失速,触底爆炸,boom!!!

        cmd = np.array(cmd)
        fdm['fcs/elevator-cmd-norm'] = cmd[0]
        fdm['fcs/aileron-cmd-norm'] = cmd[1]
        fdm['fcs/rudder-cmd-norm'] = cmd[2]

        fdm.run()
        
        # 记录
        if i % 20 == 0:
            mach = fdm['velocities/mach']
            alt = fdm['position/h-sl-ft']
            pitch = fdm['attitude/theta-deg']
            aoa = fdm['aero/alpha-deg']

            nx = fdm['accelerations/n-pilot-x-norm']
            ny = fdm['accelerations/n-pilot-y-norm']
            nz = fdm['accelerations/n-pilot-z-norm']
            
            n_total = math.sqrt(nx*nx + ny*ny + nz*nz)

            print(
                f"{t:5.1f} | {mach:4.2f} | {alt:6.0f} | "
                f"{pitch:6.1f} | {aoa:6.1f} | "
                f"{nx:6.1f} | {ny:6.1f} | {nz:6.1f} | {n_total:6.1f}"
            )
            
        # ACMI
        m_lon = fdm['position/long-gc-deg']
        m_lat = fdm['position/lat-gc-deg']
        m_alt = fdm['position/h-sl-meters']
        roll = fdm['attitude/phi-deg']
        pitch = fdm['attitude/theta-deg']
        yaw = fdm['attitude/psi-deg']
        
        acmi_file.write(f"#{t:.2f}\n")
        acmi_file.write(f"1,T={m_lon:.7f}|{m_lat:.7f}|{m_alt:.2f}|{roll:.2f}|{pitch:.2f}|{yaw:.2f}\n")

if __name__ == "__main__":
    run_straight_test()

TacView 可视化

相关推荐
DX_水位流量监测14 小时前
大坝安全监测之渗流渗压位移监测设备技术解析
大数据·运维·服务器·网络·人工智能·安全
短剑重铸之日14 小时前
《SpringBoot4.0初识》第一篇:前瞻与思想
java·开发语言·后端·spring·springboot4.0
Yeats_Liao14 小时前
MindSpore开发之路(二十四):MindSpore Hub:快速复用预训练模型
人工智能·分布式·神经网络·机器学习·个人开发
我想我不够好。14 小时前
学到的知识点 1.8
学习
2501_9418779814 小时前
从配置热更新到运行时自适应的互联网工程语法演进与多语言实践随笔分享
开发语言·前端·python
老周聊架构14 小时前
基于YOLOv8-OBB旋转目标检测数据集与模型训练
人工智能·yolo·目标检测
lsx20240614 小时前
Python 运算符详解
开发语言
酩酊仙人14 小时前
fastmcp构建mcp server和client
python·ai·mcp
AKAMAI14 小时前
基准测试:Akamai云上的NVIDIA RTX Pro 6000 Blackwell
人工智能·云计算·测试