轉自: 么的聊
鏈接:https://www.jianshu.com/p/a0b4598f928a
雖然用戶不需要掌握太多 JSBSim 飛行模擬器的細節,但是了解 JSBSim 的基本工作流程也會對學習幫助很大。本章將介紹 JSBSim 的基本概念。
仿真系統
通過參考坐標系描述不同部件在飛行器模型中的安裝位置——都支持英制和國標兩種單位制。為了增強 JSBSim 的通用模擬特性,采用屬性(properties)作為不同系統之間的參數(parameters / variables)通信接口。飛機和發動機的配置文件都采用屬性的形式進行表征。在飛行建模中,數學元素扮演着重要的角色。JSBSim 采用數據表(data tables)存儲飛行特性和參數。JSBSim 能夠建立任意形式的代數方程,允許在氣動力和飛行控制系統中擴展自由度。
坐標系 (Frames of Reference)
在介紹配置文件的語法前,需要首先理解描述飛行器的坐標系統。
-
結構坐標系:
加工制造方使用的坐標系,常用語定義飛機的重心、起落架滾輪、駕駛員視角和推進器等,JSBSim 的配置文件也采用結構坐標系來定義飛機部件的安裝位置。X 軸從飛機的頭部指向尾部,Y 軸從機身指向右側(從飛機尾部看),按照右手定則 Z 指向上方。典型的,坐標系原點位於飛機的頭部(可以選擇為頭部的尖端、或者在頭部之前的一段距離),X 軸通常與機身的中心線重合,穿過螺旋槳的輪軸或者發動機的軸線。沿 X 軸方向的距離稱作 stations;沿 Z 軸方向的距離稱作 waterline,沿 Y 軸方向的距離稱作 buttline。
值得注意的是,在 JSBSim 中進行飛機建模時,結構坐標系的原點可以在任意位置,因為 JSBSim 內部只使用與重心的相對位置,而不是各部件的坐標位置。 -
體坐標系:
JSBSim中的體坐標系與結構坐標系相似,只是沿着 Y 軸旋轉了180度,坐標原點與重心相重合。作用在飛機上的力和力矩都是在體坐標系內進行運算求和的,得到的加速度也是在體坐標系內進行積分求速度的。 -
穩定性坐標系:
與體坐標系相比,穩定坐標系的 X 軸指向相對風速在飛機對稱面的投影,Y 軸仍指向右側機翼,Z 軸遵循右手定則。 -
風速坐標系:
和穩定坐標系相似,只是風速坐標系的 X 軸直接指向相對風速方向,Z 軸與 X 軸垂直,並保持在體坐標系的 XZ 平面(也稱作參考平面)內,Y 軸遵循右手定則。
單位制
除非特殊說明,JSBSim都采用英制單位進行內部的計算。但是,在配置文件中也可以輸入其他單位制的參數。實踐中為避免單位制紊亂,建議總是顯式定義單位。采用 unit 屬性來定義,例如下面定義翼展長度的語句:
<wingspan unit="FT"> 35.8 </wingspan>
上述語句定義了翼展長度為35.8 Feet。下面等效語句則將長度單位定義為國標m(35.8 feet = 10.91 m):
<wingspan unit="M"> 10.91 </wingspan>
兩個語句在 JSBSim 中的效果是相同的,只是采用了兩種單位制。JSBSim 中的單位及其縮寫分類如下:
- 長度:M KM -> FT IN
- 角度:RAD -> DEG
- 面積:M2 -> FT2
- 體積:CC M3 LTR -> IN3 FT3
- 力:N -> LBS
- 力矩:NM -> FTLBS
- 速度:M/S -> FT/SEC
- 彈簧力:N/M -> LBS/FT
- 阻尼力:N/M/SEC -> LBS/FT/SEC
- 質量:KG -> LBS
- 能量:WATTS -> HP
- 壓強:PA ATM -> PSF INHG
通過代碼模板的形式展示 JSBSim 中飛行器相關的參數如下:
<metrics> <wingarea unit="{FT2 | M2}"> {number} </wingarea> <wingspan unit="{FT | M}"> {number} </wingspan> <chord unit="{FT | M}"> {number} </chord> <htailarea unit="{FT2 | M2}"> {number} </htailarea> <htailarm unit="{FT | M}"> {number} </htailarm> <vtailarea unit="{FT2 | M}"> {number} </vtailarea> <vtailarm unit="{FT | M}"> {number} </vtailarm> <wing_incidence unit="{RAD | DEG}"> {number} </wing_incidence> <pitot_angle unit="{RAD | DEG}"> {number} </pitot_angle> <location name="{AERORP | EYEPOINT | VRP}" unit="{IN | M}"> <x> {number} </x> <y> {number} </y> <z> {number} </z> </location> {other location blocks} </metrics>
代碼中除了飛機的幾何參數外,還有三個參考位置:
- AERORP:氣動力的作用點,為保證飛行的穩定性,氣動力作用點通常在重心之后;
- EYEPOINT:計算飛行員/駕駛儀加速度(G-forces)的點;
- VRP(Virtual Reference Point):JSBSim 輸出位置相關參數的對應點,用結構坐標系中的坐標表示。
屬性(properties)
仿真系統需要管理大量的狀態信息。對於大型的程序而言,數據的管理任務可能導致的問題有一下幾類:
- 擴展性下降:若希望添加額外的功能,貢獻者可能會覺得越來越難管理數目增加的通信接口;
- 配置性減弱:當對於不同機理(例如,環境變量、自定義文件、命令行選項等)的不同模塊進行處理時,運行配置文件會變得越來越難;
- 初始化流程復雜:程序的初始化流程隨着模型的復雜度增加而變得復雜,因為部分模塊的初始化可能會使用到一些尚未來得及初始化的模塊;
- 子工具擴展性差:通過子工具中的腳本、配置文件對程序進行擴展受限於程序提供的狀態信息,如果是非代碼開發用戶則需要等待開發團隊添加相應的變量。
屬性管理系統(Property Manager system, PM)提供了一個單獨的接口,接口允許在程序運行過程中動態地選擇狀態信息,甚至是生成一個新變量。 其中,動態生成新變量的功能對 JSBSim 的飛行控制系統至關重要,因為組成飛控系統的部分組件(例如,PID控制器、開關、加法器、增益等)只在特定的狀態文件中出現。運行過程一旦稀疏地定義了這些組件后,組件本身只是瞬時存在的,但屬性管理系統會將各組件的輸出值按照屬性的方式進行存儲。
屬性本身是一系列能夠選擇性可視的全局變量,各屬性按照繼承性、樹狀進行分類(類似於Unix的文件系統)。 屬性樹的結構包含一個根節點和一系列子節點以及終端節點。與Unix的文件系統類似,屬性能夠被當前節點或根節點引用,屬性也能夠被嫁接到其他節點上(類似於文件系統中的符號化鏈接和文件目錄)。在 JSBSim 和 FlightGear 的程序代碼中,屬性被特定的參數廣泛地引用。屬性能夠通過命令行、配置文件和腳本進行分配,甚至一個信道也可以分配屬性。屬性的命名方式如下:position/h-sl-ft、aero/qbar-psf。
為展示屬性和配置文件的功能,以高性能噴氣式飛機模型為對象進行描述。假設某一時刻一個新功能開關被添加到飛行控制面板上,例如飛機允許飛行員在飛控系統中進行超量程俯仰。對於 FlightGear 而言,器件面板是由一個配置文件定義的,開關就是在該文件上進行可視化。當進行開關定義時,開關被賦予一個屬性名。在 JSBSim 飛行控制的配置部分,器件面板定義文件中一個被賦予該屬性名的超量程俯仰開關就能夠以通道的形式更新控制率,開關的位置函數能夠按照需要的路徑進行信息傳遞。整個功能添加的過程中並不涉及任何的代碼編寫。
仿真參數的定義既可以在 JSBSim 中,也可以在配置文件中通過屬性完成。前文已經提到,屬性是用於描述參數的選項,能夠通過配置文件、命令行等獲取和設置屬性。
標准屬性指的是那些在任何飛行器中都會出現的屬性。但是氣動力系數、發動機、推進器、飛控/自動駕駛儀等有時也需要動態定義一些屬性。因為在相關的飛機配置文件被完全讀入之前,氣動力系數、發動機等參數並不是完全知曉的。用戶必須知道這些參數對應的屬性名,這樣才能夠對屬性進行修改和更新。例如,X-15飛機的飛行控制系統具有以下特性:
<flight_control name="X-15"> <channel name="Pitch"> <summer name="fcs/pitch-trim-sum"> <input>fcs/elevator-cmd-norm</input> <input>fcs/pitch-trim-cmd-norm</input> <clipto> <min>-1</min> <max>1</max> </clipto> </summer> <aerosurface_scale name="fcs/pitch-command-scale"> <input>fcs/pitch-trim-sum</input> <range> <min>-50</min> <max>50</max> </range> </aerosurface_scale> <pure_gain name="fcs/pitch-gain-1"> <input>fcs/pitch-command-scale</input> <gain>-0.36</gain> </pure_gain>
上述代碼中的第一個組件 "fcs/pitch-trim-sum" 包含兩個已知的靜態輸入,即 fcs/elevator-cmd-norm 和 fcs/pitch-trim-cmd-norm。第二個組件將第一個組件的輸出作為自身的輸入,最后一個增益組件又以上一個輸出(fcs/pitch-command-scale)作為自身的輸入。
至此,用於已經擁有了一種獲取JSBSim參數的方法,也了解了飛控系統是如何嵌入到JSBSim系統中。飛控系統中相同的組件也能夠用於構建自動駕駛儀等其他子系統
數學表達式:
作者:么的聊
鏈接:https://www.jianshu.com/p/e3dd2472ef2c
JSBSim 的函數定義方式功能強大,能夠在配置文件中定義代數表達式。函數的語法和 MathML (Mathematical Markup Language, www.w3.org/Math/)相似,但是要更簡潔。
函數(function)
函數的定義由操作符(operation)、數值(value)、表格(table)和屬性(property)組成。當前 JSBSim 支持的操作符包含:
- 求和:sum
- 求乘:product
- 求商:quotient
- 乘方:pow
- 冪指數:exp
- 絕對值:abs
- 三角函數:sin, cos, tan
- 反三角函數:asin, acos, atan, atan2
- 最小、最大值:min, max
- 變量:avg
- 分數:fraction
- 整除:mod
- 隨機數:random
- 微積分:difference, integer
在配置文件中,操作符的使用方法如下:
<sum> <value>3.14159</value> <property>velocities/qbar</property> <product> <value>0.125</value> <property>metrics/wingarea</property> </product> </sum>
上述代碼定義的運算或公式如下:
3.14159 + qbar + (0.125 * wingarea)
一個完整的函數定義應當包含函數元素(即 <function ...>)和其他元素兩部分,如下文的氣動力定義代碼所示。值得注意的是,函數定義中只能有一個非選項型元素,如函數定義代碼段中頂端處的代數運算符。也就是說, <function> 元素中不能有多個立即的子運算、屬性、表格或者數值。幾乎所有的情況下,函數元素的第一個運算符都是求乘(product)或者求和(sum),例如:
<function name="aero/coefficient/Clr"> <description>Roll moment due to yaw rate</description> <product> <property>aero/qbar-area</property> <property>metrics/bw-ft</property> <property>aero/bi2vel</property> <property>velocities/r-aero-rad_sec</property> <table> <independentVar>aero/alpha-rad</independentVar> <tableData> 0.000 0.08 0.094 0.19 </tableData> </table> </product> </function>
如上述求和以及氣動力定義代碼所示,函數定義中最低一級總是數值(value)或者屬性(property),在最低級別中的元素是不可以自身包含另外元素的。代碼也顯示,運算符代碼段中是可以包含數值、屬性、表格和其他運算符的。在運算中可以只包含一個輸入,但是這個輸入可以是單個變量或屬性,也可以是嵌套的子運算(例如求和),再在自運算內包含其他更多的變量。但需要記住的是,只包含一個輸入值的運算只有三角函數(atan2除外)。
譯者注:
函數定義中提到的數值(value)、屬性(property)、表格(table)和運算符(operation)是函數的四類基本元素,對於有一定編程基礎的讀者,可能保留英文原文更容易說明(下文將保留英文形式)。下面將四類元素進行列表說明:
- 運算符(operation):即加減乘除這些代數運算;
- 數值(value):特指具有固定大小的數字,可以理解為常數;
- 屬性(property):程序中生成的相關變量,即上一章屬性管理系統中介紹的屬性;
- 表格(table):由數值組成的表格,主要應用於插值運算,因此需要聲明獨立變量(independentVar)。
在函數定義中,元素的表達可以采用縮寫形式,當然也只有數值(value)、屬性(property)、表格(table)和運算符(operation)四類元素可以采用縮寫。例如,上述氣動力定義代碼段也可等效的寫成如下形式:
<function name="aero/coefficient/Clr"> <description>Roll moment due to yaw rate</description> <product> <p>aero/qbar-area</p> <p>metrics/bw-ft</p> <p>aero/bi2vel</p> <p>velocities/r-aero-rad_sec</p> <t> <independentVar>aero/alpha-rad</independentVar> <tableData> 0.000 0.08 0.094 0.19 </tableData> </t> </product> </function>
表格(table)
在四個元素中,表格的定義相對特殊。JSBSim 中的表格可以是一維、二維和三維形式,通常用於氣動力的插值運算(譯者注:這里的表格應當理解為表格和插值運算的結合體)。一個單向量插值運算定義形式如下:
<table> <independentVar lookup="row">property_name</independentVar> <tableData> key_1 value_1 key_2 value_2 ... ... </tableData> </table>
這里,用於插值的獨立變量是可選的,一方面獨立變量本身需要進行聲明(property_name),另一方面插值表格的矢量形式也可以聲明(lookup="row" 選擇按行插值)。上述模板表明,以 property_name 為獨立變量並且按照行插值的形式進行運算。
一個二維表格的定義如以下代碼段所示:
<table> <independentVar lookup="row">property_name</independentVar> <independentVar lookup="column">property_name</independentVar> <tableData> {col_1_key} {col_2_key} {...} {col_n_key} {row_1_key} {value_11} {value_12} {...} {value_1n} {row_2_key} {value_21} {value_22} {...} {value_2n} {...} ... ... ... ... {row_n_key} {value_n1} {value_n2} {...} {value_nn} </tableData> </table>
如代碼所示,二維表格采用的是網格輸入形式,分別按照行和列進行二維插值,用於行和列索引的獨立變量也需要聲明。
三維表格則是將其拆分為多個二維表格的形式進行代碼輸入,代碼段格式如下:
<table> <independentVar lookup="row">property_name</independentVar> <independentVar lookup="column">property_name</independentVar> <independentVar lookup="table">property_name</independentVar> <tableData breakpoint="table_1_key"> {col_1_key} {col_2_key} {...} {col_n_key} {row_1_key} {value_11} {value_12} {...} {value_1n} {row_2_key} {value_21} {value_22} {...} {value_2n} {...} ... ... ... ... {row_n_key} {value_n1} {value_n2} {...} {value_nn} </tableData> <tableData breakpoint="table_2_key"> {col_1_key} {col_2_key} {...} {col_n_key} {row_1_key} {value_11} {value_12} {...} {value_1n} {row_2_key} {value_21} {value_22} {...} {value_2n} {...} ... ... ... ... {row_n_key} {value_n1} {value_n2} {...} {value_nn} </tableData> ... <tableData breakpoint="table_n_key"> {col_1_key} {col_2_key} {...} {col_n_key} {row_1_key} {value_11} {value_12} {...} {value_1n} {row_2_key} {value_21} {value_22} {...} {value_2n} {...} ... ... ... ... {row_n_key} {value_n1} {value_n2} {...} {value_nn} </tableData> </table>
注意:JSBSim中表格的插值都采用線性內插算法,並不具備外插功能,即輸入的最大值只能返回到表格中的最大索引對應數值。
至此,相信讀者已經能夠在 XML 配置文件中完成數學公式的輸入了,后續將圍繞具體物理變量開展飛行參數的學習
