Skip to content

Commit 89e2e87

Browse files
SaschlBlueberryKing
authored andcommitted
fix: fadec init with empty atcID (#10349)
* fix: fadec init with empty atcID * fix missing init in a380 code * Set default atcId before sim's is available * Remove initialization state 0 * use ready state to await atcID * fix: readd check if fuel was loaded * request callsign before sim ready variable is set * use existing is ready var and only read/write after simulation is ready * only load fuel config from file when loading C&D * init a380 control data * always load defaults first and override later * update comments * remove unnecessary conditions --------- Co-authored-by: BBK <[email protected]> (cherry picked from commit c1c61f7)
1 parent cd6a08f commit 89e2e87

File tree

4 files changed

+161
-53
lines changed

4 files changed

+161
-53
lines changed

fbw-a32nx/src/wasm/fadec_a32nx/src/Fadec/EngineControlA32NX.cpp

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,13 @@ void EngineControl_A32NX::update() {
3434
profilerUpdate.start();
3535
#endif
3636

37-
// Get ATC ID from sim to be able to load and store fuel levels
38-
// If not yet available, request it from sim and return early
39-
// If available initialize the engine control data
40-
if (atcId.empty()) {
41-
simData.atcIdDataPtr->requestUpdateFromSim(msfsHandlerPtr->getTimeStamp(), msfsHandlerPtr->getTickCounter());
42-
if (simData.atcIdDataPtr->hasChanged()) {
43-
atcId = simData.atcIdDataPtr->data().atcID;
44-
LOG_INFO("Fadec::EngineControl_A32NX::update() - received ATC ID: " + atcId);
45-
initializeEngineControlData();
46-
}
47-
return;
37+
if (!fadecInitialized) {
38+
initializeEngineControlData();
39+
fadecInitialized = true;
4840
}
4941

42+
loadFuelConfigIfPossible();
43+
5044
const double deltaTime = std::max(0.002, msfsHandlerPtr->getSimulationDeltaTime());
5145
const double simTime = msfsHandlerPtr->getSimulationTime();
5246
const double mach = simData.simVarsDataPtr->data().airSpeedMach;
@@ -151,6 +145,40 @@ void EngineControl_A32NX::update() {
151145
// PRIVATE
152146
// =============================================================================
153147

148+
void EngineControl_A32NX::loadFuelConfigIfPossible() {
149+
#ifdef PROFILING
150+
profilerEnsureFadecIsInitialized.start();
151+
#endif
152+
const FLOAT64 simTime = msfsHandlerPtr->getSimulationTime();
153+
const UINT64 tickCounter = msfsHandlerPtr->getTickCounter();
154+
155+
if (!hasLoadedFuelConfig) {
156+
bool isSimulationReady = msfsHandlerPtr->getAircraftIsReadyVar();
157+
158+
simData.atcIdDataPtr->requestUpdateFromSim(msfsHandlerPtr->getTimeStamp(), tickCounter);
159+
160+
// we only receive the data one tick later as we request it via simconnect. But it should be enought to only perform the check after
161+
// isSimulationReady as this is set by the JS instruments after spawn
162+
if (isSimulationReady) {
163+
if (simData.atcIdDataPtr->data().atcID[0] != '\0') {
164+
atcId = simData.atcIdDataPtr->data().atcID;
165+
LOG_INFO("Fadec::EngineControl_A32NX::ensureFadecIsInitialized() - received ATC ID: " + atcId);
166+
initializeFuelTanks(simTime, tickCounter);
167+
} else {
168+
LOG_INFO("Fadec::EngineControl_A32NX::ensureFadecIsInitialized() - no ATC ID received, taking default: " + atcId);
169+
}
170+
// if ATC ID is empty, we take the default and still set hasLoadedFuelConfig to as it won't change anymore
171+
hasLoadedFuelConfig = true;
172+
}
173+
}
174+
175+
#ifdef PROFILING
176+
profilerEnsureFadecIsInitialized.stop();
177+
if (msfsHandlerPtr->getTickCounter() % 100 == 0) {
178+
profilerEnsureFadecIsInitialized.print();
179+
}
180+
#endif
181+
}
154182
/**
155183
* @brief Initializes the engine control data.
156184
*
@@ -209,7 +237,26 @@ void EngineControl_A32NX::initializeEngineControlData() {
209237
simData.engineTimer[L]->set(0);
210238
simData.engineTimer[R]->set(0);
211239

212-
// Initialize Fuel Tanks
240+
initializeFuelTanks(timeStamp, tickCounter);
241+
242+
// Initialize Pump State
243+
simData.fuelPumpState[L]->set(0);
244+
simData.fuelPumpState[R]->set(0);
245+
246+
// Initialize Thrust Limits
247+
simData.thrustLimitIdle->set(0);
248+
simData.thrustLimitClimb->set(0);
249+
simData.thrustLimitFlex->set(0);
250+
simData.thrustLimitMct->set(0);
251+
simData.thrustLimitToga->set(0);
252+
}
253+
254+
void EngineControl_A32NX::initializeFuelTanks(FLOAT64 timeStamp, UINT64 tickCounter) {
255+
LOG_INFO("Fadec::EngineControl_A32NX::initializeFuelTanks()");
256+
257+
#ifdef PROFILING
258+
ScopedTimer timer("Fadec::EngineControl_A32NX::initializeFuelTanks()");
259+
#endif
213260
const double fuelWeightGallon = simData.simVarsDataPtr->data().fuelWeightPerGallon; // weight of gallon of jet A in lbs
214261

215262
const double centerQuantity = simData.simVarsDataPtr->data().fuelTankQuantityCenter; // gal
@@ -218,6 +265,10 @@ void EngineControl_A32NX::initializeEngineControlData() {
218265
const double leftAuxQuantity = simData.simVarsDataPtr->data().fuelTankQuantityLeftAux; // gal
219266
const double rightAuxQuantity = simData.simVarsDataPtr->data().fuelTankQuantityRightAux; // gal
220267

268+
LOG_INFO("Fadec::EngineControl_A32NX::initializeFuelTanks() - Current Fuel Levels from Sim:\n Center: " + std::to_string(centerQuantity) +
269+
" gal\n Left: " + std::to_string(leftQuantity) + " gal\n Right: " + std::to_string(rightQuantity) +
270+
" gal\n Left Aux: " + std::to_string(leftAuxQuantity) + " gal\n Right Aux: " + std::to_string(rightAuxQuantity) + " gal");
271+
221272
// only loads saved fuel quantity on C/D spawn
222273
if (simData.startState->updateFromSim(timeStamp, tickCounter) == 2) {
223274
// Load fuel configuration from file
@@ -247,17 +298,6 @@ void EngineControl_A32NX::initializeEngineControlData() {
247298
simData.fuelAuxLeftPre->set(leftAuxQuantity * fuelWeightGallon); // in Pounds
248299
simData.fuelAuxRightPre->set(rightAuxQuantity * fuelWeightGallon); // in Pounds
249300
}
250-
251-
// Initialize Pump State
252-
simData.fuelPumpState[L]->set(0);
253-
simData.fuelPumpState[R]->set(0);
254-
255-
// Initialize Thrust Limits
256-
simData.thrustLimitIdle->set(0);
257-
simData.thrustLimitClimb->set(0);
258-
simData.thrustLimitFlex->set(0);
259-
simData.thrustLimitMct->set(0);
260-
simData.thrustLimitToga->set(0);
261301
}
262302

263303
double EngineControl_A32NX::generateEngineImbalance() {
@@ -973,8 +1013,11 @@ void EngineControl_A32NX::updateFuel(double deltaTimeSeconds) {
9731013

9741014
//--------------------------------------------
9751015
// Will save the current fuel quantities at a certain interval
976-
// if the aircraft is on the ground and the engines are off/shutting down
977-
if (msfsHandlerPtr->getSimOnGround() && (msfsHandlerPtr->getSimulationTime() - lastFuelSaveTime) > FUEL_SAVE_INTERVAL &&
1016+
// if the simulation is ready
1017+
// and the aircraft is on the ground and the engines are off/shutting down
1018+
1019+
if (msfsHandlerPtr->getAircraftIsReadyVar() && msfsHandlerPtr->getSimOnGround() &&
1020+
(msfsHandlerPtr->getSimulationTime() - lastFuelSaveTime) > FUEL_SAVE_INTERVAL &&
9781021
(engine1State == OFF || engine1State == SHUTTING || engine2State == OFF || engine2State == SHUTTING)) {
9791022
fuelConfiguration.setFuelLeft(simData.fuelLeftPre->get() / weightLbsPerGallon);
9801023
fuelConfiguration.setFuelRight(simData.fuelRightPre->get() / weightLbsPerGallon);

fbw-a32nx/src/wasm/fadec_a32nx/src/Fadec/EngineControlA32NX.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ class EngineControl_A32NX {
3434
FadecSimData_A32NX simData{};
3535

3636
// ATC ID for the aircraft used to load and store the fuel levels
37-
std::string atcId{};
37+
std::string atcId = "A32NX";
38+
39+
// Whether we have already loaded the fuel configuration from the config file
40+
bool hasLoadedFuelConfig = false;
41+
42+
bool fadecInitialized = false;
3843

3944
// Fuel configuration for loading and storing fuel levels
4045
FuelConfiguration_A32NX fuelConfiguration{};
@@ -98,6 +103,8 @@ class EngineControl_A32NX {
98103
SimpleProfiler profilerUpdateFuel{"Fadec::EngineControl_A32NX::updateFuel()", 100};
99104
SimpleProfiler profilerUpdateThrustLimits{"Fadec::EngineControl_A32NX::updateThrustLimits()", 100};
100105
SimpleProfiler profilerUpdateOil{"Fadec::EngineControl_A32NX::updateOil()", 100};
106+
SimpleProfiler profilerUpdateOil{"Fadec::EngineControl_A32NX::updateOil()", 100};
107+
SimpleProfiler profilerEnsureFadecIsInitialized{"Fadec::EngineControl_A32NX::ensureFadecIsInitialized()", 100};
101108
#endif
102109

103110
// ===========================================================================
@@ -126,12 +133,22 @@ class EngineControl_A32NX {
126133
// ===========================================================================
127134

128135
private:
136+
/**
137+
* @brief Initializes the required data for the engine simulation if it has not been initialized
138+
*/
139+
void loadFuelConfigIfPossible();
140+
129141
/**
130142
* @brief Initialize the FADEC and Fuel model
131-
* This is done after we have retrieved the ATC ID so we can load the fuel levels
132143
*/
133144
void initializeEngineControlData();
134145

146+
/**
147+
* @brief Initializes the fuel tanks based on a default config or the saved state of this livery
148+
* This method may be called multiple times during initialization
149+
*/
150+
void initializeFuelTanks(FLOAT64 timeStamp, UINT64 tickCounter);
151+
135152
/**
136153
* @brief Generates a random engine imbalance.
137154
*

fbw-a380x/src/wasm/fadec_a380x/src/Fadec/EngineControl_A380X.cpp

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,13 @@ void EngineControl_A380X::update() {
3131
profilerUpdate.start();
3232
#endif
3333

34-
// Get ATC ID from sim to be able to load and store fuel levels
35-
// If not yet available, request it from sim and return early
36-
// If available initialize the engine control data
37-
if (atcId.empty()) {
38-
simData.atcIdDataPtr->requestUpdateFromSim(msfsHandlerPtr->getTimeStamp(), msfsHandlerPtr->getTickCounter());
39-
if (simData.atcIdDataPtr->hasChanged()) {
40-
atcId = simData.atcIdDataPtr->data().atcID;
41-
LOG_INFO("Fadec::EngineControl_A380X::update() - received ATC ID: " + atcId);
42-
initializeEngineControlData();
43-
}
44-
return;
34+
if (!fadecInitialized) {
35+
initializeEngineControlData();
36+
fadecInitialized = true;
4537
}
4638

39+
loadFuelConfigIfPossible();
40+
4741
const double deltaTime = std::max(0.002, msfsHandlerPtr->getSimulationDeltaTime());
4842
const double mach = simData.simVarsDataPtr->data().airSpeedMach;
4943
const double pressureAltitude = simData.simVarsDataPtr->data().pressureAltitude;
@@ -130,6 +124,40 @@ void EngineControl_A380X::update() {
130124
// Private methods
131125
// =====================================================================================================================
132126

127+
void EngineControl_A380X::loadFuelConfigIfPossible() {
128+
#ifdef PROFILING
129+
profilerEnsureFadecIsInitialized.start();
130+
#endif
131+
const FLOAT64 simTime = msfsHandlerPtr->getSimulationTime();
132+
const UINT64 tickCounter = msfsHandlerPtr->getTickCounter();
133+
134+
if (!hasLoadedFuelConfig) {
135+
bool isSimulationReady = msfsHandlerPtr->getAircraftIsReadyVar();
136+
137+
simData.atcIdDataPtr->requestUpdateFromSim(msfsHandlerPtr->getTimeStamp(), tickCounter);
138+
139+
// we only receive the data one tick later as we request it via simconnect. But it should be enought to only perform the check after
140+
// isSimulationReady as this is set by the JS instruments after spawn
141+
if (isSimulationReady) {
142+
if (simData.atcIdDataPtr->data().atcID[0] != '\0') {
143+
atcId = simData.atcIdDataPtr->data().atcID;
144+
LOG_INFO("Fadec::EngineControl_A380X::ensureFadecIsInitialized() - received ATC ID: " + atcId);
145+
initializeFuelTanks(simTime, tickCounter);
146+
} else {
147+
LOG_INFO("Fadec::EngineControl_A380X::ensureFadecIsInitialized() - no ATC ID received, taking default: " + atcId);
148+
}
149+
// if ATC ID is empty, we take the default and still set hasLoadedFuelConfig to as it won't change anymore
150+
hasLoadedFuelConfig = true;
151+
}
152+
}
153+
#ifdef PROFILING
154+
profilerEnsureFadecIsInitialized.stop();
155+
if (msfsHandlerPtr->getTickCounter() % 100 == 0) {
156+
profilerEnsureFadecIsInitialized.print();
157+
}
158+
#endif
159+
}
160+
133161
void EngineControl_A380X::initializeEngineControlData() {
134162
LOG_INFO("Fadec::EngineControl_A380X::initializeEngineControlData()");
135163

@@ -193,6 +221,23 @@ void EngineControl_A380X::initializeEngineControlData() {
193221
simData.engineTimer[E3]->set(0);
194222
simData.engineTimer[E4]->set(0);
195223

224+
initializeFuelTanks(timeStamp, tickCounter);
225+
226+
// Setting initial Fuel Flow
227+
simData.fuelPumpState[E1]->set(0);
228+
simData.fuelPumpState[E2]->set(0);
229+
simData.fuelPumpState[E3]->set(0);
230+
simData.fuelPumpState[E4]->set(0);
231+
232+
// Setting initial Thrust Limits
233+
simData.thrustLimitIdle->set(0);
234+
simData.thrustLimitClimb->set(0);
235+
simData.thrustLimitFlex->set(0);
236+
simData.thrustLimitMct->set(0);
237+
simData.thrustLimitToga->set(0);
238+
}
239+
240+
void EngineControl_A380X::initializeFuelTanks(FLOAT64 timeStamp, UINT64 tickCounter) {
196241
// Setting initial Fuel Levels
197242
const double weightLbsPerGallon = simData.simVarsDataPtr->data().fuelWeightLbsPerGallon;
198243

@@ -242,19 +287,6 @@ void EngineControl_A380X::initializeEngineControlData() {
242287
simData.fuelRightOuterPre->set(simData.fuelTankDataPtr->data().fuelSystemRightOuter * weightLbsPerGallon);
243288
simData.fuelTrimPre->set(simData.fuelTankDataPtr->data().fuelSystemTrim * weightLbsPerGallon);
244289
}
245-
246-
// Setting initial Fuel Flow
247-
simData.fuelPumpState[E1]->set(0);
248-
simData.fuelPumpState[E2]->set(0);
249-
simData.fuelPumpState[E3]->set(0);
250-
simData.fuelPumpState[E4]->set(0);
251-
252-
// Setting initial Thrust Limits
253-
simData.thrustLimitIdle->set(0);
254-
simData.thrustLimitClimb->set(0);
255-
simData.thrustLimitFlex->set(0);
256-
simData.thrustLimitMct->set(0);
257-
simData.thrustLimitToga->set(0);
258290
}
259291

260292
void EngineControl_A380X::generateIdleParameters(double pressAltitude, double mach, double ambientTemperature, double ambientPressure) {
@@ -873,7 +905,7 @@ void EngineControl_A380X::updateFuel(double deltaTimeSeconds) {
873905
simData.fuelExtraTankDataPtr->writeDataToSim();
874906
}
875907

876-
// Will save the current fuel quantities if on the ground AND engines being shutdown
908+
// Will save the current fuel quantities if the aircraft is on the ground AND engines being shutdown
877909
// AND 5 seconds have passed since the last save
878910
if (msfsHandlerPtr->getSimOnGround() && (msfsHandlerPtr->getSimulationTime() - lastFuelSaveTime) > 5.0 &&
879911
(engine1State == OFF || engine1State == SHUTTING || // 1

fbw-a380x/src/wasm/fadec_a380x/src/Fadec/EngineControl_A380X.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ class EngineControl_A380X {
3434
FadecSimData_A380X simData{};
3535

3636
// ATC ID for the aircraft used to load and store the fuel levels
37-
std::string atcId{};
37+
std::string atcId = "A380X";
38+
39+
// Whether we have already loaded the fuel configuration from the config file
40+
bool hasLoadedFuelConfig = false;
41+
42+
bool fadecInitialized = false;
3843

3944
// Fuel configuration for loading and storing fuel levels
4045
FuelConfiguration_A380X fuelConfiguration{};
@@ -127,12 +132,23 @@ class EngineControl_A380X {
127132
// ===========================================================================
128133

129134
private:
135+
/**
136+
* @brief Initializes the required data for the engine simulation if it has not been initialized
137+
*/
138+
void loadFuelConfigIfPossible();
139+
130140
/**
131141
* @brief Initialize the FADEC and Fuel model
132142
* This is done after we have retrieved the ATC ID so we can load the fuel levels
133143
*/
134144
void initializeEngineControlData();
135145

146+
/**
147+
* @brief Initializes the fuel tanks based on a default config or the saved state of this livery
148+
* This method may be called multiple times during initialization
149+
*/
150+
void initializeFuelTanks(FLOAT64 timeStamp, UINT64 tickCounter);
151+
136152
/**
137153
* @brief Generate Idle / Initial Engine Parameters (non-imbalanced)
138154
*

0 commit comments

Comments
 (0)