ISSからの眺めを再現するアプリを作る

 地球を回る人工衛星は、一体どんな景色を見ながら飛んでいるのだろうか?そんな疑問の答えを知るために宇宙から地球を眺めるアプリを作った。
 百聞は一見に然ず。下の画面をご覧ください。(起動に少し時間がかかります)

 Unityで作ったものをWebGLでビルドしたものを貼り付けてあります。これは、ISS(国際宇宙ステーション)の現在位置からの地球の眺めを表示しています。
 Windowsの実行形式のファイル、データディレクトリ、ライブラリを収めたzipファイルはこちら。適当な場所に解凍して、SatelliteView配下のフォルダの実行ファイルを起動すれば見られるようになっています。
 アプリを作った過程の概要を以下に順序を追って書いていきます。

人工衛星の軌道を計算する

 これ。とにかく、現在位置を知らなければどうにもならない。
 では、どうやるか?ウェブ上で検索をすると、「人工衛星位置推算の実際(最終版)」というpdfに詳しく書かれていた。書かれた手順に従って計算すると、得られるらしい。ざっくりいうと、平均運動量だとか近点角という値を得て、計算式にあてはめたら出るよ、ということであった。
 じゃあ、その値とやらは何処か?というと、CelesTrakというサイトがあって、ここでは周回中の人工衛星のデータを公表しているのだ。しかも、サイトの運営はNORAD(北米航空宇宙防衛司令部)!なんか、映画「ウォーゲーム」のイメージが強くって、あのシャイアンマウンテンの地下司令部でコツコツと人工衛星を監視して、データを取っているんだなぁと思っていたら、とっくの昔に近くの地上施設に移転していた。
 それはさておき、そのデータというのは2行軌道要素形式(Two Line Elements)と呼ばれているもので、一つの衛星のデータが下の画像のように2行で示されている。

 ここに、計算に必要な値は全部そろっているのから、読み込んで文字列を値に直せば、位置は出せる。
 まずは、前述のpdfを基に計算用のクラスを作って、2行要素から読んだ値を入力した値を計算できるようにする。

 出た!でもこれは正しい位置なのか?
 検証するために、ISSの位置を表示しているサイトを探してみると、いくつかある。
 海外サイトなら Current Position of ISS
 日本語で作られているサイトなら、人工衛星の位置
 大人の事情で、画面は示せないが、上の値とサイトで表示されている値の差経度・緯度で1度以下の差で収まっているようだ。よし、次は地球を作らないとな。

地球を作る

 まずは球体モデルを持ってくる。Blenderで作ったモデルはテクスチャの貼り付けでうまくいかなくなるので、以前に公開されていたSphere100.fbxっていう完全球体のfbxファイルを使わせてもらう。今では公開されていたページがなくなっちゃているんだけど、作ってくれた人、ありがとう。

 で、地球というからには海や陸がなくちゃいけない。便利なことに、地球の写真を数多く公開しているサイトがあるのですよ。
 Visible Earth a catalog of NASA images and animations of our home planet
 こんどはNASA。NORADといい、NASAといい、アメリカの政府機関のおかげで面白いアプリが作れるんだから、アメリカの納税者の皆さんには感謝しかない。
 ここに掲載されている写真から、地球全体が写されている画像を選んだ。これを球体モデルに貼るのだけど、できるだけ細かくしたいので、テクスチャサイズは8192に設定。加えて、画像の大きさも8192の正方形にリサイズして貼り付けた。

うん、いいじゃないですか。

宇宙も創る

 地球がそれなりにできると、周りの星空も作らないと実感がわいてこない。そこで、Unityのskyboxの画像を変更して、星空を作る。方法はMaterialを生成して、シェーダーをSkybox/ 6 sidedに指定、6枚の画像で星空を作ることにした。地軸を直立した形で地球を置いたときに、星の方向とぶつかる面の上に点を置けば、星空の背景が作られるはずだ。
 星の位置は自由に手に入るヒッパルコス星表というデータを使用する。そこから得られた星の赤経・赤緯の座標に基づいて点を打っていくと、6枚の画像になんだかそれらしいものが浮かび上がってきた。

 そして、マテリアルに入れてやると・・

 おお、母なる地球が!そりゃあ、沖田十三も思わず懐かしくなっちゃうよな。
 地球を回るとどんな感じか見てみよう。まず、地球のモデルのスケールを適切な大きさまで広げる。衛星の軌道の大きさと釣り合う大きさになっていれば、衛星と地球の位置関係を再現できるはずなのだ。

カメラを正しい方向に向ける

 この地球上を動く物体からの眺めを見るためにはカメラを正しい向きにしなければならない。手順としては、まず、前向きのベクトルを決める。そのために、衛星の位置を現在と、1秒後の時間で計算する。現在から1秒後の位置へ向かうベクトルを、現在の前向きベクトルとして取り扱っても大きな誤差にはならない。
 次に、原点(地球モデルの中心)から現在位置までのベクトルが、頭上へ向かうベクトルとして扱えるので、そのベクトルと、衛星に見立てたオブジェクトのtransform.upベクトルとの角度を計算し、rotationをその角度分回転させれば、衛星は常に地球を下に見る姿勢を保てる。それがこちら。

 地球の上をゆっくりと移動している。うまく行っているようだ。
 カメラの画像を見てみると、

 本当に地球の上を飛んでいるように見えるね。
 実際には位置の計算は負荷が高いので、位置を格納する配列を3つ作り、現在、1秒後、2秒後を計算しておき、1秒毎に2秒後の位置の値を更新していく形にする。それらから前向きベクトルを2つ(現在・1秒後間と1秒後・2秒後間)作り、その値を合成してフレームごとに前向きベクトルを作るようにしている。

