RTK基準局を設置~その2~

前回の作業で基準局用アンテナを設置し、その座標を求めました。
今回はRasberrypiを使って自宅用NTRIPサーバーを設置します。

構想

RTK基準局はアンテナで受信した電波の遅延等を補正データーとしてローバーに送ります。
テスト的に動かすならPCを基準局にしてローバーと1対1で接続するのでもOKですが、最終的には常時稼働にしたいし、また今後台数が増えてもいい様にもしたいです。

1対1の接続イメージ

その為に下図のイメージでローカルなNTRIPサーバーを稼働させようと思います。
NTRIPサーバーにはオープンソースのNtripcasterを使用します。
受信機のデーターを受け取ってNtripcasterに投げるのはRTKLIBに含まれるSTR2STRを使います。
受信機のデーターをSTR2STRがNtripcasterに送り、NtripcasterがGCSの要求に応じてデータを配信するイメージです。

自宅内にNtripcasterを動かすイメージ。今回はこれで行く。


ところでNTRIPは基準データをネットで配信するプロトコルで、これを利用したNTRIPサーバーが各地にあり多数の善意の基準局がデーターを配信されています(こんなところや、こんなところ参照)。
本当は自分の基準データーもこれらの公開されたNTRIPサーバーに上げれば近所の人まで使えてハッピーなのですが、今回立ち上げるのは自宅に設置したRTK基準局です。 会社や学校の設備ならともかく、今のご時世に自宅の座標をセンチメートルレベルで公開してしまうのは不安があるので当面これは止めときます。

公開されたNtripサーバーを使うイメージ。本当はこうしたいところだが当面やめておく。


なお最終的に常時稼働させたいので電力が少なくて済むRaspberryPiで構築します。
RaspberryPiには、ちょっと古いですがRaspberryPi2が手持ちにあったので、str2strもNtripcasterもこの中で動作させる事にします。

という事で今回やることは次の通りです。

  1. ZED-F9P受信機の設定
  2. RaspberryPiの準備(OSインストール他)
  3. Ntripサーバー(Ntripcaster)インストール
  4. STR2STR(RTKLIBに含まれる)インストール
  5. OS起動時に自動的に立上る設定とかシャットダウンボタンの設定

ZED-F9P受信機の設定

前回アンテナ座標を得るために受信機を設定しましたが、基準局として動作させるにはRTCMデータを出力させる必要があります。
参考にしたのはトラ技2019年10月号の第1部7章で、初期状態からの変更点は・・・

  • UBX-CFG-DGNSSの中で・・・
    Differential mode3=RTK fixed: Ambiguities are fixed whenever possible.に設定。
  • UBX-RXMの全て(RAWX,SFRBX等)を停止。
  • UBX-CFG-MSGの中で以下のメッセージにUSBへの出力を有効化(Message欄に下記を選んでUSBにチェック印を入れる)。
     01-35 NAV-SAT
     F5-05 1005 (基準極座標)
     F5-4D 1077 (GPS観測データ)
     F5-57 1087 (GLONASS観測データ)
     F5-61 1097 (Galileo観測データ)
     F5-4D 1127 (BeiDou観測データ)
     F5-4D 1230 (GLONAS補正データ)
     ※QZSS(みちびき)のRTCMデーター出力は今のところF9Pでは対応していない様です。
  • UBX-CFG-NAV5の中で・・・
     Dynamic Model = 2-Stationary
     Fix Mode = 3-Auto 2D/3D
     UTC Standard = 0-Automatic
  • UBX-CFG-PRTの中で・・・
     Target = 3-USB
     Protocol in = 0+1+5-UBX+NMEA+RTCM3
     Protocol out = 0+1+5-UBX+NMEA+RTCM3
  • UBX-CFG-TMODE3の中で・・・
     Mode = 2-Fixed Mode
     Lat,Long,Altを前回求めた座標値に設定。

・・・それぞれ忘れずに設定を書き込んでおく。

RasberryPiの準備

RaspberrypiOS(現行版のTrixie、GUIは不要なのでLite版)をインストールし、sshでログインできる様に設定しました。
そして下記の基本準備を実行しておきます・・・

 $ sudo apt update
 $ sudo apt install git

Ntripcasterをインストールする。

インストールは下記コマンドで特にエラーもなく終了しました。

$ git clone https://github.com/roice/ntripcaster
$ cd ntripcaster/ntripcaster0.1.5 # この時のバージョンは0.1.5だった。
$ ./configure
$ make
$ sudo make install
$ cd /usr/local/ntripcaster/conf
$ sudo cp -p ntripcaster.conf.dist ntripcaster.conf
$ sudo cp -p sourcetable.dat.dist sourcetable.dat

次にエディタでntripcaster.confを編集します。
不明な点やたぶんローカル使用だと不要お思われる点も多いですが、下記に記載の箇所を変して動作しています。

##################################
# NtripCaster configuration file #
################################################################################

############### Server Location and Resposible Person ##########################
# Server meta info with no fuctionality.

### 下記3行を変更したがローカル使用なので多分あまり影響しない。
location BKG                     →HOIHOIDOに変更
rp_email casteradmin@ifag.de     →自分のメールアドレスに変更
server_url http://caster.ifag.de →http://192.168.1.212に変更

########################### Server Limits ######################################
# Maximum number of simultaneous connections.

### 下記3行も気分的に変更した。
max_clients 100                  → 20
max_clients_per_source 100       → 20
max_sources 40                   → 8

######################### Server passwords #####################################
# The "encoder_password" is used from the sources to log in.

### パスワードを変更しておく。
encoder_password sesam01         → XXXXXXXX

#################### Server IP/port configuration ##############################
# The server_name specifies the hostname of the server and must not be set to
# an IP-adress. It is very important that server_name resolves to the IP-adress
# the server is running at.
# For every port, the server should listen to, a new port line can be added.

### 下記1行も変更したが、これもローカルだと意味なさそう。
server_name igs.ifag.de          →rtk.hoihoido.com
#port 80
port 2101

######################## Main Server Logfile ##################################
# logfile contains information about connections, warnings, errors etc.

logdir /usr/local/ntripcaster/logs
logfile ntripcaster.log

############################ Access Control ###################################
# Here you specify which users have access to which mountpoints,
# one line per mount.
#
# Syntax: /<MOUNTPOINT>:<USER1>:<PASSWORD1>,<USER2>:<PASSWORD2>,...,<USERn>:<PASSWORDn>
#
# /<MOUNTPOINT>: name of the mountpoint. Must start with a slash.
# <USERi>: name of the user that has access to <MOUNTPOINT>.
# <PASSWORDi>: password of <USERi>.
#

### たぶん、ここが一番大事
# example:
#/mount0:user0:pass0,user1:pass1,user2:pass2
#/BUCU0:user1:password1,user2:password2 → コメントアウト
#/PADO0                                 → コメントアウト
/HOIHOIDO                              → 追加

そしてエディタでsourcetable.datも編集します。
初期設定行を全部消して下記を記載しました。こちらもローカルサーバーなので適当なところもあります(もしかするとCASやNETの行は無くてもいいのかもしれません)。
きちんとした説明は公式のドキュメントを参照してください(doc形式なのでダウンロードする方が見やすいかも)。

CAS;192.168.1.212;2101;NtripInfoCaster;HOIHOIDO;0;JPN;32.87;130.76;http://192.168.1.212
NET;LOCAL;HOIHOIDO;N;N;192.168.1.212
STR;HOIHOIDO;Koshi;RTCM3.3;1005(1),1077(1),1087(1),1097(1),1127(1),1230(1);2;GPS+GLO+GAL+BDS;;JPN;32.87;130.76;0;0;u-bloxZED-F9P;none;N;N;;

STR2STR(RTKLIB)をインストール。

RTKLIB一式をインストールしてSTR2STRが使える状態にします。
これも下記コマンドで特に問題なくインストールできました。
設定する様なファイルはありません(実行時のコマンドラインオプションに色々書く方式)。

$ git clone https://github.com/tomojitakasu/RTKLIB.git
$ cd RTKLIB/app
$ chmod 755 makeall.sh
$ ./makeall.sh

動作確認

では手動で実行してテストしてみます。まずはNtripcaster。

$ cd /usr/local/ntripcaster/bin
$ sudo ./ntripcaster

次にstr2strを実行します。
こちらはコマンドラインに動作を色々と書いています。
やっている事を一言でいうと、「シリアルポートttyACM0から230400bpsで取ってきたデーターをntripプロトコルでlocalhostのポート2101に投げる。Ntripサーバーに投げる為のパスワードはXXXXXXXXで基準局の名前はHOIHOIDO」となります。

