問題概要#
External Reactionsを使用して推力を定義した機体で、JSBSim組み込みのトリム計算機能(FGTrim)が失敗します。トリム計算が収束せず、安定した飛行状態を得ることができません。
原因#
JSBSim組み込みのFGTrim機能は、エンジン/プロペラ推進系を前提として設計されています。External Reactionsは外部力として扱われ、FGTrimの制御変数として認識されません。
詳細な原因#
- FGTrimの前提: スロットル(
fcs/throttle-cmd-norm)を調整してトリムを探索 - External Reactionsの仕組み: 外部力として直接作用、スロットル制御に応答しない
- 制御ループの不整合: FGTrimがスロットルを変更しても、External Reactionsの推力は変化しない
この問題はJSBSim公式Issue #1010で既知の制限として記録されています。
なぜExternal Reactionsを使用するのか#
External Reactionsは以下の理由で使用されます:
- 簡易的な推力モデル: エンジン/プロペラの詳細モデルが不要
- 開発初期段階: 概算推力で素早くシミュレーション開始
- 特殊な推進系: 電動モーター、ロケット等の簡易モデル化
解決方法#
回避策: 手動トリム探索の実装#
FGTrimの代わりに、scipy.optimizeを使用した最適化ベースのトリム探索を実装します。
実装例:
from scipy.optimize import minimize
import jsbsim
def trim_objective(x, fdm, target_speed_kts):
"""
トリム目的関数
Args:
x: [throttle, elevator_deg]
fdm: JSBSim FGFDMExec instance
target_speed_kts: 目標速度 (knots)
Returns:
トリム誤差(0に近いほど良い)
"""
throttle, elevator_deg = x
# 制御入力を設定
fdm['fcs/throttle-cmd-norm'] = throttle
fdm['fcs/elevator-cmd-norm'] = elevator_deg / 20.0 # ±20°正規化
# シミュレーション実行
fdm.run()
# 加速度を取得(トリム状態では0になるべき)
udot = fdm['accelerations/udot-ft_sec2'] # 前方加速度
wdot = fdm['accelerations/wdot-ft_sec2'] # 垂直加速度
qdot = fdm['accelerations/qdot-rad_sec2'] # ピッチ角速度
hdot = fdm['velocities/h-dot-fps'] # 上昇率
# 目的関数: 加速度と上昇率の二乗和を最小化
return udot**2 + wdot**2 + (qdot*10)**2 + (hdot*5)**2
# トリム探索実行
fdm = jsbsim.FGFDMExec('.')
fdm.load_model('RC_UAV_200g')
fdm.run_ic()
result = minimize(
trim_objective,
x0=[0.2, -2.0], # 初期値: スロットル20%, エレベーター-2°
args=(fdm, 20.0), # 目標速度20knots
method='Nelder-Mead', # 最適化手法
options={'maxiter': 100}
)
print(f"トリム解: スロットル={result.x[0]:.3f}, エレベーター={result.x[1]:.2f}°")重み付けの調整#
目的関数の重み(qdot*10, hdot*5)は、機体特性に応じて調整します:
- ピッチ安定性重視:
qdotの重みを大きく(例:*20) - 高度維持重視:
hdotの重みを大きく(例:*10) - 速度安定性重視:
udotの重みを大きく(例:*2)
予防策#
1. プロジェクト初期段階から手動トリム探索を計画#
External Reactionsを使用する場合は、プロジェクト初期段階から手動トリム探索実装を計画に含めます。
計画例:
- Phase 1: External Reactionsで簡易推力モデル作成
- Phase 2: 手動トリム探索実装(scipy.optimize使用)
- Phase 3: トリム解を初期条件として設定
2. FGTrim依存の設計を避ける#
External Reactionsを使用する場合、FGTrimに依存した設計を避けます。
避けるべき設計:
- ❌ FGTrimで自動的にトリム解を得る前提
- ❌ FGTrimの結果をそのまま初期条件に使用
- ❌ FGTrimエラーを無視して進行
推奨設計:
- ✅ 手動トリム探索を標準ワークフローに組み込む
- ✅ トリム解をファイルに保存して再利用
- ✅ トリム状態の検証機能を実装
3. 機体XML生成ツールに警告を追加#
機体XML生成ツールでExternal Reactions使用時の警告を表示します。
警告例:
警告: External Reactionsを使用しています。
JSBSim組み込みのFGTrim機能は使用できません。
手動トリム探索を実装してください。
参考: docs/manual_trim_search.mdまとめ#
FGTrimがExternal Reactionsで動作しない問題は、JSBSim公式の既知の制限です。
原因:
- FGTrimはエンジン/プロペラ推進系を前提
- External Reactionsはスロットル制御に応答しない
- JSBSim Issue #1010で記録済み
解決策:
- scipy.optimizeを使用した手動トリム探索
- 加速度・上昇率の二乗和を最小化
- 重み付けを機体特性に応じて調整
予防策:
- プロジェクト初期段階から手動トリム探索を計画
- FGTrim依存の設計を避ける
- XML生成ツールに警告を追加
External Reactionsの利点(簡易性、開発速度)を活かしつつ、手動トリム探索で正確なトリム解を得ることができます。
関連記事#
- 【トラブル備忘】JSBSimトリム計算が収束しない - Cmalpha符号ミスの罠(記事E-2)
- 【トラブル備忘】トリム計算失敗 - CD0過大による推力不足(記事E-6)
© 2025 Yaaasoh. All Rights Reserved.