読者です 読者をやめる 読者になる 読者になる

apollo11号のソースコードを読みつつ

これはなに?

この記事はeeic Advent Calender2016の21日目として書かれたものです。

qiita.com

はじめに

2016年7月、NASAインターン生だったchrisgarry氏がApollo11号に搭載されていた アポロ誘導コンピューター(Apllo Guidance Computer : AGC) のソースコードgithub上で公開しました。 この記事はNASAの仕様書片手にソースコードをふらふら興味の赴くままに眺めるものです。だからあまりストーリーとして通ってるわけではないので散発的に見ていただければと思います。 なんか笑えるコメントアウトを漁ってるだけで終わるかもしれない。

追記 : そんなことはなかった。資料を読み漁り過ぎてしまった。

f:id:aerith7:20161220002220j:plain

AGCあれこれ

f:id:aerith7:20161220002404p:plain:w200

写っている人はマーガレット・ハミルトン。
MITの研究者でアポロのソフトウェア開発を担当した女性です。
これ何しているかというと
自分たちの書いたAGC関連書類の隣に立っている
写真なんですね。これ一枚でいろいろな苦労が伝わってきます。。。

どの程度の量だったのか、公開されているソースコードを調べてみました。
以下のとおりです。
Luminary099に格納されている

  • 全てのソースコード : 64,992行
  • コード量 : 40,202行
  • コメント行 : 32,443行
  • 空白行 : 5,900行

ひょええ。。。 デバッグとかも満足に行えないことを考えるとすごい量ですよね。。
作業量は1400人年にも登ったのだとか。

AGCは司令船に1台、着陸船に1台計2台が搭載されました。 求められた役割は
以下のプロセスにおける自動航法・誘導
です。むしろここ以外の機能にPCは用いられなかったんですね。

  • 司令船
    • 月周回軌道に乗ること、地球への帰還軌道に遷移すること
  • 着陸船
    • 月周回軌道から着陸すること、月を離陸して司令船とランデブーすること

容量はROM : 72 KB、RAM : 4KB程度。 メモリはプログラムを全て0と1に書き起こしたあと、町工場の女性の手によって1つづつ銅線に編み込んで作ったようです。 4100個のNORゲートが一つのコンピュータに使用されています。 1960年代当時ICチップは世界最先端の部品でした。アメリカの60年代のICチップ生産量の8割がアポロ関連だったのだとか。

ソフトウェアやプログラム技法は完全に1から作られました。 AGCアセンブリ言語で書かれ、 バージョン管理システムはYULと呼ばれています。 余談ですが、AGCのエミュレーターvirtualAGCからダウンロードすることができます。興味のある方は是非。

Temporary I HOPEHOPEHOPE

LUNAR_LANDING_GUIDANCE_EQUATIONS .agc : 1375行目

多分これが一番笑いました。 テンポラリコードのまま月まで行ったんですね。。。

ASTRONAUT NOW LOOK WHERE YOU ENDED UP

THE_LUNAR_LANDING.agc : 317行目 p68

THE_LUNAR_LANDINGという名前の通り月着陸を行っているプログラムですね。 この中に頻出するp(数字)というのはサブルーチンの名前です。 NASAは略語好きなんですかね。P63 からP68まであります。 それぞれ何をしているのか資料を調べて見ました。 さっくりまとめてみます。

そもそも着陸は3つの段階に分かれています

  • Breaking Phase
    • 月周回軌道から逆噴射して着陸コースに乗ります(高度50000 ft -> 7000 ft)。基本原則は推進剤の消費を可能な限り抑えること
  • Approach Phase
    • 7000 ftから 400 ftまで降下と同時に船の角度を92°から50°に引き上げます。 ここで初めてパイロットは直接着陸地点を見れるようになります。
  • Landing Phase
    • 降下地点を見極めて着陸。

ちなみにApproach Phaseを過ぎると"着陸を中止する"という選択肢が無くなります。 それはそれ以降致命的な故障が起きると二度と帰ってこれなくなることを意味していました。

f:id:aerith7:20161220005418p:plain:w300

この中で各プログラムはどのような動きをしているのか。
まとめてみた表が以下になります。

サブルーチン名 phase 役割
P63 Breaking 自動でBreakingPhaseを実行します
P64 Approach 自動でApproachPhaseを行います
P65 Landing 速度を低減し自動垂直着陸を行います
P66 Landing 高度の手動調整を行います
P67 Landing 完全手動で着陸を行います
P68 Landing 着陸確認プログラム

