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 知识体系总览
下面这张图,是我自己画的知识结构。每次做新项目,我都会先对着这张图检查一遍模型是否完整。
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