diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 4373c1f3349..93ba1eef46e 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -84,6 +84,7 @@ 1. [FWC] Implement non-cancellable master warning for overspeed and gear not down - @tracernz (Mike) 1. [EFB] Checklist restructure to add more capabilities and use json configs - @frankkopp (Frank Kopp) 1. [FLIGHTMODEL] Landing lights or RAT extended now have drag - @Crocket63 (crocket) +1. [ATHR/FADEC] Improved reverse thrust limit - @aguther (Andreas Guther) ## 0.11.0 diff --git a/fbw-a32nx/docs/Configuration/ModelConfiguration.ini b/fbw-a32nx/docs/Configuration/ModelConfiguration.ini index f5a45e1894c..1b5a43461f6 100644 --- a/fbw-a32nx/docs/Configuration/ModelConfiguration.ini +++ b/fbw-a32nx/docs/Configuration/ModelConfiguration.ini @@ -33,8 +33,8 @@ [autothrust] ; !! WARNING CHANGE AT YOUR OWN RISK !! -; sets the target N1 for full reverse -;thrust_limit_reverse = -45.0 +; sets the target N1 in percentage of TOGA limit for full reverse +;thrust_limit_reverse_percentage_toga = 0.8 ; !! WARNING CHANGE AT YOUR OWN RISK !! ; if enabled, thrust limits IDLE, CLB and TOGA are taken from local variables diff --git a/fbw-a32nx/src/base/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/engines.cfg b/fbw-a32nx/src/base/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/engines.cfg index 750f9776b04..62b50b0a342 100644 --- a/fbw-a32nx/src/base/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/engines.cfg +++ b/fbw-a32nx/src/base/flybywire-aircraft-a320-neo/SimObjects/AirPlanes/FlyByWire_A320_NEO/engines.cfg @@ -4,7 +4,7 @@ minor = 0 [GENERALENGINEDATA] engine_type = 1 ; 0=Piston, 1=Jet, 2=None, 3=Helo-Turbine, 4=Rocket, 5=Turboprop -min_throttle_limit = -0.2 ; Minimum percent throttle. Generally negative for turbine reverser +min_throttle_limit = -1.0 ; Minimum percent throttle. Generally negative for turbine reverser master_ignition_switch = 0 starter_type = 2 ; 0=Electric, 1=Manual, 2=Bleed Air max_contrail_temperature = -39.724 diff --git a/fbw-a32nx/src/systems/instruments/src/EWD/N1Limit.tsx b/fbw-a32nx/src/systems/instruments/src/EWD/N1Limit.tsx index dc7be0896b3..f926eb5d5e0 100644 --- a/fbw-a32nx/src/systems/instruments/src/EWD/N1Limit.tsx +++ b/fbw-a32nx/src/systems/instruments/src/EWD/N1Limit.tsx @@ -52,7 +52,7 @@ export class N1Limit extends DisplayComponent { }); sub.on('autoThrustLimit').whenChanged().handle((l) => { - this.autoThrustLimit = l; + this.autoThrustLimit = Math.abs(l); }); sub.on('thrustLimitType').whenChanged().handle((l) => { diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp index 83b949e9541..3bf6ee8a2ab 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp +++ b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp @@ -223,13 +223,11 @@ void FlyByWireInterface::loadConfiguration() { // -------------------------------------------------------------------------- // load values - autothrust - autothrustThrustLimitReverse = INITypeConversion::getDouble(iniStructure, "AUTOTHRUST", "THRUST_LIMIT_REVERSE", -45.0); - - // initialize local variable for reverse - idAutothrustThrustLimitREV->set(autothrustThrustLimitReverse); + autothrustThrustLimitReversePercentageToga = + INITypeConversion::getDouble(iniStructure, "AUTOTHRUST", "THRUST_LIMIT_REVERSE_PERCENTAGE_TOGA", 0.813); // print configuration into console - std::cout << "WASM: AUTOTHRUST : THRUST_LIMIT_REVERSE = " << autothrustThrustLimitReverse << std::endl; + std::cout << "WASM: AUTOTHRUST : THRUST_LIMIT_REVERSE_PERCENTAGE_TOGA = " << autothrustThrustLimitReversePercentageToga << std::endl; // -------------------------------------------------------------------------- // load values - flight controls @@ -2407,6 +2405,9 @@ bool FlyByWireInterface::updateAutothrust(double sampleTime) { idThrottlePosition3d_1->set(idThrottlePositionLookupTable3d.get(thrustLeverAngle_1->get())); idThrottlePosition3d_2->set(idThrottlePositionLookupTable3d.get(thrustLeverAngle_2->get())); + // update reverser thrust limit + idAutothrustThrustLimitREV->set(idAutothrustThrustLimitTOGA->get() * autothrustThrustLimitReversePercentageToga); + // set client data if needed if (!autoThrustEnabled || !autopilotStateMachineEnabled || !flyByWireEnabled) { ClientDataLocalVariablesAutothrust ClientDataLocalVariablesAutothrust = { diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h index 13575633941..18b80a8f94a 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h +++ b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h @@ -76,7 +76,7 @@ class FlyByWireInterface { bool wasPaused = false; bool wasInSlew = false; - double autothrustThrustLimitReverse = -45; + double autothrustThrustLimitReversePercentageToga = 0.0; bool flightDirectorConnectLatch_1 = false; bool flightDirectorConnectLatch_2 = false; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_data.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_data.cpp index 4d55c0868ee..7fe4c426c36 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_data.cpp +++ b/fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_data.cpp @@ -180,13 +180,13 @@ Autothrust::Parameters_Autothrust_T Autothrust::Autothrust_P{ 0.0, - -20.0, + -100.0, -2.0, 0.0, - -20.0, + -100.0, { 1.8, 1.8, 1.0, 1.2, 1.2 }, diff --git a/fbw-common/src/wasm/systems/systems/src/engine/reverser_thrust.rs b/fbw-common/src/wasm/systems/systems/src/engine/reverser_thrust.rs index e3cff601ce3..d465164e9fb 100644 --- a/fbw-common/src/wasm/systems/systems/src/engine/reverser_thrust.rs +++ b/fbw-common/src/wasm/systems/systems/src/engine/reverser_thrust.rs @@ -6,7 +6,7 @@ use uom::si::{ mass::kilogram, ratio::{percent, ratio}, torque::newton_meter, - velocity::{foot_per_second, meter_per_second}, + velocity::{foot_per_second, knot, meter_per_second}, }; use crate::{ @@ -29,20 +29,26 @@ impl ReverserThrust { current_thrust: Force::default(), } } - fn update(&mut self, engine: &impl Engine, reverser_position: &impl ReverserPosition) { - self.current_thrust = if reverser_position.reverser_position().get::() - > Self::MIN_REVERSER_POS - { - let current_thrust_force = - Force::new::(engine.net_thrust().get::() * 9.80665); - - // Total net thrust with reverser will need to cancel out forward thrust generated by engine + added desired reverse thrust - (current_thrust_force - + current_thrust_force * Self::reverse_thrust_ratio_from_n1(engine.corrected_n1())) - * reverser_position.reverser_position() - } else { - Force::default() - }; + fn update( + &mut self, + engine: &impl Engine, + reverser_position: &impl ReverserPosition, + longitudinal_velocity: Velocity, + ) { + self.current_thrust = + if reverser_position.reverser_position().get::() > Self::MIN_REVERSER_POS { + let current_thrust_force = + Force::new::(engine.net_thrust().get::() * 9.80665); + + // Total net thrust with reverser will need to cancel out forward thrust generated by engine + added desired reverse thrust + (current_thrust_force + + current_thrust_force + * Self::reverse_thrust_ratio_from_n1(engine.corrected_n1()) + * Self::reverse_thrust_ratio_longitudinal_velocity(longitudinal_velocity)) + * reverser_position.reverser_position() + } else { + Force::default() + }; } fn current_thrust(&self) -> Force { @@ -50,9 +56,9 @@ impl ReverserThrust { } fn reverse_thrust_ratio_from_n1(engine_n1: Ratio) -> Ratio { - let n1_breakpoints = [0., 15., 20., 50., 55.]; + let n1_breakpoints = [0., 15., 20., 50., 55., 100.]; - let reverse_thrust_ratio = [0., 0., 0.15, 0.4, 0.42]; + let reverse_thrust_ratio = [0., 0., 0.04, 0.31, 0.31, 0.31]; Ratio::new::(interpolation( &n1_breakpoints, @@ -60,6 +66,16 @@ impl ReverserThrust { engine_n1.get::(), )) } + + fn reverse_thrust_ratio_longitudinal_velocity(longitudinal_velocity: Velocity) -> Ratio { + let longitudinal_velocity_knots = longitudinal_velocity.get::(); + + if longitudinal_velocity_knots >= 0. { + Ratio::new::(1.0) + } else { + Ratio::new::((0.1151 * longitudinal_velocity_knots).exp()) + } + } } pub struct ReverserForce { @@ -98,7 +114,11 @@ impl ReverserForce { reverser_position: &[impl ReverserPosition], ) { for (engine_index, reverser) in self.reversers.iter_mut().enumerate() { - reverser.update(engine[engine_index], &reverser_position[engine_index]); + reverser.update( + engine[engine_index], + &reverser_position[engine_index], + Velocity::new::(context.local_velocity().to_ms_vector()[2]), + ); } let total_force = self.reversers[0].current_thrust() + self.reversers[1].current_thrust();