CSV_radar.py
1 import numpy as np 2 import pandas as pd 3 import math 4 5 def generate_radar_csv(filename="pulse_compression_output.csv"): 6 """ 7 Generate realistic radar CSV data for testing the Python GUI 8 """ 9 10 # Radar parameters matching your testbench 11 num_long_chirps = 16 12 num_short_chirps = 16 13 samples_per_chirp = 512 # Reduced for manageable file size 14 fs_adc = 400e6 # 400 MHz ADC 15 timestamp_ns = 0 16 17 # Target parameters 18 targets = [ 19 {'range': 3000, 'velocity': 25, 'snr': 30, 'azimuth': 10, 'elevation': 5}, # Fast moving target 20 {'range': 5000, 'velocity': -15, 'snr': 25, 'azimuth': 20, 'elevation': 2}, # Approaching target 21 {'range': 8000, 'velocity': 5, 'snr': 20, 'azimuth': 30, 'elevation': 8}, # Slow moving target 22 {'range': 12000, 'velocity': -8, 'snr': 18, 'azimuth': 45, 'elevation': 3}, # Distant target 23 ] 24 25 # Noise parameters 26 noise_std = 5 27 clutter_std = 10 28 29 data = [] 30 chirp_number = 0 31 32 # Generate Long Chirps (30µs duration equivalent) 33 print("Generating Long Chirps...") 34 for chirp in range(num_long_chirps): 35 for sample in range(samples_per_chirp): 36 # Base noise 37 i_val = np.random.normal(0, noise_std) 38 q_val = np.random.normal(0, noise_std) 39 40 # Add clutter (stationary targets) 41 clutter_range = 2000 # Fixed clutter at 2km 42 if sample < 100: # Simulate clutter in first 100 samples 43 i_val += np.random.normal(0, clutter_std) 44 q_val += np.random.normal(0, clutter_std) 45 46 # Add moving targets with Doppler shift 47 for target in targets: 48 # Calculate range bin (simplified) 49 range_bin = int(target['range'] / 20) # ~20m per bin 50 doppler_phase = 2 * math.pi * target['velocity'] * chirp / 100 # Doppler phase shift 51 52 # Target appears around its range bin with some spread 53 if abs(sample - range_bin) < 10: 54 # Signal amplitude decreases with range 55 amplitude = target['snr'] * (10000 / target['range']) 56 phase = 2 * math.pi * sample / 50 + doppler_phase 57 58 i_val += amplitude * math.cos(phase) 59 q_val += amplitude * math.sin(phase) 60 61 # Calculate derived values 62 magnitude_squared = i_val**2 + q_val**2 63 64 data.append({ 65 'timestamp_ns': timestamp_ns, 66 'chirp_number': chirp_number, 67 'chirp_type': 'LONG', 68 'sample_index': sample, 69 'I_value': int(i_val), 70 'Q_value': int(q_val), 71 'magnitude_squared': int(magnitude_squared) 72 }) 73 74 timestamp_ns += int(1e9 / fs_adc) # 2.5ns per sample at 400MHz 75 76 chirp_number += 1 77 timestamp_ns += 137000 # Add listening period (137µs) 78 79 # Guard time between long and short chirps 80 timestamp_ns += 175400 # 175.4µs guard time 81 82 # Generate Short Chirps (0.5µs duration equivalent) 83 print("Generating Short Chirps...") 84 for chirp in range(num_short_chirps): 85 for sample in range(samples_per_chirp): 86 # Base noise 87 i_val = np.random.normal(0, noise_std) 88 q_val = np.random.normal(0, noise_std) 89 90 # Add clutter (different characteristics for short chirps) 91 if sample < 50: # Less clutter for short chirps 92 i_val += np.random.normal(0, clutter_std/2) 93 q_val += np.random.normal(0, clutter_std/2) 94 95 # Add moving targets with different Doppler for short chirps 96 for target in targets: 97 # Range bin calculation (different for short chirps) 98 range_bin = int(target['range'] / 40) # Different range resolution 99 doppler_phase = 2 * math.pi * target['velocity'] * (chirp + 5) / 80 # Different Doppler 100 101 # Target appears around its range bin 102 if abs(sample - range_bin) < 8: 103 # Different amplitude characteristics for short chirps 104 amplitude = target['snr'] * 0.7 * (8000 / target['range']) # 70% amplitude 105 phase = 2 * math.pi * sample / 30 + doppler_phase 106 107 i_val += amplitude * math.cos(phase) 108 q_val += amplitude * math.sin(phase) 109 110 # Calculate derived values 111 magnitude_squared = i_val**2 + q_val**2 112 113 data.append({ 114 'timestamp_ns': timestamp_ns, 115 'chirp_number': chirp_number, 116 'chirp_type': 'SHORT', 117 'sample_index': sample, 118 'I_value': int(i_val), 119 'Q_value': int(q_val), 120 'magnitude_squared': int(magnitude_squared) 121 }) 122 123 timestamp_ns += int(1e9 / fs_adc) # 2.5ns per sample 124 125 chirp_number += 1 126 timestamp_ns += 174500 # Add listening period (174.5µs) 127 128 # Create DataFrame 129 df = pd.DataFrame(data) 130 131 # Save to CSV 132 df.to_csv(filename, index=False) 133 print(f"Generated CSV file: {filename}") 134 print(f"Total samples: {len(df)}") 135 print(f"Long chirps: {num_long_chirps}, Short chirps: {num_short_chirps}") 136 print(f"Samples per chirp: {samples_per_chirp}") 137 print(f"File size: {len(df) // 1000}K samples") 138 139 return df 140 141 def analyze_generated_data(df): 142 """ 143 Analyze the generated data to verify target detection 144 """ 145 print("\n=== Data Analysis ===") 146 147 # Basic statistics 148 long_chirps = df[df['chirp_type'] == 'LONG'] 149 short_chirps = df[df['chirp_type'] == 'SHORT'] 150 151 print(f"Long chirp samples: {len(long_chirps)}") 152 print(f"Short chirp samples: {len(short_chirps)}") 153 print(f"Unique chirp numbers: {df['chirp_number'].nunique()}") 154 155 # Calculate actual magnitude and phase for analysis 156 df['magnitude'] = np.sqrt(df['I_value']**2 + df['Q_value']**2) 157 df['phase_rad'] = np.arctan2(df['Q_value'], df['I_value']) 158 159 # Find high-magnitude samples (potential targets) 160 high_mag_threshold = df['magnitude'].quantile(0.95) # Top 5% 161 targets_detected = df[df['magnitude'] > high_mag_threshold] 162 163 print(f"\nTarget detection threshold: {high_mag_threshold:.2f}") 164 print(f"High magnitude samples: {len(targets_detected)}") 165 166 # Group by chirp type 167 long_targets = targets_detected[targets_detected['chirp_type'] == 'LONG'] 168 short_targets = targets_detected[targets_detected['chirp_type'] == 'SHORT'] 169 170 print(f"Targets in long chirps: {len(long_targets)}") 171 print(f"Targets in short chirps: {len(short_targets)}") 172 173 return df 174 175 if __name__ == "__main__": 176 # Generate the CSV file 177 df = generate_radar_csv("test_radar_data.csv") 178 179 # Analyze the generated data 180 analyze_generated_data(df) 181 182 print("\n=== CSV File Ready ===") 183 print("You can now test the Python GUI with this CSV file!") 184 print("The file contains:") 185 print("- 16 Long chirps + 16 Short chirps") 186 print("- 4 simulated targets at different ranges and velocities") 187 print("- Realistic noise and clutter") 188 print("- Proper I/Q data for Doppler processing")