マイコンカーラリーではエンコーダを使って距離と速度の測定をおこなっています。
距離の方は問題ありませんが、エンコーダパルスから速度を求める場合はサンプリング速度と精度のトレードオフに注意する必要があります。
昨日マイコンカーラリーに熱心に取り組んでおられる先生から
「速度計測のレスポンスを上げようと思ってサンプリング間隔を1mSにしたら速度測定の精度がえらい悪くなってしまって結局元の10 mSに戻した。」というお話を伺いました。
その時はハードウェアに起因する問題と思いましたが、後でゆっくり考えてみるとこれは量子化誤差の影響によるものだと思われます。
エンコーダを使った速度計測は制御でよく使われるテーマなので、解説をまとめてみました。
ロータリーエンコーダについて
マイコンカーラリーロボットは距離と速度を計測するためにエンコーダを使っています。

エンコーダは上図のような構造になっていて軸の回転でA,B 2相のパルスとZ相(原点パルス、無いタイプも多い)を出力します。
信号がA,Bの2相あるのは回転方向を検出するためで、回転の向きに関わらず正確に位置を検出できるようになっています。
マイコンカーラリーは前進しかしないので回転方向の判別は必要ありませんが2相のパルスの、立上がりと立下りを検出することにより100パルスのエンコーダでも400のパルス信号を得ることができます(4逓倍処理)

ロータリーエンコーダによる速度計測の原理

マイコンカーラリーでは上写真のようにロータリーエンコーダの軸にタイヤを取り付けて距離を測定します、測量で使っている距離測定車輪(下写真)と同じ原理です。
ロータリーエンコーダによる距離測定精度について
例えばエンコーダの仕様が100パルス/回転、エンコーダに取り付けた車輪の径が21mmとすると距離分解能は次のようになります。
21 × π / 100 ≒ 0.66 mm 2逓倍で 0.33 mm 4逓倍で 0.165 mm の分解能
距離測定については十分な分解能があり、どちらかと言えば距離測定用車輪のスリップの影響に気を付けなければなりません。
0.165mm分解能で測定できる距離
マイコンカーラリーのプログラムではエンコーダパルスを32bitのlong変数でカウントしているので4逓倍の0.165mm単位でオーバーフロー無しに測定できる距離は
0.165 mm × 231 = 354334802 mm = 354334 m
となり、マイコンカーラリー競技においては全く問題ないことがわかります。
ロータリーエンコーダによる速度計測誤差
エンコーダのパルス数から速度を求めるには
速度 = 距離 ÷ 時間
の関係を使い、単位時間あたりの移動量を単位時間に発生するエンコーダのパルス数から求めて時間で割って速度を求めますが、その際に量子化誤差の影響が生じます。
例えば秒速1 m / S の時 1 mSあたりの移動量は1 mmとなり2逓倍の0.33 mm分解能でも3パルス程度しか発生しません。
上の図でP1,P2,P3,P4がパルスの位置としてその間隔が0.33 mm 、1 mSの移動量 ℓ が1.1 mmの場合、パルスを読み込むタイミングによって 1 mSに3パルスか4パルス発生することになり、 1.1 m/Sの速度が 0.99 m/S と 1.32 m/Sのどちらかの値になってしまい、3割近く速い速度を検出することになり、速度が0.98 m/S すなわち ℓ が0.98 mm の場合は2パルスか3パルスのどちらかになり、 0.66 m/S か0.99 m/S と 3割以上低い速度を検出することになります。
この量子化誤差は速度が速ければ小さく速度が低いほど大きくなり、1 mSサンプリングにおいて速度 0.33 m/S 未満では速度0の検出結果が発生します。
得られた結果を平均すれば正確な速度に近づきますがそれでは応答速度を上げるためにサンプリング間隔を短くした意味が無くなります。
それではどのような手段を用いれば応答速度と精度の両立を図ることが出来るかを次にまとめてみます。
速度計測精度向上のための手法
1.エンコーダの分解能を上げる
産業用には1000 pulse/revを超えるエンコーダがいくらでもありますがマイコンカーラリーに使えるエンコーダはコストとサイズの制限から 100 pulse/rev になっています。
それでもR8Cがサポートしている 4逓倍機能を使えば単純に誤差が1/2になるので まずタイマの設定は 4逓倍にするべきです。
2.速度に応じてサンプリング間隔を変える
マイコンカーラリーでは速度が速いほど速度検出に高い応答性が必要で、速度が遅い場合はサンプリング間隔を長くしても走行姿勢への影響は少なくなります。
例えば 1 mSの割り込みでパルスの数を監視し20パルス以上のカウント差が生じた時点で速度を求めるという処理にすれば5%未満の誤差で、 速度 5 m/S 時には 応答速度 約 1 mS以内 2mS、 速度1 m/Sの時は7 mSの応答速度が得られます(2逓倍時)
4逓倍の場合は40パルス以上のカウント差で計測すれば上記の応答速度で2.5%未満の誤差、5%の誤差を許容すれば速度1 m/Sで4 mSの応答速度が得られます。
3.タイマーでパルスとパルスの間隔を正確に計測する。
回転速度精度0.1%のように高精度な速度計測をおこなう場合はこの手法を使います。
パルス信号でフリーランタイマーの値をキャプチャーすることでパルスとパルスの間隔を正確に計測でき、タイマークロックが高速なほど回転速度計測の分解能も上がります。
この場合に注意しなければならないのはエンコーダの機械精度です。
一回転に生じる100パルスの間隔が完全に均等なのが理想ですが実際にはある程度のバラつきがあり、そのバラつきを抑えるために10パルスとか20パルスをまとめてパルス間隔を測定する必要があります。
パルス間隔を計測する場合はインプットキャプチャが発生する毎に割り込みでキャプチャーしたタイマの値を読みだして処理するのでパルス発生頻度が高すぎると処理が追い付かなくなります。
例えばエンコーダのA相信号の立ち上がりでキャプチャを発生させることにすると 0.66 mm毎に割り込みが発生します。
最高速度6m/Sとして考えると 1mSに 6 / 0.66 =9.1 回で、最短で約0.1 mS毎の割り込みとなり、割り込み関数内の処理を工夫して簡潔にすればR8Cでも何とか処理出来そうな割り込み間隔です。
10MHzでタイマーをカウントアップすれば1パルスだけで理論的には1/1000以上の精度で速度が求められますが、エンコーダの機械的誤差(パルス信号の不均一さ)による誤差が発生するので数パルス以上使って速度を求める必要があります。
機会があればどのくらいのCPU時間占有率でこの処理が実現できるか実験してみたいと思います。