diff --git a/ArduPlane/tuning.cpp b/ArduPlane/tuning.cpp index 2471ee4625..95c415cf8e 100644 --- a/ArduPlane/tuning.cpp +++ b/ArduPlane/tuning.cpp @@ -277,21 +277,45 @@ float AP_Tuning_Plane::controller_error(uint8_t parm) if (!plane.quadplane.available()) { return 0; } + + // in general a good tune will have rmsP significantly greater + // than rmsD. Otherwise it is too easy to push D too high while + // tuning a quadplane and end up with D dominating + const float max_P_D_ratio = 3.0f; switch(parm) { // special handling of dual-parameters case TUNING_RATE_ROLL_PI: case TUNING_RATE_ROLL_P: case TUNING_RATE_ROLL_I: - case TUNING_RATE_ROLL_D: return plane.quadplane.attitude_control->control_monitor_rms_output_roll(); + + case TUNING_RATE_ROLL_D: { + // special case for D term to keep it well below P + float rms_P = plane.quadplane.attitude_control->control_monitor_rms_output_roll_P(); + float rms_D = plane.quadplane.attitude_control->control_monitor_rms_output_roll_D(); + if (rms_P < rms_D * max_P_D_ratio) { + return max_P_D_ratio; + } + return rms_P+rms_D; + } + case TUNING_RATE_PITCH_PI: case TUNING_RATE_PITCH_P: case TUNING_RATE_PITCH_I: - case TUNING_RATE_PITCH_D: return plane.quadplane.attitude_control->control_monitor_rms_output_pitch(); + case TUNING_RATE_PITCH_D: { + // special case for D term to keep it well below P + float rms_P = plane.quadplane.attitude_control->control_monitor_rms_output_pitch_P(); + float rms_D = plane.quadplane.attitude_control->control_monitor_rms_output_pitch_D(); + if (rms_P < rms_D * max_P_D_ratio) { + return max_P_D_ratio; + } + return rms_P+rms_D; + } + case TUNING_RATE_YAW_PI: case TUNING_RATE_YAW_P: case TUNING_RATE_YAW_I: