示例#1
0
static void servoMixer(void)
{
    int16_t input[INPUT_ITEMS];
    static int16_t currentOutput[MAX_SERVO_RULES];
    uint8_t i;

    if (f.PASSTHRU_MODE) {
        // Direct passthru from RX
        input[INPUT_ROLL] = rcCommand[ROLL];
        input[INPUT_PITCH] = rcCommand[PITCH];
        input[INPUT_YAW] = rcCommand[YAW];
    } else {
        // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
        input[INPUT_ROLL] = axisPID[ROLL];
        input[INPUT_PITCH] = axisPID[PITCH];
        input[INPUT_YAW] = axisPID[YAW];
    }

    input[INPUT_THROTTLE] = motor[0];
    input[INPUT_AUX1] = mcfg.midrc - rcData[AUX1];
    input[INPUT_AUX2] = mcfg.midrc - rcData[AUX2];
    input[INPUT_AUX3] = mcfg.midrc - rcData[AUX3];
    input[INPUT_AUX4] = mcfg.midrc - rcData[AUX4];
    input[INPUT_RC_ROLL] = mcfg.midrc - rcData[ROLL];
    input[INPUT_RC_PITCH] = mcfg.midrc - rcData[PITCH];
    input[INPUT_RC_YAW] = mcfg.midrc - rcData[YAW];
    input[INPUT_RC_THROTTLE] = mcfg.midrc - rcData[THROTTLE];

    for (i = 0; i < MAX_SERVOS; i++)
        servo[i] = servoMiddle(i);

    // mix servos according to rules
    for (i = 0; i < numberRules; i++) {
        // consider rule if no box assigned or box is active
        if (currentServoMixer[i].box == 0 || rcOptions[BOXSERVO1 + currentServoMixer[i].box - 1]) {
            uint8_t target = currentServoMixer[i].targetChannel;
            uint8_t from = currentServoMixer[i].fromChannel;
            uint16_t servo_width = cfg.servoConf[target].max - cfg.servoConf[target].min;
            int16_t min = currentServoMixer[i].min * servo_width / 100 - servo_width / 2;
            int16_t max = currentServoMixer[i].max * servo_width / 100 - servo_width / 2;

            if (currentServoMixer[i].speed == 0)
                currentOutput[i] = input[from];
            else {
                if (currentOutput[i] < input[from])
                    currentOutput[i] = constrain(currentOutput[i] + currentServoMixer[i].speed, currentOutput[i], input[from]);
                else if (currentOutput[i] > input[from])
                    currentOutput[i] = constrain(currentOutput[i] - currentServoMixer[i].speed, input[from], currentOutput[i]);
            }

            servo[target] += servoDirection(target, from) * constrain(((int32_t)currentOutput[i] * currentServoMixer[i].rate) / 100, min, max);
        } else
            currentOutput[i] = 0;
    }

    // servo rates
    for (i = 0; i < MAX_SERVOS; i++)
        servo[i] = ((int32_t)cfg.servoConf[i].rate * servo[i]) / 100;
}
示例#2
0
STATIC_UNIT_TESTED void servoMixer(void)
{
    int16_t input[INPUT_SOURCE_COUNT]; // Range [-500:+500]
    static int16_t currentOutput[MAX_SERVO_RULES];
    uint8_t i;

    if (FLIGHT_MODE(PASSTHRU_MODE)) {
        // Direct passthru from RX
        input[INPUT_STABILIZED_ROLL] = rcCommand[ROLL];
        input[INPUT_STABILIZED_PITCH] = rcCommand[PITCH];
        input[INPUT_STABILIZED_YAW] = rcCommand[YAW];
    } else {
        // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
        input[INPUT_STABILIZED_ROLL] = axisPID[ROLL];
        input[INPUT_STABILIZED_PITCH] = axisPID[PITCH];
        input[INPUT_STABILIZED_YAW] = axisPID[YAW];

        // Reverse yaw servo when inverted in 3D mode
        if (feature(FEATURE_3D) && (rcData[THROTTLE] < rxConfig->midrc)) {
            input[INPUT_STABILIZED_YAW] *= -1;
        }
    }

    input[INPUT_GIMBAL_PITCH] = scaleRange(attitude.values.pitch, -1800, 1800, -500, +500);
    input[INPUT_GIMBAL_ROLL] = scaleRange(attitude.values.roll, -1800, 1800, -500, +500);

    input[INPUT_STABILIZED_THROTTLE] = motor[0] - 1000 - 500;  // Since it derives from rcCommand or mincommand and must be [-500:+500]

    // center the RC input value around the RC middle value
    // by subtracting the RC middle value from the RC input value, we get:
    // data - middle = input
    // 2000 - 1500 = +500
    // 1500 - 1500 = 0
    // 1000 - 1500 = -500
    input[INPUT_RC_ROLL]     = rcData[ROLL]     - rxConfig->midrc;
    input[INPUT_RC_PITCH]    = rcData[PITCH]    - rxConfig->midrc;
    input[INPUT_RC_YAW]      = rcData[YAW]      - rxConfig->midrc;
    input[INPUT_RC_THROTTLE] = rcData[THROTTLE] - rxConfig->midrc;
    input[INPUT_RC_AUX1]     = rcData[AUX1]     - rxConfig->midrc;
    input[INPUT_RC_AUX2]     = rcData[AUX2]     - rxConfig->midrc;
    input[INPUT_RC_AUX3]     = rcData[AUX3]     - rxConfig->midrc;
    input[INPUT_RC_AUX4]     = rcData[AUX4]     - rxConfig->midrc;

    for (i = 0; i < MAX_SUPPORTED_SERVOS; i++)
        servo[i] = 0;

    // mix servos according to rules
    for (i = 0; i < servoRuleCount; i++) {
        // consider rule if no box assigned or box is active
        if (currentServoMixer[i].box == 0 || IS_RC_MODE_ACTIVE(BOXSERVO1 + currentServoMixer[i].box - 1)) {
            uint8_t target = currentServoMixer[i].targetChannel;
            uint8_t from = currentServoMixer[i].inputSource;
            uint16_t servo_width = servoConf[target].max - servoConf[target].min;
            int16_t min = currentServoMixer[i].min * servo_width / 100 - servo_width / 2;
            int16_t max = currentServoMixer[i].max * servo_width / 100 - servo_width / 2;

            if (currentServoMixer[i].speed == 0)
                currentOutput[i] = input[from];
            else {
                if (currentOutput[i] < input[from])
                    currentOutput[i] = constrain(currentOutput[i] + currentServoMixer[i].speed, currentOutput[i], input[from]);
                else if (currentOutput[i] > input[from])
                    currentOutput[i] = constrain(currentOutput[i] - currentServoMixer[i].speed, input[from], currentOutput[i]);
            }

            servo[target] += servoDirection(target, from) * constrain(((int32_t)currentOutput[i] * currentServoMixer[i].rate) / 100, min, max);
        } else {
            currentOutput[i] = 0;
        }
    }

    for (i = 0; i < MAX_SUPPORTED_SERVOS; i++) {
        servo[i] = ((int32_t)servoConf[i].rate * servo[i]) / 100L;
        servo[i] += determineServoMiddleOrForwardFromChannel(i);
    }
}
示例#3
0
static void servoMixer(void)
{
    int16_t input[INPUT_ITEMS];
    static int16_t currentOutput[MAX_SERVO_RULES];
    uint8_t i;

    if (f.PASSTHRU_MODE) {
        // Direct passthru from RX
        input[INPUT_ROLL] = rcCommand[ROLL];
        input[INPUT_PITCH] = rcCommand[PITCH];
        input[INPUT_YAW] = rcCommand[YAW];
    } else {
        // Assisted modes (gyro only or gyro+acc according to AUX configuration in Gui
        input[INPUT_ROLL] = axisPID[ROLL];
        input[INPUT_PITCH] = axisPID[PITCH];
        input[INPUT_YAW] = axisPID[YAW];
    }

    input[INPUT_THROTTLE] = motor[0];

    // center the RC input value around the RC middle value
    // by subtracting the RC middle value from the RC input value, we get:
    // data - middle = input
    // 2000 - 1500 = +500
    // 1500 - 1500 = 0
    // 1000 - 1500 = -500
    input[INPUT_AUX1] = rcData[AUX1] - mcfg.midrc;
    input[INPUT_AUX2] = rcData[AUX2] - mcfg.midrc;
    input[INPUT_AUX3] = rcData[AUX3] - mcfg.midrc;
    input[INPUT_AUX4] = rcData[AUX4] - mcfg.midrc;
    input[INPUT_RC_ROLL] = rcData[ROLL] - mcfg.midrc;
    input[INPUT_RC_PITCH] = rcData[PITCH] - mcfg.midrc;
    input[INPUT_RC_YAW] = rcData[YAW] - mcfg.midrc;
    input[INPUT_RC_THROTTLE] = rcData[THROTTLE] - mcfg.midrc;

    // mix servos according to rules
    for (i = 0; i < numberRules; i++) {
        // consider rule if no box assigned or box is active
        if (currentServoMixer[i].box == 0 || rcOptions[BOXSERVO1 + currentServoMixer[i].box - 1]) {
            uint8_t target = currentServoMixer[i].targetChannel;
            uint8_t from = currentServoMixer[i].fromChannel;
            uint16_t servo_width = cfg.servoConf[target].max - cfg.servoConf[target].min;
            int16_t min = currentServoMixer[i].min * servo_width / 100 - servo_width / 2;
            int16_t max = currentServoMixer[i].max * servo_width / 100 - servo_width / 2;

            if (currentServoMixer[i].speed == 0) {
                // directly use the input value if speed is not provided
                currentOutput[i] = input[from];
            } else {
                // apply speed constraints
                if (currentOutput[i] < input[from])
                    currentOutput[i] = constrain(currentOutput[i] + currentServoMixer[i].speed, currentOutput[i], input[from]);
                else if (currentOutput[i] > input[from])
                    currentOutput[i] = constrain(currentOutput[i] - currentServoMixer[i].speed, input[from], currentOutput[i]);
            }

            // start with the output value
            servo[target] = (int16_t)currentOutput[i];

            // apply rate from mixer rule
            servo[target] *= ((float)currentServoMixer[i].rate / 100);

            // apply rate fro m servoconfiguration
            servo[target] *= ((float)cfg.servoConf[target].rate / 100);

            // constrain the width of the servo's movement
            servo[target] = constrain(servo[target], min, max);

            // reverse direction if necessary
            servo[target] *= servoDirection(target, from);

            // center the servo around its middle
            servo[target] += servoMiddle(i);
        }
    }
}