4. 增广比例导引律设计
任务定义
针对匀速直线运动目标(可等效为机动目标的一种特例),设计增广比例导引律(Augmented Proportional Navigation, APN),在经典比例导引(PN)基础上引入目标加速度补偿项,以减小脱靶量。通过数值仿真对比PN与APN在目标常值机动情形下的制导性能,验证补偿项的有效性。
制导律设计
三维制导问题可解耦为两个相互垂直的平面内制导问题。以纵向平面为例,弹目相对运动方程为:
r_ddot = r·q_dot² + a_t_r - a_m_r
q_ddot = -(2·r_dot·q_dot)/r + a_t_q/r - a_m_q/r
其中r为弹目相对距离,q为视线角,a_t为目标的加速度在视线系下的分量,a_m为导弹加速度在视线系下的分量。经典PN制导律为:
a_m_q = N·V_c·q_dot
其中N为导航比(通常取3~5),V_c = -r_dot为接近速度。APN在PN基础上增加目标加速度前馈补偿项:
a_m_q = N·V_c·q_dot + (N/2)·a_t_q
补偿系数N/2来源于最优控制推导,可在目标常值机动时显著减小脱靶量。实际工程中目标加速度a_t_q需通过目标状态估计器获得,本案例假设其已知(或由理想测量给出),以聚焦制导律本身的性能验证。
仿真代码
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
# 物理常量与初始条件
V_m = 300.0 # 导弹速度 m/s
V_t = 150.0 # 目标速度 m/s
x_m0, y_m0 = 0.0, 0.0
x_t0, y_t0 = 3000.0, 1000.0
theta_m0 = np.deg2rad(0.0) # 导弹初始弹道角
theta_t0 = np.deg2rad(180.0) # 目标初始航向角(朝-x方向飞行)
a_t_const = 20.0 # 目标常值法向加速度 m/s^2(机动)
N = 3.0 # 导航比
# 状态: [x_m, y_m, vx_m, vy_m, x_t, y_t, vx_t, vy_t]
def apn_dynamics(t, state, use_apn):
x_m, y_m, vx_m, vy_m, x_t, y_t, vx_t, vy_t = state
# 相对运动参数
rx, ry = x_t - x_m, y_t - y_m
r = np.hypot(rx, ry)
if r < 1e-6:
return np.zeros(8)
# 视线角与视线角速率
q = np.arctan2(ry, rx)
v_rel_x = vx_t - vx_m
v_rel_y = vy_t - vy_m
# 视线坐标系基向量
e_r = np.array([np.cos(q), np.sin(q)])
e_q = np.array([-np.sin(q), np.cos(q)])
v_rel_r = v_rel_x * e_r[0] + v_rel_y * e_r[1]
v_rel_q = v_rel_x * e_q[0] + v_rel_y * e_q[1]
q_dot = v_rel_q / r
r_dot = v_rel_r
V_c = -r_dot
# 目标加速度(视线系)
a_t_vec = np.array([0.0, a_t_const]) # 惯性系下常值法向
a_t_q = a_t_vec[0] * e_q[0] + a_t_vec[1] * e_q[1]
# 导弹加速度指令(视线系法向)
if use_apn:
a_m_q = N * V_c * q_dot + (N / 2.0) * a_t_q
else:
a_m_q = N * V_c * q_dot
# 转换到惯性系
a_m_vec = a_m_q * e_q
# 目标加速度(惯性系,常值法向,垂直于目标速度方向)
# 目标速度方向角
theta_t = np.arctan2(vy_t, vx_t)
a_t_inertial = a_t_const * np.array([-np.sin(theta_t), np.cos(theta_t)])
# 状态导数
dx_m = vx_m
dy_m = vy_m
dvx_m = a_m_vec[0]
dvy_m = a_m_vec[1]
dx_t = vx_t
dy_t = vy_t
dvx_t = a_t_inertial[0]
dvy_t = a_t_inertial[1]
return [dx_m, dy_m, dvx_m, dvy_m, dx_t, dy_t, dvx_t, dvy_t]
def simulate(use_apn):
# 初始速度分量
vx_m0 = V_m * np.cos(theta_m0)
vy_m0 = V_m * np.sin(theta_m0)
vx_t0 = V_t * np.cos(theta_t0)
vy_t0 = V_t * np.sin(theta_t0)
state0 = [x_m0, y_m0, vx_m0, vy_m0, x_t0, y_t0, vx_t0, vy_t0]
# 事件:弹目距离小于阈值或导弹飞行时间上限
def hit_event(t, state):
x_m, y_m, _, _, x_t, y_t, _, _ = state
return np.hypot(x_t - x_m, y_t - y_m) - 0.5
hit_event.terminal = True
hit_event.direction = -1
t_span = (0, 15)
t_eval = np.linspace(0, 15, 3000)
sol = solve_ivp(apn_dynamics, t_span, state0, t_eval=t_eval,
events=hit_event, args=(use_apn,),
rtol=1e-8, atol=1e-10, max_step=0.01)
return sol
# 运行两种制导律仿真
sol_pn = simulate(use_apn=False)
sol_apn = simulate(use_apn=True)
# 计算脱靶量
def compute_miss(sol):
if sol.t.size == 0:
return None
x_m = sol.y[0]; y_m = sol.y[1]
x_t = sol.y[4]; y_t = sol.y[5]
r_final = np.hypot(x_t - x_m, y_t - y_m)
return r_final[-1]
miss_pn = compute_miss(sol_pn)
miss_apn = compute_miss(sol_apn)
print(f"PN 脱靶量: {miss_pn:.4f} m")
print(f"APN 脱靶量: {miss_apn:.4f} m")
# 绘制弹道轨迹
plt.figure(figsize=(10, 6))
plt.plot(sol_pn.y[0], sol_pn.y[1], 'b-', linewidth=1.5, label='PN')
plt.plot(sol_apn.y[0], sol_apn.y[1], 'r-', linewidth=1.5, label='APN')
plt.plot(sol_pn.y[4], sol_pn.y[5], 'g--', linewidth=1.5, label='Target')
plt.plot(x_m0, y_m0, 'ko', markersize=8)
plt.plot(x_t0, y_t0, 'k^', markersize=8)
plt.xlabel('x (m)'); plt.ylabel('y (m)')
plt.title('Trajectory Comparison: PN vs APN')
plt.legend(); plt.grid(True); plt.axis('equal')
plt.savefig('trajectory_compare.png', dpi=150)
plt.show()
仿真结果分析
运行上述代码,可得到PN与APN的弹道轨迹对比图。仿真终止条件为弹目距离小于0.5 m(视为命中)或飞行时间超过15 s。终端脱靶量由最后一个仿真时刻的弹目距离给出。
预期结果:目标以20 m/s²常值法向加速度机动时,PN制导将产生数米量级的脱靶量;而APN由于补偿了目标加速度,脱靶量显著减小(通常小于0.5 m)。具体数值取决于初始几何关系和导航比,但APN的脱靶量应明显小于PN,从而验证补偿项的有效性。
验证方法
运行仿真代码后,观察终端脱靶量输出与轨迹图。判定标准:
- APN脱靶量应小于PN脱靶量,且通常小于0.5 m(命中阈值);
- 轨迹图中APN弹道末端更接近目标轨迹,表明补偿项修正了过载需求;
- 可通过修改
a_t_const值(如设为0)验证:当目标无机动时,PN与APN性能应基本一致,此时补偿项趋近于零。
若需进一步验证不同机动幅值下的鲁棒性,可扫描a_t_const从0到50 m/s²,绘制脱靶量对比曲线,观察APN的脱靶量增长斜率明显低于PN。