【ISSUE】RaspberryPi + OBD2 で取得した車両情報を解析してみる

0

2024年12月23日 17:28

オフィスや自宅を快適にするIoT byゆめみ③ Advent Calendar 2018

さて、このAdvent Calendarの趣旨に合っているのか?と思っている皆さん。「タイトル」的にはアウトですが、「テーマ」的にはセーフという曲折を含めつつ、書いていきます:)

Advent Calendar の趣旨は?

このアドカレのタイトルは「オフィスや自宅を快適にするIoT」ですが、テーマは「続々と登場するIoTガジェットやサービス。果たして実際に生活は豊かになるのか?皆さんが試してみた、生活や身の回りを改善するIoTプログラミングを、教えてください。」
とあったので、「自分の好きな車 = 身の回り」ってことにしました(すいません🙇‍♂️)

TL;DR

ODB2 + Raspi で車の走行性能を数値化できる(ようになるための準備ができる)
車種にもよりますが、自分の車では「エンジン回転数」「スピード」を取得してグラフ化しました。下のグラフは回転数のグラフです。

キャプチャ.PNG

ODB2/ODBⅡとは

OBD = On-Board Diagnostics です。ざっくり言えば、元は「自動車の自己診断システム」で、最近では「車両情報」の意味も含まれていると思います。車速、回転数、水温、湯音、CANデータなどなどです。

歴史

1991年、US カリフォルニア州にて、州内で販売される新車に搭載が義務付けられた。
1996年、US 全土でも新車に搭載が義務付け。
2001年、EU でも排出ガス規制の一環で新車に搭載義務付け。
2006年、日本でも新車に搭載義務付け。

2008年時点で、アメリカで販売される全ての自動車にCANを信号のプロトコルとして埋め込む事が義務づけられている

本来の目的のデータ以外にも、車速、エンジン回転数などが取得できる。
規定されているデータの種類(PID)は100種類 + 各自動車メーカ独自拡張。なので、一概にすべての車に適用はできないかもしれません。

ODB2 ≠ CAN

CAN (Controller Area Network) = プロトコル
OBD2 = CAN 上でやり取りされるデータ

CANの一例

プロトコル備考
SAE J1850 PWMフォードが使用
SAE J1850 VPWドイツの自動車メーカーが使用
ISO 9141-2クライスラーや、ヨーロッパ、アジアの車で使われる
ISO 14230 KWP2000Keyword Protocol 2000
ISO 15765 CANボッシュによって開発された。他のOBDプロトコルと違って、変種が自動車業界の外でも使用されている。

システム構成

今回OBD2からデータ取得するために、以下のようなシステム構成になりました。

スペック等備考
検証車TOYOTA カローラフィールダー エアロツアラー
OBD2コネクタELM327 Bluetooth対応版iPhone未対応
RaspberryPi3 Model B+Python3, obd2ライブラリ使用
macbook pro

OBD2コネクタ

image.png

結構いろんな種類あるんですが自分はこれを使ってます。はずれが多いらしいんですが、これは問題なく使えてるので大丈夫かと

超小型モデル OBDII 診断 ELM327 Bluetooth ブルートゥース スキャンツール テスター OBD2 - Amazon.co.jp

システム説明

主にBluetoothを制御するstart.shと、OBD2からデータを取得しExcelに落とし込むlogging.pyの2つのファイルで構成されています。
実行するときにはstart.shsudoで実行することで、Bluetooth設定が終わったら自動的にlogging.pyが起動します。

start.sh

img

この各行の意味を追っていきたいと思います。

hciconfig

hciconfigとはBluetooth(BT)をコマンドラインユーティリティから使うためのコマンドです。Bluezデーモンを使うのでインストールされてない場合は以下の通りインストールします

img

無事インストールできれば、BTが認識できているか確認してみます。以下のようにBT機器のMACアドレスが表示されてればOKです。

img

確認ができたらhcitool -aでBTモジュールを確認します

img

RaspiにあるBTモジュールが認識されていれば、このような感じの情報が出力されます。このhci0というのがデバイスごとに割り振られるデバイスIDです。このデバイスIDを使って通信するBTモジュールを指定します。なので、メモしておきましょう。

sudo hciconfig hci0 up

このコマンドでデバイスIDがhci0のデバイスの電源をUPにします。このコマンドを実行してsudo hciconfigを確認したときにUP RUNNINGという表記がされていればOKです。

img

rfcomm

rfcommはBluetoothの通信プロファイルに1つです。このプロファイルでは、通信上はBluetoothで接続されているデバイスと通信を行うのですが、見かけ上、シリアル通信としてプログラムできるという利点があります。

image.png

rmmod

Loadable Kernel Moduleのアンロードを行います。後で説明するmodprodeで読み込んだ情報を削除します。OBD2の接続するとき毎回行う必要はないかもしれないんですが、念のためやってます。rfcomm自体は再起動すると設定が失われます。逆に言えば電源が入っていればずっと保持されるので、rmmodしておいたほうが無難かと...。

modprobe

rmmodの反対でLoadable Kernel Moduleのロードを行います。modprobe rfcommrfcommプロトコルが利用可能になります。

rfcomm bind

