ECUモニタ開発状況

ローバーミニ,すでにクラッシックカーの領域に入りつつありますが,1992年以降に日本で新車として販売されたミニにはインジェクション方式が導入され,制御用のコンピュータECUも載せている。趣味として関数プログラミング言語 Haskell を使ってこの制御用コンピュータのデータをモニタリングしようとしてきましたが,少しづつ開発を進めています。ちなみに現在も引き続き車内にMacBookAirを持ち込んで,運転中に自動記録しつつ,車載モニターにライブデータを表示しています。

スライドショーには JavaScript が必要です。

開発の現況

全体としては安定してモニタリングできるようになり,プログラムの一部を改造しても他の部分に影響を出しにくくなりました(モジュラー化が進んだ。以前は各パーツが密接に絡み合っていたため,一部を改造するとしばらくコンパイルエラーのみならずロジックエラーを誘発していた。)。

Rover Mini ECU(MEMS) Monitor Screen Shot

2019年5月の Rover Mini ECU(MEMS) Monitor スクリーンショット

これは2019年5月にとったスクリーンショット。数値表示だけでは一瞥したときに全体像が把握できないなと,アスタリスクによる各データのリアルタイム棒グラフをつけたもの。

試作したRover Mini ECUモニタの画面

開発が進んだRover Mini ECUモニタのスクリーンショット

そしてこちらは過去データや他のデータとの相関を見たいと思い,縦棒グラフを並べるようになったバージョン。

2019年9月現在の画面

そして現在は複数のデータを同一のグラフに描画しています。一通り走った後,エンジンを停止した状態(エンジンを切っても10秒くらいはECUが動作しています。おそらく冷却液用の冷却ファンをしばらくまわすため)での画面キャプチャ。画面右側は,テキスト表示でむりやり表現した温度や回転数など各種センサー値の重ね合わせグラフ。テキスト表示なのは,ラズパイなど超小型コンピュータで動作させる際に簡単に実現できそうだからです(GUIはメモリや処理能力に要求される水準がTUIに比べて圧倒的に高いが,超小型コンピュータにそれを求めるのは酷ですものね)。

ループ処理や例外処理を見直し,エンジンの稼働状況やECUと繋がれた信号線の状態に影響を受けにくくなり,安定して稼働するようにしました。

こちらのログは岡崎から名古屋に帰る道すがら記録したものです。時々接続が切れて再接続しています(再接続に1秒近くかかっているのはあえて待ち時間を1000m秒入れているから)。路面の凸凹やアクセルオフ時の振動に連動(?)して接続が切れているので,コネクタかセンサ固定に何か問題がありそう。

Rover Mini ECU(MEMS) Monitor CSV Data

Rover Mini ECU(MEMS) Monitor CSV Data

得られた学び

前回の報告から進展したHaskellの学び,Haskell中級編といったところでしょうか。

モナドを作れるようになった

モナド,Haskell初心者のつまづきの石です。わかってしまえばなんてことはない概念ですが,RealWorldHaskellとかでゆっくりまなびつつ,試しにECUとのコミュニケーションモジュールで自作のモナドを作ってみました。裏で動く仕組みが理解できたため,ソースを見ても動作に検討がつくようになりましたし,liftとか融合とか,避けていた知識を身に着けたら,いろんなことがより簡素に表現できるようになりました。結局,ECUとのコミュニケーションモジュールは,出来合いの ReaderT を活用しています。ちなみに,モナドはRealWorldHaskellの記載内容から変わったところ(変わるところ)があるので,要注意。

Haskellでの例外処理を理解した

関数やIOモナド,スレッド間通信などがからむので,"Parallel and Concurrent Programming in Haskell"を電子書籍で購入して並行プログラミング関係だけ読み,初歩はマスターできました。このプロジェクトではマルチスレッド間の資源の取り合いはほとんどないので,できるだけ例外をマスクして,Eitherなどで把握・対処するようにしています。STMを利用したチャンネルで,スレッド間の通信をおこなうようにしました。

Haskell用TUIライブラリを使ってみた

Brickを使ってみました。GUIの基礎概念は知ってはいましたが,使ってみたのはほぼ初めて。プログラミングをよくやっていたのは学生時代で,まだGUIが一般的でない時代にPascalやModula II でPOSシステム,パソコン通信プログラム(端末エミュレータ)などを作っていました。まだオブジェクト指向という考えが広まる前で,インタフェースもGUI普及前。ユーザーとしては,まわりがワープロを使っている時代にMacintosh Plusで卒業論文を書いていたのでまさにエバンジェリストといった感じでしたが,イベント処理とか,GUIやオブジェクト指向でのクラスとかいった概念は,Smalltalkでちょっと触ったくらい。学び直しました。とはいえ,Brickのドキュメントを読むと一通り書いてあるので,それで済ませましたが。

グラフの作成

TextPlotというそのものズバリの名前の,テキスト文字によるグラフ作成ライブラリを使ってみました。ライブラリのソースを読んでみたのですが,仕組みとしては事前に考えていた内容そのものであったものの,その表現が関数プログラミングの利点を活用してすごく簡素に書かれていてびっくり。ただ,機能がシンプルで,随分前に進化が止まっているようなので,カラー化とか凡例表示とか,Vector化とか,いろいろ改造していきたい。

今後の計画

ラズパイでの稼働

本来はMacBookAirなどノートパソコンではなく,ラズパイなど超小型コンピュータで稼働させたいところですが,大型ライブラリBrickを使うために,ラズパイで直接コンパイルすることは難しそう。Docker と QEMU でクロスコンパイル環境を用意しましたが,stack を利用してのコンパイルはまだ完了していません。これをなんとかしたい。

グラフ表示の改善

表示要素が多いと,グラフの把握が難しくなります。カラー機能自体は既に使っていますが,TextPlot側が対応していないので,要改造。
また,凡例表示や,X軸時刻表示(今は単なる相対時系列番号)も課題。

終わりに向かって

ハードの監視というきわめてHaskell向きではない分野で手続き的な表現を多用していましたが,少しづつ関数プログラミングらしい表現を取り入れています(FunctorやAplicativeFunctorな演算子の導入とか)。抽象化が進むので,機能を増やしてもそれほどソースの行数が増えず,実行速度もあまり遅くならないことに感動。

OLYMPUS DIGITAL CAMERA