OpenVSPのPythonAPIで作成済みのモデルの舵角を設定してαスイープの計算を行う
はじめに
OpenVSPのPythonAPIで作成済みのモデルの舵角を設定してαスイープの計算を行う
↓参考にしたサンプルプログラム(PythonではなくAngelScriptで書かれている)
↓まとめ記事
ソースコードの解説
ソースコード全文はこれ
import openvsp as vsp
def MyFindParm(cs_group_container_id, parm_name):
# Find param_id from cs_group_container_id and parm_name
parm_ids = vsp.FindContainerParmIDs( cs_group_container_id )
for parm_id in parm_ids:
if parm_name == vsp.GetParmName(parm_id):
return parm_id
return ''
def set_control_surface(geom_name, deflection, cs_group_name, sub_id=0, gains=(1,1)):
# Set control surface group
group_index = vsp.CreateVSPAEROControlSurfaceGroup()
group_name = 'ControlSurfaceGroup_' + str(group_index)
vsp.SetVSPAEROControlGroupName(cs_group_name, group_index)
# Add subsurface to control surface group
cs_name_vec = vsp.GetAvailableCSNameVec(group_index)
selcted = [1 + i for i, cs_name in enumerate(cs_name_vec) if geom_name in cs_name]
vsp.AddSelectedToCSGroup(selcted, group_index)
# Set gain (deferential)
print('\n', cs_group_name, ':', vsp.GetActiveCSNameVec(group_index))
print('\t', f"{'container_id':14s}", f"{'parm_name':24s}", f"{'group_name':22s}", f"{'parm_id':14s}", f"{'value':8s}")
geom_id = vsp.FindGeomsWithName(geom_name)[0]
cs_group_container_id = vsp.FindContainer('VSPAEROSettings', 0)
for i, gain in enumerate(gains):
parm_name = 'Surf_' + vsp.GetSubSurf(geom_id, sub_id) + '_' + str(i) + '_Gain'
parm_id = MyFindParm(cs_group_container_id, parm_name)
# parm_id = vsp.FindParm(cs_group_container_id, parm_name, group_name) # なぜか反応しない...
if parm_id != '':
vsp.SetParmVal(parm_id, gain)
print('\t', f'{cs_group_container_id:14s}', f'{parm_name:24s}', f'{group_name:22s}', f'{parm_id:14s}', f'{gain:8.3f}')
else:
print('\t', 'Failed to find ' + parm_name)
# Set defrection angle
parm_name = 'DeflectionAngle'
parm_id = vsp.FindParm(cs_group_container_id, parm_name, group_name)
vsp.SetParmVal(parm_id, deflection)
# Check if deflection angle successfully applied
if deflection == vsp.GetParmVal(parm_id):
print('\t', f'{cs_group_container_id:14s}', f'{parm_name:24s}', f'{group_name:22s}', f'{parm_id:14s}', f'{deflection:8.3f}')
else:
print('Failed to set deflection angle')
exit()
return parm_id
使い方のサンプル
import sys
import os
import numpy as np
# ../bin/AnalysisVSPAERO.py をモジュールとしてインポート
sys.path.append(os.path.join('..')) # 親ディレクトリをモジュール探索パスに追加
from bin.AnalysisVSPAERO import *
import openvsp as vsp
if __name__=='__main__':
vsp.ClearVSPModel()
vsp.Update()
vsp.ReadVSPFile('G103A.vsp3')
vsp.Update()
set_control_surface(geom_name='WingGeom', deflection=-10, cs_group_name='AILERON_GROUP', gains=(-1,-1))
set_control_surface(geom_name='HTailGeom', deflection=0, cs_group_name='Elevator_Group', gains=(1,-1))
set_control_surface(geom_name='VTailGeom', deflection=0, cs_group_name='Rudder_Group')
vsp.Update()
alpha = np.linspace(-4, 12, 9)
mach = [0.1]
vsp_sweep(vsp=vsp, alpha=alpha, mach=mach)
解説していく
準備するもの
今回はGUIで作成したモデルを用いて、VSPAEROによる解析の部分だけをプログラムにする
GUIにおけるモデリングのやり方もいつか記事にはしたいと思っている
全体の流れ
全体の流れは以下の通り
この記事では「舵面の設定」について詳しく説明する
↓「モデルの初期化と読み込み」「VSPAEROのスイープ解析の実行」についてはこちら
舵面の設定
舵面の設定は、以下の自作関数で行う
def set_control_surface(geom_name, deflection, cs_group_name, gains=(1,1), sub_id=0):
(略)
return parm_id
引数geom_name
:設定したい舵面を有するジオメトリの名前 [str]deflection
:舵角 (deg) [float]cs_group_name
:Control Surface Groupの名前 [str]gains
:舵面のゲイン (右舷後縁下げ正、左舷後縁上げ正)[tuple of float]sub_id
:1つのジオメトリに複数のSubsurfaceがあるときに使うインデックス [int]
返値parm_id
:舵角のパラメータID [str]
Control Surface Groupの作成
# Set control surface group
group_index = vsp.CreateVSPAEROControlSurfaceGroup()
vsp.SetVSPAEROControlGroupName(cs_group_name, group_index)
まず、新しいControl Surface Groupを追加し、名前を設定する
↓GUIでいうところの「User Groups > Add」をして「Group Name」を編集する操作
↓メソッドの詳細
group_index = vsp.CreateVSPAEROControlSurfaceGroup()
新しいVSPAERO Control Surface Groupを、デフォルトの命名規則を使って追加する関数
返値group_index
:新しいVSPAERO Control Surface Groupのインデックス [int]
vsp.SetVSPAEROControlGroupName(cs_group_name, group_index)
指定されたインデックスのControl Surface Groupの名前を設定する関数
引数cs_group_name
:Control Surface Groupに設定する名前 [str]group_index
:Control Surface Groupのインデックス [int]
SubsurfaceをControl Surface Groupに追加
# Add subsurface to control surface group
cs_name_vec = vsp.GetAvailableCSNameVec(group_index)
selcted = [1 + i for i, cs_name in enumerate(cs_name_vec) if geom_name in cs_name]
vsp.AddSelectedToCSGroup(selcted, group_index)
ここでは、Control Surface Groupに追加可能な全てのサブサーフェスのリストを取得し、指定のジオメトリにあるサブサーフェスのみを抽出してControl Surface Groupに追加する
↓GUIでいうところの「Available Control Surfaces」で選択したControl Surfaceを「Add Selected」する操作
↓メソッドの詳細
cs_name_vec = vsp.GetAvailableCSNameVec(group_index)
Control Surface Group内の、指定したインデックスで使用可能な(使用されていない)Control Surfaceの名前を取得する関数
引数group_index
:Control Surface Groupのインデックス [int]
返値cs_name_vec
:アクティブなControl Surfaceの名前の配列 [array of str]
↓GUIでいうところの「Available Control Surfaces」にある文字列がリストで取得できる
vsp.AddSelectedToCSGroup(selcted, group_index)
GetAvailableCSNameVec()の配列内の指定したインデックスのControl Surfaceを、指定したインデックスのControl Surface Groupに追加する関数
引数selcted
:グループに追加するControl Surfaceのインデックスを指定する配列(配列のインデックスは1始まり)[array of int]group_index
:Control Surface Groupのインデックス [int]
例えば、上記の画像において「WingGeom_Surf0_AILERON」「WingGeom_Surf1_AILERON」を追加したい場合には、引数として[1, 2]
を与える(配列は1始まりのため)
Control Surfaceのゲインを設定
# Set gain (deferential)
print('\n', cs_group_name, ':', vsp.GetActiveCSNameVec(group_index))
print('\t', f"{'container_id':14s}", f"{'parm_name':24s}", f"{'group_name':22s}", f"{'parm_id':14s}", f"{'value':8s}")
geom_id = vsp.FindGeomsWithName(geom_name)[0]
group_name = 'ControlSurfaceGroup_' + str(group_index)
cs_group_container_id = vsp.FindContainer('VSPAEROSettings', 0)
for i, gain in enumerate(gains):
parm_name = 'Surf_' + vsp.GetSubSurf(geom_id, sub_id) + '_' + str(i) + '_Gain'
parm_id = MyFindParm(cs_group_container_id, parm_name)
# parm_id = vsp.FindParm(cs_group_container_id, parm_name, group_name) # なぜか反応しない...
if parm_id != '':
vsp.SetParmVal(parm_id, gain)
print('\t', f'{cs_group_container_id:14s}', f'{parm_name:24s}', f'{group_name:22s}', f'{parm_id:14s}', f'{gain:8.3f}')
else:
print('\t', 'Failed to find ' + parm_name)
ゲインを設定するためのパラメータIDを取得し、両舷のループを回してゲインを設定する
↓GUIでいうところの「Deflection Gain per Surface」を設定する操作
次のステップで設定する舵角はControl Surface Groupにつき1つの値を設定する
例えば、あるControl Surface Groupに右舷エルロン(後縁下げ正)、左舷エルロン(後縁上げ正)、ラダー(後縁右振り正)を追加し、舵角を10度と設定する
右舷エルロン、左舷エルロン、ラダーのゲインをそれぞれ[0.8, 1.0, -1.5]にすると、各舵面の舵角は次のようになる
- 右舷エルロン:8度(後縁下げ)
- 左舷エルロン:10度(後縁上げ)
- ラダー:15度(後縁左振り)
こんな感じで、複数の舵角を同時に動かしたい時などにゲインをうまく活用すればよい
OpenVSPでは、右舷をモデリングした後にそれをミラーリングして左舷のモデルを生成する
このとき、Subsurfaceの舵角は右舷が後縁下げ正、左舷が後縁上げ正になる
エルロンなどはこのままで問題ないが、エレベータは両舷同時に後縁を上げ下げしたいので、ゲインを(1.0, -1.0)に設定し、左舷の舵角を反転させる必要がある
↓メソッドの詳細
geom_id = vsp.FindGeomsWithName( name )
指定された名前を持つすべてのGeom IDを検索して返す関数
引数name
:ジオメトリの名前 [str]
返値geom_id
:ジオメトリ名の配列 [array of str]
↓使い方の例
container_id = vsp.FindContainer(name, index)
指定された名前のパラメータコンテナのIDを取得する関数
引数name
:パラメータコンテナの名前 [str]index
:パラメータコンテナのインデックス [int]
返値container_id
:パラメータコンテナのID [str]
利用可能な全てのパラメータコンテナのIDと名前は以下のプログラムで取得できる
container_ids = vsp.FindContainers()
print(f"{'container_id':14s}", f"{'container_name':24s}")
print('-'*(14+24))
for container_id in container_ids:
container_name = vsp.GetContainerName(container_id)
print(f'{container_id:14s}', f'{container_name:24s}')
結果は次のようになる
container_id container_name
--------------------------------------
YYFORBMCGS UserParms
BKUBOSBURK Vehicle
ZCZWAYJMXW FuselageGeom
FJECIMNCTU WingGeom
NLLTMWNMDW HTailGeom
JWMUAVWHDI VTailGeom
XZLZXSVPJC FuselageGeom
ZKIZZUSYSG WingGeom
HCAZGTRJBB HTailGeom
BJCBBPTNVH VTailGeom
MHPOTOSWKA ClippingMgr
_Al7075T6 Aluminum 7075-T6
_Al6061T6 Aluminum 6061-T6
_Al2024T3 Aluminum 2024-T3
_Ti6Al4V Titanium Ti-6Al-4V
_CrMo4130 Steel AISI 4130
_AS4-Uni Carbon Epoxy AS4 3501-6
_AS4-1 Carbon Epoxy AS4 3501-6 [0_2/90]s
_AS4-2 Carbon Epoxy AS4 3501-6 [0/90]_2s
_AS4-3 Carbon Epoxy AS4 3501-6 [0/90/+-45]s
_AS4-4 Carbon Epoxy AS4 3501-6 [+-30]_2s
_AS4-5 Carbon Epoxy AS4 3501-6 [+-45]_2s
_AS4-6 Carbon Epoxy AS4 3501-6 [+-60]_2s
_S2-Uni Glass Epoxy S2 3501-6
_S2-1 Glass Epoxy S2 3501-6 [0_2/90]s
_S2-2 Glass Epoxy S2 3501-6 [0/90]_2s
_S2-3 Glass Epoxy S2 3501-6 [0/90/+-45]s
_Balsa Balsa LTR
_Spruce Sitka Spruce LTR
_hmce HM Carbon Epoxy
VOGXOHRSMS DefaultShell
QVXPSRUKPN DefaultBeam
COWPEHJDST DefaultShell
OARHUEJGPP DefaultBeam
FNJGUJZFBF DefaultShell
XCCBVWPOLK DefaultBeam
RACKAMXDNK DefaultShell
PJNHRDKFPO DefaultBeam
OGVIHUJDBG DefaultShell
SPRSDOAUZC DefaultBeam
VUWDHKEMKK DefaultShell
UNRQQKECJA DefaultBeam
YNJNPQDOYR DefaultShell
JIVIFKIBIY DefaultBeam
TTDCJHDVST DefaultShell
KBHLISDQFV DefaultBeam
USZFBOTYQR DefaultShell
XESYZAIVWB DefaultBeam
FGMUQJXWHP DefaultShell
HQMJALIDRY DefaultBeam
HITPYRUTRS DefaultShell
PCVFIXCDHD DefaultBeam
BSCWYFCOTV DefaultShell
XZUKCQWFXD DefaultBeam
VXDOJDKZSA DefaultShell
FPXXEUQSJR DefaultBeam
IICCRLNLTQ DefaultShell
HQSQKNNOPZ DefaultBeam
XCEYAVSJSR DefaultShell
NRFRXDEZIB DefaultBeam
ACXOXTDLCY DefaultShell
AADHXUVIKC DefaultBeam
PKJMMZJRGU DefaultShell
CUUZDPVWMO DefaultBeam
EEXTHJZJLW DefaultShell
SNLAAXDIET DefaultBeam
KAGPJCXMPX DefaultShell
ALDMNLJNLD DefaultBeam
OLBVHEMBPW DefaultShell
YYMUSAYPQE DefaultBeam
LAJBHIEVAP DefaultShell
WWUBSVDIXF DefaultBeam
LIJJWAXVCO DefaultShell
QLUEJFDGBG DefaultBeam
YKYHQMHXQH DefaultShell
CHELZMOXVA DefaultBeam
PVSUXHQCLG DefaultShell
FCCJAJAJCZ DefaultBeam
DJXBVMRICQ DefaultShell
LOBOMMODAG DefaultBeam
VEWXCCYXKI DefaultShell
DSCYMOHTEZ DefaultBeam
DCEWZQRCUV DefaultShell
TGADDHGPDO DefaultBeam
PETTNTWNWG DefaultShell
FKESCHTLVH DefaultBeam
VQTWMESCIC VSPAEROSettings
WQVXRECTVI CFDMeshSettings
AUVRUABDVD SurfaceIntersectSettings
MJEUJOKXGZ CFDGridDensity
ZOMQZIARIU WaveDragSettings
PLLKMERWBP ParasiteDragSettings
これの下の方にある「VSPAEROSettings」が今回呼び出しているパラメータコンテナである
subsurf_id = vsp.GetSubSurf(geom_id, index)
指定されたサブサーフェスのIDを取得する関数
引数geom_id
:ジオメトリ名 [str]index
:Subsurfaceのインデックス [int]
返値
subsurf_id
:SubsurfaceのID
parm_id = vsp.FindParm(parm_container_id, parm_name, group_name)
パラメータコンテナID、パラメータ名、パラメータグループを指定してパラメータIDを検索する関数
引数parm_container_id
:パラメータコンテナID [str]parm_name
:パラメータ名 [str]group_name
:パラメータグループ [str]
返値parm_id
:パラメータID [str]
パラメータIDが見つからなかったときは空の文字列''
を返す
ちなみに、パラメータコンテナ内にあるすべてのパラメータID、パラメータ名、パラメータグループは以下のプログラムで取得できる
# //==== Get and List All Parms in the Container ====//
container_id = vsp.FindContainer('VSPAEROSettings', 0)
parm_ids = vsp.FindContainerParmIDs( container_id )
print(f"{'container_id':14s}", f"{'parm_name':26s}", f"{'group_name':22s}", f"{'parm_id':14s}", f"{'get_parm_id':14s}\n" + '-'*(14+26+22+14+14))
for parm_id in parm_ids:
parm_name = vsp.GetParmName(parm_id)
group_name = vsp.GetParmDisplayGroupName(parm_id)
get_parm_id = vsp.FindParm(container_id, parm_name, group_name)
print(f'{container_id:14s}', f'{parm_name:26s}', f'{group_name:22s}', f"{parm_id:14s}", f"{get_parm_id:14s}")
結果は次のようになる
container_id parm_name group_name parm_id get_parm_id
------------------------------------------------------------------------------------------
VQTWMESCIC ActuatorDiskFlag VSPAERO NGBYYWDXIQK NGBYYWDXIQK
VQTWMESCIC AlphaEnd VSPAERO NSLFBZGBGDQ NSLFBZGBGDQ
VQTWMESCIC AlphaNpts VSPAERO XPVVYGUTYJE XPVVYGUTYJE
VQTWMESCIC AlphaStart VSPAERO SQEJJVMZNTC SQEJJVMZNTC
VQTWMESCIC AlternateInputFormatFlag VSPAERO PYSAOMZITOK PYSAOMZITOK
VQTWMESCIC AnalysisMethod VSPAERO BLGSZQUZVCE BLGSZQUZVCE
VQTWMESCIC AutoTimeNumRevs VSPAERO IXLHIPRIVVT IXLHIPRIVVT
VQTWMESCIC AutoTimeStepFlag VSPAERO VIMBFLVXDNA VIMBFLVXDNA
VQTWMESCIC BetaEnd VSPAERO UDBUSQNEIJU UDBUSQNEIJU
VQTWMESCIC BetaNpts VSPAERO SKBHBWVDJZB SKBHBWVDJZB
VQTWMESCIC BetaStart VSPAERO FHQKCJJDBEO FHQKCJJDBEO
VQTWMESCIC Clmax VSPAERO DTUCDSBVNDG DTUCDSBVNDG
VQTWMESCIC ClmaxToggle VSPAERO BHJUCSFGXTZ BHJUCSFGXTZ
VQTWMESCIC CpSliceFlag VSPAERO JKTGDIEEZLT JKTGDIEEZLT
VQTWMESCIC CpSlicePlotLinesFlag VSPAERO CDNQMGSGIXA CDNQMGSGIXA
VQTWMESCIC CpSliceYAxisFlipFlag VSPAERO OPWWTHPGWCY OPWWTHPGWCY
VQTWMESCIC FarDist VSPAERO RZFSGGDPSOX RZFSGGDPSOX
VQTWMESCIC FarDistToggle VSPAERO HGMPNKDCZBK HGMPNKDCZBK
VQTWMESCIC FixedWakeFlag VSPAERO HYOXEKKJAKU HYOXEKKJAKU
VQTWMESCIC FromSteadyState VSPAERO WOTHIQUDIIP WOTHIQUDIIP
VQTWMESCIC GeomSet VSPAERO FRWEHEHDJQF FRWEHEHDJQF
VQTWMESCIC GroundEffect VSPAERO DIHXTWXQDBX DIHXTWXQDBX
VQTWMESCIC GroundEffectToggle VSPAERO WLLIWTQEUUJ WLLIWTQEUUJ
VQTWMESCIC HoverRamp VSPAERO HBRLUWFBKJC HBRLUWFBKJC
VQTWMESCIC HoverRampFlag VSPAERO OZIYXMZHBXD OZIYXMZHBXD
VQTWMESCIC KTCorrection VSPAERO GKTFENYKSHI GKTFENYKSHI
VQTWMESCIC LoadDistSelectType VSPAERO YSDPARQHVEQ YSDPARQHVEQ
VQTWMESCIC MachEnd VSPAERO LZBYNRFKCJA LZBYNRFKCJA
VQTWMESCIC MachNpts VSPAERO OMXNROCMYLP OMXNROCMYLP
VQTWMESCIC MachStart VSPAERO YBOKHBNVUIR YBOKHBNVUIR
VQTWMESCIC Machref VSPAERO RCOSNSBLXNB RCOSNSBLXNB
VQTWMESCIC ManualVrefFlag VSPAERO HERKPZBOLNR HERKPZBOLNR
VQTWMESCIC MassSet VSPAERO CRESYACQECB CRESYACQECB
VQTWMESCIC MassSliceDir VSPAERO ORPJSSLCWFV ORPJSSLCWFV
VQTWMESCIC MaxTurnAngle VSPAERO ZFGGPFYNYLE ZFGGPFYNYLE
VQTWMESCIC MaxTurnToggle VSPAERO OGVBYRNCZLL OGVBYRNCZLL
VQTWMESCIC NCPU VSPAERO XIUSHMILOIW XIUSHMILOIW
VQTWMESCIC NoiseCalcFlag VSPAERO CREZALBXOLG CREZALBXOLG
VQTWMESCIC NoiseCalcType VSPAERO SHGKODZITHC SHGKODZITHC
VQTWMESCIC NoiseUnits VSPAERO QGLUETHZILD QGLUETHZILD
VQTWMESCIC NumMassSlice VSPAERO ARNXEMYVUTH ARNXEMYVUTH
VQTWMESCIC NumTimeSteps VSPAERO EGPULZFNODM EGPULZFNODM
VQTWMESCIC Precondition VSPAERO ZNNLYOVOACL ZNNLYOVOACL
VQTWMESCIC ReCref VSPAERO FGMLBMLIXSL FGMLBMLIXSL
VQTWMESCIC ReCrefEnd VSPAERO EPWKGMJFBYV EPWKGMJFBYV
VQTWMESCIC ReCrefNpts VSPAERO GMRAUPKKVWV GMRAUPKKVWV
VQTWMESCIC RefFlag VSPAERO TTJJCCOCOFV TTJJCCOCOFV
VQTWMESCIC Rho VSPAERO MDJVJTBKGBT MDJVJTBKGBT
VQTWMESCIC RootWakeNodes VSPAERO BZDPCWIQRBD BZDPCWIQRBD
VQTWMESCIC RotateBladesFlag VSPAERO PONQGIXXLWK PONQGIXXLWK
VQTWMESCIC Sref VSPAERO SEJRVYTNPUG SEJRVYTNPUG
VQTWMESCIC Symmetry VSPAERO MRLTAPSFHBJ MRLTAPSFHBJ
VQTWMESCIC TimeStepSize VSPAERO NCJRTAESWOK NCJRTAESWOK
VQTWMESCIC UniformPropRPMFlag VSPAERO NBOCEBYAAMU NBOCEBYAAMU
VQTWMESCIC UnsteadyGroupSelectType VSPAERO ACPBPXCYUZM ACPBPXCYUZM
VQTWMESCIC UnsteadyType VSPAERO PABCOERZUNS PABCOERZUNS
VQTWMESCIC Vinf VSPAERO OAUGFIMNYIW OAUGFIMNYIW
VQTWMESCIC Vref VSPAERO KXGWQXGKWPX KXGWQXGKWPX
VQTWMESCIC WakeNumIter VSPAERO PGXCLVPVJVQ PGXCLVPVJVQ
VQTWMESCIC Write2DFEMFlag VSPAERO FRCRUNJPTVE FRCRUNJPTVE
VQTWMESCIC Xcg VSPAERO RCNZDHAEIZT RCNZDHAEIZT
VQTWMESCIC Ycg VSPAERO LHSKPTHCTOE LHSKPTHCTOE
VQTWMESCIC Zcg VSPAERO EAXPHWYCOQT EAXPHWYCOQT
VQTWMESCIC bref VSPAERO OSLKEOXGSND OSLKEOXGSND
VQTWMESCIC cref VSPAERO HOUBFMZNZIB HOUBFMZNZIB
VQTWMESCIC m_ConvergenceXMax VSPAERO ALHKXUENFVJ ALHKXUENFVJ
VQTWMESCIC m_ConvergenceXMaxIsManual VSPAERO PSYRJVBMVDE PSYRJVBMVDE
VQTWMESCIC m_ConvergenceXMin VSPAERO BPIJNVFDOEB BPIJNVFDOEB
VQTWMESCIC m_ConvergenceXMinIsManual VSPAERO BZPEQVKYDGI BZPEQVKYDGI
VQTWMESCIC m_ConvergenceYMax VSPAERO PVCKNOUAURT PVCKNOUAURT
VQTWMESCIC m_ConvergenceYMaxIsManual VSPAERO XAIITDLCWTP XAIITDLCWTP
VQTWMESCIC m_ConvergenceYMin VSPAERO VXCUGNJRNVC VXCUGNJRNVC
VQTWMESCIC m_ConvergenceYMinIsManual VSPAERO IVFGWSRZSGM IVFGWSRZSGM
VQTWMESCIC m_CpSliceXMax VSPAERO LOZDZMIHUPK LOZDZMIHUPK
VQTWMESCIC m_CpSliceXMaxIsManual VSPAERO AAZJLFYSAPP AAZJLFYSAPP
VQTWMESCIC m_CpSliceXMin VSPAERO KSALKTHOCGW KSALKTHOCGW
VQTWMESCIC m_CpSliceXMinIsManual VSPAERO UJUGVGGMIHB UJUGVGGMIHB
VQTWMESCIC m_CpSliceYMax VSPAERO LBMWMOCCWCP LBMWMOCCWCP
VQTWMESCIC m_CpSliceYMaxIsManual VSPAERO LWJMPGEJDST LWJMPGEJDST
VQTWMESCIC m_CpSliceYMin VSPAERO EORUJKEMLKA EORUJKEMLKA
VQTWMESCIC m_CpSliceYMinIsManual VSPAERO YPKCYBDBFNX YPKCYBDBFNX
VQTWMESCIC m_LoadDistXMax VSPAERO SUKIKMEBOJU SUKIKMEBOJU
VQTWMESCIC m_LoadDistXMaxIsManual VSPAERO SHWNBGRQMTY SHWNBGRQMTY
VQTWMESCIC m_LoadDistXMin VSPAERO CFOXENVIYIE CFOXENVIYIE
VQTWMESCIC m_LoadDistXMinIsManual VSPAERO QCJDDPBNANZ QCJDDPBNANZ
VQTWMESCIC m_LoadDistYMax VSPAERO RXQERZOQUPM RXQERZOQUPM
VQTWMESCIC m_LoadDistYMaxIsManual VSPAERO RNUMWLZKRBU RNUMWLZKRBU
VQTWMESCIC m_LoadDistYMin VSPAERO INYKJQFFXSO INYKJQFFXSO
VQTWMESCIC m_LoadDistYMinIsManual VSPAERO KDDNKKUUOAX KDDNKKUUOAX
VQTWMESCIC m_SweepXMax VSPAERO KTPKOCDTTQE KTPKOCDTTQE
VQTWMESCIC m_SweepXMaxIsManual VSPAERO WOJTCWRPRXC WOJTCWRPRXC
VQTWMESCIC m_SweepXMin VSPAERO UMCTGDNJORT UMCTGDNJORT
VQTWMESCIC m_SweepXMinIsManual VSPAERO UCCFTJVUMGQ UCCFTJVUMGQ
VQTWMESCIC m_SweepYMax VSPAERO XQCMCWRSSSG XQCMCWRSSSG
VQTWMESCIC m_SweepYMaxIsManual VSPAERO SUKVXUXDGSI SUKVXUXDGSI
VQTWMESCIC m_SweepYMin VSPAERO RUNWAMSDLFC RUNWAMSDLFC
VQTWMESCIC m_SweepYMinIsManual VSPAERO OOJLSTSWWML OOJLSTSWWML
VQTWMESCIC m_UnsteadyXMax VSPAERO UQVOLDOWVVC UQVOLDOWVVC
VQTWMESCIC m_UnsteadyXMaxIsManual VSPAERO AKZIEJWZSVK AKZIEJWZSVK
VQTWMESCIC m_UnsteadyXMin VSPAERO LGQZDSZVHOR LGQZDSZVHOR
VQTWMESCIC m_UnsteadyXMinIsManual VSPAERO OBJVCNKRRSC OBJVCNKRRSC
VQTWMESCIC m_UnsteadyYMax VSPAERO XBPGTLLWEEA XBPGTLLWEEA
VQTWMESCIC m_UnsteadyYMaxIsManual VSPAERO IXJEPEQFVGI IXJEPEQFVGI
VQTWMESCIC m_UnsteadyYMin VSPAERO ZQHPOXEZMHB ZQHPOXEZMHB
VQTWMESCIC m_UnsteadyYMinIsManual VSPAERO DYFJHDSDJES DYFJHDSDJES
VQTWMESCIC ActiveFlag ControlSurfaceGroup_0 MMSFYVGOLWT MMSFYVGOLWT
VQTWMESCIC DeflectionAngle ControlSurfaceGroup_0 ULYMLNXOZCB ULYMLNXOZCB
VQTWMESCIC Surf_YUESKTHJKH_0_Gain ControlSurfaceGroup_0 QDAQIZLWKJJ QDAQIZLWKJJ
VQTWMESCIC Surf_YUESKTHJKH_1_Gain ControlSurfaceGroup_0 EQWSSNIHWSY EQWSSNIHWSY
VQTWMESCIC ActiveFlag ControlSurfaceGroup_1 QSVGPYVNPFZ QSVGPYVNPFZ
VQTWMESCIC DeflectionAngle ControlSurfaceGroup_1 TAUESNQUUND TAUESNQUUND
VQTWMESCIC Surf_IBJGZQKXFM_0_Gain ControlSurfaceGroup_1 DPHIIISDGMG DPHIIISDGMG
VQTWMESCIC Surf_IBJGZQKXFM_1_Gain ControlSurfaceGroup_1 SPSBISDMKFN SPSBISDMKFN
VQTWMESCIC ActiveFlag ControlSurfaceGroup_2 BZYAMBEWQUB BZYAMBEWQUB
VQTWMESCIC DeflectionAngle ControlSurfaceGroup_2 FDDZHDUAHFQ FDDZHDUAHFQ
VQTWMESCIC Surf_ANFQIKDKMO_0_Gain ControlSurfaceGroup_2 VIUIYJPMYYP VIUIYJPMYYP
VQTWMESCIC CutPosition CpSlice SVPFWMEDZVS SVPFWMEDZVS
VQTWMESCIC CutType CpSlice DTQKRUTAROO DTQKRUTAROO
VQTWMESCIC DrawCutFlag CpSlice HWSQNLRPBOO HWSQNLRPBOO
def MyFindParm(cs_group_container_id, parm_name):
# Find param_id from cs_group_container_id and parm_name
parm_ids = vsp.FindContainerParmIDs( cs_group_container_id )
for parm_id in parm_ids:
if parm_name == vsp.GetParmName(parm_id):
return parm_id
return ''
今回はなぜかset_control_surface()
内でvsp.FindParm()
が使えなかったので、同じ機能を持つ関数を自作した
set_val = vsp.SetParmVal(parm_id, val)
指定されたパラメータの値を設定する関数
引数parm_id
:パラメータID [str]val
:パラメータに設定する値 [float]
返値set_val
:実際にパラメータに設定された値 [float]
Control Surfaceの舵角を設定
# Set defrection angle
parm_name = 'DeflectionAngle'
parm_id = vsp.FindParm(cs_group_container_id, parm_name, group_name)
vsp.SetParmVal(parm_id, deflection)
ゲインと同様の手順で舵角を設定する
↓GUIでいうところの「Control Group Angles」を設定する操作
おまけ
OpenVSPのモデルのvsp3ファイルはxml形式で記述されているので、テキストエディターを使えばGUIで設定した各パラメータのIDを確認することができる
↓XML形式とは
使い方
↓環境構築はこれ
ディレクトリ構成は以下の通り
./
├─bin
│ │ AnalysisVSPAERO.py
│ └─ CST.py
└─G103A
│ test_control_surface.py
└─ G103A.vsp3
G103A.vsp3のモデルをtest_control_surface.pyで解析する
import sys
import os
import numpy as np
# ../bin/AnalysisVSPAERO.py をモジュールとしてインポート
sys.path.append(os.path.join('..')) # 親ディレクトリをモジュール探索パスに追加
from bin.AnalysisVSPAERO import *
import openvsp as vsp
if __name__=='__main__':
# Close and open the file
vsp.ClearVSPModel()
vsp.Update()
vsp.ReadVSPFile('G103A.vsp3')
vsp.Update()
# Set control surface
set_control_surface(geom_name='WingGeom', deflection=10, cs_group_name='AILERON_GROUP', gains=(1,1))
set_control_surface(geom_name='HTailGeom', deflection=0, cs_group_name='Elevator_Group', gains=(1,-1))
set_control_surface(geom_name='VTailGeom', deflection=0, cs_group_name='Rudder_Group')
vsp.Update()
# Execute VSPAEROSweep
alpha = np.linspace(-4, 12, 9)
mach = [0.1]
vsp_sweep(vsp=vsp, alpha=alpha, mach=mach)
PowerShellを立ち上げ、以下のコマンドで実行する
conda activate vsppytools
python .\test_control_surface.py
結果は「G103A_DegenGeom.polar」というファイルに保存される
Beta Mach AoA Re/1e6 CL CDo CDi CDtot CDt CDtot_t CS L/D E CFx CFy CFz CMx CMy CMz CMl CMm CMn FOpt
0.000000000000 0.100000000000 -4.000000000000 4.400000000000 -0.078751346025 0.009892928407 0.003873528826 0.013766457233 0.004809061807 0.014701990214 -0.010061841926 -5.720523784276 0.008338118346 0.008239506634 -0.010061841926 -0.079519811217 0.068559900710 0.013682917371 -0.004389216743 -0.068559900710 0.013682917371 0.004389216743 0.000000000000
0.000000000000 0.100000000000 -2.000000000000 4.400000000000 0.139136765354 0.010070356383 0.004791951074 0.014862307457 0.004582703934 0.014653060317 -0.010466691549 9.361720295303 0.024108591476 0.019709056824 -0.010466691549 0.138533319946 0.068608065480 0.018976654781 -0.002919251458 -0.068608065480 0.018976654781 0.002919251458 0.000000000000
0.000000000000 0.100000000000 0.000000000000 4.400000000000 0.356471526421 0.010762441141 0.006196197493 0.016958638634 0.006308838269 0.017071279410 -0.010756586840 21.020055566846 0.138686114003 0.016958638634 -0.010756586840 0.356471526421 0.068540110394 0.024189726776 -0.001439322610 -0.068540110394 0.024189726776 0.001439322610 0.000000000000
0.000000000000 0.100000000000 2.000000000000 4.400000000000 0.574678982130 0.011965676331 0.008022265440 0.019987941771 0.009833702536 0.021799378867 -0.011047414935 28.751283585215 0.305813621634 -0.000080241585 -0.011047414935 0.575026472329 0.068178713911 0.031244274440 0.000092523743 -0.068178713911 0.031244274440 -0.000092523743 0.000000000000
0.000000000000 0.100000000000 4.000000000000 4.400000000000 0.791479240528 0.013650867861 0.010386245284 0.024037113145 0.015417897980 0.029068765841 -0.011469911291 32.927383407220 0.482359707132 -0.031232240915 -0.011469911291 0.791227981129 0.067704364648 0.037134662079 0.001516327989 -0.067704364648 0.037134662079 -0.001516327989 0.000000000000
0.000000000000 0.100000000000 6.000000000000 4.400000000000 1.010071251058 0.015833623154 0.013211869745 0.029045492899 0.022646735707 0.038480358861 -0.011925136009 34.775490109917 0.650129007015 -0.076694817014 -0.011925136009 1.007574055797 0.067635069977 0.046311592127 0.002853453692 -0.067635069977 0.046311592127 -0.002853453692 0.000000000000
0.000000000000 0.100000000000 8.000000000000 4.400000000000 1.224380204870 0.018403939712 0.016602715340 0.035006655053 0.032239951194 0.050643890906 -0.012272064554 34.975641146762 0.792603996344 -0.135734817174 -0.012272064554 1.217336605620 0.066139518935 0.051098330018 0.004279116911 -0.066139518935 0.051098330018 -0.004279116911 0.000000000000
0.000000000000 0.100000000000 10.000000000000 4.400000000000 1.440248801627 0.021420912712 0.020719616798 0.042140529510 0.044015490959 0.065436403671 -0.012658124693 34.177282971179 0.911064932174 -0.208596259612 -0.012658124693 1.425685812264 0.066035975358 0.058755810827 0.005685028542 -0.066035975358 0.058755810827 -0.005685028542 0.000000000000
0.000000000000 0.100000000000 12.000000000000 4.400000000000 1.652287123792 0.024754473568 0.025422554906 0.050177028473 0.058407872731 0.083162346299 -0.012832581499 32.929154516893 1.007025278061 -0.294449269611 -0.012832581499 1.626613076691 0.064562591023 0.064793952075 0.006996347144 -0.064562591023 0.064793952075 -0.006996347144 0.000000000000
ちゃんと機体を左に回転させるロールモーメントが生じているのが分かる(OpenVSPの座標系は、X:機体後方正、Y:右舷正、Z:上方正)
以上
おわりに
OpenVSPのPythonAPIで作成済みのモデルの舵角を設定してαスイープの計算を行った
ドキュメントの読み方もなんとなくわかってきたので、次はトリムドポーラーを計算できるようになりたい
↓関連記事
コメント