Ejemplo n.º 1
0
// rotor_ramp - ramps rotor towards target
// result put in _rotor_out and sent to ESC
void AP_MotorsHeli::rotor_ramp(int16_t rotor_target)
{
    // return immediately if not ramping required
    if (_rsc_mode == AP_MOTORS_HELI_RSC_MODE_NONE) {
        _rotor_out = rotor_target;
        return;
    }

    // range check rotor_target
    rotor_target = constrain_int16(rotor_target,0,1000);

    // ramp rotor esc output towards target
    if (_rotor_out < rotor_target) {
        // allow rotor out to jump to rotor's current speed
        if (_rotor_out < _rotor_speed_estimate) {
            _rotor_out = _rotor_speed_estimate;
        }
        // ramp up slowly to target
        _rotor_out += _rsc_ramp_increment;
        if (_rotor_out > rotor_target) {
            _rotor_out = rotor_target;
        }
    }else{
        // ramping down happens instantly
        _rotor_out = rotor_target;
    }

    // ramp rotor speed estimate towards rotor out
    if (_rotor_speed_estimate < _rotor_out) {
        _rotor_speed_estimate += _rsc_runup_increment;
        if (_rotor_speed_estimate > _rotor_out) {
            _rotor_speed_estimate = _rotor_out;
        }
    }else{
        _rotor_speed_estimate -= _rsc_runup_increment;
        if (_rotor_speed_estimate < _rotor_out) {
            _rotor_speed_estimate = _rotor_out;
        }
    }

    // set runup complete flag
    if (!_heliflags.rotor_runup_complete && rotor_target > 0 && _rotor_speed_estimate >= rotor_target) {
        _heliflags.rotor_runup_complete = true;
    }
    if (_heliflags.rotor_runup_complete && _rotor_speed_estimate <= _rsc_critical) {
        _heliflags.rotor_runup_complete = false;
    }

    // output to rsc servo
    write_rsc(_rotor_out);
}
Ejemplo n.º 2
0
// rsc_control - update value to send to tail and main rotor's ESC
// desired_rotor_speed is a desired speed from 0 to 1000
void AP_MotorsHeli::rsc_control()
{
    // if disarmed output minimums
    if (!armed()) {
        // shut down tail rotor
        if (_tail_type == AP_MOTORS_HELI_TAILTYPE_DIRECTDRIVE_VARPITCH || _tail_type == AP_MOTORS_HELI_TAILTYPE_DIRECTDRIVE_FIXEDPITCH) {
            _tail_direct_drive_out = 0;
            write_aux(_tail_direct_drive_out);
        }
        // shut down main rotor
        if (_rsc_mode != AP_MOTORS_HELI_RSC_MODE_NONE) {
            _rotor_out = 0;
            _rotor_speed_estimate = 0;
            write_rsc(_rotor_out);
        }
        return;
    }

    // ramp up or down main rotor and tail
    if (_rotor_desired > 0) {
        // ramp up tail rotor (this does nothing if not using direct drive variable pitch tail)
        tail_ramp(_direct_drive_tailspeed);
        // note: this always returns true if not using direct drive variable pitch tail
        if (tail_rotor_runup_complete()) {
            rotor_ramp(_rotor_desired);
        }
    }else{
        // shutting down main rotor
        rotor_ramp(0);
        // if completed shutting down main motor then shut-down tail rotor.  Note: this does nothing if not using direct drive vairable pitch tail
        if (_rotor_speed_estimate <= 0) {
            tail_ramp(0);
        }
    }

    // direct drive fixed pitch tail servo gets copy of yaw servo out (ch4) while main rotor is running
    if (_tail_type == AP_MOTORS_HELI_TAILTYPE_DIRECTDRIVE_FIXEDPITCH) {
        // output fixed-pitch speed control if Ch8 is high
        if (_rotor_desired > 0 || _rotor_speed_estimate > 0) {
            // copy yaw output to tail esc
            write_aux(_servo_4->servo_out);
        }else{
            write_aux(0);
        }
    }
}
Ejemplo n.º 3
0
// output - update value to send to ESC/Servo
void AP_MotorsHeli_RSC::output(RotorControlState state)
{
    switch (state){
        case ROTOR_CONTROL_STOP:
            // set rotor ramp to decrease speed to zero, this happens instantly inside update_rotor_ramp()
            update_rotor_ramp(0.0f);

            // control output forced to zero
            _control_output = 0;
            break;

        case ROTOR_CONTROL_IDLE:
            // set rotor ramp to decrease speed to zero
            update_rotor_ramp(0.0f);

            // set rotor control speed to idle speed parameter, this happens instantly and ignore ramping
            _control_output = _idle_output;
            break;

        case ROTOR_CONTROL_ACTIVE:
            // set main rotor ramp to increase to full speed
            update_rotor_ramp(1.0f);

            if ((_control_mode == ROTOR_CONTROL_MODE_SPEED_PASSTHROUGH) || (_control_mode == ROTOR_CONTROL_MODE_SPEED_SETPOINT)) {
                // set control rotor speed to ramp slewed value between idle and desired speed
                _control_output = _idle_output + (_rotor_ramp_output * (_desired_speed - _idle_output));
            } else if (_control_mode == ROTOR_CONTROL_MODE_OPEN_LOOP_POWER_OUTPUT) {
                // throttle output depending on estimated power demand. Output is ramped up from idle speed during rotor runup.
                _control_output = _idle_output + (_rotor_ramp_output * ((_power_output_low - _idle_output) + (_power_output_range * _load_feedforward)));
            }
            break;
    }

    // update rotor speed run-up estimate
    update_rotor_runup();

    // output to rsc servo
    write_rsc(_control_output);
}
Ejemplo n.º 4
0
// output - update value to send to ESC/Servo
void AP_MotorsHeli_RSC::output(RotorControlState state)
{
    float dt;
    uint64_t now = AP_HAL::micros64();
    float last_control_output = _control_output;
    
    if (_last_update_us == 0) {
        _last_update_us = now;
        dt = 0.001f;
    } else {
        dt = 1.0e-6f * (now - _last_update_us);
        _last_update_us = now;
    }
    
    switch (state){
        case ROTOR_CONTROL_STOP:
            // set rotor ramp to decrease speed to zero, this happens instantly inside update_rotor_ramp()
            update_rotor_ramp(0.0f, dt);

            // control output forced to zero
            _control_output = 0.0f;
            break;

        case ROTOR_CONTROL_IDLE:
            // set rotor ramp to decrease speed to zero
            update_rotor_ramp(0.0f, dt);

            // set rotor control speed to idle speed parameter, this happens instantly and ignore ramping
            _control_output = _idle_output;
            break;

        case ROTOR_CONTROL_ACTIVE:
            // set main rotor ramp to increase to full speed
            update_rotor_ramp(1.0f, dt);

            if ((_control_mode == ROTOR_CONTROL_MODE_SPEED_PASSTHROUGH) || (_control_mode == ROTOR_CONTROL_MODE_SPEED_SETPOINT)) {
                // set control rotor speed to ramp slewed value between idle and desired speed
                _control_output = _idle_output + (_rotor_ramp_output * (_desired_speed - _idle_output));
            } else if (_control_mode == ROTOR_CONTROL_MODE_OPEN_LOOP_POWER_OUTPUT) {
                // throttle output depending on estimated power demand. Output is ramped up from idle speed during rotor runup. A negative load
                // is for the left side of the V-curve (-ve collective) A positive load is for the right side (+ve collective)
                if (_load_feedforward >= 0) {
                    float range = _power_output_high - _power_output_low;
                    _control_output = _idle_output + (_rotor_ramp_output * ((_power_output_low - _idle_output) + (range * _load_feedforward)));
                } else {
                    float range = _power_output_negc - _power_output_low;
                    _control_output = _idle_output + (_rotor_ramp_output * ((_power_output_low - _idle_output) - (range * _load_feedforward)));
                }
            }
            break;
    }

    // update rotor speed run-up estimate
    update_rotor_runup(dt);

    if (_power_slewrate > 0) {
        // implement slew rate for throttle
        float max_delta = dt * _power_slewrate * 0.01f;
        _control_output = constrain_float(_control_output, last_control_output-max_delta, last_control_output+max_delta);
    }
    
    // output to rsc servo
    write_rsc(_control_output);
}