Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(efb/fbw): Support for TO/GA button built into the throttle (not on axis) #8247

Merged
merged 21 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

## 0.12.0

1. [EFB/FBW] Added option for TOGA off axis for devices where the TOGA button is built into the throttle - @ImmortalCake
ImmortalCake marked this conversation as resolved.
Show resolved Hide resolved
1. [EFB/ATSU] Added NOAA (aviationweather.gov) as a METAR source - @tracernz (Mike)
1. [EFB] Fixed the main page and landing calculator to use the selected METAR source - @tracernz (Mike)
1. [FMS] Improve layout of PERF CLB, PERF CRZ and PERF DES pages according to H3 - @BlueberryKing (BlueberryKing)
Expand Down
1 change: 1 addition & 0 deletions fbw-a32nx/src/localization/flypad/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@
"ReverseFull": "Reverse Full",
"ReverseIdle": "Reverse Idle",
"ReverserOnAxis": "Reverser On Axis",
"TogaOnAxis": "TOGA On Axis",
"SaveAndApply": "Save and Apply",
"SetFromThrottle": "Set from Throttle",
"ThrottleConfigurationReset": "Throttle Configuration Reset"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export const ThrottleConfig = ({ isShown, onClose }: ThrottleConfigProps) => {
const [reverserOnAxis1, setReverserOnAxis1] = useSimVar('L:A32NX_THROTTLE_MAPPING_USE_REVERSE_ON_AXIS:1', 'number', 1000);
const [, setReverserOnAxis2] = useSimVar('L:A32NX_THROTTLE_MAPPING_USE_REVERSE_ON_AXIS:2', 'number', 1000);

const [togaOnAxis1, setTogaOnAxis1] = useSimVar('L:A32NX_THROTTLE_MAPPING_USE_TOGA_ON_AXIS:1', 'number', 1000);
const [, setTogaOnAxis2] = useSimVar('L:A32NX_THROTTLE_MAPPING_USE_TOGA_ON_AXIS:2', 'number', 1000);

const [, syncToDisk] = useSimVar('K:A32NX.THROTTLE_MAPPING_SAVE_TO_FILE', 'number', 1000);
const [, defaultsToThrottle] = useSimVar('K:A32NX.THROTTLE_MAPPING_SET_DEFAULTS', 'number', 100);
const [, syncToThrottle] = useSimVar('K:A32NX.THROTTLE_MAPPING_LOAD_FROM_FILE', 'number', 100);
Expand Down Expand Up @@ -76,15 +79,18 @@ export const ThrottleConfig = ({ isShown, onClose }: ThrottleConfigProps) => {
if (reverserOnAxis1 === 0 && selectedIndex < 2) {
setSelectedIndex(2);
}
if (togaOnAxis1 === 0 && selectedIndex > 4) {
setSelectedIndex(4);
}
}, [reverserOnAxis1, selectedIndex]);

