世界を動かす技術を、日本語で。

Fortran F-16シミュレーターをUnity3Dに移植する

概要

  • 「Aircraft Control and Simulation」では、航空機制御とシミュレーションの基礎を解説
  • F-16の飛行モデル用Fortranコードが付録に掲載、GitHubでも公開
  • 航空宇宙分野の座標系や単位系、専門用語の違いを詳述
  • 空気データ計算や力・モーメントの扱い、PID制御など実装例を提示
  • ゲーム開発と実機設計のアプローチの違いを比較、各モデルの限界も解説

「Aircraft Control and Simulation」のF-16飛行モデル解説

  • 「Aircraft Control and Simulation」 は、航空機の制御理論とシミュレーション技術を扱う専門書
  • 付録 にはF-16戦闘機のシミュレーション用 Fortranソースコード を収録
  • この飛行モデルは、 風洞実験データ に基づく多数の ルックアップテーブル と数式で構成
  • ソースコードは GitHub で公開され、 itch.io で体験可能、 YouTube でデモ視聴も可能
  • 本書の内容は密度が高く、 航空力学の教科書 としては標準的な難解さ

ゲーム開発と実機設計の違い

  • ゲーム開発では、 高次パラメータ (旋回率・G制限など)を直接調整可能
  • 実機設計は、 翼型の形状・配置 など低次パラメータから設計を積み上げる
  • すべての設計判断には トレードオフ が伴い、目標達成には他の性能を妥協する必要
  • CFD(数値流体力学)による完全なシミュレーションは 実装・検証が非常に困難
  • F-16モデルは 高次・低次の中間 的なアプローチ、ゲーム用モデルとの比較材料

航空宇宙分野の座標系と単位系

  • 航空宇宙分野では、 右手系・X前方・Y右・Z下 の座標系を標準採用
  • ゲームエンジン(Unity等)との 座標変換関数 を実装し、互換性を確保
  • 角度やトルクの変換時には 符号反転 も必要
  • アメリカ航空宇宙業界 は独自の US慣用単位系 を使用
    • 距離: フィート
    • 質量: スラグ
    • 速度: フィート/秒 または ノット (海里/時)
    • 温度: ランキン度
  • 単位変換関数 を用意し、実装時の混乱を回避

専門用語の整理

  • α(アルファ) :迎角(Angle of Attack)
  • β(ベータ) :横滑り角(Side Slip Angle)
  • X軸 :機体前後方向(Longitudinal axis)
  • Y軸 :機体左右方向(Lateral axis)
  • Z軸 :機体上下方向(Normal axis、下向き)
  • φ(ファイ) :ロール角(X軸回り)
  • θ(シータ) :ピッチ角(Y軸回り)
  • ψ(プサイ) :ヨー角(Z軸回り)
  • P, Q, R :各軸回りの角速度

空気データ計算方法

  • 飛行機は 空気の流れ を正確に測定することが不可欠

  • 静圧 :機体周囲の大気圧力、 高度 で変化

  • 動圧 :ピトー管で計測、機体前進による圧力増加

  • 動圧・静圧 から 指示対気速度(Indicated Airspeed) を算出

  • 指示対気速度は 失速速度 などの基準値として重要

  • シミュレーションでは、 実速度・高度 から動圧を逆算

  • FortranコードC#クラス(AirDataComputer) へ翻訳

  • US慣用単位 (スラグ/ft³、フィート、ランキン度)をそのまま利用

    • 例:海面気密度2.377e-3スラグ/ft³、温度519.0R、温度勾配0.703e-5R/ft
  • 計算手順

    • 高度に応じて温度・気密度を計算
    • マッハ数計算:速度/音速
    • 動圧計算:0.5×密度×速度²

