void updateBoardAlignment(int16_t roll, int16_t pitch) { const float sinAlignYaw = sin_approx(DECIDEGREES_TO_RADIANS(boardAlignment()->yawDeciDegrees)); const float cosAlignYaw = cos_approx(DECIDEGREES_TO_RADIANS(boardAlignment()->yawDeciDegrees)); boardAlignmentMutable()->rollDeciDegrees += -sinAlignYaw * pitch + cosAlignYaw * roll; boardAlignmentMutable()->pitchDeciDegrees += cosAlignYaw * pitch + sinAlignYaw * roll; initBoardAlignment(); }
void initBoardAlignment(void) { if (isBoardAlignmentStandard(boardAlignment())) { return; } standardBoardAlignment = false; fp_angles_t rotationAngles; rotationAngles.angles.roll = degreesToRadians(boardAlignment()->rollDegrees); rotationAngles.angles.pitch = degreesToRadians(boardAlignment()->pitchDegrees); rotationAngles.angles.yaw = degreesToRadians(boardAlignment()->yawDegrees); buildRotationMatrix(&rotationAngles, boardRotation); }
void initBoardAlignment(void) { if (isBoardAlignmentStandard(boardAlignment())) { standardBoardAlignment = true; } else { fp_angles_t rotationAngles; standardBoardAlignment = false; rotationAngles.angles.roll = DECIDEGREES_TO_RADIANS(boardAlignment()->rollDeciDegrees ); rotationAngles.angles.pitch = DECIDEGREES_TO_RADIANS(boardAlignment()->pitchDeciDegrees); rotationAngles.angles.yaw = DECIDEGREES_TO_RADIANS(boardAlignment()->yawDeciDegrees ); rotationMatrixFromAngles(&boardRotMatrix, &rotationAngles); } }
static void applyStepAdjustment(controlRateConfig_t *controlRateConfig, uint8_t adjustmentFunction, int delta) { if (delta > 0) { beeperConfirmationBeeps(2); } else { beeperConfirmationBeeps(1); } switch (adjustmentFunction) { case ADJUSTMENT_RC_EXPO: applyAdjustmentExpo(ADJUSTMENT_RC_EXPO, &controlRateConfig->stabilized.rcExpo8, delta); break; case ADJUSTMENT_RC_YAW_EXPO: applyAdjustmentExpo(ADJUSTMENT_RC_YAW_EXPO, &controlRateConfig->stabilized.rcYawExpo8, delta); break; case ADJUSTMENT_MANUAL_RC_EXPO: applyAdjustmentExpo(ADJUSTMENT_MANUAL_RC_EXPO, &controlRateConfig->manual.rcExpo8, delta); break; case ADJUSTMENT_MANUAL_RC_YAW_EXPO: applyAdjustmentExpo(ADJUSTMENT_MANUAL_RC_YAW_EXPO, &controlRateConfig->manual.rcYawExpo8, delta); break; case ADJUSTMENT_THROTTLE_EXPO: applyAdjustmentExpo(ADJUSTMENT_THROTTLE_EXPO, &controlRateConfig->throttle.rcExpo8, delta); break; case ADJUSTMENT_PITCH_ROLL_RATE: case ADJUSTMENT_PITCH_RATE: applyAdjustmentU8(ADJUSTMENT_PITCH_RATE, &controlRateConfig->stabilized.rates[FD_PITCH], delta, CONTROL_RATE_CONFIG_ROLL_PITCH_RATE_MIN, CONTROL_RATE_CONFIG_ROLL_PITCH_RATE_MAX); if (adjustmentFunction == ADJUSTMENT_PITCH_RATE) { schedulePidGainsUpdate(); break; } // follow though for combined ADJUSTMENT_PITCH_ROLL_RATE FALLTHROUGH; case ADJUSTMENT_ROLL_RATE: applyAdjustmentU8(ADJUSTMENT_ROLL_RATE, &controlRateConfig->stabilized.rates[FD_ROLL], delta, CONTROL_RATE_CONFIG_ROLL_PITCH_RATE_MIN, CONTROL_RATE_CONFIG_ROLL_PITCH_RATE_MAX); schedulePidGainsUpdate(); break; case ADJUSTMENT_MANUAL_PITCH_ROLL_RATE: case ADJUSTMENT_MANUAL_ROLL_RATE: applyAdjustmentManualRate(ADJUSTMENT_MANUAL_ROLL_RATE, &controlRateConfig->manual.rates[FD_ROLL], delta); if (adjustmentFunction == ADJUSTMENT_MANUAL_ROLL_RATE) break; // follow though for combined ADJUSTMENT_MANUAL_PITCH_ROLL_RATE FALLTHROUGH; case ADJUSTMENT_MANUAL_PITCH_RATE: applyAdjustmentManualRate(ADJUSTMENT_MANUAL_PITCH_RATE, &controlRateConfig->manual.rates[FD_PITCH], delta); break; case ADJUSTMENT_YAW_RATE: applyAdjustmentU8(ADJUSTMENT_YAW_RATE, &controlRateConfig->stabilized.rates[FD_YAW], delta, CONTROL_RATE_CONFIG_YAW_RATE_MIN, CONTROL_RATE_CONFIG_YAW_RATE_MAX); schedulePidGainsUpdate(); break; case ADJUSTMENT_MANUAL_YAW_RATE: applyAdjustmentManualRate(ADJUSTMENT_MANUAL_YAW_RATE, &controlRateConfig->manual.rates[FD_YAW], delta); break; case ADJUSTMENT_PITCH_ROLL_P: case ADJUSTMENT_PITCH_P: applyAdjustmentPID(ADJUSTMENT_PITCH_P, &pidBankMutable()->pid[PID_PITCH].P, delta); if (adjustmentFunction == ADJUSTMENT_PITCH_P) { schedulePidGainsUpdate(); break; } // follow though for combined ADJUSTMENT_PITCH_ROLL_P FALLTHROUGH; case ADJUSTMENT_ROLL_P: applyAdjustmentPID(ADJUSTMENT_ROLL_P, &pidBankMutable()->pid[PID_ROLL].P, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_PITCH_ROLL_I: case ADJUSTMENT_PITCH_I: applyAdjustmentPID(ADJUSTMENT_PITCH_I, &pidBankMutable()->pid[PID_PITCH].I, delta); if (adjustmentFunction == ADJUSTMENT_PITCH_I) { schedulePidGainsUpdate(); break; } // follow though for combined ADJUSTMENT_PITCH_ROLL_I FALLTHROUGH; case ADJUSTMENT_ROLL_I: applyAdjustmentPID(ADJUSTMENT_ROLL_I, &pidBankMutable()->pid[PID_ROLL].I, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_PITCH_ROLL_D: case ADJUSTMENT_PITCH_D: applyAdjustmentPID(ADJUSTMENT_PITCH_D, &pidBankMutable()->pid[PID_PITCH].D, delta); if (adjustmentFunction == ADJUSTMENT_PITCH_D) { schedulePidGainsUpdate(); break; } // follow though for combined ADJUSTMENT_PITCH_ROLL_D FALLTHROUGH; case ADJUSTMENT_ROLL_D: applyAdjustmentPID(ADJUSTMENT_ROLL_D, &pidBankMutable()->pid[PID_ROLL].D, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_YAW_P: applyAdjustmentPID(ADJUSTMENT_YAW_P, &pidBankMutable()->pid[PID_YAW].P, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_YAW_I: applyAdjustmentPID(ADJUSTMENT_YAW_I, &pidBankMutable()->pid[PID_YAW].I, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_YAW_D: applyAdjustmentPID(ADJUSTMENT_YAW_D, &pidBankMutable()->pid[PID_YAW].D, delta); schedulePidGainsUpdate(); break; case ADJUSTMENT_NAV_FW_CRUISE_THR: applyAdjustmentU16(ADJUSTMENT_NAV_FW_CRUISE_THR, &navConfigMutable()->fw.cruise_throttle, delta, 1000, 2000); break; case ADJUSTMENT_NAV_FW_PITCH2THR: applyAdjustmentU8(ADJUSTMENT_NAV_FW_PITCH2THR, &navConfigMutable()->fw.pitch_to_throttle, delta, 0, 100); break; case ADJUSTMENT_ROLL_BOARD_ALIGNMENT: updateBoardAlignment(delta, 0); blackboxLogInflightAdjustmentEvent(ADJUSTMENT_ROLL_BOARD_ALIGNMENT, boardAlignment()->rollDeciDegrees); break; case ADJUSTMENT_PITCH_BOARD_ALIGNMENT: updateBoardAlignment(0, delta); blackboxLogInflightAdjustmentEvent(ADJUSTMENT_PITCH_BOARD_ALIGNMENT, boardAlignment()->pitchDeciDegrees); break; case ADJUSTMENT_LEVEL_P: applyAdjustmentPID(ADJUSTMENT_LEVEL_P, &pidBankMutable()->pid[PID_LEVEL].P, delta); // TODO: Need to call something to take it into account? break; case ADJUSTMENT_LEVEL_I: applyAdjustmentPID(ADJUSTMENT_LEVEL_I, &pidBankMutable()->pid[PID_LEVEL].I, delta); // TODO: Need to call something to take it into account? break; case ADJUSTMENT_LEVEL_D: applyAdjustmentPID(ADJUSTMENT_LEVEL_D, &pidBankMutable()->pid[PID_LEVEL].D, delta); // TODO: Need to call something to take it into account? break; case ADJUSTMENT_POS_XY_P: applyAdjustmentPID(ADJUSTMENT_POS_XY_P, &pidBankMutable()->pid[PID_POS_XY].P, delta); navigationUsePIDs(); break; case ADJUSTMENT_POS_XY_I: applyAdjustmentPID(ADJUSTMENT_POS_XY_I, &pidBankMutable()->pid[PID_POS_XY].I, delta); navigationUsePIDs(); break; case ADJUSTMENT_POS_XY_D: applyAdjustmentPID(ADJUSTMENT_POS_XY_D, &pidBankMutable()->pid[PID_POS_XY].D, delta); navigationUsePIDs(); break; case ADJUSTMENT_POS_Z_P: applyAdjustmentPID(ADJUSTMENT_POS_Z_P, &pidBankMutable()->pid[PID_POS_Z].P, delta); navigationUsePIDs(); break; case ADJUSTMENT_POS_Z_I: applyAdjustmentPID(ADJUSTMENT_POS_Z_I, &pidBankMutable()->pid[PID_POS_Z].I, delta); navigationUsePIDs(); break; case ADJUSTMENT_POS_Z_D: applyAdjustmentPID(ADJUSTMENT_POS_Z_D, &pidBankMutable()->pid[PID_POS_Z].D, delta); navigationUsePIDs(); break; case ADJUSTMENT_HEADING_P: applyAdjustmentPID(ADJUSTMENT_HEADING_P, &pidBankMutable()->pid[PID_HEADING].P, delta); // TODO: navigationUsePIDs()? break; case ADJUSTMENT_VEL_XY_P: applyAdjustmentPID(ADJUSTMENT_VEL_XY_P, &pidBankMutable()->pid[PID_VEL_XY].P, delta); navigationUsePIDs(); break; case ADJUSTMENT_VEL_XY_I: applyAdjustmentPID(ADJUSTMENT_VEL_XY_I, &pidBankMutable()->pid[PID_VEL_XY].I, delta); navigationUsePIDs(); break; case ADJUSTMENT_VEL_XY_D: applyAdjustmentPID(ADJUSTMENT_VEL_XY_D, &pidBankMutable()->pid[PID_VEL_XY].D, delta); navigationUsePIDs(); break; case ADJUSTMENT_VEL_Z_P: applyAdjustmentPID(ADJUSTMENT_VEL_Z_P, &pidBankMutable()->pid[PID_VEL_Z].P, delta); navigationUsePIDs(); break; case ADJUSTMENT_VEL_Z_I: applyAdjustmentPID(ADJUSTMENT_VEL_Z_I, &pidBankMutable()->pid[PID_VEL_Z].I, delta); navigationUsePIDs(); break; case ADJUSTMENT_VEL_Z_D: applyAdjustmentPID(ADJUSTMENT_VEL_Z_D, &pidBankMutable()->pid[PID_VEL_Z].D, delta); navigationUsePIDs(); break; case ADJUSTMENT_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE: applyAdjustmentU16(ADJUSTMENT_FW_MIN_THROTTLE_DOWN_PITCH_ANGLE, &mixerConfigMutable()->fwMinThrottleDownPitchAngle, delta, 0, FW_MIN_THROTTLE_DOWN_PITCH_ANGLE_MAX); break; default: break; }; }
static void showStatusPage(void) { uint8_t rowIndex = PAGE_TITLE_LINE_COUNT; if (feature(FEATURE_VBAT)) { i2c_OLED_set_line(rowIndex++); tfp_sprintf(lineBuffer, "V: %d.%1d ", vbat / 10, vbat % 10); padLineBufferToChar(12); i2c_OLED_send_string(lineBuffer); uint8_t batteryPercentage = calculateBatteryPercentage(); drawHorizonalPercentageBar(10, batteryPercentage); } if (feature(FEATURE_CURRENT_METER)) { i2c_OLED_set_line(rowIndex++); tfp_sprintf(lineBuffer, "mAh: %d", mAhDrawn); padLineBufferToChar(12); i2c_OLED_send_string(lineBuffer); uint8_t capacityPercentage = calculateBatteryCapacityRemainingPercentage(); drawHorizonalPercentageBar(10, capacityPercentage); } #ifdef GPS if (feature(FEATURE_GPS)) { tfp_sprintf(lineBuffer, "Sats: %d", gpsSol.numSat); padHalfLineBuffer(); i2c_OLED_set_line(rowIndex); i2c_OLED_send_string(lineBuffer); tfp_sprintf(lineBuffer, "Fix: %s", gpsFixTypeText[gpsSol.fixType]); padHalfLineBuffer(); i2c_OLED_set_xy(HALF_SCREEN_CHARACTER_COLUMN_COUNT, rowIndex++); i2c_OLED_send_string(lineBuffer); tfp_sprintf(lineBuffer, "HDOP: %d.%1d", gpsSol.hdop / 100, gpsSol.hdop % 100); padLineBuffer(); i2c_OLED_set_line(rowIndex++); i2c_OLED_send_string(lineBuffer); tfp_sprintf(lineBuffer, "La/Lo: %d/%d", gpsSol.llh.lat / GPS_DEGREES_DIVIDER, gpsSol.llh.lon / GPS_DEGREES_DIVIDER); padLineBuffer(); i2c_OLED_set_line(rowIndex++); i2c_OLED_send_string(lineBuffer); } #endif #ifdef MAG if (sensors(SENSOR_MAG)) { tfp_sprintf(lineBuffer, "HDG: %d", DECIDEGREES_TO_DEGREES(attitude.values.yaw)); padHalfLineBuffer(); i2c_OLED_set_line(rowIndex); i2c_OLED_send_string(lineBuffer); } #endif #ifdef BARO if (sensors(SENSOR_BARO)) { int32_t alt = baroCalculateAltitude(); tfp_sprintf(lineBuffer, "Alt: %d", alt / 100); padHalfLineBuffer(); i2c_OLED_set_xy(HALF_SCREEN_CHARACTER_COLUMN_COUNT, rowIndex); i2c_OLED_send_string(lineBuffer); } #endif rowIndex++; char rollTrim[7], pitchTrim[7]; formatTrimDegrees(rollTrim, boardAlignment()->rollDeciDegrees); formatTrimDegrees(pitchTrim, boardAlignment()->pitchDeciDegrees); tfp_sprintf(lineBuffer, "Acc: %sR, %sP", rollTrim, pitchTrim ); i2c_OLED_set_line(rowIndex++); i2c_OLED_send_string(lineBuffer); }