浅谈APM系列-----throttle_loop

SCHED_TASK(throttle_loop, 50, 75)

位置:X:\ardupilot\ArduCopter\ArduCopter.cpp

// throttle_loop - should be run at 50 hz
// ---------------------------
void Copter::throttle_loop()
{
    // update throttle_low_comp value (controls priority of throttle vs attitude control)(控制油门与姿态控制的优先级)
    update_throttle_thr_mix();

    // check auto_armed status
    update_auto_armed();

#if FRAME_CONFIG == HELI_FRAME
    // update rotor speed
    heli_update_rotor_speed_targets();

    // update trad heli swash plate movement
    heli_update_landing_swash();
#endif

    // compensate for ground effect (if enabled)
    update_ground_effect_detector();
}

X:\ardupilot\ArduCopter\land_detector.cpp

// update_throttle_thr_mix - 
// sets motors throttle_low_comp value depending upon vehicle state low values favour pilot/autopilot throttle over attitude control, 
//  high values favour attitude control over throttle has no effect when throttle is above hover throttle
void Copter::update_throttle_thr_mix()
{
#if FRAME_CONFIG != HELI_FRAME
    // if disarmed or landed prioritise throttle
    if(!motors->armed() || ap.land_complete) {
        attitude_control->set_throttle_mix_min();
        return;
    }

    if (flightmode->has_manual_throttle()) {//true,飞手手动控制油门
        // manual throttle
        if(channel_throttle->get_control_in() <= 0) {
	// throttle vs attitude control prioritisation used when landing 
	//(higher values mean we prioritise attitude control over throttle)
            attitude_control->set_throttle_mix_min();
        } else {
	// throttle vs attitude control prioritisation used when using manual throttle 
	// (higher values mean we prioritise attitude control over throttle)
            attitude_control->set_throttle_mix_man();
        }
    } else {//自驾仪自动控制油门
        // autopilot controlled throttle

        // check for aggressive flight requests - requested roll or pitch angle below 15 degrees(检查是否有攻击性的飞行请求-要求的滚动或倾斜角度低于15度)
        const Vector3f angle_target = attitude_control->get_att_target_euler_cd();
        bool large_angle_request = (norm(angle_target.x, angle_target.y) > LAND_CHECK_LARGE_ANGLE_CD);// 1500 -> maximum angle target to be considered landing

        // check for large external disturbance - angle error over 30 degrees(检查大的外部干扰-角度误差超过30度)
        const float angle_error = attitude_control->get_att_error_angle_deg();//返回目标推力矢量和当前推力矢量之间的夹角。
        bool large_angle_error = (angle_error > LAND_CHECK_ANGLE_ERROR_DEG);//30 ->  maximum angle error to be considered landing

        // check for large acceleration - falling or high turbulence(检查是否有大的加速度-下降或高湍流)
        Vector3f accel_ef = ahrs.get_accel_ef_blended();
        accel_ef.z += GRAVITY_MSS;//Z方向,抵消重力
        bool accel_moving = (accel_ef.length() > LAND_CHECK_ACCEL_MOVING);//3 -> maximum acceleration after subtracting gravity

        // check for requested decent
        bool descent_not_demanded = pos_control->get_desired_velocity().z >= 0.0f;

        if ( large_angle_request || large_angle_error || accel_moving || descent_not_demanded) {
            // throttle vs attitude control prioritisation used during active flight
            // (higher values mean we prioritise attitude control over throttle)
            attitude_control->set_throttle_mix_max();
        } else {
            // throttle vs attitude control prioritisation used when landing 
            //(higher values mean we prioritise attitude control over throttle)
            attitude_control->set_throttle_mix_min();
        }
    }
#endif
}

 

X:\ardupilot\ArduCopter\system.cpp

// update_auto_armed - update status of auto_armed flag
void Copter::update_auto_armed()
{
    // disarm checks(上锁检查)
    if(ap.auto_armed){
        // if motors are disarmed, auto_armed should also be false
        // 如果电机上锁,自动解锁应该是FALSE
        if(!motors->armed()) {
            set_auto_armed(false);
            return;
        }
        // if in stabilize or acro flight mode and throttle is zero, auto-armed should become false
        // 如果在自稳和特技飞行模式并且油门是0,自动解锁应该变成FALSE
        if(flightmode->has_manual_throttle() && ap.throttle_zero && !failsafe.radio) {
            set_auto_armed(false);
        }
#if FRAME_CONFIG == HELI_FRAME
        // if helicopters are on the ground, and the motor is switched off, auto-armed should be false
        // so that rotor runup is checked again before attempting to take-off
        if(ap.land_complete && !motors->rotor_runup_complete()) {
            set_auto_armed(false);
        }
#endif // HELI_FRAME
    }else{
        // arm checks(解锁检查)
        
#if FRAME_CONFIG == HELI_FRAME
        // for tradheli if motors are armed and throttle is above zero and the motor is started, auto_armed should be true
        if(motors->armed() && !ap.throttle_zero && motors->rotor_runup_complete()) {
            set_auto_armed(true);
        }
#else
        // if motors are armed and throttle is above zero auto_armed should be true
        // 如果电机是解锁的并且油门在0之上,自动解锁应该是TRUE
        // if motors are armed and we are in throw mode, then auto_ermed should be true
        // 如果电机解锁并且处于抛飞模式,自动解锁为TRUE
        if(motors->armed() && (!ap.throttle_zero || control_mode == THROW)) {
            set_auto_armed(true);
        }
#endif // HELI_FRAME
    }
}

