diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 7e5f267f498..9d55c57105b 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -10,11 +10,24 @@ 1. [ADIRU] Implemented wind speed computation from TAS/GS/HDG - @tracernz (Mike) 1. [FMGC] Show proper transition names and final approach slope from AAU1 - @tracernz (Mike) 1. [FMGC] Don't accept blank input or / for hold distance - @tracernz (Mike) +1. [HYD] Faster core hydraulics solver - @Crocket63 (crocket) 1. [ATSU] Fix LSK6L not returning to ATSU DATALINK page in ATC MENU - @BravoMike99 (Bruno_pt99#5802) 1. [HYD] Trimmable physical assemblies - @Crocket63 (crocket) 1. [HYD] Simulation of the rudder mechanical assembly and yaw dampers - @Crocket63 (crocket) +1. [HYD] Simple temperature simulation - @Crocket63 (crocket) 1. [FLIGHTMODEL] Reduced flap induced drag - @donstim (donbikes#4084) 1. [EFB] Fix and improve pushback system and add API documentation - @frankkopp (Frank Kopp) +1. [RMP] RMPs navigation backup - Julian Sebline (Julian Sebline#8476 on Discord) +1. [SEC] Fix GND SPLR logic, add missing GND SPLR partial extension condition - @lukecologne (luke) +1. [FMGC] Improved importing flight plans from MSFS World Map - @frankkopp (Frank Kopp) +1. [EFB] Added boarding time indication to Payload page - @ChristianLutzCL (Christian Lutz) @frankkopp (Frank Kopp) +1. [EFB] Show correct runway numbers in landing calculator's runway widget when heading is between 0-5 degrees - @2hwk (2Cas#1022) +1. [ADIRU/ND/PFD] Initial support for polar navigation - @tracernz (Mike) +1. [FLIGHTMODEL] Update gear drag - @donstim (donbikes#4084) +1. [FLIGHT MODEL/EFB] Modified empty weight cg and loading station/fuel tank locations - @donstim (donbikes#4084) +1. [HYD] Fix gear sequence starting when failing prox sensor - @Crocket63 (crocket) +1. [MISC] Added aircraft version check and uer notification - @frankkopp (Frank Kopp) +1. [EFB] Allow payload page passenger seating to be manipulated by external apps & WASM via LocalVars - @2hwk (2Cas#1022) ## 0.9.0 @@ -70,6 +83,7 @@ 1. [FMGC] Fix inbound leg time for holds - @tracernz (Mike) 1. [MCDU] Improved visuals of Init-A and Init-B page - @derl30n (Leon) 1. [MODEL] Added new animated gear gravity extension handle- @tyler58546 (tyler58546), @MoreRightRudder (Mike), @Crocket63 (crocket), @Lantarius +1. [HYD] Custom Lvar for gear lever to fix ground collision bug - @Crocket63 (crocket) 1. [HYD] Randomised per actuator flow restrictions at plane init - @Crocket63 (crocket) 1. [MCDU] Hide stored elements on A/C Status when there are none - @tracernz (Mike) 1. [FMGC] Fix ident for CD legs - @tracernz (Mike) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index b495948338f..2e447ba35f9 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -89,6 +89,12 @@ jobs: run: | ./scripts/cdn.sh $BUNNY_BUCKET_DESTINATION ./build-modules ./scripts/cdn.sh $BUNNY_BUCKET_DESTINATION ./${{ env.BUILD_DIR_NAME }} + - name: Upload to CloudFlare CDN + env: + CLOUDFLARE_BUCKET_PASSWORD: ${{ secrets.CLOUDFLARE_BUCKET_PASSWORD }} + CDN_BUCKET_DESTINATION: addons/a32nx/master + run: | + ./scripts/cf-cdn.sh $CDN_BUCKET_DESTINATION ./build-modules - name: Delete old GitHub Pre-Release assets uses: mknejp/delete-release-assets@v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f7d92ef3e2..9d594385774 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,6 +66,12 @@ jobs: run: | ./scripts/cdn.sh $BUNNY_BUCKET_DESTINATION ./build-modules ./scripts/cdn.sh $BUNNY_BUCKET_DESTINATION ./${{ env.BUILD_DIR_NAME }} + - name: Upload to CloudFlare CDN + env: + CLOUDFLARE_BUCKET_PASSWORD: ${{ secrets.CLOUDFLARE_BUCKET_PASSWORD }} + CDN_BUCKET_DESTINATION: addons/a32nx/stable + run: | + ./scripts/cf-cdn.sh $CDN_BUCKET_DESTINATION ./build-modules - name: Delete old GitHub Pre-Release assets uses: mknejp/delete-release-assets@v1 with: diff --git a/.vscode/launch.json b/.vscode/launch.json index ccffc7571e3..f56365c72cc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -44,6 +44,18 @@ "y:/external/src/": "${workspaceFolder}/src/", "z:/external/src/": "${workspaceFolder}/src/", } + }, + { + "name": "Rust Test Debugger", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/target/debug/", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": true, + "preLaunchTask": "cargo test build", } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ac6e2eef097..4bf778ed782 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -36,6 +36,19 @@ "kind": "build", "isDefault": true } + }, + { + "label": "Build Rust Tests", + "type": "shell", + "command": "cargo test build", + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } } ] } diff --git a/Cargo.lock b/Cargo.lock index 793f28bc77c..9f683563b4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -944,6 +944,7 @@ dependencies = [ name = "systems" version = "0.1.0" dependencies = [ + "bitflags", "bounded-vec-deque", "fxhash", "nalgebra", diff --git a/docs/a320-simvars.md b/docs/a320-simvars.md index 3989c608e45..ab66a6809f5 100644 --- a/docs/a320-simvars.md +++ b/docs/a320-simvars.md @@ -392,6 +392,10 @@ - Number - The current mode of the right radio management panel. +- A32NX_RMP_{L,R}_NAV_BUTTON_SELECTED + - Bool + - Whether the NAV push button on the corresponding RMP is pushed or not. + - A32NX_RMP_L_VHF2_STANDBY - Hz - The VHF 2 standby frequency for the left RMP. @@ -408,6 +412,42 @@ - Hz - The VHF 3 standby frequency for the right RMP. +- A32NX_RMP_{L,R}_SAVED_ACTIVE_FREQUENCY_VOR + - Hz + - The VOR active frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_ACTIVE_FREQUENCY_ILS + - Hz + - The ILS active frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_ACTIVE_FREQUENCY_ADF + - Hz + - The ADF active frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_STANDBY_FREQUENCY_VOR + - Hz + - The VOR standby frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_STANDBY_FREQUENCY_ILS + - Hz + - The ILS standby frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_STANDBY_FREQUENCY_ADF + - Hz + - The ADF standby frequency that is saved for display for the left/right RMP. + +- A32NX_RMP_{L,R}_SAVED_COURSE_VOR + - Number + - The VOR course tuned via the left/right RMP + +- A32NX_RMP_{L,R}_SAVED_COURSE_ILS + - Number + - The ILS course tuned via the left/right RMP + +- A32NX_RMP_ILS_TUNED + - Bool + - If the ILS is tuned via the RMP + - A32NX_TO_CONFIG_FLAPS_ENTERED - Bool - True if the pilot has entered a FLAPS value in the PERF TAKE OFF takeoff @@ -809,6 +849,14 @@ - BLUE - YELLOW +- A32NX_HYD_{loop_name}_RESERVOIR_OVHT + - Boolean + - Reservoir of {loop_name} hydraulic circuit is overheating + - {loop_name} + - GREEN + - BLUE + - YELLOW + - A32NX_HYD_{loop_name}_EDPUMP_ACTIVE - Bool - Engine driven pump of {loop_name} hydraulic circuit is active @@ -888,6 +936,13 @@ - BLUE - YELLOW +- A32NX_HYD_{loop_name}_EPUMP_OVHT + - Bool + - Electric pump of {loop_name} hydraulic circuit is overheating + - {loop_name} + - BLUE + - YELLOW + - A32NX_HYD_{loop_name}_PUMP_1_FIRE_VALVE_OPENED - Bool - Engine driven pump of {loop_name} hydraulic circuit can receive hydraulic fluid @@ -1032,6 +1087,15 @@ GOAROUND | 6 DONE | 7 +- A32NX_FMGC_RADIONAV_TUNING_MODE + - Enum + - Hold the FMGCs current tuning mode + Value | Meaning + --- | --- + 0 | AUTO + 1 | MANUAL + 2 | REMOTE VIA RMPs + - A32NX_FLAPS_HANDLE_INDEX - Number - Indicates the physical flaps handle position @@ -1336,23 +1400,28 @@ - 2 - 3 -- A32NX_PAX_TOTAL_ROWS_{rows} - - Number - - Indicates the current number of pax in the selected rows - - {rows} - - 1_6 - - 7_13 - - 14_21 - - 22_29 +- A32NX_BOARDING_STARTED_BY_USR + - Bool + - Indicates current pax/cargo loading state -- A32NX_PAX_TOTAL_ROWS_{rows}_DESIRED - - Number - - Indicates the target number of pax in the selected rows +- A32NX_PAX_FLAGS_{station} + - Bitwise + - Indicates the current pax in the selected rows (max 53 bits) + - Read-Only! + - {station} + - A + - B + - C + - D + +- A32NX_PAX_FLAGS_{station}_DESIRED + - Bitwise + - Indicates the target number of pax in the selected rows (max 53 bits) - {rows} - - 1_6 - - 7_13 - - 14_21 - - 22_29 + - A + - B + - C + - D - PAYLOAD STATION WEIGHT:{stationIndex} - Number (Kilograms) @@ -1432,6 +1501,7 @@ In the variables below, {number} should be replaced with one item in the set: { - 0 is CAPT, 1 is NORM, 2 is F/O - A32NX_ADIRS_ADIRU_{number}_STATE + - Deprecated: use A32NX_ADIRS_IR_{number}_MAINT_WORD instead. - Enum - The Inertial Reference alignment state. Description | Value @@ -1441,6 +1511,7 @@ In the variables below, {number} should be replaced with one item in the set: { Aligned | 2 - A32NX_ADIRS_REMAINING_IR_ALIGNMENT_TIME + - Deprecated: use A32NX_ADIRS_IR_{number}_MAINT_WORD instead. - Seconds - The remaining alignment duration. Zero seconds when the system is aligned or the system is not aligning. @@ -1494,7 +1565,7 @@ In the variables below, {number} should be replaced with one item in the set: { - A32NX_ADIRS_IR_{number}_HEADING - Arinc429Word - - The inertial heading of the aircraft. + - The magnetic heading of the aircraft (true in polar region). - A32NX_ADIRS_IR_{number}_TRUE_HEADING - Arinc429Word @@ -1502,7 +1573,7 @@ In the variables below, {number} should be replaced with one item in the set: { - A32NX_ADIRS_IR_{number}_TRACK - Arinc429Word - - The inertial track of the aircraft. + - The magnetic track of the aircraft (true in polar region). - A32NX_ADIRS_IR_{number}_TRUE_TRACK - Arinc429Word @@ -1588,10 +1659,44 @@ In the variables below, {number} should be replaced with one item in the set: { - Arinc429Word - The roll rate (φ^dot) of the aircraft +- A32NX_ADIRS_IR_{number}_MAINT_WORD + - Arinc429Word + - Indicates state of the IR + Bit | Meaning + --- | --- + 0 | ALIGNMENT_NOT_READY + 1 | REV_ATT_MODE + 2 | NAV_MODE + 3 | VALID_SET_HEADING + 4 | ATTITUDE_INVALID + 5 | DC_FAIL + 6 | ON_DC + 7 | ADR_FAULT + 8 | IR_FAULT + 9 | DC_FAIL_ON_DC + 10 | ALIGN_FAULT + 11 | NO_IRS_INITIAL + 12 | EXCESS_MOTION_ERROR + 13 | ADR_IR_FAULT + 14 | EXTREME_LATITUDE + 15,16,17 | ALIGN_7_10_MINUTES + 16,17 | ALIGN_6_MINUTES + 15,17 | ALIGN_5_MINUTES + 16 | ALIGN_4_MINUTES + 15,16 | ALIGN_3_MINUTES + 16 | ALIGN_2_MINUTES + 15 | ALIGN_1_MINUTES + 18 | COMPUTED_LATITUDE_MISCOMPARE + - A32NX_ADIRS_USES_GPS_AS_PRIMARY + - Deprecated, this is an FM function, not ADIRU - Bool - Whether or not the GPS is used as the primary means of navigation/position determination. +- A32NX_PUSH_TRUE_REF + - Bool + - True reference pushbutton status + ## Radio Receivers - A32NX_RADIO_RECEIVER_USAGE_ENABLED @@ -3225,6 +3330,18 @@ In the variables below, {number} should be replaced with one item in the set: { - Indicates the position of the gear emergency extension crank handle from 0 to 300 (3 turns) - Percent +- A32NX_GEAR_LEVER_POSITION_REQUEST + - Indicates that the pilot tries to move the gear lever (1=down) + - Boolean + +- A32NX_GEAR_HANDLE_POSITION + - Indicates the actual position of the gear handle + - Percent over 100 + +- A32NX_GEAR_HANDLE_HITS_LOCK_SOUND + - Indicates that gear lever just hit the baulk lock mechanism + - Boolean + ## ATC (ATA 34) - A32NX_TRANSPONDER_MODE @@ -3330,13 +3447,13 @@ In the variables below, {number} should be replaced with one item in the set: { - Boolean - Read/Write - Whether the pushback system is enabled - - Further conditions are "Pushback Tug Attached" and "Aircraft On Ground" otherwise the system + - Further conditions are "Pushback Tug Attached" and "Aircraft On Ground" otherwise the system has no impact on the aircraft - A32NX_PUSHBACK_SPD_FACTOR - Number - Read/Write - - Determines the speed of the pushback tug from -100% to 100% + - Determines the speed of the pushback tug from -100% to 100% - {number} - -1.0 - 1.0 @@ -3344,7 +3461,7 @@ In the variables below, {number} should be replaced with one item in the set: { - A32NX_PUSHBACK_HDG_FACTOR - Number - Read/Write - - Determines the heading of the pushback tug from max left (-1.0) to right (1.0) + - Determines the heading of the pushback tug from max left (-1.0) to right (1.0) - {number} - -1.0 - 1.0 diff --git a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml index 1a588a89957..597b7138f55 100644 --- a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml +++ b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/Airbus.xml @@ -145,7 +145,8 @@ PUSH_ECAM_#BASE_NAME# PUSH_ECAM_#BASE_NAME#_SEQ2 PUSH_ECAM_#BASE_NAME#_SEQ1 - A320_Neo_EICAS_2_ECAM_CHANGE_PAGE_#BASE_NAME# + + A32NX_SD_PAGE_CHANGED A32NX_ECAM_SD_CURRENT_PAGE_INDEX mcdubuttons 0.1 @@ -160,9 +161,12 @@ #ANIM_NAME_BUTTON# - #GROUP_INDEX# -1 > if{ - (>H:#EVENT_NAME#) #GROUP_INDEX# + (L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) #GROUP_INDEX# != if{ + #GROUP_INDEX# (>L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) + } els{ + -1 (>L:A32NX_ECAM_SD_CURRENT_PAGE_INDEX) } + (>H:A32NX_SD_PAGE_CHANGED) diff --git a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/AirlinerCommon.xml b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/AirlinerCommon.xml index cf366cabd1c..2dc26f20905 100644 --- a/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/AirlinerCommon.xml +++ b/flybywire-aircraft-a320-neo/ModelBehaviorDefs/A32NX/AirlinerCommon.xml @@ -278,8 +278,11 @@ 1 0.04 0.01 + 0.02 AIRLINER - 1 + (L:A32NX_ELEC_DC_ESS_BUS_IS_POWERED, Bool) + (L:A32NX_ELEC_DC_ESS_BUS_IS_POWERED, Bool) + (L:A32NX_ELEC_DC_ESS_BUS_IS_POWERED, Bool) @@ -318,6 +321,7 @@ #PREFIX#_AudioReceiver_Push_mic_call_03#SUFFIX_ID# #PREFIX#_AudioReceiver_Push_mic_call_03_SEQ1#SUFFIX_ID# #PREFIX#_AudioReceiver_Push_mic_call_03_SEQ2#SUFFIX_ID# + #PREFIX#_AudioReceiver_Knob_MKR_LED#SUFFIX_ID# False @@ -396,6 +400,267 @@ TT:COCKPIT.TOOLTIPS.TRANSMITTER_VHF_R_AUDIO_TOGGLE TT:COCKPIT.TOOLTIPS.TRANSMITTER_SELECT_VHF_R + + + BUTTON + #NODE_ID_RECEIVER_VOICE# + #ANIM_NAME_PUSH_RECEIVER_VOICE# + #NODE_ID_BUTTON_VOICE_SEQ1# + #NODE_ID_BUTTON_VOICE_SEQ2# + + (L:XMLVAR_NAV_#SIDE#_VOICE_Switch_Down) ! (>L:XMLVAR_NAV_#SIDE#_VOICE_Switch_Down) + (L:XMLVAR_NAV_L_VOICE_Switch_Down) (L:XMLVAR_NAV_R_VOICE_Switch_Down) or (>L:XMLVAR_NAV_VOICE_Switch_Down) + + (L:XMLVAR_NAV_VOICE_Switch_Down) 0 == if{ + (L:XMLVAR_NAV_L_VOR1_Switch_Down) (L:XMLVAR_NAV_R_VOR1_Switch_Down) or if{ + 1 (>K:RADIO_VOR1_IDENT_ENABLE) + 1 (>K:RADIO_DME1_IDENT_ENABLE) + } + (L:XMLVAR_NAV_L_VOR2_Switch_Down) (L:XMLVAR_NAV_R_VOR2_Switch_Down) or if{ + 1 (>K:RADIO_VOR2_IDENT_ENABLE) + 1 (>K:RADIO_DME2_IDENT_ENABLE) + } + + (L:XMLVAR_NAV_L_ADF1_Switch_Down) (L:XMLVAR_NAV_R_ADF1_Switch_Down) or if{ + 1 (>K:RADIO_ADF_IDENT_ENABLE) + } + (L:XMLVAR_NAV_L_ADF2_Switch_Down) (L:XMLVAR_NAV_R_ADF2_Switch_Down) or if{ + 1 (>K:RADIO_ADF2_IDENT_ENABLE) + } + } + + (L:XMLVAR_NAV_VOICE_Switch_Down) 1 == if{ + 1 (>K:RADIO_VOR1_IDENT_DISABLE) + 1 (>K:RADIO_VOR2_IDENT_DISABLE) + 1 (>K:RADIO_ADF_IDENT_DISABLE) + 1 (>K:RADIO_ADF2_IDENT_DISABLE) + + 1 (>K:RADIO_DME1_IDENT_DISABLE) + 1 (>K:RADIO_DME2_IDENT_DISABLE) + } + + fcubutton + 0.1 + fcubutton + 0.5 + (L:XMLVAR_NAV_#SIDE#_VOICE_Switch_Down) + %((L:XMLVAR_NAV_#SIDE#_VOICE_Switch_Down))%{if}TT:COCKPIT.TOOLTIPS.NAV_PUSHBUTTON_VOICE_OFF%{else}TT:COCKPIT.TOOLTIPS.NAV_PUSHBUTTON_VOICE_ON%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_VOR1# + #NODE_ID_LIGHT_RECEIVER_VOR1# + #ANIM_NAME_KNOB_RECEIVER_VOR1# + #ANIM_NAME_PUSH_RECEIVER_VOR1# + VOR1 + + + (L:XMLVAR_NAV_VOICE_Switch_Down) 0 == if{ + (A:NAV SOUND:1, Bool) 1 == (L:XMLVAR_NAV_L_VOR1_Switch_Down) 0 == (L:XMLVAR_NAV_R_VOR1_Switch_Down) 0 == and and if{ + 1 (>K:RADIO_VOR1_IDENT_TOGGLE) + 1 (>K:RADIO_DME1_IDENT_SET) + } + + (A:NAV SOUND:1, Bool) 0 == (L:XMLVAR_NAV_L_VOR1_Switch_Down) 1 == (L:XMLVAR_NAV_R_VOR1_Switch_Down) 1 == or and if{ + 1 (>K:RADIO_VOR1_IDENT_TOGGLE) + 1 (>K:RADIO_DME1_IDENT_SET) + } + } + + + + (L:XMLVAR_NAV_#SIDE#_VOR1_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_VOR1_Volume) + (L:XMLVAR_NAV_#SIDE#_VOR1_Volume) (A:NAV VOLUME:1, percent over 100) > if{ + 1 (>K:NAV1_VOLUME_INC) + } + + + (L:XMLVAR_NAV_#SIDE#_VOR1_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_VOR1_Volume) + (L:XMLVAR_NAV_L_VOR1_Volume) (L:XMLVAR_NAV_R_VOR1_Volume) max (A:NAV VOLUME:1, percent over 100) < if{ + 1 (>K:NAV1_VOLUME_DEC) + } + + TT:COCKPIT.TOOLTIPS.TRANSMITTER_VOR1_VOLUME_DEC + TT:COCKPIT.TOOLTIPS.TRANSMITTER_VOR1_VOLUME_INC + %((L:XMLVAR_NAV_#SIDE#_VOR1_Switch_Down))%{if}TT:INPUT.KEY_RADIO_VOR1_IDENT_DISABLE_DESC%{else}TT:INPUT.KEY_RADIO_VOR1_IDENT_ENABLE_DESC%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_VOR2# + #NODE_ID_LIGHT_RECEIVER_VOR2# + #ANIM_NAME_KNOB_RECEIVER_VOR2# + #ANIM_NAME_PUSH_RECEIVER_VOR2# + VOR2 + + + (L:XMLVAR_NAV_VOICE_Switch_Down) 0 == if{ + (A:NAV SOUND:2, Bool) 1 == (L:XMLVAR_NAV_L_VOR2_Switch_Down) 0 == (L:XMLVAR_NAV_R_VOR2_Switch_Down) 0 == and and if{ + 1 (>K:RADIO_VOR2_IDENT_TOGGLE) + 1 (>K:RADIO_DME2_IDENT_SET) + } + + (A:NAV SOUND:2, Bool) 0 == (L:XMLVAR_NAV_L_VOR2_Switch_Down) 1 == (L:XMLVAR_NAV_R_VOR2_Switch_Down) 1 == or and if{ + 1 (>K:RADIO_VOR2_IDENT_TOGGLE) + 1 (>K:RADIO_DME2_IDENT_SET) + } + } + + + + (L:XMLVAR_NAV_#SIDE#_VOR2_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_VOR2_Volume) + (L:XMLVAR_NAV_#SIDE#_VOR2_Volume) (A:NAV VOLUME:2, percent over 100) > if{ + 1 (>K:NAV2_VOLUME_INC) + } + + + (L:XMLVAR_NAV_#SIDE#_VOR2_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_VOR2_Volume) + (L:XMLVAR_NAV_L_VOR2_Volume) (L:XMLVAR_NAV_R_VOR2_Volume) max (A:NAV VOLUME:2, percent over 100) < if{ + 1 (>K:NAV2_VOLUME_DEC) + } + + TT:COCKPIT.TOOLTIPS.TRANSMITTER_VOR2_VOLUME_DEC + TT:COCKPIT.TOOLTIPS.TRANSMITTER_VOR2_VOLUME_INC + %((L:XMLVAR_NAV_#SIDE#_VOR2_Switch_Down))%{if}TT:INPUT.KEY_RADIO_VOR2_IDENT_DISABLE_DESC%{else}TT:INPUT.KEY_RADIO_VOR2_IDENT_ENABLE_DESC%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_MKR# + #NODE_ID_LIGHT_RECEIVER_MKR# + #ANIM_NAME_KNOB_RECEIVER_MKR# + #ANIM_NAME_PUSH_RECEIVER_MKR# + #NODE_ID_LED_RECEIVER_MKR# + MKR + + (A:MARKER SOUND, Bool) 1 == (L:XMLVAR_NAV_L_MKR_Switch_Down) 0 == (L:XMLVAR_NAV_R_MKR_Switch_Down) 0 == and and if{ + 1 (>K:MARKER_SOUND_TOGGLE) + } + + (A:MARKER SOUND, Bool) 0 == (L:XMLVAR_NAV_L_MKR_Switch_Down) 1 == (L:XMLVAR_NAV_R_MKR_Switch_Down) 1 == or and if{ + 1 (>K:MARKER_SOUND_TOGGLE) + } + + + (L:XMLVAR_NAV_#SIDE#_MKR_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_MKR_Volume) + (L:XMLVAR_NAV_#SIDE#_MKR_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_MKR_Volume) + TT:COCKPIT.TOOLTIPS.NAV_KNOB_MARKERS_VOLUME_DECREASE + TT:COCKPIT.TOOLTIPS.NAV_KNOB_MARKERS_VOLUME_INCREASE + %((L:XMLVAR_NAV_#SIDE#_MKR_Switch_Down))%{if}TT:COCKPIT.TOOLTIPS.NAV_KNOB_MARKERS_IDENT_DISABLE%{else}TT:COCKPIT.TOOLTIPS.NAV_KNOB_MARKERS_IDENT_ENABLE%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_ILS# + #NODE_ID_LIGHT_RECEIVER_ILS# + #ANIM_NAME_KNOB_RECEIVER_ILS# + #ANIM_NAME_PUSH_RECEIVER_ILS# + #NODE_ID_LED_RECEIVER_ILS# + ILS + + + + (L:XMLVAR_NAV_#SIDE#_ILS_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_ILS_Volume) + (L:XMLVAR_NAV_#SIDE#_ILS_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_ILS_Volume) + TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_VOLUME_DECREASE + TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_VOLUME_INCREASE + %((L:XMLVAR_NAV_#SIDE#_ILS_Switch_Down))%{if}TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_IDENT_DISABLE%{else}TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_IDENT_ENABLE%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_MLS# + #NODE_ID_LIGHT_RECEIVER_MLS# + #ANIM_NAME_KNOB_RECEIVER_MLS# + #ANIM_NAME_PUSH_RECEIVER_MLS# + #NODE_ID_LED_RECEIVER_MLS# + MLS + + + + (L:XMLVAR_NAV_#SIDE#_MLS_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_MLS_Volume) + (L:XMLVAR_NAV_#SIDE#_MLS_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_MLS_Volume) + TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_VOLUME_DECREASE + TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_VOLUME_INCREASE + %((L:XMLVAR_NAV_#SIDE#_MLS_Switch_Down))%{if}TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_IDENT_DISABLE%{else}TT:COCKPIT.TOOLTIPS.NAV_KNOB_ILS_IDENT_ENABLE%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_ADF1# + #NODE_ID_LIGHT_RECEIVER_ADF1# + #ANIM_NAME_KNOB_RECEIVER_ADF1# + #ANIM_NAME_PUSH_RECEIVER_ADF1# + #NODE_ID_LED_RECEIVER_ADF1# + ADF1 + + + (L:XMLVAR_NAV_VOICE_Switch_Down) 0 == if{ + (A:ADF SOUND, Bool) 1 == (L:XMLVAR_NAV_L_ADF1_Switch_Down) 0 == (L:XMLVAR_NAV_R_ADF1_Switch_Down) 0 == and and if{ + 1 (>K:RADIO_ADF_IDENT_DISABLE) + } + + (A:ADF SOUND, Bool) 0 == (L:XMLVAR_NAV_L_ADF1_Switch_Down) 1 == (L:XMLVAR_NAV_R_ADF1_Switch_Down) 1 == or and if{ + 1 (>K:RADIO_ADF_IDENT_ENABLE) + } + } + + + + (L:XMLVAR_NAV_#SIDE#_ADF1_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_ADF1_Volume) + (L:XMLVAR_NAV_#SIDE#_ADF1_Volume) (A:ADF VOLUME:1, percent over 100) > if{ + 1 (>K:ADF_VOLUME_INC) + } + + + (L:XMLVAR_NAV_#SIDE#_ADF1_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_ADF1_Volume) + (L:XMLVAR_NAV_L_ADF1_Volume) (L:XMLVAR_NAV_R_ADF1_Volume) max (A:ADF VOLUME:1, percent over 100) < if{ + 1 (>K:ADF_VOLUME_DEC) + } + + TT:COCKPIT.TOOLTIPS.TRANSMITTER_ADF1_VOLUME_DEC + TT:COCKPIT.TOOLTIPS.TRANSMITTER_ADF1_VOLUME_INC + %((L:XMLVAR_NAV_#SIDE#_ADF1_Switch_Down))%{if}TT:INPUT.KEY_RADIO_ADF_IDENT_DISABLE_DESC%{else}TT:INPUT.KEY_RADIO_ADF_IDENT_ENABLE_DESC%{end} + + + + KNOB + FBW_AIRLINER_Audio_NAV_Volume_Knob_Template + #NODE_ID_RECEIVER_ADF2# + #NODE_ID_LIGHT_RECEIVER_ADF2# + #ANIM_NAME_KNOB_RECEIVER_ADF2# + #ANIM_NAME_PUSH_RECEIVER_ADF2# + #NODE_ID_LED_RECEIVER_ADF2# + ADF2 + + + (L:XMLVAR_NAV_VOICE_Switch_Down) 0 == if{ + (A:ADF SOUND:2, Bool) 1 == (L:XMLVAR_NAV_L_ADF2_Switch_Down) 0 == (L:XMLVAR_NAV_R_ADF2_Switch_Down) 0 == and and if{ + 1 (>K:RADIO_ADF2_IDENT_TOGGLE) + } + + (A:ADF SOUND:2, Bool) 0 == (L:XMLVAR_NAV_L_ADF2_Switch_Down) 1 == (L:XMLVAR_NAV_R_ADF2_Switch_Down) 1 == or and if{ + 1 (>K:RADIO_ADF2_IDENT_TOGGLE) + } + } + + + (L:XMLVAR_NAV_#SIDE#_ADF2_Volume) #VOLUME_INCREMENT_NAV# + 1 min (>L:XMLVAR_NAV_#SIDE#_ADF2_Volume) + (L:XMLVAR_NAV_#SIDE#_ADF2_Volume) #VOLUME_INCREMENT_NAV# - 0 max (>L:XMLVAR_NAV_#SIDE#_ADF2_Volume) + TT:COCKPIT.TOOLTIPS.TRANSMITTER_ADF2_VOLUME_DEC + TT:COCKPIT.TOOLTIPS.TRANSMITTER_ADF2_VOLUME_INC + %((L:XMLVAR_NAV_#SIDE#_ADF2_Switch_Down))%{if}TT:INPUT.KEY_RADIO_ADF2_IDENT_DISABLE_DESC%{else}TT:INPUT.KEY_RADIO_ADF2_IDENT_ENABLE_DESC%{end} + + + + + + + + + - - @@ -301,9 +305,10 @@ let modeId = #MODE_ID, number#; alias toggleSwitch = (L:A32NX_RMP_#SIDE#_TOGGLE_SWITCH, bool); alias selectedMode = (L:A32NX_RMP_#SIDE#_SELECTED_MODE, number); + alias navButtonPressed = (L:A32NX_RMP_#SIDE#_NAV_BUTTON_SELECTED, bool); alias annunciatorLight = (L:A32NX_OVHD_INTLT_ANN, number); let emissiveDim = if annunciatorLight == 2 { 0.05 } else { 1 }; - (if ((!inop and toggleSwitch and (selectedMode == modeId)) or (annunciatorLight == 0)) and indicatorsPowered { + (if ((!inop and toggleSwitch and ((selectedMode == modeId) or (modeId == 12 and navButtonPressed))) or (annunciatorLight == 0)) and indicatorsPowered { 1 * emissiveDim } else { 0 diff --git a/src/fadec/a320_fadec/src/EngineControl.h b/src/fadec/a320_fadec/src/EngineControl.h index a175ea73d9b..61cf4577181 100644 --- a/src/fadec/a320_fadec/src/EngineControl.h +++ b/src/fadec/a320_fadec/src/EngineControl.h @@ -657,48 +657,52 @@ class EngineControl { } } + int getStationCount(long long paxStationFlags) { + int count = 0; + int eol = 0; + while (paxStationFlags && eol < 64) { + count += paxStationFlags & 1; + paxStationFlags >>= 1; + eol++; + } + if (eol >= 64) { + std::cerr << "ERROR: limit reached" << std::endl; + } + return count; + } + /// /// FBW Payload checking and UI override function /// + // TODO: remove from FADEC logic -> rust void checkPayload() { - double fuelWeightGallon = simVars->getFuelWeightGallon(); - double aircraftEmptyWeight = simVars->getEmptyWeight(); // in LBS double conversionFactor = simVars->getConversionFactor(); - double perPaxWeightLbs = simVars->getPerPaxWeight() / conversionFactor; // in LBS - double aircraftTotalWeight = simVars->getTotalWeight(); // in LBS - double fuelTotalWeight = simVars->getFuelTotalQuantity() * fuelWeightGallon; // in LBS - double payloadTotalWeight = aircraftTotalWeight - aircraftEmptyWeight - fuelTotalWeight; // in LBS - - double paxRows1to6Actual = simVars->getPaxRows1to6Actual() * perPaxWeightLbs; // in LBS - double paxRows7to13Actual = simVars->getPaxRows7to13Actual() * perPaxWeightLbs; // in LBS - double paxRows14to21Actual = simVars->getPaxRows14to21Actual() * perPaxWeightLbs; // in LBS - double paxRows22to29Actual = simVars->getPaxRows22to29Actual() * perPaxWeightLbs; // in LBS - double paxRows1to6Desired = simVars->getPaxRows1to6Desired() * perPaxWeightLbs; // in LBS - double paxRows7to13Desired = simVars->getPaxRows7to13Desired() * perPaxWeightLbs; // in LBS - double paxRows14to21Desired = simVars->getPaxRows14to21Desired() * perPaxWeightLbs; // in LBS - double paxRows22to29Desired = simVars->getPaxRows22to29Desired() * perPaxWeightLbs; // in LBS - double cargoFwdContainerActual = simVars->getCargoFwdContainerActual() / conversionFactor; // in LBS - double cargoAftContainerActual = simVars->getCargoAftContainerActual() / conversionFactor; // in LBS - double cargoAftBaggageActual = simVars->getCargoAftBaggageActual() / conversionFactor; // in LBS - double cargoAftBulkActual = simVars->getCargoAftBulkActual() / conversionFactor; // in LBS - double cargoFwdContainerDesired = simVars->getCargoFwdContainerDesired() / conversionFactor; // in LBS - double cargoAftContainerDesired = simVars->getCargoAftContainerDesired() / conversionFactor; // in LBS - double cargoAftBaggageDesired = simVars->getCargoAftBaggageDesired() / conversionFactor; // in LBS - double cargoAftBulkDesired = simVars->getCargoAftBulkDesired() / conversionFactor; // in LBS - double paxTotalWeightActual = (paxRows1to6Actual + paxRows7to13Actual + paxRows14to21Actual + paxRows22to29Actual); - double paxTotalWeightDesired = (paxRows1to6Desired + paxRows7to13Desired + paxRows14to21Desired + paxRows22to29Desired); + double fuelWeightGallon = simVars->getFuelWeightGallon(); + double aircraftEmptyWeight = simVars->getEmptyWeight(); // in LBS + double perPaxWeightLbs = simVars->getPerPaxWeight() / conversionFactor; + double aircraftTotalWeight = simVars->getTotalWeight(); // in LBS + double fuelTotalWeight = simVars->getFuelTotalQuantity() * fuelWeightGallon; // in LBS + double pilotsWeight = simVars->getPayloadStationWeight(9) + simVars->getPayloadStationWeight(10); // in LBS + double aircraftPayloadTotalWeight = aircraftTotalWeight - aircraftEmptyWeight - fuelTotalWeight - pilotsWeight; // in LBS + double paxStationAWeight = getStationCount((long long)simVars->getPaxStationAFlags()) * perPaxWeightLbs; // in LBS + double paxStationBWeight = getStationCount((long long)simVars->getPaxStationBFlags()) * perPaxWeightLbs; // in LBS + double paxStationCWeight = getStationCount((long long)simVars->getPaxStationCFlags()) * perPaxWeightLbs; // in LBS + double paxStationDWeight = getStationCount((long long)simVars->getPaxStationDFlags()) * perPaxWeightLbs; // in LBS + double cargoFwdContainerActual = simVars->getCargoFwdContainerActual() / conversionFactor; // in LBS + double cargoAftContainerActual = simVars->getCargoAftContainerActual() / conversionFactor; // in LBS + double cargoAftBaggageActual = simVars->getCargoAftBaggageActual() / conversionFactor; // in LBS + double cargoAftBulkActual = simVars->getCargoAftBulkActual() / conversionFactor; // in LBS + double paxTotalWeightActual = (paxStationAWeight + paxStationBWeight + paxStationCWeight + paxStationDWeight); double cargoTotalWeightActual = (cargoFwdContainerActual + cargoAftContainerActual + cargoAftBaggageActual + cargoAftBulkActual); - double cargoTotalWeightDesired = (cargoFwdContainerDesired + cargoAftContainerDesired + cargoAftBaggageDesired + cargoAftBulkDesired); - - if (abs(payloadTotalWeight - paxTotalWeightActual + cargoTotalWeightActual) > 5) { + if (abs(aircraftPayloadTotalWeight - paxTotalWeightActual + cargoTotalWeightActual) > 5) { SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation1, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows1to6Actual); + &paxStationAWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation2, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows7to13Actual); + &paxStationBWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation3, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows14to21Actual); + &paxStationCWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation4, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows22to29Actual); + &paxStationDWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation5, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), &cargoFwdContainerActual); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation6, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), @@ -1064,7 +1068,7 @@ class EngineControl { /// void initialize(const char* acftRegistration) { srand((int)time(0)); - + std::cout << "FADEC: Initializing EngineControl" << std::endl; simVars = new SimVars(); diff --git a/src/fadec/a320_fadec/src/SimVars.h b/src/fadec/a320_fadec/src/SimVars.h index c7be3bdf71b..9beeb973c9b 100644 --- a/src/fadec/a320_fadec/src/SimVars.h +++ b/src/fadec/a320_fadec/src/SimVars.h @@ -110,6 +110,8 @@ class SimVars { ENUM NacelleAntiIce = get_aircraft_var_enum("ENG ANTI ICE"); + ENUM PayloadStationWeights = get_aircraft_var_enum("PAYLOAD STATION WEIGHT"); + /// /// Collection of LVars for the A32NX /// @@ -155,14 +157,14 @@ class SimVars { ID PumpStateRight; ID ConversionFactor; ID PerPaxWeight; - ID PaxRows1to6Actual; - ID PaxRows7to13Actual; - ID PaxRows14to21Actual; - ID PaxRows22to29Actual; - ID PaxRows1to6Desired; - ID PaxRows7to13Desired; - ID PaxRows14to21Desired; - ID PaxRows22to29Desired; + ID PaxStationAFlags; + ID PaxStationBFlags; + ID PaxStationCFlags; + ID PaxStationDFlags; + ID PaxStationAFlagsDesired; + ID PaxStationBFlagsDesired; + ID PaxStationCFlagsDesired; + ID PaxStationDFlagsDesired; ID CargoFwdContainerActual; ID CargoAftContainerActual; ID CargoAftBaggageActual; @@ -222,14 +224,14 @@ class SimVars { PumpStateRight = register_named_variable("A32NX_PUMP_STATE:2"); ConversionFactor = register_named_variable("A32NX_EFB_UNIT_CONVERSION_FACTOR"); PerPaxWeight = register_named_variable("A32NX_WB_PER_PAX_WEIGHT"); - PaxRows1to6Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_1_6"); - PaxRows7to13Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_7_13"); - PaxRows14to21Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_14_21"); - PaxRows22to29Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_22_29"); - PaxRows1to6Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_1_6_DESIRED"); - PaxRows7to13Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_7_13_DESIRED"); - PaxRows14to21Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_14_21_DESIRED"); - PaxRows22to29Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_22_29_DESIRED"); + PaxStationAFlags = register_named_variable("A32NX_PAX_FLAGS_A"); + PaxStationBFlags = register_named_variable("A32NX_PAX_FLAGS_B"); + PaxStationCFlags = register_named_variable("A32NX_PAX_FLAGS_C"); + PaxStationDFlags = register_named_variable("A32NX_PAX_FLAGS_D"); + PaxStationAFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_A_DESIRED"); + PaxStationBFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_B_DESIRED"); + PaxStationCFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_C_DESIRED"); + PaxStationDFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_D_DESIRED"); CargoFwdContainerActual = register_named_variable("A32NX_CARGO_FWD_BAGGAGE_CONTAINER"); CargoAftContainerActual = register_named_variable("A32NX_CARGO_AFT_CONTAINER"); CargoAftBaggageActual = register_named_variable("A32NX_CARGO_AFT_BAGGAGE"); @@ -367,14 +369,14 @@ class SimVars { FLOAT64 getPumpStateRight() { return get_named_variable_value(PumpStateRight); } FLOAT64 getPerPaxWeight() { return get_named_variable_value(PerPaxWeight); } FLOAT64 getConversionFactor() { return get_named_variable_value(ConversionFactor); } - FLOAT64 getPaxRows1to6Actual() { return get_named_variable_value(PaxRows1to6Actual); } - FLOAT64 getPaxRows7to13Actual() { return get_named_variable_value(PaxRows7to13Actual); } - FLOAT64 getPaxRows14to21Actual() { return get_named_variable_value(PaxRows14to21Actual); } - FLOAT64 getPaxRows22to29Actual() { return get_named_variable_value(PaxRows22to29Actual); } - FLOAT64 getPaxRows1to6Desired() { return get_named_variable_value(PaxRows1to6Desired); } - FLOAT64 getPaxRows7to13Desired() { return get_named_variable_value(PaxRows7to13Desired); } - FLOAT64 getPaxRows14to21Desired() { return get_named_variable_value(PaxRows14to21Desired); } - FLOAT64 getPaxRows22to29Desired() { return get_named_variable_value(PaxRows22to29Desired); } + FLOAT64 getPaxStationAFlags() { return get_named_variable_value(PaxStationAFlags); } + FLOAT64 getPaxStationBFlags() { return get_named_variable_value(PaxStationBFlags); } + FLOAT64 getPaxStationCFlags() { return get_named_variable_value(PaxStationCFlags); } + FLOAT64 getPaxStationDFlags() { return get_named_variable_value(PaxStationDFlags); } + FLOAT64 getPaxStationADesiredFlags() { return get_named_variable_value(PaxStationAFlagsDesired); } + FLOAT64 getPaxStationBDesiredFlags() { return get_named_variable_value(PaxStationBFlagsDesired); } + FLOAT64 getPaxStationCDesiredFlags() { return get_named_variable_value(PaxStationCFlagsDesired); } + FLOAT64 getPaxStationDDesiredFlags() { return get_named_variable_value(PaxStationDFlagsDesired); } FLOAT64 getCargoFwdContainerActual() { return get_named_variable_value(CargoFwdContainerActual); } FLOAT64 getCargoAftContainerActual() { return get_named_variable_value(CargoAftContainerActual); } FLOAT64 getCargoAftBaggageActual() { return get_named_variable_value(CargoAftBaggageActual); } @@ -428,4 +430,5 @@ class SimVars { FLOAT64 getEngineCombustion(int index) { return aircraft_varget(EngineCombustion, m_Units->Bool, index); } FLOAT64 getAnimDeltaTime() { return aircraft_varget(animDeltaTime, m_Units->Seconds, 0); } FLOAT64 getNAI(int index) { return aircraft_varget(NacelleAntiIce, m_Units->Bool, index); } + FLOAT64 getPayloadStationWeight(int index) { return aircraft_varget(PayloadStationWeights, m_Units->Pounds, index); } }; diff --git a/src/fadec/a380_fadec/src/EngineControl.h b/src/fadec/a380_fadec/src/EngineControl.h index b1a01a34143..9a801b04f14 100644 --- a/src/fadec/a380_fadec/src/EngineControl.h +++ b/src/fadec/a380_fadec/src/EngineControl.h @@ -527,7 +527,6 @@ class EngineControl { /// Updates Engine N1 and N2 with our own algorithm for start-up and shutdown /// void updatePrimaryParameters(int engine, double simN1, double simN2) { - if (engine == 1) { simVars->setEngine1N1(simN1); simVars->setEngine1N2(simN2); @@ -749,48 +748,52 @@ class EngineControl { } } + int getStationCount(long long paxStationFlags) { + int count = 0; + int eol = 0; + while (paxStationFlags && eol < 64) { + count += paxStationFlags & 1; + paxStationFlags >>= 1; + eol++; + } + if (eol >= 64) { + std::cerr << "ERROR: limit reached" << std::endl; + } + return count; + } + /// /// FBW Payload checking and UI override function /// + // TODO: remove from FADEC logic -> rust void checkPayload() { + double conversionFactor = simVars->getConversionFactor(); double fuelWeightGallon = simVars->getFuelWeightGallon(); double aircraftEmptyWeight = simVars->getEmptyWeight(); // in LBS - double conversionFactor = simVars->getConversionFactor(); - double perPaxWeightLbs = simVars->getPerPaxWeight() / conversionFactor; // in LBS - double aircraftTotalWeight = simVars->getTotalWeight(); // in LBS - double fuelTotalWeight = simVars->getFuelTotalQuantity() * fuelWeightGallon; // in LBS - double payloadTotalWeight = aircraftTotalWeight - aircraftEmptyWeight - fuelTotalWeight; // in LBS - - double paxRows1to6Actual = simVars->getPaxRows1to6Actual() * perPaxWeightLbs; // in LBS - double paxRows7to13Actual = simVars->getPaxRows7to13Actual() * perPaxWeightLbs; // in LBS - double paxRows14to21Actual = simVars->getPaxRows14to21Actual() * perPaxWeightLbs; // in LBS - double paxRows22to29Actual = simVars->getPaxRows22to29Actual() * perPaxWeightLbs; // in LBS - double paxRows1to6Desired = simVars->getPaxRows1to6Desired() * perPaxWeightLbs; // in LBS - double paxRows7to13Desired = simVars->getPaxRows7to13Desired() * perPaxWeightLbs; // in LBS - double paxRows14to21Desired = simVars->getPaxRows14to21Desired() * perPaxWeightLbs; // in LBS - double paxRows22to29Desired = simVars->getPaxRows22to29Desired() * perPaxWeightLbs; // in LBS - double cargoFwdContainerActual = simVars->getCargoFwdContainerActual() / conversionFactor; // in LBS - double cargoAftContainerActual = simVars->getCargoAftContainerActual() / conversionFactor; // in LBS - double cargoAftBaggageActual = simVars->getCargoAftBaggageActual() / conversionFactor; // in LBS - double cargoAftBulkActual = simVars->getCargoAftBulkActual() / conversionFactor; // in LBS - double cargoFwdContainerDesired = simVars->getCargoFwdContainerDesired() / conversionFactor; // in LBS - double cargoAftContainerDesired = simVars->getCargoAftContainerDesired() / conversionFactor; // in LBS - double cargoAftBaggageDesired = simVars->getCargoAftBaggageDesired() / conversionFactor; // in LBS - double cargoAftBulkDesired = simVars->getCargoAftBulkDesired() / conversionFactor; // in LBS - double paxTotalWeightActual = (paxRows1to6Actual + paxRows7to13Actual + paxRows14to21Actual + paxRows22to29Actual); - double paxTotalWeightDesired = (paxRows1to6Desired + paxRows7to13Desired + paxRows14to21Desired + paxRows22to29Desired); + double perPaxWeightLbs = simVars->getPerPaxWeight() / conversionFactor; + double aircraftTotalWeight = simVars->getTotalWeight(); // in LBS + double fuelTotalWeight = simVars->getFuelTotalQuantity() * fuelWeightGallon; // in LBS + double pilotsWeight = simVars->getPayloadStationWeight(9) + simVars->getPayloadStationWeight(10); // in LBS + double aircraftPayloadTotalWeight = aircraftTotalWeight - aircraftEmptyWeight - fuelTotalWeight - pilotsWeight; // in LBS + double paxStationAWeight = getStationCount((long long)simVars->getPaxStationAFlags()) * perPaxWeightLbs; // in LBS + double paxStationBWeight = getStationCount((long long)simVars->getPaxStationBFlags()) * perPaxWeightLbs; // in LBS + double paxStationCWeight = getStationCount((long long)simVars->getPaxStationCFlags()) * perPaxWeightLbs; // in LBS + double paxStationDWeight = getStationCount((long long)simVars->getPaxStationDFlags()) * perPaxWeightLbs; // in LBS + double cargoFwdContainerActual = simVars->getCargoFwdContainerActual() / conversionFactor; // in LBS + double cargoAftContainerActual = simVars->getCargoAftContainerActual() / conversionFactor; // in LBS + double cargoAftBaggageActual = simVars->getCargoAftBaggageActual() / conversionFactor; // in LBS + double cargoAftBulkActual = simVars->getCargoAftBulkActual() / conversionFactor; // in LBS + double paxTotalWeightActual = (paxStationAWeight + paxStationBWeight + paxStationCWeight + paxStationDWeight); double cargoTotalWeightActual = (cargoFwdContainerActual + cargoAftContainerActual + cargoAftBaggageActual + cargoAftBulkActual); - double cargoTotalWeightDesired = (cargoFwdContainerDesired + cargoAftContainerDesired + cargoAftBaggageDesired + cargoAftBulkDesired); - - if (abs(payloadTotalWeight - paxTotalWeightActual + cargoTotalWeightActual) > 5) { + if (abs(aircraftPayloadTotalWeight - paxTotalWeightActual + cargoTotalWeightActual) > 5) { SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation1, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows1to6Actual); + &paxStationAWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation2, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows7to13Actual); + &paxStationBWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation3, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows14to21Actual); + &paxStationCWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation4, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), - &paxRows22to29Actual); + &paxStationDWeight); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation5, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), &cargoFwdContainerActual); SimConnect_SetDataOnSimObject(hSimConnect, DataTypesID::PayloadStation6, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(double), @@ -832,10 +835,10 @@ class EngineControl { double engine4FF = simVars->getEngine4FF(); // KG/H double fuelWeightGallon = simVars->getFuelWeightGallon(); - double fuelUsedEngine1 = simVars->getFuelUsedEngine1(); // Kg + double fuelUsedEngine1 = simVars->getFuelUsedEngine1(); // Kg double fuelUsedEngine2 = simVars->getFuelUsedEngine2(); // Kg - double fuelUsedEngine3 = simVars->getFuelUsedEngine3(); // Kg - double fuelUsedEngine4 = simVars->getFuelUsedEngine4(); // Kg + double fuelUsedEngine3 = simVars->getFuelUsedEngine3(); // Kg + double fuelUsedEngine4 = simVars->getFuelUsedEngine4(); // Kg double fuelLeftPre = simVars->getFuelLeftPre(); // LBS double fuelRightPre = simVars->getFuelRightPre(); // LBS @@ -1096,7 +1099,7 @@ class EngineControl { fuelBurn3 = 0; fuelBurn4 = 0; } - fuelLeft = (fuelLeftPre - (fuelBurn1 * KGS_TO_LBS) - (fuelBurn2 * KGS_TO_LBS)) + xfrAuxLeft + (xfrCenter / 2); // LBS + fuelLeft = (fuelLeftPre - (fuelBurn1 * KGS_TO_LBS) - (fuelBurn2 * KGS_TO_LBS)) + xfrAuxLeft + (xfrCenter / 2); // LBS fuelRight = (fuelRightPre - (fuelBurn3 * KGS_TO_LBS) - (fuelBurn4 * KGS_TO_LBS)) + xfrAuxRight + (xfrCenter / 2); // LBS // Checking for Inner Tank overflow - Will be taken off with Rust code @@ -1119,10 +1122,10 @@ class EngineControl { simVars->setEngine2PreFF(engine2FF); simVars->setEngine3PreFF(engine3FF); simVars->setEngine4PreFF(engine4FF); - simVars->setFuelUsedEngine1(fuelUsedEngine1); // in KG - simVars->setFuelUsedEngine2(fuelUsedEngine2); // in KG - simVars->setFuelUsedEngine3(fuelUsedEngine3); // in KG - simVars->setFuelUsedEngine4(fuelUsedEngine4); // in KG + simVars->setFuelUsedEngine1(fuelUsedEngine1); // in KG + simVars->setFuelUsedEngine2(fuelUsedEngine2); // in KG + simVars->setFuelUsedEngine3(fuelUsedEngine3); // in KG + simVars->setFuelUsedEngine4(fuelUsedEngine4); // in KG simVars->setFuelAuxLeftPre(leftAuxQuantity); // in LBS simVars->setFuelAuxRightPre(rightAuxQuantity); // in LBS simVars->setFuelCenterPre(fuelCenter); // in LBS @@ -1440,7 +1443,6 @@ class EngineControl { timer = simVars->getEngine4Timer(); } - switch (int(engineState)) { case 2: case 3: diff --git a/src/fadec/a380_fadec/src/SimVars.h b/src/fadec/a380_fadec/src/SimVars.h index 922d304976c..6cf1d0bbafe 100644 --- a/src/fadec/a380_fadec/src/SimVars.h +++ b/src/fadec/a380_fadec/src/SimVars.h @@ -117,6 +117,8 @@ class SimVars { ENUM NacelleAntiIce = get_aircraft_var_enum("ENG ANTI ICE"); ENUM WingAntiIce = get_aircraft_var_enum("STRUCTURAL DEICE SWITCH"); + ENUM PayloadStationWeights = get_aircraft_var_enum("PAYLOAD STATION WEIGHT"); + /// /// Collection of LVars for the A32NX /// @@ -185,14 +187,14 @@ class SimVars { ID PumpStateEngine4; ID ConversionFactor; ID PerPaxWeight; - ID PaxRows1to6Actual; - ID PaxRows7to13Actual; - ID PaxRows14to21Actual; - ID PaxRows22to29Actual; - ID PaxRows1to6Desired; - ID PaxRows7to13Desired; - ID PaxRows14to21Desired; - ID PaxRows22to29Desired; + ID PaxStationAFlags; + ID PaxStationBFlags; + ID PaxStationCFlags; + ID PaxStationDFlags; + ID PaxStationAFlagsDesired; + ID PaxStationBFlagsDesired; + ID PaxStationCFlagsDesired; + ID PaxStationDFlagsDesired; ID CargoFwdContainerActual; ID CargoAftContainerActual; ID CargoAftBaggageActual; @@ -273,14 +275,14 @@ class SimVars { PumpStateEngine4 = register_named_variable("A32NX_PUMP_STATE:4"); ConversionFactor = register_named_variable("A32NX_EFB_UNIT_CONVERSION_FACTOR"); PerPaxWeight = register_named_variable("A32NX_WB_PER_PAX_WEIGHT"); - PaxRows1to6Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_1_6"); - PaxRows7to13Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_7_13"); - PaxRows14to21Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_14_21"); - PaxRows22to29Actual = register_named_variable("A32NX_PAX_TOTAL_ROWS_22_29"); - PaxRows1to6Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_1_6_DESIRED"); - PaxRows7to13Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_7_13_DESIRED"); - PaxRows14to21Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_14_21_DESIRED"); - PaxRows22to29Desired = register_named_variable("A32NX_PAX_TOTAL_ROWS_22_29_DESIRED"); + PaxStationAFlags = register_named_variable("A32NX_PAX_FLAGS_A"); + PaxStationBFlags = register_named_variable("A32NX_PAX_FLAGS_B"); + PaxStationCFlags = register_named_variable("A32NX_PAX_FLAGS_C"); + PaxStationDFlags = register_named_variable("A32NX_PAX_FLAGS_D"); + PaxStationAFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_A_DESIRED"); + PaxStationBFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_B_DESIRED"); + PaxStationCFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_C_DESIRED"); + PaxStationDFlagsDesired = register_named_variable("A32NX_PAX_FLAGS_D_DESIRED"); CargoFwdContainerActual = register_named_variable("A32NX_CARGO_FWD_BAGGAGE_CONTAINER"); CargoAftContainerActual = register_named_variable("A32NX_CARGO_AFT_CONTAINER"); CargoAftBaggageActual = register_named_variable("A32NX_CARGO_AFT_BAGGAGE"); @@ -479,14 +481,14 @@ class SimVars { FLOAT64 getPumpStateEngine4() { return get_named_variable_value(PumpStateEngine4); } FLOAT64 getPerPaxWeight() { return get_named_variable_value(PerPaxWeight); } FLOAT64 getConversionFactor() { return get_named_variable_value(ConversionFactor); } - FLOAT64 getPaxRows1to6Actual() { return get_named_variable_value(PaxRows1to6Actual); } - FLOAT64 getPaxRows7to13Actual() { return get_named_variable_value(PaxRows7to13Actual); } - FLOAT64 getPaxRows14to21Actual() { return get_named_variable_value(PaxRows14to21Actual); } - FLOAT64 getPaxRows22to29Actual() { return get_named_variable_value(PaxRows22to29Actual); } - FLOAT64 getPaxRows1to6Desired() { return get_named_variable_value(PaxRows1to6Desired); } - FLOAT64 getPaxRows7to13Desired() { return get_named_variable_value(PaxRows7to13Desired); } - FLOAT64 getPaxRows14to21Desired() { return get_named_variable_value(PaxRows14to21Desired); } - FLOAT64 getPaxRows22to29Desired() { return get_named_variable_value(PaxRows22to29Desired); } + FLOAT64 getPaxStationAFlags() { return get_named_variable_value(PaxStationAFlags); } + FLOAT64 getPaxStationBFlags() { return get_named_variable_value(PaxStationBFlags); } + FLOAT64 getPaxStationCFlags() { return get_named_variable_value(PaxStationCFlags); } + FLOAT64 getPaxStationDFlags() { return get_named_variable_value(PaxStationDFlags); } + FLOAT64 getPaxStationADesiredFlags() { return get_named_variable_value(PaxStationAFlagsDesired); } + FLOAT64 getPaxStationBDesiredFlags() { return get_named_variable_value(PaxStationBFlagsDesired); } + FLOAT64 getPaxStationCDesiredFlags() { return get_named_variable_value(PaxStationCFlagsDesired); } + FLOAT64 getPaxStationDDesiredFlags() { return get_named_variable_value(PaxStationDFlagsDesired); } FLOAT64 getCargoFwdContainerActual() { return get_named_variable_value(CargoFwdContainerActual); } FLOAT64 getCargoAftContainerActual() { return get_named_variable_value(CargoAftContainerActual); } FLOAT64 getCargoAftBaggageActual() { return get_named_variable_value(CargoAftBaggageActual); } @@ -545,4 +547,5 @@ class SimVars { FLOAT64 getAnimDeltaTime() { return aircraft_varget(animDeltaTime, m_Units->Seconds, 0); } FLOAT64 getNAI(int index) { return aircraft_varget(NacelleAntiIce, m_Units->Bool, index); } FLOAT64 getWAI() { return aircraft_varget(WingAntiIce, m_Units->Bool, 0); } + FLOAT64 getPayloadStationWeight(int index) { return aircraft_varget(PayloadStationWeights, m_Units->Pounds, index); } }; diff --git a/src/failures/src/a320.ts b/src/failures/src/a320.ts index 96b50241570..90fa2fe1667 100644 --- a/src/failures/src/a320.ts +++ b/src/failures/src/a320.ts @@ -13,6 +13,7 @@ export const A320Failure = Object.freeze({ Sec3Failure: 27004, Fcdc1Failure: 27005, Fcdc2Failure: 27006, + GreenReservoirLeak: 29000, BlueReservoirLeak: 29001, YellowReservoirLeak: 29002, @@ -22,6 +23,11 @@ export const A320Failure = Object.freeze({ GreenReservoirReturnLeak: 29006, BlueReservoirReturnLeak: 29007, YellowReservoirReturnLeak: 29008, + GreenEdpOverheat: 29009, + BlueEpumpOverheat: 29010, + YellowEdpOverheat: 29011, + YellowEpumpOverheat: 29012, + LeftPfdDisplay: 31000, RightPfdDisplay: 31001, diff --git a/src/fbw_a320/src/model/SecComputer.cpp b/src/fbw_a320/src/model/SecComputer.cpp index 7116180223b..cbc22b5c148 100644 --- a/src/fbw_a320/src/model/SecComputer.cpp +++ b/src/fbw_a320/src/model/SecComputer.cpp @@ -171,25 +171,25 @@ void SecComputer::step() real_T rtb_handleIndex; real_T rtb_zeta_deg; real_T u0; - real32_T rtb_y_fp; - real32_T rtb_y_h; + real32_T rtb_y_e; + real32_T rtb_y_fn; uint32_T rtb_DataTypeConversion1; uint32_T rtb_Switch7_c; uint32_T rtb_Switch9_c; uint32_T rtb_y; uint32_T rtb_y_af; - uint32_T rtb_y_mx; + uint32_T rtb_y_m; boolean_T rtb_VectorConcatenate[19]; boolean_T rtb_AND1_h; boolean_T rtb_AND4_a; boolean_T rtb_NOT_bl; boolean_T rtb_OR; - boolean_T rtb_OR6; - boolean_T rtb_y_am; - boolean_T rtb_y_b; - boolean_T rtb_y_k4; + boolean_T rtb_y_ei; + boolean_T rtb_y_f5; + boolean_T rtb_y_j; boolean_T rtb_y_l; - boolean_T rtb_y_m; + boolean_T rtb_y_la; + boolean_T rtb_y_ls; if (SecComputer_U.in.sim_data.computer_running) { real_T pair1RollCommand; real_T pair2SpdBrkCommand; @@ -210,14 +210,15 @@ void SecComputer::step() boolean_T abnormalCondition; boolean_T canEngageInPitch; boolean_T hasPriorityInPitch; - boolean_T leftElevatorAvail; boolean_T rightElevatorAvail; boolean_T rtb_AND2_j; + boolean_T rtb_BusAssignment_fz_logic_is_green_hydraulic_power_avail; boolean_T rtb_BusAssignment_n_logic_any_landing_gear_not_uplocked; boolean_T rtb_NOT2_b; boolean_T rtb_NOT_g; boolean_T rtb_OR1; boolean_T rtb_OR3; + boolean_T rtb_OR6; boolean_T rtb_doubleAdrFault; boolean_T rtb_doubleIrFault; boolean_T rtb_isEngagedInPitch; @@ -237,6 +238,7 @@ void SecComputer::step() SecComputer_DWork.Memory_PreviousInput_n = SecComputer_P.SRFlipFlop_initial_condition_k; SecComputer_DWork.Delay1_DSTATE_i = SecComputer_P.Delay1_InitialCondition_l; SecComputer_DWork.Delay_DSTATE_n = SecComputer_P.Delay_InitialCondition_j; + SecComputer_DWork.Delay2_DSTATE = SecComputer_P.Delay2_InitialCondition; SecComputer_DWork.Delay_DSTATE = SecComputer_P.Delay_InitialCondition; SecComputer_DWork.icLoad = true; SecComputer_MATLABFunction_e_Reset(&SecComputer_DWork.sf_MATLABFunction_jk); @@ -315,8 +317,8 @@ void SecComputer::step() (SignStatusMatrix::NormalOperation)) || SecComputer_P.Constant_Value_l); rtb_singleIrFault = (rtb_OR || rtb_OR6); rtb_doubleIrFault = (rtb_OR && rtb_OR6); - rtb_y_l = !rtb_OR3; - if ((!rtb_OR1) && rtb_y_l) { + rtb_y_j = !rtb_OR3; + if ((!rtb_OR1) && rtb_y_j) { rtb_V_ias = (SecComputer_U.in.bus_inputs.adr_2_bus.airspeed_computed_kn.Data + SecComputer_U.in.bus_inputs.adr_2_bus.airspeed_computed_kn.Data) / 2.0F; rtb_V_tas = (SecComputer_U.in.bus_inputs.adr_2_bus.airspeed_true_kn.Data + @@ -330,7 +332,7 @@ void SecComputer::step() rtb_V_tas = SecComputer_U.in.bus_inputs.adr_1_bus.airspeed_true_kn.Data; rtb_mach = SecComputer_U.in.bus_inputs.adr_1_bus.mach.Data; rtb_alpha = SecComputer_U.in.bus_inputs.adr_1_bus.aoa_corrected_deg.Data; - } else if (rtb_OR1 && rtb_y_l) { + } else if (rtb_OR1 && rtb_y_j) { rtb_V_ias = SecComputer_U.in.bus_inputs.adr_2_bus.airspeed_computed_kn.Data; rtb_V_tas = SecComputer_U.in.bus_inputs.adr_2_bus.airspeed_true_kn.Data; rtb_mach = SecComputer_U.in.bus_inputs.adr_2_bus.mach.Data; @@ -345,9 +347,9 @@ void SecComputer::step() rtb_eta_trim_limit_lo_d = rtb_V_ias; rtb_BusConversion_InsertedFor_BusAssignment_at_inport_8_BusCreator1_V_tas_kn = rtb_V_tas; rtb_BusConversion_InsertedFor_BusAssignment_at_inport_8_BusCreator1_mach = rtb_mach; - rtb_y_l = !rtb_OR; + rtb_y_j = !rtb_OR; rtb_OR1 = !rtb_OR6; - if (rtb_y_l && rtb_OR1) { + if (rtb_y_j && rtb_OR1) { rtb_theta = (SecComputer_U.in.bus_inputs.ir_1_bus.pitch_angle_deg.Data + SecComputer_U.in.bus_inputs.ir_2_bus.pitch_angle_deg.Data) / 2.0F; rtb_phi = (SecComputer_U.in.bus_inputs.ir_1_bus.roll_angle_deg.Data + @@ -366,7 +368,7 @@ void SecComputer::step() SecComputer_U.in.bus_inputs.ir_2_bus.pitch_att_rate_deg_s.Data) / 2.0F; rtb_phi_dot = (SecComputer_U.in.bus_inputs.ir_1_bus.roll_att_rate_deg_s.Data + SecComputer_U.in.bus_inputs.ir_2_bus.roll_att_rate_deg_s.Data) / 2.0F; - } else if (rtb_y_l && rtb_OR6) { + } else if (rtb_y_j && rtb_OR6) { rtb_theta = SecComputer_U.in.bus_inputs.ir_1_bus.pitch_angle_deg.Data; rtb_phi = SecComputer_U.in.bus_inputs.ir_1_bus.roll_angle_deg.Data; rtb_q = SecComputer_U.in.bus_inputs.ir_1_bus.body_pitch_rate_deg_s.Data; @@ -401,81 +403,81 @@ void SecComputer::step() rtb_Switch5_tmp_tmp = rtb_theta; rtb_Switch6_m = rtb_phi; rtb_handleIndex = rtb_n_x; - SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_OR); + SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_y_ei); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel13_bit, &rtb_Switch7_c); - rtb_OR6 = (rtb_Switch7_c != 0U); + rtb_OR = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel12_bit, &rtb_Switch7_c); - rtb_y_m = (rtb_Switch7_c != 0U); + rtb_y_f5 = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel10_bit, &rtb_Switch7_c); - rtb_OR6 = (rtb_OR6 || rtb_y_m || (rtb_Switch7_c != 0U)); - rtb_y_k4 = (rtb_OR && rtb_OR6); + rtb_OR = (rtb_OR || rtb_y_f5 || (rtb_Switch7_c != 0U)); + rtb_y_ls = (rtb_y_ei && rtb_OR); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_NOT_bl); - rtb_OR1 = (rtb_y_k4 && (!rtb_NOT_bl)); - SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_y_b); + rtb_OR6 = (rtb_y_ls && (!rtb_NOT_bl)); + SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_y_la); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel5_bit, &rtb_Switch7_c); - rtb_y_m = (rtb_Switch7_c != 0U); + rtb_y_f5 = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel4_bit, &rtb_Switch7_c); - rtb_y_am = (rtb_Switch7_c != 0U); + rtb_y_l = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel2_bit, &rtb_Switch7_c); - rtb_y_m = (rtb_y_m || rtb_y_am || (rtb_Switch7_c != 0U)); - rtb_AND4_a = (rtb_y_b && rtb_y_m); + rtb_y_f5 = (rtb_y_f5 || rtb_y_l || (rtb_Switch7_c != 0U)); + rtb_AND4_a = (rtb_y_la && rtb_y_f5); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_NOT_bl); - rtb_AND4_a = (rtb_OR1 || (rtb_AND4_a && (!rtb_NOT_bl)) || (rtb_y_k4 && rtb_AND4_a)); + rtb_AND4_a = (rtb_OR6 || (rtb_AND4_a && (!rtb_NOT_bl)) || (rtb_y_ls && rtb_AND4_a)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel15_bit, &rtb_Switch7_c); - rtb_y_am = (rtb_Switch7_c != 0U); - SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_y_l); + rtb_y_l = (rtb_Switch7_c != 0U); + SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_y_j); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel14_bit, &rtb_Switch7_c); - rtb_y_k4 = (rtb_Switch7_c != 0U); + rtb_y_ls = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel11_bit, &rtb_Switch7_c); rtb_AND1_h = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel8_bit, &rtb_Switch7_c); - rtb_OR1 = ((!rtb_y_k4) && (!rtb_AND1_h) && (rtb_Switch7_c == 0U)); + rtb_OR6 = ((!rtb_y_ls) && (!rtb_AND1_h) && (rtb_Switch7_c == 0U)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel16_bit, &rtb_Switch7_c); rtb_NOT_bl = (rtb_Switch7_c != 0U); - SecComputer_MATLABFunction_n((rtb_Switch7_c != 0U) && rtb_OR && rtb_OR6, SecComputer_U.in.time.dt, - SecComputer_P.ConfirmNode_isRisingEdge, SecComputer_P.ConfirmNode_timeDelay, &rtb_OR6, + SecComputer_MATLABFunction_n((rtb_Switch7_c != 0U) && rtb_y_ei && rtb_OR, SecComputer_U.in.time.dt, + SecComputer_P.ConfirmNode_isRisingEdge, SecComputer_P.ConfirmNode_timeDelay, &rtb_OR, &SecComputer_DWork.sf_MATLABFunction_jk); - rtb_OR = (rtb_y_am && rtb_y_l && rtb_OR1 && rtb_OR6); + rtb_OR = (rtb_y_l && rtb_y_j && rtb_OR6 && rtb_OR); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, &rtb_AND1_h); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_NOT_bl); rtb_OR6 = ((!rtb_AND1_h) && (!rtb_NOT_bl)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel7_bit, &rtb_Switch7_c); rtb_NOT_bl = (rtb_Switch7_c != 0U); - SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_y_l); + SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, &rtb_y_j); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel6_bit, &rtb_Switch7_c); rtb_AND1_h = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel3_bit, &rtb_Switch7_c); - rtb_y_am = (rtb_Switch7_c != 0U); + rtb_y_l = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_3, SecComputer_P.BitfromLabel1_bit, &rtb_Switch7_c); - rtb_OR1 = (rtb_NOT_bl && rtb_y_l && ((!rtb_AND1_h) && (!rtb_y_am) && (rtb_Switch7_c == 0U))); + rtb_OR1 = (rtb_NOT_bl && rtb_y_j && ((!rtb_AND1_h) && (!rtb_y_l) && (rtb_Switch7_c == 0U))); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_3, SecComputer_P.BitfromLabel9_bit, &rtb_Switch7_c); rtb_NOT_bl = (rtb_Switch7_c != 0U); - SecComputer_MATLABFunction_n((rtb_Switch7_c != 0U) && rtb_y_b && rtb_y_m, SecComputer_U.in.time.dt, + SecComputer_MATLABFunction_n((rtb_Switch7_c != 0U) && rtb_y_la && rtb_y_f5, SecComputer_U.in.time.dt, SecComputer_P.ConfirmNode1_isRisingEdge, SecComputer_P.ConfirmNode1_timeDelay, &rtb_NOT_bl, &SecComputer_DWork.sf_MATLABFunction_dw); - rtb_OR6 = (rtb_OR || rtb_OR6 || (rtb_OR1 && rtb_NOT_bl)); + rtb_OR = (rtb_OR || rtb_OR6 || (rtb_OR1 && rtb_NOT_bl)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel4_bit_c, &rtb_Switch7_c); rtb_NOT_bl = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_2, SecComputer_P.BitfromLabel6_bit_l, &rtb_Switch7_c); - rtb_OR = (rtb_NOT_bl || (rtb_Switch7_c != 0U)); + rtb_OR6 = (rtb_NOT_bl || (rtb_Switch7_c != 0U)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel5_bit_a, &rtb_Switch7_c); rtb_NOT_bl = (rtb_Switch7_c != 0U); @@ -486,22 +488,22 @@ void SecComputer::step() if (SecComputer_DWork.is_active_c8_SecComputer == 0U) { SecComputer_DWork.is_active_c8_SecComputer = 1U; SecComputer_DWork.is_c8_SecComputer = SecComputer_IN_OnGround; - rtb_OR1 = true; + rtb_OR6 = true; } else if (SecComputer_DWork.is_c8_SecComputer == SecComputer_IN_InAir) { - if ((static_cast(rtb_OR) > 0.1) || (static_cast(rtb_OR1) > 0.1)) { + if ((static_cast(rtb_OR6) > 0.1) || (static_cast(rtb_OR1) > 0.1)) { SecComputer_DWork.is_c8_SecComputer = SecComputer_IN_OnGround; - rtb_OR1 = true; + rtb_OR6 = true; } else { - rtb_OR1 = false; + rtb_OR6 = false; } - } else if ((!rtb_OR) && (!rtb_OR1)) { + } else if ((!rtb_OR6) && (!rtb_OR1)) { SecComputer_DWork.is_c8_SecComputer = SecComputer_IN_InAir; - rtb_OR1 = false; + rtb_OR6 = false; } else { - rtb_OR1 = true; + rtb_OR6 = true; } - rtb_OR3 = (SecComputer_U.in.sim_data.slew_on || SecComputer_U.in.sim_data.pause_on || + rtb_OR1 = (SecComputer_U.in.sim_data.slew_on || SecComputer_U.in.sim_data.pause_on || SecComputer_U.in.sim_data.tracking_mode_on_override); if (SecComputer_DWork.is_active_c30_SecComputer == 0U) { SecComputer_DWork.is_active_c30_SecComputer = 1U; @@ -510,7 +512,7 @@ void SecComputer::step() } else { switch (SecComputer_DWork.is_c30_SecComputer) { case SecComputer_IN_Flight: - if (rtb_OR1 && (rtb_theta < 2.5F)) { + if (rtb_OR6 && (rtb_theta < 2.5F)) { SecComputer_DWork.on_ground_time = SecComputer_U.in.time.simulation_time; SecComputer_DWork.is_c30_SecComputer = SecComputer_IN_FlightToGroundTransition; } else { @@ -522,7 +524,7 @@ void SecComputer::step() if (SecComputer_U.in.time.simulation_time - SecComputer_DWork.on_ground_time >= 5.0) { SecComputer_DWork.is_c30_SecComputer = SecComputer_IN_Ground; SecComputer_B.in_flight = 0.0; - } else if ((!rtb_OR1) || (rtb_theta >= 2.5F)) { + } else if ((!rtb_OR6) || (rtb_theta >= 2.5F)) { SecComputer_DWork.on_ground_time = 0.0; SecComputer_DWork.is_c30_SecComputer = SecComputer_IN_Flight; SecComputer_B.in_flight = 1.0; @@ -530,7 +532,7 @@ void SecComputer::step() break; default: - if (((!rtb_OR1) && (rtb_theta > 8.0F)) || (SecComputer_P.Constant_Value_m > 400.0)) { + if (((!rtb_OR6) && (rtb_theta > 8.0F)) || (SecComputer_P.Constant_Value_m > 400.0)) { SecComputer_DWork.on_ground_time = 0.0; SecComputer_DWork.is_c30_SecComputer = SecComputer_IN_Flight; SecComputer_B.in_flight = 1.0; @@ -543,13 +545,13 @@ void SecComputer::step() rtb_NOT_bl = (SecComputer_B.in_flight != 0.0); SecComputer_MATLABFunction_n(!SecComputer_U.in.discrete_inputs.yellow_low_pressure, SecComputer_U.in.time.dt, - SecComputer_P.ConfirmNode_isRisingEdge_a, SecComputer_P.ConfirmNode_timeDelay_c, &rtb_OR, + SecComputer_P.ConfirmNode_isRisingEdge_a, SecComputer_P.ConfirmNode_timeDelay_c, &rtb_y_ei, &SecComputer_DWork.sf_MATLABFunction_ndv); SecComputer_MATLABFunction_n(!SecComputer_U.in.discrete_inputs.blue_low_pressure, SecComputer_U.in.time.dt, - SecComputer_P.ConfirmNode1_isRisingEdge_j, SecComputer_P.ConfirmNode1_timeDelay_k, &rtb_y_l, + SecComputer_P.ConfirmNode1_isRisingEdge_j, SecComputer_P.ConfirmNode1_timeDelay_k, &rtb_y_j, &SecComputer_DWork.sf_MATLABFunction_gf); SecComputer_MATLABFunction_n(!SecComputer_U.in.discrete_inputs.green_low_pressure, SecComputer_U.in.time.dt, - SecComputer_P.ConfirmNode2_isRisingEdge, SecComputer_P.ConfirmNode2_timeDelay, &rtb_y_b, + SecComputer_P.ConfirmNode2_isRisingEdge, SecComputer_P.ConfirmNode2_timeDelay, &rtb_y_la, &SecComputer_DWork.sf_MATLABFunction_h); rtb_BusAssignment_f_logic_ir_computation_data_n_z_g = rtb_n_z; rtb_BusAssignment_f_logic_ir_computation_data_theta_dot_deg_s = rtb_theta_dot; @@ -601,32 +603,32 @@ void SecComputer::step() } if (SecComputer_U.in.discrete_inputs.is_unit_1) { - leftElevatorAvail = ((!SecComputer_U.in.discrete_inputs.l_elev_servo_failed) && rtb_y_l); - rightElevatorAvail = ((!SecComputer_U.in.discrete_inputs.r_elev_servo_failed) && rtb_y_l); + rtb_OR3 = ((!SecComputer_U.in.discrete_inputs.l_elev_servo_failed) && rtb_y_j); + rightElevatorAvail = ((!SecComputer_U.in.discrete_inputs.r_elev_servo_failed) && rtb_y_j); } else { - leftElevatorAvail = ((!SecComputer_U.in.discrete_inputs.l_elev_servo_failed) && rtb_y_b); - rightElevatorAvail = ((!SecComputer_U.in.discrete_inputs.r_elev_servo_failed) && rtb_OR); + rtb_OR3 = ((!SecComputer_U.in.discrete_inputs.l_elev_servo_failed) && rtb_y_la); + rightElevatorAvail = ((!SecComputer_U.in.discrete_inputs.r_elev_servo_failed) && rtb_y_ei); } - rtb_thsAvail = ((!SecComputer_U.in.discrete_inputs.ths_motor_fault) && (rtb_OR || rtb_y_b)); - canEngageInPitch = ((leftElevatorAvail || rightElevatorAvail) && (!SecComputer_U.in.discrete_inputs.is_unit_3)); + rtb_thsAvail = ((!SecComputer_U.in.discrete_inputs.ths_motor_fault) && (rtb_y_ei || rtb_y_la)); + canEngageInPitch = ((rtb_OR3 || rightElevatorAvail) && (!SecComputer_U.in.discrete_inputs.is_unit_3)); if (SecComputer_U.in.discrete_inputs.is_unit_1) { hasPriorityInPitch = (SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1 && SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2 && SecComputer_U.in.discrete_inputs.left_elev_not_avail_sec_opp && SecComputer_U.in.discrete_inputs.right_elev_not_avail_sec_opp); - spoilerPair1SupplyAvail = rtb_y_l; - spoilerPair2SupplyAvail = rtb_OR; + spoilerPair1SupplyAvail = rtb_y_j; + spoilerPair2SupplyAvail = rtb_y_ei; } else { hasPriorityInPitch = (SecComputer_U.in.discrete_inputs.is_unit_2 && (SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1 && SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2)); if (SecComputer_U.in.discrete_inputs.is_unit_2) { - spoilerPair1SupplyAvail = rtb_y_b; + spoilerPair1SupplyAvail = rtb_y_la; spoilerPair2SupplyAvail = false; } else { - spoilerPair1SupplyAvail = rtb_y_b; - spoilerPair2SupplyAvail = rtb_OR; + spoilerPair1SupplyAvail = rtb_y_la; + spoilerPair2SupplyAvail = rtb_y_ei; } } @@ -642,7 +644,7 @@ void SecComputer::step() SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_1_bus.discrete_status_word_1, SecComputer_P.BitfromLabel_bit, &rtb_Switch7_c); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.elac_1_bus.discrete_status_word_1, &rtb_AND4_a); - rtb_y_k4 = ((rtb_Switch7_c != 0U) && rtb_AND4_a); + rtb_y_ls = ((rtb_Switch7_c != 0U) && rtb_AND4_a); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_1, SecComputer_P.BitfromLabel1_bit_g, &rtb_Switch7_c); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_1, &rtb_AND1_h); @@ -658,20 +660,20 @@ void SecComputer::step() SecComputer_MATLABFunction_n(SecComputer_U.in.sim_data.slew_on, SecComputer_U.in.time.dt, SecComputer_P.ConfirmNode_isRisingEdge_g, SecComputer_P.ConfirmNode_timeDelay_e, &rtb_NOT_bl, &SecComputer_DWork.sf_MATLABFunction_k4); - rtb_y_am = !rtb_OR1; - abnormalCondition = ((!rtb_NOT_bl) && rtb_y_am && (((!rtb_doubleAdrFault) && ((rtb_mach > 0.91) || (rtb_alpha < + rtb_y_l = !rtb_OR6; + abnormalCondition = ((!rtb_NOT_bl) && rtb_y_l && (((!rtb_doubleAdrFault) && ((rtb_mach > 0.91) || (rtb_alpha < -10.0F) || (rtb_alpha > 40.0F) || (rtb_V_ias > 440.0F) || (rtb_V_ias < 60.0F))) || ((!rtb_doubleIrFault) && ((!rtb_singleIrFault) || (!SecComputer_P.Constant_Value_l)) && ((std::abs(static_cast(rtb_phi)) > 125.0) || ((rtb_theta > 50.0F) || (rtb_theta < -30.0F)))))); - SecComputer_DWork.abnormalConditionWasActive = (abnormalCondition || (rtb_y_am && + SecComputer_DWork.abnormalConditionWasActive = (abnormalCondition || (rtb_y_l && SecComputer_DWork.abnormalConditionWasActive)); if (rtb_doubleIrFault || ((SecComputer_B.in_flight != 0.0) && - ((rtb_BusAssignment_n_logic_any_landing_gear_not_uplocked && (!rtb_OR6)) || ((rtb_AND4_a || ((rtb_Switch7_c != - 0U) && rtb_AND1_h)) && rtb_OR6)))) { + ((rtb_BusAssignment_n_logic_any_landing_gear_not_uplocked && (!rtb_OR)) || ((rtb_AND4_a || ((rtb_Switch7_c != + 0U) && rtb_AND1_h)) && rtb_OR)))) { rtb_pitchLawCapability = pitch_efcs_law::DirectLaw; } else if ((rtb_singleAdrFault && SecComputer_P.Constant2_Value_c) || rtb_doubleAdrFault || - SecComputer_DWork.abnormalConditionWasActive || ((!rtb_y_k4) && (!rtb_AND2_j) && ((!leftElevatorAvail) || - (!rightElevatorAvail)))) { + SecComputer_DWork.abnormalConditionWasActive || ((!rtb_y_ls) && (!rtb_AND2_j) && ((!rtb_OR3) || + (!rightElevatorAvail)))) { rtb_pitchLawCapability = pitch_efcs_law::AlternateLaw2; } else { rtb_pitchLawCapability = pitch_efcs_law::AlternateLaw1; @@ -702,20 +704,20 @@ void SecComputer::step() u0 = SecComputer_P.Saturation_LowerSat_h; } - SecComputer_MATLABFunction_e(SecComputer_B.in_flight != 0.0, SecComputer_P.PulseNode_isRisingEdge_h, &rtb_y_k4, + SecComputer_MATLABFunction_e(SecComputer_B.in_flight != 0.0, SecComputer_P.PulseNode_isRisingEdge_h, &rtb_y_ls, &SecComputer_DWork.sf_MATLABFunction_b4); - rtb_y_am = (SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1 && - SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2); - rtb_AND1_h = (SecComputer_U.in.discrete_inputs.is_unit_1 && rtb_thsAvail && rtb_y_am); + rtb_y_l = (SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1 && + SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2); + rtb_AND1_h = (SecComputer_U.in.discrete_inputs.is_unit_1 && rtb_thsAvail && rtb_y_l); SecComputer_DWork.Memory_PreviousInput = SecComputer_P.Logic_table[((((!rtb_AND1_h) || (std::abs (SecComputer_U.in.analog_inputs.ths_pos_deg) <= SecComputer_P.CompareToConstant1_const) || - SecComputer_U.in.discrete_inputs.ths_override_active) + (static_cast(rtb_y_k4) << 1)) << 1) + + SecComputer_U.in.discrete_inputs.ths_override_active) + (static_cast(rtb_y_ls) << 1)) << 1) + SecComputer_DWork.Memory_PreviousInput]; rtb_NOT_bl = (rtb_AND1_h && SecComputer_DWork.Memory_PreviousInput); rtb_AND4_a = !abnormalCondition; rtb_AND1_h = ((rtb_isEngagedInPitch && (SecComputer_B.in_flight != 0.0) && ((rtb_activePitchLaw != SecComputer_P.EnumeratedConstant_Value_f) && rtb_AND4_a)) || rtb_NOT_bl); - rtb_y_k4 = rtb_AND1_h; + rtb_y_ls = rtb_AND1_h; rtb_AND2_j = rtb_NOT_bl; SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_1_bus.discrete_status_word_2, SecComputer_P.BitfromLabel7_bit_g, &rtb_Switch7_c); @@ -724,7 +726,7 @@ void SecComputer::step() SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_2, SecComputer_P.BitfromLabel6_bit_f, &rtb_Switch7_c); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_2, &rtb_AND4_a); - rtb_y_m = ((rtb_Switch7_c != 0U) && rtb_AND4_a); + rtb_y_f5 = ((rtb_Switch7_c != 0U) && rtb_AND4_a); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_actual_position_word, SecComputer_P.BitfromLabel_bit_l, &rtb_Switch7_c); SecComputer_MATLABFunction_l(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_actual_position_word, &rtb_AND4_a); @@ -744,76 +746,77 @@ void SecComputer::step() rtb_NOT_g = (rtb_Switch7_c == 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_1, SecComputer_P.BitfromLabel2_bit_p, &rtb_Switch7_c); - rtb_NOT_bl = (rtb_NOT_bl || rtb_y_m || (rtb_AND4_a || rtb_AND1_h) || (((!rtb_y_am) && rtb_NOT2_b && (rtb_NOT_g || - (rtb_Switch7_c == 0U))) || (rtb_y_am && ((SecComputer_U.in.discrete_inputs.left_elev_not_avail_sec_opp && - (!leftElevatorAvail)) || (SecComputer_U.in.discrete_inputs.right_elev_not_avail_sec_opp && (!rightElevatorAvail))))) - || ((SecComputer_U.in.analog_inputs.thr_lever_1_pos >= SecComputer_P.CompareToConstant3_const) || - (SecComputer_U.in.analog_inputs.thr_lever_2_pos >= SecComputer_P.CompareToConstant4_const))); + rtb_NOT_bl = (rtb_NOT_bl || rtb_y_f5 || (rtb_AND4_a || rtb_AND1_h) || (((!rtb_y_l) && rtb_NOT2_b && (rtb_NOT_g || + (rtb_Switch7_c == 0U))) || (rtb_y_l && ((SecComputer_U.in.discrete_inputs.left_elev_not_avail_sec_opp && (!rtb_OR3)) + || (SecComputer_U.in.discrete_inputs.right_elev_not_avail_sec_opp && (!rightElevatorAvail))))) || + ((SecComputer_U.in.analog_inputs.thr_lever_1_pos >= SecComputer_P.CompareToConstant3_const) || + (SecComputer_U.in.analog_inputs.thr_lever_2_pos >= SecComputer_P.CompareToConstant4_const))); SecComputer_MATLABFunction_n(SecComputer_U.in.analog_inputs.spd_brk_lever_pos < SecComputer_P.CompareToConstant_const, SecComputer_U.in.time.dt, SecComputer_P.ConfirmNode_isRisingEdge_e, - SecComputer_P.ConfirmNode_timeDelay_eq, &rtb_y_m, &SecComputer_DWork.sf_MATLABFunction_fh); + SecComputer_P.ConfirmNode_timeDelay_eq, &rtb_y_f5, &SecComputer_DWork.sf_MATLABFunction_fh); SecComputer_DWork.Memory_PreviousInput_f = SecComputer_P.Logic_table_i[(((static_cast(rtb_NOT_bl) << 1) + - rtb_y_m) << 1) + SecComputer_DWork.Memory_PreviousInput_f]; - rtb_y_m = (rtb_NOT_bl || SecComputer_DWork.Memory_PreviousInput_f); - rtb_NOT2_b = rtb_y_l; - rtb_NOT_g = rtb_y_b; - SecComputer_MATLABFunction_e(rtb_OR1, SecComputer_P.PulseNode3_isRisingEdge, &rtb_y_b, + rtb_y_f5) << 1) + SecComputer_DWork.Memory_PreviousInput_f]; + rtb_y_f5 = (rtb_NOT_bl || SecComputer_DWork.Memory_PreviousInput_f); + rtb_NOT2_b = rtb_y_ei; + rtb_NOT_g = rtb_y_j; + rtb_BusAssignment_fz_logic_is_green_hydraulic_power_avail = rtb_y_la; + SecComputer_MATLABFunction_e(rtb_OR6, SecComputer_P.PulseNode3_isRisingEdge, &rtb_y_la, &SecComputer_DWork.sf_MATLABFunction_nd); - rtb_NOT_bl = (rtb_y_b || ((SecComputer_U.in.analog_inputs.wheel_speed_left < SecComputer_P.CompareToConstant11_const) - && (SecComputer_U.in.analog_inputs.wheel_speed_right < SecComputer_P.CompareToConstant12_const))); - SecComputer_MATLABFunction_e(rtb_OR1, SecComputer_P.PulseNode2_isRisingEdge, &rtb_y_b, + rtb_NOT_bl = (rtb_y_la || ((SecComputer_U.in.analog_inputs.wheel_speed_left < + SecComputer_P.CompareToConstant11_const) && (SecComputer_U.in.analog_inputs.wheel_speed_right < + SecComputer_P.CompareToConstant12_const))); + SecComputer_MATLABFunction_e(rtb_OR6, SecComputer_P.PulseNode2_isRisingEdge, &rtb_y_la, &SecComputer_DWork.sf_MATLABFunction_n); SecComputer_DWork.Memory_PreviousInput_n = SecComputer_P.Logic_table_ii[(((static_cast(rtb_NOT_bl) << 1) + - rtb_y_b) << 1) + SecComputer_DWork.Memory_PreviousInput_n]; + rtb_y_la) << 1) + SecComputer_DWork.Memory_PreviousInput_n]; SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel4_bit_a, &rtb_Switch7_c); rtb_AND1_h = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_2, SecComputer_P.BitfromLabel6_bit_d, &rtb_Switch7_c); - rtb_y_b = (rtb_AND1_h && (rtb_Switch7_c != 0U)); + rtb_y_la = (rtb_AND1_h && (rtb_Switch7_c != 0U)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel5_bit_i, &rtb_Switch7_c); rtb_AND1_h = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_2, SecComputer_P.BitfromLabel7_bit_ms, &rtb_Switch7_c); - SecComputer_MATLABFunction_e(rtb_y_b || (rtb_AND1_h && (rtb_Switch7_c != 0U)), - SecComputer_P.PulseNode1_isRisingEdge_k, &rtb_y_l, &SecComputer_DWork.sf_MATLABFunction_a); + SecComputer_MATLABFunction_e(rtb_y_la || (rtb_AND1_h && (rtb_Switch7_c != 0U)), + SecComputer_P.PulseNode1_isRisingEdge_k, &rtb_y_j, &SecComputer_DWork.sf_MATLABFunction_a); rtb_NOT_bl = (SecComputer_U.in.analog_inputs.spd_brk_lever_pos < SecComputer_P.CompareToConstant_const_m); - SecComputer_DWork.Delay1_DSTATE_i = (((((SecComputer_U.in.analog_inputs.spd_brk_lever_pos > - SecComputer_P.CompareToConstant15_const) || rtb_NOT_bl) && ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= - SecComputer_P.CompareToConstant1_const_l) || (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= + rtb_AND1_h = ((((SecComputer_U.in.analog_inputs.spd_brk_lever_pos > SecComputer_P.CompareToConstant15_const) || + rtb_NOT_bl) && ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= + SecComputer_P.CompareToConstant1_const_l) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= SecComputer_P.CompareToConstant2_const))) || (((SecComputer_U.in.analog_inputs.thr_lever_1_pos < SecComputer_P.CompareToConstant3_const_a) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= SecComputer_P.CompareToConstant4_const_j)) || ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= SecComputer_P.CompareToConstant13_const) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos < - SecComputer_P.CompareToConstant14_const)))) && (rtb_y_l || ((SecComputer_U.in.analog_inputs.wheel_speed_left >= + SecComputer_P.CompareToConstant14_const)))); + SecComputer_DWork.Delay1_DSTATE_i = (rtb_AND1_h && (rtb_y_j || ((SecComputer_U.in.analog_inputs.wheel_speed_left >= SecComputer_P.CompareToConstant5_const) && (SecComputer_U.in.analog_inputs.wheel_speed_right >= SecComputer_P.CompareToConstant6_const) && SecComputer_DWork.Memory_PreviousInput_n) || SecComputer_DWork.Delay1_DSTATE_i)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel_bit_g, &rtb_Switch7_c); - rtb_AND1_h = (rtb_Switch7_c != 0U); + rtb_AND4_a = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_2, SecComputer_P.BitfromLabel2_bit_l, &rtb_Switch7_c); - rtb_y_b = (rtb_AND1_h || (rtb_Switch7_c != 0U)); + rtb_y_la = (rtb_AND4_a || (rtb_Switch7_c != 0U)); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_1_bus.discrete_word_2, SecComputer_P.BitfromLabel1_bit_a, &rtb_Switch7_c); - rtb_AND1_h = (rtb_Switch7_c != 0U); + rtb_AND4_a = (rtb_Switch7_c != 0U); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.lgciu_2_bus.discrete_word_2, SecComputer_P.BitfromLabel3_bit_m, &rtb_Switch7_c); - SecComputer_MATLABFunction_e(rtb_y_b || (rtb_AND1_h || (rtb_Switch7_c != 0U)), - SecComputer_P.PulseNode_isRisingEdge_hj, &rtb_y_l, &SecComputer_DWork.sf_MATLABFunction_e3); - SecComputer_DWork.Delay_DSTATE_n = (((((SecComputer_U.in.analog_inputs.spd_brk_lever_pos > - SecComputer_P.CompareToConstant10_const) || rtb_NOT_bl) && ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= - SecComputer_P.CompareToConstant7_const) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= - SecComputer_P.CompareToConstant16_const))) || (((SecComputer_U.in.analog_inputs.thr_lever_1_pos < - SecComputer_P.CompareToConstant17_const) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= - SecComputer_P.CompareToConstant18_const)) || ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= - SecComputer_P.CompareToConstant8_const) && (SecComputer_U.in.analog_inputs.thr_lever_2_pos < - SecComputer_P.CompareToConstant9_const)))) && (rtb_y_l || SecComputer_DWork.Delay_DSTATE_n)); - rtb_AND1_h = ((!SecComputer_DWork.Delay1_DSTATE_i) && SecComputer_DWork.Delay_DSTATE_n); + rtb_y_l = (rtb_Switch7_c != 0U); + SecComputer_MATLABFunction_e(rtb_y_la || (rtb_AND4_a || (rtb_Switch7_c != 0U)), + SecComputer_P.PulseNode_isRisingEdge_hj, &rtb_y_ei, &SecComputer_DWork.sf_MATLABFunction_e3); + SecComputer_DWork.Delay_DSTATE_n = (rtb_AND1_h && (rtb_y_ei || SecComputer_DWork.Delay_DSTATE_n)); + rtb_AND4_a = (SecComputer_U.in.analog_inputs.thr_lever_2_pos <= SecComputer_P.CompareToConstant8_const); + SecComputer_DWork.Delay2_DSTATE = (rtb_NOT_bl && ((SecComputer_U.in.analog_inputs.thr_lever_1_pos <= + SecComputer_P.CompareToConstant7_const) && rtb_AND4_a) && (rtb_y_j || SecComputer_DWork.Delay2_DSTATE)); + rtb_AND1_h = ((!SecComputer_DWork.Delay1_DSTATE_i) && (SecComputer_DWork.Delay_DSTATE_n || + SecComputer_DWork.Delay2_DSTATE)); SecComputer_Y.out.logic.total_sidestick_roll_command = pair1SpdBrkCommand; - rtb_y_b = rtb_NOT_bl; + rtb_y_la = rtb_NOT_bl; if (SecComputer_DWork.Delay1_DSTATE_i) { rtb_Switch5 = SecComputer_P.Constant_Value; } else if (rtb_AND1_h) { @@ -830,7 +833,7 @@ void SecComputer::step() SecComputer_P.BitfromLabel4_bit_m, &rtb_Switch7_c); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_2, SecComputer_P.BitfromLabel5_bit_h, &rtb_y); - if (rtb_y_m) { + if (rtb_y_f5) { rtb_Switch3 = SecComputer_P.Constant3_Value; } else { if ((rtb_Switch7_c != 0U) || (rtb_y != 0U)) { @@ -861,26 +864,26 @@ void SecComputer::step() SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_1_bus.discrete_status_word_1, SecComputer_P.BitfromLabel2_bit_o, &rtb_y_af); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.elac_2_bus.discrete_status_word_1, - SecComputer_P.BitfromLabel3_bit_j, &rtb_y_mx); + SecComputer_P.BitfromLabel3_bit_j, &rtb_y_m); if (SecComputer_U.in.bus_inputs.elac_1_bus.roll_spoiler_command_deg.SSM == static_cast(SignStatusMatrix:: NormalOperation)) { pair1SpdBrkCommand = SecComputer_U.in.bus_inputs.elac_1_bus.roll_spoiler_command_deg.Data; - rtb_y_l = (rtb_Switch7_c != 0U); - rtb_AND4_a = (rtb_y_af != 0U); + rtb_y_j = (rtb_Switch7_c != 0U); + rtb_y_ei = (rtb_y_af != 0U); } else if (SecComputer_U.in.bus_inputs.elac_2_bus.roll_spoiler_command_deg.SSM == static_cast (SignStatusMatrix::NormalOperation)) { pair1SpdBrkCommand = SecComputer_U.in.bus_inputs.elac_2_bus.roll_spoiler_command_deg.Data; - rtb_y_l = (rtb_y != 0U); - rtb_AND4_a = (rtb_y_mx != 0U); + rtb_y_j = (rtb_y != 0U); + rtb_y_ei = (rtb_y_m != 0U); } else { pair1SpdBrkCommand = rtb_Switch3 * 35.0 / 25.0; - rtb_y_l = true; - rtb_AND4_a = true; + rtb_y_j = true; + rtb_y_ei = true; } rtb_zeta_deg = std::fmax(std::fmin(pair1SpdBrkCommand, 35.0), -35.0); if (SecComputer_U.in.discrete_inputs.is_unit_1) { - if (rtb_y_l) { + if (rtb_y_j) { pair1RollCommand = rtb_zeta_deg; } else { pair1RollCommand = 0.0; @@ -896,7 +899,7 @@ void SecComputer::step() pair2SpdBrkCommand = 0.0; } else { pair1RollCommand = 0.0; - if (rtb_AND4_a) { + if (rtb_y_ei) { rtb_Switch3 = rtb_zeta_deg; } else { rtb_Switch3 = 0.0; @@ -984,7 +987,7 @@ void SecComputer::step() pair1RollCommand = pair1SpdBrkCommand; rtb_NOT_oi = rtb_handleIndex; SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_system_status_word, - SecComputer_P.BitfromLabel_bit_a1, &rtb_y_mx); + SecComputer_P.BitfromLabel_bit_a1, &rtb_y_m); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_system_status_word, SecComputer_P.BitfromLabel1_bit_gf, &rtb_y_af); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_system_status_word, @@ -995,7 +998,7 @@ void SecComputer::step() SecComputer_P.BitfromLabel4_bit_n, &rtb_DataTypeConversion1); SecComputer_MATLABFunction(&SecComputer_U.in.bus_inputs.sfcc_1_bus.slat_flap_system_status_word, SecComputer_P.BitfromLabel5_bit_m, &rtb_Switch7_c); - if (rtb_y_mx != 0U) { + if (rtb_y_m != 0U) { rtb_handleIndex = 0.0; } else if ((rtb_y_af != 0U) && (rtb_Switch7_c != 0U)) { rtb_handleIndex = 1.0; @@ -1012,16 +1015,16 @@ void SecComputer::step() } pair1SpdBrkCommand = (SecComputer_B.in_flight != 0.0); - rtb_y_l = (rtb_OR3 || ((static_cast(rtb_activePitchLaw) != SecComputer_P.CompareToConstant2_const_f) && ( + rtb_y_j = (rtb_OR1 || ((static_cast(rtb_activePitchLaw) != SecComputer_P.CompareToConstant2_const_f) && ( static_cast(rtb_activePitchLaw) != SecComputer_P.CompareToConstant3_const_o))); - rtb_AND4_a = (rtb_activePitchLaw != SecComputer_P.EnumeratedConstant_Value_i); + rtb_y_ei = (rtb_activePitchLaw != SecComputer_P.EnumeratedConstant_Value_i); LawMDLOBJ2.step(&SecComputer_U.in.time.dt, &rtb_BusAssignment_f_logic_ir_computation_data_n_z_g, &rtb_Switch5_tmp_tmp, &rtb_Switch6_m, &rtb_BusAssignment_f_logic_ir_computation_data_theta_dot_deg_s, (const_cast(&SecComputer_RGND)), &SecComputer_U.in.analog_inputs.ths_pos_deg, &rtb_eta_trim_limit_lo_d, &rtb_BusConversion_InsertedFor_BusAssignment_at_inport_8_BusCreator1_mach, &rtb_BusConversion_InsertedFor_BusAssignment_at_inport_8_BusCreator1_V_tas_kn, &rtb_handleIndex, ( const_cast(&SecComputer_RGND)), (const_cast(&SecComputer_RGND)), &u0, &pair1SpdBrkCommand, - &rtb_y_l, &rtb_AND4_a, &rtb_eta_deg, &rtb_eta_trim_dot_deg_s, &rtb_eta_trim_limit_lo, + &rtb_y_j, &rtb_y_ei, &rtb_eta_deg, &rtb_eta_trim_dot_deg_s, &rtb_eta_trim_limit_lo, &rtb_eta_trim_limit_up); LawMDLOBJ3.step(&SecComputer_U.in.time.dt, &u0, &rtb_handleIndex, &rtb_zeta_deg, &rtb_eta_trim_limit_lo_d, &pair1SpdBrkCommand); @@ -1079,7 +1082,7 @@ void SecComputer::step() } rtb_zeta_deg = SecComputer_P.DiscreteTimeIntegratorVariableTsLimit_Gain * rtb_zeta_deg * SecComputer_U.in.time.dt; - SecComputer_DWork.icLoad = ((!rtb_y_k4) || SecComputer_DWork.icLoad); + SecComputer_DWork.icLoad = ((!rtb_y_ls) || SecComputer_DWork.icLoad); if (SecComputer_DWork.icLoad) { SecComputer_DWork.Delay_DSTATE_l = SecComputer_U.in.analog_inputs.ths_pos_deg - rtb_zeta_deg; } @@ -1113,28 +1116,28 @@ void SecComputer::step() } else if (SecComputer_U.in.discrete_inputs.is_unit_2) { rtb_Switch8 = SecComputer_U.in.bus_inputs.elac_1_bus.elevator_double_pressurization_command_deg; } else { - rtb_y_fp = std::fmod(std::floor(SecComputer_P.Constant1_Value_m), 4.2949673E+9F); - rtb_Switch8.SSM = rtb_y_fp < 0.0F ? static_cast(-static_cast(static_cast(-rtb_y_fp))) - : static_cast(rtb_y_fp); + rtb_y_e = std::fmod(std::floor(SecComputer_P.Constant1_Value_m), 4.2949673E+9F); + rtb_Switch8.SSM = rtb_y_e < 0.0F ? static_cast(-static_cast(static_cast(-rtb_y_e))) : + static_cast(rtb_y_e); rtb_Switch8.Data = SecComputer_P.Constant1_Value_m; } SecComputer_MATLABFunction_l(&rtb_Switch8, &rtb_AND4_a); if (SecComputer_U.in.discrete_inputs.is_unit_1) { - rtb_y_l = SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1; + rtb_y_j = SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_1; } else { - rtb_y_l = SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2; + rtb_y_j = SecComputer_U.in.discrete_inputs.pitch_not_avail_elac_2; } - rtb_NOT_bl = (rtb_y_l && (!rtb_isEngagedInPitch) && rtb_AND4_a); + rtb_NOT_bl = (rtb_y_j && (!rtb_isEngagedInPitch) && rtb_AND4_a); if (rtb_NOT_bl) { rtb_handleIndex = rtb_Switch8.Data; } - SecComputer_MATLABFunction_n(rtb_OR || rtb_NOT2_b || rtb_NOT_g, SecComputer_U.in.time.dt, - SecComputer_P.ConfirmNode_isRisingEdge_c, SecComputer_P.ConfirmNode_timeDelay_m, &rtb_y_am, - &SecComputer_DWork.sf_MATLABFunction_i); - rtb_y_fp = static_cast(SecComputer_U.in.analog_inputs.thr_lever_2_pos); + SecComputer_MATLABFunction_n(rtb_NOT2_b || rtb_NOT_g || rtb_BusAssignment_fz_logic_is_green_hydraulic_power_avail, + SecComputer_U.in.time.dt, SecComputer_P.ConfirmNode_isRisingEdge_c, SecComputer_P.ConfirmNode_timeDelay_m, + &rtb_y_l, &SecComputer_DWork.sf_MATLABFunction_i); + rtb_y_e = static_cast(SecComputer_U.in.analog_inputs.thr_lever_2_pos); rtb_VectorConcatenate[0] = (SecComputer_U.in.discrete_inputs.l_spoiler_1_servo_failed || SecComputer_U.in.discrete_inputs.r_spoiler_1_servo_failed); rtb_VectorConcatenate[1] = (SecComputer_U.in.discrete_inputs.l_spoiler_2_servo_failed || @@ -1143,7 +1146,7 @@ void SecComputer::step() rtb_VectorConcatenate[3] = SecComputer_U.in.discrete_inputs.r_elev_servo_failed; rtb_VectorConcatenate[4] = spoilerPair1SupplyAvail; rtb_VectorConcatenate[5] = spoilerPair2SupplyAvail; - rtb_VectorConcatenate[6] = leftElevatorAvail; + rtb_VectorConcatenate[6] = rtb_OR3; rtb_VectorConcatenate[7] = rightElevatorAvail; rtb_VectorConcatenate[8] = (rtb_activePitchLaw == pitch_efcs_law::AlternateLaw2); rtb_VectorConcatenate[9] = ((rtb_activePitchLaw == pitch_efcs_law::AlternateLaw1) || (rtb_activePitchLaw == @@ -1153,18 +1156,18 @@ void SecComputer::step() rtb_VectorConcatenate[12] = rtb_isEngagedInPitch; rtb_VectorConcatenate[13] = SecComputer_P.Constant8_Value; rtb_VectorConcatenate[14] = SecComputer_DWork.Delay1_DSTATE_i; - rtb_VectorConcatenate[15] = rtb_y_b; + rtb_VectorConcatenate[15] = rtb_y_la; rtb_VectorConcatenate[16] = SecComputer_P.Constant8_Value; rtb_VectorConcatenate[17] = SecComputer_P.Constant8_Value; rtb_VectorConcatenate[18] = SecComputer_P.Constant8_Value; - SecComputer_MATLABFunction_c(rtb_VectorConcatenate, &rtb_y_h); + SecComputer_MATLABFunction_c(rtb_VectorConcatenate, &rtb_y_fn); rtb_VectorConcatenate[0] = SecComputer_P.Constant7_Value; rtb_VectorConcatenate[1] = SecComputer_P.Constant7_Value; rtb_VectorConcatenate[2] = SecComputer_DWork.pLeftStickDisabled; rtb_VectorConcatenate[3] = SecComputer_DWork.pRightStickDisabled; rtb_VectorConcatenate[4] = SecComputer_DWork.Delay_DSTATE_c; rtb_VectorConcatenate[5] = SecComputer_DWork.Delay1_DSTATE; - rtb_VectorConcatenate[6] = rtb_OR6; + rtb_VectorConcatenate[6] = rtb_OR; rtb_VectorConcatenate[7] = rtb_BusAssignment_n_logic_any_landing_gear_not_uplocked; rtb_VectorConcatenate[8] = SecComputer_P.Constant10_Value; rtb_VectorConcatenate[9] = SecComputer_P.Constant10_Value; @@ -1177,7 +1180,7 @@ void SecComputer::step() rtb_VectorConcatenate[16] = SecComputer_P.Constant10_Value; rtb_VectorConcatenate[17] = SecComputer_P.Constant10_Value; rtb_VectorConcatenate[18] = SecComputer_P.Constant10_Value; - SecComputer_MATLABFunction_c(rtb_VectorConcatenate, &rtb_y_fp); + SecComputer_MATLABFunction_c(rtb_VectorConcatenate, &rtb_y_e); SecComputer_Y.out.data = SecComputer_U.in; SecComputer_Y.out.laws.lateral_law_outputs.left_spoiler_1_command_deg = rtb_Switch3; SecComputer_Y.out.laws.lateral_law_outputs.right_spoiler_1_command_deg = pair2SpdBrkCommand; @@ -1185,35 +1188,35 @@ void SecComputer::step() SecComputer_Y.out.laws.lateral_law_outputs.right_spoiler_2_command_deg = rtb_NOT_oi; SecComputer_Y.out.laws.lateral_law_outputs.speedbrake_command_deg = rtb_Switch5; SecComputer_Y.out.laws.pitch_law_outputs.ths_command_deg = SecComputer_DWork.Delay_DSTATE; - SecComputer_Y.out.logic.on_ground = rtb_OR1; + SecComputer_Y.out.logic.on_ground = rtb_OR6; SecComputer_Y.out.logic.pitch_law_in_flight = (SecComputer_B.in_flight != 0.0); - SecComputer_Y.out.logic.tracking_mode_on = rtb_OR3; + SecComputer_Y.out.logic.tracking_mode_on = rtb_OR1; SecComputer_Y.out.logic.pitch_law_capability = rtb_pitchLawCapability; SecComputer_Y.out.logic.active_pitch_law = rtb_activePitchLaw; SecComputer_Y.out.logic.abnormal_condition_law_active = abnormalCondition; SecComputer_Y.out.logic.is_engaged_in_pitch = rtb_isEngagedInPitch; SecComputer_Y.out.logic.can_engage_in_pitch = canEngageInPitch; SecComputer_Y.out.logic.has_priority_in_pitch = hasPriorityInPitch; - SecComputer_Y.out.logic.left_elevator_avail = leftElevatorAvail; + SecComputer_Y.out.logic.left_elevator_avail = rtb_OR3; SecComputer_Y.out.logic.right_elevator_avail = rightElevatorAvail; SecComputer_Y.out.logic.ths_avail = rtb_thsAvail; - SecComputer_Y.out.logic.ths_active_commanded = rtb_y_k4; + SecComputer_Y.out.logic.ths_active_commanded = rtb_y_ls; SecComputer_Y.out.logic.ths_ground_setting_active = rtb_AND2_j; SecComputer_Y.out.logic.is_engaged_in_roll = rtb_isEngagedInRoll; SecComputer_Y.out.logic.spoiler_pair_1_avail = spoilerPair1SupplyAvail; SecComputer_Y.out.logic.spoiler_pair_2_avail = spoilerPair2SupplyAvail; - SecComputer_Y.out.logic.is_yellow_hydraulic_power_avail = rtb_OR; - SecComputer_Y.out.logic.is_blue_hydraulic_power_avail = rtb_NOT2_b; - SecComputer_Y.out.logic.is_green_hydraulic_power_avail = rtb_NOT_g; + SecComputer_Y.out.logic.is_yellow_hydraulic_power_avail = rtb_NOT2_b; + SecComputer_Y.out.logic.is_blue_hydraulic_power_avail = rtb_NOT_g; + SecComputer_Y.out.logic.is_green_hydraulic_power_avail = rtb_BusAssignment_fz_logic_is_green_hydraulic_power_avail; SecComputer_Y.out.logic.left_sidestick_disabled = SecComputer_DWork.pLeftStickDisabled; SecComputer_Y.out.logic.right_sidestick_disabled = SecComputer_DWork.pRightStickDisabled; SecComputer_Y.out.logic.left_sidestick_priority_locked = SecComputer_DWork.Delay_DSTATE_c; SecComputer_Y.out.logic.right_sidestick_priority_locked = SecComputer_DWork.Delay1_DSTATE; SecComputer_Y.out.logic.total_sidestick_pitch_command = u0; - SecComputer_Y.out.logic.ground_spoilers_armed = rtb_y_b; + SecComputer_Y.out.logic.ground_spoilers_armed = rtb_y_la; SecComputer_Y.out.logic.ground_spoilers_out = SecComputer_DWork.Delay1_DSTATE_i; SecComputer_Y.out.logic.partial_lift_dumping_active = rtb_AND1_h; - SecComputer_Y.out.logic.speed_brake_inhibited = rtb_y_m; + SecComputer_Y.out.logic.speed_brake_inhibited = rtb_y_f5; SecComputer_Y.out.logic.single_adr_failure = rtb_singleAdrFault; SecComputer_Y.out.logic.double_adr_failure = rtb_doubleAdrFault; SecComputer_Y.out.logic.cas_or_mach_disagree = SecComputer_P.Constant2_Value_c; @@ -1235,30 +1238,30 @@ void SecComputer::step() SecComputer_Y.out.logic.ir_computation_data.theta_dot_deg_s = rtb_theta_dot; SecComputer_Y.out.logic.ir_computation_data.phi_dot_deg_s = rtb_phi_dot; SecComputer_Y.out.logic.any_landing_gear_not_uplocked = rtb_BusAssignment_n_logic_any_landing_gear_not_uplocked; - SecComputer_Y.out.logic.lgciu_uplock_disagree_or_fault = rtb_OR6; + SecComputer_Y.out.logic.lgciu_uplock_disagree_or_fault = rtb_OR; SecComputer_Y.out.discrete_outputs.thr_reverse_selected = SecComputer_P.Constant1_Value_g; - SecComputer_Y.out.discrete_outputs.left_elevator_ok = leftElevatorAvail; + SecComputer_Y.out.discrete_outputs.left_elevator_ok = rtb_OR3; SecComputer_Y.out.discrete_outputs.right_elevator_ok = rightElevatorAvail; SecComputer_Y.out.discrete_outputs.ground_spoiler_out = SecComputer_DWork.Delay1_DSTATE_i; SecComputer_Y.out.discrete_outputs.sec_failed = SecComputer_P.Constant2_Value_n; - SecComputer_Y.out.discrete_outputs.left_elevator_damping_mode = (rtb_isEngagedInPitch && leftElevatorAvail); + SecComputer_Y.out.discrete_outputs.left_elevator_damping_mode = (rtb_isEngagedInPitch && rtb_OR3); SecComputer_Y.out.discrete_outputs.right_elevator_damping_mode = (rtb_isEngagedInPitch && rightElevatorAvail); - SecComputer_Y.out.discrete_outputs.ths_active = (rtb_y_k4 && rtb_thsAvail); - SecComputer_Y.out.discrete_outputs.batt_power_supply = rtb_y_am; - rtb_y_l = (rtb_isEngagedInPitch || rtb_NOT_bl); - if (rtb_y_l && leftElevatorAvail) { + SecComputer_Y.out.discrete_outputs.ths_active = (rtb_y_ls && rtb_thsAvail); + SecComputer_Y.out.discrete_outputs.batt_power_supply = rtb_y_l; + rtb_y_j = (rtb_isEngagedInPitch || rtb_NOT_bl); + if (rtb_y_j && rtb_OR3) { SecComputer_Y.out.analog_outputs.left_elev_pos_order_deg = rtb_handleIndex; } else { SecComputer_Y.out.analog_outputs.left_elev_pos_order_deg = SecComputer_P.Constant_Value_h; } - if (rtb_y_l && rightElevatorAvail) { + if (rtb_y_j && rightElevatorAvail) { SecComputer_Y.out.analog_outputs.right_elev_pos_order_deg = rtb_handleIndex; } else { SecComputer_Y.out.analog_outputs.right_elev_pos_order_deg = SecComputer_P.Constant_Value_h; } - if (rtb_y_k4 && rtb_thsAvail) { + if (rtb_y_ls && rtb_thsAvail) { SecComputer_Y.out.analog_outputs.ths_pos_order_deg = SecComputer_DWork.Delay_DSTATE; } else { SecComputer_Y.out.analog_outputs.ths_pos_order_deg = SecComputer_P.Constant_Value_h; @@ -1394,10 +1397,10 @@ void SecComputer::step() (SecComputer_U.in.analog_inputs.thr_lever_2_pos); SecComputer_Y.out.bus_outputs.discrete_status_word_1.SSM = static_cast (SecComputer_P.EnumeratedConstant1_Value); - SecComputer_Y.out.bus_outputs.discrete_status_word_1.Data = rtb_y_h; + SecComputer_Y.out.bus_outputs.discrete_status_word_1.Data = rtb_y_fn; SecComputer_Y.out.bus_outputs.discrete_status_word_2.SSM = static_cast (SecComputer_P.EnumeratedConstant1_Value); - SecComputer_Y.out.bus_outputs.discrete_status_word_2.Data = rtb_y_fp; + SecComputer_Y.out.bus_outputs.discrete_status_word_2.Data = rtb_y_e; SecComputer_DWork.icLoad = false; SecComputer_DWork.Delay_DSTATE_l = SecComputer_DWork.Delay_DSTATE; } else { @@ -1414,6 +1417,7 @@ void SecComputer::initialize() SecComputer_DWork.Memory_PreviousInput_n = SecComputer_P.SRFlipFlop_initial_condition_k; SecComputer_DWork.Delay1_DSTATE_i = SecComputer_P.Delay1_InitialCondition_l; SecComputer_DWork.Delay_DSTATE_n = SecComputer_P.Delay_InitialCondition_j; + SecComputer_DWork.Delay2_DSTATE = SecComputer_P.Delay2_InitialCondition; SecComputer_DWork.Delay_DSTATE = SecComputer_P.Delay_InitialCondition; SecComputer_DWork.icLoad = true; LawMDLOBJ2.init(); diff --git a/src/fbw_a320/src/model/SecComputer.h b/src/fbw_a320/src/model/SecComputer.h index ae7935deeff..ede5cfbd4d8 100644 --- a/src/fbw_a320/src/model/SecComputer.h +++ b/src/fbw_a320/src/model/SecComputer.h @@ -46,6 +46,7 @@ class SecComputer final boolean_T Delay1_DSTATE; boolean_T Delay1_DSTATE_i; boolean_T Delay_DSTATE_n; + boolean_T Delay2_DSTATE; uint8_T is_active_c30_SecComputer; uint8_T is_c30_SecComputer; uint8_T is_active_c8_SecComputer; @@ -163,13 +164,8 @@ class SecComputer final real_T CompareToConstant4_const_j; real_T CompareToConstant13_const; real_T CompareToConstant14_const; - real_T CompareToConstant10_const; real_T CompareToConstant7_const; - real_T CompareToConstant16_const; - real_T CompareToConstant17_const; - real_T CompareToConstant18_const; real_T CompareToConstant8_const; - real_T CompareToConstant9_const; real_T CompareToConstant2_const_f; real_T CompareToConstant3_const_o; real_T CompareToConstant1_const_p; @@ -277,6 +273,7 @@ class SecComputer final boolean_T Logic_table_ii[16]; boolean_T Delay1_InitialCondition_l; boolean_T Delay_InitialCondition_j; + boolean_T Delay2_InitialCondition; boolean_T Constant1_Value_g; boolean_T Constant2_Value_n; boolean_T Constant8_Value; diff --git a/src/fbw_a320/src/model/SecComputer_data.cpp b/src/fbw_a320/src/model/SecComputer_data.cpp index 5de3d3e38c7..18ad6a448bb 100644 --- a/src/fbw_a320/src/model/SecComputer_data.cpp +++ b/src/fbw_a320/src/model/SecComputer_data.cpp @@ -242,19 +242,9 @@ SecComputer::Parameters_SecComputer_T SecComputer::SecComputer_P{ 0.0, - 0.05, - - 0.0, - - 0.0, - - 0.0, + 25.0, - 35.0, - - 35.0, - - 0.0, + 25.0, 1.0, @@ -1747,5 +1737,7 @@ SecComputer::Parameters_SecComputer_T SecComputer::SecComputer_P{ false, + false, + false }; diff --git a/src/fmgc/src/components/FcuSync.ts b/src/fmgc/src/components/FcuSync.ts new file mode 100644 index 00000000000..912ca1465b7 --- /dev/null +++ b/src/fmgc/src/components/FcuSync.ts @@ -0,0 +1,28 @@ +import { Arinc429Word } from '@shared/arinc429'; +import { LateralMode } from '@shared/autopilot'; +import { FmgcComponent } from './FmgcComponent'; + +// Note the logic for this is different on A330/350/380 + +export class FcuSync implements FmgcComponent { + private trueRef = false; + + // eslint-disable-next-line no-empty-function + init(): void {} + + update(_deltaTime: number): void { + const irMaint = Arinc429Word.fromSimVarValue('L:A32NX_ADIRS_IR_1_MAINT_WORD'); + const trueRefPb = SimVar.GetSimVarValue('L:A32NX_PUSH_TRUE_REF', 'bool'); + + const trueRef = (irMaint.getBitValueOr(15, false) || trueRefPb) && !irMaint.getBitValueOr(2, false); + + if (trueRef !== this.trueRef) { + this.trueRef = trueRef; + SimVar.SetSimVarValue('L:A32NX_FMGC_TRUE_REF', 'boolean', trueRef); + const activeMode = SimVar.GetSimVarValue('L:A32NX_FMA_LATERAL_MODE', 'number'); + if (activeMode === LateralMode.HDG || activeMode === LateralMode.TRACK) { + SimVar.SetSimVarValue('L:A32NX_FM_HEADING_SYNC', 'boolean', true); + } + } + } +} diff --git a/src/fmgc/src/components/index.ts b/src/fmgc/src/components/index.ts index 15fab9a004e..61eae3fa8e8 100644 --- a/src/fmgc/src/components/index.ts +++ b/src/fmgc/src/components/index.ts @@ -1,3 +1,4 @@ +import { FcuSync } from '@fmgc/components/FcuSync'; import { ReadySignal } from '@fmgc/components/ReadySignal'; import { FlightPlanManager } from '@fmgc/wtsdk'; import { EfisLabels } from './EfisLabels'; @@ -10,6 +11,7 @@ const components: FmgcComponent[] = [ fmsMessages, new EfisLabels(), new ReadySignal(), + new FcuSync(), ]; export function initComponents(baseInstrument: BaseInstrument, flightPlanManager: FlightPlanManager): void { diff --git a/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts b/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts index 5c7367c6268..483e68bf223 100644 --- a/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts +++ b/src/fmgc/src/flightplanning/FlightPlanAsoboSync.ts @@ -45,142 +45,159 @@ export class FlightPlanAsoboSync { Coherent.call('LOAD_CURRENT_ATC_FLIGHTPLAN').catch(console.error); setTimeout(() => { Coherent.call('GET_FLIGHTPLAN').then(async (data: Record) => { - console.log('COHERENT GET_FLIGHTPLAN received'); - const { isDirectTo } = data; + console.log('COHERENT GET_FLIGHTPLAN received:'); + console.log('Data from MSFS flight plan:', data); + // Purpose unclear // TODO: talk to matt about dirto - if (!isDirectTo) { - // TODO FIXME: better handling of mid-air spawning and syncing fpln - if (data.waypoints.length === 0 || data.waypoints[0].icao[0] !== 'A') { - fpln.resumeSync(); - resolve(); - return; - } + const { isDirectTo } = data; + if (isDirectTo) { + return; + } - await fpln._parentInstrument.facilityLoader.getFacilityRaw(data.waypoints[0].icao, 10000).catch((e) => { - console.error('[FP LOAD] Error getting first wp data'); - console.error(e); - }); + // Mid air flight plan loading not yet supported - return if first waypoint is not an airport + // TODO FIXME: better handling of mid-air spawning and syncing fpln + if (data.waypoints.length === 0 || data.waypoints[0].icao[0] !== 'A') { + fpln.resumeSync(); + resolve(); + return; + } - // set origin - await fpln.setOrigin(data.waypoints[0].icao).catch((e) => { - console.error('[FP LOAD] Error setting origin'); - console.error(e); - }); + // result dismissed - why?? + // assumption: counter timeout issues when reading facility from MSFS? + await fpln._parentInstrument.facilityLoader.getFacilityRaw(data.waypoints[0].icao, 10000).catch((e) => { + console.error('[FP LOAD] Error getting first wp data'); + console.error(e); + }); - // set dest - await fpln.setDestination(data.waypoints[data.waypoints.length - 1].icao).catch((e) => { - console.error('[FP LOAD] Error setting Destination'); - console.error(e); - }); + // set origin + await fpln.setOrigin(data.waypoints[0].icao).catch((e) => { + console.error('[FP LOAD] Error setting origin'); + console.error(e); + }); + + // set dest + await fpln.setDestination(data.waypoints[data.waypoints.length - 1].icao).catch((e) => { + console.error('[FP LOAD] Error setting Destination'); + console.error(e); + }); - // set route + // set route + const enrouteStart = (data.departureWaypointsSize === -1) ? 1 : data.departureWaypointsSize; + // Find out first approach waypoint, - 1 to skip destination + const enrouteEnd = data.waypoints.length - ((data.arrivalWaypointsSize === -1) ? 0 : data.arrivalWaypointsSize) - 1; + const enroute = data.waypoints.slice(enrouteStart, enrouteEnd); - const enrouteStart = (data.departureWaypointsSize === -1) ? 1 : data.departureWaypointsSize; - // Find out first approach waypoint, - 1 to skip destination - const enrouteEnd = data.waypoints.length - ((data.arrivalWaypointsSize === -1) ? 1 : data.arrivalWaypointsSize) - 1; - const enroute = data.waypoints.slice(enrouteStart, enrouteEnd - 1); - for (let i = 0; i < enroute.length - 1; i++) { - const wpt = enroute[i]; - if (wpt.icao.trim() !== '') { - fpln.addWaypoint(wpt.icao, Infinity, () => console.log(`[FP LOAD] Adding [${wpt.icao}]... SUCCESS`)).catch(console.error); - } + for (let i = 0; i < enroute.length; i++) { + const wpt = enroute[i]; + if (wpt.icao.trim() !== '') { + // Without the 'await' the order of import is undefined and the flight plan waypoints + // are not in the correct order + // eslint-disable-next-line no-await-in-loop + await fpln.addWaypoint(wpt.icao, Infinity, + () => { + // console.log(`[FP LOAD] Adding [${wpt.icao}]... SUCCESS`); + }) + .catch(console.error); } + } - // set departure - // rwy index - await fpln.setDepartureRunwayIndex(data.departureRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... FAILED`); - console.error(e); - }); - // proc index - await fpln.setDepartureProcIndex(data.departureProcIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... SUCCESS`)) + // set departure + // rwy index + await fpln.setDepartureRunwayIndex(data.departureRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure Runway ${data.departureRunwayIndex} ... FAILED`); + console.error(e); + }); + // proc index + await fpln.setDepartureProcIndex(data.departureProcIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... FAILED`); + console.error(e); + }); + // origin runway + if (data.originRunwayIndex !== -1) { + await fpln.setOriginRunwayIndex(data.originRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... SUCCESS`)) .catch((e) => { - console.error(`[FP LOAD] Setting Departure Procedure ${data.departureProcIndex} ... FAILED`); + console.error(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... FAILED`); console.error(e); }); - // origin runway - if (data.originRunwayIndex !== -1) { - await fpln.setOriginRunwayIndex(data.originRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Origin ${data.originRunwayIndex} ... FAILED`); - console.error(e); - }); - } else if (data.departureRunwayIndex !== -1 && data.departureProcIndex !== -1) { - await fpln.setOriginRunwayIndexFromDeparture() - // .then(() => console.log(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex}... SUCCESS`)) + } else if (data.departureRunwayIndex !== -1 && data.departureProcIndex !== -1) { + await fpln.setOriginRunwayIndexFromDeparture() + // .then(() => console.log(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex}... SUCCESS`)) .catch((e) => { - console.error(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex} ... FAILED`); - console.error(e); - }); - } - // enroutetrans index - await fpln.setDepartureEnRouteTransitionIndex(data.departureEnRouteTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... FAILED`); + console.error(`[FP LOAD] Setting Origin using ${data.departureProcIndex}/${data.departureRunwayIndex} ... FAILED`); console.error(e); }); - // set approach - // rwy index - await fpln.setArrivalRunwayIndex(data.arrivalRunwayIndex) - // .then(() => console.log(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... SUCCESS`)) + } + // enroutetrans index + await fpln.setDepartureEnRouteTransitionIndex(data.departureEnRouteTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Departure En Route Transition ${data.departureEnRouteTransitionIndex} ... FAILED`); + console.error(e); + }); + // set approach + // rwy index + await fpln.setArrivalRunwayIndex(data.arrivalRunwayIndex) + // .then(() => console.log(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... SUCCESS`)) .catch((e) => { console.error(`[FP LOAD] Setting Arrival Runway ${data.arrivalRunwayIndex} ... FAILED`); console.error(e); }); - // approach index - await fpln.setApproachIndex(data.approachIndex) - // .then(() => console.log(`[FP LOAD] Setting Approach ${data.approachIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Approach ${data.approachIndex} ... FAILED`); - console.error(e); - }); - // approachtrans index - await fpln.setApproachTransitionIndex(data.approachTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... FAILED`); - console.error(e); - }); + // approach index + await fpln.setApproachIndex(data.approachIndex) + // .then(() => console.log(`[FP LOAD] Setting Approach ${data.approachIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Approach ${data.approachIndex} ... FAILED`); + console.error(e); + }); + // approachtrans index + await fpln.setApproachTransitionIndex(data.approachTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Approach Transition ${data.approachTransitionIndex} ... FAILED`); + console.error(e); + }); - // set arrival - // arrivalproc index - await fpln.setArrivalProcIndex(data.arrivalProcIndex) - // .then(() => console.log(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... FAILED`); - console.error(e); - }); - // arrivaltrans index - await fpln.setArrivalEnRouteTransitionIndex(data.arrivalEnRouteTransitionIndex) - // .then(() => console.log(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... SUCCESS`)) - .catch((e) => { - console.error(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... FAILED`); - console.error(e); - }); + // set arrival + // arrivalproc index + await fpln.setArrivalProcIndex(data.arrivalProcIndex) + // .then(() => console.log(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting Arrival Procedure ${data.arrivalProcIndex} ... FAILED`); + console.error(e); + }); + // arrivaltrans index + await fpln.setArrivalEnRouteTransitionIndex(data.arrivalEnRouteTransitionIndex) + // .then(() => console.log(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... SUCCESS`)) + .catch((e) => { + console.error(`[FP LOAD] Setting En Route Transition ${data.arrivalEnRouteTransitionIndex} ... FAILED`); + console.error(e); + }); - await fpln.setDestinationRunwayIndexFromApproach() - // .then(() => console.log(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... SUCCESS`)) + await fpln.setDestinationRunwayIndexFromApproach() + // .then(() => console.log(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... SUCCESS`)) .catch((e) => { console.error(`[FP LOAD] Setting Destination Runway using ${data.approachIndex} ... FAILED`); console.error(e); }); - fpln.resumeSync(); + fpln.resumeSync(); - this.fpChecksum = fpln.getCurrentFlightPlan().checksum; - // Potential CTD source? - Coherent.call('SET_ACTIVE_WAYPOINT_INDEX', 0) - .catch((e) => console.error('[FP LOAD] Error when setting Active WP')); - Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') - .catch((e) => console.error('[FP LOAD] Error when recomputing Active WP')); - resolve(); - } + this.fpChecksum = fpln.getCurrentFlightPlan().checksum; + + // Potential CTD source? + Coherent.call('SET_ACTIVE_WAYPOINT_INDEX', 0) + .catch((e) => console.error('[FP LOAD] Error when setting Active WP', e)); + Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') + .catch((e) => console.error('[FP LOAD] Error when recomputing Active WP', e)); + resolve(); + + console.log('Resulting aircraft flight plan: ', fpln); }).catch(console.error); }, 500); }, 200); @@ -270,8 +287,8 @@ export class FlightPlanAsoboSync { this.fpChecksum = plan.checksum; } Coherent.call('RECOMPUTE_ACTIVE_WAYPOINT_INDEX') - .catch((e) => console.log('[FP SAVE] Setting Active Waypoint... FAILED')) - .then(() => console.log('[FP SAVE] Setting Active Waypoint... SUCCESS')); + // .then(() => console.log('[FP SAVE] Setting Active Waypoint... SUCCESS')) + .catch((e) => console.log('[FP SAVE] Setting Active Waypoint... FAILED: ', e)); })); }); } diff --git a/src/fmgc/src/flightplanning/FlightPlanManager.ts b/src/fmgc/src/flightplanning/FlightPlanManager.ts index 23df0d9f7f2..feb23944995 100644 --- a/src/fmgc/src/flightplanning/FlightPlanManager.ts +++ b/src/fmgc/src/flightplanning/FlightPlanManager.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -23,16 +24,16 @@ */ import { NXDataStore } from '@shared/persistence'; -import { LegType, TurnDirection } from '@fmgc/types/fstypes/FSEnums'; +import { LegType } from '@fmgc/types/fstypes/FSEnums'; import { FlightLevel } from '@fmgc/guidance/vnav/verticalFlightPlan/VerticalFlightPlan'; +import { LnavConfig } from '@fmgc/guidance/LnavConfig'; +import { ApproachStats, HoldData } from '@fmgc/flightplanning/data/flightplan'; +import { SegmentType } from '@fmgc/wtsdk'; import { ManagedFlightPlan } from './ManagedFlightPlan'; import { GPS } from './GPS'; import { FlightPlanSegment } from './FlightPlanSegment'; import { FlightPlanAsoboSync } from './FlightPlanAsoboSync'; import { FixInfo } from './FixInfo'; -import { LnavConfig } from '@fmgc/guidance/LnavConfig'; -import { ApproachStats, HoldData } from '@fmgc/flightplanning/data/flightplan'; -import { SegmentType } from '@fmgc/wtsdk'; export enum WaypointConstraintType { CLB = 1, @@ -149,9 +150,12 @@ export class FlightPlanManager { } public registerListener() { + // empty } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public addHardCodedConstraints(wp) { + // empty } /** @@ -160,7 +164,9 @@ export class FlightPlanManager { * @param currentWaypoints The waypoints array to modify with the data loaded. * @param callback A callback to call when the data has completed loading. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars private _loadWaypoints(data: any, currentWaypoints: any, callback: () => void) { + // empty } /** @@ -177,6 +183,7 @@ export class FlightPlanManager { * @param {() => void} callback A callback to call when the update has completed. * @param {Boolean} log Whether or not to log the loaded flight plan value. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public updateFlightPlan(callback: () => void = () => { }, log = false, force = false): void { const flightPlanVersion = SimVar.GetSimVarValue(FlightPlanManager.FlightPlanVersionKey, 'number'); if (flightPlanVersion !== this._currentFlightPlanVersion || force) { @@ -202,6 +209,7 @@ export class FlightPlanManager { } } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public updateCurrentApproach(callback = () => { }, log = false): void { callback(); } @@ -356,16 +364,18 @@ export class FlightPlanManager { * @param forceSimVarCall Unused * @param useCorrection Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypointIndex(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): number { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex].activeWaypointIndex; } return this._flightPlans[flightPlanIndex]?.activeWaypointIndex ?? -1; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isActiveWaypointAtEnd(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): boolean { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex].activeWaypointIndex + 1 === this.getWaypointsCount(this._currentFlightPlanIndex) - 1; } return this._flightPlans[flightPlanIndex].activeWaypointIndex === this.getWaypointsCount(flightPlanIndex) - 1; @@ -403,6 +413,7 @@ export class FlightPlanManager { * Gets the index of the waypoint prior to the currently active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getPreviousActiveWaypoint(forceSimVarCall = false): WayPoint { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; const previousWaypointIndex = currentFlightPlan.activeWaypointIndex - 1; @@ -414,6 +425,7 @@ export class FlightPlanManager { * Gets the ident of the active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypointIdent(forceSimVarCall = false): string { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; if (currentFlightPlan.activeWaypoint) { @@ -427,6 +439,7 @@ export class FlightPlanManager { * Gets the active waypoint index from fs9gps. Currently unimplemented. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getGPSActiveWaypointIndex(forceSimVarCall = false): number { return this.getActiveWaypointIndex(); } @@ -436,8 +449,9 @@ export class FlightPlanManager { * @param forceSimVarCall Unused * @param useCorrection Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getActiveWaypoint(forceSimVarCall = false, useCorrection = false, flightPlanIndex = NaN): WayPoint { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -448,6 +462,7 @@ export class FlightPlanManager { * Gets the next waypoint following the active waypoint. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getNextActiveWaypoint(forceSimVarCall = false): WayPoint { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; const nextWaypointIndex = currentFlightPlan.activeWaypointIndex + 1; @@ -510,7 +525,7 @@ export class FlightPlanManager { return { name, distanceFromPpos, - } + }; } /** @@ -578,7 +593,7 @@ export class FlightPlanManager { */ public getDeparture(flightPlanIndex = NaN): WayPoint | undefined { const origin = this.getOrigin(); - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } const currentFlightPlan = this._flightPlans[flightPlanIndex]; @@ -678,7 +693,7 @@ export class FlightPlanManager { /** * Gets the index of the last waypoint in the enroute segment of the current flight plan. */ - public getEnRouteWaypointsFirstIndex(flightPlanIndex = this._currentFlightPlanIndex): number | null { + public getEnRouteWaypointsFirstIndex(flightPlanIndex = this._currentFlightPlanIndex): number | null { const currentFlightPlan = this._flightPlans[flightPlanIndex]; const enrouteSegment = currentFlightPlan?.enroute; @@ -721,7 +736,7 @@ export class FlightPlanManager { * @param waypoint The waypoint we want to find the segment for. */ public getSegmentFromWaypoint(waypoint: WayPoint | undefined, flightPlanIndex = NaN): FlightPlanSegment { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -947,6 +962,7 @@ export class FlightPlanManager { * @param {*} _callback Unused */ public addFlightPlanUpdateCallback(_callback) { + // empty } /** @@ -972,6 +988,7 @@ export class FlightPlanManager { callback(); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars addWaypointOverfly(index: number, thenSetActive = false, callback = () => { }): void { this._flightPlans[this._currentFlightPlanIndex].setWaypointOverfly(index, true); @@ -979,6 +996,7 @@ export class FlightPlanManager { callback(); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars removeWaypointOverfly(index: number, thenSetActive = false, callback = () => { }): void { this._flightPlans[this._currentFlightPlanIndex].setWaypointOverfly(index, false); @@ -1008,6 +1026,7 @@ export class FlightPlanManager { * @param index The index of the first waypoint to remove. * @param callback A callback to call when the operation finishes. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public truncateWaypoints(index: number, thenSetActive = false, callback = () => { }): void { const fp = this._flightPlans[this._currentFlightPlanIndex]; for (let i = fp.length; i >= index; i--) { @@ -1031,7 +1050,7 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan. If omitted, will get the current flight plan. */ public getWaypointsCount(flightPlanIndex = NaN): number { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { return this._flightPlans[this._currentFlightPlanIndex]?.length ?? 0; } @@ -1058,8 +1077,9 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan to get the waypoint from. If omitted, will get from the current flight plan. * @param considerApproachWaypoints Whether or not to consider approach waypoints. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public getWaypoint(index: number, flightPlanIndex = NaN, considerApproachWaypoints = false): WayPoint | undefined { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -1072,7 +1092,7 @@ export class FlightPlanManager { * @param flightPlanIndex The index of the flight plan to get the waypoints from. If omitted, will get from the current flight plan. */ public getWaypoints(flightPlanIndex = NaN): WayPoint[] { - if (isNaN(flightPlanIndex)) { + if (Number.isNaN(flightPlanIndex)) { flightPlanIndex = this._currentFlightPlanIndex; } @@ -1223,12 +1243,11 @@ export class FlightPlanManager { && currentFlightPlan.procedureDetails.departureIndex >= 0 && currentFlightPlan.originAirfield ) { - const transition = (currentFlightPlan.originAirfield.infos as AirportInfo) .departures[currentFlightPlan.procedureDetails.departureIndex] .runwayTransitions[currentFlightPlan.procedureDetails.departureRunwayIndex]; const runways = (currentFlightPlan.originAirfield.infos as AirportInfo).oneWayRunways; - await this.setOriginRunwayIndex(runways.findIndex(r => r.number === transition.runwayNumber && r.designator === transition.runwayDesignation)); + await this.setOriginRunwayIndex(runways.findIndex((r) => r.number === transition.runwayNumber && r.designator === transition.runwayDesignation)); } } @@ -1262,6 +1281,7 @@ export class FlightPlanManager { * Unused */ public getDepartureDiscontinuity() { + // empty } /** @@ -1335,6 +1355,7 @@ export class FlightPlanManager { * Unused */ public getArrivalDiscontinuity() { + // empty } /** @@ -1451,11 +1472,9 @@ export class FlightPlanManager { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; if (currentFlightPlan.hasDestination && currentFlightPlan.procedureDetails.approachIndex >= 0) { - console.error('Destination runway index is -1 with valid STAR'); const approach = (currentFlightPlan.destinationAirfield.infos as AirportInfo).approaches[currentFlightPlan.procedureDetails.approachIndex]; const destRunways = (currentFlightPlan.destinationAirfield.infos as AirportInfo).oneWayRunways; - - await this.setDestinationRunwayIndex(destRunways.findIndex(r => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator)); + await this.setDestinationRunwayIndex(destRunways.findIndex((r) => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator)); } } @@ -1472,6 +1491,7 @@ export class FlightPlanManager { * @param callback A callback to call when the operation has completed. * @param transition The approach transition index to set in the approach information. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public async setApproachIndex(index: number, callback = () => { }, transition = -1): Promise { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; // console.log(currentFlightPlan); @@ -1494,6 +1514,7 @@ export class FlightPlanManager { * Whether or not an approach is loaded in the current flight plan. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isLoadedApproach(forceSimVarCall = false): boolean { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; return currentFlightPlan.procedureDetails.approachIndex >= 0; @@ -1503,6 +1524,7 @@ export class FlightPlanManager { * Whether or not the approach is active in the current flight plan. * @param forceSimVarCall Unused */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public isActiveApproach(forceSimVarCall = false): boolean { const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; return currentFlightPlan.approach.waypoints.length > 0 @@ -1526,12 +1548,14 @@ export class FlightPlanManager { * Deactivates the approach segments in the current flight plan. */ public deactivateApproach() { + // empty } /** * Attemptes to auto-activate the approach in the current flight plan. */ public tryAutoActivateApproach() { + // empty } /** @@ -1602,7 +1626,7 @@ export class FlightPlanManager { const approach = (flightPlan.destinationAirfield.infos as AirportInfo).approaches[flightPlan.procedureDetails.approachIndex]; const runways = (flightPlan.destinationAirfield.infos as AirportInfo).oneWayRunways; - return runways.findIndex(r => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator); + return runways.findIndex((r) => r.number === approach.runwayNumber && r.designator === approach.runwayDesignator); } return -1; } @@ -1670,7 +1694,7 @@ export class FlightPlanManager { * @param callback A callback to call when the operation completes. */ public cancelDirectTo(callback = EmptyCallback.Void): void { - const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; + // const currentFlightPlan = this._flightPlans[this._currentFlightPlanIndex]; // currentFlightPlan.directTo.cancel(); callback(); @@ -1703,6 +1727,7 @@ export class FlightPlanManager { } public getCoordinatesHeadingAtDistanceAlongFlightPlan(_distance) { + // empty } /** @@ -1715,11 +1740,9 @@ export class FlightPlanManager { if (destination) { const fromStartDistance = destination.cumulativeDistanceInFP - distance; - let prevIndex; let prev; let next; for (let i = 0; i < allWaypoints.length - 1; i++) { - prevIndex = i; prev = allWaypoints[i]; next = allWaypoints[i + 1]; if (prev.cumulativeDistanceInFP < fromStartDistance && next.cumulativeDistanceInFP > fromStartDistance) { diff --git a/src/fmgc/src/flightplanning/LegsProcedure.ts b/src/fmgc/src/flightplanning/LegsProcedure.ts index 00f06fcabf5..3dfeed7ee75 100644 --- a/src/fmgc/src/flightplanning/LegsProcedure.ts +++ b/src/fmgc/src/flightplanning/LegsProcedure.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -76,7 +77,7 @@ export class LegsProcedure { private airportMagVar: number, private approachType?: ApproachType, private legAnnotations?: string[], - ) { + ) { for (const leg of this._legs) { if (this.isIcaoValid(leg.fixIcao)) { this._facilitiesToLoad.set(leg.fixIcao, this._instrument.facilityLoader.getFacilityRaw(leg.fixIcao, 2000, true)); @@ -262,72 +263,72 @@ export class LegsProcedure { } private getMagCorrection(currentLeg: RawProcedureLeg): number { - // we try to interpret PANS OPs as accurately as possible within the limits of available data - - // magnetic tracks to/from a VOR always use VOR station declination - if (currentLeg.fixIcao.charAt(0) === 'V') { - const vor: RawVor = this.getLoadedFacility(currentLeg.fixIcao) as RawVor; - if (!vor || vor.magneticVariation === undefined) { - console.warn('Leg coded incorrectly (missing vor fix or station declination)', currentLeg, vor); - return this.airportMagVar; + // we try to interpret PANS OPs as accurately as possible within the limits of available data + + // magnetic tracks to/from a VOR always use VOR station declination + if (currentLeg.fixIcao.charAt(0) === 'V') { + const vor: RawVor = this.getLoadedFacility(currentLeg.fixIcao) as RawVor; + if (!vor || vor.magneticVariation === undefined) { + console.warn('Leg coded incorrectly (missing vor fix or station declination)', currentLeg, vor); + return this.airportMagVar; + } + return 360 - vor.magneticVariation; } - return 360 - vor.magneticVariation; - } - // we use station declination for VOR/DME approaches - if (this.approachType === ApproachType.APPROACH_TYPE_VORDME) { + // we use station declination for VOR/DME approaches + if (this.approachType === ApproachType.APPROACH_TYPE_VORDME) { // find a leg with the reference navaid for the procedure - for (let i = this._legs.length - 1; i >= 0; i--) { - if (this._legs[i].originIcao.trim().length > 0) { - const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; - if (recNavaid && recNavaid.magneticVariation !== undefined) { - return 360 - recNavaid.magneticVariation; + for (let i = this._legs.length - 1; i >= 0; i--) { + if (this._legs[i].originIcao.trim().length > 0) { + const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; + if (recNavaid && recNavaid.magneticVariation !== undefined) { + return 360 - recNavaid.magneticVariation; + } + } } - } + console.warn('VOR/DME approach coded incorrectly (missing recommended navaid or station declination)', currentLeg); + return this.airportMagVar; } - console.warn('VOR/DME approach coded incorrectly (missing recommended navaid or station declination)', currentLeg); - return this.airportMagVar; - } - // for RNAV procedures use recommended navaid station declination for these leg types - let useStationDeclination = (currentLeg.type === LegType.CF || currentLeg.type === LegType.FA || currentLeg.type === LegType.FM); + // for RNAV procedures use recommended navaid station declination for these leg types + let useStationDeclination = (currentLeg.type === LegType.CF || currentLeg.type === LegType.FA || currentLeg.type === LegType.FM); - // for localiser bearings (i.e. at or beyond FACF), always use airport value - if (this.approachType === ApproachType.APPROACH_TYPE_ILS || this.approachType === ApproachType.APPROACH_TYPE_LOCALIZER) { - useStationDeclination = useStationDeclination && this._legs.indexOf(currentLeg) < this.getFacfIndex(); - } + // for localiser bearings (i.e. at or beyond FACF), always use airport value + if (this.approachType === ApproachType.APPROACH_TYPE_ILS || this.approachType === ApproachType.APPROACH_TYPE_LOCALIZER) { + useStationDeclination = useStationDeclination && this._legs.indexOf(currentLeg) < this.getFacfIndex(); + } - if (useStationDeclination) { - const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; - if (!recNavaid || recNavaid.magneticVariation === undefined) { - console.warn('Leg coded incorrectly (missing recommended navaid or station declination)', currentLeg, recNavaid); - return this.airportMagVar; + if (useStationDeclination) { + const recNavaid: RawVor = this.getLoadedFacility(currentLeg.originIcao) as RawVor; + if (!recNavaid || recNavaid.magneticVariation === undefined) { + console.warn('Leg coded incorrectly (missing recommended navaid or station declination)', currentLeg, recNavaid); + return this.airportMagVar; + } + return 360 - recNavaid.magneticVariation; } - return 360 - recNavaid.magneticVariation; - } - // for all other terminal procedure legs we use airport magnetic variation - return this.airportMagVar; + // for all other terminal procedure legs we use airport magnetic variation + return this.airportMagVar; } private getLoadedFacility(icao: string): RawFacility { - const facility = this._facilities.get(icao); - if (!facility) { - throw new Error(`Failed to load facility: ${icao}`); - } - return facility; + const facility = this._facilities.get(icao); + if (!facility) { + throw new Error(`Failed to load facility: ${icao}`); + } + return facility; } private getFacfIndex(): number { - if (this.approachType !== undefined) { - for (let i = this._legs.length - 1; i >= 0; i--) { - if (this._legs[i].fixTypeFlags & FixTypeFlags.IF) { - return i; - } + if (this.approachType !== undefined) { + for (let i = this._legs.length - 1; i >= 0; i--) { + if (this._legs[i].fixTypeFlags & FixTypeFlags.IF) { + return i; + } + } } - } - return undefined; + return undefined; } /** @@ -376,37 +377,37 @@ export class LegsProcedure { * @returns The mapped leg. */ public mapBearingAndDistanceFromOrigin(leg: RawProcedureLeg): WayPoint { - const origin = this.getLoadedFacility(leg.fixIcao); - const originIdent = origin.icao.substring(7, 12).trim(); - const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, Facilities.getMagVar(origin.lat, origin.lon)); - // this is the leg length for FC, and the DME distance for FD - const refDistance = leg.distance / 1852; - - let termPoint; - let legLength; - if (leg.type === LegType.FD) { - const recNavaid = this.getLoadedFacility(leg.originIcao); - termPoint = firstSmallCircleIntersection( - { lat: recNavaid.lat, long: recNavaid.lon }, - refDistance, - { lat: origin.lat, long: origin.lon }, - course, - ); - legLength = Avionics.Utils.computeGreatCircleDistance( - { lat: origin.lat, long: origin.lon }, - termPoint, - ); - } else { // FC - termPoint = Avionics.Utils.bearingDistanceToCoordinates( - course, - refDistance, - origin.lat, - origin.lon, - ); - legLength = refDistance; - } - - return this.buildWaypoint(`${originIdent.substring(0, 3)}/${Math.round(legLength).toString().padStart(2, '0')}`, termPoint); + const origin = this.getLoadedFacility(leg.fixIcao); + const originIdent = origin.icao.substring(7, 12).trim(); + const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, Facilities.getMagVar(origin.lat, origin.lon)); + // this is the leg length for FC, and the DME distance for FD + const refDistance = leg.distance / 1852; + + let termPoint; + let legLength; + if (leg.type === LegType.FD) { + const recNavaid = this.getLoadedFacility(leg.originIcao); + termPoint = firstSmallCircleIntersection( + { lat: recNavaid.lat, long: recNavaid.lon }, + refDistance, + { lat: origin.lat, long: origin.lon }, + course, + ); + legLength = Avionics.Utils.computeGreatCircleDistance( + { lat: origin.lat, long: origin.lon }, + termPoint, + ); + } else { // FC + termPoint = Avionics.Utils.bearingDistanceToCoordinates( + course, + refDistance, + origin.lat, + origin.lon, + ); + legLength = refDistance; + } + + return this.buildWaypoint(`${originIdent.substring(0, 3)}/${Math.round(legLength).toString().padStart(2, '0')}`, termPoint); } /** @@ -437,6 +438,7 @@ export class LegsProcedure { * @param nextLeg The next leg in the procedure to intercept. * @returns The mapped leg. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public mapHeadingToInterceptNextLeg(leg: RawProcedureLeg, prevLeg: WayPoint, nextLeg: RawProcedureLeg): WayPoint | null { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); @@ -489,7 +491,7 @@ export class LegsProcedure { public mapHeadingUntilAltitude(leg: RawProcedureLeg, prevLeg: WayPoint) { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); - const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; + // const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; const altitudeFeet = (leg.altitude1 * 3.2808399); const distanceInNM = altitudeFeet / 500.0; @@ -510,7 +512,7 @@ export class LegsProcedure { public mapVectors(leg: RawProcedureLeg, prevLeg: WayPoint) { const magVar = Facilities.getMagVar(prevLeg.infos.coordinates.lat, prevLeg.infos.coordinates.long); const course = leg.trueDegrees ? leg.course : A32NX_Util.magneticToTrue(leg.course, magVar); - const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; + // const heading = leg.trueDegrees ? A32NX_Util.trueToMagnetic(leg.course, magVar) : leg.course; const coordinates = GeoMath.relativeBearingDistanceToCoords(course, 1, prevLeg.infos.coordinates); const waypoint = this.buildWaypoint(FixNamingScheme.vector(), coordinates); @@ -531,11 +533,10 @@ export class LegsProcedure { return RawDataMapper.toWaypoint(facility, this._instrument); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public mapArcToFix(leg: RawProcedureLeg, prevLeg: WayPoint): WayPoint { const toFix = this.getLoadedFacility(leg.fixIcao); - const waypoint = RawDataMapper.toWaypoint(toFix, this._instrument); - return waypoint; } diff --git a/src/fmgc/src/flightplanning/ManagedFlightPlan.ts b/src/fmgc/src/flightplanning/ManagedFlightPlan.ts index 24a199964d9..951cbfcbbc8 100644 --- a/src/fmgc/src/flightplanning/ManagedFlightPlan.ts +++ b/src/fmgc/src/flightplanning/ManagedFlightPlan.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* * MIT License * @@ -23,6 +24,7 @@ */ import { HoldData, WaypointStats } from '@fmgc/flightplanning/data/flightplan'; +import { WaypointConstraintType } from '@fmgc/flightplanning/FlightPlanManager'; import { AltitudeDescriptor, FixTypeFlags, LegType } from '../types/fstypes/FSEnums'; import { FlightPlanSegment, SegmentType } from './FlightPlanSegment'; import { LegsProcedure } from './LegsProcedure'; @@ -32,7 +34,6 @@ import { ProcedureDetails } from './ProcedureDetails'; import { DirectTo } from './DirectTo'; import { GeoMath } from './GeoMath'; import { WaypointBuilder } from './WaypointBuilder'; -import { WaypointConstraintType } from '@fmgc/flightplanning/FlightPlanManager'; /** * A flight plan managed by the FlightPlanManager. @@ -200,11 +201,7 @@ export class ManagedFlightPlan { private computeWaypointEta(distance: number, preComputedTime? :number) { const eta = preComputedTime ?? this.computeWaypointTime(distance); - const utcTime = SimVar.GetGlobalVarValue('ZULU TIME', 'seconds'); - - // // console.log(`BRUHEGG: ${utcTime}, BRUHHH #2: ${eta}`); - return eta + utcTime; } @@ -361,7 +358,8 @@ export class ManagedFlightPlan { index?: number | undefined, segmentType?: SegmentType, ): number { - console.log('addWaypoint', waypoint, index, SegmentType[segmentType]); + console.log(`addWaypoint ${waypoint.icao}, ${index}, ${SegmentType[segmentType]}`, waypoint); + const mappedWaypoint: WayPoint = (waypoint instanceof WayPoint) ? waypoint : RawDataMapper.toWaypoint(waypoint, this._parentInstrument); if (mappedWaypoint.type === 'A' && index === 0) { @@ -482,28 +480,21 @@ export class ManagedFlightPlan { * @param index The index of the waypoint to remove. */ public removeWaypoint(index: number, noDiscontinuity: boolean = false): void { - let removed = null; if (this.originAirfield && index === 0) { - removed = this.originAirfield; this.originAirfield = undefined; - this.reflowSegments(); this.reflowDistances(); } else if (this.destinationAirfield && index === this.length - 1) { - removed = this.destinationAirfield; this.destinationAirfield = undefined; } else { const segment = this.findSegmentByWaypointIndex(index); if (segment) { - // console.log("--> REMOVING WAYPOINT ", this.getWaypoint(index), ", FROM SEGMENT ", segment); const spliced = segment.waypoints.splice(index - segment.offset, 1); - removed = spliced[0]; - + console.log(`removing waypoint ${spliced[0].icao} from segment ${segment.type}`); if (segment.waypoints.length === 0 && segment.type !== SegmentType.Enroute) { - // console.log("SEGMENT LENGTH is 0, REMOVING..."); + console.log(`removing segment ${segment.type} as length is 0`); this.removeSegment(segment.type); } - this.reflowSegments(); this.reflowDistances(); } @@ -570,7 +561,7 @@ export class ManagedFlightPlan { const atWaypoint = this.getWaypoint(index); if (!atWaypoint) { - return; + return 0; } const magVar = Facilities.getMagVar(atWaypoint.infos.coordinates.lat, atWaypoint.infos.coordinates.long); @@ -588,14 +579,13 @@ export class ManagedFlightPlan { atWaypoint.additionalData.defaultHold = defaultHold; } return index; - } else { - const manualHoldWaypoint = WaypointBuilder.fromWaypointManualHold(atWaypoint, desiredHold.turnDirection, trueCourse, desiredHold.distance, desiredHold.time, this._parentInstrument); - manualHoldWaypoint.additionalData.modifiedHold = modifiedHold; - manualHoldWaypoint.additionalData.defaultHold = defaultHold; - - this.addWaypoint(manualHoldWaypoint, index + 1); - return index + 1; } + const manualHoldWaypoint = WaypointBuilder.fromWaypointManualHold(atWaypoint, desiredHold.turnDirection, trueCourse, desiredHold.distance, desiredHold.time, this._parentInstrument); + manualHoldWaypoint.additionalData.modifiedHold = modifiedHold; + manualHoldWaypoint.additionalData.defaultHold = defaultHold; + + this.addWaypoint(manualHoldWaypoint, index + 1); + return index + 1; } /** @@ -799,7 +789,7 @@ export class ManagedFlightPlan { newFlightPlan._segments[i].waypoints = [...seg.waypoints.map((wp) => { const clone = new (wp as any).constructor(); Object.assign(clone, wp); - clone.additionalData = Object.assign({}, wp.additionalData); + clone.additionalData = { ...wp.additionalData }; return clone; })]; } @@ -832,10 +822,15 @@ export class ManagedFlightPlan { const oldToWp = this.waypoints[this.activeWaypointIndex]; - const turningPoint = WaypointBuilder.fromCoordinates('T-P', new LatLongAlt(lat, long), this._parentInstrument, { legType: LegType.CF, course: trueTrack, dynamicPpos: true }, this.getTurningPointIcao()); + const turningPoint = WaypointBuilder.fromCoordinates( + 'T-P', + new LatLongAlt(lat, long), + this._parentInstrument, { legType: LegType.CF, course: trueTrack, dynamicPpos: true }, + this.getTurningPointIcao(), + ); turningPoint.isTurningPoint = true; - let waypointIndex = this.waypoints.findIndex((w, idx) => idx >= this.activeWaypointIndex && w.icao === waypoint.icao); + const waypointIndex = this.waypoints.findIndex((w, idx) => idx >= this.activeWaypointIndex && w.icao === waypoint.icao); if (waypointIndex === -1) { // in this case the waypoint is not already in the flight plan // we string it to the start of the flight plan, add a discontinuity after, and then the existing flight plan @@ -880,7 +875,7 @@ export class ManagedFlightPlan { private getTurningPointIcao(): string { this.turningPointIndex = (this.turningPointIndex + 1) % 1000; - return `WXX TP${this.turningPointIndex.toFixed(0).padStart(3, '0')}` + return `WXX TP${this.turningPointIndex.toFixed(0).padStart(3, '0')}`; } /** @@ -925,7 +920,7 @@ export class ManagedFlightPlan { const departure: RawDeparture = airportInfo.departures[departureIndex]; if (runwayTransition) { legs.push(...runwayTransition.legs); - legAnnotations.push(...runwayTransition.legs.map(_ => departure.name)); + legAnnotations.push(...runwayTransition.legs.map((_) => departure.name)); origin.endsInDiscontinuity = false; origin.discontinuityCanBeCleared = undefined; } @@ -934,14 +929,14 @@ export class ManagedFlightPlan { if (departureIndex >= 0) { const departure: RawDeparture = airportInfo.departures[departureIndex]; legs.push(...departure.commonLegs); - legAnnotations.push(...departure.commonLegs.map(_ => departure.name)); + legAnnotations.push(...departure.commonLegs.map((_) => departure.name)); } if (transitionIndex >= 0 && departureIndex >= 0) { if (airportInfo.departures[departureIndex].enRouteTransitions.length > 0) { const transition: RawEnRouteTransition = airportInfo.departures[departureIndex].enRouteTransitions[transitionIndex]; legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); } } @@ -956,7 +951,7 @@ export class ManagedFlightPlan { if (legs.length > 0 || selectedOriginRunwayIndex >= 0 || (departureIndex >= 0 && runwayIndex >= 0)) { segment = this.addSegment(SegmentType.Departure); - let procedure = new LegsProcedure(legs, origin, this._parentInstrument, airportMagVar, undefined, legAnnotations); + const procedure = new LegsProcedure(legs, origin, this._parentInstrument, airportMagVar, undefined, legAnnotations); const runway: OneWayRunway | null = this.getOriginRunway(); @@ -983,6 +978,7 @@ export class ManagedFlightPlan { let waypointIndex = segment.offset; while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint !== undefined) { @@ -1018,7 +1014,7 @@ export class ManagedFlightPlan { const destination = this.destinationAirfield; const { arrivalIndex } = this.procedureDetails; - const { approachTransitionIndex } = this.procedureDetails; + // const { approachTransitionIndex } = this.procedureDetails; const { arrivalRunwayIndex } = this.procedureDetails; const { arrivalTransitionIndex } = this.procedureDetails; @@ -1029,7 +1025,7 @@ export class ManagedFlightPlan { const transition: RawEnRouteTransition = destinationInfo.arrivals[arrivalIndex].enRouteTransitions[arrivalTransitionIndex]; if (transition !== undefined) { legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); // console.log('MFP: buildArrival - pushing transition legs ->', legs); } } @@ -1038,7 +1034,7 @@ export class ManagedFlightPlan { // string the common legs in the middle of the STAR const arrival: RawArrival = destinationInfo.arrivals[arrivalIndex]; legs.push(...arrival.commonLegs); - legAnnotations.push(...arrival.commonLegs.map(_ => arrival.name)); + legAnnotations.push(...arrival.commonLegs.map((_) => arrival.name)); // console.log('MFP: buildArrival - pushing STAR legs ->', legs); // if no runway is selected at all (non-runway-specific approach) @@ -1051,7 +1047,7 @@ export class ManagedFlightPlan { const runwayTransition = arrival.runwayTransitions[runwayTransIndex]; if (runwayTransition) { legs.push(...runwayTransition.legs); - legAnnotations.push(...runwayTransition.legs.map(_ => arrival.name)); + legAnnotations.push(...runwayTransition.legs.map((_) => arrival.name)); } } @@ -1068,6 +1064,7 @@ export class ManagedFlightPlan { let waypointIndex = segment.offset; // console.log('MFP: buildArrival - ADDING WAYPOINTS ------------------------'); while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint) { @@ -1106,7 +1103,7 @@ export class ManagedFlightPlan { if (approachIndex >= 0 && approachTransitionIndex >= 0) { const transition: RawApproachTransition = destinationInfo.approaches[approachIndex].transitions[approachTransitionIndex]; legs.push(...transition.legs); - legAnnotations.push(...transition.legs.map(_ => transition.name)); + legAnnotations.push(...transition.legs.map((_) => transition.name)); // console.log('MFP: buildApproach - pushing approachTransition legs ->', legs); } @@ -1125,7 +1122,7 @@ export class ManagedFlightPlan { this.procedureDetails.approachType = approach.approachType; legs.push(...finalLegs); - legAnnotations.push(...finalLegs.map(_ => approachName)); + legAnnotations.push(...finalLegs.map((_) => approachName)); missedLegs.push(...approach.missedLegs); } @@ -1153,6 +1150,7 @@ export class ManagedFlightPlan { let waypointIndex = _startIndex; // console.log('MFP: buildApproach - ADDING WAYPOINTS ------------------------'); while (procedure.hasNext()) { + // eslint-disable-next-line no-await-in-loop const waypoint = await procedure.getNext(); if (waypoint !== undefined) { @@ -1164,19 +1162,19 @@ export class ManagedFlightPlan { } if (runway) { - const selectedRunwayMod = runway.designation.slice(-1); - let selectedRunwayOutput; - if (selectedRunwayMod === 'L' || selectedRunwayMod === 'C' || selectedRunwayMod === 'R') { - if (runway.designation.length === 2) { - selectedRunwayOutput = `0${runway.designation}`; - } else { - selectedRunwayOutput = runway.designation; - } - } else if (runway.designation.length === 2) { - selectedRunwayOutput = runway.designation; - } else { - selectedRunwayOutput = `0${runway.designation}`; - } + // const selectedRunwayMod = runway.designation.slice(-1); + // let selectedRunwayOutput; + // if (selectedRunwayMod === 'L' || selectedRunwayMod === 'C' || selectedRunwayMod === 'R') { + // if (runway.designation.length === 2) { + // selectedRunwayOutput = `0${runway.designation}`; + // } else { + // selectedRunwayOutput = runway.designation; + // } + // } else if (runway.designation.length === 2) { + // selectedRunwayOutput = runway.designation; + // } else { + // selectedRunwayOutput = `0${runway.designation}`; + // } // When adding approach, edit destination waypoint this.destinationAirfield.infos.coordinates = runway.beginningCoordinates; @@ -1186,7 +1184,9 @@ export class ManagedFlightPlan { if (approachIndex >= 0) { const lastLeg = approach.finalLegs[approach.finalLegs.length - 1]; if (lastLeg.type === LegType.CF) { - const magCourse = lastLeg.trueDegrees ? A32NX_Util.trueToMagnetic(lastLeg.course, Facilities.getMagVar(runway.beginningCoordinates.lat, runway.beginningCoordinates.long)) : lastLeg.course; + const magCourse = lastLeg.trueDegrees + ? A32NX_Util.trueToMagnetic(lastLeg.course, Facilities.getMagVar(runway.beginningCoordinates.lat, runway.beginningCoordinates.long)) + : lastLeg.course; this.destinationAirfield.additionalData.annotation = `C${magCourse.toFixed(0).padStart(3, '0')}°`; } else { this.destinationAirfield.additionalData.annotation = approachName; @@ -1231,26 +1231,26 @@ export class ManagedFlightPlan { private static isXfLeg(leg: WayPoint): boolean { switch (leg?.additionalData?.legType) { - case LegType.CF: - case LegType.DF: - case LegType.IF: - case LegType.RF: - case LegType.TF: - return true; - default: - return false; + case LegType.CF: + case LegType.DF: + case LegType.IF: + case LegType.RF: + case LegType.TF: + return true; + default: + return false; } } private static isFxLeg(leg: WayPoint): boolean { switch (leg?.additionalData?.legType) { - case LegType.FA: - case LegType.FC: - case LegType.FD: - case LegType.FM: - return true; - default: - return false; + case LegType.FA: + case LegType.FC: + case LegType.FD: + case LegType.FM: + return true; + default: + return false; } } @@ -1260,21 +1260,25 @@ export class ManagedFlightPlan { private static climbConstraint(leg: WayPoint): number { switch (leg.legAltitudeDescription) { - case AltitudeDescriptor.At: - case AltitudeDescriptor.AtOrBelow: - return leg.legAltitude1; - case AltitudeDescriptor.Between: - return leg.legAltitude2; + case AltitudeDescriptor.At: + case AltitudeDescriptor.AtOrBelow: + return leg.legAltitude1; + case AltitudeDescriptor.Between: + return leg.legAltitude2; + default: + break; } return Infinity; } private static descentConstraint(leg: WayPoint): number { switch (leg.legAltitudeDescription) { - case AltitudeDescriptor.At: - case AltitudeDescriptor.AtOrAbove: - case AltitudeDescriptor.Between: - return leg.legAltitude1; + case AltitudeDescriptor.At: + case AltitudeDescriptor.AtOrAbove: + case AltitudeDescriptor.Between: + return leg.legAltitude1; + default: + break; } return -Infinity; } @@ -1324,7 +1328,7 @@ export class ManagedFlightPlan { legAltitude1, legAltitude2, speedConstraint: Number.isFinite(speed) ? speed : 0, - } + }; } /** @@ -1534,8 +1538,7 @@ export class ManagedFlightPlan { default: } } else if (ManagedFlightPlan.isXfLeg(a) && ManagedFlightPlan.isXfLeg(b) - || ManagedFlightPlan.isFxLeg(a) && ManagedFlightPlan.isFxLeg(b)) - { + || ManagedFlightPlan.isFxLeg(a) && ManagedFlightPlan.isFxLeg(b)) { return a.icao === b.icao; } @@ -1593,6 +1596,7 @@ export class ManagedFlightPlan { return wp.legAltitude1; } } + return undefined; } get destinationIndex(): number { diff --git a/src/fmgc/src/flightplanning/RawDataMapper.ts b/src/fmgc/src/flightplanning/RawDataMapper.ts index 6a260d65777..3627adc4fa2 100644 --- a/src/fmgc/src/flightplanning/RawDataMapper.ts +++ b/src/fmgc/src/flightplanning/RawDataMapper.ts @@ -53,16 +53,28 @@ export class RawDataMapper { info.approaches = facility.approaches; info.approaches.forEach((approach) => approach.name = normaliseApproachName(approach.name)); - info.approaches.forEach((approach) => approach.transitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = WayPoint.formatIdentFromIcao(trans.legs[0].fixIcao)))); + info.approaches.forEach( + (approach) => approach.transitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = WayPoint.formatIdentFromIcao(trans.legs[0].fixIcao)), + ), + ); info.approaches.forEach((approach) => approach.runway = approach.runway.trim()); info.departures = facility.departures; info.departures.forEach((departure) => departure.runwayTransitions.forEach((trans) => trans.name = RawDataMapper.generateRunwayTransitionName(trans))); - info.departures.forEach((departure) => departure.enRouteTransitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateDepartureEnRouteTransitionName(trans)))); + info.departures.forEach( + (departure) => departure.enRouteTransitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateDepartureEnRouteTransitionName(trans)), + ), + ); info.arrivals = facility.arrivals; info.arrivals.forEach((arrival) => arrival.runwayTransitions.forEach((trans) => trans.name = RawDataMapper.generateRunwayTransitionName(trans))); - info.arrivals.forEach((arrival) => arrival.enRouteTransitions.forEach((trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateArrivalTransitionName(trans)))); + info.arrivals.forEach( + (arrival) => arrival.enRouteTransitions.forEach( + (trans) => trans.name.trim().length === 0 && (trans.name = RawDataMapper.generateArrivalTransitionName(trans)), + ), + ); info.runways = facility.runways; @@ -143,6 +155,8 @@ export class RawDataMapper { case 3: name += 'C'; break; + default: + break; } return name; diff --git a/src/fmgc/src/guidance/lnav/LnavDriver.ts b/src/fmgc/src/guidance/lnav/LnavDriver.ts index 104bba241d3..b49b60d0bd7 100644 --- a/src/fmgc/src/guidance/lnav/LnavDriver.ts +++ b/src/fmgc/src/guidance/lnav/LnavDriver.ts @@ -411,8 +411,9 @@ export class LnavDriver implements GuidanceComponent { private updateEfisData(activeLeg: Leg, gs: Knots) { const termination = activeLeg instanceof XFLeg ? activeLeg.fix.infos.coordinates : activeLeg.getPathEndPoint(); + const efisTrueBearing = termination ? Avionics.Utils.computeGreatCircleHeading(this.ppos, termination) : -1; const efisBearing = termination ? A32NX_Util.trueToMagnetic( - Avionics.Utils.computeGreatCircleHeading(this.ppos, termination), + efisTrueBearing, Facilities.getMagVar(this.ppos.lat, this.ppos.long), ) : -1; @@ -423,10 +424,12 @@ export class LnavDriver implements GuidanceComponent { // FIXME should be NCD if no FM position SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_BEARING', 'Degrees', efisBearing); + SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_TRUE_BEARING', 'Degrees', efisTrueBearing); SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_DISTANCE', 'Number', efisDistance); SimVar.SetSimVarValue('L:A32NX_EFIS_L_TO_WPT_ETA', 'Seconds', efisEta); SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_BEARING', 'Degrees', efisBearing); + SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_TRUE_BEARING', 'Degrees', efisTrueBearing); SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_DISTANCE', 'Number', efisDistance); SimVar.SetSimVarValue('L:A32NX_EFIS_R_TO_WPT_ETA', 'Seconds', efisEta); } @@ -481,7 +484,7 @@ export class LnavDriver implements GuidanceComponent { if (lateralModel === LateralMode.NAV) { // Set HDG (current heading) SimVar.SetSimVarValue('H:A320_Neo_FCU_HDG_PULL', 'number', 0); - SimVar.SetSimVarValue('L:A32NX_AUTOPILOT_HEADING_SELECTED', 'number', Simplane.getHeadingMagnetic()); + SimVar.SetSimVarValue('L:A32NX_FM_HEADING_SYNC', 'boolean', true); reverted = true; } diff --git a/src/fmgc/src/guidance/vnav/FlightModel.ts b/src/fmgc/src/guidance/vnav/FlightModel.ts index 62569fa8e33..6561f7ffc98 100644 --- a/src/fmgc/src/guidance/vnav/FlightModel.ts +++ b/src/fmgc/src/guidance/vnav/FlightModel.ts @@ -61,17 +61,17 @@ export class FlightModel { baseDrag = (0.0168 * Cl ** 3) - (0.0018 * Cl ** 2) - (0.0037 * Cl) + 0.0729; break; case FlapConf.CONF_3: - baseDrag = (0.0132 * Cl ** 3) - (0.0058 * Cl ** 2) + (0.0005 * Cl) + 0.0982; + baseDrag = (0.013 * Cl ** 3) - (0.0056 * Cl ** 2) + (0.0005 * Cl) + 0.0902; break; case FlapConf.CONF_FULL: - baseDrag = (0.0077 * Cl ** 3) - (0.0055 * Cl ** 2) - (0.0015 * Cl) + 0.1483; + baseDrag = (0.0077 * Cl ** 3) - (0.0056 * Cl ** 2) - (0.001 * Cl) + 0.1405; break; default: break; } const spdBrkIncrement = spdBrkDeflected ? 0.01008 : 0; - const gearIncrement = gearExtended ? 0.03 : 0; + const gearIncrement = gearExtended ? 0.0372 : 0; return baseDrag + spdBrkIncrement + gearIncrement; } diff --git a/src/fmgc/src/radionav/NavRadioManager.ts b/src/fmgc/src/radionav/NavRadioManager.ts index f3cc3cc22f0..60ae4b15763 100644 --- a/src/fmgc/src/radionav/NavRadioManager.ts +++ b/src/fmgc/src/radionav/NavRadioManager.ts @@ -8,19 +8,40 @@ export enum TuningMode { * This is a placeholder for the new radio nav tuning logic... coming soon to an A32NX near you */ export class NavRadioManager { - tuningMode1: TuningMode = TuningMode.Auto; + tuningMode: TuningMode = TuningMode.Auto; - tuningMode2: TuningMode = TuningMode.Auto; + manualTuned: boolean; - tuningMode3: TuningMode = TuningMode.Auto; + rmpTuned: boolean; constructor(public _parentInstrument: BaseInstrument) { - SimVar.SetSimVarValue('L:A32NX_FMGC_RADIONAV_1_TUNING_MODE', 'Enum', TuningMode.Manual); - SimVar.SetSimVarValue('L:A32NX_FMGC_RADIONAV_2_TUNING_MODE', 'Enum', TuningMode.Manual); - SimVar.SetSimVarValue('L:A32NX_FMGC_RADIONAV_3_TUNING_MODE', 'Enum', TuningMode.Manual); + SimVar.SetSimVarValue('L:A32NX_FMGC_RADIONAV_TUNING_MODE', 'Enum', TuningMode.Auto); } - update(_: number): void { - // Do nothing + public update(deltaTime: number, manualTuned: boolean, rmpTuned: boolean): void { + if (this.manualTuned !== manualTuned || this.rmpTuned !== rmpTuned) { + // too avoid SetSimVar too often + this.manualTuned = manualTuned; + this.rmpTuned = rmpTuned; + + if (manualTuned) { + this.tuningMode = TuningMode.Manual; + } else if (rmpTuned) { + this.tuningMode = TuningMode.Remote; + } else { + if (this.tuningMode === TuningMode.Remote) { + // Happens when NAV push button is pushed back + // It resets all the frequencies (real life behavior) + SimVar.SetSimVarValue('K:ADF_ACTIVE_SET', 'Frequency ADF BCD32', 0); + SimVar.SetSimVarValue('K:ADF2_ACTIVE_SET', 'Frequency ADF BCD32', 0); + SimVar.SetSimVarValue('K:NAV1_RADIO_SET_HZ', 'Hz', 0); + SimVar.SetSimVarValue('K:NAV2_RADIO_SET_HZ', 'Hz', 0); + SimVar.SetSimVarValue('K:NAV3_RADIO_SET_HZ', 'Hz', 0); + } + + this.tuningMode = TuningMode.Auto; + } + SimVar.SetSimVarValue('L:A32NX_FMGC_RADIONAV_TUNING_MODE', 'Enum', this.tuningMode); + } } } diff --git a/src/fonts/ECAMFontRegular_Source.sfd b/src/fonts/ECAMFontRegular_Source.sfd index c3abe91931d..ceaca3ab1c7 100644 --- a/src/fonts/ECAMFontRegular_Source.sfd +++ b/src/fonts/ECAMFontRegular_Source.sfd @@ -22,7 +22,7 @@ OS2Version: 4 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1630565342 -ModificationTime: 1634010783 +ModificationTime: 1670146205 PfmFamily: 17 TTFWeight: 400 TTFWidth: 5 @@ -89,8 +89,15 @@ NameList: AGL For New Fonts DisplaySize: -48 AntiAlias: 1 FitToEm: 0 -WinInfo: 0 29 12 -BeginChars: 65538 382 +WinInfo: 9541 29 12 +Grid +-4096 3112.08334351 m 0 + 8192 3112.08334351 l 1024 + Named: "top" +-4053.02087402 5324 m 0 + -4053.02087402 -2868 l 1024 +EndSplineSet +BeginChars: 65538 383 StartChar: .notdef Encoding: 65536 -1 0 @@ -537,7 +544,7 @@ StartChar: period Encoding: 46 46 11 Width: 2568 GlyphClass: 2 -Flags: WO +Flags: W LayerCount: 2 Fore SplineSet @@ -2497,24 +2504,24 @@ Flags: W LayerCount: 2 Fore SplineSet -120 2969 m 2,0,1 - 120 3028 120 3028 161.5 3070 c 128,-1,2 - 203 3112 203 3112 263 3112 c 2,3,-1 - 1949 3112 l 2,4,5 - 2008 3112 2008 3112 2050 3070.5 c 128,-1,6 - 2092 3029 2092 3029 2092 2969 c 2,7,-1 - 2092 144 l 2,8,9 - 2092 85 2092 85 2050 43 c 128,-1,10 - 2008 1 2008 1 1949 1 c 2,11,-1 - 263 1 l 2,12,13 - 204 1 204 1 162 43 c 128,-1,14 - 120 85 120 85 120 144 c 2,15,-1 - 120 2969 l 2,0,1 -402 2829 m 1,16,-1 - 402 284 l 1,17,-1 - 1809 284 l 1,18,-1 - 1809 2829 l 1,19,-1 - 402 2829 l 1,16,-1 +120 2969 m 6,0,1 + 120 3028 120 3028 161.5 3070 c 132,-1,2 + 203 3112 203 3112 263 3112 c 6,3,-1 + 1949 3112 l 6,4,5 + 2008 3112 2008 3112 2050 3070.5 c 132,-1,6 + 2092 3029 2092 3029 2092 2969 c 6,7,-1 + 2092 144 l 6,8,9 + 2092 85 2092 85 2050 43 c 132,-1,10 + 2008 1 2008 1 1949 1 c 6,11,-1 + 263 1 l 6,12,13 + 204 1 204 1 162 43 c 132,-1,14 + 120 85 120 85 120 144 c 6,15,-1 + 120 2969 l 6,0,1 +402 2829 m 5,16,-1 + 402 284 l 5,17,-1 + 1809 284 l 5,18,-1 + 1809 2829 l 5,19,-1 + 402 2829 l 5,16,-1 EndSplineSet Validated: 1 EndChar @@ -2946,7 +2953,7 @@ EndChar StartChar: at Encoding: 64 64 98 Width: 2568 -Flags: WO +Flags: W LayerCount: 2 Fore SplineSet @@ -5521,5 +5528,33 @@ LayerCount: 2 Fore Validated: 1 EndChar + +StartChar: uni25C7 +Encoding: 9671 9671 382 +Width: 2568 +Flags: WO +LayerCount: 2 +Fore +SplineSet +1188.15136719 3063.99804688 m 2,0,1 + 1221.84960938 3112.5625 1221.84960938 3112.5625 1269.76855469 3113.11035156 c 0,2,3 + 1317.45019531 3113.72949219 1317.45019531 3113.72949219 1351.95898438 3063.99804688 c 2,4,-1 + 2317.62597656 1672.34667969 l 2,5,6 + 2351.64257812 1623.06738281 2351.64257812 1623.06738281 2351.70605469 1554.72460938 c 0,7,8 + 2351.64257812 1485.29980469 2351.64257812 1485.29980469 2317.62597656 1436.27734375 c 2,9,-1 + 1352.53222656 45.453125 l 2,10,11 + 1318.89257812 -3.001953125 1318.89257812 -3.001953125 1270.51660156 -3.0849609375 c 0,12,13 + 1222.34667969 -3.001953125 1222.34667969 -3.001953125 1188.72363281 45.453125 c 2,14,-1 + 223.056640625 1437.10449219 l 2,15,16 + 189.584960938 1485.33984375 189.584960938 1485.33984375 191.372070312 1560.03125 c 0,17,18 + 192.993164062 1630.0703125 192.993164062 1630.0703125 223.056640625 1673.17285156 c 2,19,-1 + 1188.15136719 3063.99804688 l 2,0,1 +1269.48242188 2715.67285156 m 1,20,-1 + 464.759765625 1555.96386719 l 1,21,-1 + 1270.62792969 394.603515625 l 1,22,-1 + 2075.35058594 1554.31347656 l 1,23,-1 + 1269.48242188 2715.67285156 l 1,20,-1 +EndSplineSet +EndChar EndChars EndSplineFont diff --git a/src/instruments/buildSrc/igniter/tasks.mjs b/src/instruments/buildSrc/igniter/tasks.mjs index 301cc87a856..2a688045160 100644 --- a/src/instruments/buildSrc/igniter/tasks.mjs +++ b/src/instruments/buildSrc/igniter/tasks.mjs @@ -3,85 +3,20 @@ import { join } from 'path'; import { ExecTask } from '@flybywiresim/igniter'; import { Directories } from '../directories.mjs'; -const ecamPages = [ - { - name: 'eng-page', - path: 'SD/Pages/Eng', - }, - { - name: 'door-page', - path: 'SD/Pages/Door', - }, - { - name: 'cond-page', - path: 'SD/Pages/Cond', - }, - { - name: 'fctl-page', - path: 'SD/Pages/Fctl', - }, - { - name: 'elec-page', - path: 'SD/Pages/Elec', - }, - { - name: 'hyd-page', - path: 'SD/Pages/Hyd', - }, - { - name: 'wheel-page', - path: 'SD/Pages/Wheel', - }, - { - name: 'crz-page', - path: 'SD/Pages/Crz', - }, - { - name: 'fuel-page', - path: 'SD/Pages/Fuel', - }, - { - name: 'apu-page', - path: 'SD/Pages/Apu', - }, - { - name: 'press-page', - path: 'SD/Pages/Press', - }, - { - name: 'bleed-page', - path: 'SD/Pages/Bleed', - }, - { - name: 'status-page', - path: 'SD/Pages/Status', - }, -]; - export function getInputs() { const baseInstruments = fs.readdirSync(join(Directories.instruments, 'src'), { withFileTypes: true }) .filter((d) => d.isDirectory() && fs.existsSync(join(Directories.instruments, 'src', d.name, 'config.json'))); - return [ - ...baseInstruments.map(({ name }) => ({ path: name, name, isInstrument: true })), - ...ecamPages.map((def) => ({ ...def, isInstrument: false })), - ]; + return baseInstruments.map(({ name }) => ({ path: name, name })); } export function getInstrumentsIgniterTasks() { const baseInstruments = fs.readdirSync(join(Directories.instruments, 'src'), { withFileTypes: true }) .filter((d) => d.isDirectory() && fs.existsSync(join(Directories.instruments, 'src', d.name, 'config.json'))); - return [ - ...baseInstruments.map(({ name }) => new ExecTask( - name, - `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, - [join('src/instruments/src', name), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX', name)], - )), - ...ecamPages.map(({ name, path }) => new ExecTask( - name, - `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, - [join('src/instruments/src', path), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX/EcamPages', name)], - )), - ]; + return baseInstruments.map(({ name }) => new ExecTask( + name, + `node src/instruments/buildSrc/igniter/worker.mjs ${name}`, + [join('src/instruments/src', name), join('flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX', name)], + )); } diff --git a/src/instruments/buildSrc/simulatorBuild.mjs b/src/instruments/buildSrc/simulatorBuild.mjs index 0c88292bdb1..da1b6f82fdb 100644 --- a/src/instruments/buildSrc/simulatorBuild.mjs +++ b/src/instruments/buildSrc/simulatorBuild.mjs @@ -8,7 +8,7 @@ import { getInputs } from './igniter/tasks.mjs'; process.chdir(Directories.src); export default getInputs() - .map(({ path, name, isInstrument }) => { + .map(({ path, name }) => { const config = JSON.parse(fs.readFileSync(join(Directories.instruments, 'src', path, 'config.json'))); const additionalImports = config.additionalImports ? config.additionalImports : []; @@ -36,7 +36,6 @@ export default getInputs() ...additionalImports, ], config, - isInstrument, }), ], }; diff --git a/src/instruments/buildSrc/templatePlugins.mjs b/src/instruments/buildSrc/templatePlugins.mjs index 0ad21914b1e..c8b7a8c5208 100644 --- a/src/instruments/buildSrc/templatePlugins.mjs +++ b/src/instruments/buildSrc/templatePlugins.mjs @@ -1,20 +1,13 @@ import { join } from 'path'; import instrumentTemplate from '@flybywiresim/rollup-plugin-msfs'; -import ecamPageTemplate from '../ecam-page-template/rollup.js'; import { Directories } from './directories.mjs'; -export function getTemplatePlugin({ name, config, imports = [], isInstrument }) { - if (isInstrument) { - return instrumentTemplate({ - name, - elementName: `a32nx-${name.toLowerCase()}`, - config, - imports, - outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX'), - }); - } - return ecamPageTemplate({ +export function getTemplatePlugin({ name, config, imports = [] }) { + return instrumentTemplate({ name, - outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX/EcamPages'), + elementName: `a32nx-${name.toLowerCase()}`, + config, + imports, + outputDir: join(Directories.root, 'flybywire-aircraft-a320-neo/html_ui/Pages/VCockpit/Instruments/A32NX'), }); } diff --git a/src/instruments/ecam-page-template/rollup.js b/src/instruments/ecam-page-template/rollup.js deleted file mode 100644 index b0b601cf990..00000000000 --- a/src/instruments/ecam-page-template/rollup.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const path = require('path'); -const fs = require('fs'); - -// The bundle code contains `$`, which is a special character -// in JS replace and replaceAll, so we can't use those. -function replaceButSad(s, search, replace) { - return s.split(search).join(replace); -} - -const TEMPLATE_HTML = fs.readFileSync(path.join(__dirname, 'template.html'), 'utf8'); -const TEMPLATE_JS = fs.readFileSync(path.join(__dirname, 'template.js'), 'utf8'); - -module.exports = ({ name, outputDir }) => ({ - name: 'template', - writeBundle(_config, bundle) { - const { code: jsCode } = bundle['bundle.js']; - const { source: cssCode } = bundle['bundle.css']; - - const snakeCaseName = name.replace('-', '_'); - - const process = (s) => { - let tmp = s; - tmp = replaceButSad(tmp, 'PAGE_NAME_LOWER_SKEWER', name); - tmp = replaceButSad(tmp, 'PAGE_NAME_SKEWER', name); - tmp = replaceButSad(tmp, 'PAGE_NAME_LOWER', snakeCaseName.toLowerCase()); - tmp = replaceButSad(tmp, 'PAGE_NAME', snakeCaseName); - tmp = replaceButSad(tmp, 'PAGE_BUNDLE', jsCode); - tmp = replaceButSad(tmp, 'PAGE_STYLE', cssCode); - return tmp; - }; - - const templateHtml = process(TEMPLATE_HTML); - const templateJs = process(TEMPLATE_JS); - - fs.mkdirSync(path.join(outputDir, name), { recursive: true }); - fs.writeFileSync(path.join(outputDir, name, 'template.html'), templateHtml); - fs.writeFileSync(path.join(outputDir, name, 'template.js'), templateJs); - }, -}); diff --git a/src/instruments/ecam-page-template/template.html b/src/instruments/ecam-page-template/template.html deleted file mode 100644 index 3b70fbd3877..00000000000 --- a/src/instruments/ecam-page-template/template.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - diff --git a/src/instruments/ecam-page-template/template.js b/src/instruments/ecam-page-template/template.js deleted file mode 100644 index 46b381f5c38..00000000000 --- a/src/instruments/ecam-page-template/template.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - -/* global Airliners */ - -class A32NX_PAGE_NAME_Logic extends Airliners.EICASTemplateElement { - constructor() { - super(); - let lastTime = this._lastTime; - this.getDeltaTime = () => { - const nowTime = Date.now(); - const deltaTime = nowTime - lastTime; - lastTime = nowTime; - - return deltaTime; - }; - } - - get templateID() { - return 'A32NX_PAGE_NAME_TEMPLATE'; - } - - connectedCallback() { - super.connectedCallback(); - - // This is big hack, see `template.html`. - { - const code = document.getElementById('A32NX_PAGE_NAME_BUNDLED_STYLE').innerHTML; - const style = document.createElement('style'); - style.innerHTML = code; - document.head.appendChild(style); - } - { - const code = document.getElementById('A32NX_PAGE_NAME_BUNDLED_LOGIC').innerHTML; - const script = document.createElement('script'); - script.innerHTML = code; - document.body.appendChild(script); - } - } - - onEvent(_event) { - } - - update(_deltaTime) { - this.dispatchEvent(new CustomEvent('update', { detail: this.getDeltaTime() })); - } -} - -customElements.define('a32nx-PAGE_NAME_LOWER_SKEWER-element', A32NX_PAGE_NAME_Logic); diff --git a/src/instruments/src/Common/EWDMessages.tsx b/src/instruments/src/Common/EWDMessages.tsx index fe534dab8e7..0fe9bad737b 100644 --- a/src/instruments/src/Common/EWDMessages.tsx +++ b/src/instruments/src/Common/EWDMessages.tsx @@ -232,6 +232,15 @@ const EWDMessages = { '270055701': '\x1b<4m\x1b4mF/CTL\x1bm FCDC 2 FAULT', '290031001': '\x1b<4m*HYD', '290031201': '\x1b<4m*HYD', + '290012601': '\x1b<4m\x1b4mHYD\x1bm B RSVR OVHT', + '290012602': '\x1b<5m -BLUE ELEC PUMP.....OFF', + '290012701': '\x1b<4m\x1b4mHYD\x1bm Y RSVR OVHT', + '290012702': '\x1b<5m -PTU................OFF', + '290012703': '\x1b<5m -YELLOW ENG 2 PUMP..OFF', + '290012704': '\x1b<5m -YELLOW ELEC PUMP...OFF', + '290012801': '\x1b<4m\x1b4mHYD\x1bm G RSVR OVHT', + '290012802': '\x1b<5m -PTU................OFF', + '290012803': '\x1b<5m -GREEN ENG 1 PUMP...OFF', '308118601': '\x1b<4m\x1b4mSEVERE ICE\x1bm DETECTED', '308118602': '\x1b5m -WING ANTI ICE.......ON', '308118603': '\x1b5m -ENG MOD SEL........IGN', diff --git a/src/instruments/src/Common/NXUnits.ts b/src/instruments/src/Common/NXUnits.ts new file mode 100644 index 00000000000..325bfd52a6e --- /dev/null +++ b/src/instruments/src/Common/NXUnits.ts @@ -0,0 +1,51 @@ +/** + * Unit conversion utilities + */ + +import { NXDataStore } from '@shared/persistence'; + +export class NXUnits { + private static metricWeightVal: boolean; + + static get metricWeight() { + if (NXUnits.metricWeightVal === undefined) { + NXDataStore.getAndSubscribe('CONFIG_USING_METRIC_UNIT', (key, value) => { + NXUnits.metricWeightVal = value === '1'; + }, '1'); + } + return NXUnits.metricWeightVal; + } + + static userToKg(value) { + return NXUnits.metricWeight ? value : value / 2.204625; + } + + static kgToUser(value) { + return NXUnits.metricWeight ? value : value * 2.204625; + } + + static poundsToUser(value) { + return NXUnits.metricWeight ? value / 2.204625 : value; + } + + static userWeightUnit() { + return NXUnits.metricWeight ? 'KG' : 'LBS'; // EIS uses S suffix on LB + } + + /** + * Converts meter into ft if imperial units are selected + * @param value {number} in unit Meters + * @returns {number} in metric or ft + */ + static mToUser(value) { + return NXUnits.metricWeight ? value : value * 3.28084; + } + + /** + * Returns 'M' for meters and 'FT' for feet depending on the unit system selected + * @returns {string} 'M' (meter) OR 'FT' (feet) + */ + static userDistanceUnit() { + return NXUnits.metricWeight ? 'M' : 'FT'; + } +} diff --git a/src/instruments/src/Common/bitFlags.tsx b/src/instruments/src/Common/bitFlags.tsx index da45bce87bf..202b909c143 100644 --- a/src/instruments/src/Common/bitFlags.tsx +++ b/src/instruments/src/Common/bitFlags.tsx @@ -1,21 +1,85 @@ -import { useLocalStorage } from '@instruments/common/persistence'; -import { BitFlags } from '@shared/bitFlags'; -import { useCallback, useState } from 'react'; - -type BitFlagsSetter = (oldValue: T) => T; +/* eslint-disable function-paren-newline */ +import { useUpdate } from '@instruments/common/hooks'; +import { BitFlags, SeatFlags } from '@shared/bitFlags'; +import { useCallback, useRef, useState } from 'react'; export const useBitFlags = ( name: string, -): [BitFlags, (setter: BitFlags -) => void] => { - const [storage, setStorage] = useLocalStorage(name, ''); - const [stateValue, setValue] = useState(storage ? JSON.parse(storage) : 0); - - const setter = useCallback((valueOrSetter: BitFlags | BitFlagsSetter) => { - const executedValue: number = typeof valueOrSetter === 'function' ? valueOrSetter(stateValue) : valueOrSetter.toDouble(); - setValue(executedValue); - setStorage(JSON.stringify(executedValue)); + refreshInterval: number = 200, +): [ + BitFlags, + (setter: BitFlags) => void +] => { + const lastUpdate = useRef(Date.now() - refreshInterval - 1); + + const [stateValue, setStateValue] = useState(() => SimVar.GetSimVarValue(`L:${name}`, 'number')); + + const updateCallback = useCallback(() => { + const delta = Date.now() - lastUpdate.current; + + if (delta >= refreshInterval) { + lastUpdate.current = Date.now(); + + const newValue = SimVar.GetSimVarValue(`L:${name}`, 'number'); + if (newValue !== stateValue) { + setStateValue(newValue); + setter(new BitFlags(newValue)); + } + } + }, [name, stateValue, refreshInterval]); + + useUpdate(updateCallback); + + const setter = useCallback((value: BitFlags) => { + SimVar.SetSimVarValue(`L:${name}`, 'string', value.toString()).catch(console.error).then(); + setStateValue(value.toNumber()); }, [name, stateValue]); return [new BitFlags(stateValue), setter]; }; + +export const useSeatFlags = ( + name: string, + totalSeats: number, + refreshInterval: number = 200, +): [ + SeatFlags, + (setter: SeatFlags) => void +] => { + const lastUpdate = useRef(Date.now() - refreshInterval - 1); + + const [stateValue, setStateValue] = useState(() => SimVar.GetSimVarValue(name, 'number')); + // const [seatFlags] = useState(() => new SeatFlags(stateValue, totalSeats)); + + const updateCallback = useCallback(() => { + const delta = Date.now() - lastUpdate.current; + + if (delta >= refreshInterval) { + lastUpdate.current = Date.now(); + + const newValue = SimVar.GetSimVarValue(name, 'number'); + if (newValue !== stateValue) { + setStateValue(newValue); + // TODO: Refactor to recycle object instead of generating new object + setter(new SeatFlags(newValue, totalSeats)); + } + } + }, [name, stateValue, refreshInterval]); + + useUpdate(updateCallback); + + const setter = useCallback((value: SeatFlags) => { + lastUpdate.current = Date.now(); + // Note: as of SU XI 1.29.30.0 - Beyond (2^24) The BehaviourDebug window will incorrectly show this as its real value + 1. + // console.log(`[SetSimVarValue] ${name} => ${value.toString()}`); + SimVar.SetSimVarValue(name, 'string', value.toString()).catch(console.error).then(); + setStateValue(value.toNumber()); + // seatFlags.setFlags(value.toNumber()); + }, [name, stateValue]); + + return [ + // TODO: Refactor to recycle object instead of generating new object + new SeatFlags(stateValue, totalSeats), + setter, + ]; +}; diff --git a/src/instruments/src/Common/defaults.ts b/src/instruments/src/Common/defaults.ts index 4d9f3629023..be65440c26c 100644 --- a/src/instruments/src/Common/defaults.ts +++ b/src/instruments/src/Common/defaults.ts @@ -1,16 +1,16 @@ // We currently assume that these two elements will be found. // Might be worth implementing checking in the future. -let reactMount = document.getElementById('MSFS_REACT_MOUNT') as HTMLElement; +const reactMount = document.getElementById('MSFS_REACT_MOUNT') as HTMLElement; -const getEcamPageRenderTarget = (pageName: string): HTMLElement => (document.getElementById(`A32NX_${pageName}_PAGE_REACT_MOUNT`) as HTMLElement); +// const getEcamPageRenderTarget = (pageName: string): HTMLElement => (document.getElementById(`A32NX_${pageName}_PAGE_REACT_MOUNT`) as HTMLElement); /** * Configures the framework to render inside the ECAM. Temporary solution for moving individual SD pages to React. */ -export const setIsEcamPage = (pageName: string) => { +/* export const setIsEcamPage = (pageName: string) => { reactMount = getEcamPageRenderTarget(pageName); -}; +}; */ /** * Returns the render target which React mounts onto diff --git a/src/instruments/src/Common/utils.tsx b/src/instruments/src/Common/utils.tsx index bfaa693e404..b9d07f44784 100644 --- a/src/instruments/src/Common/utils.tsx +++ b/src/instruments/src/Common/utils.tsx @@ -1,9 +1,9 @@ import React from 'react'; -export type LayerProps = { x: number, y: number, id?: string, className?: string } +export type LayerProps = { x: number, y: number, id?: string, className?: string, visibility?: string } -export const Layer: React.FC = ({ x = 0, y = 0, id, className, children }) => ( - +export const Layer: React.FC = ({ x = 0, y = 0, id, className, children, visibility = 'visible' }) => ( + {children} ); diff --git a/src/instruments/src/EFB/Efb.tsx b/src/instruments/src/EFB/Efb.tsx index 32a36c43dc7..c9cee1270b7 100644 --- a/src/instruments/src/EFB/Efb.tsx +++ b/src/instruments/src/EFB/Efb.tsx @@ -3,15 +3,17 @@ import React, { useEffect, useState } from 'react'; +import useInterval from '@instruments/common/useInterval'; import { Redirect, Route, Switch, useHistory } from 'react-router-dom'; import { useSimVar } from '@instruments/common/simVars'; import { useInteractionEvent } from '@instruments/common/hooks'; -import { Battery } from 'react-bootstrap-icons'; -import { ToastContainer, toast } from 'react-toastify'; import { usePersistentNumberProperty, usePersistentProperty } from '@instruments/common/persistence'; + +import { Battery } from 'react-bootstrap-icons'; +import { toast, ToastContainer } from 'react-toastify'; import { distanceTo } from 'msfs-geo'; -import useInterval from '@instruments/common/useInterval'; import { Tooltip } from './UtilComponents/TooltipWrapper'; +import { FbwLogo } from './UtilComponents/FbwLogo'; import { AlertModal, ModalContainer, useModals } from './UtilComponents/Modals/Modals'; import NavigraphClient, { NavigraphContext } from './ChartsApi/Navigraph'; import 'react-toastify/dist/ReactToastify.css'; @@ -19,7 +21,6 @@ import './toast.css'; import { StatusBar } from './StatusBar/StatusBar'; import { ToolBar } from './ToolBar/ToolBar'; - import { Dashboard } from './Dashboard/Dashboard'; import { Dispatch } from './Dispatch/Dispatch'; import { Ground } from './Ground/Ground'; @@ -31,10 +32,7 @@ import { Failures } from './Failures/Failures'; import { Presets } from './Presets/Presets'; import { clearEfbState, useAppDispatch, useAppSelector } from './Store/store'; - import { fetchSimbriefDataAction, isSimbriefDataLoaded } from './Store/features/simBrief'; - -import { FbwLogo } from './UtilComponents/FbwLogo'; import { setFlightPlanProgress } from './Store/features/flightProgress'; import { Checklists, setAutomaticItemStates } from './Checklists/Checklists'; import { CHECKLISTS } from './Checklists/Lists'; @@ -243,7 +241,6 @@ const Efb = () => { const offToLoaded = () => { const shouldWait = powerState === PowerStates.SHUTOFF || powerState === PowerStates.EMPTY; setPowerState(PowerStates.LOADING); - if (shouldWait) { setTimeout(() => { setPowerState(PowerStates.LOADED); @@ -251,6 +248,7 @@ const Efb = () => { } else { setPowerState(PowerStates.LOADED); } + return (<>); }; useInteractionEvent('A32NX_EFB_POWER', () => { diff --git a/src/instruments/src/EFB/Ground/Pages/Payload/Loadsheet/a20nv55.json b/src/instruments/src/EFB/Ground/Pages/Payload/Loadsheet/a20nv55.json index 5a8d86df9b8..45d2a6ecb52 100644 --- a/src/instruments/src/EFB/Ground/Pages/Payload/Loadsheet/a20nv55.json +++ b/src/instruments/src/EFB/Ground/Pages/Payload/Loadsheet/a20nv55.json @@ -1,16 +1,16 @@ { "specs": { "prefix": "A32NX", - "emptyPosition": -8.75, - "macSize": 13.454, - "leMacZ": -5.386, + "emptyPosition": -9.42, + "macSize": 13.464, + "leMacZ": -5.383, "weights": { "maxZfw": 64300, "minZfw": 42500 }, "pax": { - "defaultPaxWeight": 80, - "defaultBagWeight": 15, + "defaultPaxWeight": 84, + "defaultBagWeight": 20, "minPaxWeight": 10, "maxPaxWeight": 250, "minBagWeight": 1, @@ -20,6 +20,7 @@ "seatMap": [ { "name": "ROWS [1-6]", + "capacity": 36, "rows": [ { "seats": [ @@ -288,12 +289,13 @@ ], "index": 0, "stationIndex": 1, - "position": 21.98, + "position": 20.0, "fill": 0.19, - "simVar": "A32NX_PAX_TOTAL_ROWS_1_6" + "simVar": "A32NX_PAX_FLAGS_A" }, { "name": "ROWS [7-13]", + "capacity": 42, "rows": [ { "seats": [ @@ -606,12 +608,13 @@ ], "index": 1, "stationIndex": 2, - "position": 2.86, + "position": 0.9, "fill": 0.25, - "simVar": "A32NX_PAX_TOTAL_ROWS_7_13" + "simVar": "A32NX_PAX_FLAGS_B" }, { "name": "ROWS [14-21]", + "capacity": 48, "rows": [ { "seats": [ @@ -968,12 +971,13 @@ ], "index": 2, "stationIndex": 3, - "position": -15.34, + "position": -17.3, "fill": 0.28, - "simVar": "A32NX_PAX_TOTAL_ROWS_14_21" + "simVar": "A32NX_PAX_FLAGS_C" }, { "name": "ROWS [22-29]", + "capacity": 48, "rows": [ { "seats": [ @@ -1331,8 +1335,8 @@ "fill": 0.28, "index": 3, "stationIndex": 4, - "position": -32.81, - "simVar": "A32NX_PAX_TOTAL_ROWS_22_29" + "position": -36.3, + "simVar": "A32NX_PAX_FLAGS_D" } ], "cargoMap": [ @@ -1341,7 +1345,7 @@ "weight": 3402, "index": 0, "stationIndex": 5, - "position": 18.28, + "position": 16.3, "progressBarWidth": 160, "simVar": "A32NX_CARGO_FWD_BAGGAGE_CONTAINER" }, @@ -1350,7 +1354,7 @@ "weight": 2426, "index": 1, "stationIndex": 6, - "position": -15.96, + "position": -25.1, "progressBarWidth": 100, "simVar": "A32NX_CARGO_AFT_CONTAINER" }, @@ -1359,7 +1363,7 @@ "weight": 2110, "index": 2, "stationIndex": 7, - "position": -27.1, + "position": -35.1, "progressBarWidth": 100, "simVar": "A32NX_CARGO_AFT_BAGGAGE" }, @@ -1368,7 +1372,7 @@ "weight": 1497, "index": 3, "stationIndex": 8, - "position": -37.35, + "position": -44.4, "progressBarWidth": 100, "simVar": "A32NX_CARGO_AFT_BULK_LOOSE" } diff --git a/src/instruments/src/EFB/Ground/Pages/Payload/Payload.tsx b/src/instruments/src/EFB/Ground/Pages/Payload/Payload.tsx index 97d1f23ac69..494d442b05d 100644 --- a/src/instruments/src/EFB/Ground/Pages/Payload/Payload.tsx +++ b/src/instruments/src/EFB/Ground/Pages/Payload/Payload.tsx @@ -11,12 +11,12 @@ import { import { useSimVar } from '@instruments/common/simVars'; import { Units } from '@shared/units'; import { usePersistentProperty } from '@instruments/common/persistence'; -import { BitFlags } from '@shared/bitFlags'; -import { useBitFlags } from '@instruments/common/bitFlags'; import { round } from 'lodash'; +import { useSeatFlags } from '@instruments/common/bitFlags'; +import { SeatFlags } from '@shared/bitFlags'; import { CargoWidget } from './Seating/CargoWidget'; import { ChartWidget } from './Chart/ChartWidget'; -import { PaxStationInfo, CargoStationInfo } from './Seating/Constants'; +import { CargoStationInfo, PaxStationInfo } from './Seating/Constants'; import { t } from '../../../translation'; import { TooltipWrapper } from '../../../UtilComponents/TooltipWrapper'; import { SimpleInput } from '../../../UtilComponents/Form/SimpleInput/SimpleInput'; @@ -32,6 +32,34 @@ export const Payload = () => { const { usingMetric } = Units; const { showModal } = useModals(); + const [aFlags] = useSeatFlags(`L:${Loadsheet.seatMap[0].simVar}`, Loadsheet.seatMap[0].capacity); + const [bFlags] = useSeatFlags(`L:${Loadsheet.seatMap[1].simVar}`, Loadsheet.seatMap[1].capacity); + const [cFlags] = useSeatFlags(`L:${Loadsheet.seatMap[2].simVar}`, Loadsheet.seatMap[2].capacity); + const [dFlags] = useSeatFlags(`L:${Loadsheet.seatMap[3].simVar}`, Loadsheet.seatMap[3].capacity); + + const [aFlagsDesired, setAFlagsDesired] = useSeatFlags(`L:${Loadsheet.seatMap[0].simVar}_DESIRED`, Loadsheet.seatMap[0].capacity); + const [bFlagsDesired, setBFlagsDesired] = useSeatFlags(`L:${Loadsheet.seatMap[1].simVar}_DESIRED`, Loadsheet.seatMap[1].capacity); + const [cFlagsDesired, setCFlagsDesired] = useSeatFlags(`L:${Loadsheet.seatMap[2].simVar}_DESIRED`, Loadsheet.seatMap[2].capacity); + const [dFlagsDesired, setDFlagsDesired] = useSeatFlags(`L:${Loadsheet.seatMap[3].simVar}_DESIRED`, Loadsheet.seatMap[3].capacity); + + const activeFlags = useMemo(() => [aFlags, bFlags, cFlags, dFlags], [aFlags, bFlags, cFlags, dFlags]); + const desiredFlags = useMemo(() => [aFlagsDesired, bFlagsDesired, cFlagsDesired, dFlagsDesired], [aFlagsDesired, bFlagsDesired, cFlagsDesired, dFlagsDesired]); + const setDesiredFlags = useMemo(() => [setAFlagsDesired, setBFlagsDesired, setCFlagsDesired, setDFlagsDesired], []); + + const [fwdBag] = useSimVar(`L:${Loadsheet.cargoMap[0].simVar}`, 'Number', 200); + const [aftCont] = useSimVar(`L:${Loadsheet.cargoMap[1].simVar}`, 'Number', 200); + const [aftBag] = useSimVar(`L:${Loadsheet.cargoMap[2].simVar}`, 'Number', 200); + const [aftBulk] = useSimVar(`L:${Loadsheet.cargoMap[3].simVar}`, 'Number', 200); + + const [fwdBagDesired, setFwdBagDesired] = useSimVar(`L:${Loadsheet.cargoMap[0].simVar}_DESIRED`, 'Number', 200); + const [aftContDesired, setAftContDesired] = useSimVar(`L:${Loadsheet.cargoMap[1].simVar}_DESIRED`, 'Number', 200); + const [aftBagDesired, setAftBagDesired] = useSimVar(`L:${Loadsheet.cargoMap[2].simVar}_DESIRED`, 'Number', 200); + const [aftBulkDesired, setAftBulkDesired] = useSimVar(`L:${Loadsheet.cargoMap[3].simVar}_DESIRED`, 'Number', 200); + + const cargo = useMemo(() => [fwdBag, aftCont, aftBag, aftBulk], [fwdBag, aftCont, aftBag, aftBulk]); + const cargoDesired = useMemo(() => [fwdBagDesired, aftContDesired, aftBagDesired, aftBulkDesired], [fwdBagDesired, aftContDesired, aftBagDesired, aftBulkDesired]); + const setCargoDesired = useMemo(() => [setFwdBagDesired, setAftContDesired, setAftBagDesired, setAftBulkDesired], []); + const massUnitForDisplay = usingMetric ? 'KGS' : 'LBS'; const simbriefDataLoaded = isSimbriefDataLoaded(); @@ -44,62 +72,31 @@ export const Payload = () => { const [emptyWeight] = useSimVar('A:EMPTY WEIGHT', usingMetric ? 'Kilograms' : 'Pounds', 2_000); - const [paxA] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_1_6', 'Number'); - const [paxB] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_7_13', 'Number'); - const [paxC] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_14_21', 'Number'); - const [paxD] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_22_29', 'Number'); - - const pax = [paxA, paxB, paxC, paxD]; - - const [paxADesired, setPaxADesired] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_1_6_DESIRED', 'number'); - const [paxBDesired, setPaxBDesired] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_7_13_DESIRED', 'number'); - const [paxCDesired, setPaxCDesired] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_14_21_DESIRED', 'number'); - const [paxDDesired, setPaxDDesired] = useSimVar('L:A32NX_PAX_TOTAL_ROWS_22_29_DESIRED', 'number'); - const [stationSize, setStationLen] = useState([]); - const totalPax = useMemo(() => pax && pax.length > 0 && pax.reduce((a, b) => a + b), [...pax]); const maxPax = useMemo(() => ((stationSize && stationSize.length > 0) ? stationSize.reduce((a, b) => a + b) : -1), [stationSize]); - const [aFlags, setAFlags] = useBitFlags('PAX_FLAGS_A'); - const [bFlags, setBFlags] = useBitFlags('PAX_FLAGS_B'); - const [cFlags, setCFlags] = useBitFlags('PAX_FLAGS_C'); - const [dFlags, setDFlags] = useBitFlags('PAX_FLAGS_D'); - - const paxDesired = [paxADesired, paxBDesired, paxCDesired, paxDDesired]; - const [setPaxDesired] = useState([setPaxADesired, setPaxBDesired, setPaxCDesired, setPaxDDesired]); - const totalPaxDesired = useMemo(() => (paxDesired && paxDesired.length > 0 && paxDesired.reduce((a, b) => parseInt(a) + parseInt(b))), [...paxDesired]); - - const [aFlagsDesired, setAFlagsDesired] = useBitFlags('PAX_FLAGS_A_DESIRED'); - const [bFlagsDesired, setBFlagsDesired] = useBitFlags('PAX_FLAGS_B_DESIRED'); - const [cFlagsDesired, setCFlagsDesired] = useBitFlags('PAX_FLAGS_C_DESIRED'); - const [dFlagsDesired, setDFlagsDesired] = useBitFlags('PAX_FLAGS_D_DESIRED'); - - const activeFlags = [aFlags, bFlags, cFlags, dFlags]; - const desiredFlags = [aFlagsDesired, bFlagsDesired, cFlagsDesired, dFlagsDesired]; - const setActiveFlags = useMemo(() => [setAFlags, setBFlags, setCFlags, setDFlags], []); - const setDesiredFlags = useMemo(() => [setAFlagsDesired, setBFlagsDesired, setCFlagsDesired, setDFlagsDesired], []); - - const [clicked, setClicked] = useState(false); - - const [fwdBag] = useSimVar('L:A32NX_CARGO_FWD_BAGGAGE_CONTAINER', 'Number', 200); - const [aftCont] = useSimVar('L:A32NX_CARGO_AFT_CONTAINER', 'Number', 200); - const [aftBag] = useSimVar('L:A32NX_CARGO_AFT_BAGGAGE', 'Number', 200); - const [aftBulk] = useSimVar('L:A32NX_CARGO_AFT_BULK_LOOSE', 'Number', 200); - - const cargo = [fwdBag, aftCont, aftBag, aftBulk]; + // Calculate Total Pax from Pax Flags + const totalPax = useMemo(() => { + let p = 0; + activeFlags.forEach((flag) => { + p += flag.getTotalFilledSeats(); + }); + return p; + }, [...activeFlags]); - const [fwdBagDesired, setFwdBagDesired] = useSimVar('L:A32NX_CARGO_FWD_BAGGAGE_CONTAINER_DESIRED', 'Number', 200); - const [aftContDesired, setAftContDesired] = useSimVar('L:A32NX_CARGO_AFT_CONTAINER_DESIRED', 'Number', 200); - const [aftBagDesired, setAftBagDesired] = useSimVar('L:A32NX_CARGO_AFT_BAGGAGE_DESIRED', 'Number', 200); - const [aftBulkDesired, setAftBulkDesired] = useSimVar('L:A32NX_CARGO_AFT_BULK_LOOSE_DESIRED', 'Number', 200); + const totalPaxDesired = useMemo(() => { + let p = 0; + desiredFlags.forEach((flag) => { + p += flag.getTotalFilledSeats(); + }); + return p; + }, [...desiredFlags]); - const cargoDesired = [fwdBagDesired, aftContDesired, aftBagDesired, aftBulkDesired]; - const setCargoDesired = useMemo(() => [setFwdBagDesired, setAftContDesired, setAftBagDesired, setAftBulkDesired], []); - const totalCargoDesired = useMemo(() => ((cargoDesired && cargoDesired.length > 0) ? cargoDesired.reduce((a, b) => parseInt(a) + parseInt(b)) : -1), [...cargoDesired, ...paxDesired]); + const totalCargoDesired = useMemo(() => ((cargoDesired && cargoDesired.length > 0) ? cargoDesired.reduce((a, b) => a + b) : -1), [...cargoDesired]); const [cargoStationSize, setCargoStationLen] = useState([]); - const totalCargo = useMemo(() => ((cargo && cargo.length > 0) ? cargo.reduce((a, b) => parseInt(a) + parseInt(b)) : -1), [...cargo, ...pax]); + const totalCargo = useMemo(() => ((cargo && cargo.length > 0) ? cargo.reduce((a, b) => a + b) : -1), [...cargo]); const maxCargo = useMemo(() => ((cargoStationSize && cargoStationSize.length > 0) ? cargoStationSize.reduce((a, b) => a + b) : -1), [cargoStationSize]); const [centerCurrent] = useSimVar('FUEL TANK CENTER QUANTITY', 'Gallons', 2_000); @@ -161,63 +158,16 @@ export const Payload = () => { const [eng2Running] = useSimVar('ENG COMBUSTION:2', 'Bool', 2_000); const [coldAndDark, setColdAndDark] = useState(true); - const returnSeats = useCallback((stationIndex: number, empty: boolean, flags: BitFlags[]): number[] => { - const seats: number[] = []; - const bitFlags: BitFlags = flags[stationIndex]; - for (let seatId = 0; seatId < stationSize[stationIndex]; seatId++) { - if (!empty && bitFlags.getBitIndex(seatId)) { - seats.push(seatId); - } else if (empty && !bitFlags.getBitIndex(seatId)) { - seats.push(seatId); - } - } - return seats; - }, [...desiredFlags, ...activeFlags]); - - const returnNumSeats = useCallback((stationIndex: number, empty: boolean, flags: BitFlags[]): number => { - let count = 0; - const bitFlags: BitFlags = flags[stationIndex]; - for (let seatId = 0; seatId < stationSize[stationIndex]; seatId++) { - if (!empty && bitFlags.getBitIndex(seatId)) { - count++; - } else if (empty && !bitFlags.getBitIndex(seatId)) { - count++; - } - } - return count; - }, [...desiredFlags, ...activeFlags]); - - const chooseSeats = useCallback((stationIndex: number, choices: number[], numChoose: number) => { - const bitFlags: BitFlags = activeFlags[stationIndex]; - for (let i = 0; i < numChoose; i++) { - if (choices.length > 0) { - const chosen = ~~(Math.random() * choices.length); - bitFlags.toggleBitIndex(choices[chosen]); - choices.splice(chosen, 1); - } - } - setActiveFlags[stationIndex](bitFlags); - }, [...pax, ...activeFlags]); - - const chooseDesiredSeats = useCallback((stationIndex: number, choices: number[], numChoose: number) => { - const bitFlags: BitFlags = desiredFlags[stationIndex]; - for (let i = 0; i < numChoose; i++) { - if (choices.length > 0) { - const chosen = ~~(Math.random() * choices.length); - bitFlags.toggleBitIndex(choices[chosen]); - choices.splice(chosen, 1); - } + const chooseDesiredSeats = useCallback((stationIndex: number, fillSeats: boolean = true, numChoose: number) => { + const seatFlags: SeatFlags = desiredFlags[stationIndex]; + if (fillSeats) { + seatFlags.fillEmptySeats(numChoose); + } else { + seatFlags.emptyFilledSeats(numChoose); } - setDesiredFlags[stationIndex](bitFlags); - }, [...paxDesired, ...desiredFlags]); - const calculateSeatOptions = useCallback((stationIndex: number, increase: boolean): number[] => { - const plannedSeats = returnSeats(stationIndex, increase, desiredFlags); - const activeSeats = returnSeats(stationIndex, !increase, activeFlags); - - const intersection = activeSeats.filter((element) => plannedSeats.includes(element)); - return intersection; - }, [...activeFlags, ...desiredFlags]); + setDesiredFlags[stationIndex](seatFlags); + }, [...desiredFlags]); const setTargetPax = useCallback((numOfPax: number) => { if (!stationSize || numOfPax === totalPaxDesired || numOfPax > maxPax || numOfPax < 0) return; @@ -225,20 +175,24 @@ export const Payload = () => { let paxRemaining = numOfPax; const fillStation = (stationIndex: number, percent: number, paxToFill: number) => { - const pax = Math.min(Math.trunc(percent * paxToFill), stationSize[stationIndex]); - setPaxDesired[stationIndex](pax); - paxRemaining -= pax; + const sFlags: SeatFlags = desiredFlags[stationIndex]; + const toBeFilled = Math.min(Math.trunc(percent * paxToFill), stationSize[stationIndex]); + + paxRemaining -= toBeFilled; - const paxCount = returnNumSeats(stationIndex, false, activeFlags); - const seats: number[] = returnSeats(stationIndex, pax[stationIndex] > paxCount, activeFlags); - chooseDesiredSeats(stationIndex, seats, Math.abs(paxCount - pax[stationIndex])); + const planSeatedPax = sFlags.getTotalFilledSeats(); + chooseDesiredSeats( + stationIndex, + (toBeFilled > planSeatedPax), + Math.abs(toBeFilled - planSeatedPax), + ); }; - for (let i = pax.length - 1; i > 0; i--) { + for (let i = seatMap.length - 1; i > 0; i--) { fillStation(i, seatMap[i].fill, numOfPax); } fillStation(0, 1, paxRemaining); - }, [...paxDesired, totalPaxDesired, maxPax, ...stationSize, ...seatMap]); + }, [maxPax, ...stationSize, ...seatMap, totalPaxDesired]); const setTargetCargo = useCallback((numberOfPax: number, freight: number, perBagWeight: number = paxBagWeight) => { const bagWeight = numberOfPax * perBagWeight; @@ -256,23 +210,24 @@ export const Payload = () => { fillCargo(i, cargoStationSize[i] / maxCargo, loadableCargoWeight); } fillCargo(0, 1, remainingWeight); - }, [...cargoDesired, paxBagWeight, ...cargoStationSize]); + }, [maxCargo, ...cargoStationSize, ...cargoMap, ...cargoDesired, paxBagWeight]); const calculatePaxMoment = useCallback(() => { let paxMoment = 0; - pax.forEach((station, i) => { - paxMoment += station * paxWeight * seatMap[i].position; + activeFlags.forEach((stationFlag, i) => { + paxMoment += stationFlag.getTotalFilledSeats() * paxWeight * seatMap[i].position; }); return paxMoment; - }, [paxWeight, ...pax, seatMap]); + }, [paxWeight, seatMap, ...activeFlags]); const calculatePaxDesiredMoment = useCallback(() => { let paxMoment = 0; - paxDesired.forEach((station, i) => { - paxMoment += station * paxWeight * seatMap[i].position; + desiredFlags.forEach((stationFlag, i) => { + paxMoment += stationFlag.getTotalFilledSeats() * paxWeight * seatMap[i].position; }); + return paxMoment; - }, [paxWeight, ...paxDesired, seatMap]); + }, [paxWeight, seatMap, ...desiredFlags]); const calculateCargoMoment = useCallback(() => { let cargoMoment = 0; @@ -311,33 +266,30 @@ export const Payload = () => { setCargoDesired[cargoStation](Math.round(Units.kilogramToUser(cargoMap[cargoStation].weight) * cargoPercent)); }, [cargoMap]); - const onClickSeat = useCallback((station: number, seatId: number) => { - setClicked(true); - let newPax = totalPaxDesired; - // TODO FIXME: This calculation does not work correctly if user clicks on many seats in rapid succession - const freight = Math.max(totalCargoDesired - totalPaxDesired * paxBagWeight, 0); - const bitFlags: BitFlags = desiredFlags[station]; + const onClickSeat = useCallback((stationIndex: number, seatId: number) => { + const seatFlags: SeatFlags = desiredFlags[stationIndex]; + seatFlags.toggleSeatId(seatId); + setDesiredFlags[stationIndex](seatFlags); - if (bitFlags.getBitIndex(seatId)) { - newPax -= 1; - setPaxDesired[station](Math.max(paxDesired[station] - 1, 0)); - } else { - newPax += 1; - setPaxDesired[station](Math.min(paxDesired[station] + 1, stationSize[station])); - } + let newPaxDesired = 0; + desiredFlags.forEach((flag) => { + newPaxDesired += flag.getTotalFilledSeats(); + }); + // TODO FIXME: This calculation does not work correctly if user clicks on many seats in rapid succession + const newPaxBag = newPaxDesired * paxBagWeight; + const paxDelta = newPaxDesired - totalPaxDesired; + const freight = Math.max(totalCargoDesired - newPaxBag + paxDelta * paxBagWeight, 0); - setTargetCargo(newPax, freight); - bitFlags.toggleBitIndex(seatId); - setDesiredFlags[station](bitFlags); - setTimeout(() => setClicked(false), 500); + setTargetCargo(newPaxDesired, freight); }, [ - totalPaxDesired, paxBagWeight, - totalCargoDesired, totalPaxDesired, - ...cargoDesired, ...paxDesired, + paxBagWeight, + totalCargoDesired, + ...cargoDesired, ...desiredFlags, ...stationSize, + totalPaxDesired, ]); - const handleDeboarding = () => { + const handleDeboarding = useCallback(() => { if (!boardingStarted) { showModal( { ); } setBoardingStarted(false); - }; + }, [totalPaxDesired, totalPax, totalCargo, totalCargoDesired]); + + const calculateBoardingTime = useMemo(() => { + // factors taken from flybywire-aircraft-a320-neo/html_ui/Pages/A32NX_Core/A32NX_Boarding.js line 175+ + let boardingRateMultiplier = 0; + if (boardingRate === 'REAL') { + boardingRateMultiplier = 5; + } else if (boardingRate === 'FAST') { + boardingRateMultiplier = 1; + } + + // value taken from flybywire-aircraft-a320-neo/html_ui/Pages/A32NX_Core/A32NX_Boarding.js line 210 + const cargoWeightPerWeightStep = 60; + + const differentialPax = Math.abs(totalPaxDesired - totalPax); + const differentialCargo = Math.abs(totalCargoDesired - totalCargo); + + const estimatedPaxBoardingSeconds = differentialPax * boardingRateMultiplier; + const estimatedCargoLoadingSeconds = (differentialCargo / cargoWeightPerWeightStep) * boardingRateMultiplier; + + return Math.max(estimatedPaxBoardingSeconds, estimatedCargoLoadingSeconds); + }, [totalPaxDesired, totalPax, totalCargoDesired, totalCargo, boardingRate]); const boardingStatusClass = useMemo(() => { if (!boardingStarted) { return 'text-theme-highlight'; } return (totalPaxDesired * paxWeight + totalCargoDesired) >= (totalPax * paxWeight + totalCargo) ? 'text-green-500' : 'text-yellow-500'; - }, [boardingStarted, paxWeight, totalPaxDesired, totalCargoDesired, totalPax, totalCargo]); + }, [boardingStarted, paxWeight, totalCargoDesired, totalCargo, totalPaxDesired, totalPax]); // Init useEffect(() => { @@ -397,11 +370,7 @@ export const Payload = () => { stationSize.push(0); } seatMap.forEach((station, i) => { - station.rows.forEach((row) => { - row.seats.forEach(() => { - stationSize[i]++; - }); - }); + stationSize[i] = station.capacity; }); setStationLen(stationSize); }, [seatMap]); @@ -418,89 +387,10 @@ export const Payload = () => { setCargoStationLen(cargoSize); }, [cargoMap]); - // Check that pax data and bitflags are valid - useEffect(() => { - pax.forEach((stationPaxNum: number, stationIndex: number) => { - const paxCount = returnNumSeats(stationIndex, false, activeFlags); - if (stationPaxNum === 0 && paxCount !== stationPaxNum) { - setActiveFlags[stationIndex](new BitFlags(0)); - } - }); - - paxDesired.forEach((stationPaxNum, stationIndex) => { - const paxCount = returnNumSeats(stationIndex, false, desiredFlags); - if (stationPaxNum === 0 && paxCount !== stationPaxNum) { - setDesiredFlags[stationIndex](new BitFlags(0)); - } - }); - if (!boardingStarted) { - setTargetPax(totalPax); - setTargetCargo(0, totalCargo); - } - }, [stationSize]); - - // Adjusted desired passenger seating layout to match station passenger count on change useEffect(() => { - paxDesired.forEach((stationNumPax, stationIndex) => { - const paxCount = returnNumSeats(stationIndex, false, desiredFlags); - if (!clicked && stationNumPax !== paxCount) { - const seatOptions = calculateSeatOptions(stationIndex, stationNumPax > paxCount); - const seatDelta = Math.abs(paxCount - stationNumPax); - - if (seatOptions.length >= seatDelta) { - chooseDesiredSeats(stationIndex, seatOptions, seatDelta); - } else if (seatOptions.length && seatOptions.length < seatDelta) { - // Fallback if we don't have enough seat options using desired as reference - const leftOver = seatDelta - seatOptions.length; - chooseDesiredSeats(stationIndex, seatOptions, seatOptions.length); - const seats: number[] = returnSeats(stationIndex, stationNumPax > paxCount, desiredFlags); - chooseDesiredSeats(stationIndex, seats, leftOver); - } else { - // Fallback if no seat options using desired as reference - const seats: number[] = returnSeats(stationIndex, stationNumPax > paxCount, desiredFlags); - chooseDesiredSeats(stationIndex, seats, seatDelta); - } - } - }); - }, [...paxDesired]); - - // Adjust actual passenger seating layout to match station passenger count on change - useEffect(() => { - pax.forEach((stationNumPax: number, stationIndex: number) => { - const paxCount = returnNumSeats(stationIndex, false, activeFlags); - if (!clicked && stationNumPax !== paxCount) { - const seatOptions = calculateSeatOptions(stationIndex, stationNumPax < paxCount); - const seatDelta = Math.abs(paxCount - stationNumPax); - if (seatOptions.length >= seatDelta) { - chooseSeats(stationIndex, seatOptions, seatDelta); - } else if (seatOptions.length && seatOptions.length < seatDelta) { - // Fallback if we don't have enough seat options using desired as reference - const leftOver = seatDelta - seatOptions.length; - chooseSeats(stationIndex, seatOptions, seatOptions.length); - const seats: number[] = returnSeats(stationIndex, stationNumPax > paxCount, activeFlags); - chooseSeats(stationIndex, seats, leftOver); - } else { - // Fallback if no seat options using desired as reference - const seats: number[] = returnSeats(stationIndex, stationNumPax > paxCount, activeFlags); - chooseSeats(stationIndex, seats, seatDelta); - } - } - }); - }, [...pax]); - - useEffect(() => { - pax.forEach((stationNumPax: number, stationIndex: number) => { - // Sync active to desired layout if pax is equal to desired - if (stationNumPax === parseInt(paxDesired[stationIndex])) { - setActiveFlags[stationIndex](desiredFlags[stationIndex]); - } - }); - }, [boardingStarted]); - - useEffect(() => { - const centerTankMoment = -6; + const centerTankMoment = -4.5; const innerTankMoment = -8; - const outerTankMoment = -13; + const outerTankMoment = -17.6; // Adjust ZFW CG Values based on payload const newZfw = emptyWeight + totalPax * paxWeight + totalCargo; const newZfwDesired = emptyWeight + totalPaxDesired * paxWeight + totalCargoDesired; @@ -568,13 +458,20 @@ export const Payload = () => { setMlwDesiredCg(newDesiredCg); } }, [ - ...pax, ...paxDesired, + ...desiredFlags, ...activeFlags, ...cargo, ...cargoDesired, ...fuel, destEfob, paxWeight, paxBagWeight, emptyWeight, ]); + const remainingTimeString = () => { + const minutes = Math.round(calculateBoardingTime / 60); + const seconds = calculateBoardingTime % 60; + const padding = seconds < 10 ? '0' : ''; + return `${minutes}:${padding}${seconds.toFixed(0)} ${t('Ground.Payload.EstimatedDurationUnit')}`; + }; + return (
@@ -753,7 +650,7 @@ export const Payload = () => {