From 630cee5316f589f7be41b6ef8aa09eccd333acb5 Mon Sep 17 00:00:00 2001 From: Saschl Date: Thu, 22 Dec 2022 09:30:42 +0100 Subject: [PATCH] feat(hyd): faster core hydraulics solver #7635 @605d7c3 --- .github/CHANGELOG.md | 1 + src/systems/a320_systems/src/hydraulic/mod.rs | 190 ++++++++---------- src/systems/a380_systems/src/hydraulic/mod.rs | 108 ++++------ .../src/hydraulic/electrical_generator.rs | 10 +- .../src/hydraulic/electrical_pump_physics.rs | 6 +- .../systems/src/hydraulic/flap_slat.rs | 6 +- .../systems/src/hydraulic/landing_gear.rs | 38 ++-- .../systems/src/hydraulic/linear_actuator.rs | 30 +-- src/systems/systems/src/hydraulic/mod.rs | 11 +- .../trimmable_horizontal_stabilizer.rs | 10 +- 10 files changed, 181 insertions(+), 229 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index e409aeb4e17..7a942de6d6d 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -10,6 +10,7 @@ 1. [ADIRU] Implemented wind speed computation from TAS/GS/HDG - @tracernz (Mike) 1. [FMGC] Show proper transition names and final approach slope from AAU1 - @tracernz (Mike) 1. [FMGC] Don't accept blank input or / for hold distance - @tracernz (Mike) +1. [HYD] Faster core hydraulics solver - @Crocket63 (crocket) 1. [ATSU] Fix LSK6L not returning to ATSU DATALINK page in ATC MENU - @BravoMike99 (Bruno_pt99#5802) 1. [HYD] Trimmable physical assemblies - @Crocket63 (crocket) 1. [HYD] Simulation of the rudder mechanical assembly and yaw dampers - @Crocket63 (crocket) diff --git a/src/systems/a320_systems/src/hydraulic/mod.rs b/src/systems/a320_systems/src/hydraulic/mod.rs index e301f3fd329..9097782094e 100644 --- a/src/systems/a320_systems/src/hydraulic/mod.rs +++ b/src/systems/a320_systems/src/hydraulic/mod.rs @@ -56,16 +56,14 @@ use systems::{ AutoOffFaultPushButton, AutoOnFaultPushButton, MomentaryOnPushButton, MomentaryPushButton, }, shared::{ - interpolation, - low_pass_filter::LowPassFilter, - random_from_normal_distribution, random_from_range, - update_iterator::{FixedStepLoop, MaxStepLoop}, - AdirsDiscreteOutputs, AirbusElectricPumpId, AirbusEngineDrivenPumpId, - DelayedFalseLogicGate, DelayedPulseTrueLogicGate, DelayedTrueLogicGate, ElectricalBusType, - ElectricalBuses, EmergencyElectricalRatPushButton, EmergencyElectricalState, - EmergencyGeneratorPower, EngineFirePushButtons, GearWheel, HydraulicColor, - HydraulicGeneratorControlUnit, LandingGearHandle, LgciuInterface, LgciuWeightOnWheels, - ReservoirAirPressure, SectionPressure, TrimmableHorizontalStabilizer, + interpolation, low_pass_filter::LowPassFilter, random_from_normal_distribution, + random_from_range, update_iterator::MaxStepLoop, AdirsDiscreteOutputs, + AirbusElectricPumpId, AirbusEngineDrivenPumpId, DelayedFalseLogicGate, + DelayedPulseTrueLogicGate, DelayedTrueLogicGate, ElectricalBusType, ElectricalBuses, + EmergencyElectricalRatPushButton, EmergencyElectricalState, EmergencyGeneratorPower, + EngineFirePushButtons, GearWheel, HydraulicColor, HydraulicGeneratorControlUnit, + LandingGearHandle, LgciuInterface, LgciuWeightOnWheels, ReservoirAirPressure, + SectionPressure, TrimmableHorizontalStabilizer, }, simulation::{ InitContext, Read, Reader, SimulationElement, SimulationElementVisitor, SimulatorReader, @@ -1424,9 +1422,7 @@ pub(super) struct A320Hydraulic { nose_steering: SteeringActuator, - core_hydraulic_updater: FixedStepLoop, - physics_updater: MaxStepLoop, - ultra_fast_physics_updater: MaxStepLoop, + core_hydraulic_updater: MaxStepLoop, brake_steer_computer: A320HydraulicBrakeSteerComputerUnit, @@ -1543,13 +1539,7 @@ impl A320Hydraulic { ElectricalBusType::DirectCurrentHot(2); // Refresh rate of core hydraulic simulation - const HYDRAULIC_SIM_TIME_STEP: Duration = Duration::from_millis(33); - // Refresh rate of max fixed step loop for fast physics - const HYDRAULIC_SIM_MAX_TIME_STEP_MILLISECONDS: Duration = Duration::from_millis(33); - // Refresh rate of max fixed step loop for fastest flight controls physics needing super stability - // and fast reacting time - const HYDRAULIC_SIM_FLIGHT_CONTROLS_MAX_TIME_STEP_MILLISECONDS: Duration = - Duration::from_millis(10); + const HYDRAULIC_SIM_TIME_STEP: Duration = Duration::from_millis(10); pub(super) fn new(context: &mut InitContext) -> A320Hydraulic { A320Hydraulic { @@ -1565,11 +1555,7 @@ impl A320Hydraulic { Ratio::new::(0.18), ), - core_hydraulic_updater: FixedStepLoop::new(Self::HYDRAULIC_SIM_TIME_STEP), - physics_updater: MaxStepLoop::new(Self::HYDRAULIC_SIM_MAX_TIME_STEP_MILLISECONDS), - ultra_fast_physics_updater: MaxStepLoop::new( - Self::HYDRAULIC_SIM_FLIGHT_CONTROLS_MAX_TIME_STEP_MILLISECONDS, - ), + core_hydraulic_updater: MaxStepLoop::new(Self::HYDRAULIC_SIM_TIME_STEP), brake_steer_computer: A320HydraulicBrakeSteerComputerUnit::new(context), @@ -1786,19 +1772,6 @@ impl A320Hydraulic { adirs: &impl AdirsDiscreteOutputs, ) { self.core_hydraulic_updater.update(context); - self.physics_updater.update(context); - self.ultra_fast_physics_updater.update(context); - - for cur_time_step in self.physics_updater { - self.update_fast_physics( - &context.with_delta(cur_time_step), - rat_and_emer_gen_man_on, - emergency_elec, - lgcius.lgciu1(), - lgcius.lgciu2(), - adirs, - ); - } self.update_with_sim_rate( context, @@ -1812,11 +1785,15 @@ impl A320Hydraulic { engine2, ); - for cur_time_step in self.ultra_fast_physics_updater { - self.update_ultra_fast_physics(&context.with_delta(cur_time_step), lgcius); - } - for cur_time_step in self.core_hydraulic_updater { + self.update_physics( + &context.with_delta(cur_time_step), + rat_and_emer_gen_man_on, + emergency_elec, + lgcius, + adirs, + ); + self.update_core_hydraulics( &context.with_delta(cur_time_step), engine1, @@ -1917,11 +1894,70 @@ impl A320Hydraulic { self.yellow_circuit.system_section_pressure_switch() == PressureSwitchState::Pressurised } - fn update_ultra_fast_physics( + // Updates at the same rate as the sim or at a fixed maximum time step if sim rate is too slow + fn update_physics( &mut self, context: &UpdateContext, + rat_and_emer_gen_man_on: &impl EmergencyElectricalRatPushButton, + emergency_elec: &(impl EmergencyElectricalState + EmergencyGeneratorPower), lgcius: &LandingGearControlInterfaceUnitSet, + adirs: &impl AdirsDiscreteOutputs, ) { + self.forward_cargo_door.update( + context, + &self.forward_cargo_door_controller, + self.yellow_circuit.system_section(), + ); + + self.aft_cargo_door.update( + context, + &self.aft_cargo_door_controller, + self.yellow_circuit.system_section(), + ); + + self.ram_air_turbine.update_physics( + &context.delta(), + context.indicated_airspeed(), + self.blue_circuit.system_section(), + ); + + self.gcu.update( + context, + &self.emergency_gen, + self.blue_circuit.system_section(), + emergency_elec, + rat_and_emer_gen_man_on, + lgcius.lgciu1(), + ); + + self.emergency_gen.update( + context, + self.blue_circuit.system_section(), + &self.gcu, + emergency_elec, + ); + + self.gear_system_hydraulic_controller.update( + adirs, + lgcius.lgciu1(), + lgcius.lgciu2(), + &self.gear_system_gravity_extension_controller, + ); + + self.trim_assembly.update( + context, + &self.trim_controller, + &self.trim_controller, + [ + self.green_circuit + .system_section() + .pressure_downstream_leak_valve(), + self.yellow_circuit + .system_section() + .pressure_downstream_leak_valve(), + ], + ); + self.left_aileron.update( context, self.aileron_system_controller.left_controllers(), @@ -1982,72 +2018,6 @@ impl A320Hydraulic { ); } - // Updates at the same rate as the sim or at a fixed maximum time step if sim rate is too slow - fn update_fast_physics( - &mut self, - context: &UpdateContext, - rat_and_emer_gen_man_on: &impl EmergencyElectricalRatPushButton, - emergency_elec: &(impl EmergencyElectricalState + EmergencyGeneratorPower), - lgciu1: &impl LgciuInterface, - lgciu2: &impl LgciuInterface, - adirs: &impl AdirsDiscreteOutputs, - ) { - self.forward_cargo_door.update( - context, - &self.forward_cargo_door_controller, - self.yellow_circuit.system_section(), - ); - - self.aft_cargo_door.update( - context, - &self.aft_cargo_door_controller, - self.yellow_circuit.system_section(), - ); - - self.ram_air_turbine.update_physics( - &context.delta(), - context.indicated_airspeed(), - self.blue_circuit.system_section(), - ); - - self.gcu.update( - context, - &self.emergency_gen, - self.blue_circuit.system_section(), - emergency_elec, - rat_and_emer_gen_man_on, - lgciu1, - ); - - self.emergency_gen.update( - context, - self.blue_circuit.system_section(), - &self.gcu, - emergency_elec, - ); - - self.gear_system_hydraulic_controller.update( - adirs, - lgciu1, - lgciu2, - &self.gear_system_gravity_extension_controller, - ); - - self.trim_assembly.update( - context, - &self.trim_controller, - &self.trim_controller, - [ - self.green_circuit - .system_section() - .pressure_downstream_leak_valve(), - self.yellow_circuit - .system_section() - .pressure_downstream_leak_valve(), - ], - ); - } - fn update_with_sim_rate( &mut self, context: &UpdateContext, @@ -10546,7 +10516,7 @@ mod tests { .set_cold_dark_inputs() .start_eng1(Ratio::new::(80.)) .start_eng2(Ratio::new::(80.)) - .run_waiting_for(Duration::from_millis(500)); + .run_waiting_for(Duration::from_millis(1000)); assert!(!test_bed.ptu_has_fault()); assert!(!test_bed.green_edp_has_fault()); diff --git a/src/systems/a380_systems/src/hydraulic/mod.rs b/src/systems/a380_systems/src/hydraulic/mod.rs index f093da09f1e..8e4318c97e8 100644 --- a/src/systems/a380_systems/src/hydraulic/mod.rs +++ b/src/systems/a380_systems/src/hydraulic/mod.rs @@ -1890,14 +1890,7 @@ impl A380Hydraulic { ); for cur_time_step in self.core_hydraulic_updater { - self.update_fast_physics( - &context.with_delta(cur_time_step), - lgcius.lgciu1(), - lgcius.lgciu2(), - adirs, - ); - - self.update_ultra_fast_physics(&context.with_delta(cur_time_step), lgcius); + self.update_physics(&context.with_delta(cur_time_step), lgcius, adirs); self.update_core_hydraulics( &context.with_delta(cur_time_step), @@ -1957,11 +1950,45 @@ impl A380Hydraulic { self.yellow_circuit.system_section_pressure_switch() == PressureSwitchState::Pressurised } - fn update_ultra_fast_physics( + fn update_physics( &mut self, context: &UpdateContext, lgcius: &LandingGearControlInterfaceUnitSet, + adirs: &impl AdirsDiscreteOutputs, ) { + self.forward_cargo_door.update( + context, + &self.forward_cargo_door_controller, + self.green_circuit.auxiliary_section(), + ); + + self.aft_cargo_door.update( + context, + &self.aft_cargo_door_controller, + self.green_circuit.auxiliary_section(), + ); + + self.gear_system_hydraulic_controller.update( + adirs, + lgcius.lgciu1(), + lgcius.lgciu2(), + &self.gear_system_gravity_extension_controller, + ); + + self.trim_assembly.update( + context, + &self.trim_controller, + &self.trim_controller, + [ + self.green_circuit + .system_section() + .pressure_downstream_leak_valve(), + self.yellow_circuit + .system_section() + .pressure_downstream_leak_valve(), + ], + ); + self.left_aileron.update( context, [ @@ -2080,48 +2107,6 @@ impl A380Hydraulic { ); } - // Updates at the same rate as the sim or at a fixed maximum time step if sim rate is too slow - fn update_fast_physics( - &mut self, - context: &UpdateContext, - lgciu1: &impl LgciuInterface, - lgciu2: &impl LgciuInterface, - adirs: &impl AdirsDiscreteOutputs, - ) { - self.forward_cargo_door.update( - context, - &self.forward_cargo_door_controller, - self.green_circuit.auxiliary_section(), - ); - - self.aft_cargo_door.update( - context, - &self.aft_cargo_door_controller, - self.green_circuit.auxiliary_section(), - ); - - self.gear_system_hydraulic_controller.update( - adirs, - lgciu1, - lgciu2, - &self.gear_system_gravity_extension_controller, - ); - - self.trim_assembly.update( - context, - &self.trim_controller, - &self.trim_controller, - [ - self.green_circuit - .system_section() - .pressure_downstream_leak_valve(), - self.yellow_circuit - .system_section() - .pressure_downstream_leak_valve(), - ], - ); - } - fn update_with_sim_rate( &mut self, context: &UpdateContext, @@ -10019,27 +10004,6 @@ mod tests { assert!(test_bed.yellow_pressure().get::() < 3500.); } - #[test] - fn low_air_press_fault_causes_ptu_fault() { - let mut test_bed = test_bed_on_ground_with() - .engines_off() - .on_the_ground() - .set_cold_dark_inputs() - .start_eng1(Ratio::new::(80.)) - .start_eng2(Ratio::new::(80.)) - .run_waiting_for(Duration::from_millis(500)); - - assert!(!test_bed.green_edp_has_fault()); - assert!(!test_bed.yellow_edp_has_fault()); - - test_bed = test_bed - .air_press_low() - .run_waiting_for(Duration::from_secs_f64(10.)); - - assert!(test_bed.green_edp_has_fault()); - assert!(test_bed.yellow_edp_has_fault()); - } - #[test] fn ailerons_are_dropped_down_in_cold_and_dark() { let mut test_bed = test_bed_on_ground_with() diff --git a/src/systems/systems/src/hydraulic/electrical_generator.rs b/src/systems/systems/src/hydraulic/electrical_generator.rs index e5e85daa0f4..3ff0f08f8cd 100644 --- a/src/systems/systems/src/hydraulic/electrical_generator.rs +++ b/src/systems/systems/src/hydraulic/electrical_generator.rs @@ -364,7 +364,7 @@ impl EmergencyGeneratorPower for TestGenerator { #[cfg(test)] mod tests { use super::*; - use crate::shared::update_iterator::FixedStepLoop; + use crate::shared::update_iterator::MaxStepLoop; use crate::simulation::test::{SimulationTestBed, TestBed}; use crate::simulation::{Aircraft, SimulationElement, SimulationElementVisitor}; use std::time::Duration; @@ -478,7 +478,7 @@ mod tests { } struct TestAircraft { - updater_fixed_step: FixedStepLoop, + updater_max_step: MaxStepLoop, gcu: GeneratorControlUnit<9>, lgciu: TestLgciuSensors, @@ -491,7 +491,7 @@ mod tests { impl TestAircraft { fn new(context: &mut InitContext) -> Self { Self { - updater_fixed_step: FixedStepLoop::new(Duration::from_millis(33)), + updater_max_step: MaxStepLoop::new(Duration::from_millis(10)), gcu: gen_control_unit(), lgciu: TestLgciuSensors::compressed(), rat_man_on: TestRatManOn::not_pressed(), @@ -524,9 +524,9 @@ mod tests { } impl Aircraft for TestAircraft { fn update_after_power_distribution(&mut self, context: &UpdateContext) { - self.updater_fixed_step.update(context); + self.updater_max_step.update(context); - for cur_time_step in &mut self.updater_fixed_step { + for cur_time_step in &mut self.updater_max_step { self.gcu.update( &context.with_delta(cur_time_step), &self.emergency_gen, diff --git a/src/systems/systems/src/hydraulic/electrical_pump_physics.rs b/src/systems/systems/src/hydraulic/electrical_pump_physics.rs index d7e9f29fb1e..329be545db9 100644 --- a/src/systems/systems/src/hydraulic/electrical_pump_physics.rs +++ b/src/systems/systems/src/hydraulic/electrical_pump_physics.rs @@ -301,7 +301,7 @@ mod tests { use crate::electrical::ElectricalBus; use crate::electrical::Electricity; - use crate::shared::{update_iterator::FixedStepLoop, PotentialOrigin}; + use crate::shared::{update_iterator::MaxStepLoop, PotentialOrigin}; use crate::simulation::{Aircraft, SimulationElement, SimulationElementVisitor, UpdateContext}; use crate::simulation::test::{SimulationTestBed, TestBed}; @@ -332,7 +332,7 @@ mod tests { } struct TestAircraft { - core_hydraulic_updater: FixedStepLoop, + core_hydraulic_updater: MaxStepLoop, pump: ElectricalPumpPhysics, hydraulic_section: TestHydraulicSection, @@ -345,7 +345,7 @@ mod tests { impl TestAircraft { fn new(context: &mut InitContext) -> Self { Self { - core_hydraulic_updater: FixedStepLoop::new(Duration::from_millis(33)), + core_hydraulic_updater: MaxStepLoop::new(Duration::from_millis(10)), pump: physical_pump(context), hydraulic_section: TestHydraulicSection::default(), current_displacement: Volume::new::(0.), diff --git a/src/systems/systems/src/hydraulic/flap_slat.rs b/src/systems/systems/src/hydraulic/flap_slat.rs index 2520513b200..0b8eccc1b26 100644 --- a/src/systems/systems/src/hydraulic/flap_slat.rs +++ b/src/systems/systems/src/hydraulic/flap_slat.rs @@ -498,7 +498,7 @@ mod tests { use std::time::Duration; use uom::si::{angle::degree, pressure::psi}; - use crate::shared::update_iterator::FixedStepLoop; + use crate::shared::update_iterator::MaxStepLoop; use crate::simulation::{ test::{SimulationTestBed, TestBed}, @@ -531,7 +531,7 @@ mod tests { } struct TestAircraft { - core_hydraulic_updater: FixedStepLoop, + core_hydraulic_updater: MaxStepLoop, flaps_slats: FlapSlatAssembly, @@ -544,7 +544,7 @@ mod tests { impl TestAircraft { fn new(context: &mut InitContext, max_speed: AngularVelocity) -> Self { Self { - core_hydraulic_updater: FixedStepLoop::new(Duration::from_millis(33)), + core_hydraulic_updater: MaxStepLoop::new(Duration::from_millis(10)), flaps_slats: flap_system(context, max_speed), left_motor_angle_request: None, right_motor_angle_request: None, diff --git a/src/systems/systems/src/hydraulic/landing_gear.rs b/src/systems/systems/src/hydraulic/landing_gear.rs index 9a120ae099f..049b927d225 100644 --- a/src/systems/systems/src/hydraulic/landing_gear.rs +++ b/src/systems/systems/src/hydraulic/landing_gear.rs @@ -1283,14 +1283,16 @@ mod tests { #[test] fn door_assembly_init_uplocked() { let mut test_bed = SimulationTestBed::new(|context| { + let gear_door = main_gear_door_right_assembly(context); + TestSingleGearAircraft::new( - Duration::from_millis(33), - main_gear_door_right_assembly(context), + Duration::from_millis(10), + gear_door, main_gear_right_assembly(context, true), ) }); - test_bed.run_with_delta(Duration::from_millis(33)); + test_bed.run_with_delta(Duration::from_millis(10)); assert!(test_bed.query(|a| a.door_assembly.is_locked())); assert!( @@ -1301,14 +1303,16 @@ mod tests { #[test] fn door_uplocked_gives_correct_proximity_sensor_state() { let mut test_bed = SimulationTestBed::new(|context| { + let gear_door = main_gear_door_right_assembly(context); + TestSingleGearAircraft::new( - Duration::from_millis(33), - main_gear_door_right_assembly(context), + Duration::from_millis(10), + gear_door, main_gear_right_assembly(context, true), ) }); - test_bed.run_with_delta(Duration::from_millis(33)); + test_bed.run_with_delta(Duration::from_millis(10)); assert!( test_bed.query(|a| a.door_assembly.position_normalized()) == Ratio::new::(0.) @@ -1324,14 +1328,16 @@ mod tests { #[test] fn door_opens_gear_stays_down_and_locked() { let mut test_bed = SimulationTestBed::new(|context| { + let gear_door = main_gear_door_right_assembly(context); + TestSingleGearAircraft::new( - Duration::from_millis(33), - main_gear_door_right_assembly(context), + Duration::from_millis(10), + gear_door, main_gear_right_assembly(context, true), ) }); - test_bed.run_with_delta(Duration::from_millis(33)); + test_bed.run_with_delta(Duration::from_millis(10)); assert!(test_bed.query(|a| a.is_door_sensor_uplock(LgciuId::Lgciu1))); assert!(test_bed.query(|a| a.is_door_sensor_uplock(LgciuId::Lgciu2))); @@ -1342,9 +1348,11 @@ mod tests { #[test] fn no_unlocking_from_door_uplock_without_pressure() { let mut test_bed = SimulationTestBed::new(|context| { + let gear_door = main_gear_door_right_assembly(context); + TestSingleGearAircraft::new( - Duration::from_millis(33), - main_gear_door_right_assembly(context), + Duration::from_millis(10), + gear_door, main_gear_right_assembly(context, true), ) }); @@ -1360,13 +1368,15 @@ mod tests { #[test] fn full_retract_extend_cycle() { let mut test_bed = SimulationTestBed::new(|context| { + let gear_door = main_gear_door_right_assembly(context); + TestSingleGearAircraft::new( - Duration::from_millis(33), - main_gear_door_right_assembly(context), + Duration::from_millis(10), + gear_door, main_gear_right_assembly(context, true), ) }); - test_bed.run_with_delta(Duration::from_millis(33)); + test_bed.run_with_delta(Duration::from_millis(10)); println!("RETRACT -- > DOOR OPENING"); test_bed.command(|a| a.command_doors_opening()); diff --git a/src/systems/systems/src/hydraulic/linear_actuator.rs b/src/systems/systems/src/hydraulic/linear_actuator.rs index 7874997c54f..3273873a6c5 100644 --- a/src/systems/systems/src/hydraulic/linear_actuator.rs +++ b/src/systems/systems/src/hydraulic/linear_actuator.rs @@ -2551,7 +2551,7 @@ mod tests { fn linear_actuator_not_moving_on_locked_rigid_body() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); let actuator_position_init = test_bed.query(|a| a.body_position()); @@ -2565,7 +2565,7 @@ mod tests { fn linear_actuator_moving_on_unlocked_rigid_body() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); let actuator_position_init = test_bed.query(|a| a.body_position()); @@ -2584,7 +2584,7 @@ mod tests { fn linear_actuator_can_move_rigid_body_up() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); let actuator_position_init = test_bed.query(|a| a.body_position()); @@ -2607,7 +2607,7 @@ mod tests { fn linear_actuator_resists_body_drop_when_valves_closed() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2630,7 +2630,7 @@ mod tests { fn linear_actuator_dampens_body_drop_when_active_damping_mode() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2654,7 +2654,7 @@ mod tests { fn linear_actuator_dampens_super_slow_body_drop_when_slow_damping_mode() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2678,7 +2678,7 @@ mod tests { fn linear_actuator_without_hyd_pressure_cant_move_body_up() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2695,7 +2695,7 @@ mod tests { fn linear_actuator_losing_hyd_pressure_half_way_cant_move_body_up() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2721,7 +2721,7 @@ mod tests { fn body_gravity_movement_if_unlocked() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, false); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -2740,7 +2740,7 @@ mod tests { fn start_moving_once_unlocked() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.write_by_name(UpdateContext::PLANE_BANK_KEY, -45.); @@ -2762,7 +2762,7 @@ mod tests { fn locks_at_required_position() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.write_by_name(UpdateContext::PLANE_BANK_KEY, -45.); @@ -2791,7 +2791,7 @@ mod tests { fn soft_lock_with_zero_velocity_stops_the_body() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.write_by_name(UpdateContext::PLANE_BANK_KEY, -45.); @@ -2830,7 +2830,7 @@ mod tests { fn linear_actuator_can_control_position() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = cargo_door_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); test_bed.command(|a| a.command_unlock()); @@ -3006,7 +3006,7 @@ mod tests { fn right_main_gear_locked_down_at_init() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = main_gear_right_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); assert!(test_bed.query(|a| a.is_locked())); @@ -3102,7 +3102,7 @@ mod tests { fn left_main_gear_locked_down_at_init() { let mut test_bed = SimulationTestBed::new(|context| { let tested_object = main_gear_left_assembly(context, true); - TestAircraft::new(context, Duration::from_millis(33), tested_object) + TestAircraft::new(context, Duration::from_millis(10), tested_object) }); assert!(test_bed.query(|a| a.is_locked())); diff --git a/src/systems/systems/src/hydraulic/mod.rs b/src/systems/systems/src/hydraulic/mod.rs index 7c107146673..bb6450b59cb 100644 --- a/src/systems/systems/src/hydraulic/mod.rs +++ b/src/systems/systems/src/hydraulic/mod.rs @@ -138,9 +138,13 @@ pub struct PressureSwitch { high_hysteresis_threshold: Pressure, low_hysteresis_threshold: Pressure, + current_pressure_filtered: LowPassFilter, + sensor_type: PressureSwitchType, } impl PressureSwitch { + const PRESSURE_DYNAMIC_TIME_CONSTANT: Duration = Duration::from_millis(200); + pub fn new( high_threshold: Pressure, low_threshold: Pressure, @@ -150,6 +154,7 @@ impl PressureSwitch { state_is_pressurised: false, high_hysteresis_threshold: high_threshold, low_hysteresis_threshold: low_threshold, + current_pressure_filtered: LowPassFilter::new(Self::PRESSURE_DYNAMIC_TIME_CONSTANT), sensor_type, } } @@ -159,10 +164,12 @@ impl PressureSwitch { PressureSwitchType::Relative => current_pressure - context.ambient_pressure(), PressureSwitchType::Absolute => current_pressure, }; + self.current_pressure_filtered + .update(context.delta(), pressure_measured); - if pressure_measured <= self.low_hysteresis_threshold { + if self.current_pressure_filtered.output() <= self.low_hysteresis_threshold { self.state_is_pressurised = false; - } else if pressure_measured >= self.high_hysteresis_threshold { + } else if self.current_pressure_filtered.output() >= self.high_hysteresis_threshold { self.state_is_pressurised = true; } } diff --git a/src/systems/systems/src/hydraulic/trimmable_horizontal_stabilizer.rs b/src/systems/systems/src/hydraulic/trimmable_horizontal_stabilizer.rs index 303786f0dab..6af805708d5 100644 --- a/src/systems/systems/src/hydraulic/trimmable_horizontal_stabilizer.rs +++ b/src/systems/systems/src/hydraulic/trimmable_horizontal_stabilizer.rs @@ -740,7 +740,7 @@ mod tests { use crate::electrical::Electricity; use super::*; - use crate::shared::{update_iterator::FixedStepLoop, PotentialOrigin}; + use crate::shared::{update_iterator::MaxStepLoop, PotentialOrigin}; use crate::simulation::test::{ReadByName, SimulationTestBed, TestBed}; use crate::simulation::{Aircraft, SimulationElement}; use std::time::Duration; @@ -818,7 +818,7 @@ mod tests { } struct TestAircraft { - updater_fixed_step: FixedStepLoop, + updater_max_step: MaxStepLoop, elec_trim_control: TestElecTrimControl, manual_trim_control: TestManualTrimControl, @@ -836,7 +836,7 @@ mod tests { impl TestAircraft { fn new(context: &mut InitContext) -> Self { Self { - updater_fixed_step: FixedStepLoop::new(Duration::from_millis(33)), + updater_max_step: MaxStepLoop::new(Duration::from_millis(10)), elec_trim_control: TestElecTrimControl::inactive_control(), manual_trim_control: TestManualTrimControl::without_manual_input(), trim_assembly: TrimmableHorizontalStabilizerAssembly::new( @@ -916,9 +916,9 @@ mod tests { } fn update_after_power_distribution(&mut self, context: &UpdateContext) { - self.updater_fixed_step.update(context); + self.updater_max_step.update(context); - for cur_time_step in &mut self.updater_fixed_step { + for cur_time_step in &mut self.updater_max_step { self.trim_assembly.update( &context.with_delta(cur_time_step), &self.elec_trim_control,