下面是最后一个函数调用了。

// compensate for ground effect (if enabled)(如果使能的话,弥补地面效应)
update_ground_effect_detector();

x:\ardupilot\ArduCopter\baro_ground_effect.cpp

void Copter::update_ground_effect_detector(void)
{
    if(!g2.gndeffect_comp_enabled || !motors->armed()) {//电机没解锁或者没有使能地形匹配
        // disarmed - disable ground effect and return
        gndeffect_state.takeoff_expected = false;
        gndeffect_state.touchdown_expected = false;
        ahrs.setTakeoffExpected(gndeffect_state.takeoff_expected);
        ahrs.setTouchdownExpected(gndeffect_state.touchdown_expected);
        return;
    }

    // variable initialization
    uint32_t tnow_ms = millis();
    float xy_des_speed_cms = 0.0f;
    float xy_speed_cms = 0.0f;
    float des_climb_rate_cms = pos_control->get_desired_velocity().z;// desired velocity in cm/s

    if (pos_control->is_active_xy()) {// is_active_xy - returns true if the xy position controller has been run very recently
        Vector3f vel_target = pos_control->get_vel_target();//获取目标速度
        vel_target.z = 0.0f;//将Z方向的目标速度设置为0
        xy_des_speed_cms = vel_target.length();//XY方向的速度和
    }

    // position_ok - returns true if the horizontal absolute position is ok and home position is set
    // optflow_position_ok - returns true if optical flow based position estimate is ok
    if (position_ok() || optflow_position_ok()) {
        Vector3f vel = inertial_nav.get_velocity();
        vel.z = 0.0f;
        xy_speed_cms = vel.length();
    }

    // takeoff logic(起飞逻辑)

    // if we are armed and haven't yet taken off(如果已经解锁,还没有起飞)
    if (motors->armed() && ap.land_complete && !gndeffect_state.takeoff_expected) {
        gndeffect_state.takeoff_expected = true;
    }

    // if we aren't taking off yet, reset the takeoff timer, altitude and complete flag(如果我们还没有起飞,重置起飞计时器,高度和完成标志)
    const bool throttle_up = flightmode->has_manual_throttle() && channel_throttle->get_control_in() > 0;
    if (!throttle_up && ap.land_complete) {//貌似起飞之后ap.land_complete会发生改变,下面的代码就不执行了
        gndeffect_state.takeoff_time_ms = tnow_ms;//在有油门,并且没有起飞的情况下,一直更新
        gndeffect_state.takeoff_alt_cm = inertial_nav.get_altitude();
    }

    // if we are in takeoff_expected and we meet the conditions for having taken off
    // end the takeoff_expected state(如果我们在预期的情况下我们会满足起飞的条件)
    if (gndeffect_state.takeoff_expected && (tnow_ms-gndeffect_state.takeoff_time_ms > 5000 || inertial_nav.get_altitude()-gndeffect_state.takeoff_alt_cm > 50.0f)) {// 时间超过5秒或者高度超过50厘米
        gndeffect_state.takeoff_expected = false;//修改标志位
    }

    // landing logic(着陆逻辑)

    Vector3f angle_target_rad = attitude_control->get_att_target_euler_cd() * radians(0.01f);
    bool small_angle_request = cosf(angle_target_rad.x)*cosf(angle_target_rad.y) > cosf(radians(7.5f));
    bool xy_speed_low = (position_ok() || optflow_position_ok()) && xy_speed_cms <= 125.0f;
    bool xy_speed_demand_low = pos_control->is_active_xy() && xy_des_speed_cms <= 125.0f;
    bool slow_horizontal = xy_speed_demand_low || (xy_speed_low && !pos_control->is_active_xy()) || (control_mode == ALT_HOLD && small_angle_request);

    bool descent_demanded = pos_control->is_active_z() && des_climb_rate_cms < 0.0f;
    bool slow_descent_demanded = descent_demanded && des_climb_rate_cms >= -100.0f;
    bool z_speed_low = fabsf(inertial_nav.get_velocity_z()) <= 60.0f;
    bool slow_descent = (slow_descent_demanded || (z_speed_low && descent_demanded));

    gndeffect_state.touchdown_expected = slow_horizontal && slow_descent;//是否检测到着陆,两个必须都是TRUE,着陆才完成

    // Prepare the EKF for ground effect if either takeoff or touchdown is expected.(如果预期起飞或着陆,准备EKF的地面效果)
    ahrs.setTakeoffExpected(gndeffect_state.takeoff_expected);
    ahrs.setTouchdownExpected(gndeffect_state.touchdown_expected);
}

今天就先到这里吧。


未完。。。。。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值