飛行シミュレーションアルゴリズムのお勉強

目次 (2023/1/31 ver.0.02)

1番目のタブが選択された!

1.flutter_cubeライブラリ

目次

1.1 クラスの種類

Cube
3Dモデルを構成するための部品として「Cube(立方体モデル)」「Sphere(球体モデル)」「Cylinder(円柱モデル)」などが必要です。
「Cube(立方体モデル)」は、立体系モデルです。
Scene
Sceneクラスには、ゲームの環境とメニューが含まれています。
各シーンファイルを一意のレベルと考えてください。各シーンに、本質的にゲームをデザインし構築する環境、障害物、装飾を配置します。

1.2 Blender2.8の操作(その1)

日本語化
「編集」→「プリファレンス」→「インタフェース」の「翻訳」で「日本語」を選択する。
テンキーの模倣
「編集」→「プリファレンス」→「入力」の「キーボード」で「テンキーを模倣」を選択する。
  • 「1」を押す:正面、「1」+「Ctl」を押す:真後ろ
  • 「2」を押す:15°下、「8」を押す:15°上
  • 「3」を押す:右側面、「3」+「Ctl」を押す:左側面
  • 「4」を押す:15°左、「6」:15°右
  • 「5」を押す:投影方法の切り替え
  • 「7」を押す:真上、「7」+「Ctl」を押す:真下

1.3 Blender2.8の操作(その2)

視点移動
視点移動の方法は3つです。これは2.7と一緒です。
  • ホイールを押しながらマウスを動かす:選択しているオブジェクトを中心に視点が回ります。
  • ホイールをグリグリ:ズームイン・アウト
  • Shiftキーとマウスホイールを押しながらマウスを動かす:平行移動
オブジェクトの選択
オブジェクトの選択は、2.7から変わった部分です。
  • blender2.8でのオブジェクトの選択は左クリックです。2.7からの人は誤操作しまくるやつですね。
  • オブジェクトを選択すると、選択したオブジェクトのアウトラインがオレンジになります。
オブジェクトの移動
オブジェクトを選択し、左側にあるメニューの移動マークを押すと矢印が3つ出てきます。
矢印はそれぞれ、赤→X軸 緑→Y軸 青→Z軸となります。それぞれの座標系の矢印をつかんで動かすと、オブジェクトを移動させることができます。
また、Gキーを押すことでも移動できます。GrabのGと覚えましょう。X軸だけ移動させたい場合はGキーを押した後にX、同様にY軸だけの場合はG→Y、Z軸だけの場合はG→Zで移動できます。左クリックを押すと移動が止まります。
オブジェクトの回転
オブジェクトの回転は、Moveツールの下のアイコンです。
ショートカットはRキーです。RotateのRと覚えましょう。この流れでピンときたかと思います。
X軸を中心に回転したい場合はRキーの後にXキー、Y軸中心の場合はR→Y、Z軸中心の場合はR→Zで回転させましょう。
左クリックを押すと回転が止まります。
オブジェクトの拡大・縮小
オブジェクトの拡大・縮小は、回転の下のアイコンが拡大縮小のアイコンです。
ショートカットはSキーです。ScaleのSと覚えましょう。
X軸だけ拡大縮小したい場合は、Sキーの後にXキーを押します。
同様に、Y軸だけの場合はS→Y、Z軸の場合はS→Zです。
左クリックを押すと拡大が止まります。
ウィンドウの説明
Blender2.8からは、上部のタブから作業ウィンドウを切り替えることができます。
それぞれのウィンドウの見た目は違いますが、今はLayoutのウィンドウのままで大丈夫です。
オブジェクトの表示
オブジェクトの表示モードは右上のまるが四つ並んでいるところです。
左から、WireFrame表示、ソリッド表示、LookDev(?)表示、レンダリング表示です。モデリング中に必要な時に切り替えましょう。
LookDev表示は、2.7で言う所のマテリアル表示と同じかな?ソリッド表示だとライトやマテリアルが反映されないのに対して、ライトやマテリアルが反映される表示です。

2.地球平面モデルの概要

目次

2.1 地球平面モデルとは

1.地球平面モデルでフライトシュミレータを作る
地球平面モデルでは,
  • 本来は曲面である地球表面を平面と近似
  • 地球の公転及び自転を無視(公転及び自転による地表面の運動を等速直線運動と近似)
⇒ 地表面に固定された平面座標系(例えば𝑥𝑥軸を経線,𝑦𝑦軸を緯線に対応)は慣性座標系
運動計算はシンプルであり,近距離かつ短時間の飛行を対象とした飛行シミュレーションには有効.
図2-1に,地球平面モデルのイメージを示す.(曲面を平面に貼り付けたイメージ)

図2-1 地球平面モデルのイメージ

2.2 座標系

1.地表面固定座標系
原点:地表面上の任意の点,$x-y$平面:地表面内,$z$軸:地表面に鉛直下向き
  • 地球の公転・自転を無視⇒地表面は慣性空間に対して固定⇒地表面固定座標系は慣性座標系
  • 機体の位置の基準
【例1】 地表面局所水平座標系 $[x_{HG}, y_{HG}, z_{HG}]$(図 2-1)
原点:任意の地表基準点,$x_{HG}$軸:北向き($N$) ($y_{HG}$軸:東向き($E$),$z_{HG}$軸:鉛直下向き(D) )

【例2】 滑走路NED 座標系 $[x_{HR}, y_{HR}, z_{HR}]$ (地表面局所水平座標系の 1 種) (図2-2)
原点:滑走路基準点,$x_{HR}$ 軸:北向き($N$) ($y_{HG}$軸:東向き($E$),$z_{HG}$軸:鉛直下向き($D$) )

【例3】 滑走路軸 (Runway Axes)$[x_R, y_R, z_R]$ (図2-2)
原点:滑走路基準点,$x_R$軸:滑走路方位向き

図2-2: 滑走路NED座標系と滑走路軸

2.機体固定座標系
原点:機体重心,$x-z$平面:機体対称面,$x$軸:前方向き, $y$軸:右翼方向
  • 機体とともに加速並進・回転 ⇒ 非慣性座標系
  • 機体の速度,角速度ベクトルの成分表示に使用

図2-3: 機体固定座標系

【例1】 機体軸 (Body Axes)$[x_B, y_B, z_B]$(図2-3)
$x$軸:機体製造時の基準前後軸方向

【例2】 安定軸 (Stability Axes)
$x$軸:釣合い飛行(対称飛行)時の速度ベクトル方向 (釣合い飛行から外れた後も,軸は機体固定)
3.局所水平座標系(NED座標系)
原点:機体重心,$x$軸:北向き($N$),$y$軸:東向き(E) ($z$軸:鉛直下向き($D$))(図2-4)
  • 機体とともに加速並進 ⇒ 非慣性座標系, 回転はせず,常に$N/E/D$方向
  • 機体の姿勢の基準

図2-4: 局所水平座標系

2.3 6自由度シミュレーションと3自由度シミュレーション

最初に3自由度シミュレーションを行う
6自由度シミュレーションでは,飛行制御を行う際に誘導系と制御系の両方の設計が必要である.
設計した誘導制御系の性能が不十分な場合,誘導系と制御系の両方の設計変更が必要なため,作業量は膨大となる.
そこで誘導系のみの設計・評価用として,誘導系からの姿勢コマンドは制御系により完全に達成されるものと仮定し, 制御系部と機体回転運動を解く運動計算部はスキップした3自由度シミュレーションプログラムを別途作成し, 誘導系のみの設計・評価に活用する.
この場合の運動計算は回転運動を含まないため,質点の運動方程式となる.
3自由度シミュレーションを用いて誘導系のみの設計が完了すれば,続いて制御系の設計を行い,6自由度シミュレーションにより誘導・制御系の総合評価を行う手順となる.
このように手順を2段階とすることにより,誘導制御系設計の効率化が実現する.
図2-5に6自由度シミュレーションと3自由度シミュレーションのイメージを示す.

図2-5: 6自由度シミュレーションと3自由度シミュレーションのイメージ

3.地球平面モデル3自由度シミュレーション

目次

3.1 クォータニオンを使って何をするか

そもそもクォータニオンを使って何がやりたいのでしょうか?大きく分けて以下の 2 つがあるように思います。
  • 3D 空間における「回転」を表す
  • 3D 物体の「姿勢」を表す
2 つと言ったのですが、メインは「回転」の方でしょう。
「姿勢」は単純に「どういう回転でその向きになったか」として捉えることができます。
注意点として、「姿勢」は「方向」よりも多くの情報を含んでいます。
クォータニオンを用いた回転を扱うときに、回転させたい対象が「姿勢」なのか「方向」なのかを混乱しないようにすることが肝要です。
方向は「進行方向」や「視線」といったものを表していますが、姿勢はそれに加えて、その方向周りの角度の情報も含みます。
航空機でいえば、機首の向いている方向だけでなく、機首に対して機体がどれだけ傾いているのかも指定してはじめて機体の姿勢が完全に決まります。
数理的には以下のようになっています。
自由度 備考
方向 2 進行方向は三次元ベクトル (3 個のパラメータ) で表せますが、そのベクトルの大きさは意味を持たないので 1 減らして 2 です
姿勢 3 方向 + 1 です
つまり、姿勢は最小 3 個のパラメータで表せるということです。
回転も姿勢と本質的に同じものなので、同様に 3 個のパラメータで表せます。
実際にオイラー角は 3 個のパラメータで姿勢や回転を表します (回転を表す方法はクォータニオンだけではなく、オイラー角による方法もメジャーな方法の 1 つです)。
オイラー角は Unity ではインスペクターの Rotation 項目で表示されているやつです。
(しかし transform.rotation は Quaternion 型なので少し紛らわしいですね...この記事でも注意喚起がなされています)

3.2 クォータニオンとは

クォータニオンは任意軸回転がキーワードとして言及される場面も多いです。
いかなる回転 (三次元空間内) も表現できることが強みです。具体的には以下のように定義します。
三次元空間において
  • 方向ベクトル $(\lambda_x, \lambda_y, \lambda_z)$ を回転軸として
  • 角度 $\theta$ だけ回転する
という「回転」を表すクォータニオンは、四次元ベクトル $(\lambda_x \sin⁡{\frac{\theta}{2}}, \lambda_y \sin⁡{\frac{\theta}{2}}, \lambda_z \sin⁡{\frac{\theta}{2}}, \cos{\frac{\theta}{2}})$ で表します。
これらは Unity では、Quaternion 型変数を qua として、
  • qua.x = $\lambda_x \sin⁡{\frac{\theta}{2}}$
  • qua.y = $\lambda_y \sin⁡{\frac{\theta}{2}}$
  • qua.z = $\lambda_z \sin⁡{\frac{\theta}{2}}$
  • qua.w = $\cos{\frac{\theta}{2}}$
という風に対応しています。
(が、Unity の Quaternion を扱うときにこれらの成分を直接触ることはあまりないかもです...スクリプトリファレンスにもクォータニオンに熟知していない限りは x, y, z, w の値を直接変更しないでくださいと書いてあります)
また Unity で上記の定義に則ってクォータニオンを生成するときは Quaternion.AngleAxis を用います (オイラー角など他の方法でクォータニオンを生成する方法は後述します)。


// Y 軸 (上方向) まわりに 30 度回転するのを表すクォータニオン
Quaternion.AngleAxis(30, Vector3.up)

ところで上の定義を見ると
  • なんでいきなり三角関数が...
  • $\frac{\theta}{2}$ ってなんだよ... $\theta$ でいじゃん...
