前回、ミリ波レーダの前振りをして今回は FMCW という現実的な方法を説明しようと思っていましたが、前回の最後にちょっと触れた短い時間電波を照射してそれが反射して戻ってくるまでの時間を測定するという方法を「もしこれでやろうとするとどうなるか」を少し深掘りしてみようと思います。こういう妄想は頭のトレーニングになると信じていて、要は課題達成、問題解決のための引き出しを増やすことになるのではないかと思っています。
前回軽く計算したとおり、電波を何かに照射して戻ってくる時間を測定した場合、戻ってきたときには発信電波は終わっていないといけないので(受信アンテナ=送信アンテナの場合。違っても回り込まれたら同じ)、たとえば 10m を測定しようとしたら 67ns となってエネルギー的に短そう、かといって長い距離だけを測定しようとすると反射電力が小さいので(後で触れます)これも難しそうということでした。
その辺りの事情は置いておき、対象物の反射率が高くて、またアンテナの指向性も強いとしてそれなりの S / N で電波が戻ってくると云う前提とします。
そうならば、アナログ的には送信波、受信波を BPF などの強い共振回路を通して信号波の存在を確認して、それらの時間差を測定すればいいわけです。ただ、強い共振回路だとノイズに対しても勝手な共振信号を作ってしまうので、さじ加減が難しそうです。
デジタルでやる場合はどうでしょうか。デジタルフィルタで BPF を作ったらアナログ共振回路と同じことが起きて、ちょっとしたノイズをきっかけに共振周波数が続いてしまいそうです。そこで DFT というか、当該周波数の正弦波と余弦波を重畳してそのベクトル和を積分することで信号の存在が確認する方法が考えられます。
scilab スクリプトで確認してみます。
clear
rand('seed',0) // 乱数のもと
N=10000; // ポイント数
randomdata=((rand(1,N,'uniform'))-0.5) // 乱数発生
noise_m=0.1 // ノイズレベル
attenation=0.2 // 受信信号レベル
n=[1:N]
t(n)=(n-1)/N
t=t'
frequency=200 // 発振周波数
frequency1=200 // 評価周波数
sig_size=1000 // 発振周波数の長さ
t_delay=1600 // 戻ってくるまでの時間
sig_start=1001 // 送信信号のスタート時刻
sig_end=sig_start+sig_size-1 // 送信信号の終了時刻
rec_start=sig_start+t_delay // 受信信号のスタート時刻
rec_end=rec_start+sig_size-1 // 受信信号の終了時刻
s_sin=sin(2*%pi*frequency1*t) // 重畳正弦波
s_cos=cos(2*%pi*frequency1*t) // 重畳余弦波
sig(n)=0
sig(sig_start:sig_end)=sin(2*%pi*frequency .*t(1:sig_size)) // 送信信号生成
rec(n)=0
rec(rec_start:rec_end)=sin(2*%pi*frequency .*t(1:sig_size)) // 受信信号生成
rec_act=sig+attenation*rec+noise_m*randomdata' // トータル信号
mix1=s_sin.*rec_act // 正弦波重畳
mix2=s_cos.*rec_act // 余弦波重畳
s_power=abs(rec_act) // 受信信号レベル
// clf(1);scf(1);plot(t,mix1,t,mix2,t,s_power)
s_filter(1:N)=0
for i=1:N-sig_size
s_filter(i)=(sum(mix1(i:i+sig_size-1))^2+sum(mix2(i:i+sig_size-1))^2)^0.5 // 信号照射時間単位での総レベル
if s_power(i+1) < s_power(i) // レベル信号のピーク検出
s_power(i+1)=s_power(i)*0.99
end
end
delay=200
d_filter(1:N)=0
d_filter(delay+1:N)=s_filter(1:N-delay) // 距離検出のための遅延信号
pulse(1:N)=0
p_window(1:N)=0
for j=1:N
if d_filter(j)>s_filter(j) // コンパレータ
pulse(j)=1
end
if s_power(j)>0.1 // ウィンド生成コンパレータ
p_window(j)=1
end
end
s_filter(N-sig_size:N)=0
s_power(N-sig_size:N)=0
sig_axis0=[0,1,0,1.5]
sig_axis1=[0,1,-1.5,1.5]
sig_axis2=[0,1,0,0.5]
clf(100);scf(100);
subplot(4,1,1);plot(t,rec_act)
mtlb_axis(sig_axis1)
title('Received signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
subplot(4,1,2);plot(t,s_power,t,p_window)
mtlb_axis(sig_axis0)
title('Burst signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Burst signal','Signal window')
subplot(4,1,3);plot(t,s_filter/sig_size,t,d_filter/sig_size)
mtlb_axis(sig_axis2)
title('Filtered signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Filtered signal','Deleyed signal')
subplot(4,1,4);plot(t,pulse,t,pulse.*p_window)
mtlb_axis(sig_axis0)
title('Position pulse','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Peak position','Position pulse')
そこかしこにコメントを入れておきましたが、照射時間単位で受信信号と正弦波余弦波それぞれを重畳してからその総和を取って、三角波のようなものを作り、そのピーク位置を検出するためそれを遅延したものとを比較して、ピーク位置が立ち上がりになるようなパルスを作ります。
で、その立ち上がり時間差が照射~反射~受信の時間を表す、というものです。
遅延と比較することでピーク検出できるからくりは、こちらをご覧下さい。
ピーク検出をしたいけど、微分器は難しい。
http://blogs.yahoo.co.jp/susanoo2001_hero/7543384.html
この方式は同じレベルが続くとノイズで余分なパルスが出まくるので、受信信号の絶対値を取ってピーク検出を行い、送信波、受信波が存在している領域をウィンドとして取得しておき、ノイスを除去します。
結果はこんな風になりました。

一番下の緑の線の立ち上がり時間差を観測すれば距離を算出することが出来ます。
いかがでしょうか。上手くいきそうでしょうか。出来ないとすれば何が障害となるのでしょうか。
やはり S / N が気になりますね。それと周波数をどうするかが難しいです。ミリ波を使ったらどうなるかというと、その周波数をサンプリングする A / D コンバータが必要ですが、ちょっと技術的にどうか。かといって周波数を下げていくとアンテナは大きくなるし、指向性が悪くなります。一般にミリ波帯域だと光に周波数が近づいているので、直進性を良くすることが容易と云われています。
ただサンプリング周波数の話は解決手段があって、受信信号全体に一旦周波数の違う信号を足してビートを起こさせて、そのビートから送信タイミング、受信タイミングを検出する方法があります。いわゆるヘテロダインという方法です。
仮にそれでサンプリングの問題は解決したとしても大変そうですかね。
ところで今述べたヘテロダインという方法は FMCW 方式で出てきますので、今回はその前振りも兼ねています。(後付け)
前回軽く計算したとおり、電波を何かに照射して戻ってくる時間を測定した場合、戻ってきたときには発信電波は終わっていないといけないので(受信アンテナ=送信アンテナの場合。違っても回り込まれたら同じ)、たとえば 10m を測定しようとしたら 67ns となってエネルギー的に短そう、かといって長い距離だけを測定しようとすると反射電力が小さいので(後で触れます)これも難しそうということでした。
その辺りの事情は置いておき、対象物の反射率が高くて、またアンテナの指向性も強いとしてそれなりの S / N で電波が戻ってくると云う前提とします。
そうならば、アナログ的には送信波、受信波を BPF などの強い共振回路を通して信号波の存在を確認して、それらの時間差を測定すればいいわけです。ただ、強い共振回路だとノイズに対しても勝手な共振信号を作ってしまうので、さじ加減が難しそうです。
デジタルでやる場合はどうでしょうか。デジタルフィルタで BPF を作ったらアナログ共振回路と同じことが起きて、ちょっとしたノイズをきっかけに共振周波数が続いてしまいそうです。そこで DFT というか、当該周波数の正弦波と余弦波を重畳してそのベクトル和を積分することで信号の存在が確認する方法が考えられます。
scilab スクリプトで確認してみます。
clear
rand('seed',0) // 乱数のもと
N=10000; // ポイント数
randomdata=((rand(1,N,'uniform'))-0.5) // 乱数発生
noise_m=0.1 // ノイズレベル
attenation=0.2 // 受信信号レベル
n=[1:N]
t(n)=(n-1)/N
t=t'
frequency=200 // 発振周波数
frequency1=200 // 評価周波数
sig_size=1000 // 発振周波数の長さ
t_delay=1600 // 戻ってくるまでの時間
sig_start=1001 // 送信信号のスタート時刻
sig_end=sig_start+sig_size-1 // 送信信号の終了時刻
rec_start=sig_start+t_delay // 受信信号のスタート時刻
rec_end=rec_start+sig_size-1 // 受信信号の終了時刻
s_sin=sin(2*%pi*frequency1*t) // 重畳正弦波
s_cos=cos(2*%pi*frequency1*t) // 重畳余弦波
sig(n)=0
sig(sig_start:sig_end)=sin(2*%pi*frequency .*t(1:sig_size)) // 送信信号生成
rec(n)=0
rec(rec_start:rec_end)=sin(2*%pi*frequency .*t(1:sig_size)) // 受信信号生成
rec_act=sig+attenation*rec+noise_m*randomdata' // トータル信号
mix1=s_sin.*rec_act // 正弦波重畳
mix2=s_cos.*rec_act // 余弦波重畳
s_power=abs(rec_act) // 受信信号レベル
// clf(1);scf(1);plot(t,mix1,t,mix2,t,s_power)
s_filter(1:N)=0
for i=1:N-sig_size
s_filter(i)=(sum(mix1(i:i+sig_size-1))^2+sum(mix2(i:i+sig_size-1))^2)^0.5 // 信号照射時間単位での総レベル
if s_power(i+1) < s_power(i) // レベル信号のピーク検出
s_power(i+1)=s_power(i)*0.99
end
end
delay=200
d_filter(1:N)=0
d_filter(delay+1:N)=s_filter(1:N-delay) // 距離検出のための遅延信号
pulse(1:N)=0
p_window(1:N)=0
for j=1:N
if d_filter(j)>s_filter(j) // コンパレータ
pulse(j)=1
end
if s_power(j)>0.1 // ウィンド生成コンパレータ
p_window(j)=1
end
end
s_filter(N-sig_size:N)=0
s_power(N-sig_size:N)=0
sig_axis0=[0,1,0,1.5]
sig_axis1=[0,1,-1.5,1.5]
sig_axis2=[0,1,0,0.5]
clf(100);scf(100);
subplot(4,1,1);plot(t,rec_act)
mtlb_axis(sig_axis1)
title('Received signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
subplot(4,1,2);plot(t,s_power,t,p_window)
mtlb_axis(sig_axis0)
title('Burst signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Burst signal','Signal window')
subplot(4,1,3);plot(t,s_filter/sig_size,t,d_filter/sig_size)
mtlb_axis(sig_axis2)
title('Filtered signal','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Filtered signal','Deleyed signal')
subplot(4,1,4);plot(t,pulse,t,pulse.*p_window)
mtlb_axis(sig_axis0)
title('Position pulse','fontsize',4)
xlabel('Time','fontsize',2)
ylabel('Level','fontsize',3)
legend('Peak position','Position pulse')
そこかしこにコメントを入れておきましたが、照射時間単位で受信信号と正弦波余弦波それぞれを重畳してからその総和を取って、三角波のようなものを作り、そのピーク位置を検出するためそれを遅延したものとを比較して、ピーク位置が立ち上がりになるようなパルスを作ります。
で、その立ち上がり時間差が照射~反射~受信の時間を表す、というものです。
遅延と比較することでピーク検出できるからくりは、こちらをご覧下さい。
ピーク検出をしたいけど、微分器は難しい。
http://blogs.yahoo.co.jp/susanoo2001_hero/7543384.html
この方式は同じレベルが続くとノイズで余分なパルスが出まくるので、受信信号の絶対値を取ってピーク検出を行い、送信波、受信波が存在している領域をウィンドとして取得しておき、ノイスを除去します。
結果はこんな風になりました。

一番下の緑の線の立ち上がり時間差を観測すれば距離を算出することが出来ます。
いかがでしょうか。上手くいきそうでしょうか。出来ないとすれば何が障害となるのでしょうか。
やはり S / N が気になりますね。それと周波数をどうするかが難しいです。ミリ波を使ったらどうなるかというと、その周波数をサンプリングする A / D コンバータが必要ですが、ちょっと技術的にどうか。かといって周波数を下げていくとアンテナは大きくなるし、指向性が悪くなります。一般にミリ波帯域だと光に周波数が近づいているので、直進性を良くすることが容易と云われています。
ただサンプリング周波数の話は解決手段があって、受信信号全体に一旦周波数の違う信号を足してビートを起こさせて、そのビートから送信タイミング、受信タイミングを検出する方法があります。いわゆるヘテロダインという方法です。
仮にそれでサンプリングの問題は解決したとしても大変そうですかね。
ところで今述べたヘテロダインという方法は FMCW 方式で出てきますので、今回はその前振りも兼ねています。(後付け)