1. 导引头视场约束下的比例导引律设计

导引头视场约束下的比例导引律设计 学习卡片

任务定义

设计一种考虑导引头视场角约束的比例导引律,使导弹在攻击固定或匀速直线运动目标的过程中,目标始终保持在导引头视场角极限以内。要求:当视线角速率趋于零但目标仍处于视场边缘时,导引指令能够主动将目标拉回视场中心区域,避免因视场丢失导致制导中断。

制导律设计

传统比例导引律指令加速度为 a = N·V·λ̇,其中N为导航比,V为导弹速度,λ̇为视线角速率。该律在目标大机动或初始指向偏差较大时,可能导致视线角超出导引头视场极限±θ_max。本案例采用带视场约束项的修正比例导引律:

a_cmd = N·V·λ̇ + K·(θ_max² - λ²)·λ

其中λ为当前视线角,K为视场恢复增益。当|λ|接近θ_max时,第二项产生将视线角拉回零位的附加指令;当|λ|远小于θ_max时,该附加项趋近于零,不影响正常比例导引。该修正项在数学上等价于在视线角偏差上施加非线性比例反馈,保证视场约束始终满足。

仿真代码实现


import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt

# 参数定义
V_m = 300.0          # 导弹速度 m/s
V_t = 50.0           # 目标速度 m/s
N = 4.0              # 导航比
K = 0.02             # 视场恢复增益
theta_max = np.deg2rad(30.0)   # 导引头视场半角 rad

# 初始条件: [x_m, y_m, vx_m, vy_m, x_t, y_t, vx_t, vy_t]
# 导弹初始位置(0,0),速度方向沿x轴;目标初始位置(3000, 800),速度方向沿x轴
init_state = [0.0, 0.0, V_m, 0.0, 3000.0, 800.0, V_t, 0.0]

def guidance_law(t, state):
    """带视场约束的比例导引律"""
    x_m, y_m, vx_m, vy_m, x_t, y_t, vx_t, vy_t = state
    
    # 相对位置与速度
    rx = x_t - x_m
    ry = y_t - y_m
    r = np.sqrt(rx**2 + ry**2)
    
    # 视线角
    lam = np.arctan2(ry, rx)
    
    # 视线角速率
    v_rel_x = vx_t - vx_m
    v_rel_y = vy_t - vy_m
    lam_dot = (rx*v_rel_y - ry*v_rel_x) / (r**2)
    
    # 导弹速度方向角
    theta_m = np.arctan2(vy_m, vx_m)
    
    # 传统比例导引项
    a_png = N * V_m * lam_dot
    
    # 视场约束修正项
    a_fov = K * (theta_max**2 - lam**2) * lam
    
    # 总指令加速度(垂直于速度方向)
    a_cmd = a_png + a_fov
    
    # 状态导数
    dx_m = vx_m
    dy_m = vy_m
    dvx_m = -a_cmd * np.sin(theta_m)
    dvy_m = a_cmd * np.cos(theta_m)
    
    dx_t = vx_t
    dy_t = vy_t
    dvx_t = 0.0
    dvy_t = 0.0
    
    return [dx_m, dy_m, dvx_m, dvy_m, dx_t, dy_t, dvx_t, dvy_t]

def impact_condition(t, state):
    """脱靶量判定:相对距离小于10m视为命中"""
    x_m, y_m, _, _, x_t, y_t, _, _ = state
    return np.sqrt((x_t-x_m)**2 + (y_t-y_m)**2) - 10.0

impact_condition.terminal = True
impact_condition.direction = -1

# 仿真求解
t_span = (0, 30)
sol = solve_ivp(guidance_law, t_span, init_state, 
                events=impact_condition, max_step=0.01, rtol=1e-8, atol=1e-8)

# 提取结果
t = sol.t
x_m = sol.y[0]; y_m = sol.y[1]
x_t = sol.y[4]; y_t = sol.y[5]

# 计算视线角序列
los_angles = []
for i in range(len(t)):
    rx = x_t[i] - x_m[i]
    ry = y_t[i] - y_m[i]
    los_angles.append(np.arctan2(ry, rx))
los_angles = np.array(los_angles)

# 输出结果
print(f"仿真结束时间: {t[-1]:.2f}s")
print(f"最终脱靶量: {np.sqrt((x_t[-1]-x_m[-1])**2 + (y_t[-1]-y_m[-1])**2):.2f}m")
print(f"最大视线角: {np.max(np.abs(los_angles))*180/np.pi:.2f}°")
print(f"视场约束: ±{np.degrees(theta_max):.0f}°")
print(f"视场约束满足: {'是' if np.max(np.abs(los_angles)) <= theta_max else '否'}")

# 绘制结果
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

ax1.plot(x_m, y_m, 'b-', label='导弹轨迹')
ax1.plot(x_t, y_t, 'r--', label='目标轨迹')
ax1.plot(x_m[0], y_m[0], 'bo', label='导弹起点')
ax1.plot(x_t[0], y_t[0], 'ro', label='目标起点')
ax1.set_xlabel('x (m)'); ax1.set_ylabel('y (m)')
ax1.legend(); ax1.grid(True); ax1.set_title('弹道轨迹')
ax1.axis('equal')

ax2.plot(t, np.degrees(los_angles), 'b-', label='视线角')
ax2.axhline(y=np.degrees(theta_max), color='r', linestyle='--', label='视场边界')
ax2.axhline(y=-np.degrees(theta_max), color='r', linestyle='--')
ax2.set_xlabel('时间 (s)'); ax2.set_ylabel('视线角 (°)')
ax2.legend(); ax2.grid(True); ax2.set_title('视线角随时间变化')
plt.tight_layout()
plt.savefig('fov_guidance_result.png', dpi=150)
plt.show()

运行与验证

运行方式:将上述代码保存为 fov_guidance.py,在已安装 numpy、scipy、matplotlib 的Python环境中执行 python fov_guidance.py。

验证方法:观察终端输出的最大视线角是否小于等于30°视场半角,以及最终脱靶量是否小于10m。同时检查生成的 fov_guidance_result.png 图中视线角曲线是否始终位于±30°边界线以内。

判定标准:若最大视线角不超过θ_max且脱靶量小于10m,则证明该制导律在满足视场约束的前提下完成了精确拦截。可调整初始条件(如增大目标初始横向偏移)测试制导律在更严苛条件下的视场保持能力。

带视场约束的比例导引律结构框图 导弹运动学 速度/位置更新 目标运动 匀速直线 视线几何计算 λ, λ̇, r 视场约束判断 |λ| ≤ θ_max ? 比例导引项 N·V·λ̇ 视场修正项 K·(θ_max²-λ²)·λ Σ 位置 位置 λ̇ λ λ a_cmd 说明:视线角λ由弹目相对位置计算;当|λ|接近θ_max时,视场修正项产生恢复指令,将目标拉回视场中心。