はじめに
こんにちは、ハードウェア/OT 製品開発グループ1 でソフトウェア開発を担当している矢部です。
アプトポッドでは以前より、EDGEPLANT CAN-USB Interface という自社開発製品を取り扱っています。 こちらは車載機器の通信規格であるCAN2 データの送受信に対応したもので、CANバスに接続して使用する製品です。
EDGEPLANT CAN-USB Interface とその周辺プロダクトについては、こちらの記事でもご紹介しておりますので、よろしければご覧ください。
これまでCAN-USB Interfaceは、 弊社のアプライアンス製品 に付属する形としてのみ提供していました。 デバイスドライバーも専用のものを開発・提供しており、専用ソフトウェアからしか利用できませんでした。
今後、幅広いお客様にこちらの製品をお使いいただけるよう、オープンソースのCANドライバーであるSocket CAN3 への対応を進めています。 Socket CANはオープンソースのため、当社の専用ソフトウェアで直接利用する場合と比較すると、インターフェイス機器側で付与されるタイムスタンプが利用できないなど機能面で劣る部分もありますが、様々なサードパーティプロダクトと連携できる点が魅力です。 当社製品をSocket CANを介して利用可能にすることで、サードパーティプロダクトを介して誰でも簡単に当社製品を利用できるようになります。
今回は、CAN-USB InterfaceをSocket CANによってLinuxマシン上で使用する方法についてご紹介します。以降の説明では、当社の車載対応のLinux搭載エッジコンピュータ EDGEPLANT T1 を前提として解説していきます。
これまでの使われ方
前述の通り、これまでは 弊社のアプライアンス製品 という形で何らかの車載ターミナルデバイスとともに提供していました。これらの車載ターミナルデバイスには Yocto4 ベースのOSを搭載しており、CAN-USB Interface用のドライバや、クラウドサーバーへの接続用のクライアントソフトウェアなどが標準で組み込まれています。
こちらを用いたCANデータの可視化については、この記事などをご覧ください。 tech.aptpod.co.jp
EDGEPLANT CAN-USB Interfaceの特長
- Y分岐ケーブルによりCANバス2チャンネル分のデータを取得
- TCXOを搭載、高い周波数精度とタイマー分解能
- ペリフェラル側で、受信直後の正確なタイムスタンプを付与
- デイジーチェーン型のクロック共有機構
- 優れたコストパフォーマンス(価格)
CAN-USB Interfaceは、バスからCANデータを取得した際の正確な時刻情報を記録するため、インターフェイス機器側でタイムスタンプを付与します。インターフェイスにはマイコンが搭載されており、CANバスからデータを受信するとすぐにTCXO(温度補償型水晶発振器)による正確なタイマーによってタイムスタンプを付与します。
たとえばRaspberry PiのようなSPI経由のCANインターフェイスではCPUの負荷次第でCANデータの取りこぼしも起き得ますが、本製品ではマイコンで処理しているため、CANデータを取りこぼすことなく取得できます。(もちろん、本製品からUSBでホストコンピュータに転送する際のバッファなどには注意が必要です)
TCXOの周波数精度は±2.5ppmで、1時間連続計測でも9ミリ秒ほどしか時刻はずれません。また、タイマーの分解能は1マイクロ秒で、タイムスタンプのぶれは10マイクロ秒程度に収まります。さらに、複数台のインターフェイス機器を併用しても打刻ずれが発生しないクロック共有機構を備えており、複数台同期したタイムスタンプを取得できます。クロック共有はデイジーチェーン型の配線でシンプルにつなげることができます。これら高いタイムスタンプ精度と複数台での同期タイムスタンプの機能により、R&Dなど取得されたデータの品質が重要なケースで広くご利用いただいております。
この記事ではSocket CANを介した利用方法をご紹介しますが、CAN-USB Interfaceが持つこれらの機能性や性能を最大限活かすには、当社がご提供する専用ソフトウェアをご利用いただく必要があります。 たとえば、Socket CANを経由してやり取りするデータにはタイムスタンプを付与できないため、インターフェイス側で付与したタイムスタンプは利用できません。
製品の詳細については、CAN-USB Interfaceの製品ページをご覧ください。本製品含め当社のソリューションにご興味をお持ちいただけましたら、当社Webサイトより是非お問い合わせください。
EDGEPLANT T1 でCANデータを見る
続いて、EDGEPLANT T1 上で CAN-USB Interface を利用する方法についてご紹介します。 EDGEPLANT T1 は Ubuntu 18.04 ベースのOSで動作しているため、その他PCなどで Ubuntu がインストールできる環境であれば同様の手順で利用可能です。
CAN-USB Interface を準備する
EDGEPLANT T1 上で CAN-USB Interface を利用するための事前準備を説明します。
ドライバをインストールする
CAN-USB Interface を利用するためには、専用のドライバのインストールが必要になります。CAN-USB Interface のページで公開されているデバイスドライバをダウンロードして、インストールしてください。
インターフェースを確認する
CAN-USB Interface はインターフェースが2つあるため、接続すると can0
と can1
として見えます。
$ ip link show type can 7: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10 link/can 8: can1: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10 link/can
CAN の設定を行う
CANのビットレートを 500kbps に設定する場合、以下のように行います。
$ sudo ip link set can0 type can bitrate 500000 $ sudo ip link set can0 up
up
することで ifconfig
でも確認できるようになります。
$ ifconfig can0 can0: flags=193<UP,RUNNING,NOARP> mtu 16 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
can-utils を利用する
EDGEPLANT T1 にはデフォルトで can-utils がインストールされているため、これを使用してCANデータを見ることが出来ます。
CAN-USB Interface は使用していないですが、Raspberry Pi 上で can-utils を利用した記事もありますので、興味のある方はご覧ください。 tech.aptpod.co.jp
CANデータを受信する
candump
コマンドで受信したCANデータを見ることができます。
$ candump can0 can0 000 [8] 00 00 00 00 00 00 00 01 can0 000 [8] 00 00 00 00 00 00 00 02 can0 000 [8] 00 00 00 00 00 00 00 03 can0 000 [8] 00 00 00 00 00 00 00 04 can0 000 [8] 00 00 00 00 00 00 00 05 can0 000 [8] 00 00 00 00 00 00 00 06
CANデータを送信する
cansend
コマンドでCANデータを送信することができます。例として、can0
と can1
を接続して、データをループバックさせてみます。
can1
も 500kbps で設定して立ち上げます。
$ sudo ip link set can1 type can bitrate 500000 $ sudo ip link set can1 up
can0
からCANパケットを送信して、candump
を実行した can1
でデータを受信することを確認できました。
$ candump can1 & $ cansend can0 001#11.22.33.44.55.66.77.88 $ can1 001 [8] 11 22 33 44 55 66 77 88 // can1 の受信データ
SavvyCAN を利用する
Socket CANに対応した製品は有償無償含め多数存在していますが、ここではオープンソースの Savvy CAN を利用します。EDGEPLANT T1 は ARM アーキテクチャ の Jetson TX2 モジュールで動作していますが、Savvy CANのARM用イメージは配布されていません。自前でビルド、インストールする必要があります。
事前準備
ビルドには、Qt5 と Qt Serial Bus が必要になるので、それらをまずインストールします。
- Qt5 のインストール
$ sudo apt install qt5-default qtdeclarative5-dev libqt5serialport5-dev qttools5-dev -y
- Qt Serial Bus のビルド、インストール
# Overkill: get all qt-stuff $ sudo apt install qml-module-qt-labs-folderlistmodel qml-module-qtquick-extras qml-module-qtquick-controls2 qt5-default libqt5quickcontrols2-5 qtquickcontrols2-5-dev qtcreator qtcreator-doc libqt5serialport5-dev build-essential qml-module-qt3d qt3d5-dev qtdeclarative5-dev qtconnectivity5-dev qtmultimedia5-dev # To get rid of the private/qobject_p.h error $ sudo apt-get install qtbase5-private-dev # Build and install qtserialbus $ cd <work dir> $ git clone git://code.qt.io/qt/qtserialbus.git $ cd qtserialbus $ git checkout 5.9.8 $ qmake $ make -j6 $ sudo make install
Use qt serialbus in ubuntu 18.04 with qt 5.9 · GitHub
SavvyCAN をビルドする
SavvyCAN の 1.0.20 以降は Qt5.10(QRandomGenerator) に依存していますが、L4Tのデフォルトは Qt5.9 になっており、動作できません。
そのため、1.0.20 より前のバージョンを使う必要があります。ここでは V199.1
を使ってビルドします。
$ cd <work dir> $ git clone -b V199.1 https://github.com/collin80/SavvyCAN.git $ cd SavvyCAN $ qmake $ make -j6
SavvyCAN でデータを見る
ビルドした SavvyCAN を立ち上げます。
$ ./SavvyCAN
ツールバーの Conecction → Open Connection Windowを選択します。
Add New Device Connection-> QT SerialBus Device-> socketcan → can* を設定します。
CANフレームを受信することが出来ました。
Python で実装する
これだけではただのツール紹介なので、Pythonを用いてCANデータを扱う方法を簡単にご紹介します。
python-can をインストールする
python-can というライブラリが公開されており、こちらを利用すると簡単に実装することが出来ます。
$ sudo apt install python3-pip $ pip3 install python-can
CANデータを送受信する
can-utils の例と同じく、can0
と can1
を接続して、データをループバックさせてみます。
import asyncio import can def print_message(msg): print(msg) async def main(): can0 = can.interface.Bus(bustype="socketcan", channel="can0", bitrate=500000) can1 = can.interface.Bus(bustype="socketcan", channel="can1", bitrate=500000) listeners = [ print_message, # Callback function ] # Create Notifier with an explicit loop to use for scheduling of callbacks loop = asyncio.get_event_loop() notifier = can.Notifier(can1, listeners, loop=loop) # Send messages for id in range(10): msg = can.Message(arbitration_id=id, data=[id, 0, 0, 0, 0, 0, 0, 0]) await asyncio.sleep(0.5) can0.send(msg) notifier.stop() can0.shutdown() can1.shutdown() loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
このコードを実行すると、以下のように can1
でデータが受信できます。
$ sudo python3 loopback_test.py Timestamp: 1623221566.564898 ID: 00000000 X DLC: 8 00 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221567.066872 ID: 00000001 X DLC: 8 01 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221567.570862 ID: 00000002 X DLC: 8 02 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221568.072851 ID: 00000003 X DLC: 8 03 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221568.574905 ID: 00000004 X DLC: 8 04 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221569.078850 ID: 00000005 X DLC: 8 05 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221569.580852 ID: 00000006 X DLC: 8 06 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221570.082847 ID: 00000007 X DLC: 8 07 00 00 00 00 00 00 00 Channel: can1 Timestamp: 1623221570.584880 ID: 00000008 X DLC: 8 08 00 00 00 00 00 00 00 Channel: can1
おわりに
今回は CAN-USB Interface の紹介になりましたが、その他にもアナログデータを扱うことができる ANALOG-USB Interface も販売しております。
また、自動車からのCANデータの収集や、遠隔適合のためのソリューションとして、以下のプロダクトをご提供しております。
自動車向け遠隔計測ソリューション(CAN/CAN-FD対応)
自動車ECU向け遠隔適合ソリューション
また、自社以外の製品を使用したカスタマイズ事例も多数ありますので、ご興味をお持ちいただけましたら、まずはお気軽に弊社サイトのお問い合わせフォームよりご相談ください。
- OT : Operational Technology の略。ハードウェアおよび組込みソフトの製品開発をミッションとするグループ↩
- Controller Area Network の略。 https://ja.wikipedia.org/wiki/Controller_Area_Network↩
- https://en.wikipedia.org/wiki/SocketCAN↩
- Linuxをベースとして独自にカスタマイズしたシステムを構成できるもの。 The Yocto Project↩