Radar FMCW
Construction d'un radar FMCW avec le Pluto+
Radar FMCW avec le Pluto+
Le full-duplex du Pluto+ permet de créer un radar simple.
Principe du radar FMCW
Le radar FMCW (Frequency Modulated Continuous Wave) :
- Émet un signal dont la fréquence varie linéairement (chirp)
- Reçoit l'écho réfléchi par les cibles
- Mélange émission et réception
- La fréquence de battement est proportionnelle à la distance
Formules de base
Distance = (f_beat × c) / (2 × (BW / T_chirp))
Où :
- f_beat : fréquence de battement mesurée
- c : vitesse de la lumière (3×10⁸ m/s)
- BW : bande passante du chirp
- T_chirp : durée du chirpConfiguration matérielle
Isolation TX/RX
L'isolation entre TX et RX est critique. Utiliser des antennes séparées et orientées différemment.
| Composant | Spécification |
|---|---|
| Antenne TX | Cornet ou patch directif |
| Antenne RX | Identique, séparée de TX |
| Fréquence | 2.4 GHz (ISM) ou 5.8 GHz |
| Bande passante | 20-50 MHz |
Implémentation GNU Radio
# Génération chirp FMCW avec GNU Radio
import numpy as np
from gnuradio import gr, iio, blocks
class fmcw_radar(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
# Paramètres radar
self.center_freq = 2.4e9
self.bandwidth = 50e6 # 50 MHz de sweep
self.chirp_duration = 1e-3 # 1 ms par chirp
self.sample_rate = 10e6
# Génération du chirp
t = np.arange(0, self.chirp_duration, 1/self.sample_rate)
chirp = np.exp(1j * np.pi * self.bandwidth/self.chirp_duration * t**2)
self.chirp_signal = chirp.astype(np.complex64)
# Source chirp (répétition)
self.chirp_source = blocks.vector_source_c(
self.chirp_signal.tolist(),
repeat=True
)
# TX Pluto+
self.tx = iio.fmcomms2_sink_fc32(
"ip:192.168.2.1", [True, True], 32768
)
self.tx.set_frequency(int(self.center_freq))
self.tx.set_samplerate(int(self.sample_rate))
self.tx.set_attenuation(0, 10)
# RX Pluto+
self.rx = iio.fmcomms2_source_fc32(
"ip:192.168.2.1", [True, True], 32768
)
self.rx.set_frequency(int(self.center_freq))
self.rx.set_samplerate(int(self.sample_rate))
# Connexions
self.connect(self.chirp_source, self.tx)Traitement du signal
import numpy as np
from scipy import signal
def process_radar(tx_signal, rx_signal, sample_rate, bandwidth, chirp_duration):
"""
Traitement radar FMCW
"""
# Mélange (dérampage)
mixed = rx_signal * np.conj(tx_signal)
# FFT pour obtenir le spectre de distance
range_fft = np.fft.fft(mixed)
range_fft = np.fft.fftshift(range_fft)
# Calcul des distances
freq_axis = np.fft.fftfreq(len(mixed), 1/sample_rate)
freq_axis = np.fft.fftshift(freq_axis)
c = 3e8 # Vitesse de la lumière
range_axis = (freq_axis * c * chirp_duration) / (2 * bandwidth)
return range_axis, np.abs(range_fft)Résolution et portée
| Paramètre | Formule | Exemple (BW=50MHz, T=1ms) |
|---|---|---|
| Résolution distance | c / (2 × BW) | 3 m |
| Portée max | (c × T_chirp × fs) / (4 × BW) | 150 m |
| Résolution vitesse | λ / (2 × T_total) | Dépend de l'intégration |
Améliorations possibles
Radar Doppler
Ajouter la mesure de vitesse :
# Accumulation de plusieurs chirps
n_chirps = 64
chirp_data = np.zeros((n_chirps, samples_per_chirp), dtype=np.complex64)
for i in range(n_chirps):
chirp_data[i, :] = capture_chirp()
# FFT 2D : distance (axe 1) et vitesse (axe 0)
range_doppler = np.fft.fft2(chirp_data)MIMO (2 canaux)
Utiliser les 2 canaux RX pour :
- Amélioration du SNR (diversity)
- Estimation d'angle (direction finding)
Applications
| Application | Configuration |
|---|---|
| Détection de mouvement | Faible portée, haute sensibilité |
| Mesure de niveau | Antenne vers le bas |
| Détection véhicules | Grande portée |
| Expérimentation | Cibles connues |
Réglementation
L'émission radar est soumise à réglementation. Utiliser uniquement dans les bandes ISM (2.4 GHz, 5.8 GHz) avec les puissances autorisées, ou obtenir les autorisations nécessaires.