如何使用 FMCW 雷达的频率和时间数组绘制锯齿线性调频波形?

问题描述 投票:0回答:2

在切换到使用锯齿波之前,我使用的是正弦波,但在正弦波中高频内容并不清晰可见,但我没有任何使用锯齿波的经验。我将在 GNU Radio 中根据此代码创建一个自定义块,这样我将无法使用 scipy.signal.sawtooth 或 signal.chirp。因为有些库不能在 GNU radio 中工作。

import numpy as np
import matplotlib.pyplot as plt
from math import pi

chirp_duration = 60e-6
f0 = 1e6 
f1 = 3e6 
no_samp = 1001
rcs = 0.0377

f_step = (f1-f0)/no_samp
rf_axis = np.linspace(f0, f1, int(f_step))
rt_axis = np.linspace(0, chirp_duration, int(f_step))

# rchirp = np.cos(2 * np.pi * rf_axis * rt_axis)

plt.figure(figsize=(12, 3))
plt.xlabel("Time")
plt.ylabel("Frequency")
plt.title('Received Chirp')
plt.plot(rt_axis, rf_axis)
plt.show()

这是我用来生成正弦波线性调频信号的代码。该代码非常适合 f0 和 f1 的低频值。

python signal-processing
2个回答
1
投票

您可以使用 SciPy 生成锯齿信号 https://docs.scipy.org/doc/scipy/reference/ generated/scipy.signal.sawtooth.html

这是他们提供的示例:

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

t = np.linspace(0, 1, 500)
plt.plot(t, signal.sawtooth(2 * np.pi * 5 * t))
plt.show()

已更新 仔细考虑一下,我认为您实际上并不是在追求锯齿信号。您只需要一个重复的线性调频信号,它会在频域中产生锯齿图案。看看这是否有帮助:

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

## Make a single chirp signal
t_chirp = np.linspace(0, 2, 500)
w_chirp = signal.chirp(t_chirp, f0=1, f1=6, t1=2, method='linear')
fs = 1/(2/500)

## Repeating the chirp signal 5 times
num_repeats = 5
t = np.linspace(0, 2*num_repeats, 500*num_repeats)
w = np.copy(w_chirp)
for i in range(num_repeats-1):
    w = np.hstack((w, w_chirp))

## Finding the instantaneous frequency
analytic_signal = signal.hilbert(w)
instantaneous_phase = np.unwrap(np.angle(analytic_signal))
instantaneous_frequency = (np.diff(instantaneous_phase) / (2.0*np.pi) * fs)

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
ax[0].plot(t, w)
ax[0].set_title("Linear Chirp")
ax[0].set_xlabel('t (sec)')

ax[1].plot(t[:-1], instantaneous_frequency)
ax[1].set_title("Instantaneous Frequency")
ax[1].set_xlabel('t (sec)')
ax[1].set_ylabel("Frequency (Hz)")

plt.tight_layout()
plt.show()


0
投票

看来您的 chirp 函数可能不正确。

检查时域线性调频信号的瞬时频率,信号频率的增加速度似乎是应有的速度的两倍。

这个网站给出了一个稍微不同的产生线性调频脉冲的公式。它最初是针对 MATLAB 的,但我们可以轻松地将其转换为 Python :

def linear_chirp(t: np.ndarray, f0, f1, p, phase_offset=0):
    '''
    make a linear chirp

    Arguments:
     * t            : array of sample times
     * f0           : starting frequency 
     * f1           : end frenquency
     * p            : chirp period
     * phase_offset : initial phase offset
    '''
    return np.cos(2*np.pi*((f1-f0)/p/2*t + f0)*t + phase_offset)

以下函数,基于 astroChance 在其他答案中给出的方法,可用于检查瞬时频率:

def ifreq(t: np.ndarray, x: np.ndarray):
    '''
    find the instantaneous frequency of a singal
    Arguments:
     * t    : array of evenly spaced sample times
     * x    : signal samples at sample times `t` 
    '''
    # import scipy.signal because this is only for testing purposes
    # it is not necessary for the final version
    from scipy.signal import hilbert

    fs = len(t)/t.ptp()  # evenly spaced samples !!!
    analytic_signal = hilbert(x)
    instantaneous_phase = np.unwrap(np.angle(analytic_signal))
    return (np.diff(instantaneous_phase) / (2.0*np.pi) * fs)

为了说明这一切:

import numpy as np
import matplotlib.pyplot as plt

chirp_duration = 60e-6
f0 = 1e6 
f1 = 3e6 
no_samp = 1001

f_step = (f1-f0)/no_samp
rf_axis = np.linspace(f0, f1, int(f_step))
rt_axis = np.linspace(0, chirp_duration, int(f_step))

rchirp = np.cos(2 * np.pi * rf_axis * rt_axis)

***
define linear_chirp and ifreq here
***

mychrip = linear_chirp(rt_axis, f0, f1, chirp_duration, 0)

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
ax[0].plot(rt_axis, rchirp, 'b')
ax[0].plot(rt_axis, mychrip, 'r')
ax[0].set_title("Linear Chirp")
ax[0].set_xlabel('t (sec)')

ax[1].plot(rt_axis[:-1], ifreq(rt_axis, rchirp), 'b')
ax[1].plot(rt_axis[:-1], ifreq(rt_axis, mychrip), 'r')
ax[1].plot(rt_axis, rf_axis, 'k--')
ax[1].set_title("Instantaneous Frequency")
ax[1].set_xlabel('t (sec)')
ax[1].set_ylabel("Frequency (Hz)")

plt.tight_layout()
plt.show()

这为我们提供了以下输出,我们可以看到原始方法的频率开始正确,然后增长速度约为应有的两倍:

话虽如此,看起来您的

rf_axis
rt_axis
的生成也可能存在一些混乱。我认为您可能打算使用
np.arange
而不是
np.linspace
来生成频率。类似下面的内容对于您选择的变量名称会更有意义:

f_step = (f1-f0)/no_samp
rf_axis = np.arange(f0, f1, f_step)
rt_axis = np.linspace(0, chirp_duration, len(rf_axis))

通过尝试这个,您会发现您的频率折叠与当前值非常接近,这将导致一些混叠。

无论如何,希望这一切有所帮助,至少有一点帮助。

© www.soinside.com 2019 - 2024. All rights reserved.