スマホカメラとSSLとWSS::Raspberry Pi4 + Ubuntu22.04 + ROS2 Humble でロボット作り（その９）

# Webでスマホのカメラを表示する
今回は、Webブラウザにスマホのカメラ画像を表示する手順を書いていきます。
※すでにROS2でWeb接続まで構築した前提で記事を書いております。Webの構築などは過去の記事をご参照ください。

## スマホのカメラをWebブラウザで表示する際の注意点

2023/02/18現在、スマホのカメラをブラウザに表示させるためには、SSL接続（HTTPS）が必要となります。
また、ROS2とのWeb接続をするrosbridge_suiteは、初期設定のままだとws接続になっており、そのままではつながらないのでwss接続に変更する必要があります。
というわけで、まずはSSL接続をするための手順から順に書いていきます。

## SSL接続のための設定

https://qiita.com/shoichi4411/items/fcbe4b0fc2d98c72b55e

こちらの過去記事にて、Webの設定は済んでいる前提で説明していきます。

また、目的としてはスマホをコントローラー代わりにしてロボットを操作するという前提のため、イントラネットでの利用を想定して書いていきます。

:::note warn
外部ネットワークに公開して、遠隔地から操作する場合はドメインを取得したり、後述するSSLの設定も変わってきますのでご注意ください。
:::

### SSL用の認証ファイルの作成

/etc/apache2 以下に設定ファイルを作成します。

```bash
$ cd /etc/apache2
$ sudo mkdir ssl
$ cd ssl
```
スーパーユーザーに切り替えて秘密鍵を作成
```bash
$ sudo su
# openssl genrsa -aes256 2048 > server.key
```
パスフレーズを適当に入れる（覚えておくこと）

自己証明書を作成
```bash
# openssl req -new -x509 -key server.key -days 3650 -sha512 > server.crt
```

作成できたら
```bash
# cd ../sites-available/
# nano default-ssl.conf
```

で、サイトの設定をする

```conf
<IfModule mod_ssl.c>
        <VirtualHost _default_:443>
                ServerAdmin webmaster@localhost
                ServerName [ホスト名].local
                DocumentRoot /home/[ユーザー名]/www/html
                <Directory /home/[ユーザー名]/www/html>
                        Options FollowSymlinks Includes
                        AllowOverride All
                        AddType text/html .html
                        Require all granted
                </Directory>

                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined

                SSLEngine on
                SSLCertificateFile      /etc/apache2/ssl/server.crt
                SSLCertificateKeyFile   /etc/apache2/ssl/server.key

               <FilesMatch "\.(cgi|shtml|phtml|php)$">
                                SSLOptions +StdEnvVars
                </FilesMatch>
                <Directory /usr/lib/cgi-bin>
                                SSLOptions +StdEnvVars
                </Directory>
        </VirtualHost>
</IfModule>

```
:::note warn
[ホスト名]と[ユーザー名]の箇所は適宜書き換えてください。
:::

書き換えたら、apache2.confを開いて
```bash
# cd ..
# nano apache2.conf
```
以下の一文を追加してください。
```
SSLProtocol All -SSLv2 -SSLv3
```
:::note warn
SSLでエラーが出ないためのおまじないです。
:::

できたら、apache2 の再起動
```bash
# systemctl restart apache2
```

すると、パスフレーズを聞いてくるので、秘密鍵を作成した際に入力したパスフレーズを入力

ブラウザで、サイトを https://[ホスト名].local で確認すると「繋がりません」メッセージが出るが、詳細から、それでも繋ぐ的なメッセージをクリックすると表示されます。
※自己証明なのでそのあたりは仕方ないです。

で、このパスフレーズだけど、毎回聞いてくる＆後で記載しているrosbridgeで接続する際もROS側でもパスフレーズを聞いてくるというすごく不便な状態になるので、下記設定でパスフレーズを外す（一応バックアップも取っておく）

```bash
# cd /etc/apacch2/ssl
# cp server.key servker.key.org
# openssl rsa -in server.key -out server.key
```

apacheの再起動でパスフレーズを聞いてこないことを確認
```bash
# systemctl restart apache2
```
一般ユーザーに戻って

```bash
# exit
```

Webサーバー側の設定は完了です。

## rosbridge_suite の設定

次に、rosbridgeのSSLを有効化するため設定ファイルを開いて

```bash
$ cd /opt/ros/humble/share/rosbridge_server/launch
$ nano rosbridge_websocket_launch.xml
```

```xml
  <arg name="ssl" default="true" />
  <arg name="certfile" default="/etc/apache2/ssl/server.crt"/>
  <arg name="keyfile" default="/etc/apache2/ssl/server.key" />
```

のように修正する

修正できたら、実行する

```bash
$ ros2 launch rosbridge_server rosbridge_websocket_launch.xml
```

ブラウザ側は、Javascriptの記述

```javascript
    let ros = new ROSLIB.Ros({
+        url : 'wss://[ホスト名].local:9090'
-        url : 'ws://[ホスト名].local:9090'
    });
```

にかえればOK

これで設定が終わったので、スマホのカメラを表示してみます。

## スマホのカメラ情報取得＆表示

スマホのカメラ情報をブラウザに表示するために過去記事に書いたJavascript、htmlに追記していきます。

```javascript index.js
$(function() {
    // video要素をつくる
    const resolution = { w: 1080, h: 720 };
    let video          = document.getElementById('ctlCamera');
    // video要素にWebカメラの映像を表示させる
    let media = navigator.mediaDevices.getUserMedia({
        audio: false,
        video: {
            width: { ideal: resolution.w },
            height: { ideal: resolution.h },
            facingMode: { exact: "environment" }
        }
    }).then(function(stream) {
        video.srcObject = stream;
    })
    .catch(function(err) {
        console.log(`${err.name}: ${err.message}`);
        alert("カメラとの接続時にエラーが発生しました");
    });

});
```

```html index.html
<div id="camera_view">
    <video id="ctlCamera" width="80" height="60" autoplay nuted playsinline></video>
</div>
```

これで、無事ROS2と接続したままスマホのカメラを表示させることができました。
※レイアウトは適当です。CSSで調整してみてください。

今回は、カメラ画像を取得して表示させただけですが、スマホには傾きを取得することもできるので、スマホの傾きとロボットを連動させることもできそうです。（作ってないですが）

次回は、ロボットのクローラー部分の移動制御とブラウザでのジョイスティック操作を書く予定です。
あ、そのまえにハードウェア編でクローラーの作成記事も書く予定です。

## 目次

* [[←前回]バッテリー監視::Raspberry Pi4 + Ubuntu22.04 + ROS2 Humble でロボット作り（その８）](https://qiita.com/shoichi4411/items/a38261c921746c5d71d5)
* [[次回→]足回りの制作::Raspberry Pi4 + Ubuntu22.04 + ROS2 Humble でロボット作り（ハードウェア編その１）](https://qiita.com/shoichi4411/items/75966efb74bcbf6d78c4)