Inverse Kinematics(IK)について

はじめに

株式会社セガ 第3事業部 オンライン研究開発プログラム2部の松本と申します。

今回はInverse Kinematics(IK)に関する基本的な考え方や手法についての記事となります。

ゲーム制作の仕事に携わっているとIKの名前くらいは聞いたことがあるのではないかと思いますが、実際の中身については何をやってるのか良く分からない謎の技術だと感じている人も多いのではないでしょうか。この記事を読んでInverse Kinematicsについての理解を深めたり、あるいは改めて学び直すための良い機会になればと思います。

特にゲーム制作者ではない方にとっては、前提知識が不足していて分かり辛い所もあるかも知れませんが、本題であるIKそのものの概念や処理内容については、高校数学課程の知識 *1 があれば十分に理解できそうな内容になっているので、そうした視点で数学の復習がてら読んでみるのも良いかと思います。SNS等で度々話題になるベクトルや三角関数と言った高校数学で習う項目の有用性を感じてもらうだけでも構いません。

目次

IKの正体

まずはIKというのがどういう物なのかを説明したいのですが、いくつか前提となる知識も必要となるので、そちらから順番に説明します。

FKについて

人体のように複数の関節が連なって構成される骨格構造の姿勢を決定していく際に、構造の開始位置となるルート(=根っこ)関節から始めて、構造の終端側にある関節に向かって順番に平行移動や回転変換による姿勢計算を繰り返すことで、全身の姿勢を決定していく手法が考えられます。

この様な逐次的な手順で多関節連鎖構造の姿勢を解決する手法を、Forward Kinematics(フォワード・キネマティクス=順運動学)と呼びます。長いので今後はFK(エフ・ケー)と省略します。

FKによる平行移動と回転のイメージ図

FKの役割

ゲームに登場する3Dキャラクターの動きは、あらかじめ用意されているモーションデータを再生することで表現されていることがほとんどですが、この処理はFKによって計算されています。つまりFKはモーション再生処理に欠かせない基盤技術という位置付けです。

実際のFKモーションデータの大半は回転データの塊ですが、適切な全身のポーズや動きを作るために、どの関節にどのくらいの回転量を与えるのがいいのかというのは、FKでは決めることができません。計算で決めることができないのはもちろんのこと、人の手を使ったとしてもFK的な手続きによるデータ作成は、極めて非効率的な作業となります。ここで言うFK的手続きというのは、関節の回転角を1つずつ編集することで目的の全身ポーズや動作をつくることを指します。例えば関節が動くフィギュアやプラモで全身のポーズを付ける作業手順が、おおよそこれに該当するので、経験したことのある方は、あの作業で複雑で細かい動きを作るのがどれだけ大変か想像がつくのではないでしょうか?

まとめると、FKは既に決まっている回転データを順番に処理して姿勢を作り上げるという基礎的な役割を担いますが、その回転量そのものを決めることができないため、モーションデータを作成するだけでなく、ゲーム中にモーションの再生結果を加工して別の動きを作り出すのも難しい、ということになります。

ようやくIKの登場

そこで、制御し易い情報を与えることで、FK処理に必要な回転量を決めるための機能が求められます。

特定の部位の位置や姿勢を指定することで、そこに到達するまでの中間の関節の姿勢(=回転量)を全て計算で決める手法、すなわちInverse Kinematics(インバース・キネマティクス=逆運動学)と呼ばれる手法が、その役割を担います。こちらも今後はIK(アイ・ケー)と略します。

IKには様々な手法があり、その手法や適用範囲にも寄りますが、例えば手先の位置を決めたら、そこに連結されている前腕や上腕、場合によっては肩や背骨、そこに連結された反対側の腕の姿勢までも一度に決めるようなことも可能です。これはモーションデータを作る際にも非常に効率的なので、モーションデザイナーが扱うツールには必須の機能となっていますし、ゲーム中で再生されたモーションの結果をゲーム側の都合に合わせて修正・加工したりするのにも使われています。

IKは難しい?

計算でどのように回転量を決めるのかはパッとは思いつかないかも知れませんが、具体的なIKの手法そのものは、知ってしまえば超簡単な物から、理論背景を理解するだけでも難しい物まで様々です。今回紹介するのは基本的なアルゴリズムで、仕組みや理論は比較的簡単な部類に入るものですが、手法そのものの実用性や重要性は非常に高く、今でも多くのゲームで使われているので、学びのコストパフォーマンスはかなり良いはずです。

1ボーンIK

概要

多関節の連鎖で構成される骨格構造を1つ1つ分解すると、1つの関節とそれに対応する骨(ボーン)に相当する部位に分解できます。この単体骨に適用するIKが1ボーンIKです。1ボーンIKを組み合わせて多関節のNボーンIKとすることはできませんが、2ボーン以上のIK処理の多くが内部処理に利用している重要なIKです。

下の図は1ボーンIKの動作概要を示した図です。このような図は今後も出てくるので、その見方と合わせて動作概要を説明します。

1ボーンIKの概念図

図には、ちょっと太めの針のようなモデル表示が灰色と水色で2本分描かれています。これが制御対象の骨の初期配置(灰色)と、1ボーンIK適用後の配置(水色)を表しています。針の尖った方向がこの骨の進行方向になり、針の根本から先端までの長さはそのまま骨の長さを表します。水色の針モデルの延長線上にある白と青の四角いチェッカーマークがありますが、その中心がIKの目標位置を表しています。この図は1ボーンIKを適用したことで、骨の進行方向が目標位置の方向を向いているということを表したものです。

このように、1ボーンIKが達成する処理内容は、ある目標位置が1点与えられたら、骨の進行方向をその点の方向に向けるというものになります。IKは一般的には、与えられた目標位置に骨の先端位置が到達するような姿勢を解として導き出しますが、1ボーンの場合はそれを達成できるのが、目標位置が骨の長さと同じ距離にある場合だけなので、進行方向が合えばOKとしています。

骨の進行方向を目標位置に向けるというのは、単純に関節の位置から目標位置に向けたベクトルを計算して、骨の長さに合わせれば完了という訳にはいきません。骨の進行方向に関してはそれで解決するのですが、関節の姿勢がどのように変化したかは、それだけでは不十分だからです。

具体的な手法の説明に移る前に、少しだけ関節の姿勢について説明します。

前提知識1:X軸Y軸Z軸による姿勢表現について

各関節の姿勢は、それぞれのX軸、Y軸、Z軸の方向で与えることができます。CGなどの分野では、関節の進行方向をX軸に割り当てるのが主流となっているので、ここでもそれを前提に説明します。
先ほどのベクトル計算では、このX軸の方向を向けることはできていますが、Y軸、Z軸に関しては未解決です。X軸を回転させたのと同じ分だけY軸やZ軸も回転させることで、初めて関節の方向が変わったことになります。

3次元の場合はXYZ全ての軸の方向を決める必要がありますが、XY座標だけを取り扱う2次元の場合は、Z軸に相当する軸の方向は常に手前側に固定されていると考えることができるので、X軸とY軸の方向だけを解決すればOKです。

XYZ軸の回転イメージ(X→X'、Y→Y'、Z→Z')

手法

1ボーンIKにはいくつかの手法がありますが、ここでは三角比を使ってヨー回転量とピッチ回転量を計算する手法を紹介します。

前提知識2:ヨー回転・ピッチ回転について

その前に、ヨー回転、ピッチ回転について簡単に説明しておきます。

  • ヨー回転というのは進行方向に対して垂直上方向を回転軸とする回転です。
    進行方向基準で姿勢の左右方向を規定します。
  • ピッチ回転というのは進行方向に対して水平左方向を回転軸とする回転です。
    進行方向基準で姿勢の上下方向を規定します。

この他にロール回転というのもあって、これは進行方向軸を回転軸とし、進行方向基準で姿勢の捻じれ具合を規定しますが、ここでは一旦無視します。※あとでまた登場します。

ここでは、ヨー回転軸をZ軸、ピッチ回転軸をY軸にとり、ヨー回転角をθz、ピッチ回転角をθyとして説明します。*2

ヨー回転とピッチ回転

ヨー回転軸がZ軸なのでヨー回転ではX軸とY軸だけを回転し、ピッチ回転軸がY軸なのでピッチ回転ではX軸とZ軸だけを回転します。必然的にロール回転軸はX軸となり、ロール回転ではY軸とZ軸だけを回転します。

1ボーンIK手順
  1. IKの目標位置を関節のローカル座標に変換する
  2. ローカル座標から三角比を用いてcosθz, sinθz, cosθy, sinθyを計算する
    • \displaystyle{ \cos{θ_z} = x / \sqrt{x^2 + y^2} }
    • \displaystyle{ \sin{θ_z} = y / \sqrt{x^2 + y^2} }
    • \displaystyle{ \cos{θ_y} = \sqrt{x^2 + y^2} / \sqrt{x^2 + y^2 + z^2} }
    • \displaystyle{ \sin{θ_y} = z / \sqrt{x^2 + y^2 + z^2} }
  3. 関節の姿勢をcosθz, sinθzでヨー軸回転、cosθy, sinθyでピッチ軸回転する *3

ヨー回転(Z軸)+ピッチ回転(Y軸)時の三角比

赤いライン(X軸)に沿っている灰色表示の骨がIK適用前の初期配置です。
そこからIK目標位置(白青のチェッカーマーク中心)の方向に向けてヨー軸(Z軸)回転させた状態が中央の灰色表示の骨となり、更にそこから目標位置の方向にピッチ軸(Y軸)回転させた最終状態が水色表示の骨となります。

三角比の計算は、上の図を参考にしてください。
いきなり三角関数が出てきましたが、cos=底辺 / 斜辺、sin=高さ / 斜辺なので、手順2.のような式になります。
斜辺は三平方の定理 *4 で求めます。

この手法は3次元での1ボーンIKの一例ですが、ピッチ軸回転を無視することで、そのまま2次元でのIKにも使えるのが利点です。

その他の手法もざっくり紹介

1ボーンIKは他にも外積を用いる手法や、クォータニオンを用いる手法があるので、簡単に概要を紹介しておきます。

外積を用いる手法は回転を用いずにXYZ各軸を生成する手法ですが、今回説明したヨー回転+ピッチ回転による手法と実質的に同じ結果が得られます。

クォータニオンを用いる手法は、元の進行方向ベクトルと目標位置までの方向ベクトルから計算できる内積と外積の結果を利用してクォータニオンを生成し、このクォータニオンで姿勢を回転させる手法です。ヨー+ピッチ回転方式とは、進行方向となるX軸の方向は一致しますが、Y軸とZ軸の方向が異なる結果となります。

Up Vector Constraint

ヨー回転とピッチ回転の組み合わせで、目標位置の方向に関節の進行方向を向ける1ボーンIK手法を紹介しましたが、このままではロール回転については全く制御されていない状態です。*5

Up Vector Constraint(アップ・ベクター・コンストレイント=上方ベクトル拘束)は、関節のロール回転軸に対して垂直な任意の軸を上方ベクトルとして設定し、この上方ベクトルが拘束用の目標位置を向くようにロール回転軸の回転量を拘束する手法です。これはロール回転を制御する1ボーンIKだとも言えます。

Z軸に対するUp Vector Constraint(赤い矢印がロール回転、白赤チェッカーの中心が拘束用目標位置)

上方ベクトルはロール回転軸=X軸に垂直ならばどのような方向でも構いませんが、一般的にはY軸やZ軸、あるいはそれらの負方向を設定することが多いと思うので、ここではそれを前提に手順を紹介します。
以下の手順は、1ボーンIKを適用した後の追加処理となります。

Up Vector Constraintの手順
  1. 拘束用の目標位置 *6 を関節のローカル座標に変換する
  2. ローカル座標から三角比を用いてcosX, sinXを計算する
    • \displaystyle{ \cos{X} = y / \sqrt{y^2 + z^2} }
    • \displaystyle{ \sin{X} = z / \sqrt{y^2 + z^2} }
  3. Up Vectorとして選択する軸の種類によってcosX, sinXを変換する
    • Y軸:変更しない *7
    • Z軸:cosX = sinX, sinX = - cosX
    • 各軸の負方向合わせの場合は、上記手順で求めたcosX, sinX両方を符号反転する
  4. cosX, sinXで関節をロール回転する

1ボーンIK本体の方で三角比を用いたヨー回転+ピッチ回転の手法で説明したので、こちらも三角比で計算する手法を紹介しましたが、クォータニオンを用いて計算する方法もあります。

2ボーンIK

概要

2ボーンIKとは、連結された2本の骨の先端位置が与えられた目標位置に到達するように、2本それぞれの骨の姿勢を同時に決定するIK処理です。
人間の手足の構造に適用するのに非常に適しているため、Limb IK(リム=肢)と呼ばれることも多いです。

2ボーンIKはその基本アルゴリズムだけで、2本目の骨の関節の回転軸が1軸に限定されることや、その回転方向を1方向に限定できることがメリットです。 *8

手法

こちらもいくつかの手法が知られていますが、余弦定理を用いる手法が一般的です。骨が増えた分だけ少し複雑になるので理論背景を交えつつ順番に説明します。

理論背景を交えた手順説明

まずは前項で説明した1ボーンIKを用いて第1関節を目標位置の方向に向けます。*9

第1関節の方向を1ボーンIKを用いて目標位置の方向に向ける

目標位置に向けた第1関節の進行方向軸を基準として、第2関節の回転軸を法線とする平面を想定します。この図では手前側に法線が向いた状態となっています。
第1関節も第2関節もこの法線方向を回転軸とした1軸回転を行うため、ここからは2次元での問題として扱います。
この平面上で、第2関節の先端が目標位置に到達するように、2本の関節を回転させて以下のような三角形を形成した状態を想定します。

平面上に2本の骨が構成する三角形を想定した図

辺a、辺bの長さは、それぞれ1本目と2本目の骨の長さに相当します。これは事前に分かっている既知の値です。また、辺cの長さは1本目の関節の位置と目標位置との距離に相当しており、これは2点間の距離を計算することで求まります。このように三角形の3辺の長さが既知なので、余弦定理を用いてcosB, cosCを求めることができます。

  • \displaystyle{ \cos{B} = \bigl(c^2 + a^2 - b^2\bigr) / 2ca }
  • \displaystyle{ \cos{C} = \bigl(a^2 + b^2 - c^2\bigr) / 2ab }

cosが決まれば \displaystyle{ \cos^2{θ} + \sin^2{θ} = 1 } の関係からsinも計算できます。

  • \displaystyle{ \sin{B} = ±\sqrt{1 - \cos^2{B}} }
  • \displaystyle{ \sin{C} = ±\sqrt{1 - \cos^2{C}} }

sinの符号は回転方向の符号と一致するため、ここでの決定は一旦保留して、回転方向がどうなっているのかを確認する必要があります。各関節の回転方向を表した図を以下に示してみました。

各関節の回転方向を示した図

回転方向について考える前に、第2関節の回転角が余弦定理で求めた三角形abcの内角Cではなく、実際には外角のπ-Cとなっている点について考慮しなければなりません。
といっても、ここは以下の公式にしたがってcosCの符号を反転するだけで構いません。sinCの値はそのままです。

  • \displaystyle{ \cos{(π-C)} = -\cos{C} }
  • \displaystyle{ \sin{(π-C)} = \sin{C} }

改めて回転方向について話を戻します。
回転方向が反時計回りの場合は正方向の回転で、時計回りの場合は負方向の回転となります。この図によると、第1関節の回転Bは負方向への回転で、第2関節の回転π-Cは正方向の回転ということになります。
回転方向の正負はsinθの正負だけで表現できるので、cosの符号は変化しません。
回転方向を考慮した最終的なcosとsinの組み合わせは以下のようになります。

  • 第1関節:\displaystyle{ \cos{B} }, \displaystyle{ -\sin{B} }
  • 第2関節:\displaystyle{ -\cos{C} }, \displaystyle{ \sin{C} }

それぞれの関節についてcosとsinが決まったので、これらを使った回転変換で姿勢を作ることができるようになりましたが、2ボーンIKとしてはまだ考慮しなければならないことがあります。

2ボーンIKの条件を満たす三角形は、辺cの反対側にも想定することができるからです。

回転方向が反対となる逆側の三角形

もう1つの三角形はBとCの回転方向を正負逆にしたものなので、既に求めているsin値の符号変換だけで対応可能です。

  • 第1関節:\displaystyle{ \cos{B} }, \displaystyle{ \sin{B} }
  • 第2関節:\displaystyle{ -\cos{C} }, \displaystyle{ -\sin{C} }

2ボーンIKの計算をする場合に、どちらの三角形による結果を選択するのかは、第2関節の回転方向が正負どちらであるかという基準で決定することが一般的です。これらはあらかじめどちらか一方に決めたものを選択することもあれば、両方に回転可能な場合も考慮して、IKを適用する前にどちら側に関節が曲がっていたかを調べて、同じ方向に曲がるような選択をする場合もあります。*10 いずれにせよ、第2関節の回転方向が正なら下の三角形、負なら上の三角形を選択します。余弦定理で求めるcosの結果は一緒なので、単純にsinの符号の組み合わせの選択を行います。

回転方向の設定について

第2関節の回転軸がどの軸になるかや、回転方向が正負どちらになるのかについては、2ボーンIKを適用する対象の構造に依存します。したがって、回転軸や回転方向を規定する設定項目を用意しておくのが良いでしょう。

人体モデルに適用する場合、一般的な作り方だと腕に設定する場合と足に設定する場合では、回転方向は逆になることが多いようです。当てはめてみて逆に曲がってしまったらもう一方の設定にすれば良いだけなので、そんなに難しく考える必要はありません。

2ボーンIKの手順(まとめ)
  1. 1ボーンIKを用いて目標位置の方向に第1関節を向ける
  2. 余弦定理でcosB, cosCを求める(cosCは符号反転する)
  3. sinB, sinCを求める(符号は正とする)
  4. 第2関節の回転方向設定によりsinB, sinCいずれかの符号反転を行う
    • 正回転:-sinB
    • 負回転:-sinC
  5. 得られたcos, sinの組み合わせで、各関節を回転させる

 

次項以降では、2ボーンIKに対するいくつかの基本的な機能拡張について説明します。

Up Vector Constraint

2ボーンIKは、1ボーンIK適用後に第2関節の回転軸を法線とする平面上での三角形を想定して計算するという基本アルゴリズムでした。2次元の場合はこれ以上のIK解は存在しませんが、3次元の場合はロール軸回転が存在するため、無限の解が存在することになります。これらの中から任意の平面上の三角形を選択したい場合は、1ボーンIKの計算後にUp Vector Constraintをかけることで対応します。 *11

2ボーンIKへのUp Vector Constraint適用イメージ

キャラクターモーションの補正目的で2ボーンIKを使う場合は、元のモーション姿勢から1ボーンIKを適用した状態での平面をそのまま使い、Up Vector Constraintをかけないことも多いですが、そこから手足の開き具合の調節が必要な場合などには、この機能に頼らなければなりません。

第2関節の回転角制限

2ボーンIKでは第2関節の曲がる方向を選択することで、回転角の範囲が自動的に0~180°か-180~0°のいずれかに制限されますが、この曲がり具合の範囲を更に制限することができるので、その手法について説明します。

理論背景を交えた手順説明

通常の2ボーンIK処理の工程で、cの長さを目標位置と第1関節の位置との距離として求めますが、ここでも余弦定理を使うことで角Cの角度制限の問題を、辺cの長さの範囲制限の問題に落とし込み、第2関節の回転角制限を実現します。

ここでは実際の回転計算で考慮する三角形の外角(π-C)ではなく、余弦定理で求める対象となる三角形の内角Cの方で考えます。

角Cの最小回転角をθmin、最大回転角をθmaxとします。(0 ≦ θmin ≦ θmax ≦180°)
設定は角度で与えておいたとしても、実際には事前処理でcosθmin, cosθmaxを求めておくのが効率的です。
辺a、辺bの長さと、それらがなす角Cに対するcosθmin, cosθmaxが既知なので、余弦定理で辺cの長さの最小値と最大値が決まります。 *12

  • \displaystyle{ c_{min} = \sqrt{ a^2 + b^2 - 2ab \cos{θ_{min}}} }
  • \displaystyle{ c_{max} = \sqrt{ a^2 + b^2 - 2ab \cos{θ_{max}}} }

実際の距離から求めた辺cの長さを、この\displaystyle{ c_{min} }\displaystyle{ c_{max} }で範囲制限した結果を新たなcとして2ボーンIKを計算することで、第2関節の角度が範囲制限された状態で、対応する第1関節の角度と共に求まります。

第2関節の角度制限適用例(最小角度:30°、最大角度:170°)

最初からcの長さを規定するパラメーター(距離に対する比率など)で範囲制限することもありますが、その方法だとaとbの長さの比率がキャラによって異なる場合に、制限する角度を一定に保つことができないという問題があります。aとbの長さの比率が固定なら\displaystyle{ c_{min} }\displaystyle{ c_{max} }は完全に事前計算可能なので、この方式を選択することにより2ボーンIKの処理負荷が余計に増えることはありません。

回転角制限の副作用

回転制限がかかると目標位置への到達という、IKが達成すべき本来の目的が達成できなくなってしまいます。しかしながら、目標位置への到達が多少阻害されたとしても、挙動の乱れや関節間の回転限界を超えた不自然な姿勢を見せないことの方が重視されるケースも多々あるため、そうしたメリット・デメリットを天秤にかけて、必要な場合には回転角制限をかけることを選択しなければなりません。

回転角制限が必要となる事例

2ボーンIKを適用する事例では、実はそこまで回転角制限が必要になるケースはありません。これは2ボーンIK自体に最初から関節が逆側に曲がらないような回転制限が自動的にかかっているためで、これは2ボーンIKの大きなメリットと言えます。
ただ、目標位置の配置によっては2本の関節が伸びきったり曲がったりするような状態、すなわち第2関節の最大角度が180°まで振り切ったり少し戻ったりするようなギリギリの状態になることがあり、そのような状態では目標位置の僅かな移動量に対し角度の変化量が極端に大きくなることから、その急激な挙動変化が不自然な動きとして目立つようになります。このような急激な角度変化の影響を緩和し目立たなくする目的で、最大角度を180°よりも少し小さい値 *13 に設定することで関節が完全に伸びきらないように設定しておくことがあります。手足を限界まで伸ばさなくても支障がない、あるいは限界まで伸び切って欲しくない場面ではメリットしかないので試してみてください。

2ボーンIKをキャラクターに適用する

エンドエフェクターについて

2ボーンIKを人型キャラクターなどに適用する場合は、腕や足に設定することが多いですが、実際に当てはめてみると腕部だと上腕+前腕、脚部だと腿+脛という割り当てになり、手足や足先の関節が対象から外れてしまうので、1ボーン分足りないと感じるかもしれません。実際のゲーム中で位置や姿勢を合わせたいのは手の指先や足先だったり足の裏面だったりするのに、このままではIK処理が合わせるのは手首、足首の位置になってしまうからです。

2ボーンIKの人型キャラクターへの適用例

IKの位置や姿勢を目標に合わせたい部位のことをエンドエフェクター、あるいは単にエフェクターと呼びます。これは末端効果器という意味で、IKを使って動作させるロボットアームなどの先端に接続されて実際に作業を行う装置を想定していることから、このような呼び方をしています。

先程の人型キャラクターの例に話を戻すと、手先や足先の部位がエフェクターに相当することになりますが、このエフェクター部位はIKの計算対象には含まなくて良いのです。
あらかじめ何らかの手法で求められているエフェクターの姿勢や位置から逆算して、途中の関節の姿勢や位置を計算するのがIKなので、エフェクターの位置を目標位置として渡してしまえば、IK内ではエフェクターそのものの制御をする必要がないからです。*14

エフェクターの目標位置の置き換え

もう少し具体的に説明すると、もしエフェクターの姿勢があらかじめ固定されているのなら、実際にエフェクターが効果を作用させたい位置とエフェクターの関節位置との相対的な位置関係も固定されていることになります。であれば本来の目標位置から、この相対的な位置差分を引いた位置をIKの目標位置にすれば、エフェクターが作用する位置にも自動的に合うことになります

人体で例えれば、手先エフェクターの実際の作用点が指先だった場合は、その時点での指先の位置と手先エフェクターの関節位置との相対的な位置関係を求めておけば良いのです。

エフェクターの作用位置を考慮した目標位置の平行移動

図で説明すると、エフェクターの先端部を本来の目標位置である白のチェッカーマーク位置に合わせたい場合に、エフェクターの位置差分を考慮して得られたピンクのチェッカーマーク位置を2ボーンIKの目標位置として計算することで、エフェクターの先端位置は自動的に白のチェッカーマークに到達するという仕掛けです。

エフェクターの関節位置が目標に到達すると実際の作用位置も自動的に目標に到達する

この手法は多くのIKに応用可能で、IK制御が必要な連鎖数を1つ減らすことが可能となります。*15

2ボーンIK+エフェクター部位の制御イメージ

疑似3ボーンIK

エフェクターの姿勢が固定されたままだと、IKによる姿勢変化が大きくなった時に、親となる第2関節とエフェクターとの間の回転角が極端な状態になることがあります。

エフェクター部位の関節の角度が極端になった例(左手)

エフェクターの固定姿勢を決める際に、目標位置や対象の状態を見てある程度の変化を付けておいたり、目標位置への到達を多少犠牲にしてでも回転制限の範囲内になるようにエフェクターの姿勢を後から変更する方法も考えられますが、どうせならエフェクター部位もIKに計算させてしまいたいと考えるはずです。

エフェクターもIKに含めて解決した場合

人間の手足のケースならば3ボーンに対応したIKを適用することで解決できそうですが、ここでは2ボーンIKを使って疑似的に3ボーン分のIK処理を実現する手法について紹介します。

疑似3ボーンIKの手順
  1. IK適用前の第2関節と第3関節間のローカル回転差分を計算する
  2. 第3関節の関節位置と先端位置の移動差分を計算する
  3. 手順2.で求めた移動差分を目標位置から差し引いた位置を新たな目標位置とする
  4. 第1関節と第2関節に2ボーンIKを適用する
  5. 手順1.で求めたローカル回転差分を用いて、第3関節の姿勢を再構成

  6. 手順5.で求めた第3関節の姿勢と、第3関節の初期姿勢の中間姿勢を計算し、これを第3関節の姿勢とする
    • 中間姿勢のブレンド率は追加パラメーターとして別途与える必要がある
    • 0%だとブレンドターゲット側、100%だと初期姿勢側としてブレンドする
  7. 手順6.のブレンド率が100%以外(未満)の場合は、手順2.~4.を再び実行する *16

 

細かく手順を書きましたが、ざっくり言うと、2ボーンIK計算後に第3関節の姿勢を初期姿勢を使って加工し、目標位置からずれた分を再度2ボーンIKを計算することで解消しています。手順2.~4.は、2ボーンIKで必要となる手順そのものなので、そのまま機能を呼び出せばOKです。

ブレンド率の調整で出る結果の幅のサンプルが以下の画像となりますが、この幅は第3関節の初期姿勢だけでなく目標位置の場所によっても広がったり狭まったりします。

ブレンド率による結果の幅

人型キャラクターに適用する時の様にエフェクター部位を第3関節とする場合には、必要なら姿勢を外部から与えて拘束してもいいのですが、通常は元のモーションで得られるFK姿勢をそのまま使えば十分です。下の適用例は疑似3ボーンIKとUp Vector Constraintのみで、Tポーズの状態から1分くらいで適当にポーズ付けしたものです。

疑似3ボーンIK(+Up Vector Constraint)の人型キャラクターへの適用例
別バージョン

上の説明では回転差分を用いることで元のFK姿勢とのブレンドを行う方式について説明しましたが、回転差分を用いずに第2関節と同じ姿勢をそのままブレンド対象とするやり方もあるので、設定によって使い分けられるようにしておくと便利です。

他にも2ボーンIKの適用後にエフェクター部位の回転制限をかけて目標位置からずれてしまった結果に対して、追加処理で手順2.~4.を適用することで、回転制限もある程度考慮しつつ目標位置に到達するといった簡易方式も考えられます。 *17

特徴

追加で第3関節のブレンド率の設定が必要となることや、2ボーンIKを2回計算することによる処理負荷増の問題はありますが、2ボーンIKの仕組みやメリットを生かしたまま3ボーン分のIK処理が実現できるという点で、導入し易いのではないかと思います。特にエフェクターの先端は目標位置に到達して欲しいけど、姿勢拘束はボチボチで良いという場合に最適です。

また、一般的に四足歩行動物の四肢の制御は人間の手足よりも1ボーン多い関節制御が必要となるため、3ボーン以上に対応したIKアルゴリズム+エフェクター部位の制御を行う必要がありますが、この手法を用いることで2ボーンIKの機能しかなくても四足歩行動物の四肢の制御への対応が可能となります。以下は動作サンプルです。

疑似3ボーンIK+エフェクター制御の動作サンプル(前足→後ろ足→ブレンド率制御の様子)

まとめ

IKの基本的な概念、基本処理となる1ボーンIKと今でも広範囲で使われている2ボーンIKの具体的な処理内容について説明しました。数学の授業で習った時には何に使うのか今ひとつピンと来なかった余弦定理も、ここではしっかり役に立っています。

IKアルゴリズムには他にも様々な手法があり、それぞれ適用できる範囲や得意分野が異なります。また今でも新しいIKアルゴリズムや既存のアルゴリズムの改善の提案が各所で発表されているので、そうした手法についても学ぶきっかけになればと思います。

特に昨今は商用ゲームエンジンに標準機能として様々なIK処理が実装されるようになったので、自分でIK処理を新たに作成する機会は減っているかも知れません。それでも自社エンジンやタイトルにIK処理を組み込む事例はまだまだありますし、仮に既に用意されているIKの機能を使うだけであっても、その仕組みや特徴を理解しているのとそうでないのとでは、同じIK機能を使ってるにも関わらずゲーム上での挙動が大きく変わることがあったりするので、IK処理の知識は無駄になりません。

今回はIK本体のアルゴリズムを中心に解説しましたが、実際のゲーム制作においては、IKに与える目標位置の取得方法や加工の仕方、各種パラメーターの設定にも工夫が必要となり、最終的な挙動に与える影響度としてはむしろそちらの方が重要だったりもします。今後機会があれば、そういった内容にも触れられれば良いなと思っています。

終わりに

セガでは商用ゲームエンジンだけでなく自社開発エンジンによるゲーム開発も行われており、開発メンバーとして一緒に働ける仲間を幅広く募集しています。セガでのゲーム開発に興味がある方は、下記サイトにアクセスしてみてください。

recruit.sega.jp

©SEGA

 

*1:+α

*2:この場合は必然的にX軸がロール回転軸となります。

*3:回転の処理はX軸、Y軸、Z軸それぞれに対して計算する必要があります。1つずつ計算しても良いのですが、通常は行列などを使ってまとめて処理します。

*4:中学3年で習う「底辺の2乗+高さの2乗=斜辺の2乗」です。

*5:これは外積版やクォータニオン版も同様です

*6:1ボーンIK用の目標位置とは別に設定される

*7:手順2.で求めたcosX, sinXの式はY軸合せの場合の式なので

*8:これは他のIKだと非常に面倒な追加処理を要求されます

*9:この図では第2関節も一緒に追従させていますが、計算上は第2関節は放置していて問題ありません。

*10:適用前の角度が180°の場合は方向が決められないので、その場合に正負どちらを優先するかは決めておく必要があります。

*11:この処理自体は1ボーンIKにかかるものなので計算手順も同じです。

*12:余弦定理の式が先程とは違いますが、cについて展開し直しただけです

*13:例えば170~175°程度

*14: IKで決定した最終位置にエフェクター部位を接続する処理も、IK処理全体の枠組みの中には含まれますが、IKアルゴリズムそのものが解決する内容ではないという意味です。

*15:エフェクター部位の情報もIK計算に必要な場合は残す必要があります

*16:100%の場合は、そのままIK処理を終了する

*17:その場合、結果として回転制限を突破する可能性もあります

CEDEC 2022 セガグループによるセッション紹介!

今年も日に日に暑さが増し、CEDECが近くなってまいりました。

昨年に続きオンラインで開催されるゲーム業界最大のカンファレンスに、

セガからも多くの社員が登壇します!

CEDEC2022

cedec.cesa.or.jp

会期:2022年8月23日(火)~8月25日(木)

今回で7回目となる、セッションと登壇者紹介に加え、ここでしか見れない当日の資料の抜粋チラ見せ付きで株式会社セガ、第3事業部の麓からご紹介致します。

 

  • 開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて
    • セッション内容
    • 講演者
    • スナップショット
  • 『PSO2 ニュージェネシス』長期運営タイトルにおける、大規模バージョンアップを支えた開発手法の紹介
    • セッション内容
    • 講演者
    • スナップショット
  • 『PSO2 ニュージェネシス』アバターカスタマイズ ローンチ作業を振り返って
    • セッション内容
    • 講演者
    • スナップショット
  • 『PSO2 ニュージェネシス』今更聞けない!広大なフィールドの作り方
    • セッション内容
    • 講演者
    • スナップショット
  • 『PSO2 ニュージェネシス』におけるエフェクトエディタ制作事例
    • セッション内容
    • 講演者
    • スナップショット
  • withコロナ時代:ワーキングペアレントの働き方と悩み/上司・経営者の立場での悩み
    • セッション内容
    • 講演者
    • スナップショット

開発もQAも自動テスト!「LOST JUDGMENT:裁かれざる記憶」のQAテスター参加で進化した「テスト自動化チーム(仮)」の取り組みについて

セッション内容

近年のゲーム開発では、開発規模が拡大するとともに、マルチプラットフォームや多言語対応、多拠点開発(海外・在宅勤務を含む)の必要性が増し、開発スピードや品質の維持のためにテスト自動化の重要性が日々高まっています。一方で、ゲーム開発におけるテスト自動化は、一般的には開発部門またはQA部門の片方が主体となって行われることが多く、どちらかが得意な切り口(単体テスト中心、画像認識によるプレイテスト中心など)に偏りがちです。
本講演では、開発部門とQA部門からそれぞれ参加して、一つの「テスト自動化チーム(仮)」を結成し、プログラマもQAテスターも各々の得意分野の自動テストを書くことで、より広範囲かつ効果的なテスト自動化を達成して、開発スピードと品質の向上に貢献した事例について、マルチプラットフォーム・多言語・多拠点開発となった「LOST JUDGMENT:裁かれざる記憶」の実例をもとに、開発部門とQA部門のそれぞれの視点を交えて紹介します。

 

講演者

株式会社セガ 
第1事業部
阪上 直樹


プロジェクト業務部
門脇 健造

開発技術部
粉川 貴至

08月24日(水) 14:50 〜 15:50 レギュラーセッション

cedec.cesa.or.jp

スナップショット

続きを読む

CEDEC 2021 セガグループによるセッション紹介!

今年もやってきました、毎年恒例のCEDECでのセガグループによるセッション紹介です!
株式会社セガ、第3事業部の麓です。

昨年に続きオンラインで開催されるゲーム業界最大のカンファレンス

CEDEC2021

 

cedec.cesa.or.jp

https://cedec.cesa.or.jp/2021/

会期:2021年8月24日(火)~8月26日(木)
にグループ(および関連会社)から今年も登壇します!
今回で6回目となる、セッションと登壇者紹介に加え、ここでしか見れない当日の資料からの抜粋付きでご紹介します。

 

プランナーもハックしよう ~業務効率化、ローコード開発とテクニカルプランナー~

セッション内容

本セッションでは実務においてプランナーが行った業務効率化の例をご紹介します。
その際に利用した、プランナーでもできる自動化としてローコード開発の紹介も行います。
これらの取り組みを通じて、雑務や人力の仕事が多いプランナー業の改革と、将来の新たなプランナー像であるテクニカルプランナーのキャリアパスを提起します。

 

講演者

株式会社セガ 
ゲームコンテンツ&サービス事業本部 第4事業部開発2部
瀧澤 翼
リードプランナー

08月25日(水) 13:30 〜 13:55 ショートセッション

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210708131251j:plain

 f:id:sgtech:20210708131245j:plain

 

Android/iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~

セッション内容

当講演では、Android/iOS 向けタイトルにおける、オンプレミスで動作する実機上での自動テスト環境構築・運用時に得たノウハウについて共有します。
中でも一般的に言及が少ない、自動テスト環境を構築するのに必要な"周辺情報"にフォーカスして解説を行います。
"周辺情報"とは、テスト実行そのものやテストフレームワーク"以外"の以下の内容を指します。

・端末の管理や情報の取得
iOS 端末の IP アドレスを取得するにはどうしたらいいか等。
・アプリケーションイメージの転送や起動
iOS のアプリケーションイメージをコマンドラインで実機に転送・起動するのはどうすればいいのか等。
・実機上の映像の動画撮影
Android/iOS 実機上でゲームの映像を録画する場合それにはどんな手段があってそれぞれのメリットデメリットは何があるか等。
・テスト結果の取得と整形、通知

その他、環境構築後の運用時に発生した問題とその解決方法の共有も行います。
当講演を通じ、 Android/iOS 実機上で自動テストやってみようかな、と思う人が少しでも増えれば嬉しく思います。

講演者

株式会社セガ
開発技術部
竹原 涼
廣島 岳史

08月25日(水) 14:50 〜 15:50 レギュラーセッション

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210720210755p:plain

f:id:sgtech:20210720210814p:plain

進化したSympathy:『PSO2:NGS』が奏でるインタラクティブミュージック

セッション内容

『ファンタシースター』シリーズの最新作『ファンタシースターオンライン2 ニュージェネシス』(通称:PSO2:NGS)では、『PSO2』で構築した既存のBGMシステム「Sympathy」をベースにして、新たな要素、機能を追加した新システム「Sympathy2.0」を制作致しました。そこに至る過程について、システム設計からツールのバージョンアップ、実装例までをご紹介できればと思います。

講演者

株式会社セガ
ゲームコンテンツ&サービス事業本部 第2事業部 サウンドセクション
小林 秀聡
サウンドディレクター・サウンドクリエイター

ゲームコンテンツ&サービス事業本部 第3事業部 第3開発1部 第3プログラムセクション
増田 亮
リードプログラマー

08月26日(木) 14:50 〜 15:50 レギュラーセッション

cedec.cesa.or.jp

「それ、どれだけ売れるの?」キャラクターIPソシャゲにおけるIP商品力の定量化と取り組み

セッション内容

本セッションでは、キャラクターIPを使用したソーシャルゲームにおけるIP商品(=販売するキャラクター)の商品力を客観的に把握するための運営上の取り組みについてご紹介します。
キャラクターIPを使用したソーシャルゲームの運営には、事業上大きな課題があります。それは売上がその時々に販売するIP商品力に影響され適切な運営の弊害になるというリスクです。まずこの運営リスクについてご説明します。
次に、課題解決の取り組みとして、リスクを低減するため「商品力」を定量的に把握する試みについてご説明します。主に個人の売上データを用いた定量化するためのクリアすべき具体的な課題と統計的分析手法を用いた対策方法について解説します。
また、定量化した商品力指標の運営上の利用例を紹介します。

講演者

株式会社セガ

戦略支援部
柴宮 朋和
ビジネス&データ分析1課 課長代行 / データアナリストスペシャリスト

第4開発2部
川上普史
マネージャー/運営リーダー

08月25日(水) 11:50 〜 12:15 ショートセッション

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210720210551p:plain

f:id:sgtech:20210720210603p:plain

ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~

セッション内容

近年、モバイルゲームの規模も大規模化しており、そのアセットデータのダウンロードに掛かる時間も増大する傾向にあります。
弊社では、アセットデータのダウンロード待ち時間を HTTP/2 を採用することにより低減することに成功しました。
当講演では、この HTTP/2 の仕様のゲーム開発者向け解説とモバイル向けタイトルでの導入・運用事例を紹介します。
仕様の解説では、 HTTP/2 を採用すると何故ダウンロード時間の低減が可能なのかに加え、クライアントサーバ間の通信の効率化に寄与する点についても触れます。
導入事例では、具体的にアセットダウンロードがどれだけ高速になったかの実例も併せて紹介を行います。
運用事例については、HTTP/2 はゲーム業界においてはまだ事例紹介が少なく枯れ切っていない面も多くある為、採用したタイトルの運用中に実際に発生したトラブルとその解決方法について特に時間を掛けて紹介を行う予定です。

講演者

株式会社セガ
開発技術部
竹原 涼

山田 英伸

08月25日(水) 11:20 〜 12:20 レギュラーセッション

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210720210850p:plain

f:id:sgtech:20210720210905p:plain

ゲーム業界の男性育児休業~職場復帰の実態。リモートワークでの育児両立の難しさと働き方。3社事例紹介。

セッション内容

2020年より、ゲーム業界でもリモートワークが恒常化してきました。
その中で、ワーキングペアレントの働き方はどのように変わったでしょうか?
新たに生まれた課題は何でしょうか?

「仕事への影響・不安」を持ちながらも、育児休業を取得し、職場復帰した登壇者たちが、「男性育児休業の実態」と、「リモートワークでの育児両立の難しさと働き方」をテーマに、3社の事例を紹介します。

厚生労働省が発表している「男性の育児休業取得促進等に関する参考資料集」を元に、「制度の説明」「取得方法」を冒頭で紹介。
その後、本セッション用にゲーム業界各社で取った最新の「男性の育児休業~復帰後の働き方(リモート含む)アンケート」についての共有を行います。

<2021年版アンケートのご協力をお願いいたします>
●【男性育休アンケート】対象者:「取得経験者」「取得しなかった方」「非該当者(性別問わず)」⇒それぞれのご意見をお聞かせください

docs.google.com

・「上司」「経営者」の立場からの意見、考え方も、一例としてお伝えいたします。
・各社社内コミュニティの紹介や、オンライン環境での活動状況もお話しいたします。

 

講演者

セガサミーホールディングス株式会社

総務本部 コミュニケーションサービス部 コミュニケーション推進課
茂呂 真由美

株式会社セガ

ゲームコンテンツ&サービス事業本部 第3事業部 第3開発1部 第3プログラムセクション
増田 亮
リードプログラマー

ゲームコンテンツ&サービス事業本部第4事業部戦略支援部ビジネス&データ分析2課
竹内 公紀
データアナリスト/課長代行

ゲームコンテンツ&サービス事業本部第4事業部第4開発2部第一ソフト開発セクション
渡邉 吉治
リードプログラマー

ほか

08月24日(火) 11:20 〜 12:20 パネルディスカッション

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210720211123p:plain

リモートワークでどうなった?!ワーキングペアレントの働き方と悩み

セッション内容

Zoom参加者は、「扱って欲しい議題」「悩み」「相談したいこと」を、CEDEC受講登録後のマイページの当セッション専用申込フォーム内「アンケートリンク」より、事前提出してください。

事前提出いただいた議題を取り上げ、「3つのパート」に分け、ディスカッションします。「リモートワーク下での悩み・議題」を優先して取り上げますが、それ以外でも、「課題感が大きい」「議論の必要性が高い」と判断したものは、議題に取り上げさせていただきます。

●ディスカッション<1>(茂呂)
事前アンケートで「多かった悩み」「気になった悩み」をピックアップして進行

●ディスカッション<2>(竹内)
「育児休業~復帰後に関して」「男性特有の悩み」をピックアップして進行

●ディスカッション<3>(佐々木)
「当人以外の職場の仲間・管理職・人事総務・経営者等」の議題をピックアップして進行

今回の受講をその場限りのものにせず、それぞれの職場に今回の知見を持ち帰り、共有していただけると嬉しいです。
ゲーム業界全体が、多様な働き方について相談しやすい環境になることを願っており、その話題作りのキッカケとなるセッションになることを目指しています。

 

講演者

セガサミーホールディングス株式会社

総務本部 コミュニケーションサービス部 コミュニケーション推進課
茂呂 真由美

株式会社セガ


ゲームコンテンツ&サービス事業本部第4事業部戦略支援部ビジネス&データ分析2課
竹内 公紀
データアナリスト/課長代行

ほか

08月24日(火) 13:30 〜 14:30 ラウンドテーブル

cedec.cesa.or.jp

スナップショット

f:id:sgtech:20210720211213p:plain



メタバースにおける飲用体験システムの開発:VRShaker

セッション内容

現実空間での飲用、喫食体験は人間関係を形成する上で重要な物の一つと言えるだろう。しかし、近年の社会状況からそれらの体験が難しい物となっている。
そこで、自宅にいながら、遠隔地の人と共にバーで他の人に作ってもらったカクテルを味わう体験ができるシステム:VRShakerを製作した。
バーテンダーのカクテルシェイク動作をトラッキングし、現実世界の遠隔地にあるVRShaker筐体がカクテルシェイカーをシェイクする。体験者は構築されたメタバース上で呑みながら会話をすることができる。
本セッションでは、コロナウィルスと共生しなければならない現代においてメタバースを用いた喫食体験とその可能性について議論する。

講演者

株式会社セガ

アミューズメントコンテンツ開発生産本部 メダル研究開発部
鈴木 謙太

ほか

08月26日(木) 11:20 〜 11:45

cedec.cesa.or.jp

 

いかがでしょうか?

今回紹介したセッションで聴講したい!と思ったセッションはありましたか?
CEDECを聴講して情報収集や交流をし、ゲーム業界の今を知り、業界の未来について語り合いませんか?
それでは皆さんCEDECでお会いましょう!

 

私達は将来CEDECに登壇してみたいと思っている、やる気のある方を求めています。
そんな貴方、以下にアクセスしてみませんか?

 

recruit.sega.jp

 

※複数社登壇の場合でもセガの社員のみ表記しています 
©SEGA

クォータニオンとは何ぞや?:基礎線形代数講座

---【追記:2022-04-01】---

「基礎線形代数講座」のPDFファイルをこの記事から直接閲覧、ダウンロードできるようにしました。記事内後半の「公開先」に追記してあります。

--- 【追記ここまで】---

みなさん、はじめまして。技術本部 開発技術部のYです。

ひさびさの技術ブログ記事ですが、タイトルからお察しの通り、今回は数学のお話です。

#数学かよ って思った方、ごめんなさい(苦笑)

数学の勉強会

弊社では昨年、有志による隔週での数学の勉強会を行いました。ご多分に漏れず、コロナ禍の影響で会議室に集合しての勉強会は中断、再開の目処も立たず諸々の事情により残念ながら中止となり、用意した資料の配布および各自の自学ということになりました。

勉強会の内容は、高校数学の超駆け足での復習から始めて、主に大学初年度で学ぶ線形代数の基礎の学び直し 、および応用としての3次元回転の表現の基礎の理解といった感じです。

「線形代数」とは、微積分と並び理工系の科学・技術の諸分野で基礎中の基礎として用いられる数学の分野で、ゲームでは主に3DCGの技術的基礎として応用されています。昨今のAIブームでも一時期話題になりました。 タイトルにある「クォータニオン」とは、日本語では「四元数」と訳され、ゲームではキャラや背景などを3次元回転させるときに応用されるもので、勉強会の中では最後に出てくるラスボスであり少し難しい数学の概念です。

勉強会の趣旨は、この「クォータニオン」を数学的にきちんと理解することを えさ ゴールとして、そのために(実際はそれだけでなくさまざまな技術の基礎となっている)「線形代数」の基礎をきちんと学び直そうということでした。

なぜ数学?

ゲーム開発においても分業化・専業化の流れは著しく、ゲームアプリケーション(みなさんに遊んで頂いているゲームそのもの)を開発する際、いわゆるゲームエンジンや各種ライブラリを用いるのが当たり前になっています。これらエンジンやライブラリは、ゲーム開発者にさまざまな機能を提供し効率よく開発できるようにすることが役割であり、極端な話、三角関数を全く知らなくても3Dゲームを作れる時代になっています。 しかしながら例えばゲーム固有の表現のためにシェーダー(画面を描画する機能)をカスタマイズしたい場合や、当然のことながらエンジンやライブラリそのものの開発者は、ある程度のさまざまな数学の知識が必要となります。技術的に高度なことをしようと思うとなおさら深い理解が必要です。

このように数学や物理学は、ゲーム業界のみならず理工系のさまざまな分野で、科学者・技術者を根元から支える基礎となり重要な武器となっています。

資料を公開します

今回、この勉強会用に用意した資料「基礎線形代数講座:線形代数 回転の表現」を一般に公開いたします。全8講、本文が全部で140ページのPDFで、各講は以下のような標題です。

  • 第1講 イントロダクション
  • 第2講 初等関数
  • 第3講 ベクトル
  • 第4講 行列 I:連立一次方程式
  • 第5講 行列 II:線形変換
  • 第6講 行列 III:固有値・対角化
  • 第7講 回転の表現 I
  • 第8講 回転の表現 II

線形代数 基礎の本質的な部分をできるだけ簡潔に分かりやすく学べるように全体を組み立ててみました。各項目を学ぶ順番や手法、一部は定義すら一般的なものと違う(例:行列式)こともあります 。いわゆる「大人の学び直し」ではあるのですが、内容はガチの数学となっています。 記事の最後に公開先へのリンクを張っておきますので、興味のある方は参考にして頂ければと思います。

特に学生の方で、この資料で線形代数を学んでみようと思われた奇特な方がいらっしゃれば、言うまでもないことですが読んだ後改めて講義で指定されている教科書を読んでみましょう。きっとこれまで以上に理解が深まることと思います。

この記事では、その中から「クォータニオン」の導入部分である、第8講の第2節までをそのまま引用します。導入部なので内容は平易となっていますが、複素数・行列・三角関数に関するある程度の知識がないと理解は難しいと思われます。ぜひ紙と鉛筆を用意して、ご自身でも図や式を書いたり計算したりしながら、じっくり読んでみてください。

基礎線形代数講座からの引用

【第8講】回転の表現II


【8-1】はじめに

本講では、4種の3次元回転の表現の最後としてクォータニオンについて学ぶ。クォータニオンは日本語では四元数(しげんすう)と訳されるもので、1843年にハミルトンにより発見された複素数を拡張した代数体系であり、3次元の回転の表現としても多くの利点を備えている。
その性質から特に計算機を用いる場合にも他の表現手法に比べ優位な点が多く、近年 宇宙機を始め、3DCGやCV、ロボット工学等々さまざまな分野で応用されている。一方で他の表現手法に比べるとやや抽象的でその本質(4次元空間に埋め込まれた3次元回転)が捉えづらい面も否めない。本講では、拡張の元になった大きさ1の複素数の積による複素平面内での回転の復習から始め、ハミルトンによる発見に至るまでの過程*1をたどる事でクォータニオンを導入し、その性質を分かりやすく解説する。


●おさらい
任意の複素数 $ x+iy $ に大きさ $ 1 $ の複素数 $ \cos\theta+i \sin\theta $ を掛ける事は複素平面内での $ \theta $ 回転を表していた。実際 \[ (x'+iy')=(\cos\theta+i\sin\theta)(x+iy)=(x\cos\theta-y\sin\theta)+i(x\sin\theta+y\cos\theta ) \] この式で、$ 1 $ と $ i $ をベクトルの基底としてみると、 \[ x→x'=x\cos\theta-y\sin\theta,\ y→y'=x\sin\theta+y\cos\theta \] という線形変換と見ることができて、行列形式で書けば \[ \begin{eqnarray} \left[ \begin{array}{c} x' \\ y' \\ \end{array} \right]=\left[ \begin{array}{cc} \cos\theta & -\sin\theta\\ \sin\theta & \cos\theta\\ \end{array} \right] \left[ \begin{array}{c} x \\ y \\ \end{array} \right] \end{eqnarray} \] となり、すなわち複素平面である $ 1-i $ 平面での $ \theta $ 回転を表している事がわかる。

これの本質は、$ i $を掛けるという事:基底 1 と $ i $ との閉じた代数が、$ 1-i $ 平面内で一回りする回転に相当していることにある。


【8-2】クォータニオンの導入:ハミルトン劇場

[8-2-1] 拡張複素数で複素( 3次元)空間を回したい

ハミルトンは複素数を拡張して、虚数単位 $ i $ の他に独立な別の虚数単位 $ j $ を導入 $( i^2=-1,\ j^2=-1,\ \overline {i}=-i,\ \overline {j}=-j)$、$ 1,i,j $ の 3つの元で $ 1-i $平面、$ 1-j $平面、$ i-j $平面それぞれの回転を表現できないか?と考えた(つまり複素平面を複素空間に拡張できないか?ってこと) 。

「独立な異なる虚数単位 $ i,j $」に違和感がある人もいると思う。新しい代数として拡張していっているので、うまく拡張できさえすればあとは「慣れ」ではあるのだが「複素数」を以下のように解釈することで別の虚数単位を導入するという拡張も違和感が減るかもしれない。
おさらい*2:2行 2列の行列 $ \begin{eqnarray} I= \left[ \begin{array}{cc} 0 & -1\\ 1 & 0\\ \end{array} \right] \end{eqnarray} $ を考えると(この行列は 上の おさらいで出てきた 2次の 回転行列で $ \theta=\pi/2 $ としたものでもあることに注意)、 $ \begin{eqnarray} I^2= \left[ \begin{array}{cc} -1 & 0\\ 0 & -1\\ \end{array} \right] = -E \end{eqnarray} $ ( $ E $ は単位行列 )となる(つまり 2乗して -1)。また行列 $ Z=xE+yI\ (x,y∈\Bbb R ) $ を考えると、 $ \begin{eqnarray} Z = \left[ \begin{array}{cc} x & -y\\ y & x\\ \end{array} \right] \end{eqnarray} $ なので、$ Z = O $ となるのは $ x=y=0 $ のときのみ(つまり $ E $ と $ I $ は線形独立)。この行列 $ Z=xE+yI $ に対し $ E $ を $ 1, I $ を $ i $ に対応させることで、複素数 $ z=x+iy $ に対応させる事が可能となる。
ここでさらに別の行列 例えば $ \begin{eqnarray} J = \left[ \begin{array}{cc} 1 & -\sqrt{2}\\ \sqrt{2} & -1\\ \end{array} \right] \end{eqnarray} $ を考えると、$ J^2=-E $ を満たし、この $ J $ を含め $ E,I,J $ が線形独立であることは容易に確かめられる。このような「複素数の拡張」(上の $ J $ の事)がうまく行くかどうかは別にして「違和感」のない表現もやろうと思えば可能ではある。


以下、ハミルトンがクォータニオンを発見するまでの過程*3をたどってみよう。
ハミルトン:$ 1-i $平面と $ 1-j $平面の回転は当然できた。


でも $ i-j $平面がうまくいかない。 $ i\times j $ の扱いがどうにもこうにも…
とりあえず $ i\times j $ を $ ij $ として回るようにはできたけど*4、この $ ij $ って本来 $ i $ にならないと $ i-j $平面にはならない。でも $ ij = i $ としてしまうと $ i $ を掛けても $ -j $ にならずに $ -1 $ となってうまく回らない。どうしたものか・・・
(ちなみに後に別の数学者により、このような $ 1,i,j $ による 「複素数の拡張」(三元数に相当)は、うまく行かない事が証明されている。)


[8-2-2] 4次元? マジか 4次元??

ある日運河のほとりを歩いている時(実話*5)にひらめいた: もう一つ虚数単位を導入して $ i\times j=k $ としてみよう。実数単位 $ 1 $ と虚数単位 $ i,j,k $ で 4次元になるけど、うまくいくかも・・・
回転面は $ 1-i, 1-j, 1-k $平面, $ i-j, j-k, k-i $平面の6面になるのか。3次元回転をうまく取り出すには、$ i-j, j-k, k-i $平面の回転がこんな風になるといいのかな?


●$ i $ を掛けると?:想定図のように $ j-k $平面を回すため、$ ij=k $ としてみよう


お、$ j-k $平面だけでなく $ 1-i $平面も同時に回るんだ。そりゃそうか。しかもそれぞれの平面内で回りそうだ。
角度 $ \theta $ の場合として「大きさ」1の $ (\cos \theta+ i \sin \theta) $ を、4次元に拡張した「複素数」$ (w+ix+jy+kz) $ に( $ i^2=-1,\ ij=k, \ ik=-j $ に注意して)掛けてみよう:
\[ \eqalign{ (w'+ix'+jy'+kz')=(\cos\theta&+i\sin\theta)(w+ix+jy+kz)\\
=&w\cos\theta+ix\cos\theta+jy\cos\theta+kz\cos\theta\\ &+iw\sin\theta-x\sin\theta+ky\sin\theta-jz\sin\theta\\ =&(w\cos\theta-x\sin\theta)+i(w\sin\theta+x\cos\theta)\\ &+j(y\cos\theta-z\sin\theta)+k(y\sin\theta+z\cos\theta) \tag{8-2-1}\\ } \]
確かに $ w-x $平面( $ 1-i $平面:下から2行目)と $ y-z $平面( $ j-k $平面:下から1行目)がそれぞれの平面内 で同時に別々に回っている*6

つまりこういうこと
\begin{eqnarray} \left[ \begin{array}{c} w' \\ x' \\ y' \\ z' \\ \end{array} \right]=\left[ \begin{array}{cccc} \cos\theta & -\sin\theta & 0 & 0\\ \sin\theta & \cos\theta & 0 & 0\\ 0 & 0 & \cos\theta & -\sin\theta\\ 0 & 0 & \sin\theta & \cos\theta\\ \end{array} \right] \left[ \begin{array}{c} w \\ x \\ y \\ z \\ \end{array} \right] \end{eqnarray}


●$ j $ を掛けると?:想定図のように $ k-i $平面を回すため、$ jk=i $ としてみよう


およ。さっきの $ i $ を掛けて $ j-k $平面をうまく回せる条件:$ i\times j=k $ と合わせると、$ ij=k,\ ji=-k $ となって、なんと積は可換じゃなくなる! まあしょうがないか…。

角度 $\theta$ だと同様に:
\[ \eqalign{ (\cos\theta&+j\sin\theta)(w+ix+jy+kz)\\ =&(w\cos\theta-y\sin\theta)+j(w\sin\theta+y\cos\theta)\\ &+k(z\cos\theta-x\sin\theta)+i(z\sin\theta+x\cos\theta) \tag{8-2-2}\\ } \]
ん、これも別々に回っている。

●残り $ k $ を掛けると?:想定図のように $ i-j $平面を回すため、$ ki=j $ としてみよう


これも角度 $\theta$ だと同様に:
\[ \eqalign{ (\cos\theta&+k\sin\theta)(w+ix+jy+kz)\\ =&(w\cos\theta-z\sin\theta)+k(w\sin\theta+z\cos\theta)\\ &+i(x\cos\theta-y\sin\theta)+j(x\sin\theta+y\cos\theta) \tag{8-2-3}\\ } \]

●とりあえず分かったこと

虚数単位 $ i,j,k $ に対して積を $ ij=k, ji=-k, jk=i, kj=-i, ki=j, ik=-j $ として $ w+ix+jy+kz $ に左から $ \cos\theta+i\sin\theta $ を掛けると、$ 1-i $平面, $ j-k$平面が同時に $ \theta $ 回転 する。$ j,k $ で回しても同様。でもこのままだと$ 1-i $平面で余計な回転が発生し、最終的に実現したい純粋な 3次元の回転を切り出せない。何かうまい方法はないのだろうか?

つまりこうなって欲しい
\begin{eqnarray} \left[ \begin{array}{c} w' \\ x' \\ y' \\ z' \\ \end{array} \right]=\left[ \begin{array}{cccc} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & \cos\theta & -\sin\theta\\ 0 & 0 & \sin\theta & \cos\theta\\ \end{array} \right] \left[ \begin{array}{c} w \\ x \\ y \\ z \\ \end{array} \right] \end{eqnarray}


●そういえば非可換だった*7

非可換なので、右から掛けたらどうなる?
右から $ i $ を掛けた場合:

なんと $ 1-i $平面は同じ向きで、$ j-k $平面は逆向きに回る!じゃあ $ -i $ だとその逆になるだろう。

右から $ -i $ を掛けた場合:

これなら、左から $ i $ を、右から $ (-i) $ を掛けることで $ 1-i $平面の回転だけを無くせそう。


●というわけで

左から $ i $ 右から $ -i $ を掛けた場合:

$ j-k $平面は2倍回りそうだけどw やってみよう。
\[ \eqalign{ (\cos\theta&+i\sin\theta)(w+ix+jy+kz)(\cos\theta-i\sin\theta)\\ =&(\cos\theta+i\sin\theta)\{(w\cos\theta+x\sin\theta)+i(-w\sin\theta+x\cos\theta)\\ &+j(y\cos\theta-z\sin\theta)+k(y\sin\theta+z\cos\theta)\}\\ =&w\cos^2\theta+x\sin\theta\cos\theta-(-w\sin^2\theta+x\sin\theta\cos\theta)\\ &+i(-w\sin\theta\cos\theta+x\cos^2\theta)+j(y\cos^2\theta-z\sin\theta\cos\theta)\\ &+k(y\sin\theta\cos\theta+z\cos^2\theta)+i(w\sin\theta\cos\theta+x\sin^2\theta)\\ &+k(y\sin\theta\cos\theta-z\sin^2\theta)-j(y\sin^2\theta+z\sin\theta\cos\theta)\\ =&w(\cos^2\theta+\sin^2\theta)+ix(\cos^2\theta+\sin^2\theta)\\ &+j\{y(\cos^2\theta-\sin^2\theta)-z(2\sin\theta\cos\theta)\}\\ &+k\{y(2\sin\theta\cos\theta)+z(\cos^2\theta-\sin^2\theta)\}\\ =&w+ix+j(y\cos2\theta-z\sin2\theta)+k(y\sin2\theta+z\cos2\theta)\tag{8-2-4} } \]
最後は倍角の公式を使った。これで $ j-k $平面 だけを回せた!
めでたしめでたし。2倍回るけどw

こうなった
\begin{eqnarray} \left[ \begin{array}{c} w' \\ x' \\ y' \\ z' \\ \end{array} \right]=\left[ \begin{array}{cccc} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & \cos2\theta & -\sin2\theta\\ 0 & 0 & \sin2\theta & \cos2\theta\\ \end{array} \right] \left[ \begin{array}{c} w \\ x \\ y \\ z \\ \end{array} \right] \end{eqnarray}


・・・ハミルトン劇場 終


このあと第8講は

  • 【8-3】クォータニオン:定義と諸性質
  • 【8-4】クォータニオン:3次元回転の表現
  • 【8-5】 [▼]付録 1:一般的な4次元の回転について
  • 【8-6】付録2:成分表示における4次元内積の不変性について
  • 【8-7】 [▼A]付録 3:オイラーの公式と代数的補間式 について

と続きます・・・。

公開先

--- 【追記:2022-04-01】 ---

PDFファイルは以下のリンク先でも閲覧、ダウンロードできます。

f:id:sgtech:20220406024044p:plain

基礎線形代数講座20210615.pdf - Google ドライブ

--- 【追記ここまで】 ---

--- 【更新:2022-07-15】---

「基礎線形代数講座」は、開発技術部の技術資料一般公開先でもある、Speaker Deck サイトにて公開しています。

#技術資料一般公開先サイトを Speaker Deck に引っ越しました

--- 【更新ここまで】 ---

--- 各項目は以下のような内容となっています。

【第1講】イントロダクション

 【1-1】はじめに

 【1-2】数学導入:数の拡張

  [1-2-1] 自然数 ℕ:全てはここから

  [1-2-2] 整数 ℤ:0の発見、負の数の導入

  [1-2-3] 有理数 ℚ :分数・小数の導入

  [1-2-4] 実数 ℝ:無理数の導入

  [1-2-5] 複素数 ℂ:虚数の導入

  [1-2-6] まとめ

 【1-3】付録:ギリシャ文字一覧

【第2講】初等関数

 【2-1】はじめに

 【2-2】指数・対数関数

  [2-2-1] 指数関数の定義と性質

  [2-2-2] 対数関数の定義と性質

  [2-2-3] 自然対数と自然指数

  [2-2-4] 応用例

 【2-3】三角関数

  [2-3-1] 三角関数の定義と性質

  [2-3-2] 三角関数の主な公式

  [2-3-3] ド・モアブルの定理

  [2-3-4] 応用例

 【2-4】指数関数の別定義

 【2-5】[▼A] オイラーの公式

 【2-6】付録1:二項定理(二項展開)

 【2-7】付録2:総和記号

 【2-8】付録3:sinθ/θ→ 1 (θ→ 0) の証明

 【2-9】付録4:三角関数の各公式の証明

【第3講】ベクトル

 【3-1】はじめに

 【3-2】ベクトルがもつ性質

  [3-2-1] ベクトル自体がもつ性質

  [3-2-2] ベクトルの組がもつ性質

 【3-3】内積

  [3-3-1] 定義

  [3-3-2] 代数的性質

  [3-3-3] 幾何学的意味

 【3-4】抽象化されたベクトルの概念と例

 【3-5】外積

  [3-5-1] 定義

  [3-5-2] 代数的性質

  [3-5-3] 幾何学的意味

 【3-6】n本のベクトルが張るn次元体積

  [3-6-1] 2次元:2次元体積(面積)

  [3-6-2] 3次元:3次元体積(体積)

  [3-6-3] n次元:n次元体積

 【3-7】付録1:Levi-Civita記号

  [3-7-1] Levi-Civita記号 (3次の場合)

  [3-7-2] 拡張Levi-Civita記号 (n次の場合)

 【3-8】付録2:外積の公式の証明

 【3-9】付録3:置換と転倒数の偶奇性

【第4講】行列I:連立一次方程式

 【4-1】はじめに

 【4-2】掃き出し法

  [4-2-1] 連立一次方程式の加減法による解法

  [4-2-2] 掃き出し法と行基本変形

  [4-2-3] 不定解、解なしとなる場合

  [4-2-4] 連立一次方程式の違う見かた

 【4-3】行列式の導入

  [4-3-1] あらためて「関数」D(a,b,c) とは

  [4-3-2] 行列式の定義

  [4-3-3] 行列式の性質 I

 【4-4】行列の導入

  [4-3-1] 導入小話:もしかすると行列って・・・・

  [4-4-2] 行列と演算の定義

  [4-4-3] 行列の基本性質

  [4-4-4] 連立一次方程式の行列による表示

 【4-5】付録1:行列式の重要な性質

 【4-6】付録2:簡約行列の構造

 【4-7】付録3:補足説明

 【4-8】付録4:行列式の定義について

【第5講】行列II:線形変換

 【5-1】はじめに

 【5-2】線形変換(一次変換)

  [5-2-1] 線形変換の例

 【5-3】逆行列

  [5-3-1] 行列式の性質II:余因子展開と積の行列式

  [5-3-2] 逆行列の定義と余因子行列による表示

  [5-3-3] 正則行列/逆行列の性質

 【5-4】直交行列

  [5-4-1] 転置行列の性質

  [5-4-2] 直交行列の定義と性質

 【5-5】線形変換の行列による表示

  [5-5-1] この節のねらい

  [5-5-2] 必要な諸定義

  [5-5-2] ベクトルの列ベクトルによる表示

  [5-5-3] ベクトルの組の行列による表示

  [5-5-4] 線形変換の行列による表示

  [5-5-5] 基底の変換と座標変換

  [5-5-6] 線形変換に対する基底の変換と表示行列の変換

  [5-5-7] 線形変換と座標変換(ActiveとPassive)

  [5-5-8] 合成変換の行列による表示

 【5-6】[▼C]付録1:Levi-Civita記号の積の性質

 【5-7】付録2:複素数の行列による表現

【第6講】行列III:固有値・対角化

 【6-1】はじめに

 【6-2】固有ベクトルと固有値

  [6-2-1] 線形変換の点の「向きの流れ」

  [6-2-2] 固有ベクトル・固有値と固有方程式

 【6-3】行列の対角化

  [6-3-1] 線形独立な固有ベクトルへの基底の変換

  [6-3-2] 対角化可能な条件

  [6-3-3] 相似変換

  [6-3-4] 行列の三角化

  [6-3-5] 固有値の諸性質

 【6-4】実対称行列の対角化

  [6-4-1] 実対称行列の固有値・固有ベクトル

  [6-4-2] グラム・シュミットの正規直交化法

  [6-4-3] 実対称行列の対角化

  [6-4-4] 実二次形式

 【6-5】応用例

  [6-5-1] 剛体回転におけるオイラーの定理

  [6-5-2] 漸化式と特性方程式

  [6-5-3] [▼B] フーリエ級数展開

  [6-5-4] 行列指数関数

 【6-6】付録1:複素ベクトル空間・行列について

 【6-7】付録2:各証明

 【6-8】[▼A]付録3:オイラーの公式の行列表現

【第7講】回転の表現I

 【7-1】はじめに

 【7-2】回転行列

  [7-2-1] 考察の定式化

  [7-2-2] 表示行列としての回転行列

 【7-3】オイラー角と仲間たち

  [7-3-1] 回転後の基底の姿勢を3つの回転角で表す

  [7-3-2] オイラー角

  [7-3-3] Tait-Bryan角

  [7-3-4] ジンバルロック

 【7-4】回転ベクトル

  [7-4-1] 定義とロドリゲスの回転公式

  [7-4-2] 回転行列による表示

  [7-4-3] 回転行列の固有値・固有ベクトル

  [7-4-4] 3次元回転の大域的な構造

 【7-5】付録1:回転変換に関する2証明

 【7-6】[▼A,C]付録2:3次回転行列となる行列指数関数

【第8講】回転の表現II

 【8-1】はじめに

 【8-2】クォータニオンの導入:ハミルトン劇場

  [8-2-1] 拡張複素数で複素(3次元)空間を回したい

  [8-2-2] 4次元? マジか4次元??

 【8-3】クォータニオン:定義と諸性質

  [8-3-1] 定義

  [8-3-2] スカラー+ベクトル表記

  [8-3-3] ベクトル部の性質

  [8-3-4] ノルム・逆元と積の性質

  [8-3-5] 単位クォータニオンと極形式

  [8-3-6] 4次元ベクトルとしての内積

 【8-4】クォータニオン:3次元回転の表現

  [8-4-1] 任意軸まわりの回転

  [8-4-2] 3次元回転の合成

  [8-4-3] 回転行列による表示

  [8-4-4] 単位クォータニオンのパラメータ領域

  [8-4-5] 球面線形補間

 【8-5】[▼]付録1:一般的な4次元の回転について

 【8-6】付録2:成分表示における4次元内積の不変性について

 【8-7】[▼A]付録3:オイラーの公式と代数的補間式について

--- 

セガでは共に技術力を高め合い研鑽していける方を募集しています。 興味がある方は下記サイトにアクセスして下さい。

recruit.sega.jp

*1:あくまで筆者の想像(妄想)による過程であり、史実に基づいたものではありません。

*2:詳細は第5講 付録2参照

*3:くどいですが、筆者による想像(妄想)です

*4: $ 𝑖\times 𝑖𝑗=𝑖^2𝑗=−𝑗 $ ってこと

*5:運河を渡る橋に $ 𝑖^2=𝑗^2=𝑘^2=𝑖𝑗𝑘=−1 $ と刻んだとの事

*6:ちなみに 4次元では 2本の直交する基底で張られる (回転 )面を、基底を共有せずに 2面とることが できる( 3次元ではできない)。この場合 $ 1−𝑖 $平面 と $ 𝑗−𝑘 $平面 は原点のみで交わっている事に注意。

*7:ハミルトン卿ご自身は、この積の非可換性(当時初?)あまりお気に召さなかったらしい

アーケードゲームを支えるデバッグ術

ブログ読者のみなさん、はじめまして。
株式会社セガのベテランプログラマー阿部です。

このエントリーではデバッグ手法のあれこれについての体験談と、デバッグをテーマに一昨年に実施されたプログラマー向け新人研修の概要をお伝えしたいと思います。

EXE ファイルのデバッグ

同僚が作った EXE ファイルが手元にあり、あなたはこれを Windows で起動しようとしています。
起動してみたところ何も反応がなく、しかもそれは想定外のことでした。
「何コレ、動かないんだけど」とあなたが同僚に文句を伝えると、同僚はあなたに返します。
「こっちでは動いてるよ」

 

困りましたね。
あなたの手元には EXE のソースコードも無ければ、Visual Studio もありません。
こんな時、どうするのが正解でしょうか?

実はこんな状況でもやれる事がいくつかあるんです。
わたしなら プロセスのメモリダンプ を取って、同僚に渡します。

 


プロセスダンプがあれば、同僚はプログラムがどこまで進んだのかを Visual Studio で把握することができるようになるのです。
プロセスダンプの取得は ツール不要で Windows デスクトップから操作可能 なので、この方法は一番気軽に試せることでしょう。

 

f:id:sgtech:20201124210821p:plain

プロセスダンプの取得

あるいはその前に Sysinternals Suite に含まれる DebugView の出力を確認してみると、プログラムに埋め込まれた OutputDebugString() から 何らかの手掛かりが得られるかもしれません。
もし EXE ファイルと PDB ファイルが揃っていて 別の PC 開発環境があるなら、イーサネット経由でリモートデバッガをアタッチしても良いでしょう。
PDB ファイルが無いとしても 仮に EXE が .NET アセンブリなのであれば、ILSpy などの逆アセンブラーが使えるかもしれません。

 

こういう知識は「持っているかどうか」がとても重要 で、仕事の速いプログラマーほど よりたくさんの手段を自然と身に着けているような気がしています。
社内には SYS ファイル(デバイスドライバー)をデバッグできるプログラマーとかもいて、もうリスペクトしかないです。

イーサネット絡みのデバッグ

ネットワーク上のゲームサーバーと通信するクライアントプログラムを書いて、これをアーケードゲーム機で起動させたとします。
ゲームサーバーとの通信が「たまに成功しないことがある」という場合は、どうデバッグしたら良いのでしようか?

近年のアーケードゲーム機は PC アーキテクチャーをベースに設計されることも多く、セガでも Windows を搭載した機種が多数リリースされています。
コピーガードやリバースエンジニアリング防止を目的として、多くのアーケードゲーム機ではデスクトップ画面を開くことはできず、ネットワーク経由でのログインやプロセスへのアタッチもできません(外界からは ロックダウン されています)。

 

「たまに失敗」という場合は、ソースコードレビューで判明するバグがあるとは考えにくいです。
そこでわたしなら、 イーサネットを流れるイーサフレームを Wireshark でパケットキャプチャーする ことから始めてみます。

 

f:id:sgtech:20201124210834p:plain

フレームの測定


イーサネットを観測することで、最初にまず以下を見極められると期待しています。

  • ケース1: 想定通りにパケットが流れていない(送信失敗)
  • ケース2: 想定外のパケットが流れている
  • ケース3: 想定通りのパケットが流れている(送信成功)

その結果、クライアントのコードが悪いのか、OS 側スタックのネットワーク設定が悪いのか、上流のネットワークが悪いのかを絞り込める、という算段です。

 

f:id:sgtech:20201124210838p:plain

問題を切り分ける


なお 「上流のネットワークが悪い」という結果だった場合は、キャプチャーの測定範囲を変更して 問題の機器を特定 していきます。
過去には、全国ゲームセンターにあるルーターが原因ということもありました。

ルーターが IP パケットのチェックサムを再計算するときに、特定条件下で計算ミスが起こるため、
ルーターのさらに上位にあるネットワーク機器でパケットがドロップされていた

というもので、本来ならばルーターファームウェアを修正し更新版を配信することになります。

 

通信エラーだけではありません。
TCP 通信において 「スループットが足りない」という場合、ここでもパケットキャプチャーから始めるのは良い選択の1つ です。
測定結果から、次に挙げるような点検箇所がいくつか見つかることでしょう。

  • SYN パケットに時間が掛かっている
    → コネクションプールを導入するか、セッションクローズしないプロトコルを採用する
  • リクエストからレスポンスまでの間隔が圧倒的に長い
    → サーバー処理でスワップアウトやスロークエリが発生していないか確認する

周辺機器絡みのデバッグ

広く使われている キャラクター表示器 は、シリアルポートから送信されたアスキー文字や SJIS をドットマトリクスとして表示してくれます。

 

f:id:sgtech:20201124210830p:plain

キャラクター表示器(VFD)

ある日「キャラクター表示器の表示がおかしい」という報告をもらって現地確認に行くと、見慣れない文字列が確かに表示されていました。
プログラムから制御しているというのに、 プログラム内に存在しない文字列が表示されてしまうのはおかしい ですね。
この表示器を含めて、多くは RS232C という低速でレガシーなシリアルポートを使って接続しています。
RS232C 通信は物理層での冗長性に乏しいため、ひょっとすると外的要因でポートに電気的なノイズが乗ってしまい、パケットが化けてしまったのかもしれません。

 

ということで早速 RS232C を測定しました。
RS232C の測定には ロジックアナライザーという測定機器を使います 。
RS232C 接続を構成するラインをプローブすれば、各ラインの Hi/Lo をタイミングチャートとして確認できるようになります。

 

f:id:sgtech:20201124210826p:plain

研修で使用した ZEROPLUS 製 ロジックアナライザー

f:id:sgtech:20201124210842p:plain

測定結果のタイミングチャート

実際測定してみると、タイミングチャート上はプログラムからの出力がそのまま反映されており、異常な部分は見つかりませんでした(結局その後の調査で 別の原因が見付かりました)。

 

同じ手法は USB 機器にも使えます。
USB 機器の場合は USB 対応のプロトコルアナライザーを導入することもできます(実は USBPcap + Wireshark という別の選択肢もあります)。

ゲームセンターに設置されるアーケードゲームは、ゲームパッドに縛られない、多彩なユーザーインターフェースが特徴の1つになっています。
さらにユーザーインターフェースだけでなく、キャビネット上の電飾や可動部のモーターなど さまざまな周辺機器がつながっており、それらをすべてプログラムで制御しています。
そういった周辺機器としては、既製品を採用することもあれば、新規に設計することもあります。
ここにもデバッグの機会が大いにあります。

デバッグスキルブートキャンプ

ここまでいくつか紹介したように、「プログラムのデバッグに使えるもの」にはツール(ソフトウェア)だけでなく、測定機器(ハードウェア)も重要な一端を担っていることが理解いただけたかと思います。
また大学や専門学校などで 「プログラミングをマスターする機会」はあっても、「デバッグをマスターする機会」は無いのが実情 です。

わたしが所属する技術本部では、これらの背景を踏まえてプログラマー向け新人研修が実施されました。
デバッグスキルにフォーカスしたハンズオン研修、題して「デバッグスキルブートキャンプ」です。

学生時代に触れる機会が少ないであろう測定機器にも触れながら バグを正しく観測する技術 を習得し、 printf デバッグ だけでは決して成し得ない、バグの根本原因に辿り着く 貴重な体験を重視としたカリキュラム になっています。

 

開催形態は以下の通り。
他の新人研修とは異なり、新人プログラマーが実務に少し馴染んだ年末年始に開催されています。

  • ハンズオン重視: 当日フラっとやってきて学べればよい
  • 予習・宿題は原則ナシ: 「座学 20min、ハンズオン 75min」とか「座学 10min、ハンズオン 45min」とか
  • 開催時期はプロジェクト配属後6か月後から
  • 開催ペースは毎週1回、計9回(9ネタ)ほど

 

本来なら社内に広く展開して必修化した方が社員みんなの為になるのですが、測定機材の都合もあって一部組織内での開催にとどまっているのが現状のようです。
各回資料は社内公開されていますが、そのうち一冊の本に体系化されたらイイなと密かに期待しています。


f:id:sgtech:20201124210850j:plainf:id:sgtech:20201124210854j:plain

f:id:sgtech:20201124210845j:plain

 

黒子に徹する、裏方系エンジニア

デバッグの世界とデバッグスキルブートキャンプについて紹介しました。
最後にわたしが所属する技術本部について紹介します。

技術本部にはいろいろなキャリアの開発者が在籍しており、 ゲーム体験・感動体験を下支えする何か を日々開発しています。
わたし自身を例に挙げると 以下のような感じです。

  • ゲームを開発するためのライブラリを作ったり
  • コンバーターとか自動化ツールを作ったり
  • Windows Embedded を使いこなして、アーケードゲーム機向けの OS をビルドしたり
  • 開発者向けグループウェアを管理したり

近隣のデスクには ちょっと違う種類の仕事をしている人がいますね。

  • データベースとか VM をいじる人
  • 基板回路を設計する人
  • Maya 上のメッシュモデルをあれこれする人
  • ルーターとか「目新しいユーザーインターフェースデバイス」をいじめる人(w)など

千人規模の社内開発者を支える技術本部にはいろいろな仕事があって、それぞれに奥が深そうです。
そして ゲーム自体のおもしろさを追求するのとは違った立ち位置で、ゲーム周辺にある様々な問題を解決 しています。

 

わたしもゲーム開発を後押しする裏方系エンジニアに転身したことで、結果的にはいろいろなテクノロジースキルを身に着けることができました。
「開発したゲームで世界をあっと言わせる!」という部分に自信を持てなくても、「技術のことなら何でも任せて!」という自信に満ちたプログラマー/ソフトウェアエンジニアなら、セガでキャリアを積むのも悪くないと思いますよ。

ということで、現場で成長をつづけながら「縁の下の力持ち」として共に働ける仲間を求めています。

 

recruit.sega.jp


-----

©SEGA
記載されている会社名、製品名は、各社の登録商標または商標です。

 

Powered by はてなブログ