概要
- ChainerCVのdetection example + tellopyでトイドローンを自動で動かしてみたお話
- アプリケーションとしては人についていくものプログラムを作った
- !注意!
- 安全面は各自の自己責任でお願いします
- 周りに人が居ないか,ぶつかっても壊れるようなものがないかを確認してください
- (ドローン自体の個体差等があるため)コードそのままコピペしても動くとは限りません
- コードはあくまで参考程度にし,自己責任で一行づつ実装してください
- そうしないと思わぬ事故が起こりえます(実際デバッグしている時,結構怖かったです)
- 安全面は各自の自己責任でお願いします
- 2019/01/07 ver1.0
- 2019/01/08 ver1.1 コメント追加
まえがき
何か作って発表しないと単位が降ってこない授業を履修していたので,何か作る必要が生じていた. 「ディープラーニング,ハヤッテル」くらいのノリで作ったブツで発表したものがあったのでWeb記事に供養したというお話.
あんまり大したこともしていないし,この記事の中身もそんなにないけど強いて言うのであれば, “転がっている学習済モデルを使って”(重要),ディープを何かにくっつけたアプリケーションは, 大した技術力もいらずかつ短時間でそれっぽく見えるなにかを作れるってことかなぁ.
関連研究のsurveyとかは特にしていないので,やり方被っている某がある可能性大. なので,もし知っている方がいたらTwitter等で教えていただけると助かります. あと研究界隈だとドローンって表記せずUAVとかマルチコプターとか言う気がするけど,これはあくまでお遊びなのでドローン表記で.
ソースコード
- https://github.com/scepter914/TelloFollowingPerson
書き散らしただけでリファクタリング全くしてないコードなのはご容赦を
環境構築 && version
- READMEに書いたのでそちらを参照を
処理の流れ
- host PCからTelloに制御信号を送って初期位置へ移動させる
- Telloから画像を取得,host PCに画像を送る
- ChainerCVでObject Detectionをして,トラッキング対象物(人)の検出と画像内位置を取得
- 取得したデータでTelloの移動制御を行い,hostPCからTelloを移動させる信号を送る
Telloとは
DJIから販売されているトイドローン. Amazonから買えて1万円超えくらい. Pythonから叩けるので遊ぶのに便利. ggるといろいろ記事が出てくる.
- 参考
Telloの自動制御
pythonでtelloを動かすライブラリのTelloPyを使った. ノートPCでtelloのwifiに繋いで,exampleコードを動かすとドローンが自動で動く便利なブツ.いや本当に凄い. これだけで結構遊べる気がする.
import tellopy
help(tellopy)
を見ればなんとなく中身が分かる. というか元実装が読みやすいので,元実装見ながらのコーディングがおすすめ.
- 参考
Object Detection Task
使ったライブラリはChainerCV,なので使うフレームワークはChainer. ChainerCVはDeepの学習済モデルとか含めてよしなにexampleから簡単に動かせるライブラリ.実際くっそ楽. 今回はChainerCVのObject Detectionのサンプルコードを利用する. Object Detectionはざっくりいうとinputの画像に対して, オブジェクトを検出して「四角で囲んだここにはhogeがある」って言ってくれるタスクのこと.
そして今回使ったアルゴリズムはみんな大好きYOLO(You Only Look Once). YOLOはObject Detectionタスクのアルゴリズムの一種. 詳しくは論文読んでください.
Detectionのコードはhttps://github.com/chainer/chainercv/tree/master/examples/yoloにあるdemo.pyほとんどそのまま. ここではFPSを上げたかったのでsampleにあったYolo v2 tinyを使った. ここでうだうだ説明するよりChainerCVの実装を読んだ方が早いのであとは省略.
あとなぜだかよくわからんけどexampleのコードをそのまま動かしたら
File "demo.py", line 7, in <module>
from chainercv.experimental.links import YOLOv2Tiny
ImportError: cannot import name 'YOLOv2Tiny'
とerrorが出たので,でっちあげでファイルコピってimport周りを少し書き換えた.(非常にクソ解法)
-
追記 2019/01/08(コメント貰ったので捕捉)
- Yolov2tinyはRelease前だったからでした
- git cloneして pip install -e chainercv/
-
参考
- https://github.com/chainer/chainercv ChainerCV
Telloの移動制御
- くっそ
稚拙シンプルな実装 - Detectionによってbounding boxの座標,ラベルが求まるので,(複数人映っている可能性も考慮して)人間(label == 14)がラベルのものの重心位置とbounding boxの平均面積を算出
- 左右,上下: 重心位置が画面の中心にくるように,(適当なゲインを調整して)上下左右に移動する
- 前後: 平均面積がある閾値になるように,(適当なゲインを調整して)前後に移動する
- 人に近づくとbounding boxの面積は大きくなる,人から遠ざかるとbounding boxの面積は小さくなる
図を作るのすらもめんどい
他に参考にしたもの
- http://robonchu.hatenablog.com/entry/2018/10/09/215542 yolo + tello
- https://github.com/mutsuyuki/DroneControllByYOLOv2 yolo + tello ジェスチャー
- https://github.com/Ubotica/telloCV/ tello * CV
結果
それっぽく動いたけれど,自分のノートPCのCPU onlyでDetectionの推論が0.15fpsで結構しんどい気持ちになった. 自分のコードの書き方が悪いのかもしれないけど,単純にスペック不足…?
他感想的な
実装に関して
- 当たり前だけど一気にやらずに一個一個実装していった(テストコードも特にリファクタリングしていないのでGithubに乗せたままな気がする)
- 順番としては
- ChainerCVのYoloのdemoをそのまま動かす
- videoから画像を取ってきてYoloのdemoに突っ込むのでFPSを確認
- videoからとってきた画像でドローンの制御指定値の算出のデバッグ(実際にドローンを動かしていない)
- ドローン単体でtake offとlandが動くことを確認
- ドローンに前後上下左右の指令を出して,どのくらい移動量があるかを確認
- ドローンから画像をとってこれるかを確認
- ドローンからとってきた画像でDetectionしてみる
- ドローンからとってきた画像で制御指定値の算出を確認(実際にドローンを動かしていない)
- 実際に人に付いていくデモをしてみる
- こんな感じで実装した.
トイドローンについて
- バッテリー持ち
すぐにバッテリーが切れるので,案外デバッグ(というよりパラメータ調整)が捗らなかった. 充電待ちの時間が結構あったので,もし時間に迫られる+何かを作らないといけない,みたいなシチュエーションだとあんまりトイドローンを使うのはおすすめできないかも.
- デバッグ
デバッグがマジで怖い… 例えば本来whileを抜けるはずなのに抜けないバグを仕込んで,着陸しようとしないとかいうバグを仕込んでしまったバカがいたわけです. Telloはありがたいことにバッテリーがすぐ切れるので,充電切れによりことなきを得たけど.もし数十分飛んでたらどないしようと思った. 因みにこれ作る間に,不時着によりプロペラ一個破壊しました.(Tello買うと予備プロペラが4つ入っているのでゆーても壊れるものなのかもしれない) 皆様もお気をつけを…