ardupilot 关于设备车Rover的学习《3》------模式控制

目录


摘要


本节主要记录ardupilot中小车rover代码是如何进行模式更新的,欢迎批评指正!


1.模式简介


rover中主要用的模式如下:

    //自动飞行模式----- Auto Pilot modes
    // ----------------
    enum Number : uint8_t {
        MANUAL       = 0,  //手动模式
        ACRO         = 1,  //速率模式
        STEERING     = 3,  //转向模式
        HOLD         = 4,  //保持模式
        LOITER       = 5,  //悬停模式
        FOLLOW       = 6,  //跟随模式
        SIMPLE       = 7,  //简单模式
        AUTO         = 10, //自动模式
        RTL          = 11, //返航模式
        SMART_RTL    = 12, //智能返航模式
        GUIDED       = 15, //引导模式
        INITIALISING = 16  //初始化模式
    };

这种主要比较常用的模式:手动模式 ,保持模式 ,悬停模式,自动模式,返航模式。


2.如何设置模式


一般设置模式主要是通过模式开关5通道来实现,也可以通过辅助开关实现,本节主要讲解通过5通道模式开关来实现。
打开MP地面站通过MP地面站直接设置,或者通过全局参数来实现模式的设置。
在这里插入图片描述


3.模式代码实现


    SCHED_TASK_CLASS(RC_Channels,         (RC_Channels*)&rover.g2.rc_channels, read_mode_switch,        7,    200,  57), //读取模式开关

读取模式开关

void RC_Channels::read_mode_switch()
{
	//判断遥控是否有效
    if (!has_valid_input()) 
    {
        //如果没有遥控器输入立即退出------ exit immediately when no RC input
        return;
    }
    //读取遥控器模式通道值
    RC_Channel *c = flight_mode_channel();
    //没有设置,立即返回
    if (c == nullptr) 
    {
        return;
    }
    //数据读取
    c->read_mode_switch();
}
void RC_Channel::read_mode_switch()
{
    int8_t position;
    //读取6段开关的位置
    if (read_6pos_switch(position)) 
    {
        //设置飞行模式和简单模式设置---- set flight mode and simple mode setting
        mode_switch_changed(modeswitch_pos_t(position));
    }
}

根据开关位置设置对应的模式

void RC_Channel_Rover::mode_switch_changed(modeswitch_pos_t new_pos)
{
    if (new_pos < 0 || (uint8_t)new_pos > rover.num_modes) 
    {
        //直接返回---- should not have been called
        return;
    }
    //根据所在位置设置相对的模式
    rover.set_mode((Mode::Number)rover.modes[new_pos].get(), ModeReason::RC_COMMAND);
}

到这里最重要的就是实现函数了。

rover.set_mode((Mode::Number)rover.modes[new_pos].get(), ModeReason::RC_COMMAND);
bool Rover::set_mode(const uint8_t new_mode, ModeReason reason)
{
	//检查
    static_assert(sizeof(Mode::Number) == sizeof(new_mode), "The new mode can't be mapped to the vehicles mode number");
    //读取模式
    Mode *mode = rover.mode_from_mode_num((enum Mode::Number)new_mode);
    //是否为空
    if (mode == nullptr) 
    {
        notify_no_such_mode(new_mode);
        return false;
    }
    //设置进去
    return rover.set_mode(*mode, reason);
}
Mode *Rover::mode_from_mode_num(const enum Mode::Number num)
{
    Mode *ret = nullptr;
    switch (num) {
    case Mode::Number::MANUAL: //手动
        ret = &mode_manual;
        break;
    case Mode::Number::ACRO:  //速率
        ret = &mode_acro;
        break;
    case Mode::Number::STEERING: //转向
        ret = &mode_steering;
        break; 
    case Mode::Number::HOLD: //保持
        ret = &mode_hold;
        break;
    case Mode::Number::LOITER: //定点
        ret = &mode_loiter;
        break;
    case Mode::Number::FOLLOW: //跟随
        ret = &mode_follow;
        break;
    case Mode::Number::SIMPLE: //简单模式
        ret = &mode_simple;
        break;
    case Mode::Number::AUTO:  //自动模式
        ret = &mode_auto;
        break;
    case Mode::Number::RTL:   //返航模式
        ret = &mode_rtl;
        break;
    case Mode::Number::SMART_RTL: //智能返航模式
        ret = &mode_smartrtl;
        break;
    case Mode::Number::GUIDED:  //引导模式
        ret = &mode_guided;
        break;
    case Mode::Number::INITIALISING: //初始化模式
        ret = &mode_initializing;
        break;
    default:
        break;
    }
    return ret;
}

最后调用设置模式:

    //设置进去
    return rover.set_mode(*mode, reason);
bool Rover::set_mode(Mode &new_mode, ModeReason reason)
{
	//判断模式是否最新
    if (control_mode == &new_mode) 
    {
        //don't switch modes if we are already in the correct mode.
    	//如果我们已经处于正确的模式,请不要切换模式。
        return true;
    }
    //记录老的模式
    Mode &old_mode = *control_mode;
    //判断模式
    if (!new_mode.enter()) 
    {
        //Log error that we failed to enter desired flight mode
    	//日志错误:我们未能进入所需的飞行模式
        AP::logger().Write_Error(LogErrorSubsystem::FLIGHT_MODE,
                                 LogErrorCode(new_mode.mode_number()));
        gcs().send_text(MAV_SEVERITY_WARNING, "Flight mode change failed");
        return false;
    }

    control_mode = &new_mode;

    // pilot requested flight mode change during a fence breach indicates pilot is attempting to manually recover
    // this flight mode change could be automatic (i.e. fence, battery, GPS or GCS failsafe)
    // but it should be harmless to disable the fence temporarily in these situations as well
    //在围栏破裂期间,飞行员请求的飞行模式改变表明飞行员正试图手动恢复
    //这种飞行模式改变可以是自动的(即围栏、电池、GPS或GCS故障保护)
    //但在这些情况下暂时关闭围栏也是无害的
    g2.fence.manual_recovery_start();

#if CAMERA == ENABLED
    camera.set_is_auto_mode(control_mode->mode_number() == Mode::Number::AUTO);
#endif

    old_mode.exit();

    control_mode_reason = reason;
    logger.Write_Mode(control_mode->mode_number(), control_mode_reason);
    gcs().send_message(MSG_HEARTBEAT);

    notify_mode(control_mode);
    return true;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔城烟雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值