Pusher

リモートデバイス/ロボットを遠隔操作するプロトコルやソフトウェアフレームワークを調べてみた

nantacon

リモートデバイスやロボットをWebブラウザから遠隔操作したいと思った際に使える、リアルタイム通信のプロトコルやソフトウェアフレームワークを紹介する。

ちょっとしたIoT機器をスマートスピーカーから操作するなんていうことは、今時すぐにできることが多い。Google HomeとSwitchbotデバイスを繋いだらいろんな事ができる。

ただシステム間で双方向通信を行い、リアルタイムに任意のデバイスを思い通りに動かしたいとなると、まだそこまでよくパッケージ化された仕組みはない。何かしらのソフトウェアフレームワークを活用し、開発行為を挟む必要がある。本記事は、その開発に必要な知識を提供する。

デバイス/ロボットをリアルタイム遠隔操作するプロトコル

GPT4で候補を列挙してみた結果

GPT4で候補を聞いてみると、下記のとおりである。

  1. WebRTC:
    • WebRTC(Web Real-Time Communication)は、ブラウザ間で直接、ビデオ、オーディオ、および一般的なデータをリアルタイムで交換するためのオープンソースプロジェクトです。
    • これは主にビデオチャットや高度な通信機能をウェブアプリケーションに統合する場合に利用されます。
  2. WebSocket:
    • WebSocketは、ウェブサーバとクライアント間のフルデュプレックス通信チャネルを提供するプロトコルです。
    • リアルタイムウェブアプリケーションに適しており、チャットアプリやリアルタイム通知の配信などに使用されます。
  3. MQTT (Message Queuing Telemetry Transport):
    • 軽量なメッセージングプロトコルで、特にネットワーク帯域が限られている環境や、リアルタイムでのデバイス間通信が求められるIoT環境に適しています。
  4. TCP/IP:
    • 低レベルの通信にはTCP/IPが広く使用されており、シリアル通信などの基本的なデータ転送にも利用されます。
    • シリアルポート経由でデバイス間を接続する際には、TCP/IPを使ったカスタムソリューションが考えられます。
  5. Serial Communication (RS-232, RS-485 etc.):
    • 物理的なケーブルを使ってマシン間でデータを直接送受信する古典的な方法です。
    • これは主に産業機械や古いシステムでの通信に使用されています。

信頼性のある遠隔操作通信となると、WebSocketが一番の様子

列挙してみるのをみると、WebSocketが一番安泰のように見える。TCPベースなので、UDPベースのWebRTCなどと比べて遅いが、操作信号のような低容量でありつつ信頼性が求められる信号というと、やはりWebSocketに落ち着く。

映像データをリアルタイム伝送するとなるとWebRTCは外せない。ただこれはUDPベースなので、信頼性が心配である。映像などの非構造データを送るのはいいが、ミッションクリティカルな情報を送るときに心配だ。

MQTTはデータ伝送量を絞るのには良いが、リアルタイム性が落ちる。

TCP/IPやシリアル通信は、ややネイティブすぎて、このまま本格的なシステムに実用するコストが高すぎる。

将来的にはWebTransportがデファクトスタンダードになる

一方で、WebSocketというと非常に前からあるイメージ。調べてみると、WebSocketは2009〜2010年くらいには存在している模様。

代替のプロトコルはないか?と調べてみるとWebTransportというものがあった。

WebTransportはGoogle製のQUICをコア技術にしており、UDPベースでありながら高速で信頼性の高い双方向通信可能なプロトコルらしい(とはいえ、利用しているソフトウェアフレームワークもあるようなので、この辺りの正確な状況はよくわからない)。

2022年にやっとリリースされたばかりの新しい技術のようで、まだ標準化プロセスの最中。日本語の関連記事は少ない。

上のリンク先のページの比較表を日本語訳してみると下記の通り。WebTransportの方が将来的に良い部分が多い。標準化が進み、普及して実用例が増えていけば、デファクトスタンダードはいずれWebSocketからWebTransportに置き換わっていくのだろうと思う。ただしばらくはWebSocketが主流だろう。