と思ってしまいそうです。
その答えは「こう定義すれば具体的な回転計算が超楽だから」なのですが、本記事を読み進めて行くことで少しずつ実感していただけたらと思います。

3.3 クォータニオンによる回転操作

クォータニオンによる「回転」を定義したからには、実際に「三次元ベクトル」や「姿勢」を回転させる計算方法を導出してあげる必要があります。
三次元ベクトル $\vec{v}$ の回転計算は
  • キャラクターの視線をある方向へと徐々に向けて行く (3D ゲーム)
  • 宇宙機に搭載した望遠鏡を所望の方向へ向ける (航空宇宙)
といった場面で必要になります。
また、姿勢 $p$ の回転計算は、
  • クォータニオンとクォータニオンの補間 (3D ゲーム)
  • 航空機や宇宙機の三軸姿勢制御 (航空宇宙)
といった場面で必要になります。
結論としては、三次元ベクトル $\vec{v}$ や姿勢クォータニオン $p$ に対し、回転 $q$ を実施した結果は以下のように大変シンプルなものになります!!!!!!!
回転させるもの 回転結果 備考
$\vec{v}$ $q \otimes \vec{v} \otimes \bar{q}$ $\bar{q}$ は $q$ の逆回転
姿勢クォータニオン $p$ $q \otimes p$
逆に
回転操作をシンプルな計算で実現できるように、クォータニオンをあのように定義した
とも言えます。
なお、クォータニオン同士のかけ算 $q \otimes p$ や、クォータニオンとベクトルとのかけ算 $q \otimes \vec{v}$ はまだ定義していないですが、1-4 で導入します。
また、こうした事柄はクォータニオンを自分で実装する場合には必要な知見なのですが、Unity ではいずれも単に
Unityでの回転操作
v2 = q * v   // 三次元ベクトル v の回転
p2 = q * p   // 姿勢 p の回転
と「*」演算子で実現することができます。
$q \otimes \vec{v} \otimes \bar{q}$ な量を q * v と記述するのは少し紛らわしさがありますが、実用上とても簡便です。
演算子の順番は重要で、左右を入れ替えてはダメです。

3.4 なぜクォータニオンなのか

三次元空間上での回転や姿勢を表現する方法には代表的なものが 3 つあります。
  • クォータニオン
  • オイラー角
  • 回転行列 or DCM
パラメータ数 メモリ消費 計算上の扱いやすさ 備考
クォータニオン 4 バランス型で、その他様々なメリットがあります
オイラー角 3 × 具体的な姿勢をイメージしやすく、メモリ的にも優しいですが、計算上の難点を抱えています
回転行列 or DCM 9 ×
どの方法にもメリット・デメリットがあるので、状況に応じて使いこなせばいいのですが、総じてクォータニオンはバランスがとれた優秀な方法であることがわかります。

オイラー角はたった 3 個のパラメータで回転や姿勢を表現できるので、メモリ消費は少なくて済むのですが、三角関数を多用することもあって計算時間的には大きくなってしまいます。
それどころかもっと悪いことに、オイラー角の二番目の角度が ±90±90 度になる場合が特異点となって計算上の大きな問題を引き起こすことが知られています (詳しくはジンバルロックを参照)。
端的に言えば、ヨーとロールの区別ができなくなってしまう状態です。
しかしながら特に航空機の世界では
  • そもそもジンバルロックが起こるような状態にならない (ピッチが ±90±90 度になる状態...下図のような墜落時などに発生しそうな相当ヤバイ状態です...戦闘機などでは考慮が必要です)
  • ヨー、ピッチ、ロールという概念がとてもなじみ深い

といった理由によって盛んに用いられています。
また、3D ゲームの世界などにおいても、オイラー角の直感的なイメージしやすさから、UI や API 部分では用いられるケースも多いです。

3.5 クォータニオンのかけ算

4.地球平面モデル6自由度シミュレーション

4.1 縦運動の伝達関数

4.2 横・方向運動の伝達関数