ArduinoとCAN-BUS Shield V2を用いて、アルトワークスが出力しているCANデータを取得してみた。今回は、アルトワークスのESP(Electric Stability Program)が出力していると思われるCAN ID 0x1B8(16進数であることを明確にするために、以降冒頭に0xをつけて、0x1B8と記載する)の車輪速情報を取得した。
車輪速情報を取得できると、馬力計測を行った記事はこちら
このように、何かと便利なCAN情報ではあるものの、通信プロトコルを理解していないと単なる数字の羅列でしかない。そこで、CANの0x1B8のデータを「人間が見やすい数値データ」に変換する必要がある。
プログラムは、プロトコルさえ理解できれば単純なビット演算となるため、難易度はそれほど高くはない。この記事では、CANで送られてきた0x1B8のCANデータを数値データに変換する方法を紹介する。
ArduinoでCANデータIDを取得してSDカードに保存
CANプロトコル解析の結果、アルトワークスのESP(Electronic Stability Program)の情報は、CAN ID 0x1B8に含まれていることがわかった。そこで、ArduinoとCAN-BUS Shieldのフィルタ機能を使って0x1B8のみSDカードに保存するプログラムを作成し、全開加速データを取得した。
Arduinoのプログラムはこちら
車輪速データ(アルトワークスの場合0x1B8)のデータを見る
保存したデータをテキストエディタで開き、抜粋したのがこちら。
69532,440,8,4,74,4,74,4,68,4,66
69542,440,8,4,74,4,73,4,67,4,65
69552,440,8,4,73,4,73,4,65,4,64
69562,440,8,4,72,4,72,4,65,4,65
69572,440,8,4,72,4,72,4,63,4,66
69582,440,8,4,70,4,67,4,61,4,67
69593,440,8,4,66,4,68,4,59,4,63
69606,440,8,4,71,4,67,4,61,4,62
69618,440,8,4,63,4,68,4,61,4,61
69630,440,8,4,66,4,67,4,58,4,59
69641,440,8,4,67,4,67,4,58,4,58
69654,440,8,4,66,4,64,4,57,4,56
69667,440,8,4,62,4,69,4,57,4,56
データは左から、サンプリング時間[ms]、CAN ID、DLC(データ長)、0バイト目、1バイト目、2バイト目、…7バイト目の順で格納されている。ここから、車輪速を計算する。
データの変換
データ抜粋の一行目(69532msecのデータ)は、以下のような並びになっている。
TimeStamp | CAN ID | DLC | Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
69532 | 440 | 8 | 4 | 74 | 4 | 74 | 4 | 68 | 4 | 66 |
これが何を意味しているかというと、
Timestamp:69532
Arduinoが起動(リセット)してからの経過時間。69.532秒経過した時のデータであることがわかる。1行だと意味はないが、次のタイムスタンプが69542であることから、10ミリ秒後に次のデータを取得している事がわかる。加速度は速度の微分で求められるので、時間情報はとても重要だ。
CAN ID:440
16進数(HEX)変換すると0x1B8。IDは、11bitなので、0x000~0x7FF(0~2047)までの数字が入ることになる。
DLC:8
データ長を示している。この後に続くバイト数がわかる。CANメッセージによっては、データ長が8Byteだったり、7Byteだったり、4Byteだったりすることがある。今回0x1B8は、8Byteのメッセージであることを示している。
Byte0~7
この部分に実際の車輪速データが格納されている。解析は別途説明するが、アルトワークスの0x1B8データは解析により、ESP(Electronic Stability Program)の4つの車輪速であると思われる。ESPが出力している車輪速は以下のような構成。
Byte0 | 車輪速フロント右の上位バイト |
Byte1 | 車輪速フロント右の下位バイト |
Byte2 | 車輪速フロント左の上位バイト |
Byte3 | 車輪速フロント左の下位バイト |
Byte4 | 車輪速リア右の上位バイト |
Byte5 | 車輪速リア右の下位バイト |
Byte6 | 車輪速リア左の上位バイト |
Byte7 | 車輪速リア左の下位バイト |
ここで、例えばフロントの右の車輪速を求めてみる。ログデータの1行目を再度見てみると、69532,440,8,4,74,4,74,4,68,4,66 となっており、Byte0, Byte1はそれぞれ、4, 74である。
Byte0、Byte1の数値を速度に変換
算出には色々な方法があるが、今後、bit単位の解析をする際に汎用性が高いので2進数で計算してみる。
Byte0のデータ4を2進数で表すと b00000100(バイト単位なので、8ビットで記載。先頭のbはビット表記を表す)。Byte1のデータ74は、b01001010となる。車輪速は、Byte0とByte1の2つのバイトで表現され、Byte0が上位バイト、Byte1が下位バイトである。
これらビットが立っているところを足し合わせると、1098となる。
0x1B8車輪速のFactorと呼ばれる係数(解析して突き止める必要がある)は、解析の結果0.025だった。この0.25を1098にかけてやると、1098✕0.025=27.45km/h。これが、Byte0、Byte1が示しているフロント右の車輪速を意味している。
(アルトワークスのCANはビッグエンディアンで格納されていたのでリトルエンディアンでの解析方法は省略。今まで解析したことのある車両は全てビッグエンディアンだった)
ここまで、CANデータから車輪速を取得する原理について解説したが、Excelで簡単に計算することができる。
Excelで計算
生のログデータと、それをもとにExcelで計算した結果は以下からダウンロード可能(Excel形式のファイルは、念のためウィルススキャン推奨)。
Byte0,Byte1を指定して、Excelの場合は、以下の式で計算できる。
=( BITLSHIFT([Byte0],8) + [Byte1] )*0.025
[Byte0]、[Byte1]に実際に取得した値を入れる。
BITLSHIFT関数は、10進数で入力した値を2進数変換して左側にビットシフトする。今回は8bit左にシフト(すなわち256倍することになる)した結果を10進数で取得できる。
一応、一度ビット変換(この記事の説明の通り、10進数のログデータを一度8ビットに変換した後にビットシフトする)処理も別シートに記載しておいた。
今回のような車速データの場合は2バイト(16ビット)をそっくりそのまま利用する事ができるが、例えば、
・HondaのVSA車輪速など、バイトを跨ぐ場合
・クラッチを踏んだ、踏んでいない、というようなスイッチのON/OFFを表す1bitの解析をしたい場合
などは、一度8ビットに変換してから処理した方が後処理が楽だ。
元の10進数データを BIN2DEC関数を用いて、2進数表記に変換。bin2dec( [Byte0], 8 ) で、10進数を8桁の2進数に変換した。
一度処理のやり方が決まればPythonのほうが早い。以下はソースコード例。
#FR車速の取得 --------------------------------------------------------------------------------------------
# |byte0 |byte1 |byte2 |byte3 |byte4 |byte5 |byte6 |byte7 |
# |11111111|11111111|00000000|00000000|00000000|00000000|00000000|00000000|
# |<-----data ----->|
# --------------------------------------------------------------------------------------------------------
# 先頭からbyte0,byte1を抜き出す
WHEEL_SPEED_FR = canData[:,0:2];
# 抜き出したbyteに対して、対象のビットのみ取得する演算
WHEEL_SPEED_FR = (WHEEL_SPEED_FR & [0b11111111,0b11111111]);
# byte1の最下位ビットが1桁目となるようにビットシフト、byte0の最下位ビットが8桁目となるようにシフト
WHEEL_SPEED_FR = ([WHEEL_SPEED_FR[:,0] << 8 , WHEEL_SPEED_FR[:,1]]);
# byte0とbyte1を足し合わせて、Factor0.025をかける
WHEEL_SPEED_FR = np.sum(WHEEL_SPEED_FR, axis=0)*0.025;
このソースコードはこちらの記事で紹介したPythonコードから一部抜粋
まとめ
今回は、アルトワークスのCAN ID 0x1B8データから車輪速を計算する方法を紹介した。解析の方法が分かれば、CAN情報を用いた様々なプログラムやガジェットが作成可能だ。
データ自体はArduinoで取得可能なので、興味があれば是非チャレンジしてみて欲しい。
コメント