diff --git a/docs/en/config_fw/weight_and_altitude_tuning.md b/docs/en/config_fw/weight_and_altitude_tuning.md
index 520efdb59a..0bb38c5c18 100644
--- a/docs/en/config_fw/weight_and_altitude_tuning.md
+++ b/docs/en/config_fw/weight_and_altitude_tuning.md
@@ -39,7 +39,7 @@ The minimum sink rate is set in [FW_T_SINK_MIN](../advanced_config/parameter_ref
If the [Basic TECS tuning](../config_fw/position_tuning_guide_fixedwing.md#tecs-tuning-altitude-and-airspeed) was not done in standard sea level conditions then the [FW_T_SINK_MIN](../advanced_config/parameter_reference.md#FW_T_SINK_MIN) parameter must be modified by multiplying with correction factor $P$ (where $\rho$ is the air density during tuning):
-$$P = \sqrt{\rho\over{\rho_{sealevel}}}$$
+$$P = \sqrt{\frac{\rho}{\rho_{\text{sealevel}}}}$$
For more information see [Effect of Density on minimum sink rate](#effect-of-density-on-minimum-sink-rate).
@@ -49,7 +49,7 @@ The trim throttle is set using [FW_THR_TRIM](../advanced_config/parameter_refere
If basic tuning was not done in standard sealevel conditions then the value for [FW_THR_TRIM](../advanced_config/parameter_reference.md#FW_THR_TRIM) must be modified by multiplying with correction factor $P$:
-$$P = \sqrt{\rho\over{\rho_{sealevel}}}$$
+$$P = \sqrt{\frac{\rho}{\rho_{\text{sealevel}}}}$$
For more information see [Effect of Density on Trim Throttle](#effect-of-density-on-trim-throttle)
@@ -63,7 +63,7 @@ This is provided for interest only, and may be of interest to developers who wan
In the following sections we will use the notation $\hat X$ to specify that this value is a calibrated value of the variable $X$.
By calibrated we mean the value of that variable measured at sea level in standard atmospheric conditions, and when vehicle weight was equal to [WEIGHT_BASE](../advanced_config/parameter_reference.md#WEIGHT_BASE).
-E.g. by $\hat{\dot{h}}_{max}$ we specify the maximum climb rate the vehicle can achieve at [WEIGHT_BASE](../advanced_config/parameter_reference.md#WEIGHT_BASE) at sea level in standard atmospheric conditions.
+E.g. by $\hat{\dot{h}}_{\text{max}}$ we specify the maximum climb rate the vehicle can achieve at [WEIGHT_BASE](../advanced_config/parameter_reference.md#WEIGHT_BASE) at sea level in standard atmospheric conditions.
### Effect of Weight on Maximum Climb Rate
@@ -71,7 +71,7 @@ The maximum climb rate ([FW_T_CLMB_MAX](../advanced_config/parameter_reference.m
From the steady state equations of motions of an airplane we find that the maximum climb rate can be written as:
-$$\dot{h}_{max} = { V * ( Thrust - Drag ) \over{m*g}}$$
+$$\dot{h}_{\text{max}} = \frac{V \cdot (\text{Thrust} - \text{Drag})}{m \cdot g}$$
where `V` is the true airspeed and `m` is the vehicle mass.
From this equation we see that the maximum climb rates scales with vehicle mass.
@@ -82,7 +82,7 @@ The minimum sink rate ([FW_T_SINK_MIN](../advanced_config/parameter_reference.md
The minimum sink rate can be written as:
-$$\dot{h}_{min} = \sqrt{2mg\over{\rho S}} f(C_L, C_D)$$
+$$\dot{h}_{\text{min}} = \sqrt{\frac{2mg}{\rho S}}\, f(C_L, C_D)$$
where $\rho$ is the air density, S is the wing surface reference area and $f(C_L, C_D)$ is a function of the polars, lift and drag.
@@ -94,30 +94,38 @@ The minimum airspeed ([FW_AIRSPD_MIN](../advanced_config/parameter_reference.md#
In steady state flight we can demand that lift should equal weight of the vehicle:
-$$Lift = mg = {1\over{2}} \rho V^2 S C_L$$
+$$\text{Lift} = mg = \frac{1}{2} \rho V^2 S C_L$$
rearranging this equation for airspeed gives:
-$$V = \\sqrt{\\frac{2mg}{\\rho S C_D }}$$
+$$V = \sqrt{\frac{2mg}{\rho S C_L}}$$
From this equation we see that if we assume a constant angle of attack (which we generally desire), the vehicle weight affects airspeed with a square root relation.
Therefore, the airspeed limits mentioned above are all scaled using the square root of the weight ratio.
+### Effect of Bank Angle on Airspeed Limits
+
+Flying a coordinated, level turn at bank angle $\phi$ increases the load factor by $\frac{1}{\cos{\phi}}$. This is similar to the added load factor due to weight (section above), and thus the stall and minimum airspeeds are increased by an additional factor of $\sqrt{\frac{1}{\cos{\phi}}}$.
+
+The maximum airspeed ([FW_AIRSPD_MAX](../advanced_config/parameter_reference.md#FW_AIRSPD_MAX)) is _not_ compensated in this way, as it can represent structural limits of the airframe.
+
+It can be that at maximum bank angle [FW_R_LIM](../advanced_config/parameter_reference.md#FW_R_LIM), the maximum airspeed is _lower_ than the minimum airspeed (compensated for weight ratio and bank angle). This means the allowed airspeed range is empty at that bank angle. If a system is configured like this, a warning on the ground station is shown.
+
### Effect of Density on Maximum Climb Rate
The maximum climb rate is set using [FW_T_CLMB_MAX](../advanced_config/parameter_reference.md#FW_T_CLMB_MAX).
As we have seen previously, the maximum climb rate can be formulated as:
-$$\dot{h}_{max} = { V * ( Thrust - Drag ) \over{m*g}}$$
+$$\dot{h}_{\text{max}} = \frac{V \cdot (\text{Thrust} - \text{Drag})}{m \cdot g}$$
The air density affects the airspeed, the thrust and the drag and modelling this effects is not straight forward.
However, we can refer to literature and experience, which suggest that for a propeller airplane the maximum climb rate reduces approximately linear with the air density.
Therefore, we can write the maximum climb rate as:
-$$\dot{h}_{max} = \hat{\dot{h}} * {\rho_{sealevel} \over{\rho}} K$$
+$$\dot{h}_{\text{max}} = \hat{\dot{h}} \cdot \frac{\rho_{\text{sealevel}}}{\rho} K$$
-where $\rho_{sealevel}$ is the air density at sea level in the standard atmosphere and K is a scaling factor which determines the slope of the function.
+where $\rho_{\text{sealevel}}$ is the air density at sea level in the standard atmosphere and K is a scaling factor which determines the slope of the function.
Rather than trying to identify this constants, the usual practice in aviation is to specify a service ceiling altitude at which the vehicle is still able to achieve a minimum specified climb rate.
### Effect of Density on Minimum Sink Rate
@@ -126,7 +134,7 @@ The minimum sink rate is set using [FW_T_SINK_MIN](../advanced_config/parameter_
In previous sections we have seen the formula for the minimum sink rate:
-$$\dot{h}_{min} = \sqrt{2mg\over{\rho S}} f(C_L, C_D)$$
+$$\dot{h}_{\text{min}} = \sqrt{\frac{2mg}{\rho S}}\, f(C_L, C_D)$$
This shows that the minimum sink rate scales with the square root of the inverse air density.
diff --git a/src/lib/fw_performance_model/PerformanceModel.cpp b/src/lib/fw_performance_model/PerformanceModel.cpp
index e946347a44..3d3b36c8ce 100644
--- a/src/lib/fw_performance_model/PerformanceModel.cpp
+++ b/src/lib/fw_performance_model/PerformanceModel.cpp
@@ -218,6 +218,31 @@ bool PerformanceModel::runSanityChecks() const
ret = false;
}
+ const float max_bank_loadfactor = 1 / cosf(math::radians(_param_fw_r_lim.get()));
+ const float min_airspd_at_max_bank = getMinimumCalibratedAirspeed(max_bank_loadfactor, /*flaps_setpoint = */0.0f);
+
+ if (min_airspd_at_max_bank > _param_fw_airspd_max.get()) {
+
+ // Flying the maximum bank angle requires an airspeed above FW_AIRSPD_MAX.
+ // To mitigate, choose between these (or a combination):
+ // - Allow higher airspeeds (formula from getMinimumCalibratedAirspeed):
+ // FW_AIRSPD_MAX >= FW_AIRSPD_MIN * sqrt(WEIGHT_GROSS/WEIGHT_BASE) * sqrt(1/cos(FW_R_LIM))
+ // - Decrease max bank angle (same inequality, solved for FW_R_LIM):
+ // FW_R_LIM <= acos((FW_AIRSPD_MIN/FW_AIRSPD_MAX)**2 * (WEIGHT_GROSS/WEIGHT_BASE))
+ // If flying with a range of weight ratios, take the worst case (heaviest) for both these formulas.
+
+ /* EVENT
+ * @description
+ * - FW_AIRSPD_MIN: {1:.1}
+ * - FW_AIRSPD_MAX: {2:.1}
+ * - FW_R_LIM: {3:.1}
+ */
+ events::send(events::ID("fixedwing_position_control_conf_invalid_maxbank_infeasible"), events::Log::Error,
+ "Invalid configuration: FW_AIRSPD_MAX too low to sustain max bank angle",
+ _param_fw_airspd_min.get(), _param_fw_airspd_max.get(), _param_fw_r_lim.get());
+ ret = false;
+ }
+
return ret;
}
diff --git a/src/lib/fw_performance_model/PerformanceModel.hpp b/src/lib/fw_performance_model/PerformanceModel.hpp
index dece1bb3e0..07a10e8621 100644
--- a/src/lib/fw_performance_model/PerformanceModel.hpp
+++ b/src/lib/fw_performance_model/PerformanceModel.hpp
@@ -137,7 +137,8 @@ private:
(ParamFloat) _param_fw_thr_min,
(ParamFloat) _param_fw_thr_aspd_min,
(ParamFloat) _param_fw_thr_aspd_max,
- (ParamFloat) _param_fw_airspd_flp_sc
+ (ParamFloat) _param_fw_airspd_flp_sc,
+ (ParamFloat) _param_fw_r_lim
)
/**