見出し画像

[注意書きあり] MacOSでGPSレシーバを使って時刻合わせ

注意書き

この記事の公開後、改めて検証するために屋外の圏外になる場所で動作させたところ、FT8の送信のタイミングでGPSレシーバが停止するという現象が発生しました。現場で、手元にあったパッチンコアをケーブルにはめてみたりしましたが、応急処置では対処できず、現時点でもこの問題は解決していません。

一応、この記事は継続して公開しますが、上記の問題を抱えていることをご了承の上、お読み下さい。

なお、別の方法で時刻合わせする記事も公開していますので、そちら合わせてご参照頂ければと思います。

以下、公開済みの本文

FT8を運用するにあたって、PCの時刻合わせは非常に重要です。家庭内であればWi-Fiで、スマホが圏内であればテザリングを利用して、PCをインターネットに接続してNTPで時刻合わせるすることができます。しかしPOTAやSOTAのような移動運用時は、必ずしも携帯の電波が届くとは限りません。

また、場合によってはスマホを忘れた、スマホのバッテリーが切れた、充電ケーブルを忘れた、などのトラブルも考えられます。

しかし、空が開けていればGPS/GNSSの信号を利用して精度よく時刻合わせすることができます。最近はUSB接続できる安価なGPSレシーバが市販されている他、ハンディ機をGPSレシーバとして動作させることもできます。


前提

FT8を運用する際はPCが必要となりますが、一般的にはWindows PCが利用されており、雑誌やウェブの記事もWindows環境が対象のものがメインです。私はFT8をMacBook Airで運用していますので、MacOSでGPSレシーバを使って時刻合わせする方法を調査しました。

参考になった情報として、KC9WIB局がメーリングリストに投稿したgspdとChronyControlを組み合わせる方法が見つかりました。

ChronyControlはchrony (chronydデーモン・chronycクライアント) のMacOS用フロントエンドのようです。動作確認のために色々と触ってみましたが、個人的には肌に合いませんでした。

やはりCUIがシンプルでベストということで、gpsdと素のchronyを組み合わせることにしました。

gpsd

gpsdはシリアル接続されたGPSレシーバからの信号を処理するソフトウェアです。gpsmonコマンドで受信した信号をモニタリングすることもできます (後述)。オープンソースソフトウェアですので無料で利用できます。

chrony

chronyはNTPに対応した時刻同期サービスです。NTPサーバやgpsdから受信した信号を処理して時刻同期するchronydデーモンと、これと連携・制御するchronycクライアントから構成されます。chronyもgpsdと同じくオープンソースソフトウェアです。

注意点

以下、MacOSのターミナルでコマンドを実行します。プロンプトは%で表記しています。また、可読性を優先して、コマンドを実行した行の下に空行を入れるなど、適宜編集しています。

また、sudoコマンド実行時にパスワードを要求される場合がありますが、このプロンプトは省略しています。


ソフトウェアの設定

WSJT-X

FT8用のソフトとしてWSJT-Xをインストールしている場合、インストーラのReadMe.txtに従ってplistファイルを/Library/LaunchDaemonsにsudo cpしたかと思いますが、このファイルに変更を加えます。

具体的には、shmmniとshmsegの値を追加します。

% sudo vi /Library/LaunchDaemons/com.wsjtx.sysctl.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.wsjtx.sysctl</string>
    <key>Program</key>
    <string>/usr/sbin/sysctl</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/sbin/sysctl</string>
        <string>kern.sysv.shmmax=52428800</string>
        <string>kern.sysv.shmall=25600</string>
        <string>kern.sysv.shmmni=128</string>
        <string>kern.sysv.shmseg=32</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

保存したらMacを再起動しましょう。記事によってはlaunchctlコマンドで再読み込みできるとありますが、私の環境ではエラーになりました。

再起動後、設定が反映されているか確認します。

% sysctl -a | grep kern.sysv

kern.sysv.shmmax: 52428800
kern.sysv.shmmin: 1
kern.sysv.shmmni: 128
kern.sysv.shmseg: 32
kern.sysv.shmall: 25600

plistで設定した値が表示されていればOKです。

HomeBrew

HomeBrewはMacOSで利用できるパッケージ管理システムです。MacOS上で仕事をしているプログラマにはお馴染だと思います。

ターミナルに以下のコマンドをコピペすればインストールできます。最新のインストール方法は上記ウェブサイトを参照して下さい。

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

gpsd

まずはHomeBrewが提供するbrewコマンドで、gpsdをインストールします。

% brew update
% brew install gpsd

USBポートにGPSレシーバを接続すると、MacOSからはUSBシリアルデバイスとして認識されます。通常は/dev/tty.usbmodem* というファイル名になります。以下に、USBハブを介してGPSレシーバを接続した時の例を示します。

% ls /dev/tty.usbmodem*
/dev/tty.usbmodem11101

このデバイスファイルを引数に、gpsdを起動します。ここではPIDファイルも作成しています。

% sudo gpsd -n --pidfile /var/run/gpsd.pid /dev/tty.usbmodem11101

明示的にオプションを渡さない限り、gpsdはバックグラウンドで実行されますので、特に表示されずプロンプトが戻れば成功です。念のために信号を受信しているかgpsmonコマンドで確認してみます。

% gpsmon
gpsmonでリアルタイムにモニタリング

このスクショのように、リアルタイムに受信データが表示されていればOKです。gpsmonを終了するには、キーボードからq→Enterと順に入力して下さい。

chrony

次にchronyをインストールし、設定ファイルを作成します。以下に設定ファイルの例を示します。詳細はchronyのマニュアルを当たって下さい。ポイントは、下記の3点です。

  • bindcmdaddressはchronyc (後述) から参照されるので、ネットワークアドレスではなくUNIXドメインソケットを指定

  • refclockでGPSから時刻データを取得するよう設定

  • 他PCから参照されるNTPサーバとしては動作させない

% brew install chrony
% sudo vi /etc/chrony.conf

pool pool.ntp.org iburst
pidfile /var/run/chrony/chronyd.pid
driftfile /var/db/chrony/chrony.drift
bindcmdaddress /opt/homebrew/var/run/chrony/chronyd.sock
log tracking measurements statistics
logdir /var/log/chrony
maxupdateskew 100.0
dumponexit
dumpdir /var/db/chrony
rtcsync
# gpsd
refclock SHM 0 refid GPS
makestep 1 3

設定ファイルを作成したら、chronydを起動します。

% sudo chronyd

gpsdと同じくchronydもバックグラウンドで実行されますので、エラーメッセージが表示されなければOKです。Macがインターネットに接続されていれば、NTPサーバに接続して時刻合わせが自動で行われます。

この起動時に/var/run/chronyディレクトリがないというエラーが表示される場合は、このディレクトリを作成し、chmodで権限を設定してから再度実行します。

% sudo mkdir /var/run/chrony
% sudo chown root:wheel /var/run/chrony
% sudo chronyd

chronydが動作しているか、chronycコマンドで確認してみましょう。引数にtrackingを渡して実行します。以下に実行例を示します。

% sudo chronyc tracking

Reference ID : 85F3EEF3 (ntp-a2.nict.go.jp)
Stratum : 2
Ref time (UTC) : Sat May 25 05:34:51 2024
System time : 0.000415727 seconds slow of NTP time
Last offset : -0.000235692 seconds
RMS offset : 0.001010206 seconds
Frequency : 0.191 ppm slow
Residual freq : +0.531 ppm
Skew : 8.455 ppm
Root delay : 0.019880097 seconds
Root dispersion : 0.000715398 seconds
Update interval : 64.2 seconds
Leap status : Normal

NICTのNTPサーバに接続して同期していることを確認できました。GPSレシーバからの信号が認識されているか確認するには、sourcesを引数に渡して実行します。

% sudo chronyc sources

MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#x GPS 0 4 377 10 -927ms[ -927ms] +/- 200ms
^- x.ns.gin.ntt.net 2 6 377 20 -3512us[-3504us] +/- 83ms
^- time.cloudflare.com 3 6 377 20 +1662us[+1670us] +/- 67ms
^* ntp-a2.nict.go.jp 1 6 377 20 +133us[ +141us] +/- 10ms
^- time.cloudflare.com 3 6 377 21 +272us[ +280us] +/- 69ms

GPSの行があることが確認できます。


動作確認

以下のような手順で、GPSで時刻合わせができることを確認します。

Wi-Fi切断

Wi-Fiをoffにしてネットワーク接続を切断し、NTPで時刻同期できないようにします。

chronyc起動

引数を渡さずにchronycを起動するとchronycのシェルが起動し、インタラクティブにchronydを操作することができるようになります。

% sudo chronyc

chrony version 4.5
Copyright (C) 1997-2003, 2007, 2009-2023 Richard P. Curnow and others
chrony comes with ABSOLUTELY NO WARRANTY.  This is free software, and
you are welcome to redistribute it under certain conditions.  See the
GNU General Public License version 2 for details.

chronyc> 

onofflineコマンド

chronydにオフラインになったことを通知します。正常に実行された場合は200 OKが返されます。エラーが発生した場合、200 OK以外が返されます。以降のコマンドも同様です。

chronyc> onoffline

200 OK

reselectコマンド

chronydにソースを再選択させますが、実行しなくてもよいかも知れません (要検証) 。

chronyc> reselect

200 OK

trackingコマンド

信号ソースとしてGPSが選択されたことを確認します。これには少し時間が掛かることがあり、しばらくNTPサーバの情報が表示されることがあります。そのような場合は1〜2分待ってから再度trackingを実行してみましょう。

chronyc> tracking

Reference ID : 47505300 (GPS)
Stratum : 1
Ref time (UTC) : Sat May 25 06:14:19 2024
System time : 0.902774870 seconds slow of NTP time
Last offset : +0.004733979 seconds
RMS offset : 0.277205676 seconds
Frequency : 0.345 ppm slow
Residual freq : +158.457 ppm
Skew : 1.046 ppm
Root delay : 0.200000003 seconds
Root dispersion : 0.104125388 seconds
Update interval : 16.0 seconds
Leap status : Normal

makestepコマンド

この時点で時刻同期がなされるようになりますが、通常、chronyは1秒の時刻のズレを12秒掛けて修正します。1分のズレの修正には12分掛かります。

強制的に時刻を同期させたい場合は、makestepコマンドを実行します。

chronyc> makestep

200 OK

これで時刻が同期 (修正) されたことを確認できると思います。

Wi-Fi再接続

GPS信号で時刻が同期されることを確認したら、Wi-Fiに接続し直します。オンラインになったことをonofflineコマンドでchronydに通知しておきましょう。

chronyc> onoffline

200 OK

quitコマンド

暫く放置しておけば、NTPから時刻同期するようになります。quitコマンドでchronycを終了しましょう。

chronyc> quit
%

オフセット調整

この状態でも一応使えるには使えますが、処理された後のGPS信号には多少のズレ (オフセット) が発生しています。これを補正しましょう。

makestepコマンド

オンラインになっていることを確認したら、chronyc makestepコマンドで時刻を合わせます。この時、オフラインになっていてNTPサーバに接続できていないと以下の操作の意味がなくなりますので注意が必要です。

% sudo chronyc makestep
200 OK

gpsmon

gpsmonを起動し、画面下寄りのNAV_DOPにあるTOFFの値を確認します。gpsdを起動してしばらく待ち、この値が落ちついた頃の値を用いましょう。gpsmonのスクショを再掲します。

NAV_DOPにあるTOFFの値を確認

この例では、およそ60m秒強のオフセットが生じていることを確認できます。

sourcestatsコマンド

chronyc sourcestatsコマンドで、このオフセット分だけGPSの信号が遅れていることを確認します。

% sudo chronyc sourcestats

Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
GPS                         9   5   124    +39.724     21.687    +64ms   503us
time.cloudflare.com         8   4   265     -7.503     46.506   -744us  1795us
time.cloudflare.com         8   5   264     -9.226     33.019  -1312us  1197us
ntp-b2.nict.go.jp           8   5   266     -2.305     14.751    -12us   406us
x.ns.gin.ntt.net            8   7   265     +0.697     13.443  +1107us   759us

TOFFの値とほぼ同じ程度の値が、GPS行のOffset値として表示されています。

sourcesコマンド

ついでに時刻のソースを一覧するchronyc sourcesコマンドを実行してみましょう。

% sudo chronyc sources

MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
#x GPS                           0   4   377    14    +65ms[  +65ms] +/-  533us
^- time.cloudflare.com           3   6   377    46  -5983us[-6028us] +/-   73ms
^- time.cloudflare.com           3   6   377    46  +1819us[+1774us] +/-   68ms
^* ntp-b2.nict.go.jp             1   6   377    44   +275us[ +227us] +/- 8318us
^- x.ns.gin.ntt.net              2   6   377    45  +1629us[+1582us] +/-   87ms

GPS行を見ると、行頭が #x となっています。2文字目の x はデータにエラーがあることを示唆しています。おそらく時刻のソースとしてはオフセットが大きすぎるということでしょう。