特徴WEBTRANSPORTWEBSOCKETS
プロトコルQUICを利用Websocketを利用
マルチクレキシングビルトインのマルチプレキシングマルチプレキシングをサポート
信頼性ビルトインのエラー修正による信頼性提供アプリケーションレベルでのエラー対応が必要
セキュリティ デフォルトでTLSを用いた暗号化WSSによる暗号化を要求
柔軟性低レベルでの通信のために設計されている高レベルでのメッセージプロトコル
ストリーム
サポート
並列データに対するマルチストリーム対応シングルの双方向通信チャンネル
バイナリデータのサポートバイナリデータ送信の効率的なサポートバイナリとテキストのデータ送信をサポート
フロー制御より良いリソース活用のためのビルトインフロー制御フロー制御はマニュアルでの実装が必要
ブラウザの
サポート
メジャーなブラウザに
限定したサポート
様々なモダンブラウザに対する幅広いサポート
ユースケース低遅延かつリアルタイムな
アプリケーション、ゲーム開発
リアルタイム通信、メッセージアプリ
通信レイヤUDPの上に作られている
パフォーマンス重視
TCPの上に作られている
信頼性重視で潜在的により高い遅延
コネクションの
セットアップ
高速なセットアップWebTransportと比較するとやや遅い
標準化未だIETFによる標準化の最中IETFによる標準化済
WebTransportとWebSocketの比較

2024/05 現時点でWebブラウザからリモートデバイスやロボットを制御するには、WebSocketを使うのが良さそう。

但し、いずれWebTransportの時代が来るだろう。

WebSocketを活用するフレームワーク

WebSocketを使うのが良いことはわかったが、WebSocketを使う良いソフトウェアフレームワークがないかを調査してみた。結果的に、下記候補が得られたので紹介していく。

  1. ROS
  2. Socket.io
  3. Pusher

ちなみにSignalRという選択肢もあるかもしれないが、ちょっとMicrosoftに縛られすぎた選択肢であり自分があまり詳しくないので除外します。(ごめんなさい)

ROS

ROSはロボティクス研究者/技術者で知らない者はいない、定番のロボットシステムを構築するためのフレームワークである。

ROS 1とROS 2が存在しており、最近ではROS 2への移行が進んでいる。

ROS 1

ROS 1にはWebSocketによりWebブラウザとロボットシステムを繋ぐ仕組みが存在している。

より正確には、仕組みが存在しているというより、ROS を使ってWebブラウザとロボットシステムをWebSocketによる通信できるようにする機能が公開されている。Robot WebToolsというプロジェクトで推進されている。

ROS 2

ROS 2では、DDS(Data Distribution Service)というものを通信プロトコルで採用しているので、これで遠隔制御もできる。ちなみにこれはWebSocketではない。

ROS 2(Robot Operating System 2)では、通信バックボーンとしてDDS(Data Distribution Service)を採用しています。DDSはリアルタイムシステム用のミドルウェア規格で、高度なデータ通信サービスを提供することを目的としています。この技術は特に、分散システム間でのデータの効率的な配信が求められる場合に利用されます。

GPT4

ROS 1 / ROS 2に共通して言えること

ROS 1であっても、ROS 2であっても、操作側とデバイス側がネットワーク的に通信できる環境を整えられている環境の構築が必要である。2つのクライアントが単にインターネットに接続されているだけでなく、2つの接続関係をきちんと制御してやる必要がある。

オンラインゲームのように、ホストとクライアントがコロコロと変わる可能性がある場合は一筋縄ではいかないので、別の仕組みをきちんと用意してあげる必要がある。これは言葉で書くと簡単に聞こえるが、実際に実現しようとするとかなりの実装コストがかかる。

研究段階やデモシステムなどで、通信するシステムの関係性が固定で、短期的な利用であれば、そういった制約は無視できるため、ROSの活用はお勧めできる。プロダクションレベルでの利用は追加の実装コストが必要と予想する。

特にどうしてもプロダクションレベルで使いたいのであれば、最低限ROS 1ではなくROS 2の活用をおすすめする。ROS 1は今は使い勝手が良いが、将来はROS 2へと移行していくし、プロダクションに使うには信頼性が足りないなどの多くの問題がある。長くなるのでここは割愛。

クライアント間のネットワーク接続関係が固定であったり、研究レベルで使うケースであれば、ROSを使うことをおすすめする。

柔軟にクライアント間の組み合わせを変えたい、プロダクションで使いたいという場合だと、ハードルが高く、あまりお勧めできない。

Socket.IO

Socket.ioはNode.js ベースのサーバーとクライアントの間のリアルタイム通信を提供するライブラリ。サイトのキャッチフレーズには「あらゆるプラットフォームに対応した低遅延の双方向通信」と謳われている。

