4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Zoom Video SDKを使用したロボットの遠隔監視システムを作ってみる。

Last updated at Posted at 2022-07-18

この記事は、Qiita Engineer Festa 2022に参加するために執筆した記事です。

Qiita Engineer Festa 2022の「Zoom API/SDKを使ってみよう」のテーマに参加します!!

自己紹介ときっかけ

まずは、簡単に自己紹介しようと思います。

私は、明治大学大学院 先端数理科学研究科 ネットワークデザイン専攻のロボティクスを専門とする研究室の人間です。
日々、ロボットの自律走行の研究や強化学習を用いたロボットの研究を行っています。

特に私の研究は、移動ロボットとスマホアプリが複数参加することができるロボットネットワークを用いて、ロボットを遠隔操作するシステムの開発を行っています。

では、なぜ、ZoomのVideo SDKを使おうと思ったのか....................

私が、現在目指している研究では、移動ロボットにカメラを装着し、カメラ映像を確認しながらスマホアプリで移動ロボットを遠隔操作するシステムを開発することです。
つまり、ロボットの前方の映像を確認しながらスマホアプリでロボットを遠隔操作するロボットの巡回監視システムみたいなものです。
そのためには、必要なこととして

  • ロボットの映像を低遅延にスマホアプリに送信できること
     映像を見ながらロボットを操作するので遅延があっては、ロボット走行システムとして問題あり。
  • ロボットから受け取った映像を自分の開発するスマホアプリ内に埋め込むことができること
     映像確認と移動ロボットを同じスマホアプリで完結させ、できるだけユーザーの操作量を減らしたい。

が必要不可欠です。
そのために、動画共有サービスや各種動画配信サービスが提供するAPIやSDKを調査したり、実際に使ったりしました。
しかし、上にあげた二点のタスクを達成することがなかなかできませんでした。

そんな中、Zoom Video SDKを見つけ、Qiita Engineer Festaというものもやっていることも知って、これは神様に「Zoom SDKを使って記事を書け」と言われているんじゃないかと思いました(笑)。

システム構成

システム構成図はざっくりこんな感じ。
image (1).png

  • ハードウェア構成
    ロボット: Turtlebot2
    ロボット操作用PC: Surface GO 3
    Webカメラ: Logicool社製Webカメラ
  • ソフトウェア構成
    ロボットは、ROS(Robot Operating System)を使用し、ロボット操作用PCで管理
    ロボットの全面に装着したWebカメラもロボット操作用PCにUSB接続
    スマホアプリの十字キーを使ってロボットを遠隔操作
     ※ ロボットネットワークロボットの遠隔操作システムに興味がある方はこちら
    スマホアプリの十字キーの上にロボットの前方の映像を表示(今回目指していること

今回は、二つのZoom Video SDKを使用します。
ロボット操作用PCでWeb用のZoom Video SDK

スマホアプリでAndroid用のZoom Video SDK

Zoom Video SDKを使ってみる

Zoom SDKとはどんなものなのか?

Zoom SDKには主に2つのSDK(Meeting SDK & Video SDK)があります。
この二つはどう違うの? 
注目したのは、Video SDKでは、デフォルトのZoom Meetings UIを使用せず、Videoのやり取りの部分を使うことができることです。
先ほどのシステム構成図にあるように、これまでに開発したロボット操作用の十字キーの上にロボットの映像だけを埋め込みたいからです!
では、ようやく使っていきましょう。

注意
Zoom Video SDKを使用するにはVideo SDK planに加入する必要があります。こちらから

Zoom Video SDK for Web

ロボットに装着したWebカメラの映像をスマホアプリに共有するためにWeb用のZoom Video SDKを使用します。
Zoom Video SDK公式ドキュメントを参考にやっていきます。
ページ内の Sample Apps から Video SDK Web Sample を選択し、サンプルアプリのGithubのページへ移動します。

Githubページ内のドキュメント通り進めていきます。

サンプルアプリのインストール

git clone https://github.com/zoom/sample-app-videosdk.gi

react-demoとpurejs-demoという二つのサンプルアプリがありますが、今回はpurejs-demoを使っていきます。

purejs-demoディレクトリへの移動とインストール

cd sample-app-videosdk/purejs-demo
npm install

次にconfig.jsファイルを開きます。
sample-app-videosdk/purejs-demo/src/js/config.jsを開きます。
ここでは、SDK Keyの入力やミーティングを識別するためのセッション名を設定します。
セッション名は、Androidでの開発にも使うので覚えておきましょう。

config.js
export default {
    sdkKey: 'YYdjlwLjfahvaypXrY5KvCiTbX1EOZdKtGMh',
    sdkSecret: 'YGnMpzY02u3IssEsWUidKwKTpFa6mUcyX2Gv',
    topic: 'Turtlebot',// セッション名
    password: '1104', // パスワード
    name: 'robot_user', // ユーザー名
    sessionKey: '1104',
    user_identity: 'test_user'
};

注意
アプリ実行の際にwebpack.config.dev.jsファイルでエラーが発生する場合があるようです。
Webpackのファイルの書式をV3からV4へと変更する必要があります。
変更部分(ファイル内のdevServer{}を変更)

webpack.config.dev.js
devServer: {
    static: {
      directory: path.join(__dirname, ''),
     },
    https:{
    cert: './localhost.crt',
    key: './localhost.key',
    },
    host: '0.0.0.0',
    port: 3000,
    hot: true,
    client:{
      overlay: true,
    },
    
    historyApiFallback: false,
    //disableHostCheck: true,
    headers: {
      'Access-Control-Allow-Origin': https
        ? 'https://0.0.0.0:3000'
        : 'http://0.0.0.0:3000',
      'Cross-Origin-Embedder-Policy': disableCORP ? '' : 'require-corp',
      'Cross-Origin-Opener-Policy': disableCORP ? '' : 'same-origin'
    },
    open: 'index.html'
  },

アプリの実行に成功するとこんな感じ。
zoom.png

Zoom Video SDK for Android

次にAndroid用のVideo SDKをを用いてスマホアプリを開発していきます。(開発環境は、Android Studio)
参考サイトはこちら

JWTトークンの生成

Video SDK Planに加入した際のSDK Keyをもとにスマホアプリ開発に必要なJWTトークンを発行します。
こちらのサイトを参考にJWTトークンを生成します。

基本的には、公式ドキュメントの通りに進めて行きます。
今回のこの記事では、自分のアプリ用に変更をした部分を載せていきます。

Viewの配置

ロボットの映像を表示するViewを既存の十字キーの上に配置します。

actiity_robot.xml
  <us.zoom.sdk.ZoomVideoSDKVideoView
            android:id="@+id/robotVideoView"
            android:layout_width="match_parent"
            android:layout_height="261dp"
            android:layout_marginStart="10dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/joinButton" />
 
                             <!--      十字キーのView     -->

  • ユーザー名をapp_userとして参加
RobotActivity.kt
  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_robot)
       
   //         中略

        joinButton.setOnClickListener {
            if (ZoomVideoSDK.getInstance().isInSession) {
                leave()
            } else {
                join("app_user") // ユーザー名を変更
            }
        }
   }