まとめ

  • 本書のF-16飛行モデルは、 実用的な航空機シミュレーション の入門として最適
  • 座標系や単位の違い物理量の定義 に注意して実装を進める必要
  • ゲーム開発と実機設計の 設計思想の違い を理解し、用途に応じたモデル選択が重要
  • Fortranコード の現代言語(C#等)への移植も、単位変換や変数名整理で可読性向上
  • 航空機シミュレーション開発の 実践的な知識 を体系的に習得可能

Hackerたちの意見

海里は約6,076フィート、正確には1,852メートルだよ(???)。これは地球上の距離で定義されてるんだけど(もちろん近似だけどね)。だから、1海里は90度の半球の弧の1分に相当するんだ。赤道から極まで約10,000kmだから、10,000kmを90で割ってさらに60で割ると1.852kmになるんだ。

1海里は90度の半球の弧の1分に相当する 海里はSI単位じゃないから、単一の組織によって定義されてるわけじゃないよ。君の定義は昔の一般的な定義だったけど、関連する組織が定義を正確に1,852メートルに更新したみたい。もしメートルの元の定義が適用されるなら、1851.85メートル、つまり15センチ短くなってたはずだけど、新しい地球の測定によると、もっと1855メートルに近かったかもね。

Fortranは任意の開始インデックスを持つ配列をサポートしてるから、この場合は-2だね。だからこのテーブルは[-2, 9]の範囲のインデックスをサポートしてる。めっちゃ便利な機能だよ!もっと見かけると思ってたのに。オフセットを0(Luaだと1)に合わせるためだけの面倒なコードがたくさんあるからね!

パスカル(間違ってなければモジュラも)もこれをサポートしてるよ。

1ベースのインデックスの問題には同意するけど、0ベースはすごく自然だと思う。もし-2ベースが必要なら、配列は要らないんじゃないかな。

なんでそれが必要なのかよくわからないな。今、配列から3番目の要素を取得するには、開始インデックスを知っておかないといけないから、関数に渡すパラメータがもう一つ増えるよね。

.NETはこれをサポートしてるのは、[Visual] Basicがサポートしてるからだよ。C#や他の言語からも使えるけど、いい構文がないんだ。// これも多次元配列をサポートしてるから、パラメータが配列になってる。var array = Array.CreateInstance(elementType: typeof(Int32), lengths: [ 5 ], lowerBounds: [ -2 ]); // これはコンパイルエラーになる、型はInt32[*]であってInt32[]じゃない。// Console.WriteLine(array[0]); array.SetValue(value: 42, index: -2); Console.WriteLine(array.GetValue(-2));

Luaは実際には任意のインデックスを持ってるんだけど、標準ライブラリのいくつかのイテレータ関数は配列が1から始まることを前提にしてるんだよね。

残念ながら、Fortranの実装にはいくつかの不一致があるんだ。特定の操作を行うと、カスタムインデックスから1ベースのインデックスに戻っちゃうことがあるよ。 https://github.com/sourceryinstitute/fidbits/blob/master/src... https://fortran-lang.discourse.group/t/just-say-no-to-non-de...

この機能はFortran '77では問題なく動いて、ポータブルだったけど、現代の機能との相互作用には驚くべき落とし穴がいっぱいあるんだよね。コンパイラが正しく実装しても、実際にそれをやってるのは2つだけだから、あんまりポータブルじゃない。

"実は、Fortranは数式の翻訳が結構得意なんだ。" 言語名がFORmula TRANslatorから来てるって知ってるといいな…。

Thats_the_joke.jpg

これはあまりにも良いダジャレだから、わざとだと思う。

.......それがジョークなんだ。

ナメクジを見たら、エアロエンジニアリングの頃のPTSDが蘇ったわ。質量と力の単位を区別するために、mとfの下付き文字を使って、1セットの方程式でポンドを追跡するのって、想像しただけで大変だよね。

子供の頃、コンピュータはどんどん速くなっていって、すごく「洗練された」ビデオゲームがあったのを覚えてる。そのゲームは、ある部分をプレイするために数学(FP)コプロセッサ(80387)が必要だったんだ。 > 「プログラムには、最低12MHzの80286、1MBのRAM、DOS 5.0またはDR DOS、1.2MBの5 1⁄4インチまたは1.44MBの3 1⁄2インチのディスクドライブ、11MBの空き容量があるハードドライブ、VGAグラフィックスが必要です。また、Falcon3.Oはジョイスティック、スロット付きジョイスティック、デュアルジョイスティック、ラダーペダル、またはThrustMasterコントロールをサポートしています。このゲームはマウスやAd Lib、Sound Blaster、Rolandなどのさまざまなサウンドカードもサポートしています。80x87数学コプロセッサは、高忠実度のフライトモデルに対応しています。> 最適なシステム要件は、20MHzの80386システムまたはそれ以上、80x87数学コプロセッサ、EMS(拡張メモリ)付きの4MB RAM、DOS 5.0またはDR DOS、1.2MBの51⁄411または1.44MBの31⁄2インチのディスクドライブ、11MBの空きスペースがあるハードドライブ、16ビットVGAカード、マウス、ジョイスティックです。* https://vtda.org/docs/computing/SpectrumHolobyte/Falcon_3.0_... * https://en.wikipedia.org/wiki/Falcon_3.0 「すごい!」って当時思ったよ。

Falconのゲームは今でも多くのファンがいるよ。

Amiga 500でオリジナルのFalconをプレイしてた思い出がある。Apple IIcでF15 Strike Eagleを何年もやってた後は、まるで魔法みたいだった。後燃焼の音が聞こえて、地面に近づきすぎると「引き上げろ!引き上げろ!」っていうのもすごく満足感があった。Falcon 3.0が出た時はすごく興奮したけど、期待外れに感じた。グラフィックは当時としては素晴らしかったし、リアルに見えたけど、リアリズムが逆に楽しさを奪っちゃった。子供の頃、実際にF16のパイロットになりたかったわけじゃなくて、そう感じたかっただけなんだ。システムやコントロールを全部学ぶ必要なんてなかったのに。

そうそう、ハイフィデリティフライトモデルにはその数学コプロセッサが必要だったよね。これをオンにすると、まるで『ウォーゲーム』のWOPRにアクセスしたみたいに感じた!

Falcon 4.0のソースコード漏洩がFalcon BMSにつながって、今でもアクティブに開発されてるよ。

その地図は楽しかったな。確かに、クウェートの空域の飛行マップを持ってて、後部座席に対空防御のマークがあった時は、国境を越えるのがもっと楽だったかもしれないけど、それでも_価値はあったよ :)