$ cd ~/RTKLIB/appstr2str/gcc
$ ./str2str -in serial://ttyACM0:230400 -out ntrips://:XXXXXXXX@localhost:2101/HOIHOIDO

この状態でRTK基準局として補正データーを配信してくれている筈なので、Ntripプロトコルで受信できるか試してみます。

まずWindows PC上でRTKNAVIを実行し、右上の[I]ボタンを押します。
(2)Base Stationだけにチェックを入れて、TypeをNTRIP Clientに、FormatをRTCM3に設定してOpt欄の「…」を押します。
そしてラズパイサーバーのIPアドレスとポート番号(2101)を入力して一旦[GetMountp]ボタンを押すと・・・

MountpointプルダウンにNTRIPサーバー内で管理している基準局一覧が出ます。
ここでは先程作ったHOIHOIDOのみが表示されるのでこれを選びます。

OK × 2回でメイン画面に戻り、[スタートボタン]を押すと・・・

基準局で受信した結果がグラフとして出てきますね。
でもよく見るとグラフ右上の表示が「GRE」となっています。これはGPS,GLONASS,Galileoを受信していることを示しますがBeidouが無いですね。
一旦「■Stop」で止めて「Options…」ボタンを押すと下記の通りBDSにチェックが入っていませんでした。
ここにチェックを入れて・・・

再びスタートすると受信衛星数が一気に増えて賑やかになりました。
グラフ右上の表示も「GREC」となり、「C」が増えています。

という事でBeidouも受信できていますね。
なお、この中にQZSS(みちびき)が含まれていないのは上にも書いた通り、F9PのRTCM出力にQZSSを含められないからです(実は方法があったりするのでしょうか?)。

ここまで来たら目的の動作は出来ているので、あとは使いやすい様に電源を入れたら即起動する設定と、電源を切るとき用にシャットダウンボタンを追加していきます。

RaspberryPi立上げ時に起動する設定

UNIX系OSの立上り時に自動的にプログラムを実行する設定は、古くは/etc/rc.localだったり、比較的最近まで/etc/rc*.dだったりしましたが、最近はまた新しくなっていてsystemdというのが標準で、これを使えば起動が早いそうです。という事でsystemdで設定してみます。

/etc/systemd/systemの下にntripcaster.serviceという名前でファイルを作って下記の内容を書きます。

[Unit]
Description=ntripcaster
After=syslog.target

[Service]
Type=simple
WorkingDirectory= /usr/local/ntripcaster/bin
ExecStart=/usr/local/ntripcaster/bin/ntripcaster
TimeoutStopSec=5
StandardOutput=null

[Install]
WantedBy = multi-user.target

同様にstr2str.serviceという名前で以下のファイルを作ります。

[Unit]
Description=str2str
After=ntripcaster.service

[Service]
Type=simple
WorkingDirectory= /usr/local/bin
ExecStart=/usr/local/bin/str2str -in serial://ttyACM0:230400 -out ntrips://:XXXXXXXX@localhost:2101/HOIHOIDO
TimeoutStopSec=5
StandardOutput=null

[Install]
WantedBy = multi-user.target

systemdを制御する主なコマンドは下の通りなので・・・

$ sudo systemctl start <サービス名> // 手動起動
$ sudo systemctl stop <サービス名> // 手動停止
$ sudo systemctl enable <サービス名> // 自動起動設定
$ sudo systemctl disable <サービス名> // 自動起動停止
$ journalctl -u <サービス名> // ログを見る

Ntripcasterとstr2strを手動で起動してみます。

$ sudo systemctl start Ntripcaster
$ sudo systemctl start str2str

この状態で上で試したのと同様にWindows PCからNtrip経由で情報を受け取れるはずです。
問題なければ下記コマンドで一旦停止し・・・

$ sudo systemctl stop Ntripcaster
$ sudo systemctl stop str2str

立ち上げ時の自動起動を有効にすると、再起動しても立ち上がっている筈です。

$ sudo systemctl enable Ntripcaster
$ sudo systemctl enable str2str

シャットダウンボタン。

常時起動にしてもシャットダウンする事はあります。その際sshでログインしてシャットダウンするのも面倒なのでシャットダウンボタンを付けておきます(これは色々な方法がありそうですが、自分の備忘録として書いときます・・・)

まずスイッチはGPIO3とGND間にタクトスイッチを付けました。

