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

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

2025年9月26日原文(vazgriz.com)

概要

  • 「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

Hacker Newsで議論の続きを見る