はじめに
いろいろ記事を書いていますが、自分のバックグラウンドである、信号処理系統の記事を一本書こうと思い記事を書きます。自分の復習とメモも兼ねてます。
計測の分野から学んだ事ですが、特許を取得している通信でも用いられる、基礎的な技術である、直交検波について簡単な説明をしたいと思います
超音波や電磁波を使った精密な計測や通信などに用いられている、基礎的な技術です。
また、相関を使用した処理の例としても挙げられます。
せっかくなので、理想的な場合と理想的でない場合どうなるかの計算をして、可視化したいと思います。
直交検波とは
信号(搬送波)を、送信した周波数で復調し、特定の周波数成分の振幅と位相(複素振幅)を取得する手法です
受信した信号に、$cos$と$sin$をかけた信号を用意し、その信号にローパスフィルタをかけて、$sin$成分と$cos$成分を取り出し、振幅と位相を計算します。
処理内容の詳細は、式を参照してください。
計測の分野では、振幅のみを考慮して処理を行うと、波長より細かい計測ができないのですが、初期位相まで含めた計算が可能になると、送信した波の大きさよりも小さい大きさの計測が可能で、より精密な計測が可能となります。
また、通信の分野では、振幅と位相によって符号を割り当て、一つの周波数一つの時刻で複数の信号を送る事が可能となります。
式
- 必要な公式(加法定理)
\begin{align}
\cos(\alpha + \beta) = \cos\alpha \cos\beta - \sin\alpha \sin\beta \\
\sin(\alpha + \beta) = \sin\alpha \cos\beta + \cos\alpha \sin\beta
\end{align}
- 計算
- 送信信号の式
周波数を$\omega$、初期位相を$\phi$とする。初期位相は、波の始まる最初の角度。
\begin{align} s(t) &= A \cos(\omega t + \phi) \tag{1}\\ &= A \left( \cos\omega t \cos\phi - \sin\omega t \sin\phi \right) \\ \end{align}- $cos$出検波($I$成分)
\begin{align} s(t)\cos\omega t &= A \left( \cos\omega t \cos\phi - \sin\omega t \sin\phi \right)\cos\omega t \\ &= A \left( \cos^2\omega t \cos\phi - \sin\omega t \cos\omega t \sin\phi \right) \end{align}(2)(3)より\begin{align} \cos^2\omega t &= \frac{1}{2}(1 + \cos 2\omega t) \tag{2}\\ \sin\omega t \cos\omega t &= \frac{1}{2}\sin 2\omega t \tag{3} \end{align}ローパスフィルタで処理を行い、$2 \omega t$の周波数を取り除く。\begin{align} s(t)\cos\omega t &= A \left[ \frac{1}{2}(1 + \cos 2\omega t)\cos\phi - \frac{1}{2}\sin 2\omega t \sin\phi \right] \\ &= \frac{A}{2}\cos\phi + \frac{A}{2}\cos 2\omega t \cos\phi - \frac{A}{2}\sin 2\omega t \sin\phi \end{align}I = \frac{A}{2}\cos\phi- $sin$出検波($Q$成分)
\begin{align} s(t)\sin\omega t &= A \left( \cos\omega t \cos\phi - \sin\omega t \sin\phi \right)\sin\omega t \\ &= A \left( \cos\omega t \sin\omega t \cos\phi - \sin^2\omega t \sin\phi \right) \end{align}(4)(5)より\begin{align} \sin^2\omega t &= \frac{1}{2}(1 - \cos 2\omega t) \tag{4}\\ \sin\omega t \cos\omega t &= \frac{1}{2}\sin 2\omega t \tag{5} \end{align}ローパスフィルタで処理を行い、$2 \omega t$の周波数を取り除き、低周波成分(ベースバンド)のみを取得する。\begin{align} s(t)\sin\omega t &= A \left[ \frac{1}{2}\sin 2\omega t \cos\phi - \frac{1}{2}(1 - \cos 2\omega t)\sin\phi \right] \\ &=-\frac{A}{2}\sin\phi + \frac{A}{2}\sin 2\omega t \cos\phi + \frac{A }{2}\cos 2\omega t \sin\phi \end{align}Q = -\frac{A}{2}\sin\phi- 振幅と位相の復元
\begin{align} A &= 2\sqrt{I^2 + Q^2} \\ \phi &= \tan^{-1}\left( \frac{-Q}{I} \right) \end{align} - 送信信号の式
理想的な環境でない場合どうなるのか
送受信の同期がとれていなかった場合
これは、話が単純なのですが、同期の時間差ぶんだけ、位相がずれます。
式で表現すると下記のようになって、信号が$\theta$だけズレた感じになります。
\begin{align}
s(t) &= A \cos(\omega t + \phi - \theta)
\end{align}
違う周波数が乗ったらどうなるのか
式にすると下記のようになります
s(t) = A \cos(\omega t + \phi) + B \cos(\omega' t + \psi)
- $cos$成分
第一項は、計算が同じなので割愛。
\cos(\omega t + \phi) = \frac{1}{2}(1 + \cos 2\omega t)\cos\phi
- \frac{1}{2}\sin 2\omega t \sin\phi
第二項は、
\begin{align}
\cos(\omega' t + \psi)
&= \cos\omega' t \cos\psi - \sin\omega' t \sin\psi \\
\cos(\omega' t + \psi)\cos\omega t &= \cos\omega' t \cos\omega t \cos\psi- \sin\omega' t \cos\omega t \sin\psi \\
&= \frac{1}{2}\cos\psi \left[ \cos((\omega' - \omega)t) + \cos((\omega' + \omega)t) \right]
- \frac{1}{2}\sin\psi \left[ \sin((\omega' + \omega)t) + \sin((\omega' - \omega)t) \right] \\
\end{align}
参照式
\begin{align}
\cos\omega' t \cos\omega t &= \frac{1}{2} \left[ \cos((\omega' - \omega)t) + \cos((\omega' + \omega)t) \right] \\
\sin\omega' t \cos\omega t
&= \frac{1}{2} \left[ \sin((\omega' + \omega)t) + \sin((\omega' - \omega)t) \right]
\end{align}
というわけで、$\omega'$の値によってローパスフィルタをかけた時の残る成分が変わります。
-
$\omega \neq \omega'$の時
$\omega$あたりの周波数は通常カットするため、通常と変わらない成分が残ります。 -
$\omega = \omega'$の時
長くなってきたので式は割愛しますが、同じ周波数成分が残り、干渉して振幅や位相が変化します。
分離できず、振幅と位相が合成された1つの信号として観測されます。 -
$\omega \fallingdotseq \omega'$
ローパスフィルタにかからない低い周波数成分である、$\cos((\omega' - \omega)t)$や$\sin((\omega' - \omega)t)$といった成分が残ります。
このような感じで、搬送周波数と同じ周波数帯域の信号が無ければ、特定の周波数成分だけ抽出できるようになっています。
ここで重要なのは、単に低周波成分が残るのではなく、復調に用いた周波数との差(差周波)が低い成分が残る点です。
シミュレーション
理想的な場合
振幅1、初期位相$\frac{\pi}{6}$で直交検波を行った結果です。
時間差はありますが、復調されています。
別周波数がある場合(消える)
振幅1、初期位相$\frac{\pi}{6}$に明らかに違う周波数の波を足し、直交検波を行った結果です。
ローパスフィルタによる遅延はありますが、復調されています。
同一周波数がある場合(干渉する)
振幅1、初期位相$\frac{\pi}{6}$に同一周波数の波を足し、直交検波を行った結果です。
振幅が大きくなり、初期位相が変わっている事が確認できます。

少し違う周波数(混ざる)
振幅1、初期位相$\frac{\pi}{6}$に少し周波数が違う波を足し、直交検波を行った結果です。
初期位相や振幅が変わっていく事が確認できます。
おわりに
計測や通信で使われる基礎的な技術である、直交検波についてまとめてみました。
実は、これも相関を使った処理ともいえるんですよね。相関は、本当にいろいろなところで使われています。
何かの参考になれば幸いです。
シミュレーションのpythonコード
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt
# -----------------------------
# 基本設定
# -----------------------------
fs = 5000 # サンプリング周波数
T = 0.2 # 観測時間
t = np.arange(0, T, 1/fs)
f0 = 50 # 目的の周波数(復調側)
w0 = 2*np.pi*f0
# -----------------------------
# ローパスフィルタ(移動平均)
# -----------------------------
#def lpf(x, N=1000):
# return np.convolve(x, np.ones(N)/N, mode='same')
def lpf(x, fs, cutoff=10):
b, a = butter(4, cutoff/(fs/2), btype='low')
return filtfilt(b, a, x)
# -----------------------------
# 直交検波
# -----------------------------
def iq_demod(x, t, f):
w = 2*np.pi*f
i = lpf(x * np.cos(w*t),fs)
q = lpf(x * np.sin(w*t),fs)
return i, q
# -----------------------------
# 振幅・位相
# -----------------------------
def amp_phase(i, q):
A = 2*np.sqrt(i**2 + q**2)
phi = np.arctan2(-q, i)
return A, phi
# -----------------------------
# プロット関数
# -----------------------------
def plot_case(title, x, i, q, A, phi):
plt.figure(figsize=(10,6))
plt.subplot(4,1,1)
plt.plot(t, x)
plt.title(title)
plt.subplot(4,1,2)
plt.plot(t, i, label="I")
plt.plot(t, q, label="Q")
plt.legend()
plt.subplot(4,1,3)
plt.plot(t, A)
plt.title("Amplitude")
plt.subplot(4,1,4)
plt.plot(t, phi)
plt.title("Phase")
plt.tight_layout()
plt.show()
# =========================================================
# ケース1:正常系(単一周波数)
# =========================================================
A1 = 1.0
phi1 = np.pi/6
x1 = A1 * np.cos(w0*t + phi1)
i1, q1 = iq_demod(x1, t, f0)
A_est1, phi_est1 = amp_phase(i1, q1)
plot_case("Case 1: Single Frequency", x1, i1, q1, A_est1, phi_est1)
# =========================================================
# ケース2:別周波数(消える)
# =========================================================
f2 = 120
w2 = 2*np.pi*f2
x2 = (A1 * np.cos(w0*t + phi1)
+ 0.8 * np.cos(w2*t + np.pi/3))
i2, q2 = iq_demod(x2, t, f0)
A_est2, phi_est2 = amp_phase(i2, q2)
plot_case("Case 2: Different Frequency (Filtered Out)", x2, i2, q2, A_est2, phi_est2)
# =========================================================
# ケース3:同一周波数(混ざる)
# =========================================================
A3 = 0.8
phi3 = -np.pi/4
x3 = (A1 * np.cos(w0*t + phi1)
+ A3 * np.cos(w0*t + phi3))
i3, q3 = iq_demod(x3, t, f0)
A_est3, phi_est3 = amp_phase(i3, q3)
plot_case("Case 3: Same Frequency (Mixed)", x3, i3, q3, A_est3, phi_est3)
# =========================================================
# ケース4:少し違う周波数(混ざる)
# =========================================================
x4 = (A1 * np.cos(w0*t + phi1)
+ 0.8 * np.cos((w0 + 2*np.pi*2)*t))
i4, q4 = iq_demod(x4, t, f0)
A_est4, phi_est4 = amp_phase(i4, q4)
plot_case("Case 4: Nearly eqaul Frequency (Mixed)", x4, i4, q4, A_est4, phi_est4)
おまけ
通信の多重化で特許を取得しています。


