ブラウザから操作可能なラジコンを作る【７-１】



## 【７-１】RaspberryPiから低遅延で映像を飛ばす

映像を飛ばすだけなら、そう難しくありませんが
ラジコンの映像となると、遅延が問題になります。
raspivid等標準の機能では、１～５秒程度の遅延が出るため
間違いなく事故ります。

ここでは、WebRTCを使用した低遅延配信でおなじみ
[OpenAyame](https://github.com/OpenAyame/ayame-web-sdk-examples)を使った映像の受取を作ります。

<br></br>
## 目次
* [【１】Raspberry pi の、GPIOをTypescriptから操作](https://qiita.com/Yasukosan/items/1bf9480c10de7d69c2a4)
* [【２】DCモーターをPWMで速度制御](https://qiita.com/Yasukosan/items/291c76c10be135fd7595)
* [【３】サーボモーターを制御](https://qiita.com/Yasukosan/items/e81c9c9d0159b32e5893)
* [【４】DualSenseをブラウザに接続](https://qiita.com/Yasukosan/items/bf3a085145db84a48823)
* [【５】DualSenseの情報をRaspberryPiに飛ばす](https://qiita.com/Yasukosan/items/400883be94751966221a)
* [【６】DualSenseのチャタリング？問題対応](https://qiita.com/Yasukosan/items/7e52609699b4b71196ca)
* [【７-１】RaspberryPiから低遅延で映像を飛ばす](https://qiita.com/Yasukosan/items/98426f1ba4dea4c9ec5f)
* [【７-２】RaspberryPiから低遅延で映像を飛ばす](https://qiita.com/Yasukosan/items/2246c8a32602ca77ace9)
* [【８】ThreeJSでVRもどきを作成](https://qiita.com/Yasukosan/items/e15e8fd002cf49e3d04d)
* [【９-１】iPhoneの加速度から頭の向きをVRに反映](https://qiita.com/Yasukosan/items/9b4333770baea4110361)
* [【９-２】スマホVRゴーグル向けデザインに変える](https://qiita.com/Yasukosan/items/7f1bb7a9d95cb76f8117)
* [【１０】ラジコン本体の製作](https://qiita.com/Yasukosan/items/0d37c1df5b5d6c02257b)
* 【１１】パワーアップとバッテリー問題の解決

<br></br>
## カメラの接続

### 使用するカメラ
RaspberryPiにUSBで繋ぐ時によくでてくる、このカメラを使用します。
購入時期が６年ほど違いますが、logicoolの[c270n](https://www.logicool.co.jp/ja-jp/products/webcams/hd-webcam-c270n.html)と同等品です
<img
    src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147738/3dc8089c-4430-48d1-b161-65c6bc09e6ec.jpeg"
    width="320"
/>


### 接続確認
オマジナイのようにデバイスが認識されているか確認します。

```powershell
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270 ←　コレ
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```
ここに出てこないと、面倒なので使えないと思ったほうが良いです。

### 対応フォーマットの確認

カメラが対応している映像フォーマットを確認します。
下の方の解像度情報は省いています。
概ねQVGA相当で30fps出せるのと、YUYVに対応しているので
RaspberryPiのハードウェアエンコーダーでh264に変換できます。

```powershell
$ v4l2-ctl --list-formats-ext --device=/dev/video0
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'YUYV' (YUYV 4:2:2)
                Size: Discrete 1280x720
                        Interval: Discrete 0.133s (7.500 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 1280x960
                        Interval: Discrete 0.133s (7.500 fps)
                        Interval: Discrete 0.200s (5.000 fps)
        [1]: 'MJPG' (Motion-JPEG, compressed)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)
                Size: Discrete 1280x960
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.050s (20.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.100s (10.000 fps)
                        Interval: Discrete 0.200s (5.000 fps)

```

<br></br>
## momoのセットアップ

OpenAyaneを利用するのに、[momo](https://github.com/shiguredo/momo)が必須になるのでセットアップを行います。

WebRTCで映像を受け取るだけであれば、[momo](https://github.com/shiguredo/momo)だけで十分ですが
後に控える、iPhoneの加速度取得がhttps必須のため
wss対応のシグナリングサーバー経由で接続する、[OpenAyame](https://github.com/OpenAyame/ayame-web-sdk-examples)を使用する事になります。

シグナリングサーバー自体を作るのは、難しくありませんので
クローズドな環境で構築する必要がある場合でも、対応は可能です。

### 依存パッケージインストール

ここからは、RaspberryPi側で作業を行います。
基本手順は公式のRaspberryPiの[セットアップドキュメント](https://github.com/shiguredo/momo/blob/develop/doc/SETUP_RASPBERRY_PI.md)を参考に行います。


まずは定番の依存ライブラリの追加
```powershell
sudo apt install libnspr4 libnss3
sudo apt install libcamera0.3

sudo apt install libxtst6
sudo apt install libegl1-mesa-dev
sudo apt install libgles2-mesa
```
## 不足ライブラリをビルド

momoが参照するライブラリが一部非推奨になっているようで
ソースからビルドする必要があります。
これ以外でメンテナンスされたライブラリを取得する方法が見つけられなかったため
記載の内容で進めていますが、メンテナンスバージョンがあるなら
そちらを使って下さい。

ビルド環境の準備
### cmake追加
```powershell
sudo apt install cmake
```
### userlandプロジェクトをclone

ビルドで使うディレクトリを作ります。
```powershell
cd ~
mkdir -p git/raspberrypi
cd git/raspberrypi
```
プロジェクトをCloneします。
```powershell
git clone http://github.com/raspberrypi/userland.git
cd userland/
ls
buildme         containers  host_applications  interface  makefiles   opensrc    README.md  vcinclude
CMakeLists.txt  helpers     host_support       LICENCE    middleware  pkgconfig  vcfw
```

### uselandをビルド

何かWarning出たりしますが、気にせず最後まで進めると
恐らく必要なライブラリファイルが生成できているはずです。

```powershell
./buildme
```

### ライブラリのリンクを作成

momoの参照先にリンクを張ります。

```powershell
sudo ln -fs /opt/vc/lib/libbcm_host.so /usr/lib/libbcm_host.so.0
sudo ln -fs /opt/vc/lib/libvcos.so /usr/lib/libvcos.so.0
sudo ln -fs /opt/vc/lib/libvchiq_arm.so /usr/lib/libvchiq_arm.so.0
sudo ln -fs /opt/vc/lib/libcontainers.so /usr/lib/libcontainers.so.0
sudo ln -fs /opt/vc/lib/libvcsm.so /usr/lib/libcontainers.so.0libvcsm.so
sudo ln -fs /opt/vc/lib/libvcsm.so.0 /usr/lib/libvcsm.so.0
sudo ln -fs /opt/vc/lib/libvcsm.so /usr/lib/libvcsm.so.0
sudo ln -fs /opt/vc/lib/libmmal.so /usr/lib/libmmal.so.0
sudo ln -fs /opt/vc/lib/libmmal_core.so /usr/lib/libmmal_core.so.0
sudo ln -fs /opt/vc/lib/libmmal_components.so /usr/lib/libmmal_components.so.0
sudo ln -fs /opt/vc/lib/libmmal_util.so /usr/lib/libmmal_util.so.0
sudo ln -fs /opt/vc/lib/libmmal_vc_client.so /usr/lib/libmmal_vc_client.so.0
```
<br></br>
## monoセットアップ

momo自体のセットアップを行います。
rootディレクトリのほうが良いという記事を見て、猿真似で実行していますが
試した限りでは別のディレクトリでも動きます。

* コントローラーの制御を行うWebSocketサーバー
* WebRTCで映像配信を行うWebRTCサーバー

最終的に２つのサーバーがそれぞれ別で動きますので
WebSocket側とディレクトリが別れていれば、問題ありません。


### rootディレクトリに移動
```powershell
cd /
```
### monoプロジェクトを取得

arm7対応のmomoが必要になりますので
2年ほど前のビルドを落とす必要があります。

・shiguredo/momo
https://github.com/shiguredo/momo/releases

```powershell
sudo wget https://github.com/shiguredo/momo/releases/download/2023.1.0/momo-2023.1.0_raspberry-pi-os_armv7.tar.gz
```
### プロジェクトの展開と実行ファイル移動

```powershell
sudo tar zxvf momo-2023.1.0_raspberry-pi-os_armv7.tar.gz momo-2023.1.0_raspberry-pi-os_armv7/
```

```powershell
sudo mv momo-2023.1.0_raspberry-pi-os_armv7/* ./
```
## テストモードで試験視聴

下記コマンドを実行すると
* カメラデバイス「/dev/video0」を使用
* ハードウェアエンコーダを使用した配信

が始まります。

```powershell
sudo ./momo --no-audio-device test
```

コマンド実行時に、何も表示されなければ恐らく動いています。

実行後、RaspberryPiのIPアドレスが192.168.10.11で作業を行っていますので
ブラウザから「http://192.198.10.11:8080/html/test.html 」にアクセスると
テスト画面から映像配信が受信できるかを確認できます。

こんな画面が出てきますので
「Connect」を押します。
<img
    src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147738/2d0db0fd-de7e-4fd4-91bd-a102bdaec364.png"
    width="320"
/>

映像が表示され
実際にほぼリアルタイムで映像が配信されます。
<img
    src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147738/9b10b2f8-a580-4f4f-ba8d-42dbf8d7bbfe.png"
    width="320"
/>


<br></br>
<br></br>
# UZAYA
Uzayaでは、多分仕事を求めています。
何かの役に立ちそうでしたら、是非お知らせを。