Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fuel): fuel pump consumption #9702

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,7 @@
<NODE_ID>PUSH_OVHD_FUEL_LTKPUMPS1</NODE_ID>
<PART_ID>OVHD_FUEL_LTKPUMPS1</PART_ID>
<ID>2</ID>
<FUEL_LINE>7</FUEL_LINE>
<SEQ_POWERED>(L:A32NX_ELEC_AC_ESS_SHED_BUS_IS_POWERED, Bool)</SEQ_POWERED>
<SEQ2_EMISSIVE_DRIVES_VISIBILITY>False</SEQ2_EMISSIVE_DRIVES_VISIBILITY>
<SEQ1_CODE_DRIVES_VISIBILITY>False</SEQ1_CODE_DRIVES_VISIBILITY>
Expand All @@ -2208,6 +2209,7 @@
<NODE_ID>PUSH_OVHD_FUEL_LTKPUMPS2</NODE_ID>
<PART_ID>OVHD_FUEL_LTKPUMPS2</PART_ID>
<ID>5</ID>
<FUEL_LINE>9</FUEL_LINE>
<SEQ_POWERED>(L:A32NX_ELEC_AC_2_BUS_IS_POWERED, Bool)</SEQ_POWERED>
<SEQ2_EMISSIVE_DRIVES_VISIBILITY>False</SEQ2_EMISSIVE_DRIVES_VISIBILITY>
<SEQ1_CODE_DRIVES_VISIBILITY>False</SEQ1_CODE_DRIVES_VISIBILITY>
Expand Down Expand Up @@ -2253,6 +2255,7 @@
<NODE_ID>PUSH_OVHD_FUEL_RTKPUMPS1</NODE_ID>
<PART_ID>OVHD_FUEL_RTKPUMPS1</PART_ID>
<ID>3</ID>
<FUEL_LINE>8</FUEL_LINE>
<SEQ_POWERED>(L:A32NX_ELEC_AC_ESS_SHED_BUS_IS_POWERED, Bool)</SEQ_POWERED>
<SEQ2_EMISSIVE_DRIVES_VISIBILITY>False</SEQ2_EMISSIVE_DRIVES_VISIBILITY>
<SEQ1_CODE_DRIVES_VISIBILITY>False</SEQ1_CODE_DRIVES_VISIBILITY>
Expand All @@ -2270,6 +2273,7 @@
<OFF_TOOLTIP>COCKPIT.TOOLTIPS.ENG_2_R_TK_PUMP2_OFF</OFF_TOOLTIP>
<ON_TOOLTIP>COCKPIT.TOOLTIPS.ENG_2_R_TK_PUMP2_ON</ON_TOOLTIP>
<ID>6</ID>
<FUEL_LINE>10</FUEL_LINE>
<SEQ_POWERED>(L:A32NX_ELEC_AC_2_BUS_IS_POWERED, Bool)</SEQ_POWERED>
<SEQ2_EMISSIVE_DRIVES_VISIBILITY>False</SEQ2_EMISSIVE_DRIVES_VISIBILITY>
<SEQ1_CODE_DRIVES_VISIBILITY>False</SEQ1_CODE_DRIVES_VISIBILITY>
Expand Down
4 changes: 4 additions & 0 deletions fbw-a32nx/src/behavior/src/A32NX_Interior_Misc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@
<UseTemplate Name="FBW_Push_Toggle">
<LEFT_SINGLE_CODE>#ID# (&gt;K:FUELSYSTEM_PUMP_TOGGLE)</LEFT_SINGLE_CODE>

