2. 基于视场约束的制导律性能评估

任务定义

本案例建立二维平面制导仿真环境,对比例导引律(PN)与带视场约束的偏置比例导引律(BPN-FOV)进行对比评估。给定初始弹目几何关系与目标机动模式,统计两种制导律在视场角限制(最大允许视场角 60°)下的脱靶量(终端相对距离最小值)及全程视场角变化曲线,用于量化视场约束对制导性能的影响。

仿真模型与制导律

采用质点动力学模型,导弹速度恒为 300 m/s,目标速度恒为 150 m/s。视线角速度由弹目相对运动计算,制导指令为法向加速度。比例导引律指令为 a_N = N·V_m·λ̇(N=4)。带视场约束的偏置比例导引律在 PN 基础上增加偏置项,当视场角接近约束边界时主动减小指令以限制视场角不超过 60°:

a_BPN = N·V_m·λ̇ + k·(σ_max - |σ|)·sign(σ)

其中 σ 为视场角(导弹速度矢量与视线夹角),σ_max = 60°,k 为偏置增益(取 2.0)。当 |σ| ≥ σ_max 时,偏置项强制将指令方向调整为减小 |σ| 的方向。

仿真代码(Python)

import numpy as np
from scipy.integrate import solve_ivp

# 常量
V_m = 300.0   # 导弹速度 m/s
V_t = 150.0   # 目标速度 m/s
N = 4.0       # 导航比
SIGMA_MAX = np.deg2rad(60.0)
K_BIAS = 2.0
T_END = 15.0

def fov_constraint(σ):
    """视场角约束:返回是否超出边界"""
    return abs(σ) > SIGMA_MAX

def guidance_pn(λ_dot):
    """比例导引指令"""
    return N * V_m * λ_dot

def guidance_bpn_fov(λ_dot, σ):
    """带视场约束的偏置比例导引"""
    a_pn = N * V_m * λ_dot
    if fov_constraint(σ):
        # 超出边界:强制减小视场角
        bias = -K_BIAS * np.sign(σ) * (abs(σ) - SIGMA_MAX)
    else:
        bias = K_BIAS * (SIGMA_MAX - abs(σ)) * np.sign(σ)
    return a_pn + bias

def simulate(guidance_func, label):
    """仿真弹目相对运动,返回时间序列与脱靶量"""
    # 初始条件:导弹在原点,目标在(5000, 3000),导弹初始航向角 30°
    # 状态: [x_m, y_m, θ_m, x_t, y_t, θ_t]
    x_m0, y_m0, θ_m0 = 0.0, 0.0, np.deg2rad(30.0)
    x_t0, y_t0, θ_t0 = 5000.0, 3000.0, np.deg2rad(150.0)
    state0 = [x_m0, y_m0, θ_m0, x_t0, y_t0, θ_t0]

    def rhs(t, s):
        x_m, y_m, θ_m, x_t, y_t, θ_t = s
        # 相对位置与视线角
        dx, dy = x_t - x_m, y_t - y_m
        r = np.hypot(dx, dy)
        λ = np.arctan2(dy, dx)
        # 视线角速度
        λ_dot = (dx * (V_t*np.sin(θ_t) - V_m*np.sin(θ_m)) -
                 dy * (V_t*np.cos(θ_t) - V_m*np.cos(θ_m))) / r**2
        # 视场角(导弹速度方向与视线夹角)
        σ = λ - θ_m
        # 归一化到 [-π, π]
        σ = (σ + np.pi) % (2*np.pi) - np.pi

        # 制导指令
        a_cmd = guidance_func(λ_dot, σ) if guidance_func.__name__ != 'guidance_pn' \
                else guidance_pn(λ_dot)
        # 限幅(最大法向过载 5g)
        a_max = 5.0 * 9.8
        a_cmd = np.clip(a_cmd, -a_max, a_max)

        # 状态导数
        dθ_m = a_cmd / V_m
        dθ_t = 0.0  # 目标匀速直线运动
        return [V_m*np.cos(θ_m), V_m*np.sin(θ_m), dθ_m,
                V_t*np.cos(θ_t), V_t*np.sin(θ_t), dθ_t]

    # 终止条件:相对距离小于 5m 或时间到
    def hit(t, s):
        return np.hypot(s[3]-s[0], s[4]-s[1]) - 5.0
    hit.terminal = True
    hit.direction = -1

    sol = solve_ivp(rhs, [0, T_END], state0, max_step=0.01,
                    events=hit, rtol=1e-6, atol=1e-8)
    ts = sol.t
    xs = sol.y
    # 相对距离序列
    r_seq = np.hypot(xs[3]-xs[0], xs[4]-xs[1])
    # 视场角序列
    λ_seq = np.arctan2(xs[4]-xs[0], xs[3]-xs[1])
    σ_seq = λ_seq - xs[2]
    σ_seq = (σ_seq + np.pi) % (2*np.pi) - np.pi
    miss = r_seq.min()
    return ts, σ_seq, miss, sol.success

# 运行仿真
ts_pn, sigma_pn, miss_pn, ok_pn = simulate(guidance_pn, "PN")
ts_bpn, sigma_bpn, miss_bpn, ok_bpn = simulate(guidance_bpn_fov, "BPN-FOV")

# 输出统计结果
print(f"PN 仿真收敛: {ok_pn}, 脱靶量: {miss_pn:.2f} m, 最大视场角: {np.degrees(np.max(np.abs(sigma_pn))):.2f}°")
print(f"BPN-FOV 仿真收敛: {ok_bpn}, 脱靶量: {miss_bpn:.2f} m, 最大视场角: {np.degrees(np.max(np.abs(sigma_bpn))):.2f}°")

运行与验证

依赖:Python 3.8+,NumPy,SciPy。

运行方式:将上述代码保存为 fov_eval.py,在终端执行 python fov_eval.py。

验证方法:观察程序输出的脱靶量与最大视场角数值。判定标准:

  • 两种制导律的仿真均返回 仿真收敛: True;
  • PN 的最大视场角应显著超过 60°(因无约束),而 BPN-FOV 的最大视场角应不超过 60°(允许 1° 数值容差);
  • BPN-FOV 的脱靶量可能大于 PN(因约束牺牲部分性能),但应保持有限值(通常小于 50 m),表明制导过程有效收敛。
视场角变化对比(PN vs BPN-FOV) 时间 (s) 视场角 (°) 0 30 60 -30 -60 0 2 4 6 8 10 +60° 约束 -60° 约束 PN(无约束) BPN-FOV(带约束) 注:曲线为示意性趋势展示,实际数值以代码运行输出为准

结果判定与说明

运行代码后,程序将打印两种制导律的脱靶量与最大视场角。预期可观察到:PN 的视场角在末段接近交汇时快速增大并超过 60° 约束,而 BPN-FOV 通过偏置项将视场角限制在边界内。脱靶量方面,BPN-FOV 因约束限制可能比 PN 略有增大,但仍在可接受范围内。若 BPN-FOV 的最大视场角超过 61° 或仿真未收敛,应检查偏置增益 K_BIAS 是否过小或限幅值是否过大。