はじめに
SpaceX をはじめ、いまや再利用ロケットの着陸はすっかり見慣れた光景になりました。第一段ブースターを逆噴射で減速し、脚を展開してパッドへピタリと降ろす——あの一連の動きは、何度見ても惚れ惚れします。
とはいえ「実際に自分で操縦してみたら、どれくらい難しいんだろう?」というのが前々から気になっていました。そこで今回は、ブラウザだけで遊べるロケット着陸ゲームを作ってみたので紹介します。インストール不要、リンクを開けばその場で遊べます。
ついでに、ボタンひとつで自動着陸してくれる 自律着陸モード(Auto Land) も載せてみました。手動で何度も墜落したあとにこれを試すと、誘導制御のありがたみが分かります。
作ったもの
こちらから今すぐ遊べます👇(PC・スマホ対応)
第一段ブースターを操作して、風に流されながらも姿勢を保ち、燃料の続くうちにパッドへソフトランディングさせるゲームです。難易度は EASY / NORMAL / HARD の3段階。HARD は風も強く燃料もシビアで、なかなか手強いです。
遊び方
操作はシンプルです。
| キー | 動作 |
|---|---|
| ↑ ↓ ← → / A D | 姿勢(機体を傾けて移動・離すと復元) |
| W / S | スロットル増減 |
| Space | 全開 |
| X | エンジン停止 |
| G | Auto Land(自律着陸) の ON/OFF |
| C | 視点切替(チェイス / サイド) |
| R | やり直し |
接地したときに「降下速度・横速度・機体の傾き・パッド中心からの距離」がすべて許容値以内なら着陸成功です。脚が無事に展開して接地している必要があります。最初はだいたい盛大に倒れます。
中身の話
物理モデル
操作性を優先して簡略化していますが、エッセンスは次の通りです。記号は位置 $\mathbf{r}=(x,y,z)$、速度 $\mathbf{v}$、スロットル $u\in[0,1]$、機体の傾き $(\theta_x,\theta_z)$ とします。なお、慣性系は y 軸を鉛直上向きとする右手系です(※一般の航空宇宙系の NED 等とは上下の向きが異なります)。
並進は、機体上向き単位ベクトル $\hat{\mathbf b}$ の方向に推力をかけ、そこへ重力 $g$ と空気抗力 $\mathbf a_{\text{drag}}$ を足します。
$$
\dot{\mathbf r}=\mathbf v,
\dot{\mathbf v}= u a_{\max}^{\text{eff}} \hat{\mathbf b}(\theta_x,\theta_z) - g \hat{\mathbf y} + \mathbf a_{\text{drag}}
$$
上式において、$\hat{\mathbf y}=[0,1,0]^\top$です。
推力は可変質量で扱っていて、推力加速度の大きさ $a_{\max}^{\text{eff}}$ は機体質量 $m$ で決まります。燃料を使うほど軽くなり、同じスロットルでも加速度が増えます($a=F/m$)。
$$
a_{\max}^{\text{eff}}=\frac{F_{\max}}{m},
m=m_{\text{dry}}+m_{\text{fuel}}
$$
燃料消費がスロットル(=推力)に比例するので、質量流量 $\propto$ 推力というロケットの基本も満たします。終盤に軽くなってホバリングに必要なスロットルが下がる、というに感じになります。
ここで $\hat{\mathbf b}(\theta_x,\theta_z)$は座標変換に関するベクトルであり、基底$\hat{\mathbf y}$について$x$ 軸まわり→$z$ 軸まわりの順に回転させたものです。
$$
\hat{\mathbf b}(\theta_x,\theta_z) = R_z(\theta_z) R_x(\theta_x) \hat{\mathbf y}
= \big(-\cos\theta_x\sin\theta_z,\ \ \cos\theta_x\cos\theta_z,\ \ \sin\theta_x\big)^T
$$
横に進むには機体を傾けて推力ベクトルを倒す必要があり、その分だけ垂直成分 $\cos\theta_x\cos\theta_z$ が減ります。「進む」と「(高度を)支える」が常にトレードオフになっています。
姿勢は、指令した傾き $\theta_{\text{cmd}}$ に実際の傾き $\theta$ が追従する2次系としてモデル化しました(グリッドフィン/RCS による安定化を1つの内ループに抽象化)。
$$
\ddot\theta = \omega_n^2 (\theta_{\text{cmd}}-\theta) - 2\zeta\omega_n \dot\theta
$$
固有角周波数 $\omega_n$ と減衰比 $\zeta$ で「キビキビ感」が決まります。この2次系の遅れこそが「姿勢が一拍遅れてついてくる」感覚の正体で、手動操縦の難しさと面白さを生んでいます。
風(空気力) は、ゆっくり変動する平均風 $w_{\text{mean}}$ に突風 $w_{\text{gust}}$ を重ね、風向成分のベクトル $\hat{\mathbf d}$を掛けて風速ベクトル $\mathbf w$ を作ります。
$$
\mathbf w = \big(w_{\text{mean}} + w_{\text{gust}}\big) \hat{\mathbf d}
$$
そのうえで、機体速度と風速の差=対気速度 $\mathbf v_{\text{rel}}=\mathbf v-\mathbf w$ に対し、速度の二乗で逆向きにかかる抗力を与え、質量で割って加速度にします。
$$
\mathbf v_{\text{rel}}=\mathbf v-\mathbf w,
\mathbf a_{\text{drag}}=-\frac{k_d}{m} \lVert\mathbf v_{\text{rel}}\rVert \mathbf v_{\text{rel}}
\Big(k_d \approx \tfrac{1}{2}\rho C_d A\Big)
$$
これにより、(1) 止まっていると風下へ押され・動くと対気速度に応じて抵抗が効く、(2) 降下が速いほど縦にも抗力がかかり自然に減速する(空力ブレーキ・終端速度)、(3) 燃料が減って軽くなるほど風に流されやすくなる($a=F/m$ と整合)、という挙動になります。いまは空気密度一定・姿勢に依らない等方抗力としています。
自律着陸(Auto Land)の誘導制御則
G キーで ON にすると自動で降りてくれます。ロジックは重い最適化を回さず、垂直・水平を分けた古典的なフィードバック形式の誘導制御則で実装しています。
垂直方向は「高度に応じた目標降下速度」を作り、それに追従します。一定減速 $a_d$ で接地速度に収める発想で、高いほど速く・近づくほど絞る形です($h$ は接地までの高度、$v_{td}$ は目標接地速度)。
$$
v_{\text{ref}}(h) = -\Big(\sqrt{2a_d\max(h-h_f, 0)} \ +\ v_{td}\Big)
$$
$$
a_z = a_{\text{ff}} \ +\ K_v\big(v_{\text{ref}} - v_z\big)
$$
$a_{\text{ff}}$ は Feed-Forward(フィードフォワード)項で、誤差を待たずに「降下中はそもそもこれくらいの減速が要る」とあらかじめ加えておく予見的な減速指令(バイアス)です。フィードバック項 $K_v(v_{\text{ref}}-v_z)$ は、その残差を詰める役割を担います。
水平方向は、パッド中心(原点)へ寄せる PD 制御に、既知の風を打ち消すフィードフォワードを足します。PD制御の中身は位置ズレ $\mathbf r_h$ を詰める比例項と、行き過ぎを抑える速度$\mathbf v_h$の微分項です。
$$
\mathbf a_h = -K_p \mathbf r_h - K_d \mathbf v_h - \mathbf a_{\text{wind}}^{\text{ff}}
$$
ここで $\mathbf a_{\text{wind}}^{\text{ff}}$ は、上の抗力モデルから見積もった「静止時に風から受ける加速度」 $\dfrac{k_d}{m}\lVert\mathbf w\rVert \mathbf w$ を打ち消すフィードフォワードです。
最後に、求めた正味加速度を推力加速度ベクトルにまとめ(重力を足し戻す)、その大きさからスロットル、向きから姿勢指令へ逆算します。
$$
\mathbf T = \big(a_{hx},\ \ a_z+g,\ \ a_{hz}\big),
u=\frac{\lVert\mathbf T\rVert}{a_{\max}^{\text{eff}}},
\theta_x=\arcsin \hat T_z,
\theta_z=\arcsin\frac{- \hat T_x}{\cos\theta_x}
$$
ただし $\hat{\mathbf T}=\mathbf T/\lVert\mathbf T\rVert$ は推力方向の単位ベクトル、$a_{\max}^{\text{eff}}=F_{\max}/m$ は現在質量での全開推力加速度です。
以上から誘導制御則は「横に動きたいぶんだけ傾け、同時にスロットルも上げて推力ベクトルを作る」という、tilt とスロットルを協調させた操作を、可変質量を考慮しながら自動でやっています。最適化計算などの派手なことはしていませんが、姿勢遅れ・風・質量変化があっても安定して降りてくれます(逆に手動だと、この協調を自分でやる必要があるので難しい、というわけです)。
終わりに
今回はブラウザで遊べるロケット着陸ゲームを作ってみました。手動で操作してみると、あの「ふわっと降りて脚で止まる」動きが、いかに繊細なバランスの上に成り立っているかが体感できて、改めて実機のすごさを感じます。
再利用ロケット開発は日本国内でも機運が高まっていて、大企業からスタートアップまで挑戦が続いています。こういうゲームやシミュレーションで遊びながら、その難しさと面白さを多くの人と共有できたら嬉しいです。
よかったら実際に着陸にチャレンジしてみてください。そして盛大に墜落してください🚀