太陽を作って、光の位置を制御する

 地球モデルを照らしているライトを時間を追って調整しないと、実際の地球とずれてしまうので、太陽の位置を調整する。
 「日の出・日の入りの計算」(長沢工・著、地人書館)の中で紹介されている太陽位置の概算式を使用することにする。近似式であるから、厳密な値とは少しずれるのだが、1度未満程の差なので、使用に差し支えないだろう。
 手順としては、太陽の黄経を計算し、それを赤緯・赤経に変換する。地球のモデルは直立していて、skyboxもそれにしたがって描画されているので、得られた赤経・赤緯から角度からベクトルを計算すれば、太陽の方向になるだろう。

 少し大きめだが、太陽に見立てた球体を配置した。太陽系っぽくていいじゃないか!
 この時、地球を照らすDirectional Lightも太陽の位置に置き、地球の方に向かうようにした。すると、現在の地球の昼夜が再現されているはずだ。
 

地球に雲と夜景を描く

 しかし、地形が表示されているだけだとなんだかしっくりこない。それはそうだろう。本物の地球には雲がかかっているし、夜になれば明かりがともるのだから。では、それを足してみよう。
 上に書いたVisible Earthの写真には、雲だけの写真と、夜の写真もそれぞれある。


 まずは雲だ。雲画像の黒い部分は透明化して保存、Unityにインポートする。球体モデルに貼り付けて、原点に配置。地球より少し大きくなるようにスケールを調整すると・・

 ますます地球らしくなってきた。
 次は夜景を作る。
 これも、画像の黒い部分は透明化する。そしてインポート。ここからは雲とは違って、シェーダーを生成して、そのメインテクスチャに指定する。シェーダーにコードを書いて挙動を決めることができるので、太陽の光が当たっている間は夜景は表示しないようにする。具体的には、法線ベクトルと光源との内積をとる。その内積が0以上になれば、光が当たっていると判定できるので(90度より浅い角度だから)、アルファ値を0にして夜景のテクスチャを表示しないようにできるのだ。
 東アジア、アメリカ、ヨーロッパなどは明かりが多くて夜景でも地形がわかりやすい。下は中国と日本付近の夜景。

 下の画像はアメリカを南から北に向かってみたところ。夜と昼の境界が現れているから、シェーダーの挙動はうまくコントロールできているようだ。

 ちょっと残念なのは、テクスチャのサイズを最大にしても、ギザギザが目立つこと。逆にフィルターを適応すると、今度はボケちゃって少し眠たい画像になるので、妥協することにした。
 

地図を表示してどこにいるかわかるようにする

 こうしてできたアプリでしばらく地球の眺めを楽しんでいたのだけど、夜の側に入って、大きな海の上を移動しているときは、どこにいる全く分からなかった。

一面青だし。真っ暗だし。しばらくしたら昼の側に抜けるのだろうけど、待ってられない。そこで、衛星の位置を示す地図を画面に表示することにした。
 地球のテクスチャに使った画像を縮小してインポート。衛星位置から経度と緯度を出して、地図上の相当する位置に赤い点を打つようにした。

 位置はわかったけど、この先どこに行くかわからないな。6分ほどの間隔で位置を計算して線を引けば、軌道が表示できそうだ。

 いいんじゃない?NASAの飛行管制センターみたいだ。
 もう一つ、カメラを追加してみる。地球の中心と衛星の延長線上にカメラを置いて、地球中心方向を見ると、真ん中が衛星の位置になる。

 真ん中に点を打って、わかりやすくした。リアルタイムで地球を見下ろすモニターのようになっている。
 作ったものをすべて表示すると、このようになった。

 今のISSからの眺めはこんな感じってことがわかるだけなのだが、一度見ると、そこそこの時間楽しめそうだ。

 日本列島もこんな感じで見えたりする。宇宙って、楽しそうだなぁ。
 こういったアプリはスクリーンセーバーにするといいんじゃないかと思ったけど、セーバーは廃れていく方向にあるだから、環境映像のように時々起動して眺めるというのが、主な使い道になるかもしれない。
 

オキュラスに対応してみる

 UnityのPlayerの設定で、VRにチェックを入れると、オキュラスリフトのようなデバイスで見ることもできます。冒頭でダウンロードできる実行形式のファイルをオキュラスが接続されたPCで実行すると、きちんと表示されて頭の動きに合わせてカメラの向きも変わります。
 ただ、地図は表示されなかった。GUIで処理したものは、VRの画面には表示されない。UIの特別な処理が必要なようだ。
 画像で示せないのだけど、VRで見た場合は宇宙船の窓から地球を眺めている感じにはなるかな。だから、地図は表示しないことにした。UIを特別に作るのが面倒だった、ということもあるけど、宇宙船の窓の外に地図が表示されてたら、興ざめでしょう?
 オキュラスリフトなんかを持っている人は、試してみてください。

 以上が、ISSからの眺めアプリの概要です。
 公開されている情報と、プログラミングで結構楽しいものが作れたりする。これはおもちゃみたいなものなんですけど、おもちゃも本気になって作ると、工夫が必要になってきて、作り上げることがが楽しくなってくる気がする。
 プログラミングの勉強には、いい題材ではないでしょうか。
 ではまた。
 
 

シェアする

  • このエントリーをはてなブックマークに追加

フォローする