PSDの精度を計測する

PSDは安価なわりに精度が高く、ロボコンでは広く使用されている赤外線 測距センサです。測定レンジは100-800mm、近くなるほど精度が高くなるという特徴があります。ここではその精度の限界を調べてみます。

時間の分解能

まず時間ですが分解能はほぼ固定です(±5msと精度はありますが、変換のタイミングを知ることができない以上、上限値で固定で考えた方が楽でしょう)。PSDは時間の分解能は50msと射程のわりに案外よくありません。これが効いてくるのは特に旋回中のセンシングです。

30deg/secで旋回していると30*50E-3=1.5deg毎に捜査するので、距離800mmにある物体の捜査の間隔は以下のようになります。

(2Π*800)*(1.5/360)=20[mm]
一周12秒の超低速旋回ですら2cmの分解能となります。対象物の大きさが知能ロボコンの対象物(半径5,6cm)と考えると有無の判別に使用できるギリギリの値です。より小さな物体をロボットが旋回しながら探査する場合は、もっと速度を落とすか、探査範囲を狭める、もしくはセンサ数を増やさないといけないということになります。

距離の精度の理論値

PSDから得られる距離の精度の理論値は、ADCの精度と、PSDの距離-出力電圧の勾配から計算できます(縦軸:出力電圧[V]、横軸:距離[cm])。具体的には、

Δl =Δv * ( ∂l / ∂v ) ( ∂l / ∂v ) : PSDの距離-出力電圧勾配 Δv:ADCで計測できる電圧の精度 Δl:PSDで計測できる距離の精度

まずSH2のADCは分解能は10bitですが精度9bitです。つまり10bitのうち、下1bitは誤差でON/OFFしてしまう可能性があるということです。電圧に換算すると以下の通りです。

5V/(2^9)=0.00977[V]

ここで、PSDのデータシートから距離-出力電圧曲線から大体の数値を読み取り、gnuplotを使って近似します。近似曲線はf(x)=a/x+b+c*xとします。理由は曲線が見た目が大体1/xになっていること、極値を持たないこと(x2の要素が無いこと)です。基本的に山勘です、深い意味はありません。

$ cat > original.txt << EOF 10 2.4 20 1.4 30 1 40 0.82 50 0.65 60 0.50 80 0.45 EOF $ gnuplot gnuplot> f(x)=a/x+b+c*x gnuplot> fit f(x) "original.txt" via a,b,c a = 20.0773 +/- 1.013 (5.044%) b = 0.437557 +/- 0.08808 (20.13%) c = -0.00349243 +/- 0.001283 (36.75%) gnuplot> set terminal png size 320,240 gnuplot> set output "original.png" gnuplot> plot f(x), "original.txt"


この近似曲線から、電圧-距離の勾配を計算します。ここでΔv(x)はADCの精度±0.5[bit]=0.00977[V]です。 Δl =Δv * ( ∂l / ∂v )

∂v(x)/∂x = -a/(x*x) + c Δx = -1/(a/(x*x)+c) * Δv(x)

よって、測定可能な距離の精度は以下のとおりになります(縦軸=誤差のPeak-To-Peak[cm]/横軸=距離[cm])。※誤差は、±(縦軸の値/2)になります。

gnuplot> f2(x)=abs(1/(-a/(x*x) +c)*0.00977) gnuplot> set terminal png size 320,240 gnuplot> set output "error.png" gnuplot> set xrange [10:80] gnuplot> plot f2(x)


距離の実測値

時間の精度および、PSDの出力の曲線は実測値も理論値も代わりませんが、そのままではADCの精度は実測値では9bitも出ません(距離は理論値と実測値が違うということになります)。だいたい値が10000ぐらいになる程度のところで、精度を改良してみます。なお、SH2のADCで読み取った値は下6bitは0で埋められており、値が26単位でしか変化しないように見えますのでご注意ください。

デフォルト

(縦軸:計測値、横軸:時間)なにも細工せず、ADCにPSDを直結した場合です。値はかなりふらついています。スパイク状のノイズが入ってしまっています。


コンデンサ(10μF)を入れる

(縦軸:計測値、横軸:時間)スパイク状のノイズはデジタル回路から入ったものだと考え、PSDの電源とGNDの間にコンデンサを入れてみました。スパイクはへりましたが、値はふらついています。


さらにボルテージフォロア回路を追加

(縦軸:計測値、横軸:時間)入力インピーダンスが大きくなるからノイズに幾分強くなるはず…が、なんも変わらん。これは無意味なようです。


さらにコンデンサを追加(330μF)

(縦軸:計測値、横軸:時間)PSDは瞬間的に電力を結構食うらしい、ということで330μFを追加。初めに比べスパイクが激減し、値も落ち着いています。この値は使えそうです


実測値xフィルタリング

平均値フィルタ

(縦軸:計測値、横軸:時間)フィルタ長さを10で平均値フィルタを噛ませてみると、ノイズの影響が小さくなります。が、あまりフィルタを長くすると応答性能が悪化するので、微妙です。PSDが50ms程度で出力変化します。フィルタ長さ10だと、500/2ms=0.4秒…遅過ぎ


メディアンフィルタ

(縦軸:計測値、横軸:時間)やはり、スパイクノイズにはメディアンフィルタでしょう。フィルタ長さを3ぐらいでもスパイク状のノイズが小さくなります。LSBで±2に落ち着きます。これが一番の候補です。


実測値xフィルタリング(メディアン)x増幅

(縦軸:計測値、横軸:時間)PSDの出力は範囲が狭いので、増幅してからADCに入れれば実質精度は倍になるはず。ということで、非反転増幅回路で2倍に増幅した上でフィルタリングしたところ、出力値は±2に落ち着きました。増幅前の精度±1bitに相当します。


結論

実測値の誤差はフィルタリングなどの方策を施せば、理論値の倍の以下に収めることができます。このグラフの横軸の距離で、±縦軸の値だけ誤差が入ることになります。

精度向上に有効なのは以下の処理。


よた話:失敗事例

PSDを使っていて、いろんな失敗があります。ほとんど知識不足とヒューマンエラーですが。

参考文献/サイト

goto TOP
このドキュメントはフリーです。
勝手に再配布/変更しても構いません
$Date: 2006/11/07 03:20:40 $
$Revision: 1.1.1.1 $