/etc/chrony.conf編集

chronyの設定ファイルで、GPS信号のオフセットを指定できます。ファイル末尾のGPSを記述しているrefclockにオプション offset を追加します。

% sudo vi /etc/chrony.conf

(上は省略)
# gpsd
refclock SHM 0 refid GPS offset 0.06
makestep 1 3

chronyd再起動

設定ファイルの変更を保存したら、chronydを再起動します。

% sudo chronyc shutdown
% sudo chronyd

sourcestatsコマンド

しばらく待ってから、chronyc sourcestatsコマンドでオフセットがどうなったか確認します。

% chronyc sourcestats 
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
GPS                        11   7   157     +0.367      7.257   +443ns   319us
time.cloudflare.com         7   5   200     +8.446     87.417    -13ms  1353us
time.cloudflare.com         7   4   201    +26.870    132.938  -8112us  2496us
x.ns.gin.ntt.net            7   5   200     +4.347     13.934    -13ms   255us
ntp-b2.nict.go.jp           7   4   200    +12.518     51.985    -11ms  1328us

60ミリ秒近くあったオフセットが、400ナノ秒まで小さくなりました。


サービス終了

chronyd

基本的にchronydは起動しっぱなしで問題ありません。もしプロセスを終了したい場合は、chrony.confで指定しているpidfileを利用します。

% sudo kill `cat /var/run/chronyd.pid`

あるいはchronycのshutdownコマンドで終了させることもできます。

% sudo chronyc shutdown

gpsd

GPSレシーバをUSBポートから外すとデバイスファイルは削除され、当然、gpsdは信号を受信できなくなります。再度同じUSBポートにGPSレシーバを接続し、同じデバイスファイルが作成されても、以前のプロセスからはGPS信号を受信できないようです。また、以前のプロセスが残ったままでは、再度gpsdを起動してもGPS信号を受信できないようです。

つまり、GPSレシーバを外した後は面倒ですがgpsdを終了する必要があります。起動時に--pidfileオプションで指定したPIDファイルを利用します。

% sudo kill `cat /var/run/gpsd.pid`

運用手順

ここまで長々と書いてきましたが、これでようやく運用できるようになりました。通常は以下のような流れになるかと思います。

  1. GPSレシーバを接続

  2. 既存gpsdプロセスがあればkill

  3. gpsd起動

  4. 既存chronydプロセスがなければchronyd起動

  5. 1〜2分待つ (その間に機器のセットアップ)

  6. FT8運用

  7. gpsdプロセスをkill

  8. GPSレシーバを外す


TODO

デバイス認識・自動起動/終了

Linuxのudevのように、GPSレシーバが接続/取り外しされたことを認識して自動でgpsdを起動/終了するようにしたいのですが、その方法が見つかていません。調査を継続します。

また、chronydはMacOSの起動と同時に起動してもよさそうです。通常であればbrew services startで登録できそうなのですが、brew services listにchronydがないので、他の方法が必要です。

スクリプト化

PIDファイルがあった場合は起動前にkillする等、自動起動の前段階としてこのあたりをうまく処理してくれるようなスクリプトがあると便利そうです。


GPSレシーバ

今回は以下のGPSレシーバで動作を確認しました。

市販品

Amazonで購入可能な、安価なUSB接続タイプのGPSレシーバです。そのままMacに接続すればUSBシリアルデバイスとして認識されます。

レシーバはUSB給電で動作しますので、それ自体のバッテリー切れを心配しなくてよいのはメリットです。車載での利用が想定されているのか分かりませんが、ケーブルがとても長いので、もしかしたらパッチンコアを装着した方がよさそうです。

TH-D75

KENWOODの最新ハンディ機であるTH-D75はGPSレシーバとして動作させることができます。PCとUSB-Cケーブルで接続すると、こちらもUSBシリアルデバイスとして認識されます。

設定方法は MENU -> GPS -> 基本設定 -> 動作モード (403) で GPSレシーバーを選択し、再起動します。しばらく待つと受信したGPS信号を画面上に表示します。

こちらはGPSレシーバを追加で持ち歩かなくて済むのがメリットです。GPSレシーバーモードにするとトランシーバとしては動作しなくなりますので、アマチュアバンドのモニタリングなどはできなくなります。また、当然のことながらハンディ機のバッテリー切れに注意が必要です。


この記事が気に入ったらサポートをしてみませんか?