流星がどの高度を飛んだか、複数のカメラで計算できるようにした
流星の動画クリップが録れると嬉しい。「あ、撮れてた!」ってなる。
でも毎回気になってたのが、「これ、上空何キロで光ってたんだろう」ということだった。火球クラスになると、ニュースで「上空80キロ付近で発光」みたいな報道がある。あの数字、どうやって出してるんだろうと思ってたら、答えは単純だった。複数の場所から同じ流星を撮って、三角測量しているだけだ。
SonotaCo Network や GMN のやってること
日本だと SonotaCo Network、海外だと Global Meteor Network(GMN)が、全国・全世界の観測者がそれぞれ検出した流星データを集めて三角測量している。使っている原理は高校の数学で出てくる三角測量そのもので、「2点から見た方角がわかれば位置が計算できる」というやつだ。
ただし流星は3D空間を飛んでいるので、2Dの三角測量ではなく空間直線の最近接点を求める計算になる。地球も球なのでそこも考慮しないといけない。
カメラは富士山周辺の3方向に置いてる
自分のシステム Meteo は、自宅の東・西・南の3方向にRTSPカメラを設置して流星を検出している。ただし全部同じ場所にある。三角測量には 離れた2拠点以上 から同じ流星を撮る必要があって、この構成では無理だった。
ということで、「他の場所にも同じシステムを展開して、検出データを中央のサーバに送ってくれたら三角測量できるはず」という設計を考えた。
以下は、実際に拠点展開しているわけではないので、デモ用にデータを作ってでもようにシミュレートしたものなので、本当に正しく動作するかは未確認。
作ったもの
こういう構造になった。
拠点A(自宅) 拠点B(別の場所)
カメラ×3 カメラ×N
検出器 検出器
station_reporter → station_reporter
↓ HTTP POST ↓
───── 三角測量サーバ ─────
↓
3D マップ表示
各拠点に station_reporter というサイドカーを追加するだけでいい。既存の検出コンテナはいじらなくて済む。station.json という設定ファイルに拠点の緯度経度と、カメラの向き(方位角・仰角・画角)を書くと自動で認識してくれる。
三角測量サーバは中央に1台置いて、複数拠点からデータを受け取る。同じ流星を複数拠点が検出したとき(時刻±5秒以内)に三角測量を実行して、高度・緯度経度・速度を計算する。結果はブラウザで3Dマップとして見られる。
こんな感じ。
関東〜東海エリアの広域ビュー。ダークマップ上に観測拠点と流星の軌道(始点・終点)が表示されている。
視点を傾けてズームするとこうなる。
高度スケール 1x(実縮尺)で北東から見下ろした3Dビュー。上空70〜115 kmの流星軌道が地表から立ち上がっているのがわかる。地表への垂直ドロップラインと破線の地表投影で、どのあたりの上空を通ったかも一目でわかる。
ピクセル座標を「空の方角」に変換するのが意外と面白かった
流星検出器が出力するのは「カメラ画像の何ピクセル目に流星があった」という情報だ。これを三角測量に使うには「北から何度、地平線から何度の方向」という天球座標に変換しないといけない。
カメラの仕様(画角・向き・傾き)を使ったピンホールカメラモデルで変換できる。やってみたら意外とシンプルで:
- ピクセルを画面中心基準の座標に変換
- 画角から焦点距離を出して方向ベクトルを計算
- カメラの向き(方位・仰角・ロール)の回転を3ステップで適用
数式にすると面倒に見えるけど、NumPy の行列演算で30行くらいで書けた。
ただ方位角の回転行列で一度ハマった。コンパス方位(0=北、90=東)って時計回りなんだけど、数学の角度は反時計回りが正方向なので符号を間違えると東に向けたカメラが西を向いた座標を返す。テストを書いてなかったら気づくのに時間かかってたと思う。
高度80〜100 kmがいかに「遠い」かがわかる
できあがった3Dマップを眺めていると改めて実感するんだけど、流星って本当に高いところで光ってる。
富士山から見上げた富士山頂の仰角は 30〜40 度くらいだけど、それはほぼ同じ高さ(3776m)。流星の発光高度は 80〜120 km。地平線から見た仰角 30 度の方向に 80 km 離れたところで光っているとすると、水平距離は 140 km になる。箱根から富士山を経由して静岡市の向こうくらいの距離だ。
そんな遠いところを毎秒 30〜60 km の速さで飛んでいて、それが一瞬光って動画に映る。上のズームビューで高度スケールを上げると、流星軌道が地図のはるか上方から斜めに降ってくるのが視覚的に確認できる。なんか改めて宇宙っぽいなと思った。
デモで試せます
まだ実際に2拠点で同時観測できたわけじゃないので(展開先を準備中)、リポジトリには合成データでデモが動くスクリプトが入っている。富士北麓・箱根・秩父の3拠点を仮想的に設定して、5件の流星軌道をあらかじめ計算して地図に表示する。
git clone https://github.com/Masakai/meteo
cd meteo
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python demo_triangulation.py
# → http://localhost:8090/ を開く
地図を右ドラッグするとカメラが傾いて3D視点になる。高度スケールのスライダーは 1x が実縮尺で、上げると流星軌道を誇張して見やすくなる。
次にやりたいこと
実際の2拠点運用ができたら、次は恒星を使ったカメラキャリブレーションをやってみたい。今は方位角・仰角を手動で station.json に入力しているけど、実際は設置精度に限界がある。夜間に北極星やベガを映して「このピクセルにこの星が映るはず」という照合をすれば、カメラの向きを精密に補正できるはずだ。
精度が上がると、流星の突入角度や地上投影点(もし燃え尽きずに落ちたとしたらどこに落ちるか、いわゆる隕石の落下予測)も計算できるようになる。
もちろん流星は大気圏でほぼ全部燃え尽きるけど、軌道計算の練習にはなる。
コードは GitHub (Masakai/meteo) で公開しています。三角測量関連は v3.4.0 から入っています。