Repository navigation
Expand file tree
/
Copy pathexample.py
More file actions
124 lines (106 loc) · 4.12 KB
/
Copy pathexample.py
File metadata and controls
124 lines (106 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""火控计算单元使用示例与验证。"""
import math
from fire_control import (
FireControlInput,
Hyperparameters,
FireControlResult,
solve_elevation,
)
def print_result(label: str, result: FireControlResult) -> None:
status = "CONVERGED" if result.converged else "NOT CONVERGED"
print(f"\n{'='*60}")
print(f" {label}")
print(f"{'='*60}")
print(f" 状态: {status}")
print(f" 发射仰角: {result.elevation_angle_deg:.4f}°")
print(f" {result.elevation_angle_mil:.1f} mil")
print(f" 飞行时间: {result.time_of_flight:.2f} s")
print(f" 横向偏移: {result.lateral_drift:.2f} m")
print(f" 距离误差: {result.impact_distance_error:.4f} m")
# ============================================================
# 验证1: 无阻力条件下与解析解对比
# ============================================================
print("\n" + "#" * 60)
print("# 验证1: 无阻力 (Cd=0),与解析解对比")
print("#" * 60)
v0 = 800.0 # m/s
target_d = 20000.0 # m
g_std = 9.80665
# 解析解: θ = 0.5 * arcsin(g * d / v²)
analytical_angle = 0.5 * math.asin(g_std * target_d / v0**2)
print(f"\n解析解 (真空): {math.degrees(analytical_angle):.4f}°")
fci_vacuum = FireControlInput(
target_distance=target_d,
muzzle_velocity=v0,
projectile_mass=45.0,
projectile_diameter=0.155,
latitude=0.0, # 赤道,科氏力简化
wind_speed=0.0,
)
hp_vacuum = Hyperparameters(
drag_coefficient=0.0, # 无阻力
integration_dt=0.005,
solver_tolerance=0.05,
)
result_vacuum = solve_elevation(fci_vacuum, hp_vacuum)
print_result("数值解 (Cd=0, 赤道, 无风)", result_vacuum)
diff = abs(result_vacuum.elevation_angle_deg - math.degrees(analytical_angle))
print(f"\n 与解析解偏差: {diff:.4f}° {'PASS' if diff < 0.1 else 'FAIL'}")
# ============================================================
# 验证2: 155mm 榴弹炮标准条件
# ============================================================
print("\n\n" + "#" * 60)
print("# 验证2: 155mm 榴弹炮, 标准条件, 目标 15km")
print("#" * 60)
fci_std = FireControlInput(
target_distance=15000.0,
muzzle_velocity=800.0,
projectile_mass=45.0, # M107 HE 弹约 43.5~46 kg
projectile_diameter=0.155, # 155mm
temperature=288.15, # 15°C
pressure=101325.0, # 标准大气压
humidity=0.5,
altitude=200.0, # 海拔 200m
latitude=math.radians(40.0), # 北纬 40°
azimuth=math.radians(90.0), # 向东射击
wind_speed=5.0, # 5m/s 风
wind_direction=math.radians(270.0), # 西风(从西吹来)
)
# 使用默认超参数 (Cd=0.295,适用于标准榴弹外形)
# 注:流线型弹可调低至 0.15~0.20;钝头弹可调高至 0.35~0.50
hp_std = Hyperparameters()
result_std = solve_elevation(fci_std, hp_std)
print_result("低弹道解", result_std)
# 高弹道解
result_high = solve_elevation(fci_std, hp_std, high_trajectory=True)
print_result("高弹道解", result_high)
# ============================================================
# 验证3: 不同距离的射表
# ============================================================
print("\n\n" + "#" * 60)
print("# 验证3: 射表 (155mm, 标准条件, 不同距离)")
print("#" * 60)
print(f"\n {'距离(km)':>10} {'仰角(°)':>10} {'仰角(mil)':>12} {'飞行时间(s)':>12} {'横偏(m)':>10}")
print(f" {'-'*10} {'-'*10} {'-'*12} {'-'*12} {'-'*10}")
for dist_km in [3, 5, 8, 10, 12, 14, 16, 17]:
fci_table = FireControlInput(
target_distance=dist_km * 1000.0,
muzzle_velocity=800.0,
projectile_mass=45.0,
projectile_diameter=0.155,
temperature=288.15,
pressure=101325.0,
humidity=0.5,
altitude=200.0,
latitude=math.radians(40.0),
azimuth=math.radians(0.0), # 向北
wind_speed=0.0,
)
r = solve_elevation(fci_table, hp_std)
if r.converged:
print(
f" {dist_km:>10} {r.elevation_angle_deg:>10.2f} {r.elevation_angle_mil:>12.1f}"
f" {r.time_of_flight:>12.1f} {r.lateral_drift:>10.2f}"
)
else:
print(f" {dist_km:>10} ** 超出射程 **")