Delete 8_Utils directory

This commit is contained in:
NawfalMotii79
2026-04-02 01:03:40 +01:00
committed by GitHub
parent cfbe6d2bd4
commit 81bf4cabbb
22 changed files with 0 additions and 19288 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 980 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

-188
View File
@@ -1,188 +0,0 @@
import numpy as np
import pandas as pd
import math
def generate_radar_csv(filename="pulse_compression_output.csv"):
"""
Generate realistic radar CSV data for testing the Python GUI
"""
# Radar parameters matching your testbench
num_long_chirps = 16
num_short_chirps = 16
samples_per_chirp = 512 # Reduced for manageable file size
fs_adc = 400e6 # 400 MHz ADC
timestamp_ns = 0
# Target parameters
targets = [
{'range': 3000, 'velocity': 25, 'snr': 30, 'azimuth': 10, 'elevation': 5}, # Fast moving target
{'range': 5000, 'velocity': -15, 'snr': 25, 'azimuth': 20, 'elevation': 2}, # Approaching target
{'range': 8000, 'velocity': 5, 'snr': 20, 'azimuth': 30, 'elevation': 8}, # Slow moving target
{'range': 12000, 'velocity': -8, 'snr': 18, 'azimuth': 45, 'elevation': 3}, # Distant target
]
# Noise parameters
noise_std = 5
clutter_std = 10
data = []
chirp_number = 0
# Generate Long Chirps (30µs duration equivalent)
print("Generating Long Chirps...")
for chirp in range(num_long_chirps):
for sample in range(samples_per_chirp):
# Base noise
i_val = np.random.normal(0, noise_std)
q_val = np.random.normal(0, noise_std)
# Add clutter (stationary targets)
clutter_range = 2000 # Fixed clutter at 2km
if sample < 100: # Simulate clutter in first 100 samples
i_val += np.random.normal(0, clutter_std)
q_val += np.random.normal(0, clutter_std)
# Add moving targets with Doppler shift
for target in targets:
# Calculate range bin (simplified)
range_bin = int(target['range'] / 20) # ~20m per bin
doppler_phase = 2 * math.pi * target['velocity'] * chirp / 100 # Doppler phase shift
# Target appears around its range bin with some spread
if abs(sample - range_bin) < 10:
# Signal amplitude decreases with range
amplitude = target['snr'] * (10000 / target['range'])
phase = 2 * math.pi * sample / 50 + doppler_phase
i_val += amplitude * math.cos(phase)
q_val += amplitude * math.sin(phase)
# Calculate derived values
magnitude_squared = i_val**2 + q_val**2
data.append({
'timestamp_ns': timestamp_ns,
'chirp_number': chirp_number,
'chirp_type': 'LONG',
'sample_index': sample,
'I_value': int(i_val),
'Q_value': int(q_val),
'magnitude_squared': int(magnitude_squared)
})
timestamp_ns += int(1e9 / fs_adc) # 2.5ns per sample at 400MHz
chirp_number += 1
timestamp_ns += 137000 # Add listening period (137µs)
# Guard time between long and short chirps
timestamp_ns += 175400 # 175.4µs guard time
# Generate Short Chirps (0.5µs duration equivalent)
print("Generating Short Chirps...")
for chirp in range(num_short_chirps):
for sample in range(samples_per_chirp):
# Base noise
i_val = np.random.normal(0, noise_std)
q_val = np.random.normal(0, noise_std)
# Add clutter (different characteristics for short chirps)
if sample < 50: # Less clutter for short chirps
i_val += np.random.normal(0, clutter_std/2)
q_val += np.random.normal(0, clutter_std/2)
# Add moving targets with different Doppler for short chirps
for target in targets:
# Range bin calculation (different for short chirps)
range_bin = int(target['range'] / 40) # Different range resolution
doppler_phase = 2 * math.pi * target['velocity'] * (chirp + 5) / 80 # Different Doppler
# Target appears around its range bin
if abs(sample - range_bin) < 8:
# Different amplitude characteristics for short chirps
amplitude = target['snr'] * 0.7 * (8000 / target['range']) # 70% amplitude
phase = 2 * math.pi * sample / 30 + doppler_phase
i_val += amplitude * math.cos(phase)
q_val += amplitude * math.sin(phase)
# Calculate derived values
magnitude_squared = i_val**2 + q_val**2
data.append({
'timestamp_ns': timestamp_ns,
'chirp_number': chirp_number,
'chirp_type': 'SHORT',
'sample_index': sample,
'I_value': int(i_val),
'Q_value': int(q_val),
'magnitude_squared': int(magnitude_squared)
})
timestamp_ns += int(1e9 / fs_adc) # 2.5ns per sample
chirp_number += 1
timestamp_ns += 174500 # Add listening period (174.5µs)
# Create DataFrame
df = pd.DataFrame(data)
# Save to CSV
df.to_csv(filename, index=False)
print(f"Generated CSV file: {filename}")
print(f"Total samples: {len(df)}")
print(f"Long chirps: {num_long_chirps}, Short chirps: {num_short_chirps}")
print(f"Samples per chirp: {samples_per_chirp}")
print(f"File size: {len(df) // 1000}K samples")
return df
def analyze_generated_data(df):
"""
Analyze the generated data to verify target detection
"""
print("\n=== Data Analysis ===")
# Basic statistics
long_chirps = df[df['chirp_type'] == 'LONG']
short_chirps = df[df['chirp_type'] == 'SHORT']
print(f"Long chirp samples: {len(long_chirps)}")
print(f"Short chirp samples: {len(short_chirps)}")
print(f"Unique chirp numbers: {df['chirp_number'].nunique()}")
# Calculate actual magnitude and phase for analysis
df['magnitude'] = np.sqrt(df['I_value']**2 + df['Q_value']**2)
df['phase_rad'] = np.arctan2(df['Q_value'], df['I_value'])
# Find high-magnitude samples (potential targets)
high_mag_threshold = df['magnitude'].quantile(0.95) # Top 5%
targets_detected = df[df['magnitude'] > high_mag_threshold]
print(f"\nTarget detection threshold: {high_mag_threshold:.2f}")
print(f"High magnitude samples: {len(targets_detected)}")
# Group by chirp type
long_targets = targets_detected[targets_detected['chirp_type'] == 'LONG']
short_targets = targets_detected[targets_detected['chirp_type'] == 'SHORT']
print(f"Targets in long chirps: {len(long_targets)}")
print(f"Targets in short chirps: {len(short_targets)}")
return df
if __name__ == "__main__":
# Generate the CSV file
df = generate_radar_csv("test_radar_data.csv")
# Analyze the generated data
analyze_generated_data(df)
print("\n=== CSV File Ready ===")
print("You can now test the Python GUI with this CSV file!")
print("The file contains:")
print("- 16 Long chirps + 16 Short chirps")
print("- 4 simulated targets at different ranges and velocities")
print("- Realistic noise and clutter")
print("- Proper I/Q data for Doppler processing")
-97
View File
@@ -1,97 +0,0 @@
import numpy as np
import pandas as pd
import math
def generate_small_radar_csv(filename="small_test_radar_data.csv"):
"""
Generate a smaller, faster-to-process radar CSV
"""
# Reduced parameters for faster processing
num_long_chirps = 8 # Reduced from 16
num_short_chirps = 8 # Reduced from 16
samples_per_chirp = 128 # Reduced from 512
fs_adc = 400e6
targets = [
{'range': 3000, 'velocity': 25, 'snr': 40},
{'range': 5000, 'velocity': -15, 'snr': 35},
]
data = []
chirp_number = 0
timestamp_ns = 0
# Generate Long Chirps
for chirp in range(num_long_chirps):
for sample in range(samples_per_chirp):
i_val = np.random.normal(0, 3)
q_val = np.random.normal(0, 3)
# Add targets
for target in targets:
range_bin = int(target['range'] / 40)
doppler_phase = 2 * math.pi * target['velocity'] * chirp / 50
if abs(sample - range_bin) < 5:
amplitude = target['snr'] * (8000 / target['range'])
phase = 2 * math.pi * sample / 30 + doppler_phase
i_val += amplitude * math.cos(phase)
q_val += amplitude * math.sin(phase)
magnitude_squared = i_val**2 + q_val**2
data.append({
'timestamp_ns': timestamp_ns,
'chirp_number': chirp_number,
'chirp_type': 'LONG',
'sample_index': sample,
'I_value': int(i_val),
'Q_value': int(q_val),
'magnitude_squared': int(magnitude_squared)
})
timestamp_ns += int(1e9 / fs_adc)
chirp_number += 1
timestamp_ns += 137000
# Generate Short Chirps
for chirp in range(num_short_chirps):
for sample in range(samples_per_chirp):
i_val = np.random.normal(0, 3)
q_val = np.random.normal(0, 3)
for target in targets:
range_bin = int(target['range'] / 60)
doppler_phase = 2 * math.pi * target['velocity'] * (chirp + 2) / 40
if abs(sample - range_bin) < 4:
amplitude = target['snr'] * 0.6 * (6000 / target['range'])
phase = 2 * math.pi * sample / 25 + doppler_phase
i_val += amplitude * math.cos(phase)
q_val += amplitude * math.sin(phase)
magnitude_squared = i_val**2 + q_val**2
data.append({
'timestamp_ns': timestamp_ns,
'chirp_number': chirp_number,
'chirp_type': 'SHORT',
'sample_index': sample,
'I_value': int(i_val),
'Q_value': int(q_val),
'magnitude_squared': int(magnitude_squared)
})
timestamp_ns += int(1e9 / fs_adc)
chirp_number += 1
timestamp_ns += 174500
df = pd.DataFrame(data)
df.to_csv(filename, index=False)
print(f"Generated small CSV: {filename}")
print(f"Total samples: {len(df)}")
return df
generate_small_radar_csv()
-34
View File
@@ -1,34 +0,0 @@
import numpy as np
from numpy.fft import fft, ifft
import matplotlib.pyplot as plt
n = np.arange(0, 61, 1)
Fs=125e6
Ts = 1.0 / Fs
Tb=1e-6
y = 1 + np.sin(2*np.pi*(29e6*(n**2)*(Ts**2)/(2.0*Tb)+1e6*n*Ts))
t = Ts*np.arange(0,61,1)
Y = fft(y)
M =len(Y)
m = np.arange(M)
T = M*Ts
freq = m/T
plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.stem(freq, np.abs(Y), 'b', \
markerfmt=" ", basefmt="-b")
plt.xlabel('Freq (Hz)')
plt.ylabel('FFT Amplitude |Y(freq)|')
plt.xlim(0, 40*pow(10,6))
plt.ylim(0, 20)
plt.subplot(122)
plt.plot(t, ifft(Y), 'r')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
-46
View File
@@ -1,46 +0,0 @@
import numpy as np
from numpy.fft import fft, ifft
import matplotlib.pyplot as plt
fs=125*pow(10,6) #sampling frequency
Ts=1/fs # sampling time
Tb=0.25*pow(10,-6) # burst time
Tau=1.5*pow(10,-6) # pulse repetition time
fmax=32*pow(10,6) # maximum frequency on ramp
fmin=1*pow(10,6) # minimum frequency on ramp
n=int(Tb/Ts) # number of samples per ramp
N = np.arange(0, n, 1)
theta_n= 2*np.pi*(pow(N,2)*pow(Ts,2)*(fmax-fmin)/(2*Tb)+fmin*N*Ts) # instantaneous phase
y = 1 + np.sin(theta_n) # ramp signal in time domain
M = np.arange(n, 2*n, 1)
theta_m= 2*np.pi*(pow(M,2)*pow(Ts,2)*(-fmax+fmin)/(2*Tb)+(-fmin+2*fmax)*M*Ts)-2*np.pi*((fmin-fmax)*Tb/2+(2*fmax-fmin)*Tb) # instantaneous phase
z = 1 + np.sin(theta_m) # ramp signal in time domain
x = np.concatenate((y, z))
t = Ts*np.arange(0,2*n,1)
X = fft(x)
L =len(X)
l = np.arange(L)
T = L*Ts
freq = l/T
plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.stem(freq, np.abs(X), 'b', \
markerfmt=" ", basefmt="-b")
plt.xlabel('Freq (Hz)')
plt.ylabel('FFT Amplitude |Y(freq)|')
plt.xlim(0, (fmax+fmax/10))
plt.ylim(0, 20)
plt.subplot(122)
plt.plot(2*n, y)
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
-41
View File
@@ -1,41 +0,0 @@
import numpy as np
from numpy.fft import fft, ifft
import matplotlib.pyplot as plt
fs=125*pow(10,6) #sampling frequency
Ts=1/fs # sampling time
Tb=0.5*pow(10,-6) # burst time
Tau=900*pow(10,-6) # pulse repetition time
fmax=30*pow(10,6) # maximum frequency on ramp
fmin=10*pow(10,6) # minimum frequency on ramp
n=int(Tb/Ts) # number of samples per ramp
N = np.arange(0, n, 1)
theta_n= 2*np.pi*(pow(N,2)*pow(Ts,2)*(fmax-fmin)/(2*Tb)+fmin*N*Ts) # instantaneous phase
y = 1 + np.sin(theta_n) # ramp signal in time domain
t = Ts*np.arange(0,n,1)
Y = fft(y)
M =len(Y)
m = np.arange(M)
T = M*Ts
freq = m/T
plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.stem(freq, np.abs(Y), 'b', \
markerfmt=" ", basefmt="-b")
plt.xlabel('Freq (Hz)')
plt.ylabel('FFT Amplitude |Y(freq)|')
plt.xlim(0, (1.3*fmax))
plt.ylim(0, 60)
plt.subplot(122)
plt.plot(t, ifft(Y), 'r')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
@@ -1,49 +0,0 @@
import numpy as np
from numpy.fft import fft, ifft
import matplotlib.pyplot as plt
fs=125*pow(10,6) #sampling frequency
Ts=1/fs # sampling time
Tb=0.25*pow(10,-6) # burst time
Tau=1.5*pow(10,-6) # pulse repetition time
fmax=32*pow(10,6) # maximum frequency on ramp
fmin=1*pow(10,6) # minimum frequency on ramp
n=int(Tb/Ts) # number of samples per ramp
N = np.arange(0, n, 1)
theta_n= 2*np.pi*(pow(N,2)*pow(Ts,2)*(fmax-fmin)/(2*Tb)+fmin*N*Ts) # instantaneous phase
y = 1 + np.sin(theta_n) # ramp signal in time domain
M = np.arange(n, 2*n, 1)
theta_m= 2*np.pi*(pow(M,2)*pow(Ts,2)*(-fmax+fmin)/(2*Tb)+(-fmin+2*fmax)*M*Ts)-2*np.pi*((fmin-fmax)*Tb/2+(2*fmax-fmin)*Tb) # instantaneous phase
z = 1 + np.sin(theta_m) # ramp signal in time domain
x = np.concatenate((y, z))
t = Ts*np.arange(0,2*n,1)
plt.plot(t, x)
X = fft(x)
L =len(X)
l = np.arange(L)
T = L*Ts
freq = l/T
print("The Array is: ", x) #printing the array
plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.stem(freq, np.abs(X), 'b', \
markerfmt=" ", basefmt="-b")
plt.xlabel('Freq (Hz)')
plt.ylabel('FFT Amplitude |Y(freq)|')
plt.xlim(0, (fmax+fmax/10))
plt.ylim(0, 20)
plt.subplot(122)
plt.plot(t, ifft(X), 'r')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
-24
View File
@@ -1,24 +0,0 @@
import numpy as np
# Define parameters
fs = 120e6 # Sampling frequency
Ts = 1 / fs # Sampling time
Tb = 1e-6 # Burst time
Tau = 30e-6 # Pulse repetition time
fmax = 15e6 # Maximum frequency on ramp
fmin = 1e6 # Minimum frequency on ramp
# Compute number of samples per ramp
n = int(Tb / Ts)
N = np.arange(0, n, 1)
# Compute instantaneous phase
theta_n = 2 * np.pi * ((N**2 * Ts**2 * (fmax - fmin) / (2 * Tb)) + fmin * N * Ts)
# Generate waveform and scale it to 8-bit unsigned values (0 to 255)
y = 1 + np.sin(theta_n) # Normalize from 0 to 2
y_scaled = np.round(y * 127.5).astype(int) # Scale to 8-bit range (0-255)
# Print values in Verilog-friendly format
for i in range(n):
print(f"waveform_LUT[{i}] = 8'h{y_scaled[i]:02X};")
-309
View File
@@ -1,309 +0,0 @@
import tkinter as tk
from tkinter import ttk, messagebox
import math
import numpy as np
class RadarCalculatorGUI:
def __init__(self, root):
self.root = root
self.root.title("RADAR Parameters Calculator")
self.root.geometry("850x750")
# Configure colors
self.bg_color = '#f0f0f0'
self.root.configure(bg=self.bg_color)
# Create main container
self.main_frame = ttk.Frame(root, padding="10")
self.main_frame.pack(fill=tk.BOTH, expand=True)
# Title
title_label = tk.Label(self.main_frame, text="RADAR PARAMETERS CALCULATOR",
font=('Arial', 16, 'bold'), bg=self.bg_color)
title_label.pack(pady=10)
# Create notebook for tabs
self.notebook = ttk.Notebook(self.main_frame)
self.notebook.pack(fill=tk.BOTH, expand=True, pady=10)
# Input tab
self.input_frame = ttk.Frame(self.notebook)
self.notebook.add(self.input_frame, text="Input Parameters")
# Results tab
self.results_frame = ttk.Frame(self.notebook)
self.notebook.add(self.results_frame, text="Results")
# Create input fields
self.create_input_fields()
# Create results display
self.create_results_display()
# Create button frame (outside notebook)
self.button_frame = ttk.Frame(self.main_frame)
self.button_frame.pack(fill=tk.X, pady=10)
# Create calculate button
self.create_calculate_button()
# Constants
self.c = 3e8 # Speed of light in m/s
def create_input_fields(self):
"""Create all input fields with labels and units"""
# Create a canvas with scrollbar for input fields
canvas = tk.Canvas(self.input_frame, borderwidth=0)
scrollbar = ttk.Scrollbar(self.input_frame, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
# Input fields with default values
inputs = [
("Frequency (GHz):", "10.0"),
("Pulse duration (μs):", "1.0"),
("PRF (Hz):", "1000"),
("Emitted power (dBm):", "30"),
("Antenna gain (dBi):", "20"),
("Receiver sensitivity (dBm):", "-90"),
("Radar cross section (m²):", "1.0"),
("System losses (dB):", "3"),
("Noise figure (dB):", "3"),
("Boltzmann constant (k) - optional:", "1.38e-23"),
("Temperature (K):", "290")
]
self.entries = {}
for i, (label, default) in enumerate(inputs):
# Create a frame for each input row
row_frame = ttk.Frame(scrollable_frame)
row_frame.pack(fill=tk.X, pady=5)
# Label
ttk.Label(row_frame, text=label, width=30, anchor='w').pack(side=tk.LEFT, padx=5)
# Entry
entry = ttk.Entry(row_frame, width=20, font=('Arial', 10))
entry.pack(side=tk.LEFT, padx=5)
entry.insert(0, default)
self.entries[label] = entry
# Additional notes
notes_label = tk.Label(scrollable_frame,
text="Note: All values must be numeric. Use point (.) for decimals.",
font=('Arial', 9, 'italic'), fg='gray')
notes_label.pack(pady=20)
# Pack canvas and scrollbar
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
def create_calculate_button(self):
"""Create the calculate button"""
calculate_btn = tk.Button(self.button_frame,
text="CALCULATE RADAR PARAMETERS",
command=self.calculate_parameters,
bg='#4CAF50', fg='white',
font=('Arial', 12, 'bold'),
padx=30, pady=10,
cursor='hand2')
calculate_btn.pack()
# Bind hover effect
calculate_btn.bind("<Enter>", lambda e: calculate_btn.config(bg='#45a049'))
calculate_btn.bind("<Leave>", lambda e: calculate_btn.config(bg='#4CAF50'))
def create_results_display(self):
"""Create the results display area"""
# Results title
title_label = tk.Label(self.results_frame, text="RADAR PERFORMANCE PARAMETERS",
font=('Arial', 14, 'bold'))
title_label.pack(pady=(20, 20))
# Create frame for results with scrollbar
canvas = tk.Canvas(self.results_frame, borderwidth=0)
scrollbar = ttk.Scrollbar(self.results_frame, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
# Results fields
results = [
("Maximum detectable range:", "range_result"),
("Range resolution:", "range_res_result"),
("Maximum unambiguous range:", "max_range_result"),
("Maximum detectable speed:", "speed_result"),
("Speed resolution:", "speed_res_result"),
("Doppler frequency resolution:", "doppler_res_result"),
("Pulse width (s):", "pulse_width_result"),
("Bandwidth (Hz):", "bandwidth_result"),
("SNR (dB):", "snr_result")
]
self.results_labels = {}
for i, (label, key) in enumerate(results):
# Create a frame for each result row
row_frame = ttk.Frame(scrollable_frame)
row_frame.pack(fill=tk.X, pady=10, padx=20)
# Label
ttk.Label(row_frame, text=label, font=('Arial', 11, 'bold'),
width=30, anchor='w').pack(side=tk.LEFT)
# Value
value_label = ttk.Label(row_frame, text="---", font=('Arial', 11),
foreground='blue', anchor='w')
value_label.pack(side=tk.LEFT, padx=(20, 0))
self.results_labels[key] = value_label
# Add separator
ttk.Separator(scrollable_frame, orient='horizontal').pack(fill=tk.X, pady=20)
# Add explanatory note
note_text = """
NOTES:
• Maximum detectable range is calculated using the radar equation
• Range resolution = c × τ / 2, where τ is pulse duration
• Maximum unambiguous range = c / (2 × PRF)
• Maximum detectable speed = λ × PRF / 4
• Speed resolution = λ × PRF / (2 × N) where N is number of pulses (assumed 1)
• λ (wavelength) = c / f
"""
note_label = tk.Label(scrollable_frame, text=note_text, font=('Arial', 9),
justify=tk.LEFT, bg='#f8f9fa', relief='solid',
padx=10, pady=10)
note_label.pack(fill=tk.X, padx=20, pady=10)
# Pack canvas and scrollbar
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
def get_float_value(self, entry, default=None):
"""Safely get float value from entry"""
try:
return float(entry.get())
except ValueError:
return default
def calculate_parameters(self):
"""Perform all RADAR calculations"""
try:
# Get all input values
f_ghz = self.get_float_value(self.entries["Frequency (GHz):"])
pulse_duration_us = self.get_float_value(self.entries["Pulse duration (μs):"])
prf = self.get_float_value(self.entries["PRF (Hz):"])
p_dbm = self.get_float_value(self.entries["Emitted power (dBm):"])
g_dbi = self.get_float_value(self.entries["Antenna gain (dBi):"])
sens_dbm = self.get_float_value(self.entries["Receiver sensitivity (dBm):"])
rcs = self.get_float_value(self.entries["Radar cross section (m²):"])
losses_db = self.get_float_value(self.entries["System losses (dB):"])
nf_db = self.get_float_value(self.entries["Noise figure (dB):"])
k = self.get_float_value(self.entries["Boltzmann constant (k) - optional:"])
temp = self.get_float_value(self.entries["Temperature (K):"])
# Validate inputs
if None in [f_ghz, pulse_duration_us, prf, p_dbm, g_dbi, sens_dbm, rcs, losses_db, nf_db, temp]:
messagebox.showerror("Error", "Please enter valid numeric values for all fields")
return
# Convert units
f_hz = f_ghz * 1e9
pulse_duration_s = pulse_duration_us * 1e-6
wavelength = self.c / f_hz
# Convert dB values to linear
p_linear = 10 ** ((p_dbm - 30) / 10) # Convert dBm to Watts
g_linear = 10 ** (g_dbi / 10)
sens_linear = 10 ** ((sens_dbm - 30) / 10)
losses_linear = 10 ** (losses_db / 10)
nf_linear = 10 ** (nf_db / 10)
# Calculate receiver noise power
if k is None:
k = 1.38e-23 # Default Boltzmann constant
# Calculate SNR
snr_linear = (p_linear * g_linear**2 * wavelength**2 * rcs) / (
(4 * np.pi)**3 * sens_linear * losses_linear)
snr_db = 10 * math.log10(snr_linear) if snr_linear > 0 else float('-inf')
# Maximum detectable range using radar equation
if snr_linear > 0:
range_max = ((p_linear * g_linear**2 * wavelength**2 * rcs) /
((4 * np.pi)**3 * sens_linear * losses_linear)) ** (1/4)
else:
range_max = 0
# Range resolution
range_res = (self.c * pulse_duration_s) / 2
# Maximum unambiguous range
max_unambiguous_range = self.c / (2 * prf)
# Maximum detectable speed (using half the Nyquist sampling theorem)
max_speed = (wavelength * prf) / 4
# Speed resolution (for a single pulse, approximate)
speed_res = max_speed # For single pulse, resolution equals max speed
# Doppler frequency resolution
doppler_res = 1 / pulse_duration_s
# Bandwidth
bandwidth = 1 / pulse_duration_s
# Update results display with formatted values
self.results_labels["range_result"].config(
text=f"{range_max:.2f} m ({range_max/1000:.2f} km)")
self.results_labels["range_res_result"].config(
text=f"{range_res:.2f} m")
self.results_labels["max_range_result"].config(
text=f"{max_unambiguous_range:.2f} m ({max_unambiguous_range/1000:.2f} km)")
self.results_labels["speed_result"].config(
text=f"{max_speed:.2f} m/s ({max_speed*3.6:.2f} km/h)")
self.results_labels["speed_res_result"].config(
text=f"{speed_res:.2f} m/s ({speed_res*3.6:.2f} km/h)")
self.results_labels["doppler_res_result"].config(
text=f"{doppler_res:.2f} Hz")
self.results_labels["pulse_width_result"].config(
text=f"{pulse_duration_s:.2e} s")
self.results_labels["bandwidth_result"].config(
text=f"{bandwidth:.2e} Hz")
self.results_labels["snr_result"].config(
text=f"{snr_db:.2f} dB")
# Switch to results tab
self.notebook.select(1)
# Show success message
messagebox.showinfo("Success", "Calculation completed successfully!")
except Exception as e:
messagebox.showerror("Calculation Error", f"An error occurred during calculation:\n{str(e)}")
def main():
root = tk.Tk()
app = RadarCalculatorGUI(root)
root.mainloop()
if __name__ == "__main__":
main()
-7
View File
@@ -1,7 +0,0 @@
import numpy as np
import matplotlib.pyplot as plt
n = np.arange(0, 61, 1)
Ts=8*pow(10,-9)
y = 1 + np.sin(2*np.pi*(-16*pow(10,12)*pow(n,2)*pow(Ts,2)+16*pow(10,6)*n*Ts))
plt.plot(n, y)
plt.show()
-59
View File
@@ -1,59 +0,0 @@
import numpy as np
def calculate_patch_antenna_parameters(frequency, epsilon_r, h_sub, h_cu, array):
# Constants
c = 3e8 # Speed of light in m/s
# Convert height from mm to meters
h_sub_m = h_sub * 1e-3
h_cu_m = h_cu * 1e-3
# Calculate Lambda
lamb = c /(frequency * 1e9)
# Calculate the effective dielectric constant
epsilon_eff = (epsilon_r + 1) / 2 + (epsilon_r - 1) / 2 * (1 + 12 * h_sub_m / (array[1] * h_cu_m)) ** (-0.5)
# Calculate the width of the patch
W = c / (2 * frequency * 1e9) * np.sqrt(2 / (epsilon_r + 1))
# Calculate the effective length
delta_L = 0.412 * h_sub_m * (epsilon_eff + 0.3) * (W / h_sub_m + 0.264) / ((epsilon_eff - 0.258) * (W / h_sub_m + 0.8))
# Calculate the length of the patch
L = c / (2 * frequency * 1e9 * np.sqrt(epsilon_eff)) - 2 * delta_L
# Calculate the separation distance in the horizontal axis (dx)
dx = lamb/2 # Typically 1.5 times the width of the patch
# Calculate the separation distance in the vertical axis (dy)
dy = lamb/2 # Typically 1.5 times the length of the patch
# Calculate the feeding line width (W_feed)
Z0 = 50 # Characteristic impedance of the feeding line (typically 50 ohms)
A = Z0 / 60 * np.sqrt((epsilon_r + 1) / 2) + (epsilon_r - 1) / (epsilon_r + 1) * (0.23 + 0.11 / epsilon_r)
W_feed = 8 * h_sub_m / np.exp(A) - 2 * h_cu_m
# Convert results back to mm
W_mm = W * 1e3
L_mm = L * 1e3
dx_mm = dx * 1e3
dy_mm = dy * 1e3
W_feed_mm = W_feed * 1e3
return W_mm, L_mm, dx_mm, dy_mm, W_feed_mm
# Example usage
frequency = 10.5 # Frequency in GHz
epsilon_r = 3.48 # Relative permittivity of the substrate
h_sub = 0.102 # Height of substrate in mm
h_cu = 0.07 # Height of copper in mm
array = [2, 2] # 2x2 array
W_mm, L_mm, dx_mm, dy_mm, W_feed_mm = calculate_patch_antenna_parameters(frequency, epsilon_r, h_sub, h_cu, array)
print(f"Width of the patch: {W_mm:.4f} mm")
print(f"Length of the patch: {L_mm:.4f} mm")
print(f"Separation distance in horizontal axis: {dx_mm:.4f} mm")
print(f"Separation distance in vertical axis: {dy_mm:.4f} mm")
print(f"Feeding line width: {W_feed_mm:.2f} mm")
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB