DJI から教育用インテリジェントロボットとして発売された ROBOMASTER S1 (以降 S1)。ISP でも1台購入してみました。
社内から色々便利に操作してみたい!!と思ったのですが、どうやら操作はスマフォからのみ。そこで目を付けたのは内部に使われている CAN 通信。
今回は、CAN 通信の勉強もかねて、まず S1 を動かしてみる CAN 通信のデータを取得してみることにしました。
※本記事では、S1 の説明書では記載されていない端子に有線接続しているため、S1 の製品保証外となる可能性があります。本記事の内容を参照される場合は自己責任でお願いします。
前置き
ROBOMASTER S1
「教育用インテリジェントロボット」として DJI から販売されています。
スマフォアプリや Windows アプリを用いて操作可能で、プログラミング (Scratch、Python) も可能なのですが、プログラミングもアプリを用いてとなっています。
内部のセンサやモータは CAN 通信を用いて高速に操作を行っているそうです。
当社内組み立ての様子。複数人で分担しながら2時間程度で組みあがりました。
CAN 通信
自動車内のデバイス通信向けに開発されたシリアル通信プロトコルで、1994年に標準規格になって以来、現在はほぼすべての自動車に利用されています。さらに、自動車以外では FA (Factory Automation) を始めとした産業・工業分野へも応用が広がっています。
マルチマスター方式 (どのデバイスからでも通信を行うことができる) を採用していて、通信は2本の信号線の電位差で行うため、少ない配線でデバイス同士を接続することができます。
今回取り組みの動機
S1 はアプリからのみ操作・プログラミング可能。社内 NW に接続することもできないので、もっと自由に扱いたいと考えました。具体的には、他の DJI 製品同様、API か何かで PC から操作してみたい。
そこで、CAN 通信を経由しての操作を検討してみることにしました。
Jetson TX2 で CAN 通信
CAN 通信を行うために必要なもの
CAN 対応デバイスと通信を行うためには以下が必要です。
- 制御デバイス (PC) :
実際の処理を行うデバイス。Raspberry Pi や Jetson TX2 など、シリアル通信できるもの。 - CAN controller :
制御デバイスと通信し、CAN のメッセージを管理する IC チップ。 - CAN tranceiver :
CAN controller からのコマンドを実際の CAN の信号 (電位差信号) に変換する IC チップ。
Jetson TX2 で CAN 通信
今回はJetson TX2 (標準評価ボード付き) を使って CAN データ通信を行うことにしました。
利点として、
- 現在最新版の JetPack 4.2 では、標準で CAN 関係のモジュールを使用可能。
- 評価ボード内に CAN controller が接続されているため、tranceiver のみ用意すれば CAN 通信可能。
があり、CAN の基本的な接続方法さえ押さえてしまえば簡単に CAN 通信ができます。
今回は以下のような回路で、まず Jetson TX2 内で CAN 通信をさせて機能を確認し、
更に、以下のような GPIO ポートにそのまま差すことができる CAN 接続モジュールを作成しました。
( デザインやはんだ付けはそれぞれ得意なメンバにお願いしました。)
Jetson TX2 単体で CAN 通信
S1 と Jetson TX2 で CAN 通信させるにあたって、Jetson TX2 自体の CAN モジュールが正しく動いているのを確認する必要があります。
Jetson TX2 には2つの CAN interface (CAN0, CAN1) がついていて、評価ボードにはそれぞれの CAN controller も用意されているため、Jetson TX2 単体で2つの CAN interface を使って送受信を行うことができます。
回路図の9ピンプラグの「CANH」「CANL」同士を接続し、Jetson TX2 上で以下コマンドを実行することでデータの送受信を行うことができます。
ここでは、CAN1 を受信、CAN0 を送信にしてデータを送受信します。
$ sudo modprobe can
$ sudo modprobe can_raw
$ sudo modprobe mttcan
( 同じ bitrate (1000000) で CAN0、CAN1 をそれぞれ有効化 )
$ sudo ip link set can0 type can bitrate 1000000
$ sudo ip link set up can0
$ sudo ip link set can1 type can bitrate 1000000
$ sudo ip link set up can1
( 確認 : 正常ならば IF 一覧に CAN0、CAN1 が表示される )
$ ifconfig
( CAN1 でデータ受信待ち )
$ candump can1
( 別コンソールにて CAN0 でデータ送信 )
( ID = 123、data = 12 34 56 78 90 ab (6byte) )
$ cansend can0 123#1234567890ab
( 受信側コンソールで受信確認 )
$ candump can1
can1 123 [6] 12 34 56 78 90 ab
終了時やデバイスがおかしくなった場合は down します。
$ sudo ip link set down can1
ROBOMASTER S1 の CAN 通信を読み取る
CAN の導通確認
Jetson TX2 で CAN 通信ができることが分かったので、いよいよ S1 内の通信を読み取ってみます。
まずは CAN の導通を確認します。
S1 の CAN 用ケーブルは、よく見かける 9Pin のタイプではなく、特殊な台形の 4Pin のケーブル。おそらく S1 専用です。組み立て後に余っていたポートにオシロスコープを接続し、電圧変化から CAN のデータが流れていることを確認しました。
オス側基準で、図のように CANH、CANL が流れていました。残った 2Pin はそれぞれ VDD (電源)、GND でした。
また、CAN で通信するためには、通信の速度 (bitrate) を知る必要があります。
これにもオシロスコープを用い、波形の大きさから速度を推測しました。オシロスコープ便利。
Bitrate は、CAN の規格上最大の 1Mbps でした。
Jetson TX2 を接続して CAN 通信読み取り
CAN が流れていることと、ピン配置とが確認できたので、実際に Jetson TX2 と接続してみます。
長ーーいジャンパワイヤで CANL、CANH、RND をそれぞれつないで、
candump してみます。
$ sudo modprobe can
$ sudo modprobe can_raw
$ sudo modprobe mttcan
$ sudo ip link set can0 type can bitrate 1000000
$ sudo ip link set up can0
( dump )
$ candump can0
正しくつながっていると、データが流れてきます。
can0 201 [8] 55 1B 04 75 09 C3 27 CE
can0 201 [8] 00 3F 60 00 04 20 00 01
can0 201 [8] 08 40 00 02 10 04 00 00
can0 201 [8] 04 E9 33 55 14 04 6D 09
can0 201 [8] 04 7B CE 00 04 69 08 05
can0 201 [7] 00 00 00 00 6C B1 1C
can0 203 [8] 55 16 04 FC 04 09 CD E6
can0 203 [8] 00 3F 76 A2 02 89 00 CE
can0 203 [6] FF 2E 00 02 17 71
can0 203 [8] 55 11 04 92 04 03 E3 D0
can0 203 [8] 00 3F 42 CE FF 56 1A 95
can0 203 [1] B4
can0 203 [8] 55 0F 04 A2 04 C3 E5 D0
can0 202 [8] 55 31 04 53 03 04 64 F0
can0 203 [7] 00 3F 2E 80 00 00 E9
can0 202 [8] 20 48 08 00 00 FE 2B 12
can0 202 [8] 00 AF D8 FB 46 E5 90 53
can0 202 [8] 3F 79 C4 FB BE 31 D1 81
can0 202 [8] BD 00 9D 88 3E 1A 2A 14
can0 202 [8] 01 2A FB FF FF 27 00 DB
can0 202 [1] 65
まとめと今後
CAN 通信については、普通は実車でないと試せない仕組みなので、それが動いているのを目の当たりにできたのは良い経験でした。
S1 の操縦についてはまだまだ先は長そうです。
データの読み出しはできたので、送信もできるはず。しかし、データの形式が分からないですね。バイナリを解析するのは大変そうです。
問題をシンプルにしつつ、少しずつ探っていこうと思います。