JSBSimでシミュレーションを実行する際、「座標系が合わない」「位置データが正しく取得できない」といったトラブルに遭遇することがあります。これらの多くは座標系の混同が原因です。

本記事では、JSBSimで使用する4つの座標系と、その使い分けを解説します。

この記事で学べること#

  • JSBSimの4つの座標系(緯度経度系、NED系、Body系、ECEF系)
  • 各座標系の特徴とプロパティ
  • 座標系の使い分けガイドライン
  • デカルト座標系の罠(distance-from-start-*の落とし穴)

対象読者#

  • JSBSimで位置・速度データを扱う方
  • 座標系混同でトラブルに遭遇した方
  • 模型航空機シミュレーションを行う方

JSBSimの4つの座標系#

JSBSimは、用途に応じて4つの座標系を提供しています。

1. 緯度経度系(Geodetic Coordinate System)#

定義: 地球表面上の位置を緯度・経度・高度で表す座標系

主要プロパティ:

プロパティ 説明 単位
position/lat-geod-deg 測地緯度 deg
position/long-gc-deg 地心経度 deg
position/altitude-ft 海面上高度(MSL) ft
position/h-agl-ft 対地高度(AGL) ft

特徴:

  • グローバルな位置表現に最適
  • 地球の曲率を考慮
  • FlightGearとの位置データ交換に使用

使用例:

  • 長距離飛行(数km以上)
  • GPS座標の扱い
  • FlightGearでの可視化

2. NED系(North-East-Down Coordinate System)#

定義: 機体の初期位置を原点とし、北・東・下方向を軸とする座標系

主要プロパティ:

プロパティ 説明 単位
velocities/v-north-fps 北方向速度 ft/s
velocities/v-east-fps 東方向速度 ft/s
velocities/v-down-fps 下方向速度 ft/s

特徴:

  • 慣性座標系(機体の姿勢変化に影響されない)
  • 速度を積分することでデカルト座標(X-Y-Z)を計算可能
  • 模型航空機シミュレーション(数十m移動)に最適

使用例:

  • 飛行経路の可視化(2D/3D)
  • 距離計算
  • 台形則積分でデカルト座標を算出

積分例(Pythonで実装):

# NED速度を台形則積分してデカルト座標を計算
x_north = 0.0
x_east = 0.0
x_down = 0.0

for i in range(1, len(time)):
    dt = time[i] - time[i-1]
    x_north += (v_north[i] + v_north[i-1]) / 2.0 * dt
    x_east += (v_east[i] + v_east[i-1]) / 2.0 * dt
    x_down += (v_down[i] + v_down[i-1]) / 2.0 * dt

3. Body系(Body-Fixed Coordinate System)#

定義: 機体に固定された座標系。機体の前方・右方・下方を軸とする

主要プロパティ:

プロパティ 説明 単位
velocities/u-fps 機体X軸方向速度(前方) ft/s
velocities/v-fps 機体Y軸方向速度(右方) ft/s
velocities/w-fps 機体Z軸方向速度(下方) ft/s
velocities/p-rad_sec ロールレート rad/s
velocities/q-rad_sec ピッチレート rad/s
velocities/r-rad_sec ヨーレート rad/s

特徴:

  • 機体中心の座標系
  • 姿勢制御・空力計算に使用
  • 迎角・横滑り角の算出に必要

使用例:

  • 姿勢制御ロジック
  • オートパイロット設計
  • 空力解析

迎角・横滑り角の計算:

import math

# Body系速度から迎角・横滑り角を計算
alpha = math.atan2(w, u)  # 迎角(rad)
beta = math.asin(v / math.sqrt(u**2 + v**2 + w**2))  # 横滑り角(rad)

4. ECEF系(Earth-Centered Earth-Fixed Coordinate System)#

定義: 地球の中心を原点とする慣性座標系

特徴:

  • 高度な用途(衛星軌道計算等)
  • JSBSimの内部計算で使用
  • 通常のユーザーは直接使用しない

使用例:

  • 地球規模の長距離飛行
  • 衛星シミュレーション

座標系の使い分けガイドライン#

用途別の推奨座標系#

