static long cmsx_menuMiscOnExit(const OSD_Entry *self) { UNUSED(self); motorConfigMutable()->minthrottle = motorConfig_minthrottle; motorConfigMutable()->digitalIdleOffsetValue = 10 * motorConfig_digitalIdleOffsetValue; voltageSensorADCConfigMutable(VOLTAGE_SENSOR_ADC_VBAT)->vbatscale = voltageSensorADCConfig_vbatscale; batteryConfigMutable()->vbatmaxcellvoltage = batteryConfig_vbatmaxcellvoltage; return 0; }
void targetConfiguration(void) { if (hardwareMotorType == MOTOR_BRUSHED) { motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; motorConfigMutable()->minthrottle = 1049; #if defined(FF_ACROWHOOPSP) rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048; rxConfigMutable()->spektrum_sat_bind = 5; rxConfigMutable()->spektrum_sat_bind_autoreset = 1; #else serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIAL_PORT_USART2)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB; rxConfigMutable()->serialrx_inverted = true; featureSet(FEATURE_TELEMETRY); #endif parseRcChannels("TAER1234", rxConfigMutable()); for (uint8_t pidProfileIndex = 0; pidProfileIndex < MAX_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pid[PID_ROLL].P = 80; pidProfile->pid[PID_ROLL].I = 37; pidProfile->pid[PID_ROLL].D = 35; pidProfile->pid[PID_PITCH].P = 100; pidProfile->pid[PID_PITCH].I = 37; pidProfile->pid[PID_PITCH].D = 35; pidProfile->pid[PID_YAW].P = 180; pidProfile->pid[PID_YAW].D = 45; } for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) { controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex); controlRateConfig->rcRates[FD_ROLL] = 100; controlRateConfig->rcRates[FD_PITCH] = 100; controlRateConfig->rcRates[FD_YAW] = 100; controlRateConfig->rcExpo[FD_ROLL] = 15; controlRateConfig->rcExpo[FD_PITCH] = 15; controlRateConfig->rcExpo[FD_YAW] = 15; controlRateConfig->rates[PID_ROLL] = 80; controlRateConfig->rates[PID_PITCH] = 80; controlRateConfig->rates[PID_YAW] = 80; } } }
// alternative defaults settings for AlienFlight targets void targetConfiguration(void) { if (getDetectedMotorType() == MOTOR_BRUSHED) { motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; pidConfigMutable()->pid_process_denom = 1; } if (hardwareRevision == AFF4_REV_1) { rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048; rxConfigMutable()->spektrum_sat_bind = 5; rxConfigMutable()->spektrum_sat_bind_autoreset = 1; } else { rxConfigMutable()->serialrx_provider = SERIALRX_SBUS; rxConfigMutable()->serialrx_inverted = true; serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL; telemetryConfigMutable()->telemetry_inverted = false; batteryConfigMutable()->voltageMeterSource = VOLTAGE_METER_ADC; batteryConfigMutable()->currentMeterSource = CURRENT_METER_ADC; featureEnable(FEATURE_TELEMETRY); } for (uint8_t pidProfileIndex = 0; pidProfileIndex < PID_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pid[PID_ROLL].P = 53; pidProfile->pid[PID_ROLL].I = 45; pidProfile->pid[PID_ROLL].D = 52; pidProfile->pid[PID_PITCH].P = 53; pidProfile->pid[PID_PITCH].I = 45; pidProfile->pid[PID_PITCH].D = 52; pidProfile->pid[PID_YAW].P = 64; pidProfile->pid[PID_YAW].D = 18; } *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f, 1.0f, -1.0f }; // REAR_R *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f, 1.0f }; // FRONT_R *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f, 0.414178f, 1.0f, 1.0f }; // REAR_L *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f, 0.414178f, -1.0f, -1.0f }; // FRONT_L *customMotorMixerMutable(4) = (motorMixer_t){ 1.0f, -1.0f, -0.414178f, -1.0f }; // MIDFRONT_R *customMotorMixerMutable(5) = (motorMixer_t){ 1.0f, 1.0f, -0.414178f, 1.0f }; // MIDFRONT_L *customMotorMixerMutable(6) = (motorMixer_t){ 1.0f, -1.0f, 0.414178f, 1.0f }; // MIDREAR_R *customMotorMixerMutable(7) = (motorMixer_t){ 1.0f, 1.0f, 0.414178f, -1.0f }; // MIDREAR_L }
void targetConfiguration(void) { if (getDetectedMotorType() == MOTOR_BRUSHED) { motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; motorConfigMutable()->minthrottle = 1050; // for 6mm and 7mm brushed } /* Default to Spektrum */ rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048; // all DSM* except DSM2 22ms rxConfigMutable()->spektrum_sat_bind = 5; // DSM2 11ms rxConfigMutable()->spektrum_sat_bind_autoreset = 1; rxConfigMutable()->mincheck = 1025; rxConfigMutable()->rcInterpolation = RC_SMOOTHING_MANUAL; rxConfigMutable()->rcInterpolationInterval = 14; parseRcChannels("TAER1234", rxConfigMutable()); mixerConfigMutable()->yaw_motors_reversed = true; imuConfigMutable()->small_angle = 180; blackboxConfigMutable()->p_ratio = 128; /* Breadboard-specific settings for development purposes only */ #if defined(BREADBOARD) boardAlignmentMutable()->pitchDegrees = 90; // vertical breakout board barometerConfigMutable()->baro_hardware = BARO_DEFAULT; // still testing not on V1 or V2 pcb #else barometerConfigMutable()->baro_hardware = BARO_NONE; #endif compassConfigMutable()->mag_hardware = MAG_NONE; systemConfigMutable()->cpu_overclock = 2; //216MHZ pidConfigMutable()->runaway_takeoff_prevention = false; featureEnable((FEATURE_DYNAMIC_FILTER | FEATURE_AIRMODE | FEATURE_ANTI_GRAVITY) ^ FEATURE_RX_PARALLEL_PWM); /* AlienWhoop PIDs tested with 6mm and 7mm motors on most frames */ for (uint8_t pidProfileIndex = 0; pidProfileIndex < PID_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pidSumLimit = 1000; pidProfile->pidSumLimitYaw = 1000; /* AlienWhoop PIDs tested with 6mm and 7mm motors on most frames */ pidProfile->pid[PID_PITCH].P = 115; pidProfile->pid[PID_PITCH].I = 75; pidProfile->pid[PID_PITCH].D = 95; pidProfile->pid[PID_ROLL].P = 110; pidProfile->pid[PID_ROLL].I = 75; pidProfile->pid[PID_ROLL].D = 85; pidProfile->pid[PID_YAW].P = 220; pidProfile->pid[PID_YAW].I = 75; pidProfile->pid[PID_YAW].D = 20; pidProfile->pid[PID_LEVEL].P = 65; pidProfile->pid[PID_LEVEL].I = 65; pidProfile->pid[PID_LEVEL].D = 55; /* Setpoints */ pidProfile->dterm_filter_type = FILTER_BIQUAD; pidProfile->dterm_notch_hz = 0; pidProfile->pid[PID_PITCH].F = 100; pidProfile->pid[PID_ROLL].F = 100; pidProfile->feedForwardTransition = 0; /* Anti-Gravity */ pidProfile->itermThrottleThreshold = 500; pidProfile->itermAcceleratorGain = 5000; pidProfile->levelAngleLimit = 65; } for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) { controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex); /* RC Rates */ controlRateConfig->rcRates[FD_ROLL] = 218; controlRateConfig->rcRates[FD_PITCH] = 218; controlRateConfig->rcRates[FD_YAW] = 218; /* Classic Expo */ controlRateConfig->rcExpo[FD_ROLL] = 45; controlRateConfig->rcExpo[FD_PITCH] = 45; controlRateConfig->rcExpo[FD_YAW] = 45; /* Super Expo Rates */ controlRateConfig->rates[FD_ROLL] = 0; controlRateConfig->rates[FD_PITCH] = 0; controlRateConfig->rates[FD_YAW] = 0; /* Throttle PID Attenuation (TPA) */ controlRateConfig->dynThrPID = 0; // tpa_rate off controlRateConfig->tpa_breakpoint = 1600; /* Force the clipping mixer at 100% seems better for brushed than default (off) and scaling)? */ controlRateConfig->throttle_limit_type = THROTTLE_LIMIT_TYPE_CLIP; //controlRateConfig->throttle_limit_percent = 100; controlRateConfig->thrExpo8 = 20; // 20% throttle expo } }
// alternative defaults settings for AlienFlight targets void targetConfiguration(void) { /* depending on revision ... depends on the LEDs to be utilised. */ if (hardwareRevision == AFF3_REV_2) { statusLedConfigMutable()->inversion = 0 #ifdef LED0_A_INVERTED | BIT(0) #endif #ifdef LED1_A_INVERTED | BIT(1) #endif #ifdef LED2_A_INVERTED | BIT(2) #endif ; for (int i = 0; i < STATUS_LED_NUMBER; i++) { statusLedConfigMutable()->ioTags[i] = IO_TAG_NONE; } #ifdef LED0_A statusLedConfigMutable()->ioTags[0] = IO_TAG(LED0_A); #endif #ifdef LED1_A statusLedConfigMutable()->ioTags[1] = IO_TAG(LED1_A); #endif #ifdef LED2_A statusLedConfigMutable()->ioTags[2] = IO_TAG(LED2_A); #endif } else { gyroConfigMutable()->gyro_sync_denom = 2; pidConfigMutable()->pid_process_denom = 2; } if (!haveFrSkyRX) { rxConfigMutable()->serialrx_provider = SERIALRX_SPEKTRUM2048; rxConfigMutable()->spektrum_sat_bind = 5; rxConfigMutable()->spektrum_sat_bind_autoreset = 1; parseRcChannels("TAER1234", rxConfigMutable()); } else { rxConfigMutable()->serialrx_provider = SERIALRX_SBUS; rxConfigMutable()->serialrx_inverted = true; serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL; telemetryConfigMutable()->telemetry_inverted = false; featureSet(FEATURE_TELEMETRY); beeperDevConfigMutable()->isOpenDrain = false; beeperDevConfigMutable()->isInverted = true; parseRcChannels("AETR1234", rxConfigMutable()); } if (hardwareMotorType == MOTOR_BRUSHED) { motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; pidConfigMutable()->pid_process_denom = 1; } for (uint8_t pidProfileIndex = 0; pidProfileIndex < MAX_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pid[PID_ROLL].P = 90; pidProfile->pid[PID_ROLL].I = 44; pidProfile->pid[PID_ROLL].D = 60; pidProfile->pid[PID_PITCH].P = 90; pidProfile->pid[PID_PITCH].I = 44; pidProfile->pid[PID_PITCH].D = 60; } *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f, 1.0f, -1.0f }; // REAR_R *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f, 1.0f }; // FRONT_R *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f, 0.414178f, 1.0f, 1.0f }; // REAR_L *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f, 0.414178f, -1.0f, -1.0f }; // FRONT_L *customMotorMixerMutable(4) = (motorMixer_t){ 1.0f, -1.0f, -0.414178f, -1.0f }; // MIDFRONT_R *customMotorMixerMutable(5) = (motorMixer_t){ 1.0f, 1.0f, -0.414178f, 1.0f }; // MIDFRONT_L *customMotorMixerMutable(6) = (motorMixer_t){ 1.0f, -1.0f, 0.414178f, 1.0f }; // MIDREAR_R *customMotorMixerMutable(7) = (motorMixer_t){ 1.0f, 1.0f, 0.414178f, -1.0f }; // MIDREAR_L }
void targetConfiguration(void) { #ifdef BEEBRAIN // alternative defaults settings for Beebrain target motorConfigMutable()->dev.motorPwmRate = 4000; failsafeConfigMutable()->failsafe_delay = 2; failsafeConfigMutable()->failsafe_off_delay = 0; motorConfigMutable()->minthrottle = 1049; gyroConfigMutable()->gyro_lpf = GYRO_LPF_188HZ; gyroConfigMutable()->gyro_soft_lpf_hz = 100; gyroConfigMutable()->gyro_soft_notch_hz_1 = 0; gyroConfigMutable()->gyro_soft_notch_hz_2 = 0; /*for (int channel = 0; channel < NON_AUX_CHANNEL_COUNT; channel++) { rxChannelRangeConfigsMutable(channel)->min = 1180; rxChannelRangeConfigsMutable(channel)->max = 1860; }*/ for (int profileId = 0; profileId < 2; profileId++) { pidProfilesMutable(0)->P8[ROLL] = 60; pidProfilesMutable(0)->I8[ROLL] = 70; pidProfilesMutable(0)->D8[ROLL] = 17; pidProfilesMutable(0)->P8[PITCH] = 80; pidProfilesMutable(0)->I8[PITCH] = 90; pidProfilesMutable(0)->D8[PITCH] = 18; pidProfilesMutable(0)->P8[YAW] = 200; pidProfilesMutable(0)->I8[YAW] = 45; pidProfilesMutable(0)->P8[PIDLEVEL] = 30; pidProfilesMutable(0)->D8[PIDLEVEL] = 30; for (int rateProfileId = 0; rateProfileId < CONTROL_RATE_PROFILE_COUNT; rateProfileId++) { controlRateProfilesMutable(rateProfileId)->rcRate8 = 100; controlRateProfilesMutable(rateProfileId)->rcYawRate8 = 110; controlRateProfilesMutable(rateProfileId)->rcExpo8 = 0; controlRateProfilesMutable(rateProfileId)->rates[FD_ROLL] = 77; controlRateProfilesMutable(rateProfileId)->rates[FD_PITCH] = 77; controlRateProfilesMutable(rateProfileId)->rates[FD_YAW] = 80; pidProfilesMutable(0)->dtermSetpointWeight = 200; pidProfilesMutable(0)->setpointRelaxRatio = 50; } } #endif #if !defined(AFROMINI) && !defined(BEEBRAIN) if (hardwareRevision >= NAZE32_REV5) { // naze rev4 and below used opendrain to PNP for buzzer. Rev5 and above use PP to NPN. beeperDevConfigMutable()->isOpenDrain = false; beeperDevConfigMutable()->isInverted = true; } else { beeperDevConfigMutable()->isOpenDrain = true; beeperDevConfigMutable()->isInverted = false; flashConfigMutable()->csTag = IO_TAG_NONE; } #endif #ifdef MAG_INT_EXTI if (hardwareRevision < NAZE32_REV5) { compassConfigMutable()->interruptTag = IO_TAG(PB12); } #endif }
void targetConfiguration(void) { #ifdef BEEBRAIN // alternative defaults settings for Beebrain target motorConfigMutable()->dev.motorPwmRate = 4000; failsafeConfigMutable()->failsafe_delay = 2; failsafeConfigMutable()->failsafe_off_delay = 0; motorConfigMutable()->minthrottle = 1049; gyroConfigMutable()->gyro_hardware_lpf = GYRO_HARDWARE_LPF_1KHZ_SAMPLE; gyroConfigMutable()->gyro_lowpass_hz = 100; gyroConfigMutable()->gyro_soft_notch_hz_1 = 0; gyroConfigMutable()->gyro_soft_notch_hz_2 = 0; /*for (int channel = 0; channel < NON_AUX_CHANNEL_COUNT; channel++) { rxChannelRangeConfigsMutable(channel)->min = 1180; rxChannelRangeConfigsMutable(channel)->max = 1860; }*/ for (uint8_t pidProfileIndex = 0; pidProfileIndex < MAX_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pid[PID_ROLL].P = 60; pidProfile->pid[PID_ROLL].I = 70; pidProfile->pid[PID_ROLL].D = 17; pidProfile->pid[PID_PITCH].P = 80; pidProfile->pid[PID_PITCH].I = 90; pidProfile->pid[PID_PITCH].D = 18; pidProfile->pid[PID_YAW].P = 200; pidProfile->pid[PID_YAW].I = 45; pidProfile->pid[PID_LEVEL].P = 30; pidProfile->pid[PID_LEVEL].D = 30; pidProfile->pid[PID_PITCH].F = 200; pidProfile->pid[PID_ROLL].F = 200; pidProfile->feedForwardTransition = 50; } for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) { controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex); controlRateConfig->rcRates[FD_ROLL] = 100; controlRateConfig->rcRates[FD_PITCH] = 100; controlRateConfig->rcRates[FD_YAW] = 110; controlRateConfig->rcExpo[FD_ROLL] = 0; controlRateConfig->rcExpo[FD_PITCH] = 0; controlRateConfig->rates[FD_ROLL] = 77; controlRateConfig->rates[FD_PITCH] = 77; controlRateConfig->rates[FD_YAW] = 80; } #endif #if !defined(AFROMINI) && !defined(BEEBRAIN) if (hardwareRevision >= NAZE32_REV5) { // naze rev4 and below used opendrain to PNP for buzzer. Rev5 and above use PP to NPN. beeperDevConfigMutable()->isOpenDrain = false; beeperDevConfigMutable()->isInverted = true; } else { beeperDevConfigMutable()->isOpenDrain = true; beeperDevConfigMutable()->isInverted = false; flashConfigMutable()->csTag = IO_TAG_NONE; } #endif #ifdef MAG_INT_EXTI if (hardwareRevision < NAZE32_REV5) { compassConfigMutable()->interruptTag = IO_TAG(PB12); } #endif #ifdef BLACKBOX if (hardwareRevision >= NAZE32_REV5) blackboxConfigMutable()->device = BLACKBOX_DEVICE_FLASH; #endif }
void validateAndFixGyroConfig(void) { // Prevent invalid notch cutoff if (gyroConfig()->gyro_soft_notch_cutoff_1 >= gyroConfig()->gyro_soft_notch_hz_1) { gyroConfigMutable()->gyro_soft_notch_hz_1 = 0; } if (gyroConfig()->gyro_soft_notch_cutoff_2 >= gyroConfig()->gyro_soft_notch_hz_2) { gyroConfigMutable()->gyro_soft_notch_hz_2 = 0; } if (gyroConfig()->gyro_lpf != GYRO_LPF_256HZ && gyroConfig()->gyro_lpf != GYRO_LPF_NONE) { pidConfigMutable()->pid_process_denom = 1; // When gyro set to 1khz always set pid speed 1:1 to sampling speed gyroConfigMutable()->gyro_sync_denom = 1; gyroConfigMutable()->gyro_use_32khz = false; } if (gyroConfig()->gyro_use_32khz) { // F1 and F3 can't handle high sample speed. #if defined(STM32F1) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 16); #elif defined(STM32F3) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 4); #endif } else { #if defined(STM32F1) gyroConfigMutable()->gyro_sync_denom = MAX(gyroConfig()->gyro_sync_denom, 3); #endif } float samplingTime; switch (gyroMpuDetectionResult()->sensor) { case ICM_20649_SPI: samplingTime = 1.0f / 9000.0f; break; case BMI_160_SPI: samplingTime = 0.0003125f; break; default: samplingTime = 0.000125f; break; } if (gyroConfig()->gyro_lpf != GYRO_LPF_256HZ && gyroConfig()->gyro_lpf != GYRO_LPF_NONE) { switch (gyroMpuDetectionResult()->sensor) { case ICM_20649_SPI: samplingTime = 1.0f / 1100.0f; break; default: samplingTime = 0.001f; break; } } if (gyroConfig()->gyro_use_32khz) { samplingTime = 0.00003125; } // check for looptime restrictions based on motor protocol. Motor times have safety margin float motorUpdateRestriction; switch (motorConfig()->dev.motorPwmProtocol) { case PWM_TYPE_STANDARD: motorUpdateRestriction = 1.0f / BRUSHLESS_MOTORS_PWM_RATE; break; case PWM_TYPE_ONESHOT125: motorUpdateRestriction = 0.0005f; break; case PWM_TYPE_ONESHOT42: motorUpdateRestriction = 0.0001f; break; #ifdef USE_DSHOT case PWM_TYPE_DSHOT150: motorUpdateRestriction = 0.000250f; break; case PWM_TYPE_DSHOT300: motorUpdateRestriction = 0.0001f; break; #endif default: motorUpdateRestriction = 0.00003125f; break; } if (motorConfig()->dev.useUnsyncedPwm) { // Prevent overriding the max rate of motors if ((motorConfig()->dev.motorPwmProtocol <= PWM_TYPE_BRUSHED) && (motorConfig()->dev.motorPwmProtocol != PWM_TYPE_STANDARD)) { const uint32_t maxEscRate = lrintf(1.0f / motorUpdateRestriction); motorConfigMutable()->dev.motorPwmRate = MIN(motorConfig()->dev.motorPwmRate, maxEscRate); } } else { const float pidLooptime = samplingTime * gyroConfig()->gyro_sync_denom * pidConfig()->pid_process_denom; if (pidLooptime < motorUpdateRestriction) { const uint8_t minPidProcessDenom = constrain(motorUpdateRestriction / (samplingTime * gyroConfig()->gyro_sync_denom), 1, MAX_PID_PROCESS_DENOM); pidConfigMutable()->pid_process_denom = MAX(pidConfigMutable()->pid_process_denom, minPidProcessDenom); } } }
static void validateAndFixConfig(void) { #if !defined(USE_QUAD_MIXER_ONLY) && !defined(USE_OSD_SLAVE) // Reset unsupported mixer mode to default. // This check will be gone when motor/servo mixers are loaded dynamically // by configurator as a part of configuration procedure. mixerMode_e mixerMode = mixerConfigMutable()->mixerMode; if (!(mixerMode == MIXER_CUSTOM || mixerMode == MIXER_CUSTOM_AIRPLANE || mixerMode == MIXER_CUSTOM_TRI)) { if (mixers[mixerMode].motorCount && mixers[mixerMode].motor == NULL) mixerConfigMutable()->mixerMode = MIXER_CUSTOM; #ifdef USE_SERVOS if (mixers[mixerMode].useServo && servoMixers[mixerMode].servoRuleCount == 0) mixerConfigMutable()->mixerMode = MIXER_CUSTOM_AIRPLANE; #endif } #endif #ifndef USE_OSD_SLAVE if (systemConfig()->activeRateProfile >= CONTROL_RATE_PROFILE_COUNT) { systemConfigMutable()->activeRateProfile = 0; } setControlRateProfile(systemConfig()->activeRateProfile); if (systemConfig()->pidProfileIndex >= MAX_PROFILE_COUNT) { systemConfigMutable()->pidProfileIndex = 0; } setPidProfile(systemConfig()->pidProfileIndex); // Prevent invalid notch cutoff if (currentPidProfile->dterm_notch_cutoff >= currentPidProfile->dterm_notch_hz) { currentPidProfile->dterm_notch_hz = 0; } if ((motorConfig()->dev.motorPwmProtocol == PWM_TYPE_BRUSHED) && (motorConfig()->mincommand < 1000)) { motorConfigMutable()->mincommand = 1000; } if ((motorConfig()->dev.motorPwmProtocol == PWM_TYPE_STANDARD) && (motorConfig()->dev.motorPwmRate > BRUSHLESS_MOTORS_PWM_RATE)) { motorConfigMutable()->dev.motorPwmRate = BRUSHLESS_MOTORS_PWM_RATE; } validateAndFixGyroConfig(); if (!(featureConfigured(FEATURE_RX_PARALLEL_PWM) || featureConfigured(FEATURE_RX_PPM) || featureConfigured(FEATURE_RX_SERIAL) || featureConfigured(FEATURE_RX_MSP) || featureConfigured(FEATURE_RX_SPI))) { featureSet(DEFAULT_RX_FEATURE); } if (featureConfigured(FEATURE_RX_PPM)) { featureClear(FEATURE_RX_SERIAL | FEATURE_RX_PARALLEL_PWM | FEATURE_RX_MSP | FEATURE_RX_SPI); } if (featureConfigured(FEATURE_RX_MSP)) { featureClear(FEATURE_RX_SERIAL | FEATURE_RX_PARALLEL_PWM | FEATURE_RX_PPM | FEATURE_RX_SPI); } if (featureConfigured(FEATURE_RX_SERIAL)) { featureClear(FEATURE_RX_PARALLEL_PWM | FEATURE_RX_MSP | FEATURE_RX_PPM | FEATURE_RX_SPI); } #ifdef USE_RX_SPI if (featureConfigured(FEATURE_RX_SPI)) { featureClear(FEATURE_RX_SERIAL | FEATURE_RX_PARALLEL_PWM | FEATURE_RX_PPM | FEATURE_RX_MSP); } #endif // USE_RX_SPI if (featureConfigured(FEATURE_RX_PARALLEL_PWM)) { featureClear(FEATURE_RX_SERIAL | FEATURE_RX_MSP | FEATURE_RX_PPM | FEATURE_RX_SPI); #if defined(STM32F10X) // rssi adc needs the same ports featureClear(FEATURE_RSSI_ADC); // current meter needs the same ports if (batteryConfig()->currentMeterSource == CURRENT_METER_ADC) { batteryConfigMutable()->currentMeterSource = CURRENT_METER_NONE; } #endif // STM32F10X // software serial needs free PWM ports featureClear(FEATURE_SOFTSERIAL); } #ifdef USE_SOFTSPI if (featureConfigured(FEATURE_SOFTSPI)) { featureClear(FEATURE_RX_PPM | FEATURE_RX_PARALLEL_PWM | FEATURE_SOFTSERIAL); batteryConfigMutable()->voltageMeterSource = VOLTAGE_METER_NONE; #if defined(STM32F10X) featureClear(FEATURE_LED_STRIP); // rssi adc needs the same ports featureClear(FEATURE_RSSI_ADC); // current meter needs the same ports if (batteryConfig()->currentMeterSource == CURRENT_METER_ADC) { batteryConfigMutable()->currentMeterSource = CURRENT_METER_NONE; } #endif // STM32F10X } #endif // USE_SOFTSPI #endif // USE_OSD_SLAVE if (!isSerialConfigValid(serialConfig())) { pgResetFn_serialConfig(serialConfigMutable()); } // clear features that are not supported. // I have kept them all here in one place, some could be moved to sections of code above. #ifndef USE_PPM featureClear(FEATURE_RX_PPM); #endif #ifndef USE_SERIAL_RX featureClear(FEATURE_RX_SERIAL); #endif #if !defined(USE_SOFTSERIAL1) && !defined(USE_SOFTSERIAL2) featureClear(FEATURE_SOFTSERIAL); #endif #ifndef USE_GPS featureClear(FEATURE_GPS); #endif #ifndef USE_RANGEFINDER featureClear(FEATURE_RANGEFINDER); #endif #ifndef USE_TELEMETRY featureClear(FEATURE_TELEMETRY); #endif #ifndef USE_PWM featureClear(FEATURE_RX_PARALLEL_PWM); #endif #ifndef USE_RX_MSP featureClear(FEATURE_RX_MSP); #endif #ifndef USE_LED_STRIP featureClear(FEATURE_LED_STRIP); #endif #ifndef USE_DASHBOARD featureClear(FEATURE_DASHBOARD); #endif #ifndef USE_OSD featureClear(FEATURE_OSD); #endif #ifndef USE_SERVOS featureClear(FEATURE_SERVO_TILT | FEATURE_CHANNEL_FORWARDING); #endif #ifndef USE_TRANSPONDER featureClear(FEATURE_TRANSPONDER); #endif #ifndef USE_RX_SPI featureClear(FEATURE_RX_SPI); #endif #ifndef USE_SOFTSPI featureClear(FEATURE_SOFTSPI); #endif #ifndef USE_ESC_SENSOR featureClear(FEATURE_ESC_SENSOR); #endif #ifndef USE_GYRO_DATA_ANALYSE featureClear(FEATURE_DYNAMIC_FILTER); #endif #if defined(TARGET_VALIDATECONFIG) targetValidateConfiguration(); #endif }
void targetConfiguration(void) { if (hardwareMotorType == MOTOR_BRUSHED) { motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; motorConfigMutable()->minthrottle = 1030; pidConfigMutable()->pid_process_denom = 1; } for (uint8_t pidProfileIndex = 0; pidProfileIndex < PID_PROFILE_COUNT; pidProfileIndex++) { pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex); pidProfile->pid[PID_ROLL].P = 86; pidProfile->pid[PID_ROLL].I = 50; pidProfile->pid[PID_ROLL].D = 60; pidProfile->pid[PID_PITCH].P = 90; pidProfile->pid[PID_PITCH].I = 55; pidProfile->pid[PID_PITCH].D = 60; pidProfile->pid[PID_YAW].P = 123; pidProfile->pid[PID_YAW].I = 75; } for (uint8_t rateProfileIndex = 0; rateProfileIndex < CONTROL_RATE_PROFILE_COUNT; rateProfileIndex++) { controlRateConfig_t *controlRateConfig = controlRateProfilesMutable(rateProfileIndex); controlRateConfig->rcRates[FD_YAW] = 120; controlRateConfig->rcExpo[FD_ROLL] = 15; controlRateConfig->rcExpo[FD_PITCH] = 15; controlRateConfig->rcExpo[FD_YAW] = 15; controlRateConfig->rates[FD_ROLL] = 85; controlRateConfig->rates[FD_PITCH] = 85; } batteryConfigMutable()->batteryCapacity = 250; batteryConfigMutable()->vbatmincellvoltage = 280; batteryConfigMutable()->vbatwarningcellvoltage = 330; *customMotorMixerMutable(0) = (motorMixer_t){ 1.0f, -0.414178f, 1.0f, -1.0f }; // REAR_R *customMotorMixerMutable(1) = (motorMixer_t){ 1.0f, -0.414178f, -1.0f, 1.0f }; // FRONT_R *customMotorMixerMutable(2) = (motorMixer_t){ 1.0f, 0.414178f, 1.0f, 1.0f }; // REAR_L *customMotorMixerMutable(3) = (motorMixer_t){ 1.0f, 0.414178f, -1.0f, -1.0f }; // FRONT_L vcdProfileMutable()->video_system = VIDEO_SYSTEM_NTSC; #if defined(BEESTORM) strcpy(pilotConfigMutable()->name, "BeeStorm"); #else strcpy(pilotConfigMutable()->name, "BeeBrain V2"); #endif osdConfigMutable()->cap_alarm = 250; osdConfigMutable()->item_pos[OSD_CRAFT_NAME] = OSD_POS(9, 11) | OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_MAIN_BATT_VOLTAGE] = OSD_POS(23, 10) | OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ITEM_TIMER_2] = OSD_POS(2, 10) | OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_FLYMODE] = OSD_POS(17, 10) | OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_VTX_CHANNEL] = OSD_POS(10, 10) | OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_RSSI_VALUE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ITEM_TIMER_1] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_THROTTLE_POS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_CROSSHAIRS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_HORIZON_SIDEBARS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ARTIFICIAL_HORIZON] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_CURRENT_DRAW] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_MAH_DRAWN] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_GPS_SPEED] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_GPS_LON] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_GPS_LAT] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_GPS_SATS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_HOME_DIR] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_HOME_DIST] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_COMPASS_BAR] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ALTITUDE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ROLL_PIDS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_PITCH_PIDS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_YAW_PIDS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_DEBUG] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_POWER] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_PIDRATE_PROFILE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_WARNINGS] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_AVG_CELL_VOLTAGE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_PITCH_ANGLE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ROLL_ANGLE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_MAIN_BATT_USAGE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_DISARMED] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_NUMERICAL_HEADING] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_NUMERICAL_VARIO] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ESC_TMP] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_ESC_RPM] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_G_FORCE] &= ~OSD_PROFILE_1_FLAG; osdConfigMutable()->item_pos[OSD_FLIP_ARROW] &= ~OSD_PROFILE_1_FLAG; modeActivationConditionsMutable(0)->modeId = BOXANGLE; modeActivationConditionsMutable(0)->auxChannelIndex = AUX2 - NON_AUX_CHANNEL_COUNT; modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(900); modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(2100); analyzeModeActivationConditions(); #if defined(BEEBRAIN_V2D) // DSM version for (uint8_t rxRangeIndex = 0; rxRangeIndex < NON_AUX_CHANNEL_COUNT; rxRangeIndex++) { rxChannelRangeConfig_t *channelRangeConfig = rxChannelRangeConfigsMutable(rxRangeIndex); channelRangeConfig->min = 1160; channelRangeConfig->max = 1840; } #else // Frsky version serialConfigMutable()->portConfigs[findSerialPortIndexByIdentifier(SERIALRX_UART)].functionMask = FUNCTION_TELEMETRY_FRSKY_HUB | FUNCTION_RX_SERIAL; rxConfigMutable()->rssi_channel = BBV2_FRSKY_RSSI_CH_IDX; rxFailsafeChannelConfig_t *channelFailsafeConfig = rxFailsafeChannelConfigsMutable(BBV2_FRSKY_RSSI_CH_IDX - 1); channelFailsafeConfig->mode = RX_FAILSAFE_MODE_SET; channelFailsafeConfig->step = CHANNEL_VALUE_TO_RXFAIL_STEP(1000); osdConfigMutable()->item_pos[OSD_RSSI_VALUE] = OSD_POS(2, 11) | OSD_PROFILE_1_FLAG; #endif }