からあげ帝国における闇の技術開発（DJI RONIN-Sの外部制御対応）

# からあげ帝国ってなに？

からあげ帝国とは、AIで有名で、闇のエンジニアとして君臨されているからあげ皇帝が建国された仮想国家といわれております。なぜからあげ先生とよばず、からあげ皇帝となっているかというと、帝国とは「皇帝が元首である国家」のことらしいからです。（今調べた）

からあげ帝国は、その国民の大多数が闇のエンジニアであるからあげ先生を崇拝していることもあり、国家の闇のエンジニアリング力は非常に高いと考えられるため、その闇のエンジニアリング力の一端を今回記載したいと思います。

## でもって、本題

筆者は、最近自動車系の業務ばかりしていますが、もとはロボティクス技術を専門とするエンジニアで、からあげ先生を闇の師と仰いでおり、闇のエンジニア見習いとして、日々ロボティクス技術を鍛錬しています。

ロボティクス技術というと自律移動ロボットが一番に浮かびますが、ただ単純に自律移動するだけでは意味はなく、最近ファミレスなどで見かける配膳ロボットや、TVなどでも取り上げられている食品盛り付けロボットなど、様々な技術を組み合わせた技術が求められています。その中で、需要がありそうなものの、なかなか一般的に手を出しにくい領域に、自動撮影ロボットがあると思っています。なぜ、自動撮影ロボットが難しいかというと、搭載するカメラの振動をどのように抑えるか、また、被写体に対して向きをコントロールするための外部制御可能なジンバルが、市販品で良いものがなかなかなく、ジンバル含めてすべてを自作するということは難しいという課題があります。

そこで、今回（だいぶ前にやっていたのですが、改めてイチから）市販品のジンバルを解析して、外部から制御できるようにしてしまおうという闇の技術について書いてみたいと思います。

## ハードウェアハックの基本

ということで、一般的に市販されているジンバルをハックして、外部からコントロールしてしまおうということになるのですが、一番最初に考えないといけないのが、どのようにして、外部制御可能なデバイスを探すかということになります。

ジンバルで有名なDJIの製品を調べてみると、外部制御可能なジンバルがすでに市販されていることがわかります。ではそれを使えば終わりじゃないかとなりますが、当然費用もめちゃくちゃかかります。ただ、お金を出せば解決できたりするので、ハードウェアハックの基本は、


”金があるなら金で解決しろ”


ということです。

- DJI RONIN RS2
- DJI RONIN RS3 Pro

この2つの新しいジンバルを買ってしまえば、以下のリポジトリのツールなどを使って、比較的容易に外部からジンバルを制御できるようになります。

https://github.com/ConstantRobotics/DJIR_SDK

つまり、金で解決してしまおうというわけです。

ただ、私をはじめ、最新のDJIのジンバルを購入するのは難しいという人も多いと思います。そこで、なんとか中古で安く手に入るジンバルを外部から制御できないかを模索しようというわけです。

## ハックできるか調査してみる

今回、まずはDJIのジンバルの中でも初期に発売されて、最近はヤフオクなどでも比較的安価に手に入れることができるようになったDJI RONIN-Sを題材にハックできるか調査してみようと思います。ただ、市販の製品をいきなりハックして外部から操作しようなど、そう簡単にできません。ですのでまずは、外部から制御できる可能性があるかを検討します。具体的には以下の項目を確認します。

- オプション品などで、外からリモートなどで操作できる製品が販売されていないか？
- 複数のモジュールで構成され、そのモジュール間の通信が何かが比較的容易にわかるか？
- 通信に使用しているプロトコルが比較的楽にアクセスできるものであるか？

以上を確認します。
まず、1つ目のオプション品にリモートで操作できるものがあるかという点ですが、オプション品でなくてもそもそもDJI RONIN-Sはスマートフォンからジンバルを操作することができます。ですので、RONIN-Sとスマートフォンの通信を解析してしまえば、外部から操作することができそうです。スマートフォンからコントロールしていてしかも、DJIのアプリで、すでに外部コントローラ対応をしているようなので、以下のようにPS4のコントローラを使用して、ジンバルを遠隔操作することもできます。