セッション名やパスワード、JWTトークンの設定

Zoom Video SDKでは、ミーティングの識別をセッション名で行うため、セッション名(今回は”Turtlebot”)を同じにすることでビデオのやり取りを可能にします。
また、先程生成したJWTトークンを” token ”に入力します。

RobotActivity.kt
 private fun join(name: String) {
        val audioOptions = ZoomVideoSDKAudioOption().apply {
            connect = true
            mute = false 
        }
        val videoOptions = ZoomVideoSDKVideoOption().apply {
            //localVideoOn = true // Turn on local/self video upon joining
        }
        val params = ZoomVideoSDKSessionContext().apply {
            sessionName = "Turtlebot" //セッション名
            userName = "app_user" // ユーザー名
            sessionPassword = "1104" // パスワード
            token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBfa2V5IjoiWVlkamx3TGpmYWh2YXlwWHJZNUt2Q2lUYlgxRU9aZEt0R01oIiwidHBjIjoiVHVydGxlYm90Iiwicm9sZV90eXBlIjoxLCJzZXNzaW9uX2tleSI6IjExMDQiLCJ1c2VyX2lkZW50aXR5IjoidGVzdF91c2VyIiwiaWF0IjoxNjU3ODc5Mzg2LCJleHAiOjE2NTc4ODY1ODZ9.4urEhbcGX7H-CaYEwG_a_SkU1fbalQUDmDh7hcPvX8w\n" // TODO: Pass in your JWT. In a production app, ensure that you do not hard code JWT or any confidential credentials.
            audioOption = audioOptions
            videoOption = videoOptions
        }

        val session = ZoomVideoSDK.getInstance().joinSession(params)
        if (session != null) {
            Log.d(TAG, "joinSession")
            Log.d(TAG, "  sessionName: $session.sessionName")
            Log.d(TAG, "  sessionID: $session.sessionID")

            val videoHelper = ZoomVideoSDK.getInstance().videoHelper
            videoHelper.startVideo()
            videoHelper.switchCamera()  //内カメか外カメ
        }
    }
  • ロボット側ユーザーの参加の確認
    ロボットが正常に参加すると、Android StudioのLogcatでrobot_userが参加していることがわかるはずです。
override fun onUserJoin(
                userHelper: ZoomVideoSDKUserHelper?,
                userList: MutableList<ZoomVideoSDKUser>?
            ) {
                Log.d(TAG, "onUserJoin")
                userList?.forEach { user ->
                    Log.d(TAG, "  userName: ${user.userName}") // ログ表示

                    user.videoCanvas.subscribe(
                        remoteVideoView,
                        ZoomVideoSDKVideoAspect.ZoomVideoSDKVideoAspect_Original
                    )
                }
            }

変更点は以上!!!!!!

基本的な流れは、セッション名を同じものにし、ロボットとスマホアプリの映像のやり取りを実現させ、受け取ったロボットの映像を十字キーの上のViewに配置するという流れです。(だいぶ簡略化してますが…)

実験動画

それでは、実際に研究室内を走行させてみた動画をご覧ください。

まとめ

今回は、Zoom Video SDKを使ってロボットが巡回する遠隔監視システムを作りました。
実際に動かしてみるととても簡単に使うことができ、さらには低遅延なロボット操作をすることができ、とても楽しかった!!
この機会を与えてくれたQiita Engineer Festa 2022とZoomさんに感謝します。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?