<Condition Check="FUEL_LINE">
<SEQ1_CODE>(A:FUELSYSTEM PUMP SWITCH:#ID#, Enum) 1 == (A:FUELSYSTEM LINE FUEL PRESSURE:#FUEL_LINE#, psi) 6 &lt; and</SEQ1_CODE>
</Condition>
<SEQ2_CODE>(A:FUELSYSTEM PUMP SWITCH:#ID#, Enum) 0 ==</SEQ2_CODE>

<DOWN_CODE>(A:FUELSYSTEM PUMP SWITCH:#ID#, Enum) 1 ==</DOWN_CODE>
Expand All @@ -218,6 +221,7 @@

<Template Name="FBW_Airbus_Fuel_Crossfeed">
<UseTemplate Name="FBW_Push_Toggle">
<SEQ1_CODE>(A:FUELSYSTEM VALVE OPEN:#ID#, Bool)</SEQ1_CODE>
<SEQ2_CODE>(A:FUELSYSTEM VALVE SWITCH:#ID#, Bool)</SEQ2_CODE>
<LEFT_SINGLE_CODE>#ID# (&gt;K:FUELSYSTEM_VALVE_TOGGLE)</LEFT_SINGLE_CODE>
<TOOLTIPID>%((A:FUELSYSTEM VALVE SWITCH:#ID#, Bool) !)%{if}TT:#OFF_TOOLTIP#%{else}TT:#ON_TOOLTIP#%{end}</TOOLTIPID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ use std::time::Duration;
use systems::{
apu::ApuGenerator,
electrical::{
AlternatingCurrentElectricalSystem, Contactor, ElectricalBus, Electricity,
EmergencyGenerator, ExternalPowerSource, IntegratedDriveGenerator, TransformerRectifier,
AlternatingCurrentElectricalSystem, Contactor, ElectricalBus, ElectricalElement,
Electricity, EmergencyGenerator, ExternalPowerSource, IntegratedDriveGenerator,
TransformerRectifier,
},
engine::Engine,
shared::{
AuxiliaryPowerUnitElectrical, DelayedTrueLogicGate, ElectricalBusType,
AuxiliaryPowerUnitElectrical, DelayedTrueLogicGate, ElectricalBusType, ElectricalBuses,
EngineFirePushButtons,
},
simulation::{InitContext, SimulationElement, SimulationElementVisitor, UpdateContext},
Expand All @@ -36,6 +37,7 @@ pub(super) struct A320AlternatingCurrentElectrical {
ac_stat_inv_bus: ElectricalBus,
ac_gnd_flt_service_bus: ElectricalBus,
ext_pwr_to_ac_gnd_flt_service_bus_and_tr_2_contactor: Contactor,
auxiliary_supplies: A320AuxiliaryPowerSupplies,
}
impl A320AlternatingCurrentElectrical {
pub fn new(context: &mut InitContext) -> Self {
Expand Down Expand Up @@ -66,6 +68,7 @@ impl A320AlternatingCurrentElectrical {
ElectricalBusType::AlternatingCurrentGndFltService,
),
ext_pwr_to_ac_gnd_flt_service_bus_and_tr_2_contactor: Contactor::new(context, "12XN"),
auxiliary_supplies: A320AuxiliaryPowerSupplies::new(context),
}
}

Expand Down Expand Up @@ -204,6 +207,25 @@ impl A320AlternatingCurrentElectrical {
electricity.flow(&self.static_inv_to_ac_ess_bus_contactor, &self.ac_ess_bus);
}

/// ## Dependencies:
/// * AC electrical
/// * DC electrical
pub fn update_auxiliary(
&mut self,
electricity: &mut Electricity,
emergency_overhead: &A320EmergencyElectricalOverheadPanel,
) {
self.auxiliary_supplies.update(
electricity,
&self.main_power_sources,
&self.ac_bus_1,
&self.ac_bus_2,
&self.ac_ess_shed_bus,
&self.ac_stat_inv_bus,
emergency_overhead,
);
}

fn update_shedding(
&mut self,
emergency_generator: &EmergencyGenerator,
Expand Down Expand Up @@ -333,6 +355,8 @@ impl SimulationElement for A320AlternatingCurrentElectrical {
self.ext_pwr_to_ac_gnd_flt_service_bus_and_tr_2_contactor
.accept(visitor);

self.auxiliary_supplies.accept(visitor);

visitor.visit(self);
}
}
Expand Down Expand Up @@ -460,6 +484,14 @@ impl A320MainPowerSources {
electricity.flow(&self.bus_tie_2_contactor, bus);
}

fn power_by_generator_1(
&self,
electricity: &mut Electricity,
element: &impl ElectricalElement,
) {
electricity.flow(&self.engine_1_gen, element);
}

pub fn gen_contactor_open(&self, number: usize) -> bool {
self.engine_generator_contactors[number - 1].is_open()
}
Expand Down Expand Up @@ -544,3 +576,112 @@ impl SimulationElement for A320AcEssFeedContactors {
visitor.visit(self);
}
}

struct A320AuxiliaryPowerSupplies {
// Fuel pumps 1 supply
fuel_pump_1_supply: ElectricalBus,
fuel_pump_1_normal_contactor: Contactor,
fuel_pump_1_standby_contactor: Contactor,

// Fuel pumps 2 supply
fuel_pump_2_supply: ElectricalBus,
fuel_pump_2_contactor: Contactor,

// APU fuel pump supply
apu_fuel_pump_supply: ElectricalBus,
apu_fuel_pump_static_inverter_contactor: Contactor,
apu_fuel_pump_ess_sched_contactor: Contactor,
}
impl A320AuxiliaryPowerSupplies {
fn new(context: &mut InitContext) -> Self {
Self {
fuel_pump_1_supply: ElectricalBus::new(
context,
ElectricalBusType::Virtual("FUEL_PUMP_1_SUPPLY"),
),
fuel_pump_1_normal_contactor: Contactor::new(context, "17QA"), // 18QA for R WING pump, both have the same condition
fuel_pump_1_standby_contactor: Contactor::new(context, "53QA"), // 54QA for R WING pump, both have the same condition

fuel_pump_2_supply: ElectricalBus::new(
context,
ElectricalBusType::Virtual("FUEL_PUMP_2_SUPPLY"),
),
fuel_pump_2_contactor: Contactor::new(context, "19QA"), // 20QA for R WING pump, both have the same condition

apu_fuel_pump_supply: ElectricalBus::new(
context,
ElectricalBusType::Virtual("FUEL_PUMP_APU_SUPPLY"),
),
apu_fuel_pump_static_inverter_contactor: Contactor::new(context, "9QC.1"),
apu_fuel_pump_ess_sched_contactor: Contactor::new(context, "9QC.2"),
}
}

fn update(
&mut self,
electricity: &mut Electricity,
main_power_sources: &A320MainPowerSources,
ac_bus_1: &ElectricalBus,
ac_bus_2: &ElectricalBus,
ac_ess_sched: &ElectricalBus,
static_inverter_bus: &ElectricalBus,
overhead: &A320EmergencyElectricalOverheadPanel,
) {
let dc_ess_powered =
electricity.any_is_powered(&[ElectricalBusType::DirectCurrentEssential]);
let dc_1_powered = electricity.any_is_powered(&[ElectricalBusType::DirectCurrent(1)]);
let dc_2_powered = electricity.any_is_powered(&[ElectricalBusType::DirectCurrent(2)]);
let gen_1_line_on = overhead.generator_1_line_is_on();

// Contactor powered by DC 1 but only when DC ESS is powered too
self.fuel_pump_1_normal_contactor
.close_when(gen_1_line_on && dc_1_powered && dc_ess_powered);
// Contactor powered by DC ESS if DC 1 is not powered or gen 1 line is off
self.fuel_pump_1_standby_contactor
.close_when((!gen_1_line_on || !dc_1_powered) && dc_ess_powered);

electricity.flow(ac_bus_1, &self.fuel_pump_1_normal_contactor);
main_power_sources.power_by_generator_1(electricity, &self.fuel_pump_1_standby_contactor);
electricity.flow(&self.fuel_pump_1_normal_contactor, &self.fuel_pump_1_supply);
electricity.flow(
&self.fuel_pump_1_standby_contactor,
&self.fuel_pump_1_supply,
);

// Contactor powered by DC 2
self.fuel_pump_2_contactor.close_when(dc_2_powered);
electricity.flow(ac_bus_2, &self.fuel_pump_2_contactor);
electricity.flow(&self.fuel_pump_2_contactor, &self.fuel_pump_2_supply);

let ess_sched_powered = electricity.is_powered(ac_ess_sched);
self.apu_fuel_pump_static_inverter_contactor
.close_when(!ess_sched_powered);
self.apu_fuel_pump_ess_sched_contactor
.close_when(ess_sched_powered);
electricity.flow(
static_inverter_bus,
&self.apu_fuel_pump_static_inverter_contactor,
);
electricity.flow(ac_ess_sched, &self.apu_fuel_pump_ess_sched_contactor);
electricity.flow(
&self.apu_fuel_pump_static_inverter_contactor,
&self.apu_fuel_pump_supply,
);
electricity.flow(
&self.apu_fuel_pump_ess_sched_contactor,
&self.apu_fuel_pump_supply,
);
}
}
impl SimulationElement for A320AuxiliaryPowerSupplies {
fn accept<T: SimulationElementVisitor>(&mut self, visitor: &mut T) {
self.fuel_pump_1_supply.accept(visitor);
self.fuel_pump_1_normal_contactor.accept(visitor);
self.fuel_pump_1_standby_contactor.accept(visitor);
self.apu_fuel_pump_supply.accept(visitor);
self.apu_fuel_pump_static_inverter_contactor.accept(visitor);
self.apu_fuel_pump_ess_sched_contactor.accept(visitor);

visitor.visit(self);
}
}
3 changes: 3 additions & 0 deletions fbw-a32nx/src/wasm/systems/a320_systems/src/electrical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ impl A320Electrical {
spd_cond,
);

self.alternating_current
.update_auxiliary(electricity, emergency_overhead);

self.main_galley
.update(context, electricity, &self.alternating_current, overhead);
self.secondary_galley
Expand Down
66 changes: 55 additions & 11 deletions fbw-a32nx/src/wasm/systems/a320_systems/src/fuel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

use nalgebra::Vector3;
use systems::{
fuel::{FuelCG, FuelInfo, FuelPayload, FuelSystem, FuelTank},
fuel::{FuelCG, FuelInfo, FuelPayload, FuelPump, FuelPumpProperties, FuelSystem},
shared::ElectricalBusType,
simulation::{InitContext, SimulationElement, SimulationElementVisitor},
};
use uom::si::f64::*;
Expand Down Expand Up @@ -45,7 +46,7 @@ impl From<usize> for A320FuelTankType {
}

pub struct A320Fuel {
fuel_system: FuelSystem<5>,
fuel_system: FuelSystem<5, 5>,
}
impl A320Fuel {
pub const A320_FUEL: [FuelInfo<'static>; 5] = [
Expand Down Expand Up @@ -76,17 +77,60 @@ impl A320Fuel {
},
];

// TODO: connect MSFS fuel pumps to power logic
const FUEL_PUMPS: [(usize, FuelPumpProperties); 5] = [
// Left main tank pump 1
(
2,
FuelPumpProperties {
// TODO: implement Gen 1 line
// ElectricalBusType::AlternatingCurrent(1) or Gen1
powered_by: ElectricalBusType::Virtual("FUEL_PUMP_1_SUPPLY"),
consumption_current_ampere: 8.,
},
),
// Left main tank pump 2
(
5,
FuelPumpProperties {
powered_by: ElectricalBusType::Virtual("FUEL_PUMP_2_SUPPLY"),
consumption_current_ampere: 8.,
},
),
// Right main tank pump 1
(
3,
FuelPumpProperties {
// TODO: implement Gen 1 line
// ElectricalBusType::AlternatingCurrent(1) or Gen1
powered_by: ElectricalBusType::Virtual("FUEL_PUMP_1_SUPPLY"),
consumption_current_ampere: 8.,
},
),
// Right main tank pump 2
(
6,
FuelPumpProperties {
powered_by: ElectricalBusType::Virtual("FUEL_PUMP_2_SUPPLY"),
consumption_current_ampere: 8.,
},
),
// APU fuel pump
(
7,
FuelPumpProperties {
powered_by: ElectricalBusType::Virtual("FUEL_PUMP_APU_SUPPLY"),
consumption_current_ampere: 1.,
},
),
];

pub fn new(context: &mut InitContext) -> Self {
let fuel_tanks = Self::A320_FUEL.map(|f| {
FuelTank::new(
context,
f.fuel_tank_id,
Vector3::new(f.position.0, f.position.1, f.position.2),
false,
)
});
let fuel_tanks = Self::A320_FUEL.map(|f| f.into_fuel_tank(context, false));
let fuel_pumps =
Self::FUEL_PUMPS.map(|(id, properties)| FuelPump::new(context, id, properties));
A320Fuel {
fuel_system: FuelSystem::new(context, fuel_tanks),
fuel_system: FuelSystem::new(context, fuel_tanks, fuel_pumps),
}
}

Expand Down
1 change: 1 addition & 0 deletions fbw-a32nx/src/wasm/systems/a320_systems_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ async fn systems(mut gauge: msfs::Gauge) -> Result<(), Box<dyn Error>> {
.provides_aircraft_variable("FUEL TANK RIGHT AUX QUANTITY", "gallons", 0)?
.provides_aircraft_variable("FUEL TOTAL QUANTITY WEIGHT", "Pounds", 0)?
.provides_aircraft_variable("FUELSYSTEM LINE FUEL FLOW", "gallons per hour", 18)?
.provides_aircraft_variable_range("FUELSYSTEM PUMP ACTIVE", "Bool", 1..=7)?
.provides_aircraft_variable("GEAR ANIMATION POSITION", "Percent", 0)?
.provides_aircraft_variable("GEAR ANIMATION POSITION", "Percent", 1)?
.provides_aircraft_variable("GEAR ANIMATION POSITION", "Percent", 2)?
Expand Down
Loading
Loading