int applyCurve(int x, CurveRef & curve) { switch (curve.type) { case CURVE_REF_DIFF: { int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode)); if (curveParam > 0 && x < 0) x = (x * (256 - curveParam)) >> 8; else if (curveParam < 0 && x > 0) x = (x * (256 + curveParam)) >> 8; return x; } case CURVE_REF_EXPO: return expo(x, GET_GVAR(curve.value, -100, 100, mixerCurrentFlightMode)); case CURVE_REF_FUNC: switch (curve.value) { case CURVE_X_GT0: if (x < 0) x = 0; //x|x>0 return x; case CURVE_X_LT0: if (x > 0) x = 0; //x|x<0 return x; case CURVE_ABS_X: // x|abs(x) return abs(x); case CURVE_F_GT0: //f|f>0 return x > 0 ? RESX : 0; case CURVE_F_LT0: //f|f<0 return x < 0 ? -RESX : 0; case CURVE_ABS_F: //f|abs(f) return x > 0 ? RESX : -RESX; } break; case CURVE_REF_CUSTOM: { int curveParam = curve.value; if (curveParam < 0) { x = -x; curveParam = -curveParam; } if (curveParam > 0 && curveParam <= MAX_CURVES) { return applyCustomCurve(x, curveParam - 1); } break; } }
void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS) { #if defined(PCBTARANIS) #if defined(HELI) int16_t heliAnasCopy[4]; memcpy(heliAnasCopy, heliAnas, sizeof(heliAnasCopy)); #endif #else int16_t anas2[NUM_INPUTS]; // values before expo, to ensure same expo base when multiple expo lines are used memcpy(anas2, anas, sizeof(anas2)); #endif int8_t cur_chn = -1; for (uint8_t i=0; i<MAX_EXPOS; i++) { #if defined(BOLD_FONT) if (mode==e_perout_mode_normal) swOn[i].activeExpo = false; #endif ExpoData * ed = expoAddress(i); if (!EXPO_VALID(ed)) break; // end of list if (ed->chn == cur_chn) continue; if (ed->flightModes & (1<<mixerCurrentFlightMode)) continue; if (getSwitch(ed->swtch)) { #if defined(PCBTARANIS) int v; if (ed->srcRaw == ovwrIdx) v = ovwrValue; #if defined(HELI) else if (ed->srcRaw == MIXSRC_Ele) v = heliAnasCopy[ELE_STICK]; else if (ed->srcRaw == MIXSRC_Ail) v = heliAnasCopy[AIL_STICK]; #endif else { v = getValue(ed->srcRaw); if (ed->srcRaw >= MIXSRC_FIRST_TELEM && ed->scale > 0) { v = (v * 1024) / convertTelemValue(ed->srcRaw-MIXSRC_FIRST_TELEM+1, ed->scale); } v = limit(-1024, v, 1024); } #else int16_t v = anas2[ed->chn]; #endif if (EXPO_MODE_ENABLE(ed, v)) { #if defined(BOLD_FONT) if (mode==e_perout_mode_normal) swOn[i].activeExpo = true; #endif cur_chn = ed->chn; //========== CURVE================= #if defined(PCBTARANIS) if (ed->curve.value) { v = applyCurve(v, ed->curve); } #else int8_t curveParam = ed->curveParam; if (curveParam) { if (ed->curveMode == MODE_CURVE) v = applyCurve(v, curveParam); else v = expo(v, GET_GVAR(curveParam, -100, 100, mixerCurrentFlightMode)); } #endif //========== WEIGHT =============== int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, mixerCurrentFlightMode); weight = calc100to256(weight); v = ((int32_t)v * weight) >> 8; #if defined(PCBTARANIS) //========== OFFSET =============== int16_t offset = GET_GVAR(ed->offset, -100, 100, mixerCurrentFlightMode); if (offset) v += calc100toRESX(offset); //========== TRIMS ================ if (ed->carryTrim < TRIM_ON) virtualInputsTrims[cur_chn] = -ed->carryTrim - 1; else if (ed->carryTrim == TRIM_ON && ed->srcRaw >= MIXSRC_Rud && ed->srcRaw <= MIXSRC_Ail) virtualInputsTrims[cur_chn] = ed->srcRaw - MIXSRC_Rud; else virtualInputsTrims[cur_chn] = -1; #if defined(HELI) if (ed->srcRaw == MIXSRC_Ele) { heliAnas[ELE_STICK] = v; heliTrims[ELE_STICK] = virtualInputsTrims[cur_chn]; } else if (ed->srcRaw == MIXSRC_Ail) { heliAnas[AIL_STICK] = v; heliTrims[AIL_STICK] = virtualInputsTrims[cur_chn]; } #endif #endif anas[cur_chn] = v; } } }