libwebsocketsでRTKLIBのwebアプリを作ってみた。

RTKLIB には リアルタイム測位を行う方法として、rtknavi と rtkrcv というプログラムが用意されています。前者がGUIベースのもので、後者がコマンドラインベースのものになります。rtknavi は windows 前提のGUIのため、raspberry pi などのシングルボードコンピュータで リアルタイム測位を行いたい場合には、rtkrcv を使うことになります(※1)。

(※1) https://github.com/cartoocm/RTKLIB-QT のようにgithub上でwindows 以外でも実行可能なGUI環境がいくつか公開されています。

## rtkrcv
シングルボードコンピュータには、ディスプレイがついてないことが多いですが、rtkrcv にはネットワークから測位状況を監視したり、管理コンソールにアクセスしたりできるようになっています。

### 測位状況の監視
モニターオプションの -m の後に、ポート番号を指定して、他のコンピュータからそのポートにアクセスすることで、測位状況を監視するいつものことができます。

rtkrcv を実行するコンピュータ上で rtkrcv を -m オプション付きで実行
(1025の port番号部分は適当に変更して下さい)

```
~/works/RTKLIB/app/rtkrcv/gcc$ -o rtkrcv.conf -m 1025
```

測位状況監視を監視するコンピュータ上で netcat コマンド実行
(1025の port番号部分は上で指定したものに合わせて下さい)

```
~$ nc <rtkrcvを実行してるコンピュータのIP> 1025
2018/07/22 12:27:23.000   34.726597730  137.718095903    97.3859   1   8   0.0146   0.0073   0.0372   0.0078  -0.0075  -0.0083   1.02  999.9
2018/07/22 12:27:24.000   34.726597706  137.718095947    97.3464   1   8   0.0146   0.0072   0.0371   0.0078  -0.0075  -0.0083  -0.98  999.9
2018/07/22 12:27:25.000   34.726597718  137.718095926    97.3634   1   8   0.0143   0.0070   0.0364   0.0076  -0.0073  -0.0083   0.02  999.9
2018/07/22 12:27:26.000   34.726597670  137.718095907    97.3678   1   8   0.0143   0.0071   0.0364   0.0076  -0.0074  -0.0083   0.02  999.9
...
```

solution ファイルと同じ形式で、出力されていることが分かります。

### 管理コンソールへのアクセス

コンソールオプションの -p の後に、ポート番号を指定して、他のコンピュータからアクセスすることで、rtkrcvのいつもの管理画面にアクセスすることができます。

rtkrcv を実行するコンピュータ上で rtkrcv を -p オプション付きで実行
(1024の port番号部分は適当に変更して下さい)

```
~/works/RTKLIB/app/rtkrcv/gcc$ ./rtkrcv -p 1024

```

-p オプション付きで実行すると、実行したコンソール上には、管理画面が表示されません。

別のコンピュータ上で、telnet コマンドを実行
(1024の port番号部分は上で指定したものに合わせて下さい)

```
~$ telnet localhost 1024
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

** rtkrcv ver.2.4.2 console (h:help) **
password: admin 

rtkrcv> 
```

password を聞かれますので、rtkrcv.conf の中で指定した値を入力して下さい。デフォルトでは admin になっているので、ここでは admin を入力しています。

```rtkrcv.conf
...
console-passwd     =admin
...
```

## webアプリ
RTKRCVは、上記の用にデフォルトでネットワーク経由のアクセス方法が用意されていますが、より便利なブラウザからのアクセス方法を用意している会社があります。