Socket.ioでは、クライアントたちがサーバにある「ルーム」という概念にアクセスして、通信できるようにする。ブロードキャストもできる様子。ただのWebSocketではなく、サーバーを介したマルチユーザ間の柔軟な通信ができる仕組みのようだ。

実際にこれでマルチプレイのオンラインゲームを作ってみている人もいる。

ドキュメントをみると、通信レイヤでWebTransportも選べると書いてあるので、すでにWebTransportが使われている例でもあるようだ。

歴史もそれなりにあり、WebSocketが標準化された2010年ごろから存在しているらしい。

Socket.ioは非常によく作られており、マルチクライアント間での柔軟な接続関係を作り、高速な通信ができる。高い質の双方向通信アプリを効率的に開発可能。Javascript (Node.js)を使うことが1つの制約。

(追記)Socket.ioの歴史は長いので、pythonやC++で使えるsocket.ioライブラリが出てきているので、プログラミング上の制約はあまりないかもしれない。

Pusher

Pusherはリアルタイム機能をクラウドベースで提供するサービスで、WebSocketと同様のAPIを通じてリアルタイム通信を提供する。APIを通じてリアルタイムメッセージングや通知、ブロードキャストが可能で、開発者はサーバーの管理やスケーリングを心配する必要がない。

フレームワークというより、SaaSでSocket.ioライクなことができるもののようだ(素晴らしい!)。

Github, DataDog, The Washington Postといった有名どころで使われている。

ロボットの遠隔操作で使うケースというのは見受けられなかったが、マルチゲームプレイに適している話が同社ブログに書かれていたので、原理的には使えるはず。https://pusher.com/blog/websockets-realtime-gaming-low-latency/

接続状況のモニタリングをDatadogを介して行うこともできる様子(Proプラン以上)。

無料プランもあり、お試しできそう。

さらに、幅広いプログラミング言語をサポートしている。(Python, Java, Ruby, PHP, Go, JavaScript, Unity, and React Native)

東京オリンピックで一部使われたとかの話もあり。

https://pusher.com/blog/tokyo-olympics-realtime-lighting-app

同社ブログは2019年ごろから更新されているのをみる限り、非常に若い会社なのだろうと思う。(いつかどこかに買収されるのかな?)

何にせよ、SaaSでSocket.ioサーバを立てたくない面倒くさがり屋にはとても良いものだと思われる。サーバメンテをするコストも結構かかるので、コスト面でも実はベストかもしれない。

少し金をかけてでもSaaSにしたいという人にお勧め。多くのプログラミング言語に対応しているし、利便性も高そう。DataDog連携によるモニタリングもプラス要素。

(追記) Azure Web Pub Subなど、Socket.ioをマネージドで扱ってくれるクラウドサービスも出てきているので、Pusher以外にも選択肢はあるようだ。

補足:ゲームエンジンを用いる方法

補足だが、ゲームエンジンを使う方法も考えられると思う。

Unreal EngineやUnityといったゲームエンジンではマルチプレイヤーのゲームをサポートするための仕組みが内包されているケースがある。AWSだとGameLiftとかのサービスで、マルチプレイヤーサポートをしていたりする。

ゲームエンジンという切り口で調査するとさらに広がりを見せるが、実現する手段とスケールが変わってきて発散するので、今回は範囲外としました。

まとめ

  • 現時点では、Webブラウザからリモートデバイスやロボットを操作するには、WebSocketを使った形式にするのが良い選択肢に思える。
    • 但し将来的には、WebTransportがWebSocketに置き換わっていく可能性が高い。
  • WebSocketベースでのソフトウェアフレームワークやSaaSとして、ROS, Socket.io, Pusherといった選択肢がある。
    • 研究やデモ用途でよく、ホストとクライアントの接続関係が固定のネットワークで繋がっていて、ロボットがROSで動いているなどの条件がそろえば、ROSを使うのが良い。
    • 操作ホスト側と、操作対象のクライアントであるデバイス/ロボットの接続関係がある程度柔軟に変わる可能性があり、信頼性と拡張性を求めるならば、Socket.ioを使うのが良い。
    • SaaSを使いたいならば、Pusherを使うのが良い。

次回、Sockt.ioやPusherについて実際に動かしてみたレポートを載せてみれたらと思います。

ABOUT ME
Azarashi Man
Azarashi Man
あざらし まん
普段はエンジニアとして働いています。 ソフトウェア分野のテクノロジーに関して、役立つ情報配信をしていければと思っています。
記事URLをコピーしました