逆のことも覚えてるよ。ルームメイトの8086 PCクローンでロボトロンをよく遊んでたんだけど、彼が'286にアップグレードするのにすごく興奮してたんだ。そしたらロボトロンがプレイできなくなっちゃった。多分、すごく速かったから人間が反応する時間がなかったんじゃないかな。新しいバージョンが出たかもしれないけど、よくわからないな。

母は1950年代後半から1990年代中頃まで、防衛請負業者のFORTRANプログラマーだったんだ。F16シミュレーターみたいなことをしてたよ。最後に彼女が話してたのはB1かB2爆撃機のことだったかな。70年代後半の小学生の頃、学校の休みの日に仕事の休みじゃない時に、時々彼女のオフィスに行ってた。彼女はオフィスの端末でColossal Cave Adventureをプレイさせてくれたんだ。彼女が作業してたコードのプリントアウトを見たり、未来的な飛行機のワイヤーフレーム図を見たりしたのを覚えてる。それは初期のステルス戦闘機の一つだったと思う。私がそこにいたことで、どれだけのセキュリティプロトコルを破ったんだろう… :) 彼女は何年も前に亡くなったけど、こんな仕事を見たらきっと興奮してたと思う。

参考までに、彼女はセキュリティプロトコルを破ってたわけじゃないと思う。要するに、子供たちがちゃんと読めなければ、赤いランプなしで護衛されるのは問題ないってこと。必要な時には、2歳の娘をSCIFに連れて行ったりしてたし、ペンタゴンで息子を連れて行った週もあった。あの時はスネーク・クラークの下で働いてて、みんなが彼にお菓子を持ってきてくれたんだ。彼は大半の時間、副官のオフィスでニックのアニメを見てたと思う。今ではその話を聞くと彼も楽しんでるよ。

いい話だね、シェアしてくれてありがとう!お母さん、最高だね :)

すごく面白い読書だったけど、ちょっと気になる点がある。アメリカの単位からユニティやメトリック、その他の常識的な単位に変換する関数を書くんじゃなくて、数式の中で全部メトリックに変換しちゃえばよかったのに。数学を見直すのはそんなに難しくないし、関数呼び出しも減るし、パフォーマンスも向上するし、数学もずっとシンプルになるよ。空気の密度も柔軟に、コントロール可能になるし、推力速度も弾道の仕様速度(m/s)に合わせられるから、交差点の計算も楽になるよ。信じて、FORTRANの数学を標準メトリックに変換した方がいいよ。当時はベース10を信じてなかったから、ちゃんと計算してみて。

これはすごいブログ記事だ!ジェリー・マグワイアの言葉を借りるなら、「あなたは私をハローでつかまえた。」この最初の文が本当に引き込まれた:> 私はプロのソフトウェアエンジニアで、航空宇宙産業で働いているけど、それが私が何をしているか理解していることを意味するわけじゃない。お気に入りの部分は、異なる3Dモデリング製品のX/Y/Z軸を比較した画像だね: https://vazgriz.com/wp-content/uploads/2025/05/EmVSW5AW8AAoD... さらに、下のコメントは笑いすぎてコカ・コーラが鼻に入るくらい面白いよ!> 数学的に言えば、これらはすべて同じくらい有効だ。でも、みんな知ってるよね、Unrealが最悪の選択をしたって。

この人が「空気速度をノットで測る」って概念の横に皮肉な(???)をつけてるのを見ると、彼らが航空宇宙についてどれだけ知ってるのか気になるよね。ノットは標準的な測定単位で、1海里が緯度の1分に等しいからなんだ。これは、緯度/経度をラジアンで測ることに決める日までは便利だよね。非メートル法を批判するのが流行ってるところもあるけど、こういうのは理由があってそうなってるわけで、空気速度は一般的にノットかマッハで測られるんだ。

空気速度は一般的にノットかマッハで測られる。船の速度もノットで測るけど、マッハで測ることは非常に稀だよ(しかも水中の音速が空気中よりかなり高いから、主にそういう理由でもないし)。

興味深い情報: https://github.com/ericstoneking/42 これは本格的な宇宙船シミュレーターだよ。古いFORTRANコードから開発されて、今回はCに移植されたんだ。