scipy.spatial.transform.Rotationとは#
scipy.spatial.transform.Rotationは、SciPy公式ライブラリに含まれる3D回転を扱うためのクラスです。クォータニオン、回転行列、Euler角など複数の回転表現形式を相互変換できます。
基本情報#
- パッケージ: SciPy(Scientific Python)
- ライセンス: BSD-3-Clause
- Evidence Level: L1(公式API)
- 公式ドキュメント: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.html
対応する回転表現形式#
- クォータニオン(Quaternion)
- 回転行列(Rotation Matrix)
- Euler角(Euler Angles)
- 回転ベクトル(Rotation Vector)
- 修正ロドリゲスパラメータ(Modified Rodrigues Parameters)
- Davenport角(Davenport Angles)
主要メソッド#
初期化メソッド#
| メソッド | 説明 | 使用例 |
|---|---|---|
from_euler() | Euler角から初期化 | R.from_euler('ZYX', [yaw, pitch, roll]) |
from_quat() | クォータニオンから初期化 | R.from_quat([x, y, z, w]) |
from_matrix() | 回転行列から初期化 | R.from_matrix(rotation_matrix) |
from_rotvec() | 回転ベクトルから初期化 | R.from_rotvec([rx, ry, rz]) |
変換メソッド#
| メソッド | 説明 | 使用例 |
|---|---|---|
as_euler() | Euler角に変換 | rotation.as_euler('ZYX') |
as_quat() | クォータニオンに変換 | rotation.as_quat() |
as_matrix() | 回転行列に変換 | rotation.as_matrix() |
as_rotvec() | 回転ベクトルに変換 | rotation.as_rotvec() |
Intrinsic vs Extrinsic回転(⭐重要)#
scipy.rotationでは、大文字と小文字の軸指定でIntrinsic/Extrinsic回転を区別します。
Intrinsic回転(大文字 ‘ZYX’)#
機体に固定された座標系で回転を適用(Body-centered rotations)。
from scipy.spatial.transform import Rotation as R
# Intrinsic rotations(大文字)
r_intrinsic = R.from_euler('ZYX', [90, -30, 0], degrees=True)航空機姿勢ではIntrinsic回転を使用します。
Extrinsic回転(小文字 ‘zyx’)#
固定された外部座標系で回転を適用(Global frame rotations)。
# Extrinsic rotations(小文字)
r_extrinsic = R.from_euler('zyx', [90, -30, 0], degrees=True)使い分け#
| 用途 | 使用する回転 | 軸指定 |
|---|---|---|
| 航空機姿勢 | Intrinsic | ‘ZYX’(大文字) |
| カメラ回転 | Intrinsic | ‘ZYX’(大文字) |
| ワールド座標系での回転 | Extrinsic | ‘zyx’(小文字) |
航空機姿勢への適用方法#
3-2-1 Euler角(Yaw-Pitch-Roll)の変換#
JSBSimやFlightGearでは3-2-1 sequence (Z-Y-X) を使用します。
Euler角 → クォータニオン:
from scipy.spatial.transform import Rotation as R
import numpy as np
# 姿勢角(ラジアン)
yaw = np.deg2rad(10.0) # Z軸周り(ヨー)
pitch = np.deg2rad(5.0) # Y軸周り(ピッチ)
roll = np.deg2rad(2.0) # X軸周り(ロール)
# Intrinsic回転(大文字 'ZYX')で変換
rotation = R.from_euler('ZYX', [yaw, pitch, roll], degrees=False)
# クォータニオン取得(x, y, z, w)
quat = rotation.as_quat()
print(f"クォータニオン: {quat}")クォータニオン → Euler角:
# クォータニオンから初期化
rotation = R.from_quat([0.0175, 0.0437, 0.0873, 0.9951])
# Euler角に変換(Intrinsic 'ZYX')
euler_angles = rotation.as_euler('ZYX', degrees=True)
yaw, pitch, roll = euler_angles
print(f"Yaw: {yaw:.2f}°, Pitch: {pitch:.2f}°, Roll: {roll:.2f}°")実践例: JSBSim出力データの姿勢変換#
JSBSim姿勢データ → 回転行列#
from scipy.spatial.transform import Rotation as R
import numpy as np
# JSBSimから取得した姿勢角(ラジアン)
jsbsim_phi = 0.05 # Roll
jsbsim_theta = 0.1 # Pitch
jsbsim_psi = 0.2 # Yaw
# Intrinsic 'ZYX'で回転行列を生成
rotation = R.from_euler('ZYX', [jsbsim_psi, jsbsim_theta, jsbsim_phi], degrees=False)
# Body → NED 回転行列
Tb2l = rotation.as_matrix()
print("Body → NED回転行列:\n", Tb2l)ベクトルの回転適用#
# Body座標系のベクトル(機首方向)
body_vector = np.array([1.0, 0.0, 0.0])
# NED座標系に変換
ned_vector = rotation.apply(body_vector)
print(f"NED座標系: {ned_vector}")バッチ処理(複数姿勢の一括変換)#
scipy.rotationは複数の回転を一度に処理できます。
from scipy.spatial.transform import Rotation as R
import numpy as np
# 時系列データ(10サンプル)
num_samples = 10
yaw_series = np.linspace(0, 90, num_samples)
pitch_series = np.linspace(0, 10, num_samples)
roll_series = np.linspace(0, 5, num_samples)
# バッチ変換
euler_series = np.column_stack([yaw_series, pitch_series, roll_series])
rotations = R.from_euler('ZYX', euler_series, degrees=True)
# 全サンプルのクォータニオン取得
quaternions = rotations.as_quat()
print(f"クォータニオン配列形状: {quaternions.shape}") # (10, 4)回転の合成と逆変換#
回転の合成#
from scipy.spatial.transform import Rotation as R
# 2つの回転
r1 = R.from_euler('Z', 45, degrees=True) # Z軸周り45度
r2 = R.from_euler('Y', 30, degrees=True) # Y軸周り30度
# 合成(r1の後にr2を適用)
r_combined = r2 * r1
# Euler角確認
print("合成回転:", r_combined.as_euler('ZYX', degrees=True))逆変換#
# 回転の逆
r_inv = rotation.inv()
# 元のベクトルに戻す
original_vector = r_inv.apply(ned_vector)
print(f"元のベクトル: {original_vector}")JSBSimとの連携#
FGQuaternionとの比較#
| 項目 | JSBSim (FGQuaternion) | scipy.rotation |
|---|---|---|
| クォータニオン順序 | (w, x, y, z) | (x, y, z, w) |
| Euler角順序 | 3-2-1 (Z-Y-X) | ‘ZYX’(Intrinsic) |
| 回転方向 | 右手系 | 右手系 |
注意: scipy.rotationのクォータニオンは[x, y, z, w]順序ですが、JSBSimは[w, x, y, z]順序です。
変換例#
# JSBSimクォータニオン (w, x, y, z)
jsbsim_quat = [0.9951, 0.0175, 0.0437, 0.0873]
# scipy.rotation形式に変換 (x, y, z, w)
scipy_quat = [jsbsim_quat[1], jsbsim_quat[2], jsbsim_quat[3], jsbsim_quat[0]]
# Rotationオブジェクト生成
rotation = R.from_quat(scipy_quat)まとめ#
scipy.spatial.transform.Rotationは、航空機姿勢変換に必須のPythonライブラリです。
主要機能:
- Euler角、クォータニオン、回転行列の相互変換
- Intrinsic/Extrinsic回転の区別(大文字/小文字)
- バッチ処理対応
航空機姿勢での注意点:
- Intrinsic回転(大文字 ‘ZYX’)を使用
- クォータニオン順序は
[x, y, z, w](JSBSimと異なる) - JSBSimの3-2-1 sequenceに対応
活用例:
- JSBSim出力データの姿勢変換
- FlightGear連携時の座標系変換
- 時系列姿勢データの一括処理
関連リソース#
公式ドキュメント#
scipy.spatial.transform.Rotation
- URL: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.html
- License: BSD-3-Clause
- Evidence Level: L1(公式API)
- アクセス日: 2025-10-27
from_euler メソッド
- URL: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.from_euler.html
- Evidence Level: L1(公式API)
as_euler メソッド
- URL: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.as_euler.html
- Evidence Level: L1(公式API)
関連記事#
- JSBSim座標系理解のための公式リソースガイド - 23件のドキュメント紹介(記事B-3)
- 航空宇宙座標系の業界標準 - AIAA, Stevens & Lewis, NASAの資料紹介(記事B-4)
© 2025 Yaaasoh. All Rights Reserved.