• ardupilot 关于设备车Rover的学习《2》------如何解锁


    目录

    摘要


    本节主要记录ardupilot中ROVER小车是如何进行通过遥控器进行解锁的,欢迎批评指正!


    1.序言


    ardupilot 中ROVER小车通过遥控器解锁有两种方式:

    1. 通过遥控器的方向舵实现解锁
    2. 通过遥控器上外部开关实现解锁

    在进行代码讲解之前需要注意的是小车的遥控器控制通道的映射需要注意:

    void Rover::set_control_channels(void)
    {
        //检查RCMAP上的更改
        channel_steer    = rc().channel(rcmap.roll()-1);      //横滚通道映射到方向舵
        channel_throttle = rc().channel(rcmap.throttle()-1);  //油门通道映射到油门通道
        channel_lateral  = rc().channel(rcmap.yaw()-1);       //偏航通道映射转向通道
    
        //设置遥控器的范围
        channel_steer->set_angle(SERVO_MAX); //最大是4500
        channel_throttle->set_angle(100);    //设置0-100
        //横向是空的吗,不是就设置,是的话关闭
        if (channel_lateral != nullptr)
        {
            channel_lateral->set_angle(100); //设置100
        }
    
        //步行机器人rc输入初始化------ walking robots rc input init
        channel_roll = rc().find_channel_for_option(RC_Channel::AUX_FUNC::ROLL);   //横滚201
        channel_pitch = rc().find_channel_for_option(RC_Channel::AUX_FUNC::PITCH); //俯仰202
        channel_walking_height = rc().find_channel_for_option(RC_Channel::AUX_FUNC::WALKING_HEIGHT);//211
        //设定死区
        if (channel_roll != nullptr) 
        {
            channel_roll->set_angle(SERVO_MAX);
            channel_roll->set_default_dead_zone(30);
        }
        //设定死区
        if (channel_pitch != nullptr) 
        {
            channel_pitch->set_angle(SERVO_MAX);
            channel_pitch->set_default_dead_zone(30);
        }
        //设定死区
        if (channel_walking_height != nullptr) {
            channel_walking_height->set_angle(SERVO_MAX);
            channel_walking_height->set_default_dead_zone(30);
        }    
    
        //帆船rc输入初始化----- sailboat rc input init
        g2.sailboat.init_rc_in();
    
        //允许在未启用时重新配置输出------ Allow to reconfigure output when not armed
        if (!arming.is_armed()) 
        {
            g2.motors.setup_servo_output();
            //对于一个漫游者来说,安全是微调油门----- For a rover safety is TRIM throttle
            g2.motors.setup_safety_output();
        }
        // setup correct scaling for ESCs like the UAVCAN ESCs which
        // take a proportion of speed. Default to 1000 to 2000 for systems without
        // a k_throttle output
        //为诸如UAVCAN ESC之类的ESC设置正确的缩放
        //占速度的一部分。对于不带的系统,默认值为1000到2000
        //k_throttle 输出
        hal.rcout->set_esc_scaling(1000, 2000);
        g2.servo_channels.set_esc_scaling_for(SRV_Channel::k_throttle);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    从这里可以看出,如果我们遥控器是美国手,那么我们之前的横滚通道就是控制小车的方向舵,实现小车左右旋转;我们的油门通道还是控制小车的前进后退。

    2.解锁代码实现


    1.通过遥控器的方向舵实现解锁

    SCHED_TASK(read_radio,             50,    200,   3),//读取遥控器数据
    
    • 1
    void Rover::read_radio()
    {
    
    	//判断有没有遥控器输入数据
        if (!rc().read_input())
        {
            //检测假如我们丢失遥控器信号---- check if we lost RC link
            radio_failsafe_check(channel_throttle->get_radio_in());
            return;
        }
    
        failsafe.last_valid_rc_ms = AP_HAL::millis();
        //检测RC值是否有根据----- check that RC value are valid
        radio_failsafe_check(channel_throttle->get_radio_in());
    
        //检测我们尝试做遥控器解锁或者上锁----- check if we try to do RC arm/disarm
        if(g.rc_arm_enable==1)
        {
        	//方向舵解锁上锁操作
        	rudder_arm_disarm_check();	 //只有这个功能打开才能开启
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    由于小车有时候想不通过方向舵来解锁,以及限制解锁延迟时间,这里新增加一个参数g.rc_arm_enable来实现是否开启这个功能。当然默认代码也可以关闭这个功能,可以通过参数RUDDER来实现。


    在这里插入图片描述
    到这里我们重点只需要关注函数:rudder_arm_disarm_check(); 即可。

    void Rover::rudder_arm_disarm_check()
    {
        // check if arming/disarm using rudder is allowed
    	//检查是否允许使用方向舵进行防护/解除防护
        const AP_Arming::RudderArming arming_rudder = arming.get_rudder_arming_type();
        //如果设置没有使能,直接返回
        if (arming_rudder == AP_Arming::RudderArming::IS_DISABLED)
        {
            return;
        }
    
        // In Rover we need to check that its set to the throttle trim and within the DZ
        // if throttle is not within trim dz,then pilot cannot rudder arm/disarm
        //在ROVER我们需要检查油门是在中立或者死区范围内
        //如果油门不在死区范围内,则飞行员不能操纵舵/解除舵
        if (!channel_throttle->in_trim_dz())
        {
            rudder_arm_timer = 0;
            return;
        }
    
        //检查此模式是否允许启用/禁用------ check if arming/disarming allowed from this mode
        if (!control_mode->allows_arming_from_transmitter())
        {
            rudder_arm_timer = 0;
            return;
        }
        //判断是解锁
        if (!arming.is_armed())
        {
            // when not armed, full right rudder starts arming counter
        	//未启用时,右满舵开始启用计数器
            if (channel_steer->get_control_in() > 4000) //方向杆往右边解锁
            {
            	//获取现在时间
                const uint32_t now = millis();
                //数据判断,方向舵/转向装置已运行的时间
                if ((rudder_arm_timer == 0 )||(now - rudder_arm_timer < g.rc_arm_time_ms))
                {
                	//方向舵/转向装置已运行的时间
                    if (rudder_arm_timer == 0)
                    {
                    	//记录限制时间
                        rudder_arm_timer = now;
                    }
                } else
                {
                    //时间到了开始解锁------ time to arm!
                    arming.arm(AP_Arming::Method::RUDDER);
                    //记得把数据清零
                    rudder_arm_timer = 0;
                }
            } else
            {
                //没有在全右操作------ not at full right rudder
                rudder_arm_timer = 0;
            }
        } else if ((arming_rudder == AP_Arming::RudderArming::ARMDISARM) && !g2.motors.active())
        {
            // when armed and motor not active (not moving), full left rudder starts disarming counter
        	//当解锁和电机没有激活(不运动),全左方向舵开始解除待命计数器
            if (channel_steer->get_control_in() < -4000) //方向杆往左边上锁
            {
            	//获取现在时间
                const uint32_t now = millis();
                //数据判断
                if ((rudder_arm_timer == 0) ||(now - rudder_arm_timer < g.rc_arm_time_ms))
                {
                	//记录下开始记录的时间
                    if (rudder_arm_timer == 0)
                    {
                    	//传递时间,为数据判断做铺垫
                        rudder_arm_timer = now;
                    }
                } else
                {
                    //时间到了开始上锁----- time to disarm!
                    arming.disarm(AP_Arming::Method::RUDDER);
                    //数据清零
                    rudder_arm_timer = 0;
                }
            } else
            {
                //没有在最左边---- not at full left rudder
                rudder_arm_timer = 0;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    这段代码相对好懂,重点我增加了一个参数来实现对解锁延迟大小的设定,通过g.rc_arm_time_ms设定这个值就可以来实现解锁延迟了。

    2.通过遥控器上外部开关实现解锁

    要想实现通过外部开关进行解锁,首先先要把解锁的按键找到,比如我们用遥控器的7通道解锁,那就需要把7通道映射成解锁功能。

    在这里插入图片描述
    在这里插入图片描述
    做好映射之后,我们只需要看代码实现即可:

        //初始化遥控器通道数据------ initialise rc channels
        rc().convert_options(RC_Channel::AUX_FUNC::ARMDISARM_UNUSED, RC_Channel::AUX_FUNC::ARMDISARM);     //转换信息
        rc().convert_options(RC_Channel::AUX_FUNC::SAVE_TRIM, RC_Channel::AUX_FUNC::TRIM_TO_CURRENT_SERVO_RC);
        //初始化
        rc().init();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    void RC_Channels::init(void)
    {
        //对每个通道进行初始化 setup ch_in on channels
        for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) 
        {
            channel(i)->ch_in = i;
        }
        //初始化外部开关
        init_aux_all();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    外部通道初始化

    void RC_Channels::init_aux_all()
    {
        for (uint8_t i=0; i<NUM_RC_CHANNELS; i++) 
        {
            RC_Channel *c = channel(i);
            if (c == nullptr) 
            {
                continue;
            }
            //初始化
            c->init_aux();
        }
        //复位模式
        reset_mode_switch();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    void RC_Channel::init_aux()
    {
    	//外部开关的位置信息
        AuxSwitchPos position;
        //读取三段开关信息
        if (!read_3pos_switch(position)) 
        {
        	//没有读取到,应该设置低电平
            position = AuxSwitchPos::LOW;
        }
        //初始化外部开关
        init_aux_function((aux_func_t)option.get(), position);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    void RC_Channel::init_aux_function(const aux_func_t ch_option, const AuxSwitchPos ch_flag)
    {
        //初始化通道对应的功能-----init channel options
        switch(ch_option) {
        //以下功能不需要初始化:----- the following functions do not need to be initialised:
        case AUX_FUNC::ARMDISARM: //这里就是我们的上锁,解锁映射了
        case AUX_FUNC::CAMERA_TRIGGER:
        case AUX_FUNC::CLEAR_WP:
        case AUX_FUNC::COMPASS_LEARN:
        case AUX_FUNC::DISARM:
        case AUX_FUNC::DO_NOTHING:
        case AUX_FUNC::LANDING_GEAR:
        case AUX_FUNC::LOST_VEHICLE_SOUND:
        case AUX_FUNC::RELAY:
        case AUX_FUNC::RELAY2:
        case AUX_FUNC::RELAY3:
        case AUX_FUNC::RELAY4:
        case AUX_FUNC::RELAY5:
        case AUX_FUNC::RELAY6:
        case AUX_FUNC::VISODOM_ALIGN:
        case AUX_FUNC::EKF_LANE_SWITCH:
        case AUX_FUNC::EKF_YAW_RESET:
        case AUX_FUNC::GENERATOR: // don't turn generator on or off initially
        case AUX_FUNC::EKF_POS_SOURCE:
        case AUX_FUNC::TORQEEDO_CLEAR_ERR:
        case AUX_FUNC::SCRIPTING_1:
        case AUX_FUNC::SCRIPTING_2:
        case AUX_FUNC::SCRIPTING_3:
        case AUX_FUNC::SCRIPTING_4:
        case AUX_FUNC::SCRIPTING_5:
        case AUX_FUNC::SCRIPTING_6:
        case AUX_FUNC::SCRIPTING_7:
        case AUX_FUNC::SCRIPTING_8:
        case AUX_FUNC::VTX_POWER:
        case AUX_FUNC::OPTFLOW_CAL:
        case AUX_FUNC::TURBINE_START:
            break;
        case AUX_FUNC::AVOID_ADSB:
        case AUX_FUNC::AVOID_PROXIMITY:
        case AUX_FUNC::FENCE:
        case AUX_FUNC::GPS_DISABLE:
        case AUX_FUNC::GPS_DISABLE_YAW:
        case AUX_FUNC::GRIPPER:
        case AUX_FUNC::KILL_IMU1:
        case AUX_FUNC::KILL_IMU2:
        case AUX_FUNC::MISSION_RESET:
        case AUX_FUNC::MOTOR_ESTOP:
        case AUX_FUNC::RC_OVERRIDE_ENABLE:
        case AUX_FUNC::RUNCAM_CONTROL:
        case AUX_FUNC::RUNCAM_OSD_CONTROL:
        case AUX_FUNC::SPRAYER:
        case AUX_FUNC::DISABLE_AIRSPEED_USE:
    #if HAL_MOUNT_ENABLED
        case AUX_FUNC::RETRACT_MOUNT:
    #endif
            run_aux_function(ch_option, ch_flag, AuxFuncTriggerSource::INIT);
            break;
        default:
            gcs().send_text(MAV_SEVERITY_WARNING, "Failed to init: RC%u_OPTION: %u\n",
                               (unsigned)(this->ch_in+1), (unsigned)ch_option);
    #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
            AP_BoardConfig::config_error("Failed to init: RC%u_OPTION: %u",
                               (unsigned)(this->ch_in+1), (unsigned)ch_option);
    #endif
            break;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    然后会调用

    bool RC_Channel::run_aux_function(aux_func_t ch_option, AuxSwitchPos pos, AuxFuncTriggerSource source)
    {
    	//执行这里
        const bool ret = do_aux_function(ch_option, pos);
    
        // @LoggerMessage: AUXF
        // @Description: Auxiliary function invocation information
        // @Field: TimeUS: Time since system startup
        // @Field: function: ID of triggered function
        // @Field: pos: switch position when function triggered
        // @Field: source: source of auxillary function invocation
        // @Field: result: true if function was successful
        AP::logger().Write(
            "AUXF",
            "TimeUS,function,pos,source,result",
            "s#---",
            "F----",
            "QHBBB",
            AP_HAL::micros64(),
            uint16_t(ch_option),
            uint8_t(pos),
            uint8_t(source),
            uint8_t(ret)
            );
        return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    bool RC_Channel::do_aux_function(const aux_func_t ch_option, const AuxSwitchPos ch_flag)
    {
        switch(ch_option) {
        case AUX_FUNC::CAMERA_TRIGGER:
            do_aux_function_camera_trigger(ch_flag);
            break;
    
        case AUX_FUNC::FENCE:
            do_aux_function_fence(ch_flag);
            break;
    
        case AUX_FUNC::GRIPPER:
            do_aux_function_gripper(ch_flag);
            break;
    
        case AUX_FUNC::RC_OVERRIDE_ENABLE:
            // Allow or disallow RC_Override
            do_aux_function_rc_override_enable(ch_flag);
            break;
    
        case AUX_FUNC::AVOID_PROXIMITY:
            do_aux_function_avoid_proximity(ch_flag);
            break;
    
        case AUX_FUNC::RELAY:
            do_aux_function_relay(0, ch_flag == AuxSwitchPos::HIGH);
            break;
        case AUX_FUNC::RELAY2:
            do_aux_function_relay(1, ch_flag == AuxSwitchPos::HIGH);
            break;
        case AUX_FUNC::RELAY3:
            do_aux_function_relay(2, ch_flag == AuxSwitchPos::HIGH);
            break;
        case AUX_FUNC::RELAY4:
            do_aux_function_relay(3, ch_flag == AuxSwitchPos::HIGH);
            break;
        case AUX_FUNC::RELAY5:
            do_aux_function_relay(4, ch_flag == AuxSwitchPos::HIGH);
            break;
        case AUX_FUNC::RELAY6:
            do_aux_function_relay(5, ch_flag == AuxSwitchPos::HIGH);
            break;
    
        case AUX_FUNC::RUNCAM_CONTROL:
            do_aux_function_runcam_control(ch_flag);
            break;
    
        case AUX_FUNC::RUNCAM_OSD_CONTROL:
            do_aux_function_runcam_osd_control(ch_flag);
            break;
    
        case AUX_FUNC::CLEAR_WP:
            do_aux_function_clear_wp(ch_flag);
            break;
        case AUX_FUNC::MISSION_RESET:
            do_aux_function_mission_reset(ch_flag);
            break;
    
        case AUX_FUNC::AVOID_ADSB:
            do_aux_function_avoid_adsb(ch_flag);
            break;
    
    #if HAL_GENERATOR_ENABLED
        case AUX_FUNC::GENERATOR:
            do_aux_function_generator(ch_flag);
            break;
    #endif
    
        case AUX_FUNC::SPRAYER:
            do_aux_function_sprayer(ch_flag);
            break;
    
        case AUX_FUNC::LOST_VEHICLE_SOUND:
            do_aux_function_lost_vehicle_sound(ch_flag);
            break;
        //需要用到的功能
        case AUX_FUNC::ARMDISARM:
            do_aux_function_armdisarm(ch_flag);
            break;
    
        case AUX_FUNC::DISARM:
            if (ch_flag == AuxSwitchPos::HIGH) {
                AP::arming().disarm(AP_Arming::Method::AUXSWITCH);
            }
            break;
    
        case AUX_FUNC::COMPASS_LEARN:
            if (ch_flag == AuxSwitchPos::HIGH) {
                Compass &compass = AP::compass();
                compass.set_learn_type(Compass::LEARN_INFLIGHT, false);
            }
            break;
    
        case AUX_FUNC::LANDING_GEAR: {
            AP_LandingGear *lg = AP_LandingGear::get_singleton();
            if (lg == nullptr) {
                break;
            }
            switch (ch_flag) {
            case AuxSwitchPos::LOW:
                lg->set_position(AP_LandingGear::LandingGear_Deploy);
                break;
            case AuxSwitchPos::MIDDLE:
                // nothing
                break;
            case AuxSwitchPos::HIGH:
                lg->set_position(AP_LandingGear::LandingGear_Retract);
                break;
            }
            break;
        }
    
        case AUX_FUNC::GPS_DISABLE:
            AP::gps().force_disable(ch_flag == AuxSwitchPos::HIGH);
            break;
    
        case AUX_FUNC::GPS_DISABLE_YAW:
            AP::gps().set_force_disable_yaw(ch_flag == AuxSwitchPos::HIGH);
            break;
    
        case AUX_FUNC::DISABLE_AIRSPEED_USE: {
    #if AP_AIRSPEED_ENABLED
            AP_Airspeed *airspeed = AP::airspeed();
            if (airspeed == nullptr) {
                break;
            }
            switch (ch_flag) {
            case AuxSwitchPos::HIGH:
                airspeed->force_disable_use(true);
                break;
            case AuxSwitchPos::MIDDLE:
                break;
            case AuxSwitchPos::LOW:
                airspeed->force_disable_use(false);
                break;
            }
    #endif
            break;
        }
    
        case AUX_FUNC::MOTOR_ESTOP:
            switch (ch_flag) {
            case AuxSwitchPos::HIGH: {
                SRV_Channels::set_emergency_stop(true);
    
                // log E-stop
                AP_Logger *logger = AP_Logger::get_singleton();
                if (logger && logger->logging_enabled()) {
                    logger->Write_Event(LogEvent::MOTORS_EMERGENCY_STOPPED);
                }
                break;
            }
            case AuxSwitchPos::MIDDLE:
                // nothing
                break;
            case AuxSwitchPos::LOW: {
                SRV_Channels::set_emergency_stop(false);
    
                // log E-stop cleared
                AP_Logger *logger = AP_Logger::get_singleton();
                if (logger && logger->logging_enabled()) {
                    logger->Write_Event(LogEvent::MOTORS_EMERGENCY_STOP_CLEARED);
                }
                break;
            }
            }
            break;
    
        case AUX_FUNC::VISODOM_ALIGN:
    #if HAL_VISUALODOM_ENABLED
            if (ch_flag == AuxSwitchPos::HIGH) {
                AP_VisualOdom *visual_odom = AP::visualodom();
                if (visual_odom != nullptr) {
                    visual_odom->align_sensor_to_vehicle();
                }
            }
    #endif
            break;
    
        case AUX_FUNC::EKF_POS_SOURCE:
            switch (ch_flag) {
            case AuxSwitchPos::LOW:
                // low switches to primary source
                AP::ahrs().set_posvelyaw_source_set(0);
                break;
            case AuxSwitchPos::MIDDLE:
                // middle switches to secondary source
                AP::ahrs().set_posvelyaw_source_set(1);
                break;
            case AuxSwitchPos::HIGH:
                // high switches to tertiary source
                AP::ahrs().set_posvelyaw_source_set(2);
                break;
            }
            break;
    
        case AUX_FUNC::OPTFLOW_CAL: {
    #if AP_OPTICALFLOW_ENABLED
            OpticalFlow *optflow = AP::opticalflow();
            if (optflow == nullptr) {
                gcs().send_text(MAV_SEVERITY_CRITICAL, "OptFlow Cal: failed sensor not enabled");
                break;
            }
            if (ch_flag == AuxSwitchPos::HIGH) {
                optflow->start_calibration();
            } else {
                optflow->stop_calibration();
            }
    #endif
            break;
        }
    
    #if !HAL_MINIMIZE_FEATURES
        case AUX_FUNC::KILL_IMU1:
            AP::ins().kill_imu(0, ch_flag == AuxSwitchPos::HIGH);
            break;
    
        case AUX_FUNC::KILL_IMU2:
            AP::ins().kill_imu(1, ch_flag == AuxSwitchPos::HIGH);
            break;
    #endif // HAL_MINIMIZE_FEATURES
    
        case AUX_FUNC::CAM_MODE_TOGGLE: {
            // Momentary switch to for cycling camera modes
            AP_Camera *camera = AP_Camera::get_singleton();
            if (camera == nullptr) {
                break;
            }
            switch (ch_flag) {
            case AuxSwitchPos::LOW:
                // nothing
                break;
            case AuxSwitchPos::MIDDLE:
                // nothing
                break;
            case AuxSwitchPos::HIGH:
                camera->cam_mode_toggle();
                break;
            }
            break;
        }
    
        case AUX_FUNC::RETRACT_MOUNT: {
    #if HAL_MOUNT_ENABLED
            AP_Mount *mount = AP::mount();
            if (mount == nullptr) {
                break;
            }
            switch (ch_flag) {
                case AuxSwitchPos::HIGH:
                    mount->set_mode(MAV_MOUNT_MODE_RETRACT);
                    break;
                case AuxSwitchPos::MIDDLE:
                    // nothing
                    break;
                case AuxSwitchPos::LOW:
                    mount->set_mode_to_default();
                    break;
            }
    #endif
            break;
        }
    
        case AUX_FUNC::EKF_LANE_SWITCH:
            // used to test emergency lane switch
            AP::ahrs().check_lane_switch();
            break;
    
        case AUX_FUNC::EKF_YAW_RESET:
            // used to test emergency yaw reset
            AP::ahrs().request_yaw_reset();
            break;
    
        // clear torqeedo error
        case AUX_FUNC::TORQEEDO_CLEAR_ERR: {
    #if HAL_TORQEEDO_ENABLED
            if (ch_flag == AuxSwitchPos::HIGH) {
                AP_Torqeedo *torqeedo = AP_Torqeedo::get_singleton();
                if (torqeedo != nullptr) {
                    torqeedo->clear_motor_error();
                }
            }
    #endif
            break;
        }
    
        case AUX_FUNC::SCRIPTING_1:
        case AUX_FUNC::SCRIPTING_2:
        case AUX_FUNC::SCRIPTING_3:
        case AUX_FUNC::SCRIPTING_4:
        case AUX_FUNC::SCRIPTING_5:
        case AUX_FUNC::SCRIPTING_6:
        case AUX_FUNC::SCRIPTING_7:
        case AUX_FUNC::SCRIPTING_8:
            break;
    
        default:
            gcs().send_text(MAV_SEVERITY_INFO, "Invalid channel option (%u)", (unsigned int)ch_option);
            return false;
        }
    
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303

    重点关注这个函数:

        case AUX_FUNC::ARMDISARM:
            do_aux_function_armdisarm(ch_flag);
            break;
    
    • 1
    • 2
    • 3
    void RC_Channel::do_aux_function_armdisarm(const AuxSwitchPos ch_flag)
    {
        //解锁和上锁这个外设------ arm or disarm the vehicle
        switch (ch_flag) 
        {
        case AuxSwitchPos::HIGH:
            AP::arming().arm(AP_Arming::Method::AUXSWITCH, true); //最高就是解锁
            break;
        case AuxSwitchPos::MIDDLE:
            // nothing
            break;
        case AuxSwitchPos::LOW:
            AP::arming().disarm(AP_Arming::Method::AUXSWITCH); //最低就是上锁
            break;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    到这里就实现了通过遥控器实现解锁。

  • 相关阅读:
    亚马逊、eBay、wish、Lazada、shoppe和mercari如何降低测评成本提高测评效率?
    微软Power Platform平台低代码
    matlab使用NCL提供的colormap
    数据科学的文本技术 Text Technology(IR信息检索、搜索引擎)
    【倒推题解】三数之和及其变式的优化思路
    常用CMD命令
    2024年河北省计划招聘“特岗计划”教师2300名
    Codeforces Round #909 (Div. 3)
    java-php-python-springboot网上教学系统计算机毕业设计
    Java 异常处理的使用和思考
  • 原文地址:https://blog.csdn.net/lixiaoweimashixiao/article/details/126278796