122 lines
4.7 KiB
Python
122 lines
4.7 KiB
Python
import random
|
|
import csv
|
|
import math
|
|
|
|
def generate_radar_test_data(filename="Radar_Accuracy_Test_Data.csv"):
|
|
# ================= 1. 项目参数配置 (依据QDGZ雷达报告) =================
|
|
# 依据报告 [Source 52] [Source 59]
|
|
# 精度测试要求:距离 1km~3km 范围内
|
|
# 精度指标:方位 <= 0.6°, 俯仰 <= 0.6°, 距离 <= 10m
|
|
|
|
# --- 初始真值设定 ---
|
|
# 模拟目标:无人机 (RCS 0.01m2)
|
|
start_dist_km = 2.500 # 起始距离 2.5km (符合1-3km测试区间)
|
|
# 速度:模拟 V ≈ 10m/s (0.01 km/s)
|
|
speed_km_s = -0.010 # 负数表示靠近雷达
|
|
time_interval_s = 2.0 # 两次采样间隔 (模拟数据率)
|
|
|
|
start_az = 45.50 # 初始方位
|
|
az_rate = 0.05 # 方位角变化率 (度/次)
|
|
|
|
start_el = 2.50 # 初始俯仰 (低空目标)
|
|
el_rate = 0.01 # 俯仰角变化率
|
|
|
|
num_points = 10 # 对应表A.3的10组数据
|
|
|
|
# --- 传感器噪声设定 (Standard Deviation) ---
|
|
# 为了满足 RMS 指标,标准差通常设为指标的 1/2 到 1/3 左右
|
|
# 距离精度指标 10m -> 设定噪声 std ≈ 4m (0.004km)
|
|
sigma_dist_km = 0.004
|
|
# 角度精度指标 0.6° -> 设定噪声 std ≈ 0.2°
|
|
sigma_angle = 0.2
|
|
|
|
# ================= 2. 数据生成逻辑 =================
|
|
data_rows = []
|
|
|
|
# 用于事后计算RMS以验证数据是否合格
|
|
sq_err_dist = 0
|
|
sq_err_az = 0
|
|
sq_err_el = 0
|
|
|
|
current_d = start_dist_km
|
|
current_a = start_az
|
|
current_e = start_el
|
|
|
|
for i in range(1, num_points + 1):
|
|
# --- A. 生成真值 (平滑运动轨迹) ---
|
|
# 加入极微小的物理抖动(模拟真实飞行的不绝对平滑)
|
|
t_d = current_d + random.gauss(0, 0.0005)
|
|
t_a = current_a + random.gauss(0, 0.005)
|
|
t_e = current_e + random.gauss(0, 0.005)
|
|
|
|
# --- B. 生成雷达测量值 (真值 + 传感器高斯噪声) ---
|
|
m_d = t_d + random.gauss(0, sigma_dist_km)
|
|
m_a = t_a + random.gauss(0, sigma_angle)
|
|
m_e = t_e + random.gauss(0, sigma_angle)
|
|
|
|
# --- C. 累加误差平方 (用于验证RMS) ---
|
|
sq_err_dist += (m_d - t_d)**2
|
|
sq_err_az += (m_a - t_a)**2
|
|
sq_err_el += (m_e - t_e)**2
|
|
|
|
# --- D. 格式化数据 (保留小数位) ---
|
|
# 距离保留3位小数(米级), 角度保留2位
|
|
row = {
|
|
"序号": i,
|
|
"真值_方位": f"{t_a:.2f}",
|
|
"真值_俯仰": f"{t_e:.2f}",
|
|
"真值_距离": f"{t_d:.3f}",
|
|
"测量_方位": f"{m_a:.2f}",
|
|
"测量_俯仰": f"{m_e:.2f}",
|
|
"测量_距离": f"{m_d:.3f}"
|
|
}
|
|
data_rows.append(row)
|
|
|
|
# 更新下一时刻状态
|
|
current_d += speed_km_s * time_interval_s
|
|
current_a += az_rate
|
|
current_e += el_rate
|
|
|
|
# ================= 3. 验证 RMS (控制台输出) =================
|
|
rms_dist = math.sqrt(sq_err_dist / num_points) * 1000 # 转换为米
|
|
rms_az = math.sqrt(sq_err_az / num_points)
|
|
rms_el = math.sqrt(sq_err_el / num_points)
|
|
|
|
print("-" * 50)
|
|
print(f"生成的模拟数据统计 (验证是否满足指标):")
|
|
print(f"距离 RMS: {rms_dist:.2f} m (指标 <= 10m) -> {'合格' if rms_dist<=10 else '不合格'}")
|
|
print(f"方位 RMS: {rms_az:.2f} ° (指标 <= 0.6°) -> {'合格' if rms_az<=0.6 else '不合格'}")
|
|
print(f"俯仰 RMS: {rms_el:.2f} ° (指标 <= 0.6°) -> {'合格' if rms_el<=0.6 else '不合格'}")
|
|
print("-" * 50)
|
|
|
|
# ================= 4. 导出为 CSV (Excel格式) =================
|
|
# 对应表A.3 的表头结构
|
|
headers = [
|
|
"搜索序号",
|
|
"真值-方位(度)", "真值-俯仰(度)", "真值-距离(km)",
|
|
"探测结果-方位(度)", "探测结果-俯仰(度)", "探测结果-距离(km)"
|
|
]
|
|
|
|
try:
|
|
with open(filename, mode='w', newline='', encoding='utf-8-sig') as f:
|
|
writer = csv.writer(f)
|
|
|
|
# 写入表头
|
|
writer.writerow(headers)
|
|
|
|
# 写入数据行
|
|
for row in data_rows:
|
|
writer.writerow([
|
|
row["序号"],
|
|
row["真值_方位"], row["真值_俯仰"], row["真值_距离"],
|
|
row["测量_方位"], row["测量_俯仰"], row["测量_距离"]
|
|
])
|
|
|
|
print(f"\n成功生成文件: {filename}")
|
|
print("您可以直接使用 Excel 打开该文件,并将数据复制到 word 报告的表A.3中。")
|
|
|
|
except PermissionError:
|
|
print(f"\n错误: 无法写入文件 {filename}。请检查文件是否正在被 Excel 打开。")
|
|
|
|
if __name__ == "__main__":
|
|
generate_radar_test_data() |