3. 火箭动力学模型:推力模型、气动力模型、重力模型、质量变化模型

各位同学,咱们今天聊聊火箭的“身体语言”。

说白了,火箭飞行的本质,就是各种力在打架。推力想往上冲,重力往下拽,气动力在中间捣乱。你想想看,如果搞不清这些力怎么算,那制导算法就是空中楼阁。

我个人习惯,在写任何制导代码之前,先把这几个模型在脑子里过一遍。今天咱们就把它们拆开揉碎了讲清楚。

3.1 推力模型:发动机的脾气

推力是火箭唯一的主动力。它不简单,不是给个常数就完事了。

我见过不少新手,直接写 F = 100kN 完事。结果仿真跑出来,火箭飞得跟抽风一样。为什么?因为推力跟海拔、速度、节气门开度都有关系。

工程上常用的推力模型长这样:

# 推力模型(简化版)
def thrust_model(throttle, altitude, velocity):
    # 海平面推力
    F_sl = 1200.0  # kN
    # 真空推力(海拔修正)
    F_vac = F_sl + 10.0 * altitude / 10000.0  # 简单线性修正
    # 速度影响(动压损失)
    q = 0.5 * rho(altitude) * velocity**2
    F_loss = 0.02 * q * nozzle_area
    
    F_actual = throttle * (F_vac - F_loss)
    return F_actual

核心要点:

  • 真空推力 > 海平面推力(因为没大气背压)
  • 动压越大,推力损失越明显(喷管过膨胀/欠膨胀)
  • 节气门不是线性响应,我踩过这个坑

我的经验: 有一次做高超声速飞行器仿真,我偷懒用了常数推力模型。结果在跨音速段,动压剧烈变化,推力模型跟不上,仿真直接发散。后来老老实实加了动压修正项,才收敛。

3.2 气动力模型:看不见的阻力

气动力这东西,说白了就是火箭跟空气“打架”的结果。它包含升力、阻力、侧力,还有力矩。

对于常规火箭,我们最关心的是轴向阻力。公式很简单:

# 气动力模型
def aero_model(alpha, beta, Mach, altitude):
    # 动压
    q = 0.5 * rho(altitude) * velocity**2
    
    # 阻力系数(查表或拟合)
    Cd = lookup_Cd(Mach, alpha)  # 马赫数和攻角相关
    
    # 升力系数
    Cl = lookup_Cl(alpha, Mach)
    
    # 力和力矩
    D = q * S_ref * Cd  # 阻力
    L = q * S_ref * Cl  # 升力
    return D, L

嗯,这里要注意:气动系数不是常数。它随马赫数、攻角、侧滑角剧烈变化。尤其是跨音速段(Ma≈0.8~1.2),阻力系数会突然飙升,这叫“音障”。

避坑指南: 我曾经在写再入段制导算法时,用了线性插值的气动数据。结果在Ma=1.0附近,插值出来的阻力系数误差达到30%,导致落点偏差好几公里。后来改用三次样条插值才解决。

3.3 重力模型:地球的“手”

重力模型相对简单,但有个细节很多人忽略——重力加速度不是常数。

你想想看,火箭从地面飞到几百公里高空,g值从9.8降到8.5左右。如果全程用9.8,速度增量算出来会偏大,导致燃料浪费。

# 重力模型(考虑高度变化)
def gravity_model(altitude):
    R_e = 6371.0  # 地球半径 km
    g0 = 9.80665  # 海平面重力加速度 m/s^2
    
    g = g0 * (R_e / (R_e + altitude))**2
    return g

对于近地轨道任务,这个修正就够了。如果是深空任务,还得考虑J2项摄动,不过那是后话了。

3.4 质量变化模型:火箭在“瘦身”

火箭一边飞一边烧燃料,质量在快速下降。这个模型直接决定了推力加速度的变化。

质量变化率很简单:

# 质量变化模型
def mass_flow_rate(throttle):
    m_dot = throttle * m_dot_max  # 质量流率 kg/s
    return m_dot

# 实时质量更新
def update_mass(mass, m_dot, dt):
    mass_new = mass - m_dot * dt
    return mass_new

但有个坑:多级火箭的级间分离。分离瞬间,质量会跳变,推力也会突变。我见过有人把级间分离写成连续函数,结果仿真出来的加速度曲线平滑得不像话——那是不对的。

实际工程中的处理:

  • 一级工作段:质量线性下降
  • 级间分离:质量阶跃下降(抛弃结构质量)
  • 二级点火:推力阶跃变化

3.5 知识体系总览

下面这张图,是我自己画的知识结构。每次做新项目,我都会先对着这张图检查一遍模型是否完整。

火箭动力学模型 推力模型 • 海平面推力 vs 真空推力 • 动压损失修正 • 节气门响应特性 • 喷管膨胀比影响 气动力模型 • 阻力/升力/侧力 • 马赫数 & 攻角相关性 • 跨音速段特殊处理 • 气动系数插值方法 重力模型 • 高度修正(平方反比) • J2项摄动(深空任务) • 地球自转影响(科里奥利力) 质量变化模型 • 质量流率计算 • 级间分离阶跃变化 • 燃料消耗与加速度关系 四个模型共同构成完整的火箭动力学描述,缺一不可

3.6 模型集成:让它们一起工作

有了四个模型,怎么把它们捏到一起?我习惯用一个状态向量来管理:

# 火箭状态向量
state = {
    'position': [x, y, z],      # 位置
    'velocity': [vx, vy, vz],   # 速度
    'mass': m0,                 # 当前质量
    'throttle': 1.0,            # 节气门
    'attitude': [roll, pitch, yaw]  # 姿态角
}

# 动力学积分(简化版)
def rocket_dynamics(state, dt):
    # 1. 计算推力
    F_thrust = thrust_model(state['throttle'], state['position'][2], norm(state['velocity']))
    
    # 2. 计算气动力
    alpha = calc_alpha(state['velocity'], state['attitude'])
    D, L = aero_model(alpha, 0, calc_Mach(state['velocity']), state['position'][2])
    
    # 3. 计算重力
    g = gravity_model(state['position'][2])
    
    # 4. 计算质量变化
    m_dot = mass_flow_rate(state['throttle'])
    
    # 5. 合力 = 推力 - 阻力 - 重力
    F_total = F_thrust - D - state['mass'] * g
    
    # 6. 更新状态
    accel = F_total / state['mass']
    state['velocity'][2] += accel * dt
    state['position'][2] += state['velocity'][2] * dt
    state['mass'] -= m_dot * dt
    
    return state

调试技巧: 我每次写完动力学模型,都会先做“无控飞行”测试。就是不给任何制导指令,看火箭能不能按物理规律飞。如果出现加速度突变或者能量不守恒,那一定是模型有bug。

好了,四个模型都讲完了。记住一句话:模型精度决定了制导算法的上限。模型太粗糙,再好的算法也救不回来。


公众号:蓝海资料掘金营,微信deep3321