const getOverlapErrors = (mappingsAxis: ThrottleSimvar[]) => {
const overlapErrors: string[] = [];

for (let index = reverserOnAxis1 ? 0 : 2; index < mappingsAxis.length; index++) {
for (let index = reverserOnAxis1 ? 0 : 2; index < (togaOnAxis1 ? mappingsAxis.length : mappingsAxis.length - 1); index++) {
const element = mappingsAxis[index];

for (let nextIndex = index + 1; nextIndex < mappingsAxis.length; nextIndex++) {
for (let nextIndex = index + 1; nextIndex < (togaOnAxis1 ? mappingsAxis.length : mappingsAxis.length - 1); nextIndex++) {
const nextElement = mappingsAxis[nextIndex];
if (element.getHiGetter() >= nextElement.getLowGetter() || element.getLowGetter() >= nextElement.getHiGetter()) {
overlapErrors.push(`${element.readableName} (${element.getLowGetter().toFixed(2)}) ${t('Settings.ThrottleConfig.ErrorOverlapMsg')} ${nextElement.readableName} (${nextElement.getLowGetter().toFixed(2)})`);
Expand All @@ -110,6 +116,14 @@ export const ThrottleConfig = ({ isShown, onClose }: ThrottleConfigProps) => {
}
};

const setTogaOnAxis = (togaOnAxis: number) => {
setTogaOnAxis1(togaOnAxis);
setTogaOnAxis2(togaOnAxis);
if (togaOnAxis === 0 && selectedIndex > 4) {
setSelectedIndex(4);
}
};

const switchDetent = (index: number) => {
if (index >= 0 && index <= 5) {
setSelectedIndex(index);
Expand All @@ -118,7 +132,18 @@ export const ThrottleConfig = ({ isShown, onClose }: ThrottleConfigProps) => {

const navigationBar = (
<VerticalSelectGroup>
<SelectItem onSelect={() => switchDetent(5)} selected={selectedIndex === 5}>TO/GA</SelectItem>
<SelectItem
disabled={!togaOnAxis1}
className={`${togaOnAxis1 ? '' : 'opacity-30'}`}
onSelect={() => {
if (togaOnAxis1) {
switchDetent(5);
}
}}
selected={selectedIndex === 5}
>
TO/GA
</SelectItem>
<SelectItem onSelect={() => switchDetent(4)} selected={selectedIndex === 4}>FLX</SelectItem>
<SelectItem onSelect={() => switchDetent(3)} selected={selectedIndex === 3}>CLB</SelectItem>
<SelectItem onSelect={() => switchDetent(2)} selected={selectedIndex === 2}>Idle</SelectItem>
Expand Down Expand Up @@ -263,6 +288,10 @@ export const ThrottleConfig = ({ isShown, onClose }: ThrottleConfigProps) => {
<div className="space-y-2">
<div>
<div className="flex flex-row justify-center items-center p-4 mt-auto mb-8 space-x-16 w-full rounded-lg border-2 border-theme-accent">
<div className="flex flex-row justify-center items-center space-x-4">
<div>{t('Settings.ThrottleConfig.TogaOnAxis')}</div>
<Toggle value={!!togaOnAxis1} onToggle={(value) => setTogaOnAxis(value ? 1 : 0)} />
</div>
<div className="flex flex-row justify-center items-center space-x-4">
<div>{t('Settings.ThrottleConfig.ReverserOnAxis')}</div>
<Toggle value={!!reverserOnAxis1} onToggle={(value) => setReversersOnAxis(value ? 1 : 0)} />
Expand Down
52 changes: 42 additions & 10 deletions fbw-common/src/wasm/fbw_common/src/ThrottleAxisMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ThrottleAxisMapping::ThrottleAxisMapping(unsigned int id) {
LVAR_THRUST_LEVER_ANGLE = LVAR_THRUST_LEVER_ANGLE.append(stringId);
LVAR_LOAD_CONFIG = LVAR_LOAD_CONFIG.append(stringId);
LVAR_USE_REVERSE_ON_AXIS = LVAR_USE_REVERSE_ON_AXIS.append(stringId);
LVAR_USE_TOGA_ON_AXIS = LVAR_USE_TOGA_ON_AXIS.append(stringId);
LVAR_DETENT_REVERSE_LOW = LVAR_DETENT_REVERSE_LOW.append(stringId);
LVAR_DETENT_REVERSE_HIGH = LVAR_DETENT_REVERSE_HIGH.append(stringId);
LVAR_DETENT_REVERSEIDLE_LOW = LVAR_DETENT_REVERSEIDLE_LOW.append(stringId);
Expand All @@ -34,6 +35,7 @@ ThrottleAxisMapping::ThrottleAxisMapping(unsigned int id) {
idThrustLeverAngle = std::make_unique<LocalVariable>(LVAR_THRUST_LEVER_ANGLE.c_str());
idUsingConfig = std::make_unique<LocalVariable>(LVAR_LOAD_CONFIG.c_str());
idUseReverseOnAxis = std::make_unique<LocalVariable>(LVAR_USE_REVERSE_ON_AXIS.c_str());
idUseTogaOnAxis = std::make_unique<LocalVariable>(LVAR_USE_TOGA_ON_AXIS.c_str());
idIncrementNormal = std::make_unique<LocalVariable>(LVAR_INCREMENT_NORMAL.c_str());
idIncrementSmall = std::make_unique<LocalVariable>(LVAR_INCREMENT_SMALL.c_str());
idDetentReverseLow = std::make_unique<LocalVariable>(LVAR_DETENT_REVERSE_LOW.c_str());
Expand Down Expand Up @@ -143,10 +145,14 @@ void ThrottleAxisMapping::onEventThrottleSet(long value) {
if (!useReverseOnAxis && !isReverseToggleActive) {
isReverseToggleKeyActive = false;
}
if (!useTogaOnAxis) {
isTogaActive = false;
}
setCurrentValue(value / 16384.0);
}

void ThrottleAxisMapping::onEventThrottleFull() {
isTogaActive = true;
setCurrentValue(1.0);
}

Expand All @@ -157,10 +163,20 @@ void ThrottleAxisMapping::onEventThrottleCut() {
}

void ThrottleAxisMapping::onEventThrottleIncrease() {
if (!useTogaOnAxis && currentValue == 1.0) {
// Specific binding for activating TO/GA when not on axis.
isTogaActive = true;
}
increaseThrottleBy(incrementNormal);
}

void ThrottleAxisMapping::onEventThrottleIncreaseSmall() {
if (!useTogaOnAxis) {
// Specific binding for deactivating TO/GA when not on axis.
// Not using onEventThrottleDecrease because of a bug in MSFS preventing
// use of a key on press and a key on release for the same function.
isTogaActive = false;
}
increaseThrottleBy(incrementSmall);
}

Expand Down Expand Up @@ -231,6 +247,8 @@ void ThrottleAxisMapping::setCurrentValue(double value) {
double newTLA = 0;
if (!useReverseOnAxis && (isReverseToggleActive || isReverseToggleKeyActive)) {
newTLA = (TLA_REVERSE / 2.0) * (value + 1.0);
} else if (!useTogaOnAxis && isTogaActive) {
newTLA = TLA_TOGA;
} else {
newTLA = thrustLeverAngleMapping.get(value);
}
Expand Down Expand Up @@ -280,6 +298,7 @@ void ThrottleAxisMapping::decreaseThrottleBy(double value) {
ThrottleAxisMapping::Configuration ThrottleAxisMapping::getDefaultConfiguration() {
return {
true, // use reverse on axis
true, // use toga on axis
0.05, // increment normal
0.025, // increment small
-1.00, // reverse low
Expand All @@ -299,14 +318,15 @@ ThrottleAxisMapping::Configuration ThrottleAxisMapping::getDefaultConfiguration(

ThrottleAxisMapping::Configuration ThrottleAxisMapping::loadConfigurationFromLocalVariables() {
idUsingConfig->set(true);
return {idUseReverseOnAxis->get() == 1, idIncrementNormal->get(), idIncrementSmall->get(), idDetentReverseLow->get(),
idDetentReverseHigh->get(), idDetentReverseIdleLow->get(), idDetentReverseIdleHigh->get(), idDetentIdleLow->get(),
idDetentIdleHigh->get(), idDetentClimbLow->get(), idDetentClimbHigh->get(), idDetentFlexMctLow->get(),
idDetentFlexMctHigh->get(), idDetentTogaLow->get(), idDetentTogaHigh->get()};
return {idUseReverseOnAxis->get() == 1, idUseTogaOnAxis->get() == 1, idIncrementNormal->get(), idIncrementSmall->get(),
idDetentReverseLow->get(), idDetentReverseHigh->get(), idDetentReverseIdleLow->get(), idDetentReverseIdleHigh->get(),
idDetentIdleLow->get(), idDetentIdleHigh->get(), idDetentClimbLow->get(), idDetentClimbHigh->get(),
idDetentFlexMctLow->get(), idDetentFlexMctHigh->get(), idDetentTogaLow->get(), idDetentTogaHigh->get()};
}

void ThrottleAxisMapping::storeConfigurationInLocalVariables(const Configuration& configuration) {
idUseReverseOnAxis->set(configuration.useReverseOnAxis);
idUseTogaOnAxis->set(configuration.useTogaOnAxis);
idIncrementNormal->set(configuration.incrementNormal);
idIncrementSmall->set(configuration.incrementSmall);
if (configuration.useReverseOnAxis) {
Expand All @@ -326,14 +346,20 @@ void ThrottleAxisMapping::storeConfigurationInLocalVariables(const Configuration
idDetentClimbHigh->set(configuration.climbHigh);
idDetentFlexMctLow->set(configuration.flxMctLow);
idDetentFlexMctHigh->set(configuration.flxMctHigh);
idDetentTogaLow->set(configuration.togaLow);
idDetentTogaHigh->set(configuration.togaHigh);
if (configuration.useTogaOnAxis) {
idDetentTogaLow->set(configuration.togaLow);
idDetentTogaHigh->set(configuration.togaHigh);
} else {
idDetentTogaLow->set(0.0);
idDetentTogaHigh->set(0.0);
}
}

ThrottleAxisMapping::Configuration ThrottleAxisMapping::loadConfigurationFromIniStructure(const INIStructure& structure) {
idUsingConfig->set(true);
return {
INITypeConversion::getBoolean(structure, CONFIGURATION_SECTION_COMMON, "REVERSE_ON_AXIS", false),
INITypeConversion::getBoolean(structure, CONFIGURATION_SECTION_COMMON, "TOGA_ON_AXIS", true),
INITypeConversion::getDouble(structure, CONFIGURATION_SECTION_COMMON, "KEY_INCREMENT_NORMAL", 0.05),
INITypeConversion::getDouble(structure, CONFIGURATION_SECTION_COMMON, "KEY_INCREMENT_SMALL", 0.025),
INITypeConversion::getDouble(structure, CONFIGURATION_SECTION_AXIS, "REVERSE_LOW", -1.00),
Expand All @@ -353,6 +379,7 @@ ThrottleAxisMapping::Configuration ThrottleAxisMapping::loadConfigurationFromIni

void ThrottleAxisMapping::storeConfigurationInIniStructure(INIStructure& structure, const Configuration& configuration) {
structure[CONFIGURATION_SECTION_COMMON]["REVERSE_ON_AXIS"] = configuration.useReverseOnAxis ? "true" : "false";
structure[CONFIGURATION_SECTION_COMMON]["TOGA_ON_AXIS"] = configuration.useTogaOnAxis ? "true" : "false";
structure[CONFIGURATION_SECTION_COMMON]["KEY_INCREMENT_NORMAL"] = std::to_string(configuration.incrementNormal);
structure[CONFIGURATION_SECTION_COMMON]["KEY_INCREMENT_SMALL"] = std::to_string(configuration.incrementSmall);
structure[CONFIGURATION_SECTION_AXIS]["REVERSE_LOW"] = std::to_string(configuration.reverseLow);
Expand All @@ -373,6 +400,9 @@ void ThrottleAxisMapping::updateMappingFromConfiguration(const Configuration& co
// update use reverse on axis
useReverseOnAxis = configuration.useReverseOnAxis;

// update use reverse on axis
useTogaOnAxis = configuration.useTogaOnAxis;

// update increments
incrementNormal = configuration.incrementNormal;
incrementSmall = configuration.incrementSmall;
Expand All @@ -397,12 +427,14 @@ void ThrottleAxisMapping::updateMappingFromConfiguration(const Configuration& co
// flex / mct
mappingTable.emplace_back(configuration.flxMctLow, TLA_FLEX_MCT);
mappingTable.emplace_back(configuration.flxMctHigh, TLA_FLEX_MCT);
// toga
mappingTable.emplace_back(configuration.togaLow, TLA_TOGA);
mappingTable.emplace_back(configuration.togaHigh, TLA_TOGA);
if (configuration.useTogaOnAxis) {
// toga
mappingTable.emplace_back(configuration.togaLow, TLA_TOGA);
mappingTable.emplace_back(configuration.togaHigh, TLA_TOGA);
}

// update interpolation lookup table
thrustLeverAngleMapping.initialize(mappingTable, useReverseOnAxis ? TLA_REVERSE : TLA_IDLE, TLA_TOGA);
thrustLeverAngleMapping.initialize(mappingTable, useReverseOnAxis ? TLA_REVERSE : TLA_IDLE, useTogaOnAxis ? TLA_TOGA : TLA_FLEX_MCT);

// remember idle setting
idleValue = configuration.idleLow;
Expand Down
5 changes: 5 additions & 0 deletions fbw-common/src/wasm/fbw_common/src/ThrottleAxisMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ThrottleAxisMapping {
private:
struct Configuration {
bool useReverseOnAxis;
bool useTogaOnAxis;
double incrementNormal;
double incrementSmall;
double reverseLow;
Expand Down Expand Up @@ -85,12 +86,14 @@ class ThrottleAxisMapping {
void decreaseThrottleBy(double value);

bool useReverseOnAxis = false;
bool useTogaOnAxis = false;
double incrementNormal = 0.0;
double incrementSmall = 0.0;

bool inFlight = false;
bool isReverseToggleActive = false;
bool isReverseToggleKeyActive = false;
bool isTogaActive = false;

double idleValue = 0.0;
double currentValue = 0.0;
Expand All @@ -103,6 +106,7 @@ class ThrottleAxisMapping {

std::unique_ptr<LocalVariable> idUsingConfig;
std::unique_ptr<LocalVariable> idUseReverseOnAxis;
std::unique_ptr<LocalVariable> idUseTogaOnAxis;
std::unique_ptr<LocalVariable> idIncrementNormal;
std::unique_ptr<LocalVariable> idIncrementSmall;
std::unique_ptr<LocalVariable> idDetentReverseLow;
Expand All @@ -122,6 +126,7 @@ class ThrottleAxisMapping {
std::string LVAR_THRUST_LEVER_ANGLE = "A32NX_AUTOTHRUST_TLA:";
std::string LVAR_LOAD_CONFIG = "A32NX_THROTTLE_MAPPING_LOADED_CONFIG:";
std::string LVAR_USE_REVERSE_ON_AXIS = "A32NX_THROTTLE_MAPPING_USE_REVERSE_ON_AXIS:";
std::string LVAR_USE_TOGA_ON_AXIS = "A32NX_THROTTLE_MAPPING_USE_TOGA_ON_AXIS:";
std::string LVAR_INCREMENT_NORMAL = "A32NX_THROTTLE_MAPPING_INCREMENT_NORMAL";
std::string LVAR_INCREMENT_SMALL = "A32NX_THROTTLE_MAPPING_INCREMENT_SMALL";
std::string LVAR_DETENT_REVERSE_LOW = "A32NX_THROTTLE_MAPPING_REVERSE_LOW:";
Expand Down