遠隔操作・監視・警備システムを作ってみる

みなさん.こんにちは.滝沢ロボティクス合同会社の田尻です.
最近,多くの方から弊社の遠隔操作・監視システムについてお問い合わせをいただいていますので,簡単にご紹介したいと思います.

遠隔操作・監視システム「RoboLink Powered by TakizawaRoboticsLLC.」

このシステムは,もともと弊社の自律走行ロボットを遠隔で視覚的に確認し,危ない場合は手動で操作することを目的に開発しました.
現在のところ,Android版,Mac版,Linux版,Windows版があり,マウスやタッチパネルで操作可能です.
最近は,安全性の向上やゲームパッドやハンコンを用いた操作,マップ上に現在地を表示するなど拡張機能のアップデート開発を行っています.

遠隔操作システム「RoboLink」
「RoboLink」が使用可能なロボット

システム構成

さて,今回はRoboLinkの紹介というよりは,遠隔操作・監視システムの構築方法が目的なので,紹介していきます.

システム構成

いや,シンプルすぎますね笑
でも,実際こんなもんです.もしロボットにライトのオンオフ機能や,リンク機構の稼働機能を付けたいのであれば,Ubuntuの入ったPCにマイコンとシリアル接続すれば良いと思います.ROS対応システムならスイッチングハブでも付けて,同じLANに繋いでおけば,制御できるでしょう.

今回はWebRTC技術とUDP通信を使用して機能を実装していきます.
他に映像転送ソフトとしてmjpg-streamerというものがあるのですが,絶妙に遅延し,リアルタイム操作という点においては不安があったため,WebRTCで実装しています.

遠隔監視・操作端末側

弊社ではスマートフォンをメインにPCやタブレットなどでも操作できるように開発しています.
クロスプラットフォームに対応したフレームワークを使用すると良いのではないでしょうか.
今回は,開発者のこだわりもあって,Tauriというフレームワークを使用していますが,PC版ではElectronを使用しています.
Tauriはフレームワークが新しい分,地味に使い勝手が悪いみたいなので,FlutterやReactを使うと良いのではないでしょうか.
もしくは,最初からブラウザ版として開発するのも手ですね.

さて端末側には,ロボット上のWebRTCサーバから送られる映像を表示する機能と,操作指示をUDP通信で送信する機能を持たせる必要があります.

操作指示の送信

UDP通信でロボット側に指示を送ります.
UDPの通信の実装例は,調べればいっぱいあるので,使いたい言語で自分で調べてみてください.
基本的に,遠隔操作の場合はロボット側に10Hz程度で操作指示を送ります.
間隔が大きすぎるとロボットの応答性や操作精度が低下しますし,小さすぎるとロボット側で処理が追いつかなくなって,操作遅延が起きます.

UDPはただ投げつけるだけなので,たまにパケットロストしてしまうことがありますので,それを意識した実装をしてみてください.
弊社では,json形式にしてデータを投げつけています.
興味のあるひとは,マスタリングTCP/IPという本を読んでみると勉強になるかもしれません.

映像の表示

映像の表示(クライアント側処理)はJavaScriptやTypeScriptで書くことができます.
後述のaiortcライブラリのexamples/sever内にクライアント側処理がclient.jsに記述されていますので,それを参考にコードをいじいじします.
https://github.com/aiortc/aiortc/blob/main/examples/server/client.js

ロボット側

映像のストリーミング

ロボット側にWebRTCサーバを建てる必要があります.
今回はPythonを使用します.ロボット制御系はC/C++を使用するのですが,通信系はちょっと大変なので楽させてください.
WebRTCの機能をまとめたライブラリでaiortcというものがあるので今回はそれを使用します.

https://github.com/aiortc/aiortc

ReadMeに書いてある通りにインストールすればすぐ使えます.
examples/sever内にあるserver.pyをPython3で実行後,ブラウザでローカルホストにアクセスすると,映像,音声が出ます.
使用時にpyavのバージョンエラーが出た気がしますが,必要な人はビルドして入れるか,低いバージョンを入れてみてください.
このserver.pyを参考にコードを弄って,端末側と接続できるようにします.
https://github.com/aiortc/aiortc/blob/main/examples/server/server.py

操作指示の受け取り

操作指示をUDPで受け取ります.
遠隔操作の場合,連続して指示が送られてきますので,送られてくる間隔よりも早く受け取り処理をする必要があります.
遅くなると,バッファが溜まり,遠隔操作が遅延し危険です.
pythonのthreadingライブラリなどを用いて,UDP受け取り処理をスレッド処理化するのが一番手っ取り早くて良いです.
受け取った最新のデータを,グローバル変数か何かでメイン処理に受け渡しすれば良いかと思います.
今回のロボットでは,ジョイスティックのx,y座標を受け取って,ROSで使用可能なgeometry_msgs/Twist型に変換して走行指示を与えています.

通信

ロボットにアクセスポイントを付けて,スマートフォンとP2Pで通信するのが手っ取り早いのですが,その場合,最大100m程度しか通信できません.(逆に現場作業用途などではこっちの方が便利だったりします)
なので今回は,LTEルータをロボットに取り付けて遠隔操作しています.
これまで,IIJmioのsimをpixelaのLTE対応USBドングルMT-110に挿して使用していたのですが,2GBまでしか使えない契約にしているため,通信制限が来るとロボットの映像が止まってしまっていました.
そこで新たに,楽天モバイルSIMを購入しました.
楽天モバイルは最大でも2980円+税の従量課金制で,通信制限も無制限ですので,常に映像を飛ばすようなシステムにはぴったりですね.
また,追加でLTEルータのTP-LINK MR600を購入しました.
USBドングルだと走行の振動で端子が抜けたり,端子が傷んだりすることが懸念されるからです.

VPN接続する

今回はSoftEtherVPNを使用して,VPN接続します.VPNに繋いでおけば,NAT越えしなくていいので楽です.
VPNサーバの建て方は割愛します.
UbuntuにSoftEtherVPNClientをインストールします.
全部コマンドなので,ちょっと大変です.やり方は調べてみてください.
インストールできましたら,netplanを使用して固定IPを設定しておきましょう.
同様に,スマートフォン側もVPNに接続します.
設定画面からいける場合といけない場合があります.設定画面からいけない場合は,OpenVPNやその他,VPN接続に対応したアプリをインストールします.

実際に遠隔操作・監視をしてみる

実際にやってみた動画がこちらです.操作はスマホからやっていますが,映像はPCに映しています.
30分連続操作しましたが,操作遅延や,映像遅延,映像飛びは殆どなく,実運用でも問題なさそうです.
Webカメラの映像は320x240 15fpsで飛ばしています.
解像度が高すぎたりフレームレートが高すぎると,おそらく映像が止まってしまうことも多くなるかと思います.

遠隔監視画面

いかがでしたでしょうか.
弊社では,これらの基本機能の他に,追加機能や拡張機能もオーダーメイドで開発することができます.
自社でオリジナルのシステムを開発したいけど,ノウハウがなく難しいといったお悩みがございましたら,パートナーとして一緒に開発を進めさせていただきますので,ぜひお気軽にお問い合わせください.