* [SMARTNAV-RTK](https://github.com/drotek/SMARTNAV-RTK)　Drotek社  
* [ReachView](https://github.com/emlid/ReachView)　Emlid社   

Droteck社、Emlid社ともに、GNSSモジュール、アンテナ、シングルボードコンピュータを組み合わせたRTK測位用のハードウェアとRTKLIBにwebインタフェースを追加したソフトウェアを提供しています。各社が提供するシングルボードコンピュータ以外の環境では、ソフトウェアをそのまま動かすことはできませんが、ソースコードがGPLで公開されているため、その他の環境に移植することは、それほど難しくないと思います。

これらのソフトウェアでは、rtkrcvの出力をpythonや、nodejs を使って、webアプリ化するということを行っています。

```
[ブラウザ] --- [nodejs/python(webサーバ)] --- [rtkrcv]
```

今回は、libwebsocketsを使ってrtkrcvを書き換えてwebアプリ化した rtkweb を作成してみました。

```
[ブラウザ] --- [rtkweb(libwebsockts)]
```

## rtkweb

### libwebsockets
[libwebsockets](https://libwebsockets.org/) は、websocketsだけでなく、httpやhttp2, raw tcp/udp までサポートしたC言語ライブラリです。pluginsをサポートしており、必要な機能だけplugin として開発し、デフォルト機能と組み合わせて使うことが可能です。サンプルpluginがいくつか用意されており、それらを真似することで、比較的簡単にwebsocketを使ったwebアプリを作成することが可能です。


### リポジトリ
docker 開発環境に関するものを含め、今回のコードは[こちら](https://github.com/ft28/rtkweb)で公開しています。

### docker 開発環境

.bashrc に以下設定を追加します。

```.bashrc
export USER_ID=`id -u`
export USER_NAME=`id -nu`
export GROUP_ID=`id -g`
export GROUP_NAME=`id -ng`
```

docker イメージを作成します。コンパイルに必要なライブラリと、libwebsocketsがインストールされた環境を用意します。

```
git clone https://github.com/ft28/rtkweb
cd rtkweb
git submodule init
git submodule update
docker-compose build
```

docker 環境を起動してplugin をコンパイルします。 docker-compose run でポートを公開するためには、--srvice-port オプションが必要なことに注意してください。

```
docker-compose run --service-ports websocket bash
user@48f731393273: make
```

rtkweb を起動します。

```
cd sample
user@48f731393273:/opt/rtkweb/sample$ lwsws -c ./lwsws/
Root process is 135
lwsws[136]: lwsws libwebsockets web server - license CC0 + LGPL2.1
lwsws[136]: (C) Copyright 2010-2018 Andy Green <andy@warmcat.com>
lwsws[136]: Using config dir: "./lwsws/"
lwsws[136]:   Plugins:
lwsws[136]:   Scanning /usr/local/share/libwebsockets-test-server/plugins/
lwsws[136]:    libprotocol_client_loopback_test.so
lwsws[136]:    libprotocol_dumb_increment.so
lwsws[136]:    libprotocol_generic_sessions.so
lwsws[136]:    libprotocol_lws_messageboard.so
lwsws[136]:    libprotocol_lws_mirror.so
lwsws[136]:    libprotocol_lws_raw_test.so
lwsws[136]:    libprotocol_lws_server_status.so
lwsws[136]:    libprotocol_lws_ssh_base.so
lwsws[136]:    libprotocol_lws_sshd_demo.so
lwsws[136]:    libprotocol_lws_status.so
lwsws[136]:    libprotocol_lws_table_dirlisting.so
lwsws[136]:    libprotocol_post_demo.so
lwsws[136]:   Scanning /opt/rtkweb/plugins
lwsws[136]:    libprotocol_rtkweb.so
lwsws[136]:  Using foreign event loop...
lwsws[136]: Creating Vhost 'localhost' port 7681, 2 protocols, IPv6 off
lwsws[136]: unable to chown log file /opt/rtkweb/sample/log/test-access-log
lwsws[136]:  Using non-SSL mode
lwsws[136]: created client ssl context for localhost
no navigation data: rtkweb.nav
```

libprotocol_rtkweb.so が今回作成したpluginです。ブラウザを開いて http://localhost/sample.html にアクセスすると、以下のような画面が表示されるはずです。起動時は、start/stop でrtkエンジンを開始したり、停止したりできます。

![rtkweb.png](https://qiita-image-store.s3.amazonaws.com/0/247417/66d491d5-9c94-1836-a469-7c34191a12cf.png)

このpluginでは、2秒おきにサーバーからrtkrcvコマンドの、status, observ, satellite に相当する情報を組み合わせて送信するという仕様になっています。また、入力は[前回](https://qiita.com/ft28/items/24bc73a29c1158c93528) 作成した、プレイバック用のファイルを使っています。

## まとめ
RTKLIBをlibwebsocketsをつかってwebアプリ化してみました。SMARTNAV-RTKや、ReachView のようにグラフ表示機能や、設定変更、ログダウンロード機能はありませんが、間に他のプロセスが入ってこないことやwebsocketを使ってることから、それらに比べて、実行効率は良いのではないかと思います。そのうち、グラフ機能や認証機能なども追加していこうと思います。