起飞逻辑控制代码(runway.cpp),外环控制逻辑(fw_pos_control_l1文件夹),L1导航代码(ecl_l1_pos_controller.cpp)、总能量控制(tecs.cpp).
自动起飞逻辑
SuperG与自动飞行相关的代码都在fw_pos_control_l1_mian.cpp中,下面就其中起飞部分的逻辑进行分析。
在外环控制的主函数中,对由navigator模块所传来的航点类型进行判断,根据不同的航点类型,执行不同的控制逻辑。当航点类型为SETPOINT_TYPE_TAKEOFF时,执行起飞部分代码。
首先进行的是滑跑逻辑判断,如果运行的是滑跑起飞的逻辑,则判断滑跑所需要的参数是否初始化,如果未进行初始化,则初始化当先滑跑所需要的参数。
图2 滑跑参数初始化函数
滑跑初始化函数如图2所示,所需要的参数为当前的偏航值以及当前的经纬度。可以看到在初始化时,主函数中将当前的姿态存为四元数,通过q.to_euler函数将四元数转换为姿态角(在px4代码中,有关于欧拉角的姿态都是存成四元数,再需要欧拉角的部分时将其再转换成欧拉角,这样可以有效地避免万向节锁的问题),其中转换后的euler(2)就代表着当前的偏航值。最后,将当前飞机的高度赋值给起飞地面的高度。然后通过mavlink输出‘以滑跑的方式起飞’。
下一步执行判断地面高度函数,如果global_pos中估计的地面高度可以得到并且其数据无误,那么地面高度就为global_pos中估计的地面高度。如果global_pos中的数据不能得到或者检查有问题,那么就用飞机进入起飞状态的高度作为地面高度。
图3 判断地面高度函数
在主函数中下一步执行_runway_takeoff.update()函数,此函数为整个起飞控制的核心,相当于起飞状态的一个状态机。所有起飞逻辑都在这个函数中进行判断和转换,runway_takeoff中的其他函数通过判断当前的起飞逻辑状态而执行不同的指令。
图4 滑跑起飞的状态机函数
函数所需要的参数为当前的空速,高度,经纬度,以及一个用来给地面站输出当前滑跑状态的mavlink_log_pub地址。其函数的就是判断当前的状态以及完成相应的状态转换,_state变量表示当前状态。_state中的状态有
(1) PREROTATE 预旋状态
此状态为SuperG的初始状态,在PERROTATE状态中判断初始化滑跑逻辑是否超过10s中,如果超过10s,则将当前的PERROTATE状态转化为THROTTLE_RAMP状态。否则就一直将_prerotate变量置ture,SuperG进行预旋(预旋的指令会存入att_sp中,然后通过内环控制.cpp读取att_sp值并将其赋给控制通道5,即预旋通道)
(2) THROTTLE_RAMP 油门斜坡加速状态
在此状态会停留2s,一进入该状态则将_prerotate变量置false,关闭预旋,同时将油门从0逐渐加速到最大油门(在参数列表中可以设定)。2s过后,状态转换为CLAMPED_TO_RUNWAY
(3) CLAMPED_TO_RUNWAY滑跑状态
在此状态中,SuperG用最大速度进行滑跑,同时此时的俯仰角期望为_runway_pitch_sp,由地面站进行设定,在此状态之后的几个状态,俯期望俯仰角都由总能量控制算法给定。进行判断,如果飞机的当前速度大于给定的起飞速度,状态转换为TAKEOFF
(4) TAKEOFF起飞状态
当高度小于_nav_alt(地面站设定)的时候,SuperG处于TAKEOFF状态,当高度大于_nav_alt的时候,SuperG转入CLIMBOUT状态。在此状态以前4个状态中,superG为了保持航向,都会通过轮子或者方向舵进行偏航角控制,而在后面两个状态中不会进行给定偏航角控制。在TAKEOFF之前的状态中俯仰角,滚转角的积分状态会被清零,保证在地面的状态的积分不会对空中造成干扰。
(5) CLIMBOUT 爬升状态
当高度小于_climbout_diff.(地面站设定),飞机处于爬升状态,爬升到指定高度后切换进入FLY状态进行正常的航点飞行,在此状态之前的4个状态,期望的滚转角都为0,在此状态中,期望的滚转角由L1导航算法给定,但会有一个正负max_takeoff_roll的限幅保证在此阶段滚转角指令不会过大
(6) FLY 飞行状态
飞机由目前的点向起飞航点飞行。其控制算法为总能量控制和L1导航控制,其实到达这个状态基本的起飞过程已经完成,已经与正常的航线飞行无异。
图5 起飞过程的后续逻辑
可以看出,后续的状态就是通过L1导航算出期望的滚转角,总能量控制算出期望的俯仰角。并对其进行限幅。在其给att_sp的赋值部分,我们判断起飞逻辑的状态,如果runwaytakeof 中的_prerotate的值为真,则将att_sp.pretotate值赋1,runwaytakeof 中的_prerotate的值为假,则将att_sp.pretotate值赋0,完成了对预旋状态的控制。其后的att_sp赋值部分如上面对起飞状态部分的描述,都是对不同起飞状态下的总能量控制和L1导航的姿态指令进行限幅和积分置0操作。
图6 起飞状态的油门输出
如果进入的是自动模式,当前航点类型为起飞航点,则期望的油门由runwat_takeoff中的getThrottle函数设定。函数原型如下
图7起飞状态的油门输出
当起飞状态为预旋状态时,油门输出为0,然后进行斜坡加速油门状态,最后进行最大的油门状态,CLAMPED_TO_RUNWAY状态中的油门实际是设定的最大油门,随后的油门都是有总能量控制给定。
2.3. 仿真结果
图8 自主起飞,航线飞行,自主降落过程半物理仿真飞行轨迹