rfcommセクションでも説明したようにrfcommプロトコルを利用すれば、シリアル通信としてプログラムできるようになります。しかし、そのままではシリアル通信として利用できないので、シリアルポートにrfcommbindする必要があります。バインドする先は/dev/rfcommXです。Xは0~9などの任意の数値を指定できますが、今回は0を指定しておきます。

img

ここのAA:BB:CC:11:22:33とは接続先のBTのMACアドレスです。sudo hcitool lescansudo hcitool scanで見つけたMACアドレスをメモしておきましょう。ただ、今回利用するELM327モジュールは全てAA:BB:CC:11:22:33に統一されているようでした。

ls /dev | grep rfcomm

無事にバインドが成功していれば、ls /dev | grep rfcommを実行すれば先ほど指定した番号のシリアルポートが確認できるかと思います。

rfcomm listen

先ほどバインドした番号のシリアルポートに来るデータ読む(listenする)コマンドを実行します。これを実行することで/dev/rfcomm0に流れてくるデータを他のプログラムでも確認することができます。1はチャンネルを表しています。

img

&とは、このrfcomm listenというコマンドはプロセスとして動作します。このlistenの動作自体はバックグラウンドで動作してもらいたいので&を付けます。つまり、この&を付けて実行したコマンドはバックグラウンドで動作するようになります。

logging.py

使用しているOBD2ライブラリの公式サイトはこちら

img
obd.OBD()で先ほどbindしたポート等と確認して自動的にOBD2スキャンツール(ELM327)にアクセスしてくれます。その接続先(データ取得先)をconnectionという変数で保持し、今後この変数に対して、値の要求などを行います。
接続に使用するポートを変更したいときには、以下のように使用するポートを指定します。

img

接続できているかは以下で確認できます。

img

OBDStatusには以下が定義されています

img

Basic Usage

img

基本的な使い方としては上記の通りで、connectionに対して値を要求するクエリを実行します。そのクエリの返り値が要求した結果となっています。別にcmdを使わなくてもconnection.query(obd.commands.SPEED)でも動作します。お好みで

Module Layout

このライブラリのレイアウトは以下の通りです。すべてを使いこなせる気はしませんが...。

img

csv出力

img
データ出力する先と改行を指定します。ファイルの出力先はlogging.pyと同じ位置になりますが、パス指定すれば任意の場所に出力することも可能です。データをファイルに書き込むときには以下のように記述します。

img

取得したデータ分析

この取得したデータを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はportsbrewでインストールになります。

今回は「エンジン回転数」のデータを使って、回転数のピーク部を検出して印付けしたいと思います。100%検出できるわけではないです。以下のような画像のグラフを作成します。
キャプチャ.PNG

解析データ作成

生成したcsvのデータから、解析したデータのみを取り出します。今回はエンジン回転数のファイルを作成します。ファイルの中身は数値のみになります。

img

Octaveでファイル読み込み

Octaveでそれぞれのファイルを読み込みます。この読み込まれたデータはOctave上では行列として認識されます。上記2つのデータの場合「n行1列」のデータ配列となります。しかし、rpm[1] speed[10]のようにアクセスしたい場合は「転置」を行う必要があります。

img

グラフ設定

そして、横軸(時間軸)を決めていきたいのですが、今回は時間を使用した解析は行わないので「1」から連番で振っていきます。

img
これでグラフに表示する準備ができました。グラフを表示するには以下のように記述します。

img

img

グラフ結果

car_blog1.jpg

エンジン回転数のピーク値を見つける

Octaveには様々な計算ライブラリが搭載されています。今回単純にピークを検出するfindpeaksを用います。この関数はsignalパッケージに含まれているため、Octaveのコマンドウィンドウで

img

と打ってもらう必要があります。

findpeaks

実際に先ほどのプログラムにfindpeaksを追加してグラフに表示させてみます。

img

car_blog2.jpg

しかし、このfindpeaksを用いただけでは正常にピーク値を導き出すことができません。今求めたいpeakとは「明らかに突出していて、回転数が前回の測定値よりも格段に大きいとき」という意味を持ちますので、以下のようなpeak値は不要なのです。

car_blog3.jpg

なので、プログラムにひと手間加え、次のようなプログラムが完成します。

ピーク値検出

img

car_blog4.jpg
car_blog5.jpg

修正を加える前よりかは、きれいに取得できていることが分かると思います。

まとめ

世の中には「家具、家電、その他いろいろ」なものに対するIoT製品や記事はよく見かけるのですが、「車」という分野ではあまり見かけないような気がしました。最近では「自動運転」が騒がれていますが、こんな感じの簡単で面白い「情報 X 車」コラボをしたくなったので、あえてレベルを下げてみました。
まだまだ、できることはあります。これをうまく応用して作りこむと
image.png

こんな感じの「自作の」ヘッドマウントディスプレイすら作れるようになると思います。ってかできます。なので、この記事で興味を持った方は調べてみてください。もっと面白いことたくさんあります!!

ではでは~。

ソースコード

https://gist.github.com/nomunomu0504/dc3dc538bbc7738ecdff2a771a0c6c29
[cv:issue_marketplace_engineer]

0

診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。