用途 推奨座標系 理由
模型航空機(数十m移動) NED系 デカルト座標が簡単に計算可能
長距離飛行(数km以上) 緯度経度系 地球の曲率を考慮
姿勢制御・オートパイロット Body系 機体中心の制御が容易
FlightGear可視化 緯度経度系 FlightGearとの互換性

シナリオ例#

シナリオ1: 200g級RC機の飛行経路可視化

  • 座標系: NED系
  • プロパティ: velocities/v-north-fps, v-east-fps, v-down-fps
  • 処理: 台形則積分でデカルト座標(X-Y-Z)を計算
  • 理由: 移動距離が数十mと短く、地球の曲率を無視できる

シナリオ2: 長距離飛行(東京→大阪)

  • 座標系: 緯度経度系
  • プロパティ: position/lat-geod-deg, long-gc-deg, altitude-ft
  • 理由: 地球の曲率を考慮する必要がある

シナリオ3: ピッチ角制御

  • 座標系: Body系
  • プロパティ: velocities/u-fps, w-fps, attitude/theta-rad
  • 処理: 迎角計算、ピッチレート制御
  • 理由: 機体中心の座標系が制御に適している

デカルト座標系の罠:distance-from-start-*の落とし穴#

⚠️ 重要な注意事項#

JSBSimの古いフォーラム投稿やドキュメントで、以下のプロパティが紹介されていることがあります:

position/distance-from-start-mag-mt
position/distance-from-start-lat-mt
position/distance-from-start-lon-mt

これらのプロパティは存在しません(未実装)。

検証方法#

JSBSimのソースコード[@jsbsim_github_main_2025]のFGPropagate.cppを確認すると、これらのプロパティは定義されていません。

正しい代替手法#

デカルト座標(X-Y-Z)が必要な場合は、NED系速度を台形則積分してください:

def integrate_ned_velocity(time, v_north, v_east, v_down):
    """NED速度を台形則積分してデカルト座標を計算"""
    x_north = [0.0]
    x_east = [0.0]
    x_down = [0.0]

    for i in range(1, len(time)):
        dt = time[i] - time[i-1]
        x_north.append(x_north[-1] + (v_north[i] + v_north[i-1]) / 2.0 * dt)
        x_east.append(x_east[-1] + (v_east[i] + v_east[i-1]) / 2.0 * dt)
        x_down.append(x_down[-1] + (v_down[i] + v_down[i-1]) / 2.0 * dt)

    return x_north, x_east, x_down

座標変換#

座標系間の変換が必要な場合もあります。

Body系 → NED系#

import numpy as np

def body_to_ned(u, v, w, phi, theta, psi):
    """Body系速度をNED系に変換"""
    # 回転行列(Euler角による座標変換)
    R = np.array([
        [np.cos(theta)*np.cos(psi),
         np.sin(phi)*np.sin(theta)*np.cos(psi) - np.cos(phi)*np.sin(psi),
         np.cos(phi)*np.sin(theta)*np.cos(psi) + np.sin(phi)*np.sin(psi)],
        [np.cos(theta)*np.sin(psi),
         np.sin(phi)*np.sin(theta)*np.sin(psi) + np.cos(phi)*np.cos(psi),
         np.cos(phi)*np.sin(theta)*np.sin(psi) - np.sin(phi)*np.cos(psi)],
        [-np.sin(theta),
         np.sin(phi)*np.cos(theta),
         np.cos(phi)*np.cos(theta)]
    ])

    body_velocity = np.array([u, v, w])
    ned_velocity = R @ body_velocity

    return ned_velocity[0], ned_velocity[1], ned_velocity[2]

まとめ#

  1. JSBSimは4つの座標系を提供(緯度経度系、NED系、Body系、ECEF系)
  2. 用途に応じて適切な座標系を選択
    • 模型航空機: NED系(デカルト座標計算が容易)
    • 長距離飛行: 緯度経度系(地球の曲率を考慮)
    • 姿勢制御: Body系(機体中心の座標系)
  3. *distance-from-start-プロパティは存在しない(未実装)
  4. デカルト座標はNED系速度を台形則積分して算出

次のステップ:


参照資料#

本記事の執筆にあたり、以下の資料を参照しました [@jsbsim_refman_2024; @jsbsim_github_main_2025]。


関連記事#


© 2025 Yaaasoh. All Rights Reserved.