SXXXXXXX_ScenarioSimulator/scenario_simulator/utils/radar_math.py
2025-09-30 13:06:27 +02:00

121 lines
3.8 KiB
Python

"""
Utility functions for radar-related mathematical calculations.
"""
import numpy as np
from scipy.constants import c
# Conversion Constants
METERS_PER_NAUTICAL_MILE = 1852.0
METERS_PER_SECOND_TO_KNOTS = 1.94384
DEGREES_TO_RADIANS = np.pi / 180.0
RADIANS_TO_DEGREES = 180.0 / np.pi
def calculate_max_unambiguous_range(prf: float) -> float:
"""
Calculates the maximum unambiguous range for a given PRF.
Args:
prf: Pulse Repetition Frequency in Hertz (Hz).
Returns:
The maximum unambiguous range in meters (m).
"""
if prf <= 0:
return float('inf')
return c / (2 * prf)
def calculate_max_unambiguous_velocity(carrier_frequency: float, prf: float) -> float:
"""
Calculates the maximum unambiguous velocity for a given radar configuration.
Args:
carrier_frequency: Carrier frequency in Hertz (Hz).
prf: Pulse Repetition Frequency in Hertz (Hz).
Returns:
The maximum unambiguous (Nyquist) velocity in m/s.
"""
if carrier_frequency <= 0:
return float('inf')
wavelength = c / carrier_frequency
return (prf * wavelength) / 4
def calculate_dwell_time(beamwidth_deg: float, scan_speed_deg_s: float) -> float:
"""
Calculates the time a target spends within the antenna's beam.
Args:
beamwidth_deg: The 3dB beamwidth of the antenna in degrees.
scan_speed_deg_s: The angular scan speed of the antenna in degrees/sec.
Returns:
The dwell time in seconds (s).
"""
if scan_speed_deg_s <= 0:
return float('inf') # Staring mode
return beamwidth_deg / scan_speed_deg_s
def calculate_pulses_on_target(dwell_time_s: float, prf: float) -> int:
"""
Calculates the number of pulses that hit a target during the dwell time.
Args:
dwell_time_s: The dwell time in seconds.
prf: The Pulse Repetition Frequency in Hz.
Returns:
The number of pulses hitting the target.
"""
if np.isinf(dwell_time_s):
return -1 # Represents continuous illumination (staring)
return int(dwell_time_s * prf)
def calculate_gaussian_gain(angle_off_boresight_deg: float, beamwidth_deg: float) -> float:
"""
Calculates antenna gain based on a Gaussian beam shape model.
This models the two-way (transmit and receive) gain pattern.
Args:
angle_off_boresight_deg: Angle between target and antenna centerline (degrees).
beamwidth_deg: The 3dB one-way beamwidth of the antenna in degrees.
Returns:
A dimensionless gain factor (from 0.0 to 1.0).
"""
# The standard deviation (sigma) of the Gaussian beam is related to the 3dB beamwidth
sigma = beamwidth_deg / (2 * np.sqrt(2 * np.log(2)))
# We use angle^2 / (2 * sigma^2) for the one-way gain pattern.
# This provides a more realistic falloff than a squared (two-way) model.
gain = np.exp(-(angle_off_boresight_deg**2) / (2 * sigma**2))
return gain
# --- Unit Conversion Functions ---
def meters_to_nm(meters: float) -> float:
"""Converts meters to nautical miles."""
return meters / METERS_PER_NAUTICAL_MILE
def nm_to_meters(nm: float) -> float:
"""Converts nautical miles to meters."""
return nm * METERS_PER_NAUTICAL_MILE
def mps_to_knots(mps: float) -> float:
"""Converts meters per second to knots."""
return mps * METERS_PER_SECOND_TO_KNOTS
def knots_to_mps(knots: float) -> float:
"""Converts knots to meters per second."""
return knots / METERS_PER_SECOND_TO_KNOTS
def mps_to_kmh(mps: float) -> float:
"""Converts meters per second to kilometers per hour."""
return mps * 3.6
def deg_to_rad(deg: float) -> float:
"""Converts degrees to radians."""
return deg * DEGREES_TO_RADIANS
def rad_to_deg(rad: float) -> float:
"""Converts radians to degrees."""
return rad * RADIANS_TO_DEGREES