RTKGPS+をWindowsでビルド

(2020.8.12追記 apkを更新しました。http://tmizu23.hatenablog.com/entry/2020/08/09/100146 )

スマホ用のRTKアプリ「RTKGPS+」をカスタマイズしてビルドする方法です。

GNSSの後処理キネマティック (PPK) をするためには、受信機のRawデータを取得する必要があります。Pixcel3などのアンドロイドスマホとNeo-M8TなどのRTK対応の受信機をUSBで接続してRTKGPS+を使うと、Rawデータを簡単に取得できます。ただ、オリジナルのアプリだとQZSSのデータが表示されないのと、2周波対応のZED-F9Pの受信機に対応してなさそうなので、カスタマイズしてみます。ついでにマップに地理院地図も表示できるようにしてみます。

※オリジナルのものでもQZSSのRawデータは取得できてるっぽいのでPPKの処理は問題ないですが。

2周波表示とQZSS表示のポイントは、該当箇所のコメントアウトを外すことと、RTKGPS+用のパッチを当てればよかっただけなのですが...コードを理解してそれに気が付くまでが長かった...

f:id:tmizu23:20191107194012j:plain:w300


play.google.com

Android Studioのインストール

developer.android.com

ダウンロードしてインストールする

RTKGPS+のコード取得

github.com

git で以下のコマンドで取得する。RTKLIBなど関連プロジェクトも含めて取得するため --recursive が必要なので注意!

git clone --recursive https://github.com/eltorio/RtkGps.git

Android StudioでRTKGPS+を開く

Android Studioで取得したRtkGpsフォルダを開くと、自動でSyncされて足りないライブラリなどをインストールするようにメッセージやらエラーがでるので従う。

必要なライブラリがそろうと、ビルドできるようになるがエラーで止まるので、以下のコードの修正をする。

環境変数を設定する

Windows環境変数のPathに以下を追加
C:\Users\mizutani\AppData\Local\Android\Sdk\ndk\20.0.559457
C:\Users\mizutani\AppData\Local\Android\Sdk\platform-tools

ビルドが通るようにコードの修正

  • jni/Application.mkを修正

APP_STLc++_staticから変更。APP_ABIを追加

APP_STL := c++_shared
APP_ABI := armeabi-v7a
  • build.gradleを修正

abiFiltersをarmeabi-v7a以外をコメントアウトする。(とりあえずデバッグするためにビルドを速くしたいから。リリース時は、要変更)
defaultConfigの packagingOptionsに pickFirstを追加する。

defaultConfig {
        applicationId "gpsplus.rtkgps"
        minSdkVersion 21
        targetSdkVersion 26
        multiDexEnabled true
  ndk {
            abiFilters = []
            abiFilters.add('armeabi-v7a')
            //abiFilters.add('x86')
            //abiFilters.add('x86_64')
            //abiFilters.add('arm64-v8a')
        }
        packagingOptions {
            pickFirst 'lib/armeabi-v7a/libc++_shared.so'
            pickFirst 'lib/armeabi-v7a/libproj.so'
            pickFirst 'lib/armeabi-v7a/librtkgps.so'
            pickFirst 'lib/armeabi-v7a/libntripcaster.so'
            pickFirst 'lib/armeabi-v7a/libgdalalljni.so'
            pickFirst 'lib/x86_64/libc++_shared.so'
            //pickFirst 'lib/x86_64/libntripcaster.so'
            //pickFirst 'lib/x86_64/librtkgps.so'
            //pickFirst 'lib/x86_64/libproj.so'
            //pickFirst 'lib/x86_64/libgdalalljni.so'
            //pickFirst 'lib/x86/libc++_shared.so'
            //pickFirst 'lib/x86/librtkgps.so'
            //pickFirst 'lib/x86/libgdalalljni.so'
            //pickFirst 'lib/x86/libntripcaster.so'
            //pickFirst 'lib/x86/libproj.so'
            //pickFirst 'lib/arm64-v8a/libc++_shared.so'
            //pickFirst 'lib/arm64-v8a/libproj.so'
            //pickFirst 'lib/arm64-v8a/librtkgps.so'
            //pickFirst 'lib/arm64-v8a/libntripcaster.so'
            //pickFirst 'lib/arm64-v8a/libgdalalljni.so'
        }
 もともとあるコード
}
  • License.java.sampleの変更

src/gpsplus/rtkgps/geoportail/License.java.sampleのファイル名をLicense.javaに変更

QZSSを表示できるようにコードを修正

jni/rtklib.mkのRTKLIB_CFLAGSをコメントアウトしていあるものに変更(RtkGps+の作者はQZSSが関係ない地域の人だったのかな?)

RTKLIB_CFLAGS := -DENAGLO -DENAGAL -DENAQZS -DENACMP -DNFREQ=3 -DTRACE

ライブラリのビルド

Android StudioのTerminalでRtkGps/jniのフォルダに移動後、ndk-buildのコマンドでライブラリをビルド

cd RtkGps/jni
ndk-build

アプリのビルド

Android Studioでビルドボタンを押す

アプリの起動テスト

Android StudioでBuild APKをするとbuild/outputs/debugフォルダにapkができるので、実際のスマホにコピーして、ファイルアプリから開いてインストールする。

デバッグ

https://okfoxy1990.com/android-apps-wifi-debug
Android Studioで開発したアプリを実機でテストする方法【初心者向け】 | TechAcademyマガジン

上記を参考にしてWIFI接続でデバッグできるようにする。USBは受信機を接続しているので。

開発者モードでUSBデバッグを有効にしてから、USB接続して、以下のコマンドを打つ
adb.exe tcpip 5555
USB外して、以下のコマンドを打つ。ipはスマホのipアドレスを確認して指定
adb.exe connect 192.168.1.11

Android Studioで実機のデバイスを指定して実行すると、実機にアプリがインストールされて起動する。

デバッグモードとなっているのでAndroid StudioのLogcatタブにLogが出力される。

RTKLIBの更新

submoduleとなっているRTKLIBを更新する。

rtklibexplorerバージョンの場合
cd RtkGps
git submodule deinit  -f jni/RTKLIB
git rm -rf jni/RTKLIB
rmdir /s .git\modules\jni\RTKLIB
git submodule add https://github.com/rtklibexplorer/RTKLIB.git jni/RTKLIB

jni/rtklib.mkの以下の行を削除

    $(RTKLIB_PATH)/src/rcv/ss2.c \

jni/RTKLIB-unixsocket.patchのパッチをあてる
android studioVCS -> Apply patch... でファイルを指定する

オリジナルの場合

android studioのterminalで以下を実行(コマンドプロンプトなのでフォルダ消すときはrmdir)

cd RtkGps
git submodule deinit  -f jni/RTKLIB
git rm -rf jni/RTKLIB
rmdir /s .git\modules\jni\RTKLIB
git submodule add -b rtklib_2.4.3 https://github.com/tomojitakasu/RTKLIB.git jni/RTKLIB

jni/rtklib.mkの以下の行を削除

$(RTKLIB_PATH)/src/rcv/swiftnav.c \
$(RTKLIB_PATH)/src/rcv/comnav.c \

jni/prcopt.cを変更する(面倒なのでパッチの内容)

diff --git a/jni/prcopt.c b/jni/prcopt.c
index 49d6884..7b88048 100644
--- a/jni/prcopt.c
+++ b/jni/prcopt.c
@@ -189,16 +189,16 @@ void processing_options2prcopt_t(JNIEnv* env, jobject thiz, prcopt_t *dst)
    GET_FIELD(modear, Int)
    GET_FIELD(glomodear, Int)
 
-   GET_FIELD(gpsmodear, Int)
+   //GET_FIELD(gpsmodear, Int)
    GET_FIELD(bdsmodear, Int)
-   GET_FIELD(arfilter, Int)
-   GET_FIELD(minfixsats, Int)
-   GET_FIELD(minholdsats, Int)
-   GET_FIELD(mindropsats, Int)
-   GET_FIELD(rcvstds, Int)
+   //GET_FIELD(arfilter, Int)
+   //GET_FIELD(minfixsats, Int)
+   //GET_FIELD(minholdsats, Int)
+   //GET_FIELD(mindropsats, Int)
+   //GET_FIELD(rcvstds, Int)
    GET_FIELD(armaxiter, Int)
-   GET_FIELD(varholdamb, Double)
-   GET_FIELD(gainholdamb, Double)
+   //GET_FIELD(varholdamb, Double)
+   //GET_FIELD(gainholdamb, Double)
    GET_FIELD(maxaveep, Int)
    GET_FIELD(initrst, Int)
    GET_FIELD(outsingle, Int)
@@ -352,22 +352,21 @@ static void ProcessingOptions_load_defaults(JNIEnv* env, jobject thiz)
    SET_FIELD(modear, Int)
    SET_FIELD(glomodear, Int)
 
-   SET_FIELD(gpsmodear, Int)
+   //SET_FIELD(gpsmodear, Int)
    SET_FIELD(bdsmodear, Int)
-   SET_FIELD(arfilter, Int)
-   SET_FIELD(minfixsats, Int)
-   SET_FIELD(minholdsats, Int)
-   SET_FIELD(mindropsats, Int)
-   SET_FIELD(rcvstds, Int)
+   //SET_FIELD(arfilter, Int)
+   //SET_FIELD(minfixsats, Int)
+   //SET_FIELD(minholdsats, Int)
+   //SET_FIELD(mindropsats, Int)
+   //SET_FIELD(rcvstds, Int)
    SET_FIELD(armaxiter, Int)
-   SET_FIELD(varholdamb, Double)
-   SET_FIELD(gainholdamb, Double)
-   SET_FIELD(maxaveep, Int)
-   SET_FIELD(initrst, Int)
-   SET_FIELD(outsingle, Int)
-   SET_FIELD(syncsol, Int)
-   SET_FIELD(freqopt, Int)
-
+   //SET_FIELD(varholdamb, Double)
+   //SET_FIELD(gainholdamb, Double)
+   //SET_FIELD(maxaveep, Int)
+   //SET_FIELD(initrst, Int)
+   //SET_FIELD(outsingle, Int)
+   //SET_FIELD(syncsol, Int)
+   //SET_FIELD(freqopt, Int)
    SET_FIELD(maxout, Int)
    SET_FIELD(minlock, Int)
    SET_FIELD(minfix, Int)

jni/RTKLIB-unixsocket.patchのパッチをあてる
android studioVCS -> Apply patch... でファイルを指定する

osmdroidの更新と地理院地図の追加

build.gradleにosmdroidの最新バージョン追加。もともとのosmdroidのjarは削除する

dependencies {
    implementation 'org.osmdroid:osmdroid-android:6.1.2'
もともとあったコード
}

osmdroidのバージョンの違いによりエラーがでるのでMapFragment.javaまわりを修正。地理院地図を追加してgeoportailの地図を削除。

上記を変更したRtkGps+のコードはこちらにあります。
(2019.11.29 追記:apkも以下のreleaseの中にアップしておきました。)
github.com

あとがき

もともとの目的はドローン用対空標識の座標決めで、2周波RTKだったら3分ぐらいの受信と電子基準点との後処理でFixするかも?という期待でしたが、結果5km離れた電子基準点では、3分ではFixせず、最低5分は必要でした。あと、PPKしか試してないので、RTKGps+を使って2周波のRTK測位を試したいですが、Zed-F9Pは1台しかないので、安くなってからかな...