From c9cfe3cc63f8412b5a4655fed10b0265926fbd1f Mon Sep 17 00:00:00 2001 From: Andreas Guther Date: Sat, 2 Nov 2024 11:47:12 +0100 Subject: [PATCH] feat(fdr): separate A32NX and A380X FDR files and converters; added additional data (#9125) * feat(fdr): separate A32NX and A380X FDR files and converters; added additional data * feat(fdr): removed engine data * feat(fdr): removed unnecessary data from simdata * feat(fdr): added fuel system data to simconnect interface * feat(fdr): added fuel system data to FDR * feat(fdr): improved passing of arguments to be more performant * feat(fdr): increased written flight computer count to have better analysis capabilities * feat(fbw_wasm): switched simconnect interface to return and take values by reference to improve performance * fix(fbw_wasm): added missing by references * feat(fdr): use local variables for configuration to allow changing via EFB in the future * feat(efb/fdr): added option to enable/disable FDR in EFB * feat(fdr): added DFDR event information to base data --- fbw-a32nx/src/wasm/fbw_a320/build.sh | 2 +- .../src/wasm/fbw_a320/src/AdditionalData.h | 62 -- fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h | 61 -- .../wasm/fbw_a320/src/FlightDataRecorder.cpp | 140 ---- .../wasm/fbw_a320/src/FlightDataRecorder.h | 41 -- .../wasm/fbw_a320/src/FlyByWireInterface.cpp | 302 ++++----- .../wasm/fbw_a320/src/FlyByWireInterface.h | 51 +- .../fbw_a320/src/interface/SimConnectData.h | 17 - .../src/interface/SimConnectInterface.cpp | 87 +-- .../src/interface/SimConnectInterface.h | 81 +-- .../src/recording/FlightDataRecorder.cpp | 222 +++++++ .../src/recording/FlightDataRecorder.h | 61 ++ .../src/recording/RecordingDataTypes.h | 87 +++ fbw-a380x/src/wasm/fbw_a380/build.sh | 2 +- .../src/wasm/fbw_a380/src/AdditionalData.h | 62 -- fbw-a380x/src/wasm/fbw_a380/src/EngineData.h | 53 -- .../wasm/fbw_a380/src/FlightDataRecorder.cpp | 140 ---- .../wasm/fbw_a380/src/FlightDataRecorder.h | 41 -- .../wasm/fbw_a380/src/FlyByWireInterface.cpp | 288 ++++----- .../wasm/fbw_a380/src/FlyByWireInterface.h | 46 +- .../fbw_a380/src/interface/FuelSystemData.h | 304 +++++++++ .../fbw_a380/src/interface/SimConnectData.h | 22 +- .../src/interface/SimConnectInterface.cpp | 423 ++++++++++-- .../src/interface/SimConnectInterface.h | 85 +-- .../src/recording/FlightDataRecorder.cpp | 226 +++++++ .../src/recording/FlightDataRecorder.h | 63 ++ .../src/recording/RecordingDataTypes.h | 94 +++ .../src/EFB/Localization/data/en.json | 1 + .../src/EFB/Settings/Pages/SimOptionsPage.tsx | 12 + .../instruments/src/EFB/Settings/sync.ts | 5 + tools/fdr2csv/{ => a32nx}/Cargo.lock | 67 +- tools/fdr2csv/a32nx/Cargo.toml | 22 + tools/fdr2csv/{ => a32nx}/build.rs | 0 tools/fdr2csv/{ => a32nx}/src/headers.rs | 0 tools/fdr2csv/{ => a32nx}/src/main.rs | 79 ++- tools/fdr2csv/a32nx/wrapper.hpp | 7 + tools/fdr2csv/a380x/Cargo.lock | 610 ++++++++++++++++++ tools/fdr2csv/a380x/Cargo.toml | 22 + tools/fdr2csv/a380x/build.rs | 45 ++ tools/fdr2csv/a380x/src/headers.rs | 10 + tools/fdr2csv/a380x/src/main.rs | 220 +++++++ tools/fdr2csv/a380x/wrapper.hpp | 8 + tools/fdr2csv/{ => common}/Cargo.toml | 12 +- .../{ => common}/src/csv_header_serializer.rs | 0 tools/fdr2csv/{ => common}/src/error.rs | 0 tools/fdr2csv/common/src/lib.rs | 2 + tools/fdr2csv/wrapper.hpp | 5 - 47 files changed, 2895 insertions(+), 1295 deletions(-) delete mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/AdditionalData.h delete mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h delete mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.cpp delete mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.h create mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp create mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.h create mode 100644 fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h delete mode 100644 fbw-a380x/src/wasm/fbw_a380/src/AdditionalData.h delete mode 100644 fbw-a380x/src/wasm/fbw_a380/src/EngineData.h delete mode 100644 fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.cpp delete mode 100644 fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.h create mode 100644 fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h create mode 100644 fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp create mode 100644 fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.h create mode 100644 fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h rename tools/fdr2csv/{ => a32nx}/Cargo.lock (91%) create mode 100644 tools/fdr2csv/a32nx/Cargo.toml rename tools/fdr2csv/{ => a32nx}/build.rs (100%) rename tools/fdr2csv/{ => a32nx}/src/headers.rs (100%) rename tools/fdr2csv/{ => a32nx}/src/main.rs (64%) create mode 100644 tools/fdr2csv/a32nx/wrapper.hpp create mode 100644 tools/fdr2csv/a380x/Cargo.lock create mode 100644 tools/fdr2csv/a380x/Cargo.toml create mode 100644 tools/fdr2csv/a380x/build.rs create mode 100644 tools/fdr2csv/a380x/src/headers.rs create mode 100644 tools/fdr2csv/a380x/src/main.rs create mode 100644 tools/fdr2csv/a380x/wrapper.hpp rename tools/fdr2csv/{ => common}/Cargo.toml (52%) rename tools/fdr2csv/{ => common}/src/csv_header_serializer.rs (100%) rename tools/fdr2csv/{ => common}/src/error.rs (100%) create mode 100644 tools/fdr2csv/common/src/lib.rs delete mode 100644 tools/fdr2csv/wrapper.hpp diff --git a/fbw-a32nx/src/wasm/fbw_a320/build.sh b/fbw-a32nx/src/wasm/fbw_a320/build.sh index 98696507f41..e1251e5aa01 100755 --- a/fbw-a32nx/src/wasm/fbw_a320/build.sh +++ b/fbw-a32nx/src/wasm/fbw_a320/build.sh @@ -145,7 +145,7 @@ clang++ \ -I "${FBW_COMMON_DIR}/src/zlib" \ "${FBW_COMMON_DIR}/src/zlib/zfstream.cc" \ "${DIR}/src/FlyByWireInterface.cpp" \ - "${DIR}/src/FlightDataRecorder.cpp" \ + "${DIR}/src/recording/FlightDataRecorder.cpp" \ "${DIR}/src/Arinc429.cpp" \ "${DIR}/src/Arinc429Utils.cpp" \ "${FBW_COMMON_DIR}/src/LocalVariable.cpp" \ diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/AdditionalData.h b/fbw-a32nx/src/wasm/fbw_a320/src/AdditionalData.h deleted file mode 100644 index 8edfaf2d19c..00000000000 --- a/fbw-a32nx/src/wasm/fbw_a320/src/AdditionalData.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -struct AdditionalData { - double master_warning_active; - double master_caution_active; - double park_brake_lever_pos; - double brake_pedal_left_pos; - double brake_pedal_right_pos; - double brake_left_sim_pos; - double brake_right_sim_pos; - double autobrake_armed_mode; - double autobrake_decel_light; - double spoilers_handle_pos; - double spoilers_armed; - double spoilers_handle_sim_pos; - double ground_spoilers_active; - double flaps_handle_percent; - double flaps_handle_index; - double flaps_handle_configuration_index; - double flaps_handle_sim_index; - double gear_handle_pos; - double hydraulic_green_pressure; - double hydraulic_blue_pressure; - double hydraulic_yellow_pressure; - double throttle_lever_1_pos; - double throttle_lever_2_pos; - double corrected_engine_N1_1_percent; - double corrected_engine_N1_2_percent; - unsigned long long assistanceTakeoffEnabled; - unsigned long long assistanceLandingEnabled; - unsigned long long aiAutoTrimActive; - unsigned long long aiControlsActive; - unsigned long long realisticTillerEnabled; - double tillerHandlePosition; - double noseWheelPosition; - double syncFoEfisEnabled; - double ls1Active; - double ls2Active; - double IsisLsActive; - double wingAntiIce; - // Fix missing data for FDR Analysis - // controller input data - double inputElevator; - double inputAileron; - double inputRudder; - // additional - double simulation_rate; - double wasPaused; - double slew_on; - // ambient data - double ice_structure_percent; - double ambient_pressure_mbar; - double ambient_wind_velocity_kn; - double ambient_wind_direction_deg; - double total_air_temperature_celsius; - // failures - double failuresActive; - // a.floor - double alpha_floor_condition; - // high aoa protection - double high_aoa_protection; -}; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h b/fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h deleted file mode 100644 index 640806f609b..00000000000 --- a/fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -struct EngineData { - unsigned long long simOnGround; - double generalEngineElapsedTime_1; - double generalEngineElapsedTime_2; - double standardAtmTemperature; - double turbineEngineCorrectedFuelFlow_1; - double turbineEngineCorrectedFuelFlow_2; - double fuelTankCapacityAuxLeft; - double fuelTankCapacityAuxRight; - double fuelTankCapacityMainLeft; - double fuelTankCapacityMainRight; - double fuelTankCapacityCenter; - double fuelTankQuantityAuxLeft; - double fuelTankQuantityAuxRight; - double fuelTankQuantityMainLeft; - double fuelTankQuantityMainRight; - double fuelTankQuantityCenter; - double fuelTankQuantityTotal; - double fuelWeightPerGallon; - double engineEngine1N2; - double engineEngine2N2; - double engineEngine1N1; - double engineEngine2N1; - double engineEngineIdleN1; - double engineEngineIdleN2; - double engineEngineIdleFF; - double engineEngineIdleEGT; - double engineEngine1EGT; - double engineEngine2EGT; - double engineEngine1Oil; - double engineEngine2Oil; - double engineEngine1OilTotal; - double engineEngine2OilTotal; - double engineEngineOilTemperature_1; - double engineEngineOilTemperature_2; - double engineEngineOilPressure_1; - double engineEngineOilPressure_2; - double engineEngine1VibN1; - double engineEngine2VibN1; - double engineEngine1VibN2; - double engineEngine2VibN2; - double engineEngine1FF; - double engineEngine2FF; - double engineEngine1PreFF; - double engineEngine2PreFF; - double engineEngineImbalance; - double engineFuelUsedLeft; - double engineFuelUsedRight; - double engineFuelLeftPre; - double engineFuelRightPre; - double engineFuelAuxLeftPre; - double engineFuelAuxRightPre; - double engineFuelCenterPre; - double engineEngineCycleTime; - double engineEngine1State; - double engineEngine2State; - double engineEngine1Timer; - double engineEngine2Timer; -}; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.cpp deleted file mode 100644 index 9dca8e10fb1..00000000000 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FlightDataRecorder.h" - -using namespace mINI; - -void FlightDataRecorder::initialize() { - // read configuration - INIStructure iniStructure; - INIFile iniFile(CONFIGURATION_FILEPATH); - if (!iniFile.read(iniStructure)) { - // file does not exist yet -> store the default configuration in a file - iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = "true"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = "15"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = "864000"; - iniFile.write(iniStructure, true); - } - - // read basic configuration - isEnabled = INITypeConversion::getBoolean(iniStructure, "FLIGHT_DATA_RECORDER", "ENABLED", true); - maximumFileCount = INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_FILES", 15); - maximumSampleCounter = INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE", 864000); - - // print configuration - std::cout << "WASM: Flight Data Recorder Configuration : Enabled = " << isEnabled << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfFiles = " << maximumFileCount << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfEntriesPerFile = " << maximumSampleCounter << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : Interface Version = " << INTERFACE_VERSION << std::endl; -} - -void FlightDataRecorder::update(AutopilotStateMachine* autopilotStateMachine, - AutopilotLawsModelClass* autopilotLaws, - Autothrust* autoThrust, - const EngineData& engineData, - const AdditionalData& additionalData) { - // check if enabled - if (!isEnabled) { - return; - } - - // do file management - manageFlightDataRecorderFiles(); - - // write data to file - fileStream->write((char*)(&autopilotStateMachine->getExternalOutputs().out), sizeof(autopilotStateMachine->getExternalOutputs().out)); - fileStream->write((char*)(&autopilotLaws->getExternalOutputs().out.output), sizeof(autopilotLaws->getExternalOutputs().out.output)); - fileStream->write((char*)(&autoThrust->getExternalOutputs().out), sizeof(autoThrust->getExternalOutputs().out)); - fileStream->write((char*)(&engineData), sizeof(engineData)); - fileStream->write((char*)(&additionalData), sizeof(additionalData)); -} - -void FlightDataRecorder::terminate() { - if (fileStream) { - fileStream->close(); - fileStream.reset(); - } -} - -void FlightDataRecorder::manageFlightDataRecorderFiles() { - // increase sample counter - sampleCounter++; - - // check if file is considered full - if (sampleCounter >= maximumSampleCounter) { - // close file and delete - if (fileStream) { - fileStream->close(); - fileStream.reset(); - } - // reset counter - sampleCounter = 0; - } - - if (!fileStream) { - // create new file - fileStream = std::make_shared(getFlightDataRecorderFilename().c_str()); - // write version to file - fileStream->write((char*)&INTERFACE_VERSION, sizeof(INTERFACE_VERSION)); - // clean up directory - cleanUpFlightDataRecorderFiles(); - } -} - -std::string FlightDataRecorder::getFlightDataRecorderFilename() { - // get time - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - - // get filepath based on time - std::stringstream result; - result << std::put_time(std::gmtime(&in_time_t), "\\work\\%Y-%m-%d-%H-%M-%S.fdr"); - - // return result - return result.str(); -} - -void FlightDataRecorder::cleanUpFlightDataRecorderFiles() { - // std::vector for directory entries - std::vector files; - - // extension - std::string extension = "fdr"; - - // structure representing an directory entry - struct dirent* directoryEntry; - - // open directory - DIR* directory = opendir("\\work"); - - // read directory until end - while ((directoryEntry = readdir(directory)) != NULL) { - // get filename as std::string - std::string filename = directoryEntry->d_name; - - // check if file has right extension - if (filename.find(extension, (filename.length() - extension.length())) != std::string::npos) { - files.push_back(std::move(filename)); - } - } - - // close directory - closedir(directory); - - // sort std::vector - std::sort(files.begin(), files.end(), std::greater<>()); - - // remove older files - while (files.size() > maximumFileCount) { - bool result = remove(("\\work\\" + files.back()).c_str()); - files.pop_back(); - } -} diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.h b/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.h deleted file mode 100644 index 836e2570a4e..00000000000 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlightDataRecorder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -#include "AdditionalData.h" -#include "AutopilotLaws.h" -#include "AutopilotStateMachine.h" -#include "Autothrust.h" -#include "EngineData.h" -#include "zfstream.h" - -class FlightDataRecorder { - public: - // IMPORTANT: this constant needs to increased with every interface change - const uint64_t INTERFACE_VERSION = 25; - - void initialize(); - - void update(AutopilotStateMachine* autopilotStateMachine, - AutopilotLawsModelClass* autopilotLaws, - Autothrust* autoThrust, - const EngineData& engineData, - const AdditionalData& additionalData); - - void terminate(); - - private: - const std::string CONFIGURATION_FILEPATH = "\\work\\FlightDataRecorder.ini"; - - bool isEnabled = false; - int sampleCounter = false; - int maximumSampleCounter = 0; - int maximumFileCount = 0; - std::shared_ptr fileStream; - - void manageFlightDataRecorderFiles(); - - std::string getFlightDataRecorderFilename(); - - void cleanUpFlightDataRecorderFiles(); -}; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp index 2a93f6653b7..9834fbe5d32 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp +++ b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.cpp @@ -148,11 +148,9 @@ bool FlyByWireInterface::update(double sampleTime) { result &= updateServoSolenoidStatus(); - // update additional recording data - result &= updateAdditionalData(calculatedSampleTime); - - // update engine data - result &= updateEngineData(calculatedSampleTime); + // update recording data + result &= updateBaseData(calculatedSampleTime); + result &= updateAircraftSpecificData(calculatedSampleTime); // update spoilers result &= updateSpoilers(calculatedSampleTime); @@ -163,7 +161,7 @@ bool FlyByWireInterface::update(double sampleTime) { // do not further process when active pause is on if (!simConnectInterface.isSimInActivePause()) { // update flight data recorder - flightDataRecorder.update(&autopilotStateMachine, &autopilotLaws, &autoThrust, engineData, additionalData); + flightDataRecorder.update(baseData, aircraftSpecificData, elacs, secs, facs, autopilotStateMachine, autopilotLaws, autoThrust); } // if default AP is on -> disconnect it @@ -292,6 +290,7 @@ void FlyByWireInterface::setupLocalVariables() { // register L variables for Autoland idDevelopmentAutoland_condition_Flare = std::make_unique("A32NX_DEV_FLARE_CONDITION"); + idDevelopmentAutoland_H_dot_fpm = std::make_unique("A32NX_DEV_FLARE_H_DOT"); idDevelopmentAutoland_H_dot_c_fpm = std::make_unique("A32NX_DEV_FLARE_H_DOT_C"); idDevelopmentAutoland_delta_Theta_H_dot_deg = std::make_unique("A32NX_DEV_FLARE_DELTA_THETA_H_DOT"); idDevelopmentAutoland_delta_Theta_bz_deg = std::make_unique("A32NX_DEV_FLARE_DELTA_THETA_BZ"); @@ -449,42 +448,6 @@ void FlyByWireInterface::setupLocalVariables() { idHydraulicBluePressure = std::make_unique("A32NX_HYD_BLUE_SYSTEM_1_SECTION_PRESSURE"); idHydraulicYellowPressure = std::make_unique("A32NX_HYD_YELLOW_SYSTEM_1_SECTION_PRESSURE"); - engineEngine1N2 = std::make_unique("A32NX_ENGINE_N2:1"); - engineEngine2N2 = std::make_unique("A32NX_ENGINE_N2:2"); - engineEngine1N1 = std::make_unique("A32NX_ENGINE_N1:1"); - engineEngine2N1 = std::make_unique("A32NX_ENGINE_N1:2"); - engineEngineIdleN1 = std::make_unique("A32NX_ENGINE_IDLE_N1"); - engineEngineIdleN2 = std::make_unique("A32NX_ENGINE_IDLE_N2"); - engineEngineIdleFF = std::make_unique("A32NX_ENGINE_IDLE_FF"); - engineEngineIdleEGT = std::make_unique("A32NX_ENGINE_IDLE_EGT"); - engineEngine1EGT = std::make_unique("A32NX_ENGINE_EGT:1"); - engineEngine2EGT = std::make_unique("A32NX_ENGINE_EGT:2"); - engineEngine1Oil = std::make_unique("A32NX_ENGINE_OIL_QTY:1"); - engineEngine2Oil = std::make_unique("A32NX_ENGINE_OIL_QTY:2"); - engineEngine1OilTotal = std::make_unique("A32NX_ENGINE_OIL_TOTAL:1"); - engineEngine2OilTotal = std::make_unique("A32NX_ENGINE_OIL_TOTAL:2"); - engineEngine1VibN1 = std::make_unique("A32NX_ENGINE_VIB_N1:1"); - engineEngine2VibN1 = std::make_unique("A32NX_ENGINE_VIB_N1:2"); - engineEngine1VibN2 = std::make_unique("A32NX_ENGINE_VIB_N2:1"); - engineEngine2VibN2 = std::make_unique("A32NX_ENGINE_VIB_N2:2"); - engineEngine1FF = std::make_unique("A32NX_ENGINE_FF:1"); - engineEngine2FF = std::make_unique("A32NX_ENGINE_FF:2"); - engineEngine1PreFF = std::make_unique("A32NX_ENGINE_PRE_FF:1"); - engineEngine2PreFF = std::make_unique("A32NX_ENGINE_PRE_FF:2"); - engineEngineImbalance = std::make_unique("A32NX_ENGINE_IMBALANCE"); - engineFuelUsedLeft = std::make_unique("A32NX_FUEL_USED:1"); - engineFuelUsedRight = std::make_unique("A32NX_FUEL_USED:2"); - engineFuelLeftPre = std::make_unique("A32NX_FUEL_LEFT_PRE"); - engineFuelRightPre = std::make_unique("A32NX_FUEL_RIGHT_PRE"); - engineFuelAuxLeftPre = std::make_unique("A32NX_FUEL_AUX_LEFT_PRE"); - engineFuelAuxRightPre = std::make_unique("A32NX_FUEL_AUX_RIGHT_PRE"); - engineFuelCenterPre = std::make_unique("A32NX_FUEL_CENTER_PRE"); - engineEngineCycleTime = std::make_unique("A32NX_ENGINE_CYCLE_TIME"); - engineEngine1State = std::make_unique("A32NX_ENGINE_STATE:1"); - engineEngine2State = std::make_unique("A32NX_ENGINE_STATE:2"); - engineEngine1Timer = std::make_unique("A32NX_ENGINE_TIMER:1"); - engineEngine2Timer = std::make_unique("A32NX_ENGINE_TIMER:2"); - flapsHandleIndexFlapConf = std::make_unique("A32NX_FLAPS_CONF_INDEX"); flapsPosition = std::make_unique("A32NX_LEFT_FLAPS_ANGLE"); @@ -1025,139 +988,121 @@ bool FlyByWireInterface::updateRadioReceiver(double sampleTime) { return true; } -bool FlyByWireInterface::updateAdditionalData(double sampleTime) { +bool FlyByWireInterface::updateBaseData(double sampleTime) { auto simData = simConnectInterface.getSimData(); - additionalData.master_warning_active = idMasterWarning->get(); - additionalData.master_caution_active = idMasterCaution->get(); - additionalData.park_brake_lever_pos = idParkBrakeLeverPos->get(); - additionalData.brake_pedal_left_pos = idBrakePedalLeftPos->get(); - additionalData.brake_pedal_right_pos = idBrakePedalRightPos->get(); - additionalData.brake_left_sim_pos = simData.brakeLeftPosition; - additionalData.brake_right_sim_pos = simData.brakeRightPosition; - additionalData.autobrake_armed_mode = idAutobrakeArmedMode->get(); - additionalData.autobrake_decel_light = idAutobrakeDecelLight->get(); - additionalData.spoilers_handle_pos = idSpoilersHandlePosition->get(); - additionalData.spoilers_armed = idSpoilersArmed->get(); - additionalData.spoilers_handle_sim_pos = simData.spoilers_handle_position; - additionalData.ground_spoilers_active = - idSecGroundSpoilersOut[0]->get() || idSecGroundSpoilersOut[1]->get() || idSecGroundSpoilersOut[2]->get(); - additionalData.flaps_handle_percent = idFlapsHandlePercent->get(); - additionalData.flaps_handle_index = idFlapsHandleIndex->get(); - additionalData.flaps_handle_configuration_index = flapsHandleIndexFlapConf->get(); - additionalData.flaps_handle_sim_index = simData.flapsHandleIndex; - additionalData.gear_handle_pos = simData.gearHandlePosition; - additionalData.hydraulic_green_pressure = idHydraulicGreenPressure->get(); - additionalData.hydraulic_blue_pressure = idHydraulicBluePressure->get(); - additionalData.hydraulic_yellow_pressure = idHydraulicYellowPressure->get(); - additionalData.throttle_lever_1_pos = simData.throttle_lever_1_pos; - additionalData.throttle_lever_2_pos = simData.throttle_lever_2_pos; - additionalData.corrected_engine_N1_1_percent = simData.corrected_engine_N1_1_percent; - additionalData.corrected_engine_N1_2_percent = simData.corrected_engine_N1_2_percent; - additionalData.assistanceTakeoffEnabled = simData.assistanceTakeoffEnabled; - additionalData.assistanceLandingEnabled = simData.assistanceLandingEnabled; - additionalData.aiAutoTrimActive = simData.aiAutoTrimActive; - additionalData.aiControlsActive = simData.aiControlsActive; - additionalData.realisticTillerEnabled = idRealisticTillerEnabled->get() == 1; - additionalData.tillerHandlePosition = idTillerHandlePosition->get(); - additionalData.noseWheelPosition = idNoseWheelPosition->get(); - additionalData.syncFoEfisEnabled = idSyncFoEfisEnabled->get(); - additionalData.ls1Active = idLs1Active->get(); - additionalData.ls2Active = idLs2Active->get(); - additionalData.IsisLsActive = idIsisLsActive->get(); - - additionalData.wingAntiIce = idWingAntiIce->get(); - - // Fix missing data for FDR Analysis auto simInputs = simConnectInterface.getSimInput(); - auto clientDataFlyByWire = simConnectInterface.getClientDataFlyByWire(); - auto clientDataAutothrust = simConnectInterface.getClientDataAutothrust(); - - // controller input data - additionalData.inputElevator = simInputs.inputs[0]; - additionalData.inputAileron = simInputs.inputs[1]; - additionalData.inputRudder = simInputs.inputs[2]; - // additional - additionalData.simulation_rate = simData.simulation_rate; - additionalData.wasPaused = wasPaused; - additionalData.slew_on = wasInSlew; - // ambient data - additionalData.ice_structure_percent = simData.ice_structure_percent; - additionalData.ambient_pressure_mbar = simData.ambient_pressure_mbar; - additionalData.ambient_wind_velocity_kn = simData.ambient_wind_velocity_kn; - additionalData.ambient_wind_direction_deg = simData.ambient_wind_direction_deg; - additionalData.total_air_temperature_celsius = simData.total_air_temperature_celsius; - // failure - additionalData.failuresActive = failuresConsumer.isAnyActive() ? 1.0 : 0.0; - // aoa - additionalData.alpha_floor_condition = - reinterpret_cast(&facsBusOutputs[0].discrete_word_5)->bitFromValueOr(29, false) || - reinterpret_cast(&facsBusOutputs[1].discrete_word_5)->bitFromValueOr(29, false); - // these are not correct yet - additionalData.high_aoa_protection = - reinterpret_cast(&elacsBusOutputs[0].discrete_status_word_2)->bitFromValueOr(23, false) || - reinterpret_cast(&elacsBusOutputs[1].discrete_status_word_2)->bitFromValueOr(23, false); + + // constants + double g = 9.81; + double conversion_rad_degree = 180 / M_PI; + + // calculate euler angles + double Theta_deg = -1 * simData.Theta_deg; + double Phi_deg = -1 * simData.Phi_deg; + double p_deg_s = -1 * simData.bodyRotationVelocity.z * conversion_rad_degree; + double q_deg_s = -1 * simData.bodyRotationVelocity.x * conversion_rad_degree; + double r_deg_s = simData.bodyRotationVelocity.y * conversion_rad_degree; + double qk_deg_s = q_deg_s * std::cos(Phi_deg) - r_deg_s * std::sin(Phi_deg); + double pk_deg_s = p_deg_s + (q_deg_s * std::sin(Phi_deg) + r_deg_s * std::cos(Phi_deg)) * std::tan(Theta_deg); + double rk_deg_s = (r_deg_s * std::cos(Phi_deg) + q_deg_s * std::sin(Phi_deg)) / std::cos(Theta_deg); + + // calculate accelerations + double az_m_s2 = simData.bodyRotationAcceleration.z / g + std::sin(Theta_deg); + double ax_m_s2 = simData.bodyRotationAcceleration.x / g - std::cos(Theta_deg) * std::sin(Phi_deg); + double ay_m_s2 = simData.bodyRotationAcceleration.y / g + std::cos(Theta_deg) * std::cos(Phi_deg); + + // fill data + baseData.simulation_time_s = simData.simulationTime; + baseData.simulation_delta_time_s = calculatedSampleTime; + baseData.simulation_rate = simData.simulation_rate; + baseData.simulation_slew_on = simData.slew_on; + baseData.simulation_was_pause_on = wasPaused; + baseData.aircraft_position_latitude_deg = simData.latitude_deg; + baseData.aircraft_position_longitude_deg = simData.longitude_deg; + baseData.aircraft_Theta_deg = Theta_deg; + baseData.aircraft_Phi_deg = Phi_deg; + baseData.aircraft_Psi_magnetic_deg = simData.Psi_magnetic_deg; + baseData.aircraft_Psi_magnetic_track_deg = simData.Psi_magnetic_track_deg; + baseData.aircraft_Psi_true_deg = simData.Psi_true_deg; + baseData.aircraft_qk_deg_s = qk_deg_s; + baseData.aircraft_pk_deg_s = pk_deg_s; + baseData.aircraft_rk_deg_s = rk_deg_s; + baseData.aircraft_V_indicated_kn = simData.V_ias_kn; + baseData.aircraft_V_true_kn = simData.V_tas_kn; + baseData.aircraft_V_ground_kn = simData.V_gnd_kn; + baseData.aircraft_Ma_mach = simData.V_mach; + baseData.aircraft_alpha_deg = simData.alpha_deg; + baseData.aircraft_beta_deg = simData.beta_deg; + baseData.aircraft_H_pressure_ft = simData.H_ft; + baseData.aircraft_H_indicated_ft = simData.H_ind_ft; + baseData.aircraft_H_radio_ft = simData.H_radio_ft; + baseData.aircraft_nz_g = simData.nz_g; + baseData.aircraft_ax_m_s2 = ax_m_s2; + baseData.aircraft_ay_m_s2 = ay_m_s2; + baseData.aircraft_az_m_s2 = az_m_s2; + baseData.aircraft_bx_m_s2 = simData.bx_m_s2; + baseData.aircraft_by_m_s2 = simData.by_m_s2; + baseData.aircraft_bz_m_s2 = simData.bz_m_s2; + baseData.aircraft_eta_pos = simData.eta_pos; + baseData.aircraft_eta_trim_deg = simData.eta_trim_deg; + baseData.aircraft_xi_pos = simData.xi_pos; + baseData.aircraft_zeta_pos = simData.zeta_pos; + baseData.aircraft_zeta_trim_pos = simData.zeta_trim_pos; + baseData.aircraft_total_air_temperature_deg_celsius = simData.ambient_temperature_celsius; + baseData.aircraft_ice_structure_percent = simData.ice_structure_percent; + baseData.aircraft_dfdr_event_button_pressed = idFdrEvent->get(); + baseData.atmosphere_ambient_pressure_mbar = simData.ambient_pressure_mbar; + baseData.atmosphere_ambient_wind_velocity_kn = simData.ambient_wind_velocity_kn; + baseData.atmosphere_ambient_wind_direction_deg = simData.ambient_wind_direction_deg; + baseData.simulation_input_sidestick_pitch_pos = simInputs.inputs[0]; + baseData.simulation_input_sidestick_roll_pos = simInputs.inputs[1]; + baseData.simulation_input_rudder_pos = simInputs.inputs[2]; + baseData.simulation_input_brake_pedal_left_pos = simData.brakeLeftPosition; + baseData.simulation_input_brake_pedal_right_pos = simData.brakeRightPosition; + baseData.simulation_input_flaps_handle_pos = idFlapsHandlePercent->get(); + baseData.simulation_input_flaps_handle_index = simData.flapsHandleIndex; + baseData.simulation_input_spoilers_handle_pos = idSpoilersHandlePosition->get(); + baseData.simulation_input_spoilers_are_armed = idSpoilersArmed->get(); + baseData.simulation_input_gear_handle_pos = simData.gearHandlePosition; + baseData.simulation_input_tiller_handle_pos = idTillerHandlePosition->get(); + baseData.simulation_input_parking_brake_switch_pos = idParkBrakeLeverPos->get(); + baseData.simulation_assistant_is_assisted_takeoff_enabled = simData.assistanceTakeoffEnabled; + baseData.simulation_assistant_is_assisted_landing_enabled = simData.assistanceLandingEnabled; + baseData.simulation_assistant_is_ai_automatic_trim_active = simData.aiAutoTrimActive; + baseData.simulation_assistant_is_ai_controls_active = simData.aiControlsActive; return true; } -bool FlyByWireInterface::updateEngineData(double sampleTime) { +bool FlyByWireInterface::updateAircraftSpecificData(double sampleTime) { auto simData = simConnectInterface.getSimData(); - engineData.generalEngineElapsedTime_1 = simData.generalEngineElapsedTime_1; - engineData.generalEngineElapsedTime_2 = simData.generalEngineElapsedTime_2; - engineData.standardAtmTemperature = simData.standardAtmTemperature; - engineData.turbineEngineCorrectedFuelFlow_1 = simData.turbineEngineCorrectedFuelFlow_1; - engineData.turbineEngineCorrectedFuelFlow_2 = simData.turbineEngineCorrectedFuelFlow_2; - engineData.fuelTankCapacityAuxLeft = simData.fuelTankCapacityAuxLeft; - engineData.fuelTankCapacityAuxRight = simData.fuelTankCapacityAuxRight; - engineData.fuelTankCapacityMainLeft = simData.fuelTankCapacityMainLeft; - engineData.fuelTankCapacityMainRight = simData.fuelTankCapacityMainRight; - engineData.fuelTankCapacityCenter = simData.fuelTankCapacityCenter; - engineData.fuelTankQuantityAuxLeft = simData.fuelTankQuantityAuxLeft; - engineData.fuelTankQuantityAuxRight = simData.fuelTankQuantityAuxRight; - engineData.fuelTankQuantityMainLeft = simData.fuelTankQuantityMainLeft; - engineData.fuelTankQuantityMainRight = simData.fuelTankQuantityMainRight; - engineData.fuelTankQuantityCenter = simData.fuelTankQuantityCenter; - engineData.fuelTankQuantityTotal = simData.fuelTankQuantityTotal; - engineData.fuelWeightPerGallon = simData.fuelWeightPerGallon; - engineData.engineEngine1N2 = engineEngine1N2->get(); - engineData.engineEngine2N2 = engineEngine2N2->get(); - engineData.engineEngine1N1 = engineEngine1N1->get(); - engineData.engineEngine2N1 = engineEngine2N1->get(); - engineData.engineEngineIdleN1 = engineEngineIdleN1->get(); - engineData.engineEngineIdleN2 = engineEngineIdleN2->get(); - engineData.engineEngineIdleFF = engineEngineIdleFF->get(); - engineData.engineEngineIdleEGT = engineEngineIdleEGT->get(); - engineData.engineEngine1EGT = engineEngine1EGT->get(); - engineData.engineEngine2EGT = engineEngine2EGT->get(); - engineData.engineEngine1Oil = engineEngine1Oil->get(); - engineData.engineEngine2Oil = engineEngine2Oil->get(); - engineData.engineEngine1OilTotal = engineEngine1OilTotal->get(); - engineData.engineEngine2OilTotal = engineEngine2OilTotal->get(); - engineData.engineEngine1VibN1 = engineEngine1VibN1->get(); - engineData.engineEngine2VibN1 = engineEngine2VibN1->get(); - engineData.engineEngine1VibN2 = engineEngine1VibN2->get(); - engineData.engineEngine2VibN2 = engineEngine2VibN2->get(); - engineData.engineEngineOilTemperature_1 = simData.engineEngineOilTemperature_1; - engineData.engineEngineOilTemperature_2 = simData.engineEngineOilTemperature_2; - engineData.engineEngineOilPressure_1 = simData.engineEngineOilPressure_1; - engineData.engineEngineOilPressure_2 = simData.engineEngineOilPressure_2; - engineData.engineEngine1FF = engineEngine1FF->get(); - engineData.engineEngine2FF = engineEngine2FF->get(); - engineData.engineEngine1PreFF = engineEngine1PreFF->get(); - engineData.engineEngine2PreFF = engineEngine2PreFF->get(); - engineData.engineEngineImbalance = engineEngineImbalance->get(); - engineData.engineFuelUsedLeft = engineFuelUsedLeft->get(); - engineData.engineFuelUsedRight = engineFuelUsedRight->get(); - engineData.engineFuelLeftPre = engineFuelLeftPre->get(); - engineData.engineFuelRightPre = engineFuelRightPre->get(); - engineData.engineFuelAuxLeftPre = engineFuelAuxLeftPre->get(); - engineData.engineFuelAuxRightPre = engineFuelAuxRightPre->get(); - engineData.engineFuelCenterPre = engineFuelCenterPre->get(); - engineData.engineEngineCycleTime = engineEngineCycleTime->get(); - engineData.engineEngine1State = engineEngine1State->get(); - engineData.engineEngine2State = engineEngine2State->get(); - engineData.engineEngine1Timer = engineEngine1Timer->get(); - engineData.engineEngine2Timer = engineEngine2Timer->get(); + + aircraftSpecificData.simulation_input_throttle_lever_1_pos = simData.throttle_lever_1_pos; + aircraftSpecificData.simulation_input_throttle_lever_2_pos = simData.throttle_lever_1_pos; + aircraftSpecificData.simulation_input_throttle_lever_1_angle = thrustLeverAngle_1->get(); + aircraftSpecificData.simulation_input_throttle_lever_2_angle = thrustLeverAngle_2->get(); + aircraftSpecificData.aircraft_engine_1_N1_percent = simData.corrected_engine_N1_1_percent; + aircraftSpecificData.aircraft_engine_2_N1_percent = simData.corrected_engine_N1_2_percent; + aircraftSpecificData.aircraft_hydraulic_system_green_pressure_psi = idHydraulicGreenPressure->get(); + aircraftSpecificData.aircraft_hydraulic_system_blue_pressure_psi = idHydraulicBluePressure->get(); + aircraftSpecificData.aircraft_hydraulic_system_yellow_pressure_psi = idHydraulicYellowPressure->get(); + aircraftSpecificData.aircraft_autobrake_system_armed_mode = idAutobrakeArmedMode->get(); + aircraftSpecificData.aircraft_autobrake_system_is_decel_light_on = idAutobrakeDecelLight->get(); + aircraftSpecificData.aircraft_gear_nosewheel_pos = idNoseWheelPosition->get(); + aircraftSpecificData.aircraft_gear_nosewheel_compression_percent = 2 * simData.gear_animation_pos_0 - 1; + aircraftSpecificData.aircraft_gear_main_left_compression_percent = 2 * simData.gear_animation_pos_1 - 1; + aircraftSpecificData.aircraft_gear_main_right_compression_percent = 2 * simData.gear_animation_pos_2 - 1; + aircraftSpecificData.aircraft_is_master_warning_active = idMasterWarning->get(); + aircraftSpecificData.aircraft_is_master_caution_active = idMasterCaution->get(); + aircraftSpecificData.aircraft_is_wing_anti_ice_active = idWingAntiIce->get(); + aircraftSpecificData.aircraft_is_alpha_floor_condition_active = + reinterpret_cast(&facsBusOutputs[0].discrete_word_5)->bitFromValueOr(29, false) || + reinterpret_cast(&facsBusOutputs[1].discrete_word_5)->bitFromValueOr(29, false); + aircraftSpecificData.aircraft_is_high_aoa_protection_active = + reinterpret_cast(&elacsBusOutputs[0].discrete_status_word_2)->bitFromValueOr(23, false) || + reinterpret_cast(&elacsBusOutputs[1].discrete_status_word_2)->bitFromValueOr(23, false); + aircraftSpecificData.aircraft_settings_is_realistic_tiller_enabled = idRealisticTillerEnabled->get() == 1; + aircraftSpecificData.aircraft_settings_any_failures_active = failuresConsumer.isAnyActive() ? 1.0 : 0.0; return true; } @@ -2361,8 +2306,9 @@ bool FlyByWireInterface::updateAutopilotLaws(double sampleTime) { idFlightDirectorYaw->set(autopilotLawsOutput.flight_director.Beta_c_deg); // update development variables ------------------------------------------------------------------------------------- - idDevelopmentAutoland_condition_Flare->set(autopilotLawsOutput.flare_law.condition_Flare); idAutopilot_H_dot_radio->set(autopilotLawsOutput.flare_law.H_dot_radio_fpm); + idDevelopmentAutoland_condition_Flare->set(autopilotLawsOutput.flare_law.condition_Flare); + idDevelopmentAutoland_H_dot_fpm->set(autopilotLawsOutput.flare_law.H_dot_radio_fpm); idDevelopmentAutoland_H_dot_c_fpm->set(autopilotLawsOutput.flare_law.H_dot_c_fpm); idDevelopmentAutoland_delta_Theta_H_dot_deg->set(autopilotLawsOutput.flare_law.delta_Theta_H_dot_deg); idDevelopmentAutoland_delta_Theta_bx_deg->set(autopilotLawsOutput.flare_law.delta_Theta_bx_deg); @@ -2519,7 +2465,7 @@ bool FlyByWireInterface::updateAutothrust(double sampleTime) { autoThrustInput.in.input.thrust_reduction_altitude_go_around = fmThrustReductionAltitudeGoAround->valueOr(0); autoThrustInput.in.input.flight_phase = idFmgcFlightPhase->get(); autoThrustInput.in.input.is_alt_soft_mode_active = autopilotStateMachineOutput.ALT_soft_mode_active; - autoThrustInput.in.input.is_anti_ice_wing_active = additionalData.wingAntiIce == 1; + autoThrustInput.in.input.is_anti_ice_wing_active = idWingAntiIce->get(); autoThrustInput.in.input.is_anti_ice_engine_1_active = simData.engineAntiIce_1 == 1; autoThrustInput.in.input.is_anti_ice_engine_2_active = simData.engineAntiIce_2 == 1; autoThrustInput.in.input.is_air_conditioning_1_active = idAirConditioningPack_1->get(); @@ -2630,7 +2576,7 @@ bool FlyByWireInterface::updateFoSide(double sampleTime) { auto simData = simConnectInterface.getSimData(); // FD Button - if (additionalData.syncFoEfisEnabled && simData.ap_fd_1_active != simData.ap_fd_2_active) { + if (idSyncFoEfisEnabled->get() && simData.ap_fd_1_active != simData.ap_fd_2_active) { if (last_fd1_active != simData.ap_fd_1_active) { simConnectInterface.sendEvent(SimConnectInterface::Events::TOGGLE_FLIGHT_DIRECTOR, 2); } @@ -2643,17 +2589,17 @@ bool FlyByWireInterface::updateFoSide(double sampleTime) { last_fd2_active = simData.ap_fd_2_active; // LS Button - if (additionalData.syncFoEfisEnabled && additionalData.ls1Active != additionalData.ls2Active) { - if (last_ls1_active != additionalData.ls1Active) { - idLs2Active->set(additionalData.ls1Active); + if (idSyncFoEfisEnabled->get() && idLs1Active->get() != idLs2Active->get()) { + if (last_ls1_active != idLs1Active->get()) { + idLs2Active->set(idLs1Active->get()); } - if (last_ls2_active != additionalData.ls2Active) { - idLs1Active->set(additionalData.ls2Active); + if (last_ls2_active != idLs2Active->get()) { + idLs1Active->set(idLs2Active->get()); } } - last_ls1_active = additionalData.ls1Active; - last_ls2_active = additionalData.ls2Active; + last_ls1_active = idLs1Active->get(); + last_ls2_active = idLs2Active->get(); // inHg/hPa switch // Currently synced already diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h index 0af482e4164..7ee735d4e3a 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h +++ b/fbw-a32nx/src/wasm/fbw_a320/src/FlyByWireInterface.h @@ -3,14 +3,11 @@ #include #include -#include "AdditionalData.h" #include "Arinc429.h" #include "AutopilotLaws.h" #include "AutopilotStateMachine.h" #include "Autothrust.h" #include "CalculatedRadioReceiver.h" -#include "EngineData.h" -#include "FlightDataRecorder.h" #include "InterpolatingLookupTable.h" #include "LocalVariable.h" #include "RateLimiter.h" @@ -21,6 +18,8 @@ #include "fac/Fac.h" #include "failures/FailuresConsumer.h" #include "fcdc/Fcdc.h" +#include "recording/FlightDataRecorder.h" +#include "recording/RecordingDataTypes.h" #include "sec/Sec.h" #include "utils/ConfirmNode.h" @@ -170,6 +169,7 @@ class FlyByWireInterface { bool developmentLocalVariablesEnabled = false; bool useCalculatedLocalizerAndGlideSlope = false; std::unique_ptr idDevelopmentAutoland_condition_Flare; + std::unique_ptr idDevelopmentAutoland_H_dot_fpm; std::unique_ptr idDevelopmentAutoland_H_dot_c_fpm; std::unique_ptr idDevelopmentAutoland_delta_Theta_H_dot_deg; std::unique_ptr idDevelopmentAutoland_delta_Theta_bz_deg; @@ -305,7 +305,9 @@ class FlyByWireInterface { std::vector> throttleAxis; - AdditionalData additionalData = {}; + BaseData baseData = {}; + AircraftSpecificData aircraftSpecificData = {}; + std::unique_ptr idParkBrakeLeverPos; std::unique_ptr idBrakePedalLeftPos; std::unique_ptr idBrakePedalRightPos; @@ -317,43 +319,6 @@ class FlyByWireInterface { std::unique_ptr idMasterWarning; std::unique_ptr idMasterCaution; - EngineData engineData = {}; - std::unique_ptr engineEngine1N2; - std::unique_ptr engineEngine2N2; - std::unique_ptr engineEngine1N1; - std::unique_ptr engineEngine2N1; - std::unique_ptr engineEngineIdleN1; - std::unique_ptr engineEngineIdleN2; - std::unique_ptr engineEngineIdleFF; - std::unique_ptr engineEngineIdleEGT; - std::unique_ptr engineEngine1EGT; - std::unique_ptr engineEngine2EGT; - std::unique_ptr engineEngine1Oil; - std::unique_ptr engineEngine2Oil; - std::unique_ptr engineEngine1OilTotal; - std::unique_ptr engineEngine2OilTotal; - std::unique_ptr engineEngine1VibN1; - std::unique_ptr engineEngine2VibN1; - std::unique_ptr engineEngine1VibN2; - std::unique_ptr engineEngine2VibN2; - std::unique_ptr engineEngine1FF; - std::unique_ptr engineEngine2FF; - std::unique_ptr engineEngine1PreFF; - std::unique_ptr engineEngine2PreFF; - std::unique_ptr engineEngineImbalance; - std::unique_ptr engineFuelUsedLeft; - std::unique_ptr engineFuelUsedRight; - std::unique_ptr engineFuelLeftPre; - std::unique_ptr engineFuelRightPre; - std::unique_ptr engineFuelAuxLeftPre; - std::unique_ptr engineFuelAuxRightPre; - std::unique_ptr engineFuelCenterPre; - std::unique_ptr engineEngineCycleTime; - std::unique_ptr engineEngine1State; - std::unique_ptr engineEngine2State; - std::unique_ptr engineEngine1Timer; - std::unique_ptr engineEngine2Timer; - std::unique_ptr idFlapsHandleIndex; std::unique_ptr idFlapsHandlePercent; @@ -590,8 +555,8 @@ class FlyByWireInterface { bool updateRadioReceiver(double sampleTime); - bool updateEngineData(double sampleTime); - bool updateAdditionalData(double sampleTime); + bool updateBaseData(double sampleTime); + bool updateAircraftSpecificData(double sampleTime); bool updateAutopilotStateMachine(double sampleTime); bool updateAutopilotLaws(double sampleTime); diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectData.h b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectData.h index 91db896831d..4699074c059 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectData.h +++ b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectData.h @@ -99,23 +99,6 @@ struct SimData { unsigned long long engineAntiIce_1; unsigned long long engineAntiIce_2; unsigned long long simOnGround; - double generalEngineElapsedTime_1; - double generalEngineElapsedTime_2; - double standardAtmTemperature; - double turbineEngineCorrectedFuelFlow_1; - double turbineEngineCorrectedFuelFlow_2; - double fuelTankCapacityAuxLeft; - double fuelTankCapacityAuxRight; - double fuelTankCapacityMainLeft; - double fuelTankCapacityMainRight; - double fuelTankCapacityCenter; - double fuelTankQuantityAuxLeft; - double fuelTankQuantityAuxRight; - double fuelTankQuantityMainLeft; - double fuelTankQuantityMainRight; - double fuelTankQuantityCenter; - double fuelTankQuantityTotal; - double fuelWeightPerGallon; double kohlsmanSetting_0; double kohlsmanSetting_1; unsigned long long kohlsmanSettingStd_3; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.cpp index f56942152be..fce040f53dc 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.cpp +++ b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.cpp @@ -231,23 +231,6 @@ bool SimConnectInterface::prepareSimDataSimConnectDataDefinitions() { result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "ENG ANTI ICE:1", "BOOL"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "ENG ANTI ICE:2", "BOOL"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "SIM ON GROUND", "BOOL"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG ELAPSED TIME:1", "SECONDS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG ELAPSED TIME:2", "SECONDS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "STANDARD ATM TEMPERATURE", "CELSIUS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG CORRECTED FF:1", "POUNDS PER HOUR"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG CORRECTED FF:2", "POUNDS PER HOUR"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT AUX CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT AUX CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT MAIN CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT MAIN CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK CENTER CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT AUX QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT AUX QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT MAIN QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT MAIN QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK CENTER QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TOTAL QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL WEIGHT PER GALLON", "POUNDS"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "KOHLSMAN SETTING MB:0", "MBAR"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "KOHLSMAN SETTING MB:1", "MBAR"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "KOHLSMAN SETTING STD:3", "BOOL"); @@ -1199,23 +1182,23 @@ bool SimConnectInterface::setClientDataLocalVariablesAutothrust(ClientDataLocalV return sendClientData(ClientData::LOCAL_VARIABLES_AUTOTHRUST, sizeof(output), &output); } -SimData SimConnectInterface::getSimData() { +SimData& SimConnectInterface::getSimData() { return simData; } -SimInput SimConnectInterface::getSimInput() { +SimInput& SimConnectInterface::getSimInput() { return simInput; } -SimInputAutopilot SimConnectInterface::getSimInputAutopilot() { +SimInputAutopilot& SimConnectInterface::getSimInputAutopilot() { return simInputAutopilot; } -SimInputRudderTrim SimConnectInterface::getSimInputRudderTrim() { +SimInputRudderTrim& SimConnectInterface::getSimInputRudderTrim() { return simInputRudderTrim; } -SimInputThrottles SimConnectInterface::getSimInputThrottles() { +SimInputThrottles& SimConnectInterface::getSimInputThrottles() { return simInputThrottles; } @@ -1248,53 +1231,53 @@ void SimConnectInterface::resetSimInputThrottles() { simInputThrottles.ATHR_reset_disable = 0; } -bool SimConnectInterface::setClientDataAutopilotLaws(ClientDataAutopilotLaws output) { +bool SimConnectInterface::setClientDataAutopilotLaws(ClientDataAutopilotLaws& output) { // write data and return result return sendClientData(ClientData::AUTOPILOT_LAWS, sizeof(output), &output); } -ClientDataAutopilotLaws SimConnectInterface::getClientDataAutopilotLaws() { +ClientDataAutopilotLaws& SimConnectInterface::getClientDataAutopilotLaws() { return clientDataAutopilotLaws; } -bool SimConnectInterface::setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine output) { +bool SimConnectInterface::setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine& output) { // write data and return result return sendClientData(ClientData::AUTOPILOT_STATE_MACHINE, sizeof(output), &output); } -ClientDataAutopilotStateMachine SimConnectInterface::getClientDataAutopilotStateMachine() { +ClientDataAutopilotStateMachine& SimConnectInterface::getClientDataAutopilotStateMachine() { return clientDataAutopilotStateMachine; } -ClientDataAutothrust SimConnectInterface::getClientDataAutothrust() { +ClientDataAutothrust& SimConnectInterface::getClientDataAutothrust() { return clientDataAutothrust; } -ClientDataFlyByWire SimConnectInterface::getClientDataFlyByWire() { +ClientDataFlyByWire& SimConnectInterface::getClientDataFlyByWire() { return clientDataFlyByWire; } -bool SimConnectInterface::setClientDataElacDiscretes(base_elac_discrete_inputs output) { +bool SimConnectInterface::setClientDataElacDiscretes(base_elac_discrete_inputs& output) { return sendClientData(ClientData::ELAC_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataElacAnalog(base_elac_analog_inputs output) { +bool SimConnectInterface::setClientDataElacAnalog(base_elac_analog_inputs& output) { return sendClientData(ClientData::ELAC_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataElacBusInput(base_elac_out_bus output, int elacIndex) { +bool SimConnectInterface::setClientDataElacBusInput(base_elac_out_bus& output, int elacIndex) { return sendClientData(ClientData::ELAC_1_BUS_OUTPUT + elacIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecDiscretes(base_sec_discrete_inputs output) { +bool SimConnectInterface::setClientDataSecDiscretes(base_sec_discrete_inputs& output) { return sendClientData(ClientData::SEC_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecAnalog(base_sec_analog_inputs output) { +bool SimConnectInterface::setClientDataSecAnalog(base_sec_analog_inputs& output) { return sendClientData(ClientData::SEC_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecBus(base_sec_out_bus output, int secIndex) { +bool SimConnectInterface::setClientDataSecBus(base_sec_out_bus& output, int secIndex) { if (secIndex < 2) { return sendClientData(ClientData::SEC_1_BUS_OUTPUT + secIndex, sizeof(output), &output); } else { @@ -1302,75 +1285,75 @@ bool SimConnectInterface::setClientDataSecBus(base_sec_out_bus output, int secIn } } -bool SimConnectInterface::setClientDataFacDiscretes(base_fac_discrete_inputs output) { +bool SimConnectInterface::setClientDataFacDiscretes(base_fac_discrete_inputs& output) { return sendClientData(ClientData::FAC_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFacAnalog(base_fac_analog_inputs output) { +bool SimConnectInterface::setClientDataFacAnalog(base_fac_analog_inputs& output) { return sendClientData(ClientData::FAC_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFacBus(base_fac_bus output, int facIndex) { +bool SimConnectInterface::setClientDataFacBus(base_fac_bus& output, int facIndex) { return sendClientData(ClientData::FAC_1_BUS_OUTPUT + facIndex, sizeof(output), &output); } -base_elac_discrete_outputs SimConnectInterface::getClientDataElacDiscretesOutput() { +base_elac_discrete_outputs& SimConnectInterface::getClientDataElacDiscretesOutput() { return clientDataElacDiscreteOutputs; } -base_elac_analog_outputs SimConnectInterface::getClientDataElacAnalogsOutput() { +base_elac_analog_outputs& SimConnectInterface::getClientDataElacAnalogsOutput() { return clientDataElacAnalogOutputs; } -base_elac_out_bus SimConnectInterface::getClientDataElacBusOutput() { +base_elac_out_bus& SimConnectInterface::getClientDataElacBusOutput() { return clientDataElacBusOutputs; } -base_sec_discrete_outputs SimConnectInterface::getClientDataSecDiscretesOutput() { +base_sec_discrete_outputs& SimConnectInterface::getClientDataSecDiscretesOutput() { return clientDataSecDiscreteOutputs; } -base_sec_analog_outputs SimConnectInterface::getClientDataSecAnalogsOutput() { +base_sec_analog_outputs& SimConnectInterface::getClientDataSecAnalogsOutput() { return clientDataSecAnalogOutputs; } -base_sec_out_bus SimConnectInterface::getClientDataSecBusOutput() { +base_sec_out_bus& SimConnectInterface::getClientDataSecBusOutput() { return clientDataSecBusOutputs; } -base_fac_discrete_outputs SimConnectInterface::getClientDataFacDiscretesOutput() { +base_fac_discrete_outputs& SimConnectInterface::getClientDataFacDiscretesOutput() { return clientDataFacDiscreteOutputs; } -base_fac_analog_outputs SimConnectInterface::getClientDataFacAnalogsOutput() { +base_fac_analog_outputs& SimConnectInterface::getClientDataFacAnalogsOutput() { return clientDataFacAnalogOutputs; } -base_fac_bus SimConnectInterface::getClientDataFacBusOutput() { +base_fac_bus& SimConnectInterface::getClientDataFacBusOutput() { return clientDataFacBusOutputs; } -bool SimConnectInterface::setClientDataAdr(base_adr_bus output, int adrIndex) { +bool SimConnectInterface::setClientDataAdr(base_adr_bus& output, int adrIndex) { return sendClientData(ClientData::ADR_1_INPUTS + adrIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataIr(base_ir_bus output, int irIndex) { +bool SimConnectInterface::setClientDataIr(base_ir_bus& output, int irIndex) { return sendClientData(ClientData::IR_1_INPUTS + irIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataRa(base_ra_bus output, int raIndex) { +bool SimConnectInterface::setClientDataRa(base_ra_bus& output, int raIndex) { return sendClientData(ClientData::RA_1_BUS + raIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataLgciu(base_lgciu_bus output, int lgciuIndex) { +bool SimConnectInterface::setClientDataLgciu(base_lgciu_bus& output, int lgciuIndex) { return sendClientData(ClientData::LGCIU_1_BUS + lgciuIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSfcc(base_sfcc_bus output, int sfccIndex) { +bool SimConnectInterface::setClientDataSfcc(base_sfcc_bus& output, int sfccIndex) { return sendClientData(ClientData::SFCC_1_BUS + sfccIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFmgcB(base_fmgc_b_bus output, int fmgcIndex) { +bool SimConnectInterface::setClientDataFmgcB(base_fmgc_b_bus& output, int fmgcIndex) { return sendClientData(ClientData::FMGC_1_B_BUS + fmgcIndex, sizeof(output), &output); } diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.h b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.h index 914dcc27180..4d3c0c058cf 100644 --- a/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.h +++ b/fbw-a32nx/src/wasm/fbw_a320/src/interface/SimConnectInterface.h @@ -234,59 +234,59 @@ class SimConnectInterface { void resetSimInputThrottles(); - SimData getSimData(); + SimData& getSimData(); - SimInput getSimInput(); + SimInput& getSimInput(); - SimInputAutopilot getSimInputAutopilot(); + SimInputAutopilot& getSimInputAutopilot(); - SimInputRudderTrim getSimInputRudderTrim(); + SimInputRudderTrim& getSimInputRudderTrim(); - SimInputThrottles getSimInputThrottles(); + SimInputThrottles& getSimInputThrottles(); - bool setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine output); - ClientDataAutopilotStateMachine getClientDataAutopilotStateMachine(); + bool setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine& output); + ClientDataAutopilotStateMachine& getClientDataAutopilotStateMachine(); - bool setClientDataAutopilotLaws(ClientDataAutopilotLaws output); - ClientDataAutopilotLaws getClientDataAutopilotLaws(); + bool setClientDataAutopilotLaws(ClientDataAutopilotLaws& output); + ClientDataAutopilotLaws& getClientDataAutopilotLaws(); - ClientDataAutothrust getClientDataAutothrust(); + ClientDataAutothrust& getClientDataAutothrust(); - bool setClientDataFlyByWireInput(ClientDataFlyByWireInput output); + bool setClientDataFlyByWireInput(ClientDataFlyByWireInput& output); - bool setClientDataFlyByWire(ClientDataFlyByWire output); - ClientDataFlyByWire getClientDataFlyByWire(); + bool setClientDataFlyByWire(ClientDataFlyByWire& output); + ClientDataFlyByWire& getClientDataFlyByWire(); - bool setClientDataElacDiscretes(base_elac_discrete_inputs output); - bool setClientDataElacAnalog(base_elac_analog_inputs output); - bool setClientDataElacBusInput(base_elac_out_bus output, int elacIndex); + bool setClientDataElacDiscretes(base_elac_discrete_inputs& output); + bool setClientDataElacAnalog(base_elac_analog_inputs& output); + bool setClientDataElacBusInput(base_elac_out_bus& output, int elacIndex); - base_elac_discrete_outputs getClientDataElacDiscretesOutput(); - base_elac_analog_outputs getClientDataElacAnalogsOutput(); - base_elac_out_bus getClientDataElacBusOutput(); + base_elac_discrete_outputs& getClientDataElacDiscretesOutput(); + base_elac_analog_outputs& getClientDataElacAnalogsOutput(); + base_elac_out_bus& getClientDataElacBusOutput(); - bool setClientDataSecDiscretes(base_sec_discrete_inputs output); - bool setClientDataSecAnalog(base_sec_analog_inputs output); - bool setClientDataSecBus(base_sec_out_bus output, int secIndex); + bool setClientDataSecDiscretes(base_sec_discrete_inputs& output); + bool setClientDataSecAnalog(base_sec_analog_inputs& output); + bool setClientDataSecBus(base_sec_out_bus& output, int secIndex); - base_sec_discrete_outputs getClientDataSecDiscretesOutput(); - base_sec_analog_outputs getClientDataSecAnalogsOutput(); - base_sec_out_bus getClientDataSecBusOutput(); + base_sec_discrete_outputs& getClientDataSecDiscretesOutput(); + base_sec_analog_outputs& getClientDataSecAnalogsOutput(); + base_sec_out_bus& getClientDataSecBusOutput(); - bool setClientDataFacDiscretes(base_fac_discrete_inputs output); - bool setClientDataFacAnalog(base_fac_analog_inputs output); - bool setClientDataFacBus(base_fac_bus output, int facIndex); + bool setClientDataFacDiscretes(base_fac_discrete_inputs& output); + bool setClientDataFacAnalog(base_fac_analog_inputs& output); + bool setClientDataFacBus(base_fac_bus& output, int facIndex); - base_fac_discrete_outputs getClientDataFacDiscretesOutput(); - base_fac_analog_outputs getClientDataFacAnalogsOutput(); - base_fac_bus getClientDataFacBusOutput(); + base_fac_discrete_outputs& getClientDataFacDiscretesOutput(); + base_fac_analog_outputs& getClientDataFacAnalogsOutput(); + base_fac_bus& getClientDataFacBusOutput(); - bool setClientDataAdr(base_adr_bus output, int adrIndex); - bool setClientDataIr(base_ir_bus output, int irIndex); - bool setClientDataRa(base_ra_bus output, int raIndex); - bool setClientDataLgciu(base_lgciu_bus output, int lgciuIndex); - bool setClientDataSfcc(base_sfcc_bus output, int sfccIndex); - bool setClientDataFmgcB(base_fmgc_b_bus output, int fmgcIndex); + bool setClientDataAdr(base_adr_bus& output, int adrIndex); + bool setClientDataIr(base_ir_bus& output, int irIndex); + bool setClientDataRa(base_ra_bus& output, int raIndex); + bool setClientDataLgciu(base_lgciu_bus& output, int lgciuIndex); + bool setClientDataSfcc(base_sfcc_bus& output, int sfccIndex); + bool setClientDataFmgcB(base_fmgc_b_bus& output, int fmgcIndex); void setLoggingFlightControlsEnabled(bool enabled); bool getLoggingFlightControlsEnabled(); @@ -426,7 +426,8 @@ class SimConnectInterface { * in the event->dwData field of the SIMCONNECT_RECV_EVENT struct. * * @param event The pointer to the corresponding event data - * @see https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent.htm + * @see + * https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent.htm */ void simConnectProcessEvent(const SIMCONNECT_RECV_EVENT* event); @@ -443,7 +444,8 @@ class SimConnectInterface { * all other parameters. * * @param event The pointer to the corresponding event data - * @see https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent_EX1.htm + * @see + * https://docs.flightsimulator.com/flighting/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent_EX1.htm */ void simConnectProcessEvent_EX1(const SIMCONNECT_RECV_EVENT_EX1* event); @@ -471,7 +473,6 @@ class SimConnectInterface { static std::string getSimConnectExceptionString(SIMCONNECT_EXCEPTION exception); private: - /** * @brief Process a SimConnect event with one parameter. * @param eventId Specifies the ID of the client event. diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp new file mode 100644 index 00000000000..a1361d86f34 --- /dev/null +++ b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.cpp @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FlightDataRecorder.h" + +using namespace mINI; + +void FlightDataRecorder::initialize() { + // create local variables + idIsEnabled = std::make_unique("A32NX_FDR_ENABLED"); + idMaximumFileCount = std::make_unique("A32NX_FDR_MAXIMUM_NUMBER_OF_FILES"); + idMaximumSampleCounter = std::make_unique("A32NX_FDR_MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"); + + // load configuration + loadConfiguration(); + + // print configuration + std::cout << "WASM: Flight Data Recorder Configuration : Enabled = " << idIsEnabled->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfFiles = " << idMaximumFileCount->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfEntriesPerFile = " << idMaximumSampleCounter->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : Interface Version = " << INTERFACE_VERSION << std::endl; +} + +void FlightDataRecorder::update(const BaseData& baseData, + const AircraftSpecificData& aircraftSpecificData, + Elac (&elacs)[2], + Sec (&secs)[3], + Fac (&facs)[2], + AutopilotStateMachine& autopilotStateMachine, + AutopilotLawsModelClass& autopilotLaws, + Autothrust& autoThrust) { + // check if enabled + if (!idIsEnabled->get()) { + return; + } + + // do file management + manageFlightDataRecorderFiles(); + + // write base data + fileStream->write((char*)(&baseData), sizeof(baseData)); + + // write aircraft specific data + fileStream->write((char*)(&aircraftSpecificData), sizeof(aircraftSpecificData)); + + // write ELAC data + for (int i = 0; i < NUMBER_OF_ELAC_TO_WRITE; ++i) { + writeElac(elacs[i]); + } + + // write SEC data + for (int i = 0; i < NUMBER_OF_SEC_TO_WRITE; ++i) { + writeSec(secs[i]); + } + + // write FAC data + for (int i = 0; i < NUMBER_OF_FAC_TO_WRITE; ++i) { + writeFac(facs[i]); + } + + // write AP state machine data + auto autopilotStateMachineOut = autopilotStateMachine.getExternalOutputs().out; + fileStream->write((char*)(&autopilotStateMachineOut), sizeof(autopilotStateMachineOut)); + + // write AP laws data + auto autopilotLawsOut = autopilotLaws.getExternalOutputs().out; + fileStream->write((char*)(&autopilotLawsOut), sizeof(autopilotLawsOut)); + + // write ATHR data + auto autoThrustOut = autoThrust.getExternalOutputs().out; + fileStream->write((char*)(&autoThrustOut), sizeof(autoThrustOut)); +} + +void FlightDataRecorder::writeElac(Elac& elac) { + auto bus_outputs = elac.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = elac.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = elac.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::writeSec(Sec& sec) { + auto bus_outputs = sec.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = sec.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = sec.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::writeFac(Fac& fac) { + auto bus_outputs = fac.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = fac.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = fac.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::terminate() { + if (fileStream) { + fileStream->close(); + fileStream.reset(); + } + writeConfiguration(); +} + +void FlightDataRecorder::loadConfiguration() { + // read configuration + INIStructure iniStructure; + INIFile iniFile(CONFIGURATION_FILEPATH); + if (!iniFile.read(iniStructure)) { + // file does not exist yet -> store the default configuration in a file + iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = "true"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = "15"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = "864000"; + iniFile.write(iniStructure, true); + } + + // read basic configuration + idIsEnabled->set(INITypeConversion::getBoolean(iniStructure, "FLIGHT_DATA_RECORDER", "ENABLED", true)); + idMaximumFileCount->set(INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_FILES", 15)); + idMaximumSampleCounter->set( + INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE", 864000)); +} + +void FlightDataRecorder::writeConfiguration() { + // create ini file + INIFile iniFile(CONFIGURATION_FILEPATH); + + // create structure + INIStructure iniStructure; + iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = idIsEnabled->get() == 1 ? "true" : "false"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = idMaximumFileCount->get(); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = idMaximumSampleCounter->get(); + + // write file + iniFile.write(iniStructure, true); +} + +void FlightDataRecorder::manageFlightDataRecorderFiles() { + // increase sample counter + sampleCounter++; + + // check if file is considered full + if (sampleCounter >= idMaximumSampleCounter->get()) { + // close file and delete + if (fileStream) { + fileStream->close(); + fileStream.reset(); + } + // reset counter + sampleCounter = 0; + } + + if (!fileStream) { + // create new file + fileStream = std::make_shared(getFlightDataRecorderFilename().c_str()); + // write version to file + fileStream->write((char*)&INTERFACE_VERSION, sizeof(INTERFACE_VERSION)); + // clean up directory + cleanUpFlightDataRecorderFiles(); + } +} + +std::string FlightDataRecorder::getFlightDataRecorderFilename() { + // get time + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + // get filepath based on time + std::stringstream result; + result << std::put_time(std::gmtime(&in_time_t), "\\work\\%Y-%m-%d-%H-%M-%S.fdr"); + + // return result + return result.str(); +} + +void FlightDataRecorder::cleanUpFlightDataRecorderFiles() { + // std::vector for directory entries + std::vector files; + + // extension + std::string extension = "fdr"; + + // structure representing an directory entry + struct dirent* directoryEntry; + + // open directory + DIR* directory = opendir("\\work"); + + // read directory until end + while ((directoryEntry = readdir(directory)) != NULL) { + // get filename as std::string + std::string filename = directoryEntry->d_name; + + // check if file has right extension + if (filename.find(extension, (filename.length() - extension.length())) != std::string::npos) { + files.push_back(std::move(filename)); + } + } + + // close directory + closedir(directory); + + // sort std::vector + std::sort(files.begin(), files.end(), std::greater<>()); + + // remove older files + while (files.size() > idMaximumFileCount->get()) { + bool result = remove(("\\work\\" + files.back()).c_str()); + files.pop_back(); + } +} diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.h b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.h new file mode 100644 index 00000000000..59c56b92712 --- /dev/null +++ b/fbw-a32nx/src/wasm/fbw_a320/src/recording/FlightDataRecorder.h @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include "../elac/Elac.h" +#include "../fac/Fac.h" +#include "../model/AutopilotLaws.h" +#include "../model/AutopilotStateMachine.h" +#include "../model/Autothrust.h" +#include "../sec/Sec.h" +#include "LocalVariable.h" +#include "RecordingDataTypes.h" +#include "zfstream.h" + +class FlightDataRecorder { + public: + // IMPORTANT: this constant needs to increased with every interface change + const uint64_t INTERFACE_VERSION = 3200001; + + const uint32_t NUMBER_OF_ELAC_TO_WRITE = 2; + const uint32_t NUMBER_OF_SEC_TO_WRITE = 3; + const uint32_t NUMBER_OF_FAC_TO_WRITE = 2; + + void initialize(); + + void update(const BaseData& baseData, + const AircraftSpecificData& aircraftSpecificData, + Elac (&elacs)[2], + Sec (&secs)[3], + Fac (&facs)[2], + AutopilotStateMachine& autopilotStateMachine, + AutopilotLawsModelClass& autopilotLaws, + Autothrust& autoThrust); + + void terminate(); + + private: + const std::string CONFIGURATION_FILEPATH = "\\work\\FlightDataRecorder.ini"; + + std::unique_ptr idIsEnabled; + std::unique_ptr idMaximumSampleCounter; + std::unique_ptr idMaximumFileCount; + int sampleCounter = 0; + std::shared_ptr fileStream; + + void manageFlightDataRecorderFiles(); + + std::string getFlightDataRecorderFilename(); + + void cleanUpFlightDataRecorderFiles(); + + void loadConfiguration(); + + void writeConfiguration(); + + void writeElac(Elac& elac); + + void writeSec(Sec& sec); + + void writeFac(Fac& fac); +}; diff --git a/fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h b/fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h new file mode 100644 index 00000000000..418d590e1f3 --- /dev/null +++ b/fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h @@ -0,0 +1,87 @@ +#pragma once + +struct BaseData { + double simulation_time_s; + double simulation_delta_time_s; + double simulation_rate; + double simulation_slew_on; + double simulation_was_pause_on; + double aircraft_position_latitude_deg; + double aircraft_position_longitude_deg; + double aircraft_Theta_deg; + double aircraft_Phi_deg; + double aircraft_Psi_magnetic_deg; + double aircraft_Psi_magnetic_track_deg; + double aircraft_Psi_true_deg; + double aircraft_qk_deg_s; + double aircraft_pk_deg_s; + double aircraft_rk_deg_s; + double aircraft_V_indicated_kn; + double aircraft_V_true_kn; + double aircraft_V_ground_kn; + double aircraft_Ma_mach; + double aircraft_alpha_deg; + double aircraft_beta_deg; + double aircraft_H_pressure_ft; + double aircraft_H_indicated_ft; + double aircraft_H_radio_ft; + double aircraft_nz_g; + double aircraft_ax_m_s2; + double aircraft_ay_m_s2; + double aircraft_az_m_s2; + double aircraft_bx_m_s2; + double aircraft_by_m_s2; + double aircraft_bz_m_s2; + double aircraft_eta_pos; + double aircraft_eta_trim_deg; + double aircraft_xi_pos; + double aircraft_zeta_pos; + double aircraft_zeta_trim_pos; + double aircraft_total_air_temperature_deg_celsius; + double aircraft_ice_structure_percent; + double aircraft_dfdr_event_button_pressed; + double atmosphere_ambient_pressure_mbar; + double atmosphere_ambient_wind_velocity_kn; + double atmosphere_ambient_wind_direction_deg; + double simulation_input_sidestick_pitch_pos; + double simulation_input_sidestick_roll_pos; + double simulation_input_rudder_pos; + double simulation_input_brake_pedal_left_pos; + double simulation_input_brake_pedal_right_pos; + double simulation_input_flaps_handle_pos; + double simulation_input_flaps_handle_index; + double simulation_input_spoilers_handle_pos; + double simulation_input_spoilers_are_armed; + double simulation_input_gear_handle_pos; + double simulation_input_tiller_handle_pos; + double simulation_input_parking_brake_switch_pos; + unsigned long long simulation_assistant_is_assisted_takeoff_enabled; + unsigned long long simulation_assistant_is_assisted_landing_enabled; + unsigned long long simulation_assistant_is_ai_automatic_trim_active; + unsigned long long simulation_assistant_is_ai_controls_active; +}; + +struct AircraftSpecificData { + double simulation_input_throttle_lever_1_pos; + double simulation_input_throttle_lever_2_pos; + double simulation_input_throttle_lever_1_angle; + double simulation_input_throttle_lever_2_angle; + double aircraft_engine_1_N1_percent; + double aircraft_engine_2_N1_percent; + double aircraft_hydraulic_system_green_pressure_psi; + double aircraft_hydraulic_system_blue_pressure_psi; + double aircraft_hydraulic_system_yellow_pressure_psi; + double aircraft_autobrake_system_armed_mode; + double aircraft_autobrake_system_is_decel_light_on; + double aircraft_gear_nosewheel_pos; + double aircraft_gear_nosewheel_compression_percent; + double aircraft_gear_main_left_compression_percent; + double aircraft_gear_main_right_compression_percent; + double aircraft_is_master_warning_active; + double aircraft_is_master_caution_active; + double aircraft_is_wing_anti_ice_active; + double aircraft_is_alpha_floor_condition_active; + double aircraft_is_high_aoa_protection_active; + unsigned long long aircraft_settings_is_realistic_tiller_enabled; + double aircraft_settings_any_failures_active; +}; diff --git a/fbw-a380x/src/wasm/fbw_a380/build.sh b/fbw-a380x/src/wasm/fbw_a380/build.sh index bd4ad98a501..e8f2786146e 100755 --- a/fbw-a380x/src/wasm/fbw_a380/build.sh +++ b/fbw-a380x/src/wasm/fbw_a380/build.sh @@ -139,7 +139,7 @@ clang++ \ -I "${COMMON_DIR}/fbw_common/src/zlib" \ "${COMMON_DIR}/fbw_common/src/zlib/zfstream.cc" \ "${DIR}/src/FlyByWireInterface.cpp" \ - "${DIR}/src/FlightDataRecorder.cpp" \ + "${DIR}/src/recording/FlightDataRecorder.cpp" \ "${DIR}/src/Arinc429.cpp" \ "${DIR}/src/Arinc429Utils.cpp" \ "${COMMON_DIR}/fbw_common/src/LocalVariable.cpp" \ diff --git a/fbw-a380x/src/wasm/fbw_a380/src/AdditionalData.h b/fbw-a380x/src/wasm/fbw_a380/src/AdditionalData.h deleted file mode 100644 index 8edfaf2d19c..00000000000 --- a/fbw-a380x/src/wasm/fbw_a380/src/AdditionalData.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -struct AdditionalData { - double master_warning_active; - double master_caution_active; - double park_brake_lever_pos; - double brake_pedal_left_pos; - double brake_pedal_right_pos; - double brake_left_sim_pos; - double brake_right_sim_pos; - double autobrake_armed_mode; - double autobrake_decel_light; - double spoilers_handle_pos; - double spoilers_armed; - double spoilers_handle_sim_pos; - double ground_spoilers_active; - double flaps_handle_percent; - double flaps_handle_index; - double flaps_handle_configuration_index; - double flaps_handle_sim_index; - double gear_handle_pos; - double hydraulic_green_pressure; - double hydraulic_blue_pressure; - double hydraulic_yellow_pressure; - double throttle_lever_1_pos; - double throttle_lever_2_pos; - double corrected_engine_N1_1_percent; - double corrected_engine_N1_2_percent; - unsigned long long assistanceTakeoffEnabled; - unsigned long long assistanceLandingEnabled; - unsigned long long aiAutoTrimActive; - unsigned long long aiControlsActive; - unsigned long long realisticTillerEnabled; - double tillerHandlePosition; - double noseWheelPosition; - double syncFoEfisEnabled; - double ls1Active; - double ls2Active; - double IsisLsActive; - double wingAntiIce; - // Fix missing data for FDR Analysis - // controller input data - double inputElevator; - double inputAileron; - double inputRudder; - // additional - double simulation_rate; - double wasPaused; - double slew_on; - // ambient data - double ice_structure_percent; - double ambient_pressure_mbar; - double ambient_wind_velocity_kn; - double ambient_wind_direction_deg; - double total_air_temperature_celsius; - // failures - double failuresActive; - // a.floor - double alpha_floor_condition; - // high aoa protection - double high_aoa_protection; -}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/EngineData.h b/fbw-a380x/src/wasm/fbw_a380/src/EngineData.h deleted file mode 100644 index a8502834138..00000000000 --- a/fbw-a380x/src/wasm/fbw_a380/src/EngineData.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -struct EngineData { - unsigned long long simOnGround; - double generalEngineElapsedTime_1; - double generalEngineElapsedTime_2; - double standardAtmTemperature; - double turbineEngineCorrectedFuelFlow_1; - double turbineEngineCorrectedFuelFlow_2; - double fuelTankCapacityAuxLeft; - double fuelTankCapacityAuxRight; - double fuelTankCapacityMainLeft; - double fuelTankCapacityMainRight; - double fuelTankCapacityCenter; - double fuelTankQuantityAuxLeft; - double fuelTankQuantityAuxRight; - double fuelTankQuantityMainLeft; - double fuelTankQuantityMainRight; - double fuelTankQuantityCenter; - double fuelTankQuantityTotal; - double fuelWeightPerGallon; - double engineEngine1N2; - double engineEngine2N2; - double engineEngine1N1; - double engineEngine2N1; - double engineEngineIdleN1; - double engineEngineIdleN2; - double engineEngineIdleFF; - double engineEngineIdleEGT; - double engineEngine1EGT; - double engineEngine2EGT; - double engineEngine1Oil; - double engineEngine2Oil; - double engineEngine1TotalOil; - double engineEngine2TotalOil; - double engineEngine1FF; - double engineEngine2FF; - double engineEngine1PreFF; - double engineEngine2PreFF; - double engineEngineImbalance; - double engineFuelUsedLeft; - double engineFuelUsedRight; - double engineFuelLeftPre; - double engineFuelRightPre; - double engineFuelAuxLeftPre; - double engineFuelAuxRightPre; - double engineFuelCenterPre; - double engineEngineCycleTime; - double engineEngine1State; - double engineEngine2State; - double engineEngine1Timer; - double engineEngine2Timer; -}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.cpp b/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.cpp deleted file mode 100644 index 9dca8e10fb1..00000000000 --- a/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FlightDataRecorder.h" - -using namespace mINI; - -void FlightDataRecorder::initialize() { - // read configuration - INIStructure iniStructure; - INIFile iniFile(CONFIGURATION_FILEPATH); - if (!iniFile.read(iniStructure)) { - // file does not exist yet -> store the default configuration in a file - iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = "true"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = "15"; - iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = "864000"; - iniFile.write(iniStructure, true); - } - - // read basic configuration - isEnabled = INITypeConversion::getBoolean(iniStructure, "FLIGHT_DATA_RECORDER", "ENABLED", true); - maximumFileCount = INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_FILES", 15); - maximumSampleCounter = INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE", 864000); - - // print configuration - std::cout << "WASM: Flight Data Recorder Configuration : Enabled = " << isEnabled << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfFiles = " << maximumFileCount << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfEntriesPerFile = " << maximumSampleCounter << std::endl; - std::cout << "WASM: Flight Data Recorder Configuration : Interface Version = " << INTERFACE_VERSION << std::endl; -} - -void FlightDataRecorder::update(AutopilotStateMachine* autopilotStateMachine, - AutopilotLawsModelClass* autopilotLaws, - Autothrust* autoThrust, - const EngineData& engineData, - const AdditionalData& additionalData) { - // check if enabled - if (!isEnabled) { - return; - } - - // do file management - manageFlightDataRecorderFiles(); - - // write data to file - fileStream->write((char*)(&autopilotStateMachine->getExternalOutputs().out), sizeof(autopilotStateMachine->getExternalOutputs().out)); - fileStream->write((char*)(&autopilotLaws->getExternalOutputs().out.output), sizeof(autopilotLaws->getExternalOutputs().out.output)); - fileStream->write((char*)(&autoThrust->getExternalOutputs().out), sizeof(autoThrust->getExternalOutputs().out)); - fileStream->write((char*)(&engineData), sizeof(engineData)); - fileStream->write((char*)(&additionalData), sizeof(additionalData)); -} - -void FlightDataRecorder::terminate() { - if (fileStream) { - fileStream->close(); - fileStream.reset(); - } -} - -void FlightDataRecorder::manageFlightDataRecorderFiles() { - // increase sample counter - sampleCounter++; - - // check if file is considered full - if (sampleCounter >= maximumSampleCounter) { - // close file and delete - if (fileStream) { - fileStream->close(); - fileStream.reset(); - } - // reset counter - sampleCounter = 0; - } - - if (!fileStream) { - // create new file - fileStream = std::make_shared(getFlightDataRecorderFilename().c_str()); - // write version to file - fileStream->write((char*)&INTERFACE_VERSION, sizeof(INTERFACE_VERSION)); - // clean up directory - cleanUpFlightDataRecorderFiles(); - } -} - -std::string FlightDataRecorder::getFlightDataRecorderFilename() { - // get time - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - - // get filepath based on time - std::stringstream result; - result << std::put_time(std::gmtime(&in_time_t), "\\work\\%Y-%m-%d-%H-%M-%S.fdr"); - - // return result - return result.str(); -} - -void FlightDataRecorder::cleanUpFlightDataRecorderFiles() { - // std::vector for directory entries - std::vector files; - - // extension - std::string extension = "fdr"; - - // structure representing an directory entry - struct dirent* directoryEntry; - - // open directory - DIR* directory = opendir("\\work"); - - // read directory until end - while ((directoryEntry = readdir(directory)) != NULL) { - // get filename as std::string - std::string filename = directoryEntry->d_name; - - // check if file has right extension - if (filename.find(extension, (filename.length() - extension.length())) != std::string::npos) { - files.push_back(std::move(filename)); - } - } - - // close directory - closedir(directory); - - // sort std::vector - std::sort(files.begin(), files.end(), std::greater<>()); - - // remove older files - while (files.size() > maximumFileCount) { - bool result = remove(("\\work\\" + files.back()).c_str()); - files.pop_back(); - } -} diff --git a/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.h b/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.h deleted file mode 100644 index 6a118d9f168..00000000000 --- a/fbw-a380x/src/wasm/fbw_a380/src/FlightDataRecorder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -#include "AdditionalData.h" -#include "EngineData.h" -#include "model/AutopilotLaws.h" -#include "model/AutopilotStateMachine.h" -#include "model/Autothrust.h" -#include "zlib/zfstream.h" - -class FlightDataRecorder { - public: - // IMPORTANT: this constant needs to increased with every interface change - const uint64_t INTERFACE_VERSION = 24; - - void initialize(); - - void update(AutopilotStateMachine* autopilotStateMachine, - AutopilotLawsModelClass* autopilotLaws, - Autothrust* autoThrust, - const EngineData& engineData, - const AdditionalData& additionalData); - - void terminate(); - - private: - const std::string CONFIGURATION_FILEPATH = "\\work\\FlightDataRecorder.ini"; - - bool isEnabled = false; - int sampleCounter = false; - int maximumSampleCounter = 0; - int maximumFileCount = 0; - std::shared_ptr fileStream; - - void manageFlightDataRecorderFiles(); - - std::string getFlightDataRecorderFilename(); - - void cleanUpFlightDataRecorderFiles(); -}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.cpp b/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.cpp index 23b4c9842bc..69a9f7be6b8 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.cpp +++ b/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.cpp @@ -145,11 +145,9 @@ bool FlyByWireInterface::update(double sampleTime) { result &= updateServoSolenoidStatus(); - // update additional recording data - result &= updateAdditionalData(calculatedSampleTime); - - // update engine data - result &= updateEngineData(calculatedSampleTime); + // update recording data + result &= updateBaseData(calculatedSampleTime); + result &= updateAircraftSpecificData(calculatedSampleTime); // update spoilers result &= updateSpoilers(calculatedSampleTime); @@ -160,7 +158,8 @@ bool FlyByWireInterface::update(double sampleTime) { // do not further process when active pause is on if (!simConnectInterface.isSimInActivePause()) { // update flight data recorder - flightDataRecorder.update(&autopilotStateMachine, &autopilotLaws, &autoThrust, engineData, additionalData); + flightDataRecorder.update(baseData, aircraftSpecificData, prims, secs, facs, autopilotStateMachine, autopilotLaws, autoThrust, + simConnectInterface.getFuelSystemData()); } // if default AP is on -> disconnect it @@ -463,38 +462,6 @@ void FlyByWireInterface::setupLocalVariables() { idFlapsHandlePercent = std::make_unique("A32NX_FLAPS_HANDLE_PERCENT"); idFlapsHandleIndex = std::make_unique("A32NX_FLAPS_HANDLE_INDEX"); - engineEngine1N2 = std::make_unique("A32NX_ENGINE_N2:1"); - engineEngine2N2 = std::make_unique("A32NX_ENGINE_N2:2"); - engineEngine1N1 = std::make_unique("A32NX_ENGINE_N1:1"); - engineEngine2N1 = std::make_unique("A32NX_ENGINE_N1:2"); - engineEngineIdleN1 = std::make_unique("A32NX_ENGINE_IDLE_N1"); - engineEngineIdleN2 = std::make_unique("A32NX_ENGINE_IDLE_N2"); - engineEngineIdleFF = std::make_unique("A32NX_ENGINE_IDLE_FF"); - engineEngineIdleEGT = std::make_unique("A32NX_ENGINE_IDLE_EGT"); - engineEngine1EGT = std::make_unique("A32NX_ENGINE_EGT:1"); - engineEngine2EGT = std::make_unique("A32NX_ENGINE_EGT:2"); - engineEngine1Oil = std::make_unique("A32NX_ENGINE_OIL_QTY:1"); - engineEngine2Oil = std::make_unique("A32NX_ENGINE_OIL_QTY:2"); - engineEngine1TotalOil = std::make_unique("A32NX_ENGINE_OIL_TOTAL:1"); - engineEngine2TotalOil = std::make_unique("A32NX_ENGINE_OIL_TOTAL:2"); - engineEngine1FF = std::make_unique("A32NX_ENGINE_FF:1"); - engineEngine2FF = std::make_unique("A32NX_ENGINE_FF:2"); - engineEngine1PreFF = std::make_unique("A32NX_ENGINE_PRE_FF:1"); - engineEngine2PreFF = std::make_unique("A32NX_ENGINE_PRE_FF:2"); - engineEngineImbalance = std::make_unique("A32NX_ENGINE_IMBALANCE"); - engineFuelUsedLeft = std::make_unique("A32NX_FUEL_USED:1"); - engineFuelUsedRight = std::make_unique("A32NX_FUEL_USED:2"); - engineFuelLeftPre = std::make_unique("A32NX_FUEL_LEFT_PRE"); - engineFuelRightPre = std::make_unique("A32NX_FUEL_RIGHT_PRE"); - engineFuelAuxLeftPre = std::make_unique("A32NX_FUEL_AUX_LEFT_PRE"); - engineFuelAuxRightPre = std::make_unique("A32NX_FUEL_AUX_RIGHT_PRE"); - engineFuelCenterPre = std::make_unique("A32NX_FUEL_CENTER_PRE"); - engineEngineCycleTime = std::make_unique("A32NX_ENGINE_CYCLE_TIME"); - engineEngine1State = std::make_unique("A32NX_ENGINE_STATE:1"); - engineEngine2State = std::make_unique("A32NX_ENGINE_STATE:2"); - engineEngine1Timer = std::make_unique("A32NX_ENGINE_TIMER:1"); - engineEngine2Timer = std::make_unique("A32NX_ENGINE_TIMER:2"); - flapsHandleIndexFlapConf = std::make_unique("A32NX_FLAPS_CONF_INDEX"); flapsPosition = std::make_unique("A32NX_LEFT_FLAPS_ANGLE"); @@ -1077,130 +1044,125 @@ bool FlyByWireInterface::updateRadioReceiver(double sampleTime) { return true; } -bool FlyByWireInterface::updateAdditionalData(double sampleTime) { +bool FlyByWireInterface::updateBaseData(double sampleTime) { auto simData = simConnectInterface.getSimData(); - additionalData.master_warning_active = idMasterWarning->get(); - additionalData.master_caution_active = idMasterCaution->get(); - additionalData.park_brake_lever_pos = idParkBrakeLeverPos->get(); - additionalData.brake_pedal_left_pos = idBrakePedalLeftPos->get(); - additionalData.brake_pedal_right_pos = idBrakePedalRightPos->get(); - additionalData.brake_left_sim_pos = simData.brakeLeftPosition; - additionalData.brake_right_sim_pos = simData.brakeRightPosition; - additionalData.autobrake_armed_mode = idAutobrakeArmedMode->get(); - additionalData.autobrake_decel_light = idAutobrakeDecelLight->get(); - additionalData.spoilers_handle_pos = idSpoilersHandlePosition->get(); - additionalData.spoilers_armed = idSpoilersArmed->get(); - additionalData.spoilers_handle_sim_pos = simData.spoilers_handle_position; - additionalData.ground_spoilers_active = false; - additionalData.flaps_handle_percent = idFlapsHandlePercent->get(); - additionalData.flaps_handle_index = idFlapsHandleIndex->get(); - additionalData.flaps_handle_configuration_index = flapsHandleIndexFlapConf->get(); - additionalData.flaps_handle_sim_index = simData.flapsHandleIndex; - additionalData.gear_handle_pos = simData.gearHandlePosition; - additionalData.hydraulic_green_pressure = idHydGreenSystemPressure->get(); - additionalData.hydraulic_blue_pressure = 0; - additionalData.hydraulic_yellow_pressure = idHydGreenSystemPressure->get(); - additionalData.throttle_lever_1_pos = simData.throttle_lever_1_pos; - additionalData.throttle_lever_2_pos = simData.throttle_lever_2_pos; - additionalData.corrected_engine_N1_1_percent = simData.corrected_engine_N1_1_percent; - additionalData.corrected_engine_N1_2_percent = simData.corrected_engine_N1_2_percent; - additionalData.assistanceTakeoffEnabled = simData.assistanceTakeoffEnabled; - additionalData.assistanceLandingEnabled = simData.assistanceLandingEnabled; - additionalData.aiAutoTrimActive = simData.aiAutoTrimActive; - additionalData.aiControlsActive = simData.aiControlsActive; - additionalData.realisticTillerEnabled = idRealisticTillerEnabled->get() == 1; - additionalData.tillerHandlePosition = idTillerHandlePosition->get(); - additionalData.noseWheelPosition = idNoseWheelPosition->get(); - additionalData.syncFoEfisEnabled = idSyncFoEfisEnabled->get(); - additionalData.ls1Active = idLs1Active->get(); - additionalData.ls2Active = idLs2Active->get(); - additionalData.IsisLsActive = idIsisLsActive->get(); - - additionalData.wingAntiIce = idWingAntiIce->get(); - - // Fix missing data for FDR Analysis auto simInputs = simConnectInterface.getSimInput(); - auto clientDataFlyByWire = simConnectInterface.getClientDataFlyByWire(); - auto clientDataAutothrust = simConnectInterface.getClientDataAutothrust(); - - // controller input data - additionalData.inputElevator = simInputs.inputs[0]; - additionalData.inputAileron = simInputs.inputs[1]; - additionalData.inputRudder = simInputs.inputs[2]; - // additional - additionalData.simulation_rate = simData.simulation_rate; - additionalData.wasPaused = wasPaused; - additionalData.slew_on = wasInSlew; - // ambient data - additionalData.ice_structure_percent = simData.ice_structure_percent; - additionalData.ambient_pressure_mbar = simData.ambient_pressure_mbar; - additionalData.ambient_wind_velocity_kn = simData.ambient_wind_velocity_kn; - additionalData.ambient_wind_direction_deg = simData.ambient_wind_direction_deg; - additionalData.total_air_temperature_celsius = simData.total_air_temperature_celsius; - // failure - additionalData.failuresActive = failuresConsumer.isAnyActive() ? 1.0 : 0.0; - // aoa - additionalData.alpha_floor_condition = - reinterpret_cast(&facsBusOutputs[0].discrete_word_5)->bitFromValueOr(29, false) || - reinterpret_cast(&facsBusOutputs[1].discrete_word_5)->bitFromValueOr(29, false); - // these are not correct yet - // additionalData.high_aoa_protection = - // reinterpret_cast(&elacsBusOutputs[0].discrete_status_word_2)->bitFromValueOr(23, false) || - // reinterpret_cast(&elacsBusOutputs[1].discrete_status_word_2)->bitFromValueOr(23, false); + + // constants + double g = 9.81; + double conversion_rad_degree = 180 / M_PI; + + // calculate euler angles + double Theta_deg = -1 * simData.Theta_deg; + double Phi_deg = -1 * simData.Phi_deg; + double p_deg_s = -1 * simData.bodyRotationVelocity.z * conversion_rad_degree; + double q_deg_s = -1 * simData.bodyRotationVelocity.x * conversion_rad_degree; + double r_deg_s = simData.bodyRotationVelocity.y * conversion_rad_degree; + double qk_deg_s = q_deg_s * std::cos(Phi_deg) - r_deg_s * std::sin(Phi_deg); + double pk_deg_s = p_deg_s + (q_deg_s * std::sin(Phi_deg) + r_deg_s * std::cos(Phi_deg)) * std::tan(Theta_deg); + double rk_deg_s = (r_deg_s * std::cos(Phi_deg) + q_deg_s * std::sin(Phi_deg)) / std::cos(Theta_deg); + + // calculate accelerations + double az_m_s2 = simData.bodyRotationAcceleration.z / g + std::sin(Theta_deg); + double ax_m_s2 = simData.bodyRotationAcceleration.x / g - std::cos(Theta_deg) * std::sin(Phi_deg); + double ay_m_s2 = simData.bodyRotationAcceleration.y / g + std::cos(Theta_deg) * std::cos(Phi_deg); + + baseData.simulation_time_s = simData.simulationTime; + baseData.simulation_delta_time_s = calculatedSampleTime; + baseData.simulation_rate = simData.simulation_rate; + baseData.simulation_slew_on = simData.slew_on; + baseData.simulation_was_pause_on = wasPaused; + baseData.aircraft_position_latitude_deg = simData.latitude_deg; + baseData.aircraft_position_longitude_deg = simData.longitude_deg; + baseData.aircraft_Theta_deg = Theta_deg; + baseData.aircraft_Phi_deg = Phi_deg; + baseData.aircraft_Psi_magnetic_deg = simData.Psi_magnetic_deg; + baseData.aircraft_Psi_magnetic_track_deg = simData.Psi_magnetic_track_deg; + baseData.aircraft_Psi_true_deg = simData.Psi_true_deg; + baseData.aircraft_qk_deg_s = qk_deg_s; + baseData.aircraft_pk_deg_s = pk_deg_s; + baseData.aircraft_rk_deg_s = rk_deg_s; + baseData.aircraft_V_indicated_kn = simData.V_ias_kn; + baseData.aircraft_V_true_kn = simData.V_tas_kn; + baseData.aircraft_V_ground_kn = simData.V_gnd_kn; + baseData.aircraft_Ma_mach = simData.V_mach; + baseData.aircraft_alpha_deg = simData.alpha_deg; + baseData.aircraft_beta_deg = simData.beta_deg; + baseData.aircraft_H_pressure_ft = simData.H_ft; + baseData.aircraft_H_indicated_ft = simData.H_ind_ft; + baseData.aircraft_H_radio_ft = simData.H_radio_ft; + baseData.aircraft_nz_g = simData.nz_g; + baseData.aircraft_ax_m_s2 = ax_m_s2; + baseData.aircraft_ay_m_s2 = ay_m_s2; + baseData.aircraft_az_m_s2 = az_m_s2; + baseData.aircraft_bx_m_s2 = simData.bx_m_s2; + baseData.aircraft_by_m_s2 = simData.by_m_s2; + baseData.aircraft_bz_m_s2 = simData.bz_m_s2; + baseData.aircraft_eta_pos = simData.eta_pos; + baseData.aircraft_eta_trim_deg = simData.eta_trim_deg; + baseData.aircraft_xi_pos = simData.xi_pos; + baseData.aircraft_zeta_pos = simData.zeta_pos; + baseData.aircraft_zeta_trim_pos = simData.zeta_trim_pos; + baseData.aircraft_total_air_temperature_deg_celsius = simData.ambient_temperature_celsius; + baseData.aircraft_ice_structure_percent = simData.ice_structure_percent; + baseData.aircraft_dfdr_event_button_pressed = idFdrEvent->get(); + baseData.atmosphere_ambient_pressure_mbar = simData.ambient_pressure_mbar; + baseData.atmosphere_ambient_wind_velocity_kn = simData.ambient_wind_velocity_kn; + baseData.atmosphere_ambient_wind_direction_deg = simData.ambient_wind_direction_deg; + baseData.simulation_input_sidestick_pitch_pos = simInputs.inputs[0]; + baseData.simulation_input_sidestick_roll_pos = simInputs.inputs[1]; + baseData.simulation_input_rudder_pos = simInputs.inputs[2]; + baseData.simulation_input_brake_pedal_left_pos = simData.brakeLeftPosition; + baseData.simulation_input_brake_pedal_right_pos = simData.brakeRightPosition; + baseData.simulation_input_flaps_handle_pos = idFlapsHandlePercent->get(); + baseData.simulation_input_flaps_handle_index = simData.flapsHandleIndex; + baseData.simulation_input_spoilers_handle_pos = idSpoilersHandlePosition->get(); + baseData.simulation_input_spoilers_are_armed = idSpoilersArmed->get(); + baseData.simulation_input_gear_handle_pos = simData.gearHandlePosition; + baseData.simulation_input_tiller_handle_pos = idTillerHandlePosition->get(); + baseData.simulation_input_parking_brake_switch_pos = idParkBrakeLeverPos->get(); + baseData.simulation_assistant_is_assisted_takeoff_enabled = simData.assistanceTakeoffEnabled; + baseData.simulation_assistant_is_assisted_landing_enabled = simData.assistanceLandingEnabled; + baseData.simulation_assistant_is_ai_automatic_trim_active = simData.aiAutoTrimActive; + baseData.simulation_assistant_is_ai_controls_active = simData.aiControlsActive; return true; } -bool FlyByWireInterface::updateEngineData(double sampleTime) { +bool FlyByWireInterface::updateAircraftSpecificData(double sampleTime) { auto simData = simConnectInterface.getSimData(); - engineData.generalEngineElapsedTime_1 = simData.generalEngineElapsedTime_1; - engineData.generalEngineElapsedTime_2 = simData.generalEngineElapsedTime_2; - engineData.standardAtmTemperature = simData.standardAtmTemperature; - engineData.turbineEngineCorrectedFuelFlow_1 = simData.turbineEngineCorrectedFuelFlow_1; - engineData.turbineEngineCorrectedFuelFlow_2 = simData.turbineEngineCorrectedFuelFlow_2; - engineData.fuelTankCapacityAuxLeft = simData.fuelTankCapacityAuxLeft; - engineData.fuelTankCapacityAuxRight = simData.fuelTankCapacityAuxRight; - engineData.fuelTankCapacityMainLeft = simData.fuelTankCapacityMainLeft; - engineData.fuelTankCapacityMainRight = simData.fuelTankCapacityMainRight; - engineData.fuelTankCapacityCenter = simData.fuelTankCapacityCenter; - engineData.fuelTankQuantityAuxLeft = simData.fuelTankQuantityAuxLeft; - engineData.fuelTankQuantityAuxRight = simData.fuelTankQuantityAuxRight; - engineData.fuelTankQuantityMainLeft = simData.fuelTankQuantityMainLeft; - engineData.fuelTankQuantityMainRight = simData.fuelTankQuantityMainRight; - engineData.fuelTankQuantityCenter = simData.fuelTankQuantityCenter; - engineData.fuelTankQuantityTotal = simData.fuelTankQuantityTotal; - engineData.fuelWeightPerGallon = simData.fuelWeightPerGallon; - engineData.engineEngine1N2 = engineEngine1N2->get(); - engineData.engineEngine2N2 = engineEngine2N2->get(); - engineData.engineEngine1N1 = engineEngine1N1->get(); - engineData.engineEngine2N1 = engineEngine2N1->get(); - engineData.engineEngineIdleN1 = engineEngineIdleN1->get(); - engineData.engineEngineIdleN2 = engineEngineIdleN2->get(); - engineData.engineEngineIdleFF = engineEngineIdleFF->get(); - engineData.engineEngineIdleEGT = engineEngineIdleEGT->get(); - engineData.engineEngine1EGT = engineEngine1EGT->get(); - engineData.engineEngine2EGT = engineEngine2EGT->get(); - engineData.engineEngine1Oil = engineEngine1Oil->get(); - engineData.engineEngine2Oil = engineEngine2Oil->get(); - engineData.engineEngine1TotalOil = engineEngine1TotalOil->get(); - engineData.engineEngine2TotalOil = engineEngine2TotalOil->get(); - engineData.engineEngine1FF = engineEngine1FF->get(); - engineData.engineEngine2FF = engineEngine2FF->get(); - engineData.engineEngine1PreFF = engineEngine1PreFF->get(); - engineData.engineEngine2PreFF = engineEngine2PreFF->get(); - engineData.engineEngineImbalance = engineEngineImbalance->get(); - engineData.engineFuelUsedLeft = engineFuelUsedLeft->get(); - engineData.engineFuelUsedRight = engineFuelUsedRight->get(); - engineData.engineFuelLeftPre = engineFuelLeftPre->get(); - engineData.engineFuelRightPre = engineFuelRightPre->get(); - engineData.engineFuelAuxLeftPre = engineFuelAuxLeftPre->get(); - engineData.engineFuelAuxRightPre = engineFuelAuxRightPre->get(); - engineData.engineFuelCenterPre = engineFuelCenterPre->get(); - engineData.engineEngineCycleTime = engineEngineCycleTime->get(); - engineData.engineEngine1State = engineEngine1State->get(); - engineData.engineEngine2State = engineEngine2State->get(); - engineData.engineEngine1Timer = engineEngine1Timer->get(); - engineData.engineEngine2Timer = engineEngine2Timer->get(); + + aircraftSpecificData.simulation_input_throttle_lever_1_pos = simData.throttle_lever_1_pos; + aircraftSpecificData.simulation_input_throttle_lever_2_pos = simData.throttle_lever_2_pos; + aircraftSpecificData.simulation_input_throttle_lever_3_pos = simData.throttle_lever_3_pos; + aircraftSpecificData.simulation_input_throttle_lever_4_pos = simData.throttle_lever_4_pos; + aircraftSpecificData.simulation_input_throttle_lever_1_angle = thrustLeverAngle_1->get(); + aircraftSpecificData.simulation_input_throttle_lever_2_angle = thrustLeverAngle_2->get(); + aircraftSpecificData.simulation_input_throttle_lever_3_angle = thrustLeverAngle_3->get(); + aircraftSpecificData.simulation_input_throttle_lever_4_angle = thrustLeverAngle_4->get(); + aircraftSpecificData.aircraft_engine_1_N1_percent = simData.corrected_engine_N1_1_percent; + aircraftSpecificData.aircraft_engine_2_N1_percent = simData.corrected_engine_N1_2_percent; + aircraftSpecificData.aircraft_engine_3_N1_percent = simData.corrected_engine_N1_3_percent; + aircraftSpecificData.aircraft_engine_4_N1_percent = simData.corrected_engine_N1_4_percent; + aircraftSpecificData.aircraft_hydraulic_system_green_pressure_psi = idHydGreenSystemPressure->get(); + aircraftSpecificData.aircraft_hydraulic_system_yellow_pressure_psi = idHydYellowSystemPressure->get(); + aircraftSpecificData.aircraft_autobrake_system_armed_mode = idAutobrakeArmedMode->get(); + aircraftSpecificData.aircraft_autobrake_system_is_decel_light_on = idAutobrakeDecelLight->get(); + aircraftSpecificData.aircraft_gear_nosewheel_pos = idNoseWheelPosition->get(); + aircraftSpecificData.aircraft_gear_nosewheel_compression_percent = 0.5 * simData.contact_point_compression_0 + 0.5; + aircraftSpecificData.aircraft_gear_main_left_inner_compression_percent = 0.5 * simData.contact_point_compression_1 + 0.5; + aircraftSpecificData.aircraft_gear_main_left_outer_compression_percent = 0.5 * simData.contact_point_compression_3 + 0.5; + aircraftSpecificData.aircraft_gear_main_right_inner_compression_percent = 0.5 * simData.contact_point_compression_2 + 0.5; + aircraftSpecificData.aircraft_gear_main_right_outer_compression_percent = 0.5 * simData.contact_point_compression_4 + 0.5; + aircraftSpecificData.aircraft_is_master_warning_active = idMasterWarning->get(); + aircraftSpecificData.aircraft_is_master_caution_active = idMasterCaution->get(); + aircraftSpecificData.aircraft_is_wing_anti_ice_active = idWingAntiIce->get(); + aircraftSpecificData.aircraft_is_alpha_floor_condition_active = + reinterpret_cast(&facsBusOutputs[0].discrete_word_5)->bitFromValueOr(29, false) || + reinterpret_cast(&facsBusOutputs[1].discrete_word_5)->bitFromValueOr(29, false); + aircraftSpecificData.aircraft_is_high_aoa_protection_active = 0; + aircraftSpecificData.aircraft_settings_is_realistic_tiller_enabled = idRealisticTillerEnabled->get() == 1; + aircraftSpecificData.aircraft_settings_any_failures_active = failuresConsumer.isAnyActive() ? 1.0 : 0.0; return true; } @@ -2789,7 +2751,7 @@ bool FlyByWireInterface::updateAutothrust(double sampleTime) { autoThrustInput.in.input.thrust_reduction_altitude_go_around = fmThrustReductionAltitudeGoAround->valueOr(0); autoThrustInput.in.input.flight_phase = idFmgcFlightPhase->get(); autoThrustInput.in.input.is_alt_soft_mode_active = autopilotStateMachineOutput.ALT_soft_mode_active; - autoThrustInput.in.input.is_anti_ice_wing_active = additionalData.wingAntiIce == 1; + autoThrustInput.in.input.is_anti_ice_wing_active = idWingAntiIce->get() == 1; autoThrustInput.in.input.is_anti_ice_engine_1_active = simData.engineAntiIce_1 == 1; autoThrustInput.in.input.is_anti_ice_engine_2_active = simData.engineAntiIce_2 == 1; autoThrustInput.in.input.is_anti_ice_engine_3_active = simData.engineAntiIce_3 == 1; @@ -2923,17 +2885,17 @@ bool FlyByWireInterface::updateFoSide(double sampleTime) { // Only one FD state, no sync needed // LS Button - if (additionalData.syncFoEfisEnabled && additionalData.ls1Active != additionalData.ls2Active) { - if (last_ls1_active != additionalData.ls1Active) { - idLs2Active->set(additionalData.ls1Active); + if (idSyncFoEfisEnabled->get() && idLs1Active->get() != idLs2Active->get()) { + if (last_ls1_active != idLs1Active->get()) { + idLs2Active->set(idLs1Active->get()); } - if (last_ls2_active != additionalData.ls2Active) { - idLs1Active->set(additionalData.ls2Active); + if (last_ls2_active != idLs2Active->get()) { + idLs1Active->set(idLs2Active->get()); } } - last_ls1_active = additionalData.ls1Active; - last_ls2_active = additionalData.ls2Active; + last_ls1_active = idLs1Active->get(); + last_ls2_active = idLs2Active->get(); // inHg/hPa switch // Currently synced already diff --git a/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.h b/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.h index 694c7236241..eaf5bca7f4a 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.h +++ b/fbw-a380x/src/wasm/fbw_a380/src/FlyByWireInterface.h @@ -3,11 +3,8 @@ #include #include -#include "AdditionalData.h" #include "Arinc429.h" #include "CalculatedRadioReceiver.h" -#include "EngineData.h" -#include "FlightDataRecorder.h" #include "InterpolatingLookupTable.h" #include "LocalVariable.h" #include "RateLimiter.h" @@ -19,6 +16,8 @@ #include "model/AutopilotLaws.h" #include "model/AutopilotStateMachine.h" #include "model/Autothrust.h" +#include "recording/FlightDataRecorder.h" +#include "recording/RecordingDataTypes.h" // #include "fcdc/Fcdc.h" #include "prim/Prim.h" #include "sec/Sec.h" @@ -317,7 +316,9 @@ class FlyByWireInterface { std::vector> throttleAxis; - AdditionalData additionalData = {}; + BaseData baseData = {}; + AircraftSpecificData aircraftSpecificData = {}; + std::unique_ptr idParkBrakeLeverPos; std::unique_ptr idBrakePedalLeftPos; std::unique_ptr idBrakePedalRightPos; @@ -326,39 +327,6 @@ class FlyByWireInterface { std::unique_ptr idMasterWarning; std::unique_ptr idMasterCaution; - EngineData engineData = {}; - std::unique_ptr engineEngine1N2; - std::unique_ptr engineEngine2N2; - std::unique_ptr engineEngine1N1; - std::unique_ptr engineEngine2N1; - std::unique_ptr engineEngineIdleN1; - std::unique_ptr engineEngineIdleN2; - std::unique_ptr engineEngineIdleFF; - std::unique_ptr engineEngineIdleEGT; - std::unique_ptr engineEngine1EGT; - std::unique_ptr engineEngine2EGT; - std::unique_ptr engineEngine1Oil; - std::unique_ptr engineEngine2Oil; - std::unique_ptr engineEngine1TotalOil; - std::unique_ptr engineEngine2TotalOil; - std::unique_ptr engineEngine1FF; - std::unique_ptr engineEngine2FF; - std::unique_ptr engineEngine1PreFF; - std::unique_ptr engineEngine2PreFF; - std::unique_ptr engineEngineImbalance; - std::unique_ptr engineFuelUsedLeft; - std::unique_ptr engineFuelUsedRight; - std::unique_ptr engineFuelLeftPre; - std::unique_ptr engineFuelRightPre; - std::unique_ptr engineFuelAuxLeftPre; - std::unique_ptr engineFuelAuxRightPre; - std::unique_ptr engineFuelCenterPre; - std::unique_ptr engineEngineCycleTime; - std::unique_ptr engineEngine1State; - std::unique_ptr engineEngine2State; - std::unique_ptr engineEngine1Timer; - std::unique_ptr engineEngine2Timer; - std::unique_ptr idFlapsHandleIndex; std::unique_ptr idFlapsHandlePercent; @@ -599,8 +567,8 @@ class FlyByWireInterface { bool updateRadioReceiver(double sampleTime); - bool updateEngineData(double sampleTime); - bool updateAdditionalData(double sampleTime); + bool updateBaseData(double sampleTime); + bool updateAircraftSpecificData(double sampleTime); bool updateAutopilotStateMachine(double sampleTime); bool updateAutopilotLaws(double sampleTime); diff --git a/fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h b/fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h new file mode 100644 index 00000000000..ecd64e0e4e6 --- /dev/null +++ b/fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h @@ -0,0 +1,304 @@ +#pragma once + +struct FuelSystemData { + double tank_quantity_1_left_outer; + double tank_quantity_2_feed1; + double tank_quantity_3_left_mid; + double tank_quantity_4_left_inner; + double tank_quantity_5_feed2; + double tank_quantity_6_feed3; + double tank_quantity_7_right_inner; + double tank_quantity_8_right_mid; + double tank_quantity_9_feed4; + double tank_quantity_10_right_outer; + double tank_quantity_11_trim; + double line_1_feed_tank1_to_feed1_tank_pump1; + double line_2_feed_tank1_to_feed1_tank_pump2; + double line_3_feed_tank2_to_feed2_tank_pump1; + double line_4_feed_tank2_to_feed2_tank_pump2; + double line_5_feed_tank3_to_feed3_tank_pump1; + double line_6_feed_tank3_to_feed3_tank_pump2; + double line_7_feed_tank4_to_feed4_tank_pump1; + double line_8_feed_tank4_to_feed4_tank_pump2; + double line_9_pump1_feed1_to_junc1; + double line_10_pump2_feed1_to_junc1; + double line_11_pump1_feed2_to_junc2; + double line_12_pump2_feed2_to_junc2; + double line_13_pump1_feed3_to_junc3; + double line_14_pump2_feed3_to_junc3; + double line_15_pump1_feed4_to_junc4; + double line_16_pump2_feed4_to_junc4; + double line_17_junc1_to_eng1lp_valve; + double line_18_junc2_to_eng2lp_valve; + double line_19_junc3_to_eng3lp_valve; + double line_20_junc4_to_eng4lp_valve; + double line_21_eng1lp_valve_to_eng1; + double line_22_eng2lp_valve_to_eng2; + double line_23_eng3lp_valve_to_eng3; + double line_24_eng4lp_valve_to_eng4; + double line_25_left_outer_tank_to_left_outer_tank_pump; + double line_26_left_mid_tank_to_left_mid_tank_pump_fwd; + double line_27_left_mid_tank_to_left_mid_tank_pump_aft; + double line_28_left_inner_tank_to_left_inner_tank_pump_fwd; + double line_29_left_inner_tank_to_left_inner_tank_pump_aft; + double line_30_right_outer_tank_to_right_outer_tank_pump; + double line_31_right_mid_tank_to_right_mid_tank_pump_fwd; + double line_32_right_mid_tank_to_right_mid_tank_pump_aft; + double line_33_right_inner_tank_to_right_inner_tank_pump_fwd; + double line_34_right_inner_tank_to_right_inner_tank_pump_aft; + double line_35_trim_tank_to_trim_tank_pump_left; + double line_36_trim_tank_to_trim_tank_pump_right; + double line_37_trim_tank_pump_left_to_trim_line_junction1; + double line_38_trim_tank_pump_right_to_trim_line_junction1; + double line_39_trim_line_junction1_to_trim_line_junction2; + double line_40_trim_line_junction1_to_trim_tank_inlet_valve1; + double line_41_trim_line_junction2_to_trim_line_iso_valve_fwd; + double line_42_trim_line_junction2_to_trim_line_iso_valve_aft_1; + double line_43_left_outer_tank_pump_to_fwd_gallery_junction; + double line_44_left_mid_tank_pump_fwd_to_fwd_gallery_junction; + double line_45_left_mid_tank_pump_aft_to_aft_gallery_junction1; + double line_46_left_inner_tank_pump_fwd_to_fwd_gallery_junction; + double line_47_left_inner_tank_pump_aft_to_aft_gallery_junction1; + double line_48_right_outer_tank_pump_to_fwd_gallery_junction; + double line_49_right_mid_tank_pump_fwd_to_fwd_gallery_junction; + double line_50_right_mid_tank_pump_aft_to_aft_gallery_junction1; + double line_51_right_inner_tank_pump_fwd_to_fwd_gallery_junction; + double line_52_right_inner_tank_pump_aft_to_aft_gallery_junction1; + double line_53_trim_line_iso_valve_fwd_to_fwd_gallery_junction; + double line_54_trim_line_iso_valve_aft_1_to_aft_gallery_junction1; + double line_55_fwd_gallery_junction_to_feed_tank1_fwd_xfer_valve1; + double line_56_fwd_gallery_junc_to_feed_tanks2_3_junc1; + double line_57_feed_tanks2_3_junc1_to_feed_tank2_fwd_xfer_valve1_1; + double line_58_feed_tanks2_3_junc1_to_feed_tank3_fwd_xfer_valve1_1; + double line_59_feed_tanks2_3_junc1_to_feed_tank2_fwd_xfer_valve1_2; + double line_60_feed_tanks2_3_junc1_to_feed_tank3_fwd_xfer_valve1_2; + double line_61_fwd_gallery_junction_to_feed_tank4_fwd_xfer_valve1; + double line_62_fwd_gallery_junction_to_feed_tank1_fwd_xfer_valve2; + double line_63_fwd_gallery_junc_to_feed_tanks2_3_junc2; + double line_64_feed_tanks2_3_junc2_to_feed_tank2_fwd_xfer_valve2_1; + double line_65_feed_tanks2_3_junc2_to_feed_tank3_fwd_xfer_valve2_1; + double line_66_feed_tanks2_3_junc2_to_feed_tank2_fwd_xfer_valve2_2; + double line_67_feed_tanks2_3_junc2_to_feed_tank3_fwd_xfer_valve2_2; + double line_68_fwd_gallery_junction_to_feed_tank4_fwd_xfer_valve2; + double line_69_fwd_gallery_junction_to_left_inner_fwd_xfer_valve; + double line_70_fwd_gallery_junction_to_left_mid_fwd_xfer_valve; + double line_71_fwd_gallery_junction_to_left_outer_fwd_xfer_valve; + double line_72_fwd_gallery_junction_to_right_inner_fwd_xfer_valve; + double line_73_fwd_gallery_junction_to_right_mid_fwd_xfer_valve; + double line_74_fwd_gallery_junction_to_right_outer_fwd_xfer_valve; + double line_75_feed_tank1_fwd_xfer_valve1_to_feed_tank1; + double line_76_feed_tank2_fwd_xfer_valve1_1_to_feed_tank2; + double line_77_feed_tank3_fwd_xfer_valve1_1_to_feed_tank3; + double line_78_feed_tank2_fwd_xfer_valve1_2_to_feed_tank2; + double line_79_feed_tank3_fwd_xfer_valve1_2_to_feed_tank3; + double line_80_feed_tank4_fwd_xfer_valve1_to_feed_tank4; + double line_81_feed_tank1_fwd_xfer_valve2_to_feed_tank1; + double line_82_feed_tank2_fwd_xfer_valve2_1_to_feed_tank2; + double line_83_feed_tank3_fwd_xfer_valve2_1_to_feed_tank3; + double line_84_feed_tank2_fwd_xfer_valve2_2_to_feed_tank2; + double line_85_feed_tank3_fwd_xfer_valve2_2_to_feed_tank3; + double line_86_feed_tank4_fwd_xfer_valve2_to_feed_tank4; + double line_87_left_inner_fwd_xfer_valve_to_left_inner_tank; + double line_88_left_mid_fwd_xfer_valve_to_left_mid_tank; + double line_89_left_outer_fwd_xfer_valve_to_left_outer_tank; + double line_90_right_inner_fwd_xfer_valve_to_right_inner_tank; + double line_91_right_mid_fwd_xfer_valve_to_right_mid_tank; + double line_92_right_outer_fwd_xfer_valve_to_right_outer_tank; + double line_93_aft_gallery_junction2_to_feed_tank1_aft_xfer_valve1; + double line_94_aft_gallery_junction2_to_feed_tank2_aft_xfer_valve1; + double line_95_aft_gallery_junction2_to_feed_tank3_aft_xfer_valve1; + double line_96_aft_gallery_junction2_to_feed_tank4_aft_xfer_valve1; + double line_97_feed_tank1_aft_xfer_valve1_to_feed_tank1_aft_xfer_valve2; + double line_98_feed_tank2_aft_xfer_valve1_to_feed_tank2_aft_xfer_valve2; + double line_99_feed_tank3_aft_xfer_valve1_to_feed_tank3_aft_xfer_valve2; + double line_100_feed_tank4_aft_xfer_valve1_to_feed_tank4_aft_xfer_valve2; + double line_101_aft_gallery_junction1_to_left_inner_aft_xfer_valve1; + double line_102_aft_gallery_junction1_to_left_mid_aft_xfer_valve1; + double line_103_aft_gallery_junction1_to_left_outer_aft_xfer_valve1; + double line_104_aft_gallery_junction1_to_right_inner_aft_xfer_valve1; + double line_105_aft_gallery_junction1_to_right_mid_aft_xfer_valve1; + double line_106_aft_gallery_junction1_to_right_outer_aft_xfer_valve1; + double line_107_left_inner_aft_transfer_valve1_to_left_inner_aft_xfer_valve2; + double line_108_left_mid_aft_transfer_valve1_to_left_mid_aft_xfer_valve2; + double line_109_left_outer_aft_transfer_valve1_to_left_outer_aft_xfer_valve2; + double line_110_right_inner_aft_transfer_valve1_to_right_inner_aft_xfer_valve2; + double line_111_right_mid_aft_transfer_valve1_to_right_mid_aft_xfer_valve2; + double line_112_right_outer_aft_transfer_valve1_to_right_outer_aft_xfer_valve2; + double line_113_feed_tank1_aft_xfer_valve2_to_feed_tank1; + double line_114_feed_tank2_aft_xfer_valve2_to_feed_tank2; + double line_115_feed_tank3_aft_xfer_valve2_to_feed_tank3; + double line_116_feed_tank4_aft_xfer_valve2_to_feed_tank4; + double line_117_left_inner_aft_xfer_valve2_to_left_inner_tank; + double line_118_left_mid_aft_xfer_valve2_to_left_mid_tank; + double line_119_left_outer_aft_xfer_valve2_to_left_outer_tank; + double line_120_right_inner_aft_xfer_valve2_to_right_inner_tank; + double line_121_right_mid_aft_xfer_valve2_to_right_mid_tank; + double line_122_right_outer_aft_xfer_valve2_to_right_outer_tank; + double line_123_fwd_gallery_junc_to_gallery_aux_revalve_left; + double line_124_fwd_gallery_junc_to_gallery_aux_revalve_right; + double line_125_gallery_aux_revalve_left_to_a_ft_gallery_junc1; + double line_126_gallery_aux_revalve_right_to_a_ft_gallery_junc1; + double line_127_fwd_gallery_junc_to_transfer_devalve; + double line_128_junc1_to_cross_feed_valve1; + double line_129_junc2_to_cross_feed_valve2; + double line_130_junc3_to_cross_feed_valve3; + double line_131_junc4_to_cross_feed_valve4; + double line_132_cross_feed_valve1_to_cross_feed_junc1; + double line_133_cross_feed_junc1_to_cross_feed_valve2; + double line_134_cross_feed_junc1_to_cross_feed_junc2; + double line_135_cross_feed_junc2_to_cross_feed_valve3; + double line_136_cross_feed_junc2_to_cross_feed_valve4; + double line_137_transfer_devalve_to_cross_feed_junc1; + double line_138_junc4_to_apu_feed_pump; + double line_139_apu_feed_pump_to_apu_iso_valve; + double line_140_apu_iso_valve_to_apulp_valve; + double line_141_apulp_valve_to_apu; + double line_142_left_outer_tank_to_left_outer_emer_xfer_valve; + double line_143_right_outer_tank_to_right_outer_emer_xfer_valve; + double line_144_left_outer_emer_xfer_valve_to_feed_tank1; + double line_145_right_outer_emer_xfer_valve_to_feed_tank4; + double line_146_aft_gallery_junction1_to_jetisson_nozzle_valve_left; + double line_147_aft_gallery_junction1_to_jetisson_nozzle_valve_right; + double line_148_trim_tank_inlet_valve1_to_trim_tank; + double line_149_trim_tank_inlet_valve2_to_trim_tank; + double line_150_trim_line_junction2_to_trim_line_iso_valve_aft_2; + double line_151_trim_line_junction1_to_trim_tank_inlet_valve2; + double line_152_trim_line_iso_valve_aft_2_to_aft_gallery_junction1; + double line_153_aft_gallery_junction1_to_aft_gallery_junction2; + double junction_1_junction1; + double junction_2_junction2; + double junction_3_junction3; + double junction_4_junction4; + double junction_5_trim_line_junction1; + double junction_6_trim_line_junction2; + double junction_7_fwd_gallery_junction; + double junction_8_feed_tanks2_3_junction1; + double junction_9_feed_tanks2_3_junction2; + double junction_10_aft_gallery_junction1; + double junction_11_aft_gallery_junction2; + double junction_12_cross_feed_junc; + double junction_13_cross_feed_junc; + double valve_1_engine1lp_valve; + double valve_2_engine2lp_valve; + double valve_3_engine3lp_valve; + double valve_4_engine4lp_valve; + double valve_5_feed_tank1_fwd_transfer_valve1; + double valve_6_feed_tank2_fwd_transfer_valve1_1; + double valve_7_feed_tank3_fwd_transfer_valve1_1; + double valve_8_feed_tank2_fwd_transfer_valve1_2; + double valve_9_feed_tank3_fwd_transfer_valve1_2; + double valve_10_feed_tank4_fwd_transfer_valve1; + double valve_11_feed_tank1_fwd_transfer_valve2; + double valve_12_feed_tank2_fwd_transfer_valve2_1; + double valve_13_feed_tank3_fwd_transfer_valve2_1; + double valve_14_feed_tank2_fwd_transfer_valve2_2; + double valve_15_feed_tank3_fwd_transfer_valve2_2; + double valve_16_feed_tank4_fwd_transfer_valve2; + double valve_17_left_inner_fwd_transfer_valve; + double valve_18_left_mid_fwd_transfer_valve; + double valve_19_left_outer_fwd_transfer_valve; + double valve_20_right_inner_fwd_transfer_valve; + double valve_21_right_mid_fwd_transfer_valve; + double valve_22_right_outer_fwd_transfer_valve; + double valve_23_feed_tank1_aft_transfer_valve1; + double valve_24_feed_tank2_aft_transfer_valve1; + double valve_25_feed_tank3_aft_transfer_valve1; + double valve_26_feed_tank4_aft_transfer_valve1; + double valve_27_feed_tank1_aft_transfer_valve2; + double valve_28_feed_tank2_aft_transfer_valve2; + double valve_29_feed_tank3_aft_transfer_valve2; + double valve_30_feed_tank4_aft_transfer_valve2; + double valve_31_left_inner_aft_transfer_valve1; + double valve_32_left_mid_aft_transfer_valve1; + double valve_33_left_outer_aft_transfer_valve1; + double valve_34_right_inner_aft_transfer_valve1; + double valve_35_right_mid_aft_transfer_valve1; + double valve_36_right_outer_aft_transfer_valve1; + double valve_37_left_inner_aft_transfer_valve2; + double valve_38_left_mid_aft_transfer_valve2; + double valve_39_left_outer_aft_transfer_valve2; + double valve_40_right_inner_aft_transfer_valve2; + double valve_41_right_mid_aft_transfer_valve2; + double valve_42_right_outer_aft_transfer_valve2; + double valve_43_trim_tank_inlet_valve1; + double valve_44_trim_line_isolation_valve_fwd; + double valve_45_trim_line_isolation_valve_aft_1; + double valve_46_cross_feed_valve1; + double valve_47_cross_feed_valve2; + double valve_48_cross_feed_valve3; + double valve_49_cross_feed_valve4; + double valve_50_apu_iso_valve; + double valve_51_apulp_valve; + double valve_52_left_outer_emer_transfer_valve; + double valve_53_right_outer_emer_transfer_valve; + double valve_54_gallery_aux_refuel_valve_left; + double valve_55_gallery_aux_refuel_valve_right; + double valve_56_transfer_defuel_valve; + double valve_57_jettison_nozzle_valve_left; + double valve_58_jettison_nozzle_valve_right; + double valve_59_trim_line_isolation_valve_aft_2; + double valve_60_trim_tank_inlet_valve2; + double pump_1_feed1_tank_pump1; + double pump_2_feed1_tank_pump2; + double pump_3_feed2_tank_pump1; + double pump_4_feed2_tank_pump2; + double pump_5_feed3_tank_pump1; + double pump_6_feed3_tank_pump2; + double pump_7_feed4_tank_pump1; + double pump_8_feed4_tank_pump2; + double pump_9_left_outer_tank_pump; + double pump_10_left_mid_tank_pump_fwd; + double pump_11_left_mid_tank_pump_aft; + double pump_12_left_inner_tank_pump_fwd; + double pump_13_right_inner_tank_pump_fwd; + double pump_14_right_outer_tank_pump; + double pump_15_right_mid_tank_pump_fwd; + double pump_16_right_mid_tank_pump_aft; + double pump_17_left_inner_tank_pump_aft; + double pump_18_right_inner_tank_pump_aft; + double pump_19_trim_tank_pump_left; + double pump_20_trim_tank_pump_right; + double pump_21_apu_feed_pump; + double trigger_1_innerand_mid_tanks_xfer_feed1_start; + double trigger_2_innerand_mid_tanks_xfer_feed2_start; + double trigger_3_innerand_mid_tanks_xfer_feed3_start; + double trigger_4_innerand_mid_tanks_xfer_feed4_start; + double trigger_5_equalize1and4; + double trigger_6_equalize2and3; + double trigger_7_innerand_mid_tanks_xfer_feed1and4_end; + double trigger_8_innerand_mid_tanks_xfer_feed2and3_end; + double trigger_9_innerand_mid_tanks_xfer_feed2and3_end_redundant; + double trigger_10_innerand_mid_tanks_xfer_feed1and4_end_redundant; + double trigger_11_inner_tank_left_empty; + double trigger_12_inner_tank_right_empty; + double trigger_13_mid_tanks_below8000; + double trigger_14_mid_below8000_threshold_feed2_start; + double trigger_15_mid_below8000_threshold_feed3_start; + double trigger_16_mid_below8000_threshold_feed2_end; + double trigger_17_mid_below8000_threshold_feed3_end; + double trigger_18_equalize1and3for_mid_below8000; + double trigger_19_equalize1and2for_mid_below8000; + double trigger_20_equalize2and4for_mid_below8000; + double trigger_21_equalize3and4for_mid_below8000; + double trigger_22_mid_tank_left_empty; + double trigger_23_mid_tank_right_empty; + double trigger_24_trim_tank_transfer_to_feed_tank1; + double trigger_25_trim_tank_transfer_to_feed_tank2; + double trigger_26_trim_tank_transfer_to_feed_tank3; + double trigger_27_trim_tank_transfer_to_feed_tank4; + double trigger_28_equalize1and3; + double trigger_29_equalize1and2; + double trigger_30_equalize2and4; + double trigger_31_equalize3and4; + double trigger_32_trim_tank_empty; + double trigger_33_outer_tanks_transfer_to_feed_tank1; + double trigger_34_outer_tanks_transfer_to_feed_tank2; + double trigger_35_outer_tanks_transfer_to_feed_tank1; + double trigger_36_outer_tanks_transfer_to_feed_tank2; + double trigger_37_outer_tanks_transfer_to_feed_tank1_end; + double trigger_38_outer_tanks_transfer_to_feed_tank2_end; + double trigger_39_outer_tanks_transfer_to_feed_tank3_end; + double trigger_40_outer_tanks_transfer_to_feed_tank4_end; + double trigger_41_cg_control_transfer_start; + double trigger_42_cg_control_transfer_end; +}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectData.h b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectData.h index 4b3714dd422..bbcdd37cd80 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectData.h +++ b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectData.h @@ -2,6 +2,7 @@ #include #include +#include "FuelSystemData.h" struct SimData { double nz_g; @@ -64,8 +65,12 @@ struct SimData { double longitude_deg; double throttle_lever_1_pos; double throttle_lever_2_pos; + double throttle_lever_3_pos; + double throttle_lever_4_pos; double engine_1_thrust_lbf; double engine_2_thrust_lbf; + double engine_3_thrust_lbf; + double engine_4_thrust_lbf; unsigned long long nav_valid; double nav_loc_deg; double nav_gs_deg; @@ -105,23 +110,6 @@ struct SimData { unsigned long long engineAntiIce_3; unsigned long long engineAntiIce_4; unsigned long long simOnGround; - double generalEngineElapsedTime_1; - double generalEngineElapsedTime_2; - double standardAtmTemperature; - double turbineEngineCorrectedFuelFlow_1; - double turbineEngineCorrectedFuelFlow_2; - double fuelTankCapacityAuxLeft; - double fuelTankCapacityAuxRight; - double fuelTankCapacityMainLeft; - double fuelTankCapacityMainRight; - double fuelTankCapacityCenter; - double fuelTankQuantityAuxLeft; - double fuelTankQuantityAuxRight; - double fuelTankQuantityMainLeft; - double fuelTankQuantityMainRight; - double fuelTankQuantityCenter; - double fuelTankQuantityTotal; - double fuelWeightPerGallon; double kohlsmanSetting_0; double kohlsmanSetting_1; unsigned long long kohlsmanSettingStd_3; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.cpp b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.cpp index 3b16515c0a3..7dbb1b958f3 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.cpp +++ b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.cpp @@ -196,8 +196,12 @@ bool SimConnectInterface::prepareSimDataSimConnectDataDefinitions() { result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "PLANE LONGITUDE", "DEGREES"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG THROTTLE LEVER POSITION:1", "PERCENT"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG THROTTLE LEVER POSITION:2", "PERCENT"); + result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG THROTTLE LEVER POSITION:3", "PERCENT"); + result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG THROTTLE LEVER POSITION:4", "PERCENT"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG JET THRUST:1", "POUNDS"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG JET THRUST:2", "POUNDS"); + result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG JET THRUST:3", "POUNDS"); + result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG JET THRUST:4", "POUNDS"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "NAV HAS NAV:3", "BOOL"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "NAV LOCALIZER:3", "DEGREES"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "NAV RAW GLIDE SLOPE:3", "DEGREES"); @@ -237,23 +241,6 @@ bool SimConnectInterface::prepareSimDataSimConnectDataDefinitions() { result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "ENG ANTI ICE:3", "BOOL"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "ENG ANTI ICE:4", "BOOL"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "SIM ON GROUND", "BOOL"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG ELAPSED TIME:1", "SECONDS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "GENERAL ENG ELAPSED TIME:2", "SECONDS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "STANDARD ATM TEMPERATURE", "CELSIUS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG CORRECTED FF:1", "POUNDS PER HOUR"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "TURB ENG CORRECTED FF:2", "POUNDS PER HOUR"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT AUX CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT AUX CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT MAIN CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT MAIN CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK CENTER CAPACITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT AUX QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT AUX QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK LEFT MAIN QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK RIGHT MAIN QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TANK CENTER QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL TOTAL QUANTITY", "GALLONS"); - result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "FUEL WEIGHT PER GALLON", "POUNDS"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "KOHLSMAN SETTING MB:0", "MBAR"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "KOHLSMAN SETTING MB:1", "MBAR"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_INT64, "KOHLSMAN SETTING STD:3", "BOOL"); @@ -282,6 +269,315 @@ bool SimConnectInterface::prepareSimDataSimConnectDataDefinitions() { result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "CONTACT POINT COMPRESSION:3", "PERCENT"); result &= addDataDefinition(hSimConnect, 0, SIMCONNECT_DATATYPE_FLOAT64, "CONTACT POINT COMPRESSION:4", "PERCENT"); + // ----------------------------------- + // DATA FOR FDR TO MONITOR FUEL SYSTEM + // ----------------------------------- + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:1", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:2", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:3", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:4", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:5", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:6", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:7", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:8", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:9", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:10", "GALLONS"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TANK QUANTITY:11", "GALLONS"); + + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:1", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:2", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:3", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:4", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:5", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:6", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:7", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:8", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:9", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:10", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:11", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:12", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:13", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:14", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:15", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:16", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:17", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:18", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:19", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:20", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:21", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:22", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:23", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:24", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:25", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:26", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:27", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:28", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:29", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:30", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:31", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:32", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:33", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:34", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:35", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:36", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:37", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:38", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:39", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:40", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:41", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:42", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:43", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:44", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:45", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:46", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:47", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:48", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:49", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:50", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:51", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:52", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:53", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:54", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:55", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:56", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:57", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:58", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:59", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:60", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:61", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:62", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:63", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:64", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:65", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:66", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:67", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:68", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:69", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:70", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:71", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:72", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:73", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:74", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:75", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:76", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:77", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:78", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:79", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:80", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:81", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:82", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:83", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:84", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:85", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:86", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:87", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:88", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:89", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:90", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:91", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:92", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:93", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:94", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:95", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:96", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:97", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:98", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:99", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:100", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:101", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:102", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:103", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:104", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:105", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:106", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:107", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:108", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:109", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:110", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:111", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:112", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:113", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:114", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:115", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:116", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:117", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:118", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:119", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:120", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:121", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:122", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:123", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:124", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:125", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:126", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:127", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:128", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:129", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:130", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:131", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:132", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:133", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:134", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:135", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:136", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:137", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:138", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:139", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:140", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:141", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:142", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:143", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:144", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:145", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:146", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:147", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:148", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:149", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:150", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:151", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:152", "GALLONS PER HOUR"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM LINE FUEL FLOW:153", "GALLONS PER HOUR"); + + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:1", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:2", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:3", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:4", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:5", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:6", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:7", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:8", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:9", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:10", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:11", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:12", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM JUNCTION SETTING:13", "NUMBER"); + + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:1", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:2", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:3", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:4", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:5", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:6", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:7", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:8", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:9", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:10", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:11", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:12", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:13", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:14", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:15", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:16", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:17", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:18", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:19", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:20", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:21", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:22", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:23", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:24", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:25", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:26", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:27", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:28", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:29", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:30", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:31", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:32", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:33", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:34", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:35", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:36", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:37", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:38", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:39", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:40", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:41", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:42", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:43", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:44", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:45", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:46", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:47", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:48", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:49", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:50", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:51", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:52", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:53", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:54", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:55", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:56", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:57", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:58", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:59", "PERCENT OVER 100"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM VALVE OPEN:60", "PERCENT OVER 100"); + + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:1", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:2", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:3", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:4", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:5", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:6", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:7", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:8", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:9", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:10", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:11", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:12", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:13", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:14", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:15", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:16", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:17", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:18", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:19", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:20", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM PUMP ACTIVE:21", "NUMBER"); + + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:1", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:2", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:3", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:4", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:5", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:6", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:7", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:8", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:9", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:10", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:11", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:12", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:13", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:14", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:15", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:16", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:17", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:18", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:19", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:20", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:21", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:22", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:23", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:24", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:25", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:26", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:27", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:28", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:29", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:30", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:31", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:32", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:33", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:34", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:35", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:36", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:37", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:38", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:39", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:40", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:41", "NUMBER"); + result &= addDataDefinition(hSimConnect, 1, SIMCONNECT_DATATYPE_FLOAT64, "FUELSYSTEM TRIGGER STATUS:42", "NUMBER"); + return result; } @@ -1171,8 +1467,12 @@ bool SimConnectInterface::requestData() { // request data HRESULT result = SimConnect_RequestDataOnSimObject(hSimConnect, 0, 0, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); + if (result != S_OK) { + // request failed + return false; + } - // check result of data request + result = SimConnect_RequestDataOnSimObject(hSimConnect, 1, 1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (result != S_OK) { // request failed return false; @@ -1246,37 +1546,41 @@ bool SimConnectInterface::sendEvent(Events eventId, DWORD data, DWORD priority) return true; } -bool SimConnectInterface::setClientDataLocalVariables(ClientDataLocalVariables output) { +bool SimConnectInterface::setClientDataLocalVariables(ClientDataLocalVariables& output) { // write data and return result return sendClientData(ClientData::LOCAL_VARIABLES, sizeof(output), &output); } -bool SimConnectInterface::setClientDataLocalVariablesAutothrust(ClientDataLocalVariablesAutothrust output) { +bool SimConnectInterface::setClientDataLocalVariablesAutothrust(ClientDataLocalVariablesAutothrust& output) { // write data and return result return sendClientData(ClientData::LOCAL_VARIABLES_AUTOTHRUST, sizeof(output), &output); } -SimData SimConnectInterface::getSimData() { +SimData& SimConnectInterface::getSimData() { return simData; } -SimInput SimConnectInterface::getSimInput() { +FuelSystemData& SimConnectInterface::getFuelSystemData() { + return fuelSystemData; +} + +SimInput& SimConnectInterface::getSimInput() { return simInput; } -SimInputAutopilot SimConnectInterface::getSimInputAutopilot() { +SimInputAutopilot& SimConnectInterface::getSimInputAutopilot() { return simInputAutopilot; } -SimInputPitchTrim SimConnectInterface::getSimInputPitchTrim() { +SimInputPitchTrim& SimConnectInterface::getSimInputPitchTrim() { return simInputPitchTrim; } -SimInputRudderTrim SimConnectInterface::getSimInputRudderTrim() { +SimInputRudderTrim& SimConnectInterface::getSimInputRudderTrim() { return simInputRudderTrim; } -SimInputThrottles SimConnectInterface::getSimInputThrottles() { +SimInputThrottles& SimConnectInterface::getSimInputThrottles() { return simInputThrottles; } @@ -1314,129 +1618,129 @@ void SimConnectInterface::resetSimInputThrottles() { simInputThrottles.ATHR_reset_disable = 0; } -bool SimConnectInterface::setClientDataAutopilotLaws(ClientDataAutopilotLaws output) { +bool SimConnectInterface::setClientDataAutopilotLaws(ClientDataAutopilotLaws& output) { // write data and return result return sendClientData(ClientData::AUTOPILOT_LAWS, sizeof(output), &output); } -ClientDataAutopilotLaws SimConnectInterface::getClientDataAutopilotLaws() { +ClientDataAutopilotLaws& SimConnectInterface::getClientDataAutopilotLaws() { return clientDataAutopilotLaws; } -bool SimConnectInterface::setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine output) { +bool SimConnectInterface::setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine& output) { // write data and return result return sendClientData(ClientData::AUTOPILOT_STATE_MACHINE, sizeof(output), &output); } -ClientDataAutopilotStateMachine SimConnectInterface::getClientDataAutopilotStateMachine() { +ClientDataAutopilotStateMachine& SimConnectInterface::getClientDataAutopilotStateMachine() { return clientDataAutopilotStateMachine; } -ClientDataAutothrust SimConnectInterface::getClientDataAutothrust() { +ClientDataAutothrust& SimConnectInterface::getClientDataAutothrust() { return clientDataAutothrust; } -ClientDataAutothrustA380 SimConnectInterface::getClientDataAutothrustA380() { +ClientDataAutothrustA380& SimConnectInterface::getClientDataAutothrustA380() { return clientDataAutothrustA380; } -ClientDataFlyByWire SimConnectInterface::getClientDataFlyByWire() { +ClientDataFlyByWire& SimConnectInterface::getClientDataFlyByWire() { return clientDataFlyByWire; } -bool SimConnectInterface::setClientDataPrimDiscretes(base_prim_discrete_inputs output) { +bool SimConnectInterface::setClientDataPrimDiscretes(base_prim_discrete_inputs& output) { return sendClientData(ClientData::PRIM_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataPrimAnalog(base_prim_analog_inputs output) { +bool SimConnectInterface::setClientDataPrimAnalog(base_prim_analog_inputs& output) { return sendClientData(ClientData::PRIM_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataPrimBusInput(base_prim_out_bus output, int primIndex) { +bool SimConnectInterface::setClientDataPrimBusInput(base_prim_out_bus& output, int primIndex) { return sendClientData(ClientData::PRIM_1_BUS_OUTPUT + primIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecDiscretes(base_sec_discrete_inputs output) { +bool SimConnectInterface::setClientDataSecDiscretes(base_sec_discrete_inputs& output) { return sendClientData(ClientData::SEC_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecAnalog(base_sec_analog_inputs output) { +bool SimConnectInterface::setClientDataSecAnalog(base_sec_analog_inputs& output) { return sendClientData(ClientData::SEC_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSecBus(base_sec_out_bus output, int secIndex) { +bool SimConnectInterface::setClientDataSecBus(base_sec_out_bus& output, int secIndex) { return sendClientData(ClientData::SEC_1_BUS_OUTPUT + secIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFacDiscretes(base_fac_discrete_inputs output) { +bool SimConnectInterface::setClientDataFacDiscretes(base_fac_discrete_inputs& output) { return sendClientData(ClientData::FAC_DISCRETE_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFacAnalog(base_fac_analog_inputs output) { +bool SimConnectInterface::setClientDataFacAnalog(base_fac_analog_inputs& output) { return sendClientData(ClientData::FAC_ANALOG_INPUTS, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFacBus(base_fac_bus output, int facIndex) { +bool SimConnectInterface::setClientDataFacBus(base_fac_bus& output, int facIndex) { return sendClientData(ClientData::FAC_1_BUS_OUTPUT + facIndex, sizeof(output), &output); } -base_prim_discrete_outputs SimConnectInterface::getClientDataPrimDiscretesOutput() { +base_prim_discrete_outputs& SimConnectInterface::getClientDataPrimDiscretesOutput() { return clientDataPrimDiscreteOutputs; } -base_prim_analog_outputs SimConnectInterface::getClientDataPrimAnalogsOutput() { +base_prim_analog_outputs& SimConnectInterface::getClientDataPrimAnalogsOutput() { return clientDataPrimAnalogOutputs; } -base_prim_out_bus SimConnectInterface::getClientDataPrimBusOutput() { +base_prim_out_bus& SimConnectInterface::getClientDataPrimBusOutput() { return clientDataPrimBusOutputs; } -base_sec_discrete_outputs SimConnectInterface::getClientDataSecDiscretesOutput() { +base_sec_discrete_outputs& SimConnectInterface::getClientDataSecDiscretesOutput() { return clientDataSecDiscreteOutputs; } -base_sec_analog_outputs SimConnectInterface::getClientDataSecAnalogsOutput() { +base_sec_analog_outputs& SimConnectInterface::getClientDataSecAnalogsOutput() { return clientDataSecAnalogOutputs; } -base_sec_out_bus SimConnectInterface::getClientDataSecBusOutput() { +base_sec_out_bus& SimConnectInterface::getClientDataSecBusOutput() { return clientDataSecBusOutputs; } -base_fac_discrete_outputs SimConnectInterface::getClientDataFacDiscretesOutput() { +base_fac_discrete_outputs& SimConnectInterface::getClientDataFacDiscretesOutput() { return clientDataFacDiscreteOutputs; } -base_fac_analog_outputs SimConnectInterface::getClientDataFacAnalogsOutput() { +base_fac_analog_outputs& SimConnectInterface::getClientDataFacAnalogsOutput() { return clientDataFacAnalogOutputs; } -base_fac_bus SimConnectInterface::getClientDataFacBusOutput() { +base_fac_bus& SimConnectInterface::getClientDataFacBusOutput() { return clientDataFacBusOutputs; } -bool SimConnectInterface::setClientDataAdr(base_adr_bus output, int adrIndex) { +bool SimConnectInterface::setClientDataAdr(base_adr_bus& output, int adrIndex) { return sendClientData(ClientData::ADR_1_INPUTS + adrIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataIr(base_ir_bus output, int irIndex) { +bool SimConnectInterface::setClientDataIr(base_ir_bus& output, int irIndex) { return sendClientData(ClientData::IR_1_INPUTS + irIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataRa(base_ra_bus output, int raIndex) { +bool SimConnectInterface::setClientDataRa(base_ra_bus& output, int raIndex) { return sendClientData(ClientData::RA_1_BUS + raIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataLgciu(base_lgciu_bus output, int lgciuIndex) { +bool SimConnectInterface::setClientDataLgciu(base_lgciu_bus& output, int lgciuIndex) { return sendClientData(ClientData::LGCIU_1_BUS + lgciuIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataSfcc(base_sfcc_bus output, int sfccIndex) { +bool SimConnectInterface::setClientDataSfcc(base_sfcc_bus& output, int sfccIndex) { return sendClientData(ClientData::SFCC_1_BUS + sfccIndex, sizeof(output), &output); } -bool SimConnectInterface::setClientDataFmgcB(base_fmgc_b_bus output, int fmgcIndex) { +bool SimConnectInterface::setClientDataFmgcB(base_fmgc_b_bus& output, int fmgcIndex) { return sendClientData(ClientData::FMGC_1_B_BUS + fmgcIndex, sizeof(output), &output); } @@ -3074,6 +3378,11 @@ void SimConnectInterface::simConnectProcessSimObjectData(const SIMCONNECT_RECV_S simData = *((SimData*)&data->dwData); return; + case 1: + // store fuel system data + fuelSystemData = *((FuelSystemData*)&data->dwData); + return; + default: // print unknown request id std::cout << "WASM: Unknown request id in SimConnect connection: "; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.h b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.h index 5a83dcd5972..1c691fc69d9 100644 --- a/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.h +++ b/fbw-a380x/src/wasm/fbw_a380/src/interface/SimConnectInterface.h @@ -244,9 +244,9 @@ class SimConnectInterface { bool sendEvent(Events eventId, DWORD data, DWORD priority); - bool setClientDataLocalVariables(ClientDataLocalVariables output); + bool setClientDataLocalVariables(ClientDataLocalVariables& output); - bool setClientDataLocalVariablesAutothrust(ClientDataLocalVariablesAutothrust output); + bool setClientDataLocalVariablesAutothrust(ClientDataLocalVariablesAutothrust& output); void resetSimInputPitchTrim(); @@ -256,63 +256,65 @@ class SimConnectInterface { void resetSimInputThrottles(); - SimData getSimData(); + SimData& getSimData(); - SimInput getSimInput(); + FuelSystemData& getFuelSystemData(); - SimInputAutopilot getSimInputAutopilot(); + SimInput& getSimInput(); - SimInputPitchTrim getSimInputPitchTrim(); + SimInputAutopilot& getSimInputAutopilot(); - SimInputRudderTrim getSimInputRudderTrim(); + SimInputPitchTrim& getSimInputPitchTrim(); - SimInputThrottles getSimInputThrottles(); + SimInputRudderTrim& getSimInputRudderTrim(); - bool setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine output); - ClientDataAutopilotStateMachine getClientDataAutopilotStateMachine(); + SimInputThrottles& getSimInputThrottles(); - bool setClientDataAutopilotLaws(ClientDataAutopilotLaws output); - ClientDataAutopilotLaws getClientDataAutopilotLaws(); + bool setClientDataAutopilotStateMachine(ClientDataAutopilotStateMachine& output); + ClientDataAutopilotStateMachine& getClientDataAutopilotStateMachine(); - ClientDataAutothrust getClientDataAutothrust(); + bool setClientDataAutopilotLaws(ClientDataAutopilotLaws& output); + ClientDataAutopilotLaws& getClientDataAutopilotLaws(); - ClientDataAutothrustA380 getClientDataAutothrustA380(); + ClientDataAutothrust& getClientDataAutothrust(); - bool setClientDataFlyByWireInput(ClientDataFlyByWireInput output); + ClientDataAutothrustA380& getClientDataAutothrustA380(); - bool setClientDataFlyByWire(ClientDataFlyByWire output); - ClientDataFlyByWire getClientDataFlyByWire(); + bool setClientDataFlyByWireInput(ClientDataFlyByWireInput& output); - bool setClientDataPrimDiscretes(base_prim_discrete_inputs output); - bool setClientDataPrimAnalog(base_prim_analog_inputs output); - bool setClientDataPrimBusInput(base_prim_out_bus output, int primIndex); + bool setClientDataFlyByWire(ClientDataFlyByWire& output); + ClientDataFlyByWire& getClientDataFlyByWire(); - base_prim_discrete_outputs getClientDataPrimDiscretesOutput(); - base_prim_analog_outputs getClientDataPrimAnalogsOutput(); - base_prim_out_bus getClientDataPrimBusOutput(); + bool setClientDataPrimDiscretes(base_prim_discrete_inputs& output); + bool setClientDataPrimAnalog(base_prim_analog_inputs& output); + bool setClientDataPrimBusInput(base_prim_out_bus& output, int primIndex); - bool setClientDataSecDiscretes(base_sec_discrete_inputs output); - bool setClientDataSecAnalog(base_sec_analog_inputs output); - bool setClientDataSecBus(base_sec_out_bus output, int secIndex); + base_prim_discrete_outputs& getClientDataPrimDiscretesOutput(); + base_prim_analog_outputs& getClientDataPrimAnalogsOutput(); + base_prim_out_bus& getClientDataPrimBusOutput(); - base_sec_discrete_outputs getClientDataSecDiscretesOutput(); - base_sec_analog_outputs getClientDataSecAnalogsOutput(); - base_sec_out_bus getClientDataSecBusOutput(); + bool setClientDataSecDiscretes(base_sec_discrete_inputs& output); + bool setClientDataSecAnalog(base_sec_analog_inputs& output); + bool setClientDataSecBus(base_sec_out_bus& output, int secIndex); - bool setClientDataFacDiscretes(base_fac_discrete_inputs output); - bool setClientDataFacAnalog(base_fac_analog_inputs output); - bool setClientDataFacBus(base_fac_bus output, int facIndex); + base_sec_discrete_outputs& getClientDataSecDiscretesOutput(); + base_sec_analog_outputs& getClientDataSecAnalogsOutput(); + base_sec_out_bus& getClientDataSecBusOutput(); - base_fac_discrete_outputs getClientDataFacDiscretesOutput(); - base_fac_analog_outputs getClientDataFacAnalogsOutput(); - base_fac_bus getClientDataFacBusOutput(); + bool setClientDataFacDiscretes(base_fac_discrete_inputs& output); + bool setClientDataFacAnalog(base_fac_analog_inputs& output); + bool setClientDataFacBus(base_fac_bus& output, int facIndex); - bool setClientDataAdr(base_adr_bus output, int adrIndex); - bool setClientDataIr(base_ir_bus output, int irIndex); - bool setClientDataRa(base_ra_bus output, int raIndex); - bool setClientDataLgciu(base_lgciu_bus output, int lgciuIndex); - bool setClientDataSfcc(base_sfcc_bus output, int sfccIndex); - bool setClientDataFmgcB(base_fmgc_b_bus output, int fmgcIndex); + base_fac_discrete_outputs& getClientDataFacDiscretesOutput(); + base_fac_analog_outputs& getClientDataFacAnalogsOutput(); + base_fac_bus& getClientDataFacBusOutput(); + + bool setClientDataAdr(base_adr_bus& output, int adrIndex); + bool setClientDataIr(base_ir_bus& output, int irIndex); + bool setClientDataRa(base_ra_bus& output, int raIndex); + bool setClientDataLgciu(base_lgciu_bus& output, int lgciuIndex); + bool setClientDataSfcc(base_sfcc_bus& output, int sfccIndex); + bool setClientDataFmgcB(base_fmgc_b_bus& output, int fmgcIndex); void setLoggingFlightControlsEnabled(bool enabled); bool getLoggingFlightControlsEnabled(); @@ -395,6 +397,7 @@ class SimConnectInterface { bool loggingThrottlesEnabled = false; SimData simData = {}; + FuelSystemData fuelSystemData = {}; // change to non-static when aileron events can be processed via SimConnect static SimInput simInput; SimInputPitchTrim simInputPitchTrim = {}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp new file mode 100644 index 00000000000..2178045f2d6 --- /dev/null +++ b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FlightDataRecorder.h" + +using namespace mINI; + +void FlightDataRecorder::initialize() { + // create local variables + idIsEnabled = std::make_unique("A32NX_FDR_ENABLED"); + idMaximumFileCount = std::make_unique("A32NX_FDR_MAXIMUM_NUMBER_OF_FILES"); + idMaximumSampleCounter = std::make_unique("A32NX_FDR_MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"); + + // load configuration + loadConfiguration(); + + // print configuration + std::cout << "WASM: Flight Data Recorder Configuration : Enabled = " << idIsEnabled->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfFiles = " << idMaximumFileCount->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : MaximumNumberOfEntriesPerFile = " << idMaximumSampleCounter->get() << std::endl; + std::cout << "WASM: Flight Data Recorder Configuration : Interface Version = " << INTERFACE_VERSION << std::endl; +} + +void FlightDataRecorder::update(const BaseData& baseData, + const AircraftSpecificData& aircraftSpecificData, + Prim (&prims)[3], + Sec (&secs)[3], + Fac (&facs)[2], + const AutopilotStateMachine& autopilotStateMachine, + const AutopilotLawsModelClass& autopilotLaws, + const Autothrust& autoThrust, + const FuelSystemData& fuelSystemData) { + // check if enabled + if (!idIsEnabled->get()) { + return; + } + + // do file management + manageFlightDataRecorderFiles(); + + // write base data + fileStream->write((char*)(&baseData), sizeof(baseData)); + + // write aircraft specific data + fileStream->write((char*)(&aircraftSpecificData), sizeof(aircraftSpecificData)); + + // write PRIM data + for (int i = 0; i < NUMBER_OF_PRIM_TO_WRITE; ++i) { + writePrim(prims[i]); + } + + // write SEC data + for (int i = 0; i < NUMBER_OF_SEC_TO_WRITE; ++i) { + writeSec(secs[i]); + } + + // write Pseudo FACs data + for (int i = 0; i < NUMBER_OF_FAC_TO_WRITE; ++i) { + writeFac(facs[i]); + } + + // write AP state machine data + auto autopilotStateMachineOut = autopilotStateMachine.getExternalOutputs().out; + fileStream->write((char*)(&autopilotStateMachineOut), sizeof(autopilotStateMachineOut)); + + // write AP laws data + auto autopilotLawsOut = autopilotLaws.getExternalOutputs().out; + fileStream->write((char*)(&autopilotLawsOut), sizeof(autopilotLawsOut)); + + // write ATHR data + auto autoThrustOut = autoThrust.getExternalOutputs().out; + fileStream->write((char*)(&autoThrustOut), sizeof(autoThrustOut)); + + // write fuel system data + fileStream->write((char*)(&fuelSystemData), sizeof(fuelSystemData)); +} + +void FlightDataRecorder::writePrim(Prim& prim) { + auto bus_outputs = prim.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = prim.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = prim.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::writeSec(Sec& sec) { + auto bus_outputs = sec.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = sec.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = sec.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::writeFac(Fac& fac) { + auto bus_outputs = fac.getBusOutputs(); + fileStream->write((char*)(&bus_outputs), sizeof(bus_outputs)); + auto discrete_outputs = fac.getDiscreteOutputs(); + fileStream->write((char*)(&discrete_outputs), sizeof(discrete_outputs)); + auto analog_outputs = fac.getAnalogOutputs(); + fileStream->write((char*)(&analog_outputs), sizeof(analog_outputs)); +} + +void FlightDataRecorder::terminate() { + if (fileStream) { + fileStream->close(); + fileStream.reset(); + } + writeConfiguration(); +} + +void FlightDataRecorder::loadConfiguration() { + // read configuration + INIStructure iniStructure; + INIFile iniFile(CONFIGURATION_FILEPATH); + if (!iniFile.read(iniStructure)) { + // file does not exist yet -> store the default configuration in a file + iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = "true"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = "15"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = "864000"; + iniFile.write(iniStructure, true); + } + + // read basic configuration + idIsEnabled->set(INITypeConversion::getBoolean(iniStructure, "FLIGHT_DATA_RECORDER", "ENABLED", true)); + idMaximumFileCount->set(INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_FILES", 15)); + idMaximumSampleCounter->set( + INITypeConversion::getInteger(iniStructure, "FLIGHT_DATA_RECORDER", "MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE", 864000)); +} + +void FlightDataRecorder::writeConfiguration() { + // create ini file + INIFile iniFile(CONFIGURATION_FILEPATH); + + // create structure + INIStructure iniStructure; + iniStructure["FLIGHT_DATA_RECORDER"]["ENABLED"] = idIsEnabled->get() == 1 ? "true" : "false"; + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_FILES"] = idMaximumFileCount->get(); + iniStructure["FLIGHT_DATA_RECORDER"]["MAXIMUM_NUMBER_OF_ENTRIES_PER_FILE"] = idMaximumSampleCounter->get(); + + // write file + iniFile.write(iniStructure, true); +} + +void FlightDataRecorder::manageFlightDataRecorderFiles() { + // increase sample counter + sampleCounter++; + + // check if file is considered full + if (sampleCounter >= idMaximumSampleCounter->get()) { + // close file and delete + if (fileStream) { + fileStream->close(); + fileStream.reset(); + } + // reset counter + sampleCounter = 0; + } + + if (!fileStream) { + // create new file + fileStream = std::make_shared(getFlightDataRecorderFilename().c_str()); + // write version to file + fileStream->write((char*)&INTERFACE_VERSION, sizeof(INTERFACE_VERSION)); + // clean up directory + cleanUpFlightDataRecorderFiles(); + } +} + +std::string FlightDataRecorder::getFlightDataRecorderFilename() { + // get time + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + // get filepath based on time + std::stringstream result; + result << std::put_time(std::gmtime(&in_time_t), "\\work\\%Y-%m-%d-%H-%M-%S.fdr"); + + // return result + return result.str(); +} + +void FlightDataRecorder::cleanUpFlightDataRecorderFiles() { + // std::vector for directory entries + std::vector files; + + // extension + std::string extension = "fdr"; + + // structure representing an directory entry + struct dirent* directoryEntry; + + // open directory + DIR* directory = opendir("\\work"); + + // read directory until end + while ((directoryEntry = readdir(directory)) != NULL) { + // get filename as std::string + std::string filename = directoryEntry->d_name; + + // check if file has right extension + if (filename.find(extension, (filename.length() - extension.length())) != std::string::npos) { + files.push_back(std::move(filename)); + } + } + + // close directory + closedir(directory); + + // sort std::vector + std::sort(files.begin(), files.end(), std::greater<>()); + + // remove older files + while (files.size() > idMaximumFileCount->get()) { + bool result = remove(("\\work\\" + files.back()).c_str()); + files.pop_back(); + } +} diff --git a/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.h b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.h new file mode 100644 index 00000000000..be40e82bad9 --- /dev/null +++ b/fbw-a380x/src/wasm/fbw_a380/src/recording/FlightDataRecorder.h @@ -0,0 +1,63 @@ +#pragma once + +#include + +#include "../fac/Fac.h" +#include "../interface/FuelSystemData.h" +#include "../model/AutopilotLaws.h" +#include "../model/AutopilotStateMachine.h" +#include "../model/Autothrust.h" +#include "../prim/Prim.h" +#include "../sec/Sec.h" +#include "LocalVariable.h" +#include "RecordingDataTypes.h" +#include "zlib/zfstream.h" + +class FlightDataRecorder { + public: + // IMPORTANT: this constant needs to increased with every interface change + const uint64_t INTERFACE_VERSION = 3800001; + + const uint32_t NUMBER_OF_PRIM_TO_WRITE = 3; + const uint32_t NUMBER_OF_SEC_TO_WRITE = 3; + const uint32_t NUMBER_OF_FAC_TO_WRITE = 2; + + void initialize(); + + void update(const BaseData& baseData, + const AircraftSpecificData& aircraftSpecificData, + Prim (&prims)[3], + Sec (&secs)[3], + Fac (&facs)[2], + const AutopilotStateMachine& autopilotStateMachine, + const AutopilotLawsModelClass& autopilotLaws, + const Autothrust& autoThrust, + const FuelSystemData& fuelSystemData); + + void terminate(); + + private: + const std::string CONFIGURATION_FILEPATH = "\\work\\FlightDataRecorder.ini"; + + std::unique_ptr idIsEnabled; + std::unique_ptr idMaximumSampleCounter; + std::unique_ptr idMaximumFileCount; + int sampleCounter = 0; + std::shared_ptr fileStream; + + void manageFlightDataRecorderFiles(); + + std::string getFlightDataRecorderFilename(); + + void cleanUpFlightDataRecorderFiles(); + + void loadConfiguration(); + + void writeConfiguration(); + + void writePrim(Prim& prim); + + void writeSec(Sec& sec); + + void writeFac(Fac& fac); +}; diff --git a/fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h b/fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h new file mode 100644 index 00000000000..f4bc5ea9793 --- /dev/null +++ b/fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h @@ -0,0 +1,94 @@ +#pragma once + +struct BaseData { + double simulation_time_s; + double simulation_delta_time_s; + double simulation_rate; + double simulation_slew_on; + double simulation_was_pause_on; + double aircraft_position_latitude_deg; + double aircraft_position_longitude_deg; + double aircraft_Theta_deg; + double aircraft_Phi_deg; + double aircraft_Psi_magnetic_deg; + double aircraft_Psi_magnetic_track_deg; + double aircraft_Psi_true_deg; + double aircraft_qk_deg_s; + double aircraft_pk_deg_s; + double aircraft_rk_deg_s; + double aircraft_V_indicated_kn; + double aircraft_V_true_kn; + double aircraft_V_ground_kn; + double aircraft_Ma_mach; + double aircraft_alpha_deg; + double aircraft_beta_deg; + double aircraft_H_pressure_ft; + double aircraft_H_indicated_ft; + double aircraft_H_radio_ft; + double aircraft_nz_g; + double aircraft_ax_m_s2; + double aircraft_ay_m_s2; + double aircraft_az_m_s2; + double aircraft_bx_m_s2; + double aircraft_by_m_s2; + double aircraft_bz_m_s2; + double aircraft_eta_pos; + double aircraft_eta_trim_deg; + double aircraft_xi_pos; + double aircraft_zeta_pos; + double aircraft_zeta_trim_pos; + double aircraft_total_air_temperature_deg_celsius; + double aircraft_ice_structure_percent; + double aircraft_dfdr_event_button_pressed; + double atmosphere_ambient_pressure_mbar; + double atmosphere_ambient_wind_velocity_kn; + double atmosphere_ambient_wind_direction_deg; + double simulation_input_sidestick_pitch_pos; + double simulation_input_sidestick_roll_pos; + double simulation_input_rudder_pos; + double simulation_input_brake_pedal_left_pos; + double simulation_input_brake_pedal_right_pos; + double simulation_input_flaps_handle_pos; + double simulation_input_flaps_handle_index; + double simulation_input_spoilers_handle_pos; + double simulation_input_spoilers_are_armed; + double simulation_input_gear_handle_pos; + double simulation_input_tiller_handle_pos; + double simulation_input_parking_brake_switch_pos; + unsigned long long simulation_assistant_is_assisted_takeoff_enabled; + unsigned long long simulation_assistant_is_assisted_landing_enabled; + unsigned long long simulation_assistant_is_ai_automatic_trim_active; + unsigned long long simulation_assistant_is_ai_controls_active; +}; + +struct AircraftSpecificData { + double simulation_input_throttle_lever_1_pos; + double simulation_input_throttle_lever_2_pos; + double simulation_input_throttle_lever_3_pos; + double simulation_input_throttle_lever_4_pos; + double simulation_input_throttle_lever_1_angle; + double simulation_input_throttle_lever_2_angle; + double simulation_input_throttle_lever_3_angle; + double simulation_input_throttle_lever_4_angle; + double aircraft_engine_1_N1_percent; + double aircraft_engine_2_N1_percent; + double aircraft_engine_3_N1_percent; + double aircraft_engine_4_N1_percent; + double aircraft_hydraulic_system_green_pressure_psi; + double aircraft_hydraulic_system_yellow_pressure_psi; + double aircraft_autobrake_system_armed_mode; + double aircraft_autobrake_system_is_decel_light_on; + double aircraft_gear_nosewheel_pos; + double aircraft_gear_nosewheel_compression_percent; + double aircraft_gear_main_left_inner_compression_percent; + double aircraft_gear_main_left_outer_compression_percent; + double aircraft_gear_main_right_inner_compression_percent; + double aircraft_gear_main_right_outer_compression_percent; + double aircraft_is_master_warning_active; + double aircraft_is_master_caution_active; + double aircraft_is_wing_anti_ice_active; + double aircraft_is_alpha_floor_condition_active; + double aircraft_is_high_aoa_protection_active; + unsigned long long aircraft_settings_is_realistic_tiller_enabled; + double aircraft_settings_any_failures_active; +}; diff --git a/fbw-common/src/systems/instruments/src/EFB/Localization/data/en.json b/fbw-common/src/systems/instruments/src/EFB/Localization/data/en.json index 2ca483bd1a4..54af54b25a3 100644 --- a/fbw-common/src/systems/instruments/src/EFB/Localization/data/en.json +++ b/fbw-common/src/systems/instruments/src/EFB/Localization/data/en.json @@ -669,6 +669,7 @@ "ThrottleDetents": "Throttle Detents", "Title": "Sim Options", "UseCalculatedIlsSignals": "Use Calculated ILS Signals", + "FdrEnabled": "Enable Flight Data Recorder (FDR)", "WheelChocksEnabled": "Wheel Chocks", "inHg": "inHg", "SimbridgeMachine": "Simbridge Host Machine", diff --git a/fbw-common/src/systems/instruments/src/EFB/Settings/Pages/SimOptionsPage.tsx b/fbw-common/src/systems/instruments/src/EFB/Settings/Pages/SimOptionsPage.tsx index 16a98457686..f628efe00b6 100644 --- a/fbw-common/src/systems/instruments/src/EFB/Settings/Pages/SimOptionsPage.tsx +++ b/fbw-common/src/systems/instruments/src/EFB/Settings/Pages/SimOptionsPage.tsx @@ -36,6 +36,8 @@ export const SimOptionsPage = () => { const [simbridgeEnabled, setSimbridgeEnabled] = usePersistentProperty('CONFIG_SIMBRIDGE_ENABLED', 'AUTO ON'); const [radioReceiverUsage, setRadioReceiverUsage] = usePersistentProperty('RADIO_RECEIVER_USAGE_ENABLED', '0'); const [, setRadioReceiverUsageSimVar] = useSimVar('L:A32NX_RADIO_RECEIVER_USAGE_ENABLED', 'number', 0); + const [fdrEnabled, setFdrEnabled] = usePersistentProperty('FDR_ENABLED', '1'); + const [, setFdrEnabledSimVar] = useSimVar('L:A32NX_FDR_ENABLED', 'number', 1); const [wheelChocksEnabled, setWheelChocksEnabled] = usePersistentNumberProperty('MODEL_WHEELCHOCKS_ENABLED', 1); const [conesEnabled, setConesEnabled] = usePersistentNumberProperty('MODEL_CONES_ENABLED', 1); const [pilotSeat, setPilotSeat] = usePersistentProperty('CONFIG_PILOT_SEAT', DefaultPilotSeatConfig); @@ -179,6 +181,16 @@ export const SimOptionsPage = () => { /> + + { + setFdrEnabled(value ? '1' : '0'); + setFdrEnabledSimVar(value ? 1 : 0); + }} + /> + + {aircraftContext.settingsPages.sim.wheelChocks && ( (reader: &mut impl Read) -> Result { @@ -58,21 +62,80 @@ fn read_bytes(reader: &mut impl Read) -> Result { // A single FDR record #[derive(Serialize, Default)] struct FdrData { + base: BaseData, + specific: AircraftSpecificData, + elac_1: ElacData, + elac_2: ElacData, + sec_1: SecData, + sec_2: SecData, + sec_3: SecData, + fac_1: FacData, + fac_2: FacData, ap_sm: ap_sm_output, ap_law: ap_raw_output, athr: athr_out, - engine: EngineData, - data: AdditionalData, +} + +#[derive(Serialize, Default)] +struct ElacData { + bus_outputs: base_elac_out_bus, + discrete_outputs: base_elac_discrete_outputs, + analog_outputs: base_elac_analog_outputs, +} + +#[derive(Serialize, Default)] +struct SecData { + bus_outputs: base_sec_out_bus, + discrete_outputs: base_sec_discrete_outputs, + analog_outputs: base_sec_analog_outputs, +} + +#[derive(Serialize, Default)] +struct FacData { + bus_outputs: base_fac_bus, + discrete_outputs: base_fac_discrete_outputs, + analog_outputs: base_fac_analog_outputs, } // These are helper functions to read in a whole FDR record. fn read_record(reader: &mut impl Read) -> Result { Ok(FdrData { + base: read_bytes::(reader)?, + specific: read_bytes::(reader)?, + elac_1: read_elac(reader)?, + elac_2: read_elac(reader)?, + sec_1: read_sec(reader)?, + sec_2: read_sec(reader)?, + sec_3: read_sec(reader)?, + fac_1: read_fac(reader)?, + fac_2: read_fac(reader)?, ap_sm: read_bytes::(reader)?, ap_law: read_bytes::(reader)?, athr: read_bytes::(reader)?, - engine: read_bytes::(reader)?, - data: read_bytes::(reader)?, + }) +} + +fn read_elac(reader: &mut impl Read) -> Result { + Ok(ElacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_sec(reader: &mut impl Read) -> Result { + Ok(SecData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_fac(reader: &mut impl Read) -> Result { + Ok(FacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, }) } diff --git a/tools/fdr2csv/a32nx/wrapper.hpp b/tools/fdr2csv/a32nx/wrapper.hpp new file mode 100644 index 00000000000..da3a8f3d0ea --- /dev/null +++ b/tools/fdr2csv/a32nx/wrapper.hpp @@ -0,0 +1,7 @@ +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotLaws_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotStateMachine_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/ElacComputer_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/FacComputer_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/model/SecComputer_types.h" +#include "../../../fbw-a32nx/src/wasm/fbw_a320/src/recording/RecordingDataTypes.h" diff --git a/tools/fdr2csv/a380x/Cargo.lock b/tools/fdr2csv/a380x/Cargo.lock new file mode 100644 index 00000000000..d470243e894 --- /dev/null +++ b/tools/fdr2csv/a380x/Cargo.lock @@ -0,0 +1,610 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fdr2csv-a380x" +version = "0.1.0" +dependencies = [ + "bindgen", + "bytemuck", + "clap", + "csv", + "fdr2csv_common", + "flate2", + "serde", +] + +[[package]] +name = "fdr2csv_common" +version = "0.1.0" +dependencies = [ + "bindgen", + "bytemuck", + "clap", + "csv", + "flate2", + "serde", +] + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/tools/fdr2csv/a380x/Cargo.toml b/tools/fdr2csv/a380x/Cargo.toml new file mode 100644 index 00000000000..4c9d0fedc89 --- /dev/null +++ b/tools/fdr2csv/a380x/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "fdr2csv-a380x" +version = "0.1.0" +authors = ["FlyByWire Simulations"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +bindgen = "0.69.5" + +[dependencies] +fdr2csv_common = { path = "../common" } + +clap = { version = "4.5.20", features = ["derive"] } +serde = { version = "1.0.213", features = ["derive"] } +bytemuck = { version = "1.19.0", features = ["derive"] } + +csv = "1.3.0" +flate2 = "1.0.30" + +[workspace] diff --git a/tools/fdr2csv/a380x/build.rs b/tools/fdr2csv/a380x/build.rs new file mode 100644 index 00000000000..f92c176c95d --- /dev/null +++ b/tools/fdr2csv/a380x/build.rs @@ -0,0 +1,45 @@ +use std::env; +use std::path::PathBuf; + +use bindgen::callbacks::ParseCallbacks; + +#[derive(Debug)] +struct CustomDeriveCallback {} +impl CustomDeriveCallback { + fn new() -> CustomDeriveCallback { + CustomDeriveCallback {} + } +} +impl ParseCallbacks for CustomDeriveCallback { + fn add_derives(&self, _info: &bindgen::callbacks::DeriveInfo<'_>) -> Vec { + vec!["Serialize".into(), "AnyBitPattern".into(), "Default".into()] + } +} + +fn main() { + // Tell cargo to look for shared libraries in the specified directory + println!("cargo:rustc-link-search=../../fbw-a32nx/src/wasm/fbw_a320/src/model"); + + // The bindgen::Builder is the main entry point + // to bindgen, and lets you build up options for + // the resulting bindings. + let bindings = bindgen::Builder::default() + // The input header we would like to generate + // bindings for. + .header("wrapper.hpp") + .clang_arg("-std=c++20") + // Tell cargo to invalidate the built crate whenever any of the + // included header files changed. + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(CustomDeriveCallback::new())) + // Finish the builder and generate the bindings. + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/tools/fdr2csv/a380x/src/headers.rs b/tools/fdr2csv/a380x/src/headers.rs new file mode 100644 index 00000000000..44988be32a6 --- /dev/null +++ b/tools/fdr2csv/a380x/src/headers.rs @@ -0,0 +1,10 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +use serde::Serialize; + +use bytemuck::AnyBitPattern; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/tools/fdr2csv/a380x/src/main.rs b/tools/fdr2csv/a380x/src/main.rs new file mode 100644 index 00000000000..b7df7b67fe7 --- /dev/null +++ b/tools/fdr2csv/a380x/src/main.rs @@ -0,0 +1,220 @@ +use bytemuck::AnyBitPattern; +use clap::Parser; +use csv::WriterBuilder; +use fdr2csv_common::csv_header_serializer; +use flate2::bufread::GzDecoder; +use headers::{ + ap_raw_output, ap_sm_output, athr_out, base_fac_analog_outputs, base_fac_bus, + base_fac_discrete_outputs, base_prim_analog_outputs, base_prim_discrete_outputs, + base_prim_out_bus, base_sec_analog_outputs, base_sec_discrete_outputs, base_sec_out_bus, + AircraftSpecificData, BaseData, FuelSystemData, +}; +use serde::Serialize; +use std::{ + fs::{File, OpenOptions}, + io::{prelude::*, BufReader, BufWriter, Error, ErrorKind}, + mem, +}; + +mod headers; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// Input file + #[arg(short, long)] + input: String, + /// Output file + #[arg(short, long)] + output: String, + /// Delimiter + #[arg(short, long, default_value = ",")] + delimiter: char, + /// Input file is not compressed + #[arg(short, long, default_value_t = false)] + no_compression: bool, + /// Print struct size + #[arg(short, long, default_value_t = false)] + print_struct_size: bool, + /// Print interface version of input file + #[arg(short, long, default_value_t = false)] + get_input_file_version: bool, +} + +const INTERFACE_VERSION: u64 = 3800001; + +// Read number of bytes specified by the size of T from the binary file +fn read_bytes(reader: &mut impl Read) -> Result { + let size = mem::size_of::(); + + // allocate the buffer that will hold the value read from the binary + let mut buf = vec![0u8; size]; + + // now read from the reader into the buffer + reader.read_exact(&mut buf)?; + + // If the read was successful, reinterpret the bytes as the struct, and return + let res = bytemuck::from_bytes::(buf.as_slice()); + + Ok(*res) +} + +// A single FDR record +#[derive(Serialize, Default)] +struct FdrData { + base: BaseData, + specific: AircraftSpecificData, + prim_1: PrimData, + prim_2: PrimData, + prim_3: PrimData, + sec_1: SecData, + sec_2: SecData, + sec_3: SecData, + fac_1: FacData, + fac_2: FacData, + ap_sm: ap_sm_output, + ap_law: ap_raw_output, + athr: athr_out, + fuel: FuelSystemData, +} + +#[derive(Serialize, Default)] +struct PrimData { + bus_outputs: base_prim_out_bus, + discrete_outputs: base_prim_discrete_outputs, + analog_outputs: base_prim_analog_outputs, +} + +#[derive(Serialize, Default)] +struct SecData { + bus_outputs: base_sec_out_bus, + discrete_outputs: base_sec_discrete_outputs, + analog_outputs: base_sec_analog_outputs, +} + +#[derive(Serialize, Default)] +struct FacData { + bus_outputs: base_fac_bus, + discrete_outputs: base_fac_discrete_outputs, + analog_outputs: base_fac_analog_outputs, +} + +// These are helper functions to read in a whole FDR record. +fn read_record(reader: &mut impl Read) -> Result { + Ok(FdrData { + base: read_bytes::(reader)?, + specific: read_bytes::(reader)?, + prim_1: read_prim(reader)?, + prim_2: read_prim(reader)?, + prim_3: read_prim(reader)?, + sec_1: read_sec(reader)?, + sec_2: read_sec(reader)?, + sec_3: read_sec(reader)?, + fac_1: read_fac(reader)?, + fac_2: read_fac(reader)?, + ap_sm: read_bytes::(reader)?, + ap_law: read_bytes::(reader)?, + athr: read_bytes::(reader)?, + fuel: read_bytes::(reader)?, + }) +} + +fn read_prim(reader: &mut impl Read) -> Result { + Ok(PrimData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_sec(reader: &mut impl Read) -> Result { + Ok(SecData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn read_fac(reader: &mut impl Read) -> Result { + Ok(FacData { + bus_outputs: read_bytes::(reader)?, + discrete_outputs: read_bytes::(reader)?, + analog_outputs: read_bytes::(reader)?, + }) +} + +fn main() -> Result<(), std::io::Error> { + // Parse CLI arguments + let args = Args::parse(); + + // Open the input file + let in_file = File::open(args.input.trim()) + .map_err(|e| std::io::Error::new(e.kind(), "Failed to open input file!"))?; + + // Create Gzip Reader + let mut reader: Box = if args.no_compression { + Box::new(BufReader::new(in_file)) + } else { + Box::new(GzDecoder::new(BufReader::new(in_file))) + }; + + // Read file version + let file_format_version = read_bytes::(&mut reader)?; + + // Print or check file version + if args.get_input_file_version { + println!("Interface version is {}", file_format_version); + return Ok(()); + } else if INTERFACE_VERSION != file_format_version { + return Err(std::io::Error::new( + ErrorKind::InvalidInput, + format!( + "Mismatch between converter and file version (expected {INTERFACE_VERSION}, got {file_format_version})", + ), + )); + } + + // Print info on conversion start + println!( + "Converting from '{}' to '{}' with interface version '{}' and delimiter '{}'", + args.input, args.output, file_format_version, args.delimiter + ); + + // Open or create output file in truncate mode + let out_file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(args.output.trim()) + .map_err(|e| std::io::Error::new(e.kind(), "Failed to open output file!"))?; + + let mut buf_writer = BufWriter::new(out_file); + + let mut counter = 0; + + // Generate and write the header + let header = csv_header_serializer::to_string(&FdrData::default(), args.delimiter) + .map_err(|_| std::io::Error::new(ErrorKind::Other, "Failed to generate header."))?; + buf_writer.write(header.as_bytes())?; + + // Create the CSV writer, and serialize the file. + let mut writer = WriterBuilder::new() + .delimiter(args.delimiter as u8) + .has_headers(false) + .from_writer(buf_writer); + + while let Ok(fdr_data) = read_record(&mut reader) { + writer.serialize(&fdr_data)?; + + counter += 1; + + if counter % 1000 == 0 { + print!("Processed {counter} entries...\r"); + std::io::stdout().flush()?; + } + } + + println!("Processed {counter} entries..."); + + Result::Ok(()) +} diff --git a/tools/fdr2csv/a380x/wrapper.hpp b/tools/fdr2csv/a380x/wrapper.hpp new file mode 100644 index 00000000000..7d0889a4d2c --- /dev/null +++ b/tools/fdr2csv/a380x/wrapper.hpp @@ -0,0 +1,8 @@ +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/interface/FuelSystemData.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/A380PrimComputer_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/A380SecComputer_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotLaws_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/AutopilotStateMachine_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/Autothrust_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/model/FacComputer_types.h" +#include "../../../fbw-a380x/src/wasm/fbw_a380/src/recording/RecordingDataTypes.h" diff --git a/tools/fdr2csv/Cargo.toml b/tools/fdr2csv/common/Cargo.toml similarity index 52% rename from tools/fdr2csv/Cargo.toml rename to tools/fdr2csv/common/Cargo.toml index aad3c088dd5..9a1dfd67d30 100644 --- a/tools/fdr2csv/Cargo.toml +++ b/tools/fdr2csv/common/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fdr2csv" +name = "fdr2csv_common" version = "0.1.0" authors = ["FlyByWire Simulations"] edition = "2021" @@ -7,14 +7,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -bindgen = "0.69.4" +bindgen = "0.69.5" [dependencies] -clap = { version = "4.5.9", features = ["derive"] } -serde = { version = "1.0.204", features = ["derive"] } -bytemuck = { version = "1.16.1", features = ["derive"] } +clap = { version = "4.5.20", features = ["derive"] } +serde = { version = "1.0.213", features = ["derive"] } +bytemuck = { version = "1.19.0", features = ["derive"] } csv = "1.3.0" -flate2 = "1.0.30" +flate2 = "1.0.34" [workspace] diff --git a/tools/fdr2csv/src/csv_header_serializer.rs b/tools/fdr2csv/common/src/csv_header_serializer.rs similarity index 100% rename from tools/fdr2csv/src/csv_header_serializer.rs rename to tools/fdr2csv/common/src/csv_header_serializer.rs diff --git a/tools/fdr2csv/src/error.rs b/tools/fdr2csv/common/src/error.rs similarity index 100% rename from tools/fdr2csv/src/error.rs rename to tools/fdr2csv/common/src/error.rs diff --git a/tools/fdr2csv/common/src/lib.rs b/tools/fdr2csv/common/src/lib.rs new file mode 100644 index 00000000000..1a7058da99b --- /dev/null +++ b/tools/fdr2csv/common/src/lib.rs @@ -0,0 +1,2 @@ +pub mod csv_header_serializer; +pub mod error; diff --git a/tools/fdr2csv/wrapper.hpp b/tools/fdr2csv/wrapper.hpp deleted file mode 100644 index 93959ded83a..00000000000 --- a/tools/fdr2csv/wrapper.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../../fbw-a32nx/src/wasm/fbw_a320/src/EngineData.h" -#include "../../fbw-a32nx/src/wasm/fbw_a320/src/AdditionalData.h" -#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotLaws_types.h" -#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/AutopilotStateMachine_types.h" -#include "../../fbw-a32nx/src/wasm/fbw_a320/src/model/Autothrust_types.h"