【ISSUE】RaspberryPi + OBD2 で取得した車両情報を解析してみる
2024年12月23日 17:28
さて、このAdvent Calendarの趣旨に合っているのか?と思っている皆さん。「タイトル」的にはアウトですが、「テーマ」的にはセーフという曲折を含めつつ、書いていきます:)
このアドカレのタイトルは「オフィスや自宅を快適にするIoT」ですが、テーマは「続々と登場するIoTガジェットやサービス。果たして実際に生活は豊かになるのか?皆さんが試してみた、生活や身の回りを改善するIoTプログラミングを、教えてください。」
とあったので、「自分の好きな車 = 身の回り」ってことにしました(すいません🙇♂️)
ODB2 + Raspi で車の走行性能を数値化できる(ようになるための準備ができる)
車種にもよりますが、自分の車では「エンジン回転数」「スピード」を取得してグラフ化しました。下のグラフは回転数のグラフです。
OBD = On-Board Diagnostics です。ざっくり言えば、元は「自動車の自己診断システム」で、最近では「車両情報」の意味も含まれていると思います。車速、回転数、水温、湯音、CANデータなどなどです。
1991年、US カリフォルニア州にて、州内で販売される新車に搭載が義務付けられた。
1996年、US 全土でも新車に搭載が義務付け。
2001年、EU でも排出ガス規制の一環で新車に搭載義務付け。
2006年、日本でも新車に搭載義務付け。
2008年時点で、アメリカで販売される全ての自動車にCANを信号のプロトコルとして埋め込む事が義務づけられている
本来の目的のデータ以外にも、車速、エンジン回転数などが取得できる。
規定されているデータの種類(PID)は100種類 + 各自動車メーカ独自拡張。なので、一概にすべての車に適用はできないかもしれません。
CAN (Controller Area Network) = プロトコル
OBD2 = CAN 上でやり取りされるデータ
CANの一例
プロトコル | 備考 |
---|---|
SAE J1850 PWM | フォードが使用 |
SAE J1850 VPW | ドイツの自動車メーカーが使用 |
ISO 9141-2 | クライスラーや、ヨーロッパ、アジアの車で使われる |
ISO 14230 KWP2000 | Keyword Protocol 2000 |
ISO 15765 CAN | ボッシュによって開発された。他のOBDプロトコルと違って、変種が自動車業界の外でも使用されている。 |
今回OBD2からデータ取得するために、以下のようなシステム構成になりました。
物 | スペック等 | 備考 |
---|---|---|
検証車 | TOYOTA カローラフィールダー エアロツアラー | |
OBD2コネクタ | ELM327 Bluetooth対応版 | iPhone未対応 |
RaspberryPi3 Model B+ | Python3, obd2ライブラリ使用 | |
macbook pro |
結構いろんな種類あるんですが自分はこれを使ってます。はずれが多いらしいんですが、これは問題なく使えてるので大丈夫かと
超小型モデル OBDII 診断 ELM327 Bluetooth ブルートゥース スキャンツール テスター OBD2 - Amazon.co.jp
主にBluetoothを制御するstart.sh
と、OBD2からデータを取得しExcelに落とし込むlogging.py
の2つのファイルで構成されています。
実行するときにはstart.sh
をsudo
で実行することで、Bluetooth設定が終わったら自動的にlogging.py
が起動します。
この各行の意味を追っていきたいと思います。
hciconfigとはBluetooth(BT)をコマンドラインユーティリティから使うためのコマンドです。Bluezデーモンを使うのでインストールされてない場合は以下の通りインストールします
無事インストールできれば、BTが認識できているか確認してみます。以下のようにBT機器のMACアドレスが表示されてればOKです。
確認ができたらhcitool -a
でBTモジュールを確認します
RaspiにあるBTモジュールが認識されていれば、このような感じの情報が出力されます。このhci0
というのがデバイスごとに割り振られるデバイスIDです。このデバイスIDを使って通信するBTモジュールを指定します。なので、メモしておきましょう。
このコマンドでデバイスIDがhci0
のデバイスの電源をUPにします。このコマンドを実行してsudo hciconfig
を確認したときにUP RUNNING
という表記がされていればOKです。
rfcommはBluetoothの通信プロファイルに1つです。このプロファイルでは、通信上はBluetoothで接続されているデバイスと通信を行うのですが、見かけ上、シリアル通信としてプログラムできるという利点があります。
Loadable Kernel Moduleのアンロードを行います。後で説明するmodprode
で読み込んだ情報を削除します。OBD2の接続するとき毎回行う必要はないかもしれないんですが、念のためやってます。rfcomm
自体は再起動すると設定が失われます。逆に言えば電源が入っていればずっと保持されるので、rmmod
しておいたほうが無難かと...。
rmmod
の反対でLoadable Kernel Moduleのロードを行います。modprobe rfcomm
でrfcomm
プロトコルが利用可能になります。
rfcomm
セクションでも説明したようにrfcomm
プロトコルを利用すれば、シリアル通信としてプログラムできるようになります。しかし、そのままではシリアル通信として利用できないので、シリアルポートにrfcomm
をbind
する必要があります。バインドする先は/dev/rfcommX
です。X
は0~9などの任意の数値を指定できますが、今回は0
を指定しておきます。
ここのAA:BB:CC:11:22:33
とは接続先のBTのMACアドレス
です。sudo hcitool lescan
やsudo hcitool scan
で見つけたMACアドレスをメモしておきましょう。ただ、今回利用するELM327モジュール
は全てAA:BB:CC:11:22:33
に統一されているようでした。
無事にバインドが成功していれば、ls /dev | grep rfcomm
を実行すれば先ほど指定した番号のシリアルポートが確認できるかと思います。
先ほどバインドした番号のシリアルポートに来るデータ読む(listenする)コマンドを実行します。これを実行することで/dev/rfcomm0
に流れてくるデータを他のプログラムでも確認することができます。1
はチャンネルを表しています。
&
とは、このrfcomm listen
というコマンドはプロセスとして動作します。このlisten
の動作自体はバックグラウンドで動作してもらいたいので&
を付けます。つまり、この&
を付けて実行したコマンドはバックグラウンドで動作するようになります。
使用しているOBD2ライブラリの公式サイトはこちら
obd.OBD()
で先ほどbindしたポート等と確認して自動的にOBD2スキャンツール(ELM327)にアクセスしてくれます。その接続先(データ取得先)をconnection
という変数で保持し、今後この変数に対して、値の要求などを行います。
接続に使用するポートを変更したいときには、以下のように使用するポートを指定します。
接続できているかは以下で確認できます。
OBDStatusには以下が定義されています
基本的な使い方としては上記の通りで、connection
に対して値を要求するクエリを実行します。そのクエリの返り値が要求した結果となっています。別にcmd
を使わなくてもconnection.query(obd.commands.SPEED)
でも動作します。お好みで
このライブラリのレイアウトは以下の通りです。すべてを使いこなせる気はしませんが...。
データ出力する先と改行を指定します。ファイルの出力先はlogging.py
と同じ位置になりますが、パス指定すれば任意の場所に出力することも可能です。データをファイルに書き込むときには以下のように記述します。
この取得したデータをOctave
を使って、解析的なことをしてみたいなと思います。今回利用するのはGNU Octave
です。
GNU Octave は、主に数値解析を目的とした高レベルプログラミング言語である。Octaveは線形ならびに非線形問題を数値的に解くためのコマンドライン·インタフェースを提供する。また、 MATLABとほぼ互換性のある、数値実験を行うためのプログラミング言語として使用することができる。 Octaveは、GNUプロジェクトの一つでGNU General Public Licenseの条件の下のフリーソフトウェアである。 GNU OctaveとScilabは、MATLABのオープンソース代替品の一つである。 ただし、Octaveは、ScilabよりもMATLABとの互換性維持に重点を置いている
Wikipedia - GNU Octave
ダウンロード先はこちら
解析は普通のPCを使います。今回はWindowsを使いますがMacでも同じです。インストール等の開設は省略します。インストーラーで終わってしまうので...。Macはports
かbrew
でインストールになります。
今回は「エンジン回転数」のデータを使って、回転数のピーク部を検出して印付けしたいと思います。100%検出できるわけではないです。以下のような画像のグラフを作成します。
生成したcsvのデータから、解析したデータのみを取り出します。今回はエンジン回転数のファイルを作成します。ファイルの中身は数値のみになります。
Octaveでそれぞれのファイルを読み込みます。この読み込まれたデータはOctave上では行列として認識されます。上記2つのデータの場合「n行1列」のデータ配列となります。しかし、rpm[1]
speed[10]
のようにアクセスしたい場合は「転置」を行う必要があります。
そして、横軸(時間軸)を決めていきたいのですが、今回は時間を使用した解析は行わないので「1」から連番で振っていきます。
これでグラフに表示する準備ができました。グラフを表示するには以下のように記述します。
Octaveには様々な計算ライブラリが搭載されています。今回単純にピークを検出するfindpeaks
を用います。この関数はsignal
パッケージに含まれているため、Octaveのコマンドウィンドウで
と打ってもらう必要があります。
実際に先ほどのプログラムにfindpeaks
を追加してグラフに表示させてみます。
しかし、このfindpeaks
を用いただけでは正常にピーク値を導き出すことができません。今求めたいpeakとは「明らかに突出していて、回転数が前回の測定値よりも格段に大きいとき」という意味を持ちますので、以下のようなpeak値は不要なのです。
なので、プログラムにひと手間加え、次のようなプログラムが完成します。
修正を加える前よりかは、きれいに取得できていることが分かると思います。
世の中には「家具、家電、その他いろいろ」なものに対するIoT製品や記事はよく見かけるのですが、「車」という分野ではあまり見かけないような気がしました。最近では「自動運転」が騒がれていますが、こんな感じの簡単で面白い「情報 X 車」コラボをしたくなったので、あえてレベルを下げてみました。
まだまだ、できることはあります。これをうまく応用して作りこむと
こんな感じの「自作の」ヘッドマウントディスプレイすら作れるようになると思います。ってかできます。なので、この記事で興味を持った方は調べてみてください。もっと面白いことたくさんあります!!
ではでは~。
https://gist.github.com/nomunomu0504/dc3dc538bbc7738ecdff2a771a0c6c29
[cv:issue_marketplace_engineer]
診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。