冒頭のp68のコメントアウト行は着陸動作を全て終了して初めてたどり着くんですね。
なかなかおしゃれ。

ふと気になりました

どうやって着陸地点を確認しているんでしょうか。HUDもない時代です。
調べてみました。
これは着陸船の窓の図です。

f:id:aerith7:20161220032727p:plain:w200

何か目盛りがあるのが見えると思います。 プログラムに与えられた数値をみて照準を合わせると月の一点に定まるんだとか。 LPD(Landing Point Designator)と書いてますがほぼ完全に目視なんですね。。。なんともアナログ。。。

いい時代ですね

p66、p67はp63 ~ p65のプロセスの任意のタイミングで飛行士が自由に使用できるようになっています。 このような形で人に任せたのは当時の技術だと月の表面をみてから動的に着陸を判断することができなかったからなんですね。 また、着陸地点の選定も周回軌道から撮影した写真が根拠でしかないので着陸時に初めて障害物を見つけるということも想定されていました。 アポロの着陸脚は重量制限のため非常に脆弱で、少しでもかたむく・乗り上げることは月から脱出できなくなることを意味していました。

実際アポロ11号では最終着陸フェーズにおいて、 着陸地点のクレーターをp66を使用して一度上昇回避しています。
下の高度記録の102:44あたりのがまさにそうですね。
f:id:aerith7:20161220032220p:plain:w300

1201&1202エラー

EXECUTIVE.agc : 205 146行目です。

これが1201&1202エラーか。。。。!!(一人大興奮)

なにそれ?

アポロ11号の着陸中に起きた2つのエラーのことです。 アポロ11号の実際の着陸プロセスが以下になります。

f:id:aerith7:20161220032130p:plain:w300

10秒に1回くらい警報が鳴り続けている中、無視して降下したことがわかると思います。
当時の通信(ログ付きなのでこれがわかりやすい気がします。)を聞くとアームストロングが1202について教えてくれって言っていますね。地上からは結局教えてくれないんですが。 1202と1201は調べてみるとシステムオーバーフローのエラーなようです。 システムオーバーフローするとAGCは再起動をかけるようになっています。 1分に1回再起動しながら月に着陸するの、恐ろしすぎますね。。

実はアラームがなった時点で着陸中止臨界点が3分後に迫ってきていました。 当時NASAの誰もこのエラーの理由をすぐには突き止められなかった中、 着陸中止かどうかを数十秒のうちに決断しなければなりませんでした。そんな時に NASAのチーフソフトウェアエンジニアはAGCにはタスクを優先順で処理する機能が備わっているため(1960年代にこんなことできている時点で凄いのですが)着陸自体に影響はないと考え、数秒のうちにgoサインを出しました。 それで着陸は無事に成功したわけです。

数秒のうちに判断を下した技術者、命がかかっている中冷静にNASAの判断に従っている飛行士、 どちらも本当に凄いですね(語彙力)

ちなみに調べたところ、理由はハードウェア由来だったようです。 ランデブー用レーダーのクロック周波数が微妙に本体のそれと微妙に同期しておらず、 それによるデータの過剰な入力によるものだったそうです。

カ、カルマンフィルターだー!!!

KALMAN_FILTER.agcなるファイルを発見。 世界最古のカルマンフィルターです。
カルマンフィルターを適用し、実装したのはスタンリー・シュミットというNASAの技術者で当時どのように航法システムを開発したのかが回顧録として公開されています。

カルマンフィルターの開発経緯

もしこれを解決するのに必要な努力量を我々が正確に理解していたら、多分考え直したと思う(笑)

とはシュミットの弁です。
航法・誘導をするためにもっとも重要な事は何でしょうか。それは
「自分の乗っている正確な軌道を観測データから計算する」
ことです。
地上からアポロ宇宙船を観測して位置を特定するだけでは大気の影響を受け非常に大きな誤差が出てしまいます。 また軌道変更を正確に行うにはリアルタイムで位置を把握しながら10㍉秒単位でエンジンの点火と停止を行わなければなりません。
以上の理由からどうしても宇宙船自身で位置を読み取り、軌道を計算する必要がありました。

IMU(Inertial Measurement Unit)というセンサーがアポロにはついており、ここから加速度やジャイロセンサーの値が入ってきます。IMU自体に蓄積される誤差は定期的に宇宙飛行士が望遠鏡を月と太陽に向けて補正していたようです。 ところどころアナログになるのが本当に1960年代という感じがします。

