Pixhawk原生固件PX4之TAKEOFF的启动流程

欢迎交流~ 个人 Gitter 交流平台,点击直达:Gitter


以TAKEOFF为例说明PX4中一个飞行模式的启动流程

  • 众所周知由遥控器或者地面站决定Main state作为用户期望到达的飞行模式

  • 然后有commander进行条件判断后输出一个Navigation state作为飞机最终的飞行模式

  • 进而由navigator模块中的函数作为具体的飞行模式实现方法

  • 具体的实现还得看位置控制


一、 首先从commander.cpp选中TAKEOFF开始

if (!strcmp(argv[1], "takeoff"))

comm

这里需要注意的是

cmd.command = vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF;

此结构体vehicle_command_s cmd被赋值,用户希望进入TAKEOFF模式。

这里省略对是否能切换到该模式的条件判断,直接进入TAKEOFF导航模式set_control_mode()

void
set_control_mode()
{
    /* set vehicle_control_mode according to set_navigation_state */
    ...
    switch (status.nav_state) {
    ...
    case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF:
        control_mode.flag_control_manual_enabled = false;
        control_mode.flag_control_auto_enabled = true;
        control_mode.flag_control_rates_enabled = true;
        control_mode.flag_control_attitude_enabled = true;
        control_mode.flag_control_rattitude_enabled = false;
        control_mode.flag_control_altitude_enabled = true;
        control_mode.flag_control_climb_rate_enabled = true;
        control_mode.flag_control_position_enabled = !status.in_transition_mode;
        control_mode.flag_control_velocity_enabled = !status.in_transition_mode;
        control_mode.flag_control_acceleration_enabled = false;
        control_mode.flag_control_termination_enabled = false;
        break;
        ...
    }

二、 进入navigator_main函数

① 在主函数中完成对vehicle_command话题的检查更新后,根据commander中的模式选择为当前的结构体rep赋值

if (cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF) {
/ TAKEOFF 起飞
    struct position_setpoint_triplet_s *rep = get_takeoff_triplet(); // takeoff_triplet

    // store current position as previous position and goal as next
    // 将现在的位置作为之前的位置存起来,将目标位置作为下一个航点
    rep->previous.yaw = get_global_position()->yaw;
    rep->previous.lat = get_global_position()->lat;
    rep->previous.lon = get_global_position()->lon;
    rep->previous.alt = get_global_position()->alt;

    rep->current.loiter_radius = get_loiter_radius();
    rep->current.loiter_direction = 1; // 顺时针
    rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;
    rep->current.yaw = cmd.param4; // 偏航角(if magnetometer present), ignored without magnetometer

    /****
    MAV_CMD_NAV_TAKEOFF Takeoff from ground / hand
    Mission Param #1    Minimum pitch (if airspeed sensor present), desired pitch without sensor
    Mission Param #2    Empty
    Mission Param #3    Empty
    Mission Param #4    Yaw angle (if magnetometer present), ignored without magnetometer
    Mission Param #5    Latitude
    Mission Param #6    Longitude
    Mission Param #7    Altitude
    *****/

    if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {
        rep->current.lat = (cmd.param5 < 1000) ? cmd.param5 : cmd.param5 / (double)1e7;
        rep->current.lon = (cmd.param6 < 1000) ? cmd.param6 : cmd.param6 / (double)1e7;
    } else {
            // If one of them is non-finite, reset both
            rep->current.lat = NAN;
            rep->current.lon = NAN;
            }

    rep->current.alt = cmd.param7;

    rep->previous.valid = true;
    rep->current.valid = true;
    rep->next.valid = false;

}

② 根据commander设定的导航状态进入相应导航模式

switch (_vstatus.nav_state) {
...
    case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF:
        _pos_sp_triplet_published_invalid_once = false;
        _navigation_mode = &_takeoff; // takeoff模式
        break;
...
}

③ 遍历导航模式,并为每个模式设置active/inactive

 /* iterate through navigation modes and set active/inactive for each */
// 遍历导航模式,并为每个模式设置active/inactive
for (unsigned int i = 0; i < NAVIGATOR_MODE_ARRAY_SIZE; i++) {
_navigation_mode_array[i]->run(_navigation_mode == _navigation_mode_array[i]);
}

由②已经知道_navigation_mode = &_takeoff,所以这里run激活的是takeoff飞行模式。其中

_navigation_mode_array[0] = &_mission;
_navigation_mode_array[1] = &_loiter;
_navigation_mode_array[2] = &_rtl;
_navigation_mode_array[3] = &_dataLinkLoss;
_navigation_mode_array[4] = &_engineFailure;
_navigation_mode_array[5] = &_gpsFailure;
_navigation_mode_array[6] = &_rcLoss;
_navigation_mode_array[7] = &_takeoff;
_navigation_mode_array[8] = &_land;
_navigation_mode_array[9] = &_follow_target;

注意: navigator模块中每一种模式都对应有on_inactive 、on_activation和on_active三个模式,由NavigatorMode::run(bool active)选择

void
NavigatorMode::run(bool active)
{
    if (active) {
        if (_first_run) { // 首次运行
            /* first run */
            _first_run = false;
            /* Reset stay in failsafe flag */
            _navigator->get_mission_result()->stay_in_failsafe = false;
            _navigator->set_mission_result_updated();
            /* 当模式激活时此函数会被调用一次,pos_sp_triplet必须在此初始化 */
            on_activation(); // 运行我

        } else { 
            /* 模式已激活时调用此函数 */
            on_active(); // 实际功能实现
        }

    } else {
        /* 模式未激活时调用此函数 */
        _first_run = true;
        // 
        on_inactive();
    }
}

由此可见一个模式的启用在navigator中是先经过on_activation()初始化,然后在on_active完成功能实现。

三、 takeoff过程

TAKEOFF其实没有什么好说的,必须有GPS才可以。

首先初始化home点的航点信息set_takeoff_position(),然后起飞MIS_TAKEOFF_ALT高度后悬停_navigator->set_can_loiter_at_sp(true)


                                          By Fantasy

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 原生Android TV固件是指运行原生Android操作系统的电视设备的固件。与传统的定制化操作系统不同,原生Android TV固件基于Google开源的Android操作系统,提供了更纯净的用户体验和更丰富的功能。 原生Android TV固件的优势在于其稳定性和兼容性。由于采用了原生Android操作系统,它能够充分利用Google官方提供的最新更新和安全补丁,保证系统的稳定运行。同时,原生Android TV固件与其他Android设备具有高度的兼容性,可以轻松与各种应用和设备进行连接和交互,提供更广阔的应用选择和功能拓展空间。 此外,原生Android TV固件还提供了丰富的媒体功能和智能化体验。它支持高清视频播放、声音输出和网络连接,可以通过各种应用快速访问流媒体服务和在线视频内容。另外,原生Android TV固件还具有语音控制和智能推荐功能,用户可以通过语音命令轻松控制电视和应用,智能推荐算法也能够根据用户的观看习惯和喜好提供个性化的内容推荐。 然而,原生Android TV固件也有一些限制。由于操作系统的开放性和多样性,某些应用可能不适配或无法在原生Android TV上运行。此外,原生Android TV固件在硬件方面对电视设备的要求较高,低端设备可能无法提供流畅的使用体验。 总体而言,原生Android TV固件是一种值得推荐的选择,它提供了更稳定、兼容和智能化的电视体验,让用户能够享受到更多的媒体和应用内容。 ### 回答2: 原生Android TV固件是指由Google官方开发和维护的操作系统软件,专门为智能电视设备设计的。它采用了与智能手机和平板电脑相似的Android操作系统,并针对大屏幕和遥控器进行了优化。 原生Android TV固件具有以下特点: 1. 用户界面:原生Android TV固件提供了一个简洁、直观的用户界面,用户可以通过遥控器轻松地导航和操作电视。主屏幕上的应用图标和内容推荐帮助用户快速访问他们喜欢的应用和媒体内容。 2. 应用和媒体内容:原生Android TV固件兼容众多电视应用和媒体服务,包括影片、音乐、游戏和社交媒体等。用户可以通过Google Play商店下载和安装各种应用程序,以满足他们的个性化需求。 3. 语音控制:原生Android TV固件支持语音搜索和语音操作,用户可以通过麦克风遥控器或是电视内置的语音识别功能轻松实现语音控制。 4. 联网功能:原生Android TV固件可以通过内置的Wi-Fi或有线网络连接到互联网,用户可以浏览网页、观看在线视频和进行网络游戏等。 5. 兼容性:原生Android TV固件具有良好的兼容性,可与各种电视设备和外部设备(如音频系统、游戏手柄等)配对使用,并通过HDMI接口提供高清视频输出。 总之,原生Android TV固件为用户提供了一个全面的智能电视体验,结合了丰富的应用和媒体内容、简单直观的界面、语音控制和联网功能。它使用户能够轻松访问他们的喜爱内容,并提供了个性化、智能化的娱乐和信息服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值