计算火箭残骸音爆位置和时间的数学模型及Python代码

ChatGPT4o 使用 ChatGPT 4o 回答

问题:

建立数学模型,分析如果要精准确定空中单个残骸发生音爆时的位置坐标(经度、纬度、高程)和时间,至少需要布置几台监测设备?假设某火箭一级残骸分离后,在落点附近布置了7台监测设备,各台设备三维坐标(经度、纬度、高程)、音爆抵达时间(相对于观测系统时钟0时)如下表所示: 设备 经度(°) 纬度(°) 高程(m) 音爆抵达时间(s) A 110.241 27.204 824 100.767 B 110.780 27.456 727 112.220 C 110.712 27.785 742 188.020 D 110.251 27.825 850 258.985 E 110.524 27.617 786 118.443 F 110.467 27.921 678 266.871 G 110.047 27.121 575 163.024 从上表中选取合适的数据,计算残骸发生音爆时的位置和时间。 给出python代码

回答:

要确定空中单个残骸发生音爆时的位置坐标(经度、纬度、高程)和时间,我们可以使用多点定位技术。具体来说,我们可以利用音爆抵达不同监测设备的时间差来反推音爆发生的时间和位置。

假设音爆在某个位置 ((x, y, z)) 发生,音爆发生的时间为 (t_0)。音爆传播的速度为 (v)(通常取声速 (v \approx 343 , \text{m/s}))。对于每个监测设备 (i),其坐标为 ((x_i, y_i, z_i)),音爆抵达时间为 (t_i)。根据音爆传播的原理,有以下关系:

[ t_i = t_0 + \frac{\sqrt{(x - x_i)^2 + (y - y_i)^2 + (z - z_i)^2}}{v} ]

我们可以通过最小二乘法来求解这个非线性方程组。下面是使用Python进行求解的代码:

import numpy as np
from scipy.optimize import least_squares

# 声速 (m/s)
v = 343.0

# 监测设备的坐标和音爆抵达时间
data = {
    'A': {'lon': 110.241, 'lat': 27.204, 'alt': 824, 'time': 100.767},
    'B': {'lon': 110.780, 'lat': 27.456, 'alt': 727, 'time': 112.220},
    'C': {'lon': 110.712, 'lat': 27.785, 'alt': 742, 'time': 188.020},
    'D': {'lon': 110.251, 'lat': 27.825, 'alt': 850, 'time': 258.985},
    'E': {'lon': 110.524, 'lat': 27.617, 'alt': 786, 'time': 118.443},
    'F': {'lon': 110.467, 'lat': 27.921, 'alt': 678, 'time': 266.871},
    'G': {'lon': 110.047, 'lat': 27.121, 'alt': 575, 'time': 163.024}
}

# 将经纬度转换为笛卡尔坐标(假设地球是平的)
def latlon_to_cartesian(lon, lat, alt):
    R = 6371000  # 地球半径 (m)
    x = R * np.cos(np.radians(lat)) * np.cos(np.radians(lon))
    y = R * np.cos(np.radians(lat)) * np.sin(np.radians(lon))
    z = R * np.sin(np.radians(lat)) + alt
    return np.array([x, y, z])

# 监测设备的笛卡尔坐标和音爆抵达时间
positions = []
times = []
for key in data:
    pos = latlon_to_cartesian(data[key]['lon'], data[key]['lat'], data[key]['alt'])
    positions.append(pos)
    times.append(data[key]['time'])

positions = np.array(positions)
times = np.array(times)

# 残骸音爆位置和时间的初始猜测
initial_guess = np.array([positions[:, 0].mean(), positions[:, 1].mean(), positions[:, 2].mean(), times.mean()])

# 定义残差函数
def residuals(params, positions, times, v):
    x, y, z, t0 = params
    residuals = []
    for i in range(len(positions)):
        xi, yi, zi = positions[i]
        ti = times[i]
        predicted_time = t0 + np.sqrt((x - xi)**2 + (y - yi)**2 + (z - zi)**2) / v
        residuals.append(predicted_time - ti)
    return residuals

# 使用最小二乘法求解
result = least_squares(residuals, initial_guess, args=(positions, times, v))

# 输出结果
x, y, z, t0 = result.x
print(f"音爆发生位置: x={x:.2f}, y={y:.2f}, z={z:.2f}")
print(f"音爆发生时间: t0={t0:.2f} s")

# 将笛卡尔坐标转换回经纬度和高程
def cartesian_to_latlon(x, y, z):
    R = 6371000  # 地球半径 (m)
    lon = np.degrees(np.arctan2(y, x))
    hyp = np.sqrt(x**2 + y**2)
    lat = np.degrees(np.arctan2(z, hyp))
    alt = z - R * np.sin(np.radians(lat))
    return lon, lat, alt

lon, lat, alt = cartesian_to_latlon(x, y, z)
print(f"音爆发生位置: 经度={lon:.6f}°, 纬度={lat:.6f}°, 高程={alt:.2f} m")

这个代码首先将监测设备的经纬度和高程转换为笛卡尔坐标,然后使用最小二乘法来求解音爆发生的位置和时间。最后,将结果转换回经纬度和高程并输出。