それでこの観測データをどう評価するのかということになります。
当時のNASAのコンピューターは非常に貧弱で、この値を積分し続けて近似曲線を引くには数時間かかります。 数時間かかるどころかパンクの恐れすらあります。 (追記 : 当時NASAに軌道計算できるコンピューターはこの1台しかありませんでした!つまりミッション中に万が一こいつがパンクすると。。。 あとはおわかりですね。) とても組み込みで実現できるようなものではありませんでした。 (最小二乗法などはことごとく不可能だったわけです。)

ここでNASAは統計的にフィルタリングすることによって誤差を取り除こうとします。 実際にウィーナーフィルターを使用した研究が走っており、レーザー誘導ミサイルの制御で大きな成果を上げていました。 しかし、ウィーナーフィルターは定常性を仮定し過去のデータが全て分かっている場合に初めて有効になります。 確かにミサイルの軌道は着弾まで変わりませんが、宇宙船は道中で軌道を変更する必要があります。 またデータが途中で脱落する可能性もあります。
シュミットはこの手法では開発できないと考えていました。
そんな時にカルマンの「 A new Approach to linear Filtering and Prediction Problems 」なる論文を目にするわけです。 ウィナーフィルターの制約条件である定常性と無限時間観測の仮定を取り除いたカルマンフィルターをソフトウェアに組み込むために、シュミットはカルマンをJPLに呼びました。1959年の暮れの事です。

実はこの時カルマンは自分がなぜJPLに呼ばれたのか全く知らなかったという事です。
カルマンフィルターは線形モデルでしか成立しないのに対し、軌道計算は非線形であるのが課題でしたが、 2回目のミーティングでカルマンは現在の観測点周りで線形化する事により非線形モデルに適用するアイデアを思いつきます。 これが現在拡張カルマンフィルターと呼ばれているものです。
そうしてこうして精度が向上し無事にアポロ宇宙船に乗ったのでした。。。
もっと詳しく知りたい方は資料にリンク貼ったので見てみてください。

その他面白コメントアウト

TRASHY LITTLE SUBROUTINES(つまんないサブルーチン)

LUNAR_LANDING_GUIDANCE_EQUATIONS .agc : 175行目

NUMERO MYSTERIOSO(神秘の数字)

LUNAR_LANDING_GUIDANCE_EQUATIONS.agc : 666行目 なんだこの変数名・・

OFF TO SEE THE WIZARD

LUNAR_LANDING.agc :
オズの魔法使いの「We're Off to See the Wizard」じゃないかなと思っているのですがどうでしょうか。

なんかここら辺に当時の機械と人間の微妙な関係が見えますね・・・笑

COME AGAIN SOON

BURN_BABY_BURN—MASTER_IGNITION_ROUTINE.agc : 925行目

HONI SOIT QUI MAL Y PENSE(悪意を抱く者に災いあれ)、NOLI ME TANGERE(私に触れるな)

BURN_BABY_BURN—MASTER_IGNITION_ROUTINE.agc :

これ書いた人は調べてみると当時23歳だったそうです。 これ僕と同い年の人がやってたんかと思うと震えますね。。 チームの中でも若かったですしちょっと意味深なコメントとかも入れてたのでしょうか。 ちなみにBURN_BABY_BURNなる単語、調べてみると60年代に流行ったDJの決め台詞なんだとか。

PINBALL_GAME_BUTTONS_AND_LIGHTS.agc

ファイル名が完全にふざけていますね。。。 月に着陸することをピンボールゲームといったとか。 プログラム自体はUIルーチンを担当しているようです。

追記 : シェークスピアの引用箇所を見つけました。

おわりに

伝えたかったのは以下の3つ。

  • これ完全に空飛ぶ棺桶じゃん・・
  • ユーモアって大事
  • 60年代の人間とコンピューターの絶妙な関係

eeicにおいて宇宙電気電子の分野に進む人はごく少数ですが、 少しでも宇宙に興味を持ってくれる人がいたらそれはとっても嬉しいなって。

反省

宇宙が好きすぎて大量に資料を摂取するあまり、 完全にストーリーも何もなくただふらふらと興味の赴くままに書くだけのアレになってしまいました。 来年度書く機会があったらちゃんと技術系の話をしよう。。

参考文献