https://www.youtube.com/watch?v=NiStbtbBxZs

とはいえ、外部からコントロールするために、2つ目の項目の通信の仕様がわかるかですが、スマートフォンとRONIN-Sの通信は、おそらくBluetoothかWiFiということになるかと思いますが、これをスマートフォンの通信をハックして代わりに通信するというのは現実的にはかなり厳しいです。というのも、通信内容を解析するために、いろいろとコマンドを送りながら、送信されているシグナルがどう変化していくかを見ていく必要があるのですが、Peer to Peerで接続しているデバイスの通信を盗み見るというのは、専用の機材を手に入れるなど、なかなかハードルが高く現実的ではありません。ですので、この方法で外部操作はできないと考えて良さそうです。

では続いて、他に外部操作する手段がないか調査を進めていくと、今はもう購入できなくなっていますが、遠隔操作のオプションがあるようです。ですので、何かしらのコマンドを外部から送ることで動作させることができそうです。

https://store.dji.com/jp/product/ronin-s-tethered-control-handle

さらに調査を続けていくと、どうやらDJI RONIN-Sは2つの外部通信ポートをあらかじめ用意しているようです。1つ目はS.BUSでこちらの通信は、DJIらしく、ドローンなどのプロポ（いわゆるコントローラ）で使用されているプロトコルで、以下のYouTubeのようにプロポからそのままコマンドを送り込むことができるようです。

https://www.youtube.com/watch?v=JaJVnz8Ks30

ちなみにS.BUSについてはこのあたりのサイトで詳しく説明されていますので、こちらを用いて外部操作することもできそうです。

https://rikei-tawamure.com/entry/2020/03/17/120606

ただ、読んでいただければわかりますが、S.BUSの通信は通常のシリアル通信とは異なり、回路を付け加えないといけないなど、頑張ればできると思われるものの、なかなか大変そうに見えます。ですので、3つの項目のうち最後の比較的楽にアクセスできるかと言われると少し難しそうです。

それでは、最後に残されたCANの通信を調べていきたいと思います。CANは言わずもがな、通信の規格として規定されているので、ツールを用意すれば比較的楽に通信することができそうです。しかもなんと言っても、CANの場合は、機器の通信ラインに外部ツールを接続するだけで、どのような通信が行われているのかをすべて簡単に見ることができます。自動車などでも使われていて、一般的な通信方式で、しかも筆者は過去にDJI RoboMaster S1のCANを解析して、M5Stackなどで外部から操作できるようにした実績があります。

しかも、なんとDJI RONIN-Sの公式のマニュアルにCANを使うときの話が書かれており、そもそも外部通信としてCANに対応しているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179542/49af2a6c-4256-08c6-6ad2-fafa53c6cbd8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179542/e27379a8-1df0-1597-f169-b31523ececf9.png)

こちらのDJI Pro Wireless Receiverを接続することができるようです。

https://store.dji.com/jp/product/dji-pro-wireless-receiver?vid=83931

GitHubを探してみたところ、頑張った人はいたようですが、外部制御できるまでには至らなかったようです。

https://github.com/Wodie/RoninS_CAN

ということで、今回CAN-BUSを使用して、外部から制御可能になるかを進めていきたいと思います。

## CAN-BUS通信に最適なツール

以前私がRoboMaster S1の通信を解析したときには、KvaserというCANのツールを使用して、CANデータの取得を行いました。しかし、なかなか高価ということもあるので、NVIDIA Jetson NXなどのSBCでCANを搭載しているものでも、データ取得できるように、SocketCANをROSで扱えるようにするというツールも作っています。こちらを用いれば比較的容易にCANの解析ができると思います。

https://github.com/tatsuyai713/ros_socket_can_driver

