タイトルの件
拙作のメーター用Webアプリなのですが、
メーターをなめらかに動くように見せるためには、いわゆる30とか60fpsとか言われているように1秒間に30から60回画面を書き換える必要があります。
実際のところ描画にはWebGLを使っている関係上GPUアクセラレーションの恩恵を受けることができるので、描画性能的には割と安いスマホでも60fps出すのはそんなに困難ではありません。(pixi.js様々)
問題なのはECUとかセンサーユニットからデータを取得する方で、秒間60回もデータを取るのはかなり大変です。
特にOBD2-ELM327は通信がかなり遅く、手元のBluetooth ELM327アダプタだと、大体1回の通信で80msの時間がかかります。(USB接続のものならばもう少し早いですが、それでも20~40msはかかります。)
OBD2の通信では原則1回の通信で1種類の車両情報を通信するだけですので、車速・エンジン回転数・水温・ブースト圧を通信しようとすると320msになり、1秒間に3.1回になります。この更新頻度でメーターの画面更新をするなら3.1fpsになりほぼコマ送り状態になってしまいます(*1)。
というわけなので、通信が遅い場合でも表示はなめらかに見せる(見せかける)ために、補完方法を実装しております。
補間方法を説明する動画が↓になります。
真ん中のタコメータの液晶グラフ表示(黒)は生のセンサ情報(240ms間隔)、赤い針が補間後の値になります。
最初のケースでは補間なしですので、240ms間隔の更新になりコマ送り状態です。
次にあるのが以前から実装しているのは線形補間で、
これはセンサ情報の到達頻度を事前集計した上で、現在とその一つ前のセンサ情報値から内挿で補完する方法です。
これを使えば240ms間隔のセンサ情報頻度でも見かけ上なめらかな表示にすることができます。
しかしこの方法は一つ難点がありまして、なめらかに表示できる代わりに補間値がセンサ情報更新間隔(ここでは240ms)だけ遅延します。実際上の動画でも、液晶グラフ表示の回転数に対して赤い針の回転数が遅れているのがわかります。
そこで今回新規に実装するのがPIDコントローラ(を模したjavascriptライブラリ)になります。と言っても実際はほとんど積分ゲインのみ使用しています。
これを使うと、補間値とセンサ値の差が蓄積されるほどセンサ値の増減速度(針の速度)が増えていくようになります。するとなめらかな動きを維持したまま、センサ情報と補間値の差を小さくすることができます。実際上の動画でも液晶表示に追従して針が動いているのがわかります。
ただこの方式も当然完全ではなく、センサ値の増減が入れ替わる瞬間(増えていた回転数が下がり始める瞬間)に補間値が行き過ぎるオーバーシュートが出ます。
グラフで説明すると下図のとおりです。
線形補間法はなめらかに(直線に)値が更新されていますが生の値(青)より遅れて更新、PID補間は生の値に追従していますがオーバーシュートが出ているのがわかります。
(*1)ただ一応ELM327には1回の通信で最大6種類のPID通信が可能な場合があるようで、(データシート p.45によればJ1979対応のECUでCAN通信を行っている場合、らしい)拙作のプログラムでも現在実装を試みているところであり、これが使えれば問題はいくらか緩和します。ただしECUやOBDIIアダプタによっては使えないこともあるようです。)
Posted at 2023/02/15 06:14:46 | |
トラックバック(0) | 日記