いつか黒歴史

いろいろ書きます

WebRTCを使ったカメラ付きラジコンカーをつくりたい

ブログ移しました!

WebRTCを使ったカメラ付きラジコンカーをつくりたい | いつか黒歴史

# はじめに この記事は[東京高専プロコンゼミ① Advent Calendar 2020](https://adventar.org/calendars/5509)の10日目です. [WebRTC Native Client Momo](https://github.com/shiguredo/momo)とRaspberry Piを使って,遠くから操作できるカメラ付きラジコンモドキを作りたいという記事です. タイトルにWebRTCと入っていますが,WebRTCについてよくわかってないです.ごめんなさい. [:contents] # WebRTCとは > WebRTCを使用すると、オープンスタンダード上で動作するリアルタイム通信機能をアプリケーションに追加できます。出典:[WebRTC](https://webrtc.org/) 今回はAndroid上のGoogle ChromeRaspberry Pi上の[WebRTC Native Client Momo](https://github.com/shiguredo/momo)で通信を行います. # インストール Momoの[Relese](https://github.com/shiguredo/momo/releases)より自分にあったファイルをダウンロードします.Raspberry Pi 2,3,4は`momo-_raspberry-pi-os_armv7.tar.gz`という名前のファイルです.`tar xvf [ファイル名]`で解凍できます.中にある`momo`が実行ファイルです. 以下で必要なパッケージを入れておきます.
sudo apt-get install libnspr4 libnss3
# ローカルで動かす ひとまずRaspberry PiAndroid端末がローカルネットワークにある状態で動かしてみます. Momoをtestモードで起動します.
./momo --no-audio-device test
AndroidChromeのアドレスバー以下を入力します.
<Raspberry PiのIPアドレス>:8080/html/test.html
すると以下のようなページが表示されます.
f:id:null_P:20201203124233j:plain
AndroidGoogle Chrome
Connectを押すことでカメラの映像が表示されます. 低遅延です. # 遠隔で動かす WebRTCでP2P接続するためには,お互いの情報をお互いに渡してくれるシグナリングサーバーというものが必要になります. ローカルで動かすtestモードでは、Momoがシグナリングサーバーになっていたのですが,今回はMomoと同じく時雨堂様が開発している[Ayame Labo](https://ayame-labo.shiguredo.jp/)を使い,Raspberry PiUbuntuAndroid端末がLAN内になくても接続できるようにします. けしからんネットワークにより,手元のRaspberry Piではうまく接続ができないので,長野県にいる知人に頼んで,Ubuntuで動かしてもらいました.
f:id:null_P:20201203181115p:plain
ここにいるらしい
## 知人のUbuntu上で環境構築 Momoのインストールは省きます. どうやらカメラがついていないようなので,[v4l2loopback](https://github.com/umlaeute/v4l2loopback)で仮想カメラを作ります. 以下でビルドを行います.
git clone https://github.com/umlaeute/v4l2loopback.git
make && sudo make install
読み込みます.
sudo modprobe v4l2loopback
このままでは何も映っていないカメラなので,ffmpegで動画を流し込みます.`-stream_loop -1`で動画が無限ループします.
ffmpeg -stream_loop -1 -re -i [動画ファイル名].mp4 -f v4l2 /dev/video0
## 動かしてみる [Ayame Labo](https://ayame-labo.shiguredo.jp/)にサインアップして,ルームIDとシグナリングキーを控えておきます. AyameモードでMomoを起動します.
./momo --no-audio-device ayame wss://ayame-labo.shiguredo.jp/signaling [Ayame LaboのルームID] --signaling-key [Ayame Laboのシグナリングキー]
[Ayame Labo](https://ayame-labo.shiguredo.jp/)にサンプルがあるので,そちらを使わせていただきました. ネットワークの問題かMomoが動いているマシンの問題かわかりませんが,カクツクことがあります. 流れている動画は,以前箱根のほうに行った時のものです. # コントロールする このままではただカメラの映像を垂れ流しているだけなので,コントロールできないので,なにか文字列を送れるようにしてみます. Momoは`--serial /dev/ttyhoge,huge`オプションをつけることでWebRTCのデータチャネルとシリアルポートを繋げる?ことができます. 今回は都合のいいシリアルデバイスがないので,`socat`で仮想シリアルデバイスを作ります. ## 仮想シリアルデバイスをつくる `socat`をインストールします.
sudo apt install socat
[こちらの動画](https://www.youtube.com/watch?v=iFmD-CeB96A)をp参考にさせていただきました. 以下を実行して表示されたシリアルポート同士が繋がっています.
socat -d -d pty,raw,echo=0 pty,raw,echo=0
2020/12/04 18:23:04 socat[1664] N PTY is /dev/pts/1
2020/12/04 18:23:04 socat[1664] N PTY is /dev/pts/2
2020/12/04 18:23:04 socat[1664] N starting data transfer loop with FDs [5,5] and [7,7]
今回の場合は,`/dev/pts/1`と`/dev/pts/2`のようです. ## --serialオプションを付けて動かしてみる 今回のMomoの起動コマンドです.
./momo -- serial /dev/pts/1,9600 --no-audio-device ayame wss://ayame-labo.shiguredo.jp/signaling [ルームID] --signaling-key [シグナリングキー]
`cat`でシリアルポートを覗きます.
cat /dev/pts/2
こんな感じで映像以外も送受信できます.Youtubeの動画のほうはUbuntuAndroid別々に録画していますが,電波時計を見ながらタイミングをとったので,互いの録画にあまりズレはないと思います. # タイヤを履かせたいし,ボディも着せたい 車体やコントローラーは現在友人らと制作中です. 今回は`cat`を使っていましたが,PythonやCで`socat`のシリアルポートを読んで,Raspberry PiのGPIOを制御すればラジコンみたいになると思います.Arduinoとかを繋いでもいいかもね... github.com
f:id:null_P:20201204202241j:plain
制作途中のコントローラー