From 52a6245b490018a4715f1919c0b388a76ba3cdfb Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Fri, 17 Apr 2020 20:25:18 +0100 Subject: [PATCH] Add --carrier-position command line argument Takes special values "FLOLS" and "abeam" to set up aligned for final approach or at the 180 for the carrier flight deck. Or alternatively a catapult or parking position. --- src/GUI/LauncherArgumentTokenizer.cxx | 2 +- src/GUI/LocationController.cxx | 26 +++-- src/GUI/qml/LocationCarrierView.qml | 150 ++++++++++++++------------ src/Main/options.cxx | 12 ++- src/Main/positioninit.cxx | 25 ++++- 5 files changed, 128 insertions(+), 87 deletions(-) diff --git a/src/GUI/LauncherArgumentTokenizer.cxx b/src/GUI/LauncherArgumentTokenizer.cxx index 5f2f5ddc5..562651326 100644 --- a/src/GUI/LauncherArgumentTokenizer.cxx +++ b/src/GUI/LauncherArgumentTokenizer.cxx @@ -148,7 +148,7 @@ void LauncherArgumentTokenizer::setArgString(QString argString) const std::set positionalArgs({ "lat", "lon", "vor", "ndb", "fix" - "airport", "parkpos", "runway", "carrier" + "airport", "parking-id", "runway", "carrier", "carrier-position" }); bool LauncherArgumentTokenizer::haveArgsIn(const std::set& args) const diff --git a/src/GUI/LocationController.cxx b/src/GUI/LocationController.cxx index ac934e878..7188ab334 100644 --- a/src/GUI/LocationController.cxx +++ b/src/GUI/LocationController.cxx @@ -687,7 +687,7 @@ void LocationController::setLocationProperties() "runway-requested" << "navaid-id" << "offset-azimuth-deg" << "offset-distance-nm" << "glideslope-deg" << "speed-set" << "on-ground" << "airspeed-kt" << - "airport-id" << "runway" << "parkpos" << "carrier" << "abeam"; + "airport-id" << "runway" << "parkpos" << "carrier" << "carrier-position"; Q_FOREACH(QString s, props) { SGPropertyNode* c = presets->getChild(s.toStdString()); @@ -717,15 +717,16 @@ void LocationController::setLocationProperties() fgSetString("/sim/presets/carrier", m_carrierName.toStdString()); if (m_useCarrierFLOLS) { - fgSetBool("/sim/presets/runway-requested", true ); - // treat the FLOLS as a runway, for the purposes of communication with position-init - fgSetString("/sim/presets/runway", "FLOLS"); + if (m_abeam) { + fgSetString("/sim/presets/carrier-position", "abeam"); + } else { + fgSetString("/sim/presets/carrier-position", "FLOLS"); + } fgSetDouble("/sim/presets/offset-distance-nm", m_offsetDistance.convertToUnit(Units::NauticalMiles).value); - fgSetBool("/sim/presets/abeam", m_abeam); applyAltitude(); applyAirspeed(); } else if (!m_carrierParking.isEmpty()) { - fgSetString("/sim/presets/parkpos", m_carrierParking.toStdString()); + fgSetString("/sim/presets/carrier-position", m_carrierParking.toStdString()); } if (m_tuneNAV1) { @@ -924,13 +925,16 @@ void LocationController::onCollectConfig() m_config->setArg("carrier", m_carrierName); if (!m_carrierParking.isEmpty()) { - m_config->setArg("parkpos", m_carrierParking); + m_config->setArg("carrier-position", m_carrierParking); } else if (m_useCarrierFLOLS) { - m_config->setArg("runway", QStringLiteral("FLOLS")); + if (m_abeam) { + m_config->setArg("carrier-position", QStringLiteral("abeam")); + } else { + m_config->setArg("carrier-position", QStringLiteral("FLOLS")); + } const double offsetNm = m_offsetDistance.convertToUnit(Units::NauticalMiles).value; m_config->setArg("offset-distance", QString::number(offsetNm)); - if (m_abeam) m_config->setArg("carrier-abeam", QStringLiteral("true")); applyAltitude(); applyAirspeed(); } @@ -951,7 +955,7 @@ void LocationController::onCollectConfig() // pick by default applyOnFinal(); } else if (m_useAvailableParking) { - m_config->setArg("parkpos", QStringLiteral("AVAILABLE")); + m_config->setArg("parking-id", QStringLiteral("AVAILABLE")); } else if (onRunway) { if (m_airportLocation->type() == FGPositioned::AIRPORT) { m_config->setArg("runway", QString::fromStdString(m_detailLocation->ident())); @@ -969,7 +973,7 @@ void LocationController::onCollectConfig() } } else if (atParking) { // parking selection - m_config->setArg("parkpos", QString::fromStdString(m_detailLocation->ident())); + m_config->setArg("parking-id", QString::fromStdString(m_detailLocation->ident())); } // of location is an airport } else { diff --git a/src/GUI/qml/LocationCarrierView.qml b/src/GUI/qml/LocationCarrierView.qml index b51c446d3..77935d226 100644 --- a/src/GUI/qml/LocationCarrierView.qml +++ b/src/GUI/qml/LocationCarrierView.qml @@ -63,7 +63,7 @@ Item { Column { id: selectionGrid spacing: Style.margin - width: parent.width + width: parent.width * 0.3 StyledText { // heading text id: headingText @@ -103,8 +103,6 @@ Item { anchors.verticalCenter: parent.verticalCenter enabled: flolsRadio.selected } - - } // Abeam the FLOLS @@ -132,70 +130,6 @@ Item { } } - // Offset selection - readonly property bool offsetEnabled: (flolsRadio.selected || abeamRadio.selected) - - Row { - anchors.left: parent.left - anchors.leftMargin: Style.margin - anchors.right: parent.right - anchors.rightMargin: Style.margin - spacing: Style.margin - - Item { - height: 1; width: Style.strutSize - } - - NumericalEdit { - id: offsetNmEdit - quantity: _location.offsetDistance - onCommit: _location.offsetDistance = newValue; - label: qsTr("at") - unitsMode: Units.Distance - live: true - anchors.verticalCenter: parent.verticalCenter - enabled: selectionGrid.offsetEnabled - } - - StyledText { - text: qsTr(" from the FLOLS (aka the ball)") - anchors.verticalCenter: parent.verticalCenter - enabled: selectionGrid.offsetEnabled - } - - Item { - height: 1; width: Style.strutSize - } - - ToggleSwitch { - id: airspeedToggle - enabled: selectionGrid.offsetEnabled - checked: _location.speedEnabled - onCheckedChanged: _location.speedEnabled = checked; - anchors.verticalCenter: parent.verticalCenter - } - - NumericalEdit { - id: airspeedSpinbox - label: qsTr("Airspeed:") - unitsMode: Units.SpeedWithoutMach - enabled: _location.speedEnabled && selectionGrid.offsetEnabled - quantity: _location.airspeed - onCommit: _location.airspeed = newValue - anchors.verticalCenter: parent.verticalCenter - } - - Item { - height: 1; width: Style.strutSize - } - - LocationAltitudeRow - { - enabled: selectionGrid.offsetEnabled - width: parent.width - } - - } // of Offset selection // parking row Row { @@ -213,7 +147,11 @@ Item { anchors.verticalCenter: parent.verticalCenter group: radioGroup onClicked: { - if (selected) parkingChoice.setLocation(); + if (selected) { + parkingChoice.setLocation(); + _location.useCarrierFLOLS = false; + _location.abeam = false; + } } selected : (! _location.abeam) && (! _location.useCarrierFLOLS) } @@ -256,9 +194,85 @@ Item { } } } + } + + Column { + id: offsetGrid + spacing: Style.margin + anchors.leftMargin: Style.margin + anchors.right: parent.right + anchors.rightMargin: Style.margin + width: parent.width * 0.7 + anchors.verticalCenter: parent.verticalCenter + + // Offset selection + readonly property bool offsetEnabled: (flolsRadio.selected || abeamRadio.selected) + + Row { + anchors.right: parent.right + anchors.left: parent.left + anchors.leftMargin: Style.margin + anchors.rightMargin: Style.margin + width : parent.width * 0.7 + + NumericalEdit { + id: offsetNmEdit + quantity: _location.offsetDistance + onCommit: _location.offsetDistance = newValue; + label: qsTr("at") + unitsMode: Units.Distance + live: true + anchors.verticalCenter: parent.verticalCenter + enabled: offsetGrid.offsetEnabled + } + + StyledText { + text: qsTr(" from the FLOLS (aka the ball)") + anchors.verticalCenter: parent.verticalCenter + enabled: offsetGrid.offsetEnabled + } + } + + Row { + anchors.right: parent.right + anchors.left: parent.left + anchors.leftMargin: Style.margin + anchors.rightMargin: Style.margin + width : parent.width * 0.7 + + ToggleSwitch { + id: airspeedToggle + enabled: offsetGrid.offsetEnabled + checked: _location.speedEnabled + onCheckedChanged: _location.speedEnabled = checked; + anchors.verticalCenter: parent.verticalCenter + } + + NumericalEdit { + id: airspeedSpinbox + label: qsTr("Airspeed:") + unitsMode: Units.SpeedWithoutMach + enabled: _location.speedEnabled && offsetGrid.offsetEnabled + quantity: _location.airspeed + onCommit: _location.airspeed = newValue + anchors.verticalCenter: parent.verticalCenter + } + + Item { + height: 1; width: Style.strutSize + } + + LocationAltitudeRow + { + enabled: offsetGrid.offsetEnabled + width: parent.width + } + + } // of Offset selection ToggleSwitch { anchors.left: parent.left + anchors.right: parent.right anchors.leftMargin: Style.margin label: qsTr("Tune navigation radio (TACAN) to carrier") checked: _location.tuneNAV1 diff --git a/src/Main/options.cxx b/src/Main/options.cxx index ba02003ac..c6eba0982 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -698,6 +698,7 @@ clearLocation () fgSetString("/sim/presets/ndb-id", ""); fgSetString("/sim/presets/carrier", ""); fgSetString("/sim/presets/parkpos", ""); + fgSetString("/sim/presets/carrier-position", ""); fgSetString("/sim/presets/fix", ""); } @@ -756,6 +757,13 @@ fgOptCarrier( const char * arg ) return FG_OPTIONS_OK; } +static int +fgOptCarrierPos( const char * arg ) +{ + fgSetString("/sim/presets/carrier-position", arg); + return FG_OPTIONS_OK; +} + static int fgOptParkpos( const char * arg ) { @@ -1679,8 +1687,7 @@ struct OptionDesc { {"ndb", true, OPTION_FUNC, "", false, "", fgOptNDB }, {"ndb-frequency", true, OPTION_DOUBLE, "/sim/presets/ndb-freq", false, "", fgOptVOR }, {"carrier", true, OPTION_FUNC, "", false, "", fgOptCarrier }, - {"carrier-abeam", true, OPTION_BOOL, "/sim/presets/carrier-abeam", true, "", 0 }, - {"parkpos", true, OPTION_FUNC, "", false, "", fgOptParkpos }, + {"carrier-position", true, OPTION_FUNC, "", false, "", fgOptCarrierPos }, {"fix", true, OPTION_FUNC, "", false, "", fgOptFIX }, {"offset-distance", true, OPTION_DOUBLE, "/sim/presets/offset-distance-nm", false, "", 0 }, {"offset-azimuth", true, OPTION_DOUBLE, "/sim/presets/offset-azimuth-deg", false, "", 0 }, @@ -1839,6 +1846,7 @@ struct OptionDesc { {"livery", true, OPTION_FUNC, "", false, "", fgOptLivery }, {"ai-scenario", true, OPTION_FUNC | OPTION_MULTI, "", false, "", fgOptScenario }, {"parking-id", true, OPTION_FUNC, "", false, "", fgOptParkpos }, + {"parkpos", true, OPTION_FUNC, "", false, "", fgOptParkpos }, {"version", false, OPTION_IGNORE, "", false, "", 0 }, {"json-report", false, OPTION_IGNORE, "", false, "", 0 }, {"enable-fpe", false, OPTION_IGNORE, "", false, "", 0}, diff --git a/src/Main/positioninit.cxx b/src/Main/positioninit.cxx index ba70eb54d..21867c4b6 100644 --- a/src/Main/positioninit.cxx +++ b/src/Main/positioninit.cxx @@ -836,20 +836,35 @@ void finalizePosition() * carrier, recalculate the 'initial' position here */ std::string carrier = fgGetString("/sim/presets/carrier"); + std::string carrierpos = fgGetString("/sim/presets/carrier-position"); std::string parkpos = fgGetString("/sim/presets/parkpos"); std::string runway = fgGetString("/sim/presets/runway"); std::string apt = fgGetString("/sim/presets/airport-id"); - const bool rwy_req = fgGetBool("/sim/presets/runway-requested"); - const bool abeam = fgGetBool("/sim/presets/carrier-abeam"); if (!carrier.empty()) { - const bool atFLOLS = rwy_req && (runway == "FLOLS" || parkpos == "FLOLS"); + /* /sim/presets/carrier-position can take a number of different values + - name of a parking/cataputt + - FLOLS - to position on final approach + - abeam - on an abeam position from the FLOLS, heading downwind + - indicating a start position of a catapult + */ + + // Convert to lower case to simplify comparison + std::transform(carrierpos.begin(), + carrierpos.end(), + carrierpos.begin(), + [](unsigned char c) { return std::tolower(c); }); + + const bool inair = (carrierpos == "flols") || (carrierpos == "abeam"); + const bool abeam = (carrierpos == "abeam"); InitPosResult carrierResult; - if (atFLOLS) { + if (inair) { carrierResult = setFinalPosFromCarrierFLOLS(carrier, abeam); } else { - carrierResult = setFinalPosFromCarrier(carrier, parkpos); + // We don't simply use carrierpos as it is now lower case, and the + // search against parking/catapult positions is case-sensitive. + carrierResult = setFinalPosFromCarrier(carrier, fgGetString("/sim/presets/carrier-position")); } if (carrierResult == ExactPosition) { done = true;