プログラムからGPIOをコントロールするライブラリとして以前はwiringPiを使っていましたが、もう古くてサポートされない様です。で、今風なのはlibgpiodだそうなので、まずこれをインストールしておきます。

$sudo apt install libgpiod3

そして下の内容でsdbuttond.cというファイルを作成し・・・

#include <stdio.h>
//#include <wiringPi.h>
#include <gpiod.h>
#include <stdlib.h>
#include <unistd.h>

//#define DBG

#define STARTTIME 10
#define STOPTIME 3
#define SDBUTTON 3

void DoShutdown() {
#ifdef DBG
  printf("Exec shutdown!!\n");
#endif
  system ("shutdown -h now");
}

int main() {
  int starttimer=STARTTIME;
  int stoptimer=STOPTIME;
  int enablef=0;
  int val;


  // libgpiod関係の準備ここから
  const char *chip_path = "/dev/gpiochip0";
  unsigned int offset = SDBUTTON;  // GPIO**
  struct gpiod_chip *chip;
  struct gpiod_line_config *line_cfg;
  struct gpiod_request_config *req_cfg;
  struct gpiod_line_request *request;
  struct gpiod_line_settings *settings;

  // チップを開く
  chip = gpiod_chip_open(chip_path);
  if (!chip) {
    perror("gpiod_chip_open");
    return 1;
  }

  // ライン設定作成
  settings = gpiod_line_settings_new();
  gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
  gpiod_line_settings_set_bias(settings, GPIOD_LINE_BIAS_PULL_UP);

  // ラインコンフィグ
  line_cfg = gpiod_line_config_new();
  gpiod_line_config_add_line_settings(line_cfg, &offset, 1, settings);

  // リクエスト設定
  req_cfg = gpiod_request_config_new();
  gpiod_request_config_set_consumer(req_cfg, "button");

  // リクエスト作成
  request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
  if (!request) {
    perror("gpiod_chip_request_lines");
    return 1;
  }
  // libgpiod関係の準備ここまで


  while(1) {
    val = gpiod_line_request_get_value(request, offset);
    if (enablef==0) {
      // まだイネーブルになっていない場合。
      if (val == 1) {
        starttimer--;
      } else {
        starttimer=STARTTIME;
      }
      if ( starttimer == 0) { enablef = 1;}
    } else {
      // イネーブルになった後。
      if (val == 0) {
        stoptimer--;
      } else {
        stoptimer=STOPTIME;
      }
      if ( stoptimer == 0 ) {
        DoShutdown();
        return 0;
      }
    }
#ifdef DBG
    printf("enablef:%d starttimer:%d stotimer:%d\n",
           enablef,starttimer,stoptimer);
#endif
    sleep(1);
  }
}

各#defineの意味は下記の通りです。

  • #define STARTTIME 10
    起動後この秒数はボタンを押してもシャットダウンしない。
  • #define STOPTIME 3
    この秒数押すとシャットダウンする(但しポーリングにつき1秒のばらつき有り)
  • #define SDBUTTON 3
    ボタンを接続するGPIO番号。3にしておくと再立ち上げにも使える。


次の様にコンパイルして実行ファイルsdbuttondを/usr/local/binの下にコピーします。

$ gcc sdbuttond.c -o sdbuttond -lgpiod
$ sudo cp sdbuttond /usr/local/bin
$ sudo chmod 755 /usr/local/bin/sdbuttond

先の2件と同様に/etc/systemd/system/sdbuttond.serviceを下の内容で作って・・・

[Unit]
Description=sdbuttond
After=syslog.target

[Service]
Type=simple
WorkingDirectory= /usr/local/bin
ExecStart=/usr/local/bin/sdbuttond
TimeoutStopSec=5
StandardOutput=null

[Install]
WantedBy = multi-user.target

お試し実行してみます。

$ sudo systemctl start sdbuttond

これでGPIO3に付けたタクトスイッチを数秒押すとシャットダウンする筈・・・試すと思惑通りシャットダウンしました。
ではもう一度立上げて恒久起動にします。

$ sudo systemctl enable sdbuttond

以上で一通りのインストールが終わったので・・・

写真の様なケースをThingiverseからダウンロードしてプリントし、壁に貼り付けていますが、本当に常時稼働させる様になったら防火対策のため金属製のケースに入れたいと思います。

Leave a Reply

Your email address will not be published. Required fields are marked *


*