環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 20.04 |
ROS | Noetic |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
例えばロボットのカメラの画像を遠隔から監視してロボットを動かしたいという場合があります。手元にubuntuやROSの載っているPCがあればよいのですが、タブレットやスマホから見たいとするとweb経由でカメラを見るのが便利です。
web video server
web video serverはrosの中のimage形のトピックをwebに配信してくれるノードです。便利なことに、特にTopic名を指定しなくても自動でImage型のTopicを探して配信してくれます。
paramで変えられますが、デフォルトでは8080ポートで動作します。
sudo apt-get install -y ros-noetic-web-video-server
ソースコード
laucnch
wwwサーバーノード、カメラノードとImageの配信ノードの3つを立ち上げます。
<launch>
<include file="$(find hard_lecture)/launch/usb_cam.launch" />
<include file="$(find roswww)/launch/roswww.launch" />
<node pkg="web_video_server" type="web_video_server" name="web_video_server" />
</launch>
htmlファイル
カメラ画像を見るためのhtmlファイルです。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>ROS Image Web Viewer</title>
</head>
<body>
<h1>/image_raw</h1>
<script>
document.write("<img src='http://"+location.hostname +":8080/stream?topic=/image_raw&type=ros_compressed'></img>");
</script>
</body>
</html>
実行
USBカメラをPCに刺します。ls /dev/video0
があることを確認して、以下のコマンドでwebサーバー達を起動します。
roslaunch web_lecture camera_stream.launch
web_video_serverが生成するページから見る
この状態でブラウザを開いてlocalhost:8080
にアクセスします。すると以下のようなページが出てきます。Image型でpublishされているTopicの一覧が出てくるので、目的のTopicをクリックします。
クリックすると以下のようなページになって、動画のストリームが見れます。
http://localhost:8080/stream?topic=/image_raw
で/image_raw
に流れている画像が見れます。
http://localhost:8080/stream?topic=/image_raw&type=ros_compressed
だとcompressed
で圧縮されている画像が見れます。
roswwwのページから見る
今までと同じようにhttp://localhost:8085
のサーバーから見る方法を考えます。
http://localhost:8086/web_lecture/camera.html
にアクセスをします。このページでは8086
のサーバーのhtmlから8080
のサーバーの画像を取得するために少しjavascriptで小細工をしています。
<script>
document.write("<img src='http://"+location.hostname +":8080/stream?topic=/head_camera/image_raw&type=ros_compressed'></img>");
</script>
全画面で見る
スマホ等の画面にフルスクリーンのようにできる限り大きく映したいことがあります。
<!doctype html>
<html lang="ja">
<head>
<title>ROS Image Web Viewer</title>
<style>
*{
margin: 0px;
padding: 0px;
border: 0px;
}
.full_picture{
width: 100vw;
height: 100vh;
object-fit: contain;
}
</style>
</head>
<body>
<script>
var image_topic = "/head_camera/image_raw";
document.write("<img class='full_picture' src='http://"+location.hostname +":8080/stream?topic=" + image_topic + "&type=ros_compressed'></img>");
</script>
</body>
</html>
これで/head_camera/image_raw
のトピックがフルスクリーンで表示されます。
<style>
要素内はCSSの記述です。 *{margin: 0px; padding: 0px; border: 0px;}
は全ての要素について余白を無く表示するための指定です。これがないと余計な余白が表示されます。
上記のようにlocation変数を使うことでうまく画像のurlを生成しています。 .full_picture{width: 100vw; height: 100vh; object-fit: contain;}
がフルスクリーン表示をしているところです。vw
、vh
はブラウザのサイズに対する大きさの指定で、ブラウザの画面と同じ大きさを指定しています。object-fit: contain
は元の画像のアスペク比を保ったまま画像が収まるようにできる限り拡大するという指定です。
参考
web video server
javascript: locationについて