3、比例导引法(PN)及其最优性:纯比例导引、增广比例导引、PN与最优控制的关系

比例导引法,说白了就是导弹制导领域最经典、最实用的方法之一。我入行那会儿,第一个接触的制导律就是它。你想想看,一个简单的比例关系,就能让导弹精准地命中目标,这背后其实藏着不少数学和控制的智慧。

这一节,咱们就聊聊纯比例导引、增广比例导引,以及它们和最优控制之间那些有意思的联系。

3.1 纯比例导引(PPN)

纯比例导引的核心思想很简单:导弹的转弯角速度,与视线角速度成正比。用公式表达就是:

a_cmd = N * V_m * λ_dot

其中:

  • a_cmd —— 指令加速度(垂直于视线方向)
  • N —— 导航比,通常取3~5
  • V_m —— 导弹速度
  • λ_dot —— 视线角速度

嗯,这里要注意:N的取值很关键。我见过不少新手上来就取N=2,结果弹道振荡得厉害。我个人习惯,对付机动性不强的目标,N取3就够了;要是目标会做高机动,我会把N调到4甚至5。

核心要点:纯比例导引的本质,就是让导弹的加速度指令始终与视线角速度保持线性关系。这个关系虽然简单,但在工程上极其鲁棒。

为什么会这样?因为视线角速度直接反映了目标相对于导弹的运动趋势。当视线角速度为零时,说明导弹正对着目标飞,这时候不需要额外的机动。反之,如果视线角速度很大,说明目标在横向移动,导弹就得赶紧转弯跟上。

3.2 增广比例导引(APN)

纯比例导引有个明显的短板——它假设目标不做机动。但在实战中,目标哪会乖乖让你打?于是就有了增广比例导引。

APN在PPN的基础上,增加了一个补偿项:

a_cmd = N * V_m * λ_dot + (N/2) * a_T

这里的a_T是目标加速度的估计值。说白了,就是提前把目标可能的机动考虑进去。

我在项目中遇到过这样的情况:用纯比例导引打一个做5g机动的靶机,脱靶量总是偏大。后来换成增广比例导引,脱靶量直接降了一个数量级。当然,前提是你能比较准确地估计出目标的加速度。

实战技巧:目标加速度的估计,通常可以通过卡尔曼滤波或者α-β滤波器来实现。我个人建议,如果目标机动频率不高,用α-β滤波器就足够了,计算量小,实时性好。

3.3 PN与最优控制的关系

你可能要问:比例导引这么简单,它和最优控制能扯上什么关系?

其实,在一定的假设条件下,比例导引就是最优控制问题的解析解。我们来推导一下。

考虑一个线性化的追逃问题,性能指标是:

J = ∫(0 to t_f) a_cmd² dt

也就是最小化控制能量的消耗。同时,终端约束是零脱靶量。

用最优控制理论(庞特里亚金极小值原理)求解,你会发现:最优控制律恰好就是比例导引的形式。导航比N的取值,与剩余飞行时间有关。

关键结论:当目标不做机动、导弹速度恒定、且视线角较小时,比例导引就是能量最优的制导律。这就是为什么PN在工程上如此受欢迎——它既简单,又在某种意义上是最优的。

我记得有一次做仿真对比,把PN和用直接法求解的最优制导律放在一起比较。结果发现,在大多数场景下,PN的能耗只比最优解高出不到5%。你想想看,一个这么简单的比例关系,居然能接近理论最优,这本身就是件很神奇的事。

3.4 代码实现示例

下面给出一段Python代码,实现纯比例导引和增广比例导引的仿真。代码不长,但核心逻辑都在里面了。

import numpy as np
import matplotlib.pyplot as plt

def ppn_guidance(lambda_dot, V_m, N=3):
    """
    纯比例导引
    lambda_dot: 视线角速度 (rad/s)
    V_m: 导弹速度 (m/s)
    N: 导航比
    """
    a_cmd = N * V_m * lambda_dot
    return a_cmd

def apn_guidance(lambda_dot, V_m, a_T, N=3):
    """
    增广比例导引
    a_T: 目标加速度估计 (m/s^2)
    """
    a_cmd = N * V_m * lambda_dot + (N/2) * a_T
    return a_cmd

# 仿真参数
dt = 0.01  # 时间步长
t_total = 10.0  # 总仿真时间
steps = int(t_total / dt)

# 初始状态
missile_pos = np.array([0.0, 0.0])
target_pos = np.array([1000.0, 500.0])
missile_vel = np.array([300.0, 0.0])
target_vel = np.array([-50.0, 0.0])

# 存储轨迹
traj_missile = [missile_pos.copy()]
traj_target = [target_pos.copy()]

for i in range(steps):
    # 计算视线角和视线角速度
    r_vec = target_pos - missile_pos
    r = np.linalg.norm(r_vec)
    lambda_angle = np.arctan2(r_vec[1], r_vec[0])
    
    # 这里简化处理,实际中需要用滤波器估计lambda_dot
    lambda_dot = (target_vel[1] - missile_vel[1]) / r
    
    # 计算指令加速度
    V_m = np.linalg.norm(missile_vel)
    a_cmd = ppn_guidance(lambda_dot, V_m, N=3)
    
    # 更新导弹状态
    missile_vel[1] += a_cmd * dt
    missile_pos += missile_vel * dt
    
    # 更新目标状态(匀速直线运动)
    target_pos += target_vel * dt
    
    # 记录轨迹
    traj_missile.append(missile_pos.copy())
    traj_target.append(target_pos.copy())
    
    # 判断是否命中
    if r < 5.0:
        print(f"命中!时间: {i*dt:.2f}s")
        break

# 绘制轨迹
traj_missile = np.array(traj_missile)
traj_target = np.array(traj_target)

plt.figure(figsize=(10, 6))
plt.plot(traj_missile[:,0], traj_missile[:,1], 'b-', label='导弹轨迹')
plt.plot(traj_target[:,0], traj_target[:,1], 'r--', label='目标轨迹')
plt.xlabel('X (m)')
plt.ylabel('Y (m)')
plt.title('比例导引法仿真')
plt.legend()
plt.grid(True)
plt.show()

注意:上面的代码中,视线角速度的计算做了简化处理。在实际工程中,视线角速度通常通过滤波器(如卡尔曼滤波)从测量数据中估计得到,直接差分会导致噪声放大。我曾经因为这个问题吃过亏,仿真里跑得好好的,一上硬件就炸了。

3.5 知识体系图

下面这张图,帮你理清比例导引法的知识脉络:

比例导引法(PN)知识体系 比例导引法(PN) 纯比例导引(PPN) 增广比例导引(APN) 与最优控制的关系 a_cmd = N * V_m * λ_dot 导航比N通常取3~5 a_cmd = N*V_m*λ_dot + (N/2)*a_T 需估计目标加速度a_T 最小化控制能量 J=∫a²dt 特定条件下PN即为最优解 工程实用性与理论最优性的完美结合

从这张图可以看得很清楚:比例导引法从最简单的纯比例形式出发,通过引入目标加速度补偿得到增广形式,再往深处挖,它和最优控制理论有着内在的联系。我个人觉得,理解这三者之间的关系,是掌握制导律设计的关键一步。

我的建议:如果你刚开始学制导律,先把纯比例导引吃透。仿真跑熟了,再考虑增广和最优控制的问题。别一上来就搞复杂的,容易把自己绕进去。


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