（ただ、まだROS1にしか対応していないですが・・・・

今回もCANの解析はとりあえずKvaserを使用しますが、実際に外部からコントロールするためにKvaserが必要となると、普通にはなかなか手に入らない（Amazonで66000円くらい）ということもあり、実際に外部制御するときは、比較的CANの通信が容易なESP32を搭載したM5Stackに最終的には移植したいと思います。ちなみに筆者はRoboMasterS1をM5Stackで制御するRoboStackS1というリポジトリを公開しています。

https://github.com/RoboMasterS1Challenge/robostacks1

## CAN-BUSデータを解析する

CAN-BUSのデータ解析については、以前DJI RoboMaster S1を解析した際と同じですので、詳細は省略しますが、まずはWindowsであればKvaserとBUSMASTERを用いて、CANのデータのログを取得できるようにします。

すると以下のような形で、CANのコマンドが出ていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179542/0d796da8-183f-f3fd-827f-a874d72288b2.png)

ここで、このログファイルを解析していくことになるのですが、運の良いことに、このデータを眺めていると、RoboMasterS1とほぼ同じであることがわかります。

と言うことで、先頭バイトが0x55で、ヘッダーデータとメインのデータが並んでいる形態であることがわかるため、基本的にデータ解析に困ることはなく、実際にジンバルを付属のジョイステックで動かしながらCANデータを順次取得していきます。

すると以下のことがわかってきます。

- ジョイスティックの操作を行うと、CANのIDが0x12でコマンドが送信されている
- ジョイスティックのコマンドは、ジンバルのロール・ピッチ・ヨーの速度を指示している
- 本体からは、常時CAN IDが0x21に情報が流れており、動きによって変化することがわかる
- 色々ジンバルを操作していきながら0x21のデータの配列を見ていくと、各軸に対するトルク、ロール・ピッチ・ヨーに関しては、目標角度・相対角度・実角度、さらに現在の角速度と思われるデータが出力されていることがわかる

このようにデータを解析した結果、ジンバルのロール・ピッチ・ヨーの角度の情報が出力され、ジョイスティックからは速度のコマンドが出ていることがわかったため、インタフェースさえ適切に用意すれば、目標の角度に制御するような制御機を作成できることがわかります。

## CANでデータのやり取りを行えるようにするドライバを作成する

CANのデータを読み込む機能に関しては、今回はKvaserを使用して、以下の以前に私が作成したROS 2に対応したKvaserのドライバを使用します。

https://github.com/tatsuyai713/ros_kvaser_can_driver

これを用いて、取得したCANのフレームは/can_rxにデータがくるため、そのデータを読み込み、独自のメッセージ型を定義し、DJI RONIN-SからくるデータをROS 2ネットワークに出力するようにします。一方、外部の何かしらのツールからTwistのメッセージを受け取り、その角速度指示を使用し、DJI RONIN-Sに搭載されているジョイスティックと同じメッセージを送信することで、仮想的にジョイスティックで指示しているように、ROS 2の世界の指示をCAN経由でRONIN-Sに送信します。

この辺りのパッケージは、以前にRoboMasterS1で作成したものと大きく違いはないですが、CRCの計算はRoboMasterS1と同じであることは確認しつつも、Initialの値を総当たりで探すなどを行う必要があります。

そして、作成したものが以下のパッケージになります。

https://github.com/tatsuyai713/ros_ronin_s_driver

## まとめ

今回はからあげ帝国の技術開発として、ハードウェアハックをすることで、外部制御できないジンバルをROS 2で操作できるようにしてみました。DJIは相変わらず、CANの使い方がおかしいですが、たまたまRoboMasterS1と同じフォーマットであったこともあり、簡単にハックすることができました。これによって、ROS 2でロボットと連携して動かすような撮影のロボットなどを、古くてそれなりにオークションでも安くなってきたDJI RONIN-Sを使用できるようになりましたので、選択の幅が広がったかと思います。（DJIさんには怒られるかもですが・・・・