FlightAwareにフィードする

週の前半に見た週間天気予報ではせっかくの週末が天気悪いということだったが、土曜日は夕方まで雨が降らずむしろ晴れていたくらいで、これ幸いにアンテナを屋根の高さに上げた。

コリニアアンテナを屋根に上げた
事情があって、前回とは屋根自体が違う。倉庫の鉄筋から単管をドーンと外に突き出した形。⌀48.6ミリのありふれた単管と⌀32ミリの細めの単管を直交クランプで交差し、そこに「なんちゃってコリニアアンテナ」を留めた。パイプの太さが違う用の筋交金具は見つけられなかったので支え無し。直交クランプだけだとちょっと強度が心配ではある。単管はそれぞれキャップを付けた。(上下の単管の下端は無し)
アンテナを屋根に上げるまでは、アンテナの入ったJ管の上端を自己融着テープで防水してビニールテープで保護して地上に置いたアンテナポールに建てていたのだが、親からの報告によると、鳥が留っていたのと、野良猫の子供がアンテナにじゃれていたとのことで、短期間であったにも関わらずビニールテープの保護部がみごとに破壊されていた。そこで、融着テープとビニールテープの保護をやりなおした上で、鳥の足で破壊されないようパイプキャップを被せてさらにビニールテープを巻きつけて固定した。(キャップの耐候性が心配だった)

カバレッジ
アンテナを上げてからフィードの準備のためにdump1090-faを停めるまで数時間ほど取得したカバレッジ。このカバレッジはアンテナを上げてから新規に取得し直したものなので北西方向はアンテナが地上にあったときよりも50kmほど狭くなっている。カバレッジを見るなら少なくとも24時間は取得した方が良さそう。で、東北東側は長野県まで到達し、南西側も和歌山・奈良に突入した。しかし、期待される見晴らしよりもまだだいぶ狭い。まぁ、想定されるカバレッジの内側ぎりぎりを航空機が飛んでくれないとカバレッジとして描かれないので、取得開始から僅か数時間では無理というものではある。

フィードしたい

dump1090-faと受信データをマップにプロットするアプリで航空機の飛行状況をPCで見て薄気味悪くニヤニヤできるようになったわけだが、せっかくなのでデータを共有することにしたい。フィード先は大手だとFlightradar24、FlightAware、planetfinder、RadarBox (RadarBox24)、ADS-B Exchangeとか? dump1090-faを使っているからというわけではないが、今回はFlightAwareに参加することにした。
Raspberry Piを使っていたら、それ用に提供されているイメージファイルをMicroSDカードに焼くだけとかパッケージをインストールするだけとかとにかく簡単なのだろうが、arm64のOrange Pi Zero Plusなので少しだけ手間がかかる。

FlightAwareにデータをフィードするにはクライアントのアプリケーションとしてPiAwareが必要。受信用のdump1090-faは前回そのまま。 そのPiAwareがOrange Pi Zero Plus + Armbian (Debian Buster)ではそこら辺からダウンロードしてインストールして終わりとはいかない部分。 まぁ、ビルドするだけなんだけど。

PiAwareのビルド

必要なパッケージをインストールする。dump1090-faをビルドしたときにインストールしたパッケージが残っているものとする。

$ sudo apt install tcl8.6-dev python3-venv      ← README.mdで必要とされているもの
$ sudo apt install libboost-system-dev libboost-program-options-dev libboost-regex-dev libboost-filesystem-dev devscripts python3-dev     ←おそらく他に足りないもの

インストールするパッケージが依存する他のパッケージもそれなりにインストールされる。

$ git clone https://github.com/flightaware/piaware_builder.git
$ cd piaware_builder
$ ./sensible-build.sh buster   ←重要
使用中のOS(ArmbianのDebian)のバージョンを引数として指定。今回は buster を付けた。
暫く進行して以下の表示で終われば正常。 Ok, package is ready to be built in ./package-buster
run 'dpkg-buildpackage -b' there (or move it to a Pi and do so there, or use pbuilder, etc)

flightaware_builderディレクトリの下にpackage-busterディレクトリが作成されている。

$ cd ~/piaware_builder/package-buster   ←最後のbusterは自身の使用中のOSに合うものを(というか上のメッセージに書かれているのに従う)。
ここまでがビルドの準備。
ビルド
$ dpkg-buildpackage -b --no-sign

中略

make[2]: Entering directory '/home/hoge/piaware_builder/package-buster/dump978'
g++ -g -O2 -fdebug-prefix-map=/home/hoge/piaware_builder/package-buster=. -fstack-protector-strong -Wformat -Werror=format-security -std=c++11 -Wall -Wno-psabi -Werror -O2 -g -Ilibs -Wdate-time -D_FORTIFY_SOURCE=2 -DVERSION=\"3.8.0\"  -c -o faup978_main.o faup978_main.cc
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
make[2]: *** [: faup978_main.o] Error 1
make[2]: Leaving directory '/home/hoge/piaware_builder/package-buster/dump978'
make[1]: *** [debian/rules:54: build_dump978] Error 2
make[1]: Leaving directory '/home/hoge/piaware_builder/package-buster'
make: *** [debian/rules:95: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2

ビルド失敗。メモリが足りてなくて停まったっぽい。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:          479Mi       101Mi       260Mi       2.0Mi       117Mi       366Mi
Swap:         239Mi          0B       239Mi

うわっ少なっ! まぁ登載メモリが512MBでストレージがMicroSDカードなシングルボードコンピュータだからこんなもんだよね。こりゃ「空きメモリ使い切り+スワップ使い果たし」も仕方ない。

Linuxの作法はよく知らないけどスワップを一時的に拡張することにした。
現在のスワップを停止。

$ sudo swapoff -a
$ free -h
              total        used        free      shared  buff/cache   available
Mem:          479Mi       101Mi       259Mi       2.0Mi       118Mi       366Mi
Swap:            0B          0B          0B

スワップをオフにしたので当然0バイトになった。
臨時スワップ用のイメージファイルを1GBで作成する。

$ sudo dd if=/dev/zero of=/swap.img bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 55.3854 s, 19.4 MB/s

ファイル作成にはちょっと時間がかかるかも。

$ sudo chmod 600 /swap.img  おそらくパーミッションを変更しないと次がNG
$ sudo mkswap /swap.img 作成したファイルをスワップファイルに指定。
$ sudo swapon /swap.img  作成したスワップをオンにする。
$ free -h
              total        used        free      shared  buff/cache   available
Mem:          479Mi       102Mi        59Mi       2.0Mi       316Mi       364Mi
Swap:         1.0Gi          0B       1.0Gi

これで1GBのスワップが有効になった。
これは設定ファイルを書き込んではいないのでシステム再起動で変更前に戻る。ただし、1GBの/swap.imgは残るので不要になったら消す。

2020年5月21日追記:
大物ビルド時ではなく通常時のためのスワップ設定について。
システム負荷が低いときでも遠慮せずにガンガンSwapするのが最近のArmbainの初期値みたい。昔のSLCならともかく最近のTLCのようなアホみたいに耐久性の低いmicroSDカードでスワップしまくると早々に壊れる可能性がある。そこで、本当のメモリ不足(非常時)のためのスワップは活かしたまま、普段はなるべくスワップさせない設定。
変更するファイル /etc/sysctl.conf (追記または修正 1行)
vm.swappiness=1
Armbianだと何故か初期値100で書かれているかもしれないので1にする。0にはしない。
$ sudo sysctl vm.swappiness=1 (システム起動後に手動でただちに設定を反映させたい場合)

再ビルドする。

$ cd ~/piaware_builder/package-buster
$ dpkg-buildpackage -b
今度は正常にビルドできた。

1階層上の~/piaware_builderに戻るとpiawareのパッケージが出来ているのでそれをインストールする。
今回はpiaware_3.8.0_arm64.deb

$ sudo dpkg -i piaware_3.8.0_arm64.deb
Selecting previously unselected package piaware.
(Reading database ... 53203 files and directories currently installed.)
Preparing to unpack piaware_3.8.0_arm64.deb ...
Unpacking piaware (3.8.0) ...
dpkg: dependency problems prevent configuration of piaware:
 piaware depends on tclx8.4; however:
  Package tclx8.4 is not installed.
 piaware depends on tcllib; however:
  Package tcllib is not installed.
 piaware depends on tcl-tls; however:
  Package tcl-tls is not installed.
 piaware depends on itcl3; however:
  Package itcl3 is not installed.

dpkg: error processing package piaware (--install):
 dependency problems - leaving unconfigured
Processing triggers for libc-bin (2.28-10) ...
Processing triggers for systemd (241-7~deb10u3) ...
Processing triggers for rsyslog (8.1901.0-1) ...
Processing triggers for man-db (2.8.5-2) ...
Errors were encountered while processing:
 piaware

まだパッケージが足りないとかいってる。しかも、古いバージョンを要求してる。面倒ねぇ。

$ apt install tclx8.4 tcllib tcl-tls itcl3
$ apt install --fix-broken

$ sudo dpkg -i piaware_3.8.0_arm64.deb
(Reading database ... 55491 files and directories currently installed.)
Preparing to unpack piaware_3.8.0_arm64.deb ...
Unpacking piaware (3.8.0) over (3.8.0) ...
Setting up piaware (3.8.0) ...
Processing triggers for libc-bin (2.28-10) ...
Processing triggers for systemd (241-7~deb10u3) ...
Processing triggers for rsyslog (8.1901.0-1) ...
Processing triggers for man-db (2.8.5-2) ...
今度は大丈夫。

「今度は大丈夫」なのはPiAware3.8の場合で、4.0ではtcl-tlsが専用版が要るみたい。そのビルドについてはdump1090-faとPiAwareをVersion 4.0に更新に書いている。

$ sudo piaware-config allow-auto-updates yes
$ sudo piaware-config allow-manual-updates yes

これで設定ファイルの/etc/piaware.confに設定が2行追加される。
flightaware.com側からの操作が受け付けられる。(後のMLATの設定で使われる)
その他の設定はPiAware 3 Advanced Configurationを参照。特に何か無ければ追加指定する必要はなさそうだけど。

起動中のPiAwareの未指定値含めて全オプション状態を表示するなら piaware-config -showall (これはこの記事では省略)

$ piaware-status
PiAware master process (piaware) is running with pid 1321.
PiAware ADS-B client (faup1090) is running with pid 1352.
PiAware ADS-B UAT client (faup978) is not running (disabled by configuration settings)
PiAware mlat client (fa-mlat-client) is running with pid 15669.
Local ADS-B receiver (dump1090-fa) is running with pid 1117.

dump1090-fa (pid 1117) is listening for ES connections on port 30005.
faup1090 is connected to the ADS-B receiver.
piaware is connected to FlightAware.

dump1090 is producing data on localhost:30005.

Your feeder ID is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (from /var/cache/piaware/feeder_id)
稼働中のステータス表示はこんなの。動いているべきもの停まってるべきものを確認する。

システムを再起動してpiawareが自動起動することを確認する。

FlightAware.com参加

ブラウザでhttps://ja.flightaware.com/にアクセスして会員登録する。
会員としてログインした状態でhttps://ja.flightaware.com/adsb/piaware/claimを開く。

FlightAware.com参加 1
グローバルIPアドレスを見てるのかな?シングルボードコンピュータのpiawareと同じNATにいるPCでアクセスしたら特に何もせずに自動的にアカウントとPiAwareが紐付けられた。(っていうことはPiAwareはそれまで勝手にflightaware.comに接続してたってこと? ヨクナイゾ)

LAN側のファイアウォールで外部との通信をブロックしているとかがなければ、これでフィードが始まっている。なお、他のアプリなどでdump1090-faからデータを引いているとフィードが停まることがあるようなので、そういう場合は要対策。

FlightAware.com参加 2
flightaware.comの最上部にある「My ADS-B」で自身のフィード状況のページを開き、サイト情報のすぐ上にあるサイト番号のかかれたバー(オレンジ?)の右にあるギアアイコンを開き、「MLATが有効です」が選択されていることを確認。そして、「場所設定」と「高さを設定して下さい」でアンテナの場所と高さを入力。[Save]で保存。これで「MLAT」が有効になり緑になる筈。(piaware-configでallow-mlatをno指定していないこと)

FlightAware.com参加 3
で、FlightAwareのフィーダーになったわけだけど、これでFlightAwareの会員クラスが普通の無料会員であるBasicからEnterpriseに自動的に変わって、月々$89.95の会費が無料ということなんだけど、会員のクラスが上がったところで、そもそもFlightAwareで見れる情報って何故かあまり楽しくないように思う。特にフィーダーの楽しみがない。(FlightRadar24はFlightAwareよりもさらにフィーダー向け情報が楽しくなかったことを追記しておきます。FR24の方は自分の順位付近のランキング見るのも大変だし)
もう少し見せ方があるんじゃないかしら?

FlightAware.com参加 4
フィードしたデータとは関係なく、FlightAwareで特定の航空機のフライト情報の例。緑〜黄色のモニャモニャしたのは雨雲。

関連記事:

dump1090 Prometheus ExporterでADS-B受信状況を監視する

前の記事ではdump1090-fa(他のdump-1090でも同じ)をインストールして実行したが、こういうのは基本的には停まらず動き続けてくれることが前提のサービスなので動いていることを監視したいという欲求はある筈。(dump1090が動いているホストのシステム稼働状況を監視するのとは別にdump1090の稼働状況を監視したいという意味)  それで、そう考えた先人はPrometheusで監視する用のexporterとしてdump1090 Prometheus Exporterと、Grafana用ダッシュボードのdump1090export Grafana dashboardというのを作ってくれている。ここは凄く感謝して使わせていただくことに。

dump1090 Prometheus Exporterのインストールと起動

以下、https://github.com/claws/dump1090-exporterを参照して進めた。

dump1090exportは必ずしもdump1090-fa(など)と同じホストに置く必要はないみたいだけど、敢えて別けて置く必要もまたないわけで、今回はdump1090exportをdump1090-faと同じホストで実行させるようにする。使用するのは前回と同じくOrange Pi Zero Plusというシングルボードコンピュータで動くArmbian(Debian Linux)のホスト。Raspberry PiとRaspbianやPCのLinuxもほぼ似たようなものかと。

Armbianはコンパクトなので最初からあれもこれもてんこ盛りで入っているわけではないので幾つかパッケージをインストールする。Pythonが必要だが、Python2系はダメらしいのでpython3系でパッケージをインストールする。

$ sudo apt install python3-pip python3-setuptools python3-dev
$ sudo apt install wheel  #上の他に必要かも
$ sudo pip3 install dump1090exporter

Python3系用のpipはArmbianのパッケージでインストールするとpip3らしい。Linuxの他のディストリビューションやxBSD等では必要に応じてpipに読み替えて実行いただければ。
dump1090exportはpipでインストールするだけなので簡単。Python用で必要なのは勝手にインストールされる。

/usr/local/bin/dump1090exporterが実行に使用するファイル。

$ dump1090exporter -h
usage: dump1090exporter [-h] [--url <dump1090 url>] [--host <exporter host>]
                        [--port <exporter port>]
                        [--aircraft-interval <aircraft data refresh interval>]
                        [--stats-interval <stats data refresh interval>]
                        [--latitude <receiver latitude>]
                        [--longitude <receiver longitude>] [--debug]

dump1090 Prometheus Exporter

optional arguments:
  -h, --help            show this help message and exit
  --url <dump1090 url>  Url of the dump1090 service to be monitored
  --host <exporter host>
                        The address to expose collected metrics from. Default
                        is all interfaces.
  --port <exporter port>
                        The port to expose collected metrics from. Default is
                        9105
  --aircraft-interval <aircraft data refresh interval>
                        The number of seconds between updates of the aircraft
                        data. Default is 10 seconds
  --stats-interval <stats data refresh interval>
                        The number of seconds between updates of the stats
                        data. Default is 60 seconds
  --latitude <receiver latitude>
                        The latitude of the receiver position to use as the
                        origin.
  --longitude <receiver longitude>
                        The longitude of the receiver position to use as the
                        origin.
  --debug               Print debug output
dump1090exporterのREADME.rstによると実行サンプルは以下。
$ dump1090exporter \
  --url=http://192.168.1.201:8080 \
  --port=9105 \
  --latitude=-34.9285 \
  --longitude=138.6007 \
  --debug

ただし、dump1090-faが動いているホストで実行する場合は--url, --host, --portは指定する必要はなさそう。また、2つのインターバル指定も多くの場合は初期値から変えなくて良さそうなので--latitude(緯度)と--longitude(経度)だけ指定する。もちろん、動作テストのとき以外は--debugは要らない筈。

その後のdump1090exporterの更新で、--resource-pathというオプションが追加になっている。これはおそらく指定必須で、dump1090-faが出力するcraft.jsonなどのpathを指定する必要がある。piawareのデフォルトでは/run/dump1090-faあたりかな?サービス起動用のファイル/lib/systemd/system/dump1090-fa.serviceを見て--write-jsonで指定されているpathがそれ。

なので、デフォルトではdump1090-faが/runに頻繁にファイル出力していることになる。ストレージがmicroSDカードなどのNANDメモリを使用したものだと非常によろしくない。できればRAMディスクの/tmpなどに出力するようにしたい。

/lib/systemd/system/dump1090-fa.service (追加+変更) ExecStartPre=/bin/bash -c '/bin/mkdir -p /tmp/dump1090-fa 2> /dev/null'
ExecStartPre=/bin/chown dump1090:nogroup /tmp/dump1090-fa
ExecStartPre=/bin/chmod 755 /tmp/dump1090-fa
ExecStart=/usr/share/dump1090-fa/start-dump1090-fa --write-json /tmp/dump1090-fa --quiet

ExecStartPreの3行は追加。bash, mkdir, chown, chmodのpathはシステムによっては /bin ではなく /usr/bin など異なるので必要に応じて変更。
ExecStartの行は--write-jsonの後のpathを変更している。

systemdのサービス用ファイルを変更したら sudo systemctl daemon-reload を実行してから systemctl restart dump1090-fa のようにdump1090-faを再起動する。

dump1090-faのウェブUIを有効にしている場合、dump1090-faのサービス用ファイルで(またはdump1090-faの設定ファイルで)jsonファイルの出力先を変更すると、ウェブUIのデータ取得先が/run/dump1090-faのままになるので地図が表示されるだけになる。 /etc/lighttpd/conf-available の下にある 89-dump1090-fa.conf と 89-skyaware.confの中にある "/run/dump1090-fa" を "/tmp/dump1090-fa" など変更したpathに書き換える。

システム起動時にdump1090exporterを自動起動させるためのsystemd用ファイルは作っても良いと思うが面倒なので/etc/rc.localに2行挿入した。

/etc/rc.local (2行挿入、最後の"exit 0"の直前の行辺り)
/bin/sleep 20
/usr/local/bin/dump1090exporter --latitude=-35.00000000 --longitude=136.00000000 &

↑は古いdump1090-exporterの場合。新しいdump1090-exporterでは--resource-pathも指定する。上述のようにdump1090-faのファイルを /tmp/dump1090-fa に出力するなら↓。出力先を変更してなくても --resource-path "/run/dump1090-fa" など指定は必要。

/etc/rc.local (2行挿入、最後の"exit 0"の直前の行辺り)
/bin/sleep 20
/usr/local/bin/dump1090exporter --latitude=-35.0000000 --longitude=136.00000000 --resource-path "/tmp/dump1090-fa" &

システム起動が落ち着いてからdump1090exporterを起動させるというつもりて20秒の余裕を持たせた。

手動でも自動実行でもdump1090exporterが起動してから、情報が出力されていることを確認してみる。

curlで実行(ブラウザでも可)
$ curl http://192.168.0.127:9105/metrics

ここでは192.168.0.127がdump1090exporterが動いているホストのIPアドレスとする。

# HELP dump1090_messages_total Number of Mode-S messages processed since start up
# TYPE dump1090_messages_total gauge
dump1090_messages_total{time_period="latest"} 8462670
# HELP dump1090_recent_aircraft_max_range Maximum range of recently observed aircraft
# TYPE dump1090_recent_aircraft_max_range gauge
dump1090_recent_aircraft_max_range{time_period="latest"} 0.0
後略

何か値が入っていて120行程度?ドバッと出力されればOK。

これでdump1090exporter側は完了。

Prometheus側の設定

dump1090exporterのREADME.rstによると設定ファイルに以下のようなのを追記することになっている。

/usr/local/etc/prometheus.yml (既存の設定に編集追加)
1
2
3
4
5
6
scrape_configs:
  - job_name: 'dump1090'
    scrape_interval: 10s
    scrape_timeout: 5s
    static_configs:
      - targets: ['192.168.1.201:9105']

1行目のscrape_configs:の行は既にprometheus.ymlにあると思われるので、その下層の設定の後に2〜6行目を追加する。
targetsにdump1090exporterが動いているホストのIPアドレスを指定する。
Prometheusを再起動するなり設定ファイルをリロードさせるなり。

Prometheusはこれだけ。

Grafanaのダッシュボード追加

提供されているにダッシュボードを貰ってきてGrafanaにインポートしたら後は眺めるだけ。何も考えなくてよいのでラク。

dump1090 Prometheus Exporter 1
https://grafana.com/grafana/dashboards/768にダッシュボードがある。
ページを開いて右列のDownload JSONのリンクをクリックしてJSONファイルをダウンロードする。

dump1090 Prometheus Exporter 2
Grafanaの左列の Createにポインタを合わせ、サブメニューのImportをクリックする。

dump1090 Prometheus Exporter 3
右方のUpload .json fileボタンをクリックする。
ファイル選択画面が表示されるので先にダウンロードしたJSONファイルを選択してアップロードする。

dump1090 Prometheus Exporter 4
インポート画面に変わるのでOptionsの1番下のPrometheusのドロップダウンメニューからPrometheus(稼働中のPrometheusが複数ある場合はdump1090exporterのデータを取り込んでいるPrometheus)を選択する。
Importボタンをクリックする。

dump1090 Prometheus Exporter 5
自動的にインポートしたダッシュボード画面に切り替わる筈。Prometheusがdump1090exporterからデータを取り込み始めたとき以降のデータは遡って見ることができる。(もちろん、破棄された過去データは見れない)

dump1090 Prometheus Exporter 6
1つ前の画像はブラウザ画面が狭くて見難かったけど、実際に見るであろう2Kサイズくらいで表示するとこんな感じ。
それぞれのグラフの概要も表示されるので、それが何を示しているのかもわかる。他人が作ったダッシュボード(やグラフ)ってどういう意図で何を示そうとしているのか解らなくて困ることがあるので、こういう心配りは嬉しい。しかし、messages / secのグラフでlatest(直近の1秒)とlast 1 min(直近の1分間の平均?)を示している意図は判らない。
最上段のサマリの数字は、リアルタイム(今回のdump1090exporterの設定では10秒毎の更新)で、その時点でdump1090に検知されている情報。Aircraft Totalは、検知されている航空機数。Aircraft with Positionで位置の通知が正常に受信できている航空機。なのでAircraft without Positionは単純にその引き算。それが直下のグラフでは水色のラインで示されている。Max Rangeはその時点で一番遠くにいる航空機までの距離。Messages/Secは1秒あたりに受信するADS-Bの(Mode-S)メッセージパケット数。Signal PeakとSignal Meanは電波強度を示すためのピークと移動平均。ノイズはサマリの数値には表示されないが、Signal Strengthグラフには表示されている。単位はdbFSで個人的には馴染みがない。

見たら判るが、dump1090exporterがdump1090から取得するデータは統計情報(受信状況)だけ。dump1090が受信した個別の航空機のデータは含まれない。だから、dump1090exporterで取得したデータから各航空機の飛行経路をプレイバックできるかというと無理。作った人にそういう気持ちはなかったみたい。まぁ個別航空機のデータまで含んだらデータ量増えすぎなのでこれで良いと思う。

この記事では関係ないんだけど、
ADS-Bのメッセージパケットは航空機1機あたりで沢山来る。1パケットは112ビットまたは56ビット。仮に1バイト8ビットとして1バイトコードの文字データを送信するとすると英数字で14文字または7文字しか送れない程度の大きさでしかない。これでは航空機の識別番号と速度、位置、高度、その他幾つかの全てを1パケットで送るのは無理。それぞれの情報をタイプコード別に違うパケットとして送信するみたい。だから、電波状況によってはパケットを取りこぼして位置(だけ)が取得できない航空機とかがでてくるのね、きっと。パケットの仕様はよく見てないというか「がとらぼ」の中の人の頭のレベルでは理解できないので間違ってたらスミマセン。興味のある人はhttps://mode-s.org/を見て下さい。

関連記事:
Up