jsbsim的脚本文件分为几大类:
1.系统脚本:
systems 包含通用飞机各部分功能模块组件以及自动飞行控件:Autopilot.xml 和 自动飞行的算法控件:GNCUtilities.xml
2.引擎脚本:
engine:包含各个飞机的发动机控件
3.飞机脚本:
aircraft:包含各个飞机的控件、输入输出、初始化参数
4.控制脚本:
scripts:一次飞行模拟的全过程
现在来分析一次自动驾驶飞行所使用的部分脚本,以及脚本中的参数意义。
分析:C172的自动驾驶飞行
在脚本文件scripts中找到c1722.xml文件
<use aircraft="c172x" initialize="reset01"/>
<run start="0.0" end="200" dt="0.00833333"> <event name="Engine start">
<condition>simulation/sim-time-sec ge 0.25</condition>
<set name="fcs/throttle-cmd-norm" value="0.65"/>
<set name="fcs/mixture-cmd-norm" value="0.87"/>
<set name="propulsion/magneto_cmd" value="3"/>
<set name="propulsion/starter_cmd" value="1"/>
<set name="ap/heading_hold" value="0"/>
<notify>
<property>velocities/vc-kts</property>
<property>position/h-agl-ft</property>
</notify>
</event> <event name="Trim">
<condition>simulation/sim-time-sec ge 0.50</condition>
<set name="simulation/do_simple_trim" value="0"/>
<notify>
<property>velocities/vc-kts</property>
<property>position/h-agl-ft</property>
</notify>
</event> <event name="Set roll autopilot">
<condition>simulation/sim-time-sec ge 5.0</condition>
<set name="ap/attitude_hold" value="1"/>
<notify>
<property>velocities/vc-kts</property>
<property>position/h-agl-ft</property>
</notify>
</event> </run>
第一行:可以看到飞机文件用的是c172x.xml 初始化文件用的是:reset01.xml
第二行:表示执行的过程,0到200秒,间隔帧数是0.008秒
第四行:event代表事件处理:
遇到condition的条件成立就执行后面的set步骤
以上是整体框架。
下面开启我们的疑问列表:
1.飞机文件c172x.xml是干什么的?初始化文件又初始化哪些东西?
2.第五行中的 sim-time-sec是什么意思?表达式是完成什么条件?
3.哪些和自动飞行控制有关?
。。。。。。
1.飞机文件c172x.xml是干什么的?初始化文件又初始化哪些东西?
答1:飞机文件c172x.xml是在“飞机脚本aircraft”文件夹下的c172x文件夹中,
初始化文件reset01.xml也在这个文件夹中。
初始化文件很简单:
<initialize name="reset00">
<vt unit="KTS"> 100.0 </vt>
<latitude unit="DEG"> 28.0 </latitude>
<longitude unit="DEG"> -90.0 </longitude>
<psi unit="DEG"> 200.0 </psi>
<altitude unit="FT"> 4000.0 </altitude>
<running> 0 </running>
</initialize>
初始化了飞机的位置,姿态等信息
飞机定义文件c172x.xml包含了很多东西,但我们只关心部分代码:
。。。
<system file="GNCUtilities"/> <system file="Autopilot">
<property value="0.523"> guidance/roll-angle-limit </property>
<property value="0.174"> guidance/roll-rate-limit </property>
</system> <autopilot file="c172ap"/> <flight_control name="c172">
<channel name="Pitch">
<summer name="fcs/pitch-trim-sum">
<input>ap/elevator_cmd</input>
<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/elevator-control">
<input>fcs/pitch-trim-sum</input>
<range>
<min>-28</min>
<max> 23</max>
</range>
<gain>0.01745</gain>
</aerosurface_scale> <actuator name="fcs/elevator-actuator">
<input> fcs/elevator-control </input>
<lag> 60 </lag>
<bias> 0.002 </bias>
<hysteresis_width> 0.05 </hysteresis_width>
<clipto>
<!-- +/- 20 degrees -->
<min> -0.34 </min>
<max> 0.34 </max>
</clipto>
<output>fcs/elevator-pos-rad</output>
</actuator> </channel>
。。。
这里我们看到:飞机文件引用了两个和自动飞行相关的系统文件:GNCUtilities和 Autopilot
这个两个文件提供通用的自动飞行算法和组件
接着我们又看到这个c172飞机自定义了一个自动飞行的文件:c172ap
我们的问题列表又多了一个问题:4.自定义自动飞行文件c172ap做了哪些事情?
问题保留,我们接着看这个飞机文件:
飞机脚本文件提供了自己的飞行控制组件:
<flight_control name="c172">
这个里面又分成很多部分,我们只看一个通道:Pitch
里面有一个加法器定义一个属性值 <summer name="fcs/pitch-trim-sum">
这个值由三方输入参数构成:
1.ap/elevator_cmd
2.fcs/elevator-cmd-norm
3.fcs/pitch-trim-cmd-norm
其中的2和3都是在jsbsim中有明确绑定的 “成员变量”
只有1我们没见过
我们的问题列表又多了一个问题:5.输入参数ap/elevator_cmd在哪里定义?由什么提供输入?
似乎问题总在加多,但其实都在抽丝剥茧中变少变得更加具体,继续把Pitch通道看完:
我们看到这个加法器属性值fcs/pitch-trim-sum又作为输入参数被下一个算法使用,得到值fcs/elevator-control
这个值fcs/elevator-control又被fcs/elevator-actuator继续输入使用算出最终的输出fcs/elevator-pos-rad
这个通道Pitch就此结束。
这个通道是干什么的?为了计算飞机一个姿态参数的!(此文仅讨论自动驾驶部分)
先跳过其他问题,我们看4.自定义自动飞行文件c172ap做了哪些事情?
答4 这个是一个自定义的c172自动驾驶脚本 用来定义便于自动驾驶计算的一些值和自动驾驶算法 (飞机自动驾驶算法举例)
打开c172ap.xml文件发现自定义输出输出的地方:答5
<!-- INTERFACE PROPERTIES --> <property>ap/attitude_hold</property>
<property>ap/altitude_hold</property>
<property>ap/heading_hold</property>
<property>ap/altitude_setpoint</property>
<property>ap/heading_setpoint</property>
<property>ap/aileron_cmd</property>
<property>ap/elevator_cmd</property>
<property>ap/airspeed_setpoint</property>
<property>ap/airspeed_hold</property>
<property>ap/throttle-cmd-norm</property> <!-- INITIAL GAIN VALUES --> <property value="0.5"> ap/hdg-roll-err-c1 </property>
<property value="50.0"> ap/roll-pid-kp </property>
<property value="5.0"> ap/roll-pid-ki </property>
<property value="17.0"> ap/roll-pid-kd </property> <!-- <property>attitude/sensor/phi-rad</property> -->
还有自动驾驶算法函数:
关于c172机翼滚转自动算法 和 偏航自动驾驶算法:(统一为roll通道提供算法,暂时忽略)
<!--
=====================================================
ROLL CHANNEL
=====================================================
--> <!-- Wing leveler --> <channel name="Roll wing leveler"> <sensor name="fcs/attitude/sensor/phi-rad">
<input> attitude/phi-rad </input>
<lag> 0.5 </lag>
<delay> 2 </delay>
<noise variation="PERCENT" distribution="GAUSSIAN"> 0.05 </noise>
<quantization name="attitude/sensor/quantized/phi-rad">
<bits> 12 </bits>
<min> -3.1416 </min>
<max> 3.1416 </max>
</quantization>
<bias> 0.001 </bias>
</sensor> <switch name="fcs/wing-leveler-ap-on-off">
<default value="-1"/>
<test value="0">
ap/attitude_hold == 1
</test>
</switch> <pid name="fcs/roll-ap-error-pid">
<input>attitude/phi-rad</input>
<kp> ap/roll-pid-kp </kp>
<ki> ap/roll-pid-ki </ki>
<kd> ap/roll-pid-kd </kd>
<trigger> fcs/wing-leveler-ap-on-off </trigger>
</pid> <switch name="fcs/roll-ap-autoswitch">
<default value="0.0"/>
<test value="-fcs/roll-ap-error-pid">
ap/attitude_hold == 1
</test>
</switch> </channel> <!-- Heading hold --> <channel name="Roll heading hold">
<pure_gain name="fcs/heading-true-degrees">
<input>attitude/heading-true-rad</input>
<gain>57.3</gain> <!-- convert to degrees -->
</pure_gain> <summer name="fcs/heading-error">
<input> -fcs/heading-true-degrees</input>
<input> ap/heading_setpoint </input>
</summer> <switch name="fcs/heading-error-bias-switch">
<default value="0.0"/>
<test value="360.0">
fcs/heading-error lt -180
</test>
<test value="-360.0">
fcs/heading-error gt 180
</test>
</switch> <summer name="fcs/heading-corrected">
<input> fcs/heading-error-bias-switch </input>
<input> fcs/heading-error </input>
<clipto>
<min>-30</min>
<max>30</max>
</clipto>
</summer> <pure_gain name="fcs/heading-command">
<input> fcs/heading-corrected </input>
<gain> 0.01745 </gain>
</pure_gain> <lag_filter name="fcs/heading-roll-error-lag">
<input> fcs/heading-command </input>
<c1> ap/hdg-roll-err-c1 </c1>
</lag_filter> <summer name="fcs/heading-roll-error">
<input> fcs/heading-roll-error-lag </input>
<input> -attitude/phi-rad </input>
</summer> <switch name="fcs/heading-roll-error-switch">
<default value="0.0"/>
<test value="fcs/heading-roll-error">
ap/heading_hold == 1
</test>
</switch> <pid name="fcs/heading-pi-controller">
<input> fcs/heading-roll-error-switch </input>
<kp> 6.0 </kp>
<ki> 0.13 </ki>
<kd> 6.0 </kd>
</pid> <switch name="fcs/roll-command-selector">
<default value="0.0"/>
<test value="fcs/heading-pi-controller">
ap/heading_hold == 1
gear/unit[2]/WOW == 0
</test>
<test value="fcs/roll-ap-autoswitch">
ap/attitude_hold == 1
gear/unit[2]/WOW == 0
</test>
<output>ap/aileron_cmd</output>
</switch>
<!--
<switch name="fcs/roll-command-selector-steering">
<default value="0.0"/>
<test value="fcs/heading-pi-controller">
ap/heading_hold == 1
gear/unit/WOW == 1
</test>
<output>fcs/steer-cmd-norm</output>
</switch>
-->
</channel>
关于c172高度保持自动驾驶算法:(为pitch通道提供算法,开始分析)
<!--
=====================================================
PITCH CHANNEL
=====================================================
--> <!-- Altitude hold --> <!-- The Altitude Error component below computes the altitude error, subtracting
the desired altitude (altitude_setpoint) from the actual altitude above sea
level (_not_ Above Ground Level). This error signal is interpreted as an
hdot command (hdot is time rate of change of altitude, or rate of climb). As
such it is limited to a maximum absolute value of 12 fps here (720 fpm). The
maximum achievable climb rate depends on altitude. The commanded climb rate
is scheduled in the HDot Command component, below. For the given altitude
(left column in the table), the commanded maaximum climb rate divided by 100
is given in the right column.
下方的“高度误差”组件计算高度误差,从海平面以上的实际高度(_not_高于地面高度)减去所需的高度(altitude_setpoint)。
该错误信号被解释为hdot命令(hdot是高度变化的时间速率或爬升速率)。 因此,这里限制为最大绝对值12 fps(720 fpm)。
可达到的最大爬升率取决于高度。 命令爬升率安排在下面的HDot Command组件中。
对于给定的高度(表中的左栏),在右栏中给出了命令的最大爬升率除以100。
--> <channel name="Pitch altitude hold"> <!--
The difference between the desired altitude and the actual altitude
is determined, and limited to 100. The output from this component is
the desired climb rate in percent of maximum.
确定所需高度与实际高度之间的差异,并将其限制为100.此组件的输出是所需的爬升率,以最大百分比表示
-->
<summer name="fcs/altitude-error">
<input> ap/altitude_setpoint </input>
<input> -position/h-agl-ft </input>
<clipto>
<min>-100</min>
<max> 100</max>
</clipto>
</summer> <!--
The desired climb rate is lagged slightly for stability.
为了稳定性,所需的爬升率略有滞后
-->
<lag_filter name="fcs/alt-error-lag">
<input> fcs/altitude-error </input>
<c1> 1 </c1>
</lag_filter> <!--
Dependent on altitude, the lagged (and limited) altitude error is multipled
by the scheduled gain determined from the table, below. The output from this
component is the absolute climb rate in feet/second. For example, if the desired
climb rate is 100 percent of maximum and the current altitude is 1000.0 ft., then
the output from this component would be 11 ft. sec.
取决于高度,滞后(和有限)高度误差乘以从下表中确定的预定增益。 该组件的输出是以英尺/秒为单位的绝对爬升率。
例如,如果所需爬升率为最大值的100%且当前海拔高度为1000.0英尺,则此组件的输出将为11英尺/秒。
-->
<scheduled_gain name="fcs/hdot-command">
<input> fcs/alt-error-lag </input>
<table>
<independentVar>position/h-sl-ft</independentVar>
<tableData>
0.0 0.12
1000.0 0.11
2000.0 0.10
3000.0 0.096
4000.0 0.093
5000.0 0.086
6000.0 0.078
7000.0 0.069
8000.0 0.061
9000.0 0.053
10000.0 0.045
11000.0 0.037
12000.0 0.028
</tableData>
</table>
</scheduled_gain> <!--
This component calculates the climb rate error, taking the difference between
the commanded climb rate (from the previous component) and actual climb rate
in ft./sec.
该组件计算爬升率误差,取命令爬升率(来自前一个组件)与实际爬升率之间的差值,单位为英尺/秒。
-->
<summer name="fcs/hdot-error">
<input> fcs/hdot-command </input>
<input> -velocities/h-dot-fps </input>
</summer> <!--
If the altitude hold autopilot command is ON, then this switch component will
pass through the climb rate error (from the previous component). Otherwise, it
will pass zero.
如果高度保持自动驾驶仪命令为ON,则此开关组件将通过爬升率误差(来自前一个组件)。 否则,它将传递零
-->
<switch name="fcs/ap-alt-hold-switch">
<default value="0.0"/>
<test value="fcs/hdot-error">
ap/altitude_hold == 1
</test>
</switch> <!--
The windup trigger below assumes the elevator will travel +/-23 degrees. The
elevator, however, does not travel symmetrically. This will need to be addressed
in a fix to the deadband component.
下面的饱和触发器假定电梯将行驶+/- 23度。 然而,电梯不对称地行进。 这需要通过修复死区组件来解决
-->
<deadband name="fcs/windup-trigger">
<input> fcs/elevator-pos-deg </input>
<width>46.0</width>
</deadband> <!--
The integrator integrates the hdot error (when the switch component passes that
signal through above when the altitude hold is selected ON). In the situation
where the elevator becomes saturated, the integrator ceases to integrate. The
windup protection is indicated below, with the windup-trigger property being
the trigger to halt integration. When the windup trigger is non-zero (when the
elevator position falls outside the range +/- 23 degrees - a deadband of 46
degrees) then the deadband passes a non-zero value, triggering the anti-windup
logic in the integrator. The proportional component multiplies the error signal by a constant, providing
the proportional control action of this PI altitude hold controller. The pid component combines the proportional and integral control
signals. It clips the sum to +/- 1.0.
积分器集成了hdot错误(当选择高度保持为ON时,当开关组件通过上面的信号时)。
在电梯变得饱和的情况下,积分器停止积分。 饱和保护如下所示,其中windup-trigger属性是停止积分的触发器。
当卷绕触发器非零时(当电梯位置落在+/- 23度范围之外 - 死区为46度时),死区通过非零值,触发积分器中的抗饱和逻辑。
比例分量将误差信号乘以常数,提供该PI高度保持控制器的比例控制动作。
pid组件结合了比例和积分控制信号。 它将总和剪辑为+/- 1.0。
--> <pid name="fcs/altitude-hold-pid">
<input> fcs/ap-alt-hold-switch </input>
<kp> 0.01 </kp>
<ki> 0.00015 </ki>
<kd> 0.0003 </kd>
<trigger> fcs/windup-trigger </trigger>
<clipto> <min>-1.0</min>
<max> 1.0</max> </clipto>
</pid> <!--
The elevator component flips the sign on the output of the control summer
above and sets the ap/elevator_command property.
电梯组件翻转上面控制夏季输出上的标志并设置ap / elevator_command属性
-->
<pure_gain name="fcs/elevator">
<input> fcs/altitude-hold-pid </input>
<gain> -1.0 </gain>
<output> ap/elevator_cmd </output>
</pure_gain>
</channel>
这个高度保持最后输出就是,之前在飞机文件里使用的参数ap/elevator_cmd (答5)
我们这里似乎又要添加新的疑问列表了:
6.可以计算出ap/elevator_cmd的输入参数ap/altitude_setpoint,从哪里设置?
答6:我在另外一个脚本文件c1723.xml中找到了ap/altitude_setpoint的输入。
于是我发现c1722.xml的脚本文件并没有用到自动驾驶的pitch通道。
于是,我重新比对c1723.xml和c1722.xml中关于自动驾驶的使用,可以回答问题3和问题2
答2: sim-time-sec是仿真的时间,限定条件是到达某个设定时间坐某事event
答3:c1722.xml没有使用很多自动驾驶功能,只有其中ap/heading_hold和ap/attitude_hold是和自动驾驶有关的。
ap/heading_hold 和 ap/attitude_hold 是在在c172ap.xml自定义文件中的自定义属性值
用来参与自定义的自动驾驶计算,算出的值,例如:ap/elevator_cmd
ap/elevator_cmd将会送入自定义的飞机文件中,作为飞控的某一个通道的输入参数使用。
至此1到6所有疑问都已解答,并了解了自动驾驶的简单使用过程。
下面我们尽量深入分析自动驾驶,来看脚本文件:c1723.xml
。。。
<event name="engine start">
<description>Start the engine and set roll control to heading hold启动发动机并将滚动控制设置为航向保持</description>
<condition> sim-time-sec >= 0.25 </condition>
<set name="fcs/throttle-cmd-norm" value="1.0" action="FG_RAMP" tc ="0.5"/>
<set name="fcs/mixture-cmd-norm" value="1.00" action="FG_RAMP" tc ="0.5"/>
<set name="propulsion/magneto_cmd" value="3"/>
<set name="propulsion/starter_cmd" value="1"/>
<set name="ap/roll-attitude-mode" value="1"/>
<set name="ap/autopilot-roll-on" value="1"/>
<notify>
<property>simulation/run_id</property>
<property>ap/hdg-roll-err-c1</property>
</notify>
</event> <event name="Begin roll">
<description>Release brakes and get rolling with flaps at 10 degrees.松开制动器,襟翼滚动10度 </description>
<condition> sim-time-sec >= 2.0 </condition>
<set name="fcs/left-brake-cmd-norm" value="0"/>
<set name="fcs/right-brake-cmd-norm" value="0"/>
<set name="fcs/center-brake-cmd-norm" value="0"/>
<set name="fcs/flap-cmd-norm" value="0.33"/>
</event> <event name="Rotate">
<description>Set Autopilot for 400 ft and rotate at 49 keas.当空速达到49 节时,,将自动驾驶目标高度设置为400英尺</description>
<notify/>
<condition> velocities/vc-kts >= 49 </condition>
<set name="ap/altitude_setpoint" value="400.0"/>
<set name="ap/altitude_hold" value="1"/>
<set name="ap/roll-attitude-mode" value="1"/>
</event> <event name="Set autopilot for 6000 ft.">
<description>Set Autopilot for 6000 ft after a five second delay. 当空速达到49 节时,5秒延迟后将自动驾驶目标高度设置为6000英尺</description>
<notify/>
<condition> velocities/vc-kts >= 49 </condition>
<delay>5.0</delay>
<set name="ap/altitude_setpoint" value="6000.0"/>
</event> 。。。
就看其中的四个事件,简要分析
1."engine start" 启动发动机并将滚动控制设置为航向保持
<set name="ap/roll-attitude-mode" value="1"/>
<set name="ap/autopilot-roll-on" value="1"/>
2."Begin roll" 松开制动器,襟翼滚动10度
3."Rotate" 当空速达到49 节时,,将自动驾驶目标高度设置为400英尺
<set name="ap/altitude_setpoint" value="400.0"/>
<set name="ap/altitude_hold" value="1"/>
<set name="ap/roll-attitude-mode" value="1"/>
4."Set autopilot for 6000 ft." 当空速达到49 节时,5秒延迟后将自动驾驶目标高度设置为6000英尺
<set name="ap/altitude_setpoint" value="6000.0"/>
这里用了几个自定义的自动驾驶的参数:
ap/roll-attitude-mode 在系统systems的Autopilot.xml文件中定义 0机翼控制 1滚转角保持
ap/autopilot-roll-on 在系统systems的Autopilot.xml文件中定义 0 关闭 1 打开 自动驾驶系统
ap/altitude_setpoint 在自定义文件c172ap.xml中文件中定义 需要脚本输入的目标高度 单位:英尺(FT)
ap/altitude_hold 在自定义文件c172ap.xml中文件中定义 需要脚本输入控制 高度保持是否开启 0关闭 1开启