1
0
Fork 0

Improved launcher metric units support

For our Russian friends, especially. Also add preliminary support
for above-field elevations (needs FG changes)
This commit is contained in:
James Turner 2018-11-07 09:22:50 +01:00
parent d052dc2576
commit 2cd3036488
7 changed files with 83 additions and 23 deletions

View file

@ -682,6 +682,9 @@ void LocationController::applyAirspeed()
if (m_speedEnabled && (m_airspeed.unit != Units::NoUnits)) {
if (m_airspeed.unit == Units::Knots) {
m_config->setArg("vc", QString::number(m_airspeed.value));
} else if (m_airspeed.unit == Units::KilometersPerHour) {
const double vc = m_airspeed.convertToUnit(Units::Knots).value;
m_config->setArg("vc", QString::number(vc));
} else if (m_airspeed.unit == Units::Mach) {
m_config->setArg("mach", QString::number(m_airspeed.value));
} else {
@ -704,7 +707,7 @@ void LocationController::applyPositionOffset()
// flip direction of azimuth to balance the flip done in fgApplyStartOffset
// I don't know why that flip exists but changing it there will break
// command-line compatability so compensating here instead
int offsetAzimuth = m_offsetRadial.value - 180;
int offsetAzimuth = static_cast<int>(m_offsetRadial.value) - 180;
m_config->setArg("offset-azimuth", QString::number(offsetAzimuth));
const double offsetNm = m_offsetDistance.convertToUnit(Units::NauticalMiles).value;
m_config->setArg("offset-distance", QString::number(offsetNm));
@ -733,6 +736,15 @@ void LocationController::applyAltitude()
// FIXME - allow the sim to accept real FlightLevel arguments
m_config->setArg("altitude", QString::number(m_altitude.value * 100));
break;
case Units::FeetAboveFieldElevation:
m_config->setArg("altitude", QString::number(m_altitude.value));
break;
case Units::MetersMSL:
const double ftMSL = m_altitude.convertToUnit(Units::FeetMSL).value;
m_config->setArg("altitude", QString::number(ftMSL));
break;
}
}

View file

@ -22,6 +22,7 @@
#include <cmath>
#include <cassert>
#include <algorithm>
#include <simgear/constants.h>
@ -70,10 +71,12 @@ std::vector<UnitData> static_unitData = {
{ "", "", "" }, // noUnits
{ "ft", "feet above sea-level (MSL)", "000000", false, -2000, 180000, 50},
{ "ft AGL", "feet above ground level (AGL)", "000000", false, 0, 180000, 50},
{ "ft above field", "feet above airfield", "000000", false, 0, 180000, 50},
{ "FL", "Flight-level", "000", true /* prefix */, 0.0, 500.0, 5.0},
{ "m", "meters above sea-level (MSL)", "000000", false, -500, 100000, 50},
{ "kts", "Knots", "9999", false, 0, 999999, 10.0},
{ "M", "Mach", "00.000", true /* prefix */, 0.0, 99.0, 0.05, false /* no wrap */, 3 /* decimal places */},
{ "KM/H", "Kilometers/hour", "9999", false, 0, 999999, 10.0},
{ "°True", "degrees true", "000", false, 0, 359, 5.0, true /* wraps */},
{ "°Mag", "degrees magnetic", "000", false, 0, 359, 5.0, true /* wraps */},
{ "UTC", "Universal coordinated time", ""},
@ -91,11 +94,12 @@ std::vector<UnitsModel::UnitVec> static_modeData = {
{ Units::FeetMSL, Units::FlightLevel},
{ Units::FeetMSL, Units::FeetAGL, Units::FlightLevel},
{ Units::FeetMSL, Units::MetersMSL, Units::FlightLevel},
{ Units::Knots, Units::Mach },
{ Units::Knots },
{ Units::Knots, Units::Mach, Units::KilometersPerHour },
{ Units::Knots, Units::KilometersPerHour },
{ Units::DegreesMagnetic, Units::DegreesTrue },
{ Units::TimeLocal, Units::TimeUTC},
{ Units::NauticalMiles }
{ Units::NauticalMiles, Units::Kilometers },
{ Units::FeetMSL, Units::MetersMSL, Units::FeetAboveFieldElevation},
};
const int UnitLongNameRole = Qt::UserRole + 1;
@ -115,7 +119,7 @@ UnitsModel::UnitsModel()
int UnitsModel::rowCount(const QModelIndex &) const
{
return m_enabledUnits.size();
return static_cast<int>(m_enabledUnits.size());
}
QVariant UnitsModel::data(const QModelIndex &index, int role) const
@ -194,7 +198,13 @@ Units::Type UnitsModel::selectedUnit() const
int UnitsModel::numChoices() const
{
return m_enabledUnits.size();
return static_cast<int>(m_enabledUnits.size());
}
bool UnitsModel::isUnitInMode(int unit) const
{
auto it = std::find(m_enabledUnits.begin(), m_enabledUnits.end(), unit);
return it != m_enabledUnits.end();
}
QHash<int, QByteArray> UnitsModel::roleNames() const
@ -274,9 +284,9 @@ void UnitsModel::setSelectedUnit(int u)
return;
}
int index = std::distance(m_enabledUnits.begin(), it);
auto index = std::distance(m_enabledUnits.begin(), it);
if (index != m_activeIndex) {
m_activeIndex = index;
m_activeIndex = static_cast<quint32>(index);
emit selectionChanged(m_activeIndex);
}
}
@ -331,16 +341,28 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
return {u, value * 100};
} else if (unit == Units::MetersMSL) {
return {u, value * SG_METER_TO_FEET};
} else if ((unit == Units::FeetAGL) || (unit == Units::FeetAboveFieldElevation)) {
return {u, value};
}
break;
}
case Units::FeetAboveFieldElevation:
case Units::FeetAGL:
// treat as FeetMSL
return {u, convertToUnit(Units::FeetMSL).value};
case Units::MetersMSL:
return {u, convertToUnit(Units::FeetMSL).value * SG_FEET_TO_METER};
case Units::Mach:
{
if (unit == Units::Knots) {
// obviously this depends on altitude, let's
// use the value at sea level for now
return {u, value / 667.0};
} else if (unit == Units::KilometersPerHour) {
return convertToUnit(Units::Knots).convertToUnit(u);
}
break;
}
@ -351,10 +373,20 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
// obviously this depends on altitude, let's
// use the value at sea level for now
return {u, value * 667.0};
} else if (unit == Units::KilometersPerHour) {
return {u, value * SG_KMH_TO_MPS * SG_MPS_TO_KT};
}
break;
}
case Units::KilometersPerHour:
if (unit == Units::Knots) {
return {u, value * SG_KT_TO_MPS * SG_MPS_TO_KMH};
} else {
// round-trip via Knots
return convertToUnit(Units::Knots).convertToUnit(u);
}
case Units::DegreesMagnetic:
case Units::DegreesTrue:
{
@ -367,15 +399,11 @@ QuantityValue QuantityValue::convertToUnit(Units::Type u) const
}
case Units::FlightLevel:
{
if (unit == Units::FeetMSL) {
return {u, static_cast<double>(static_cast<int>(value / 100))};
} else {
return convertToUnit(Units::FeetMSL).convertToUnit(u);
}
if (unit == Units::MetersMSL) {
return {u, static_cast<double>(static_cast<int>(value * SG_METER_TO_FEET / 100))};
}
break;
}
default:
qWarning() << Q_FUNC_INFO << "unhandled case:" << u << "from" << unit;

View file

@ -45,10 +45,12 @@ public:
NoUnits = 0,
FeetMSL,
FeetAGL,
FeetAboveFieldElevation,
FlightLevel,
MetersMSL,
Knots,
Mach,
KilometersPerHour,
DegreesTrue,
DegreesMagnetic,
TimeUTC,
@ -64,11 +66,12 @@ public:
Altitude = 0, // MSL, FlightLevel
AltitudeIncludingAGL,
AltitudeIncludingMeters,
Speed, // Mach or knots
SpeedOnlyKnots = 4,
Speed, // Mach or knots or KM/H
SpeedWithoutMach = 4,
Heading, // degrees true or magnetic
Timezone,
Distance = 7 // Nm only for now
Distance = 7, // Nm or Kilometers only for now
AltitudeIncludingMetersAndAboveField,
};
Q_ENUMS(Mode)
@ -150,7 +153,7 @@ public:
int selectedIndex() const
{
return m_activeIndex;
return static_cast<int>(m_activeIndex);
}
double minValue() const;
@ -165,6 +168,8 @@ public:
QString shortText() const;
Units::Type selectedUnit() const;
int numChoices() const;
Q_INVOKABLE bool isUnitInMode(int unit) const;
public slots:
void setMode(Units::Mode mode);
@ -178,7 +183,7 @@ signals:
private:
Units::Mode m_mode = Units::Altitude;
int m_activeIndex = 0;
quint32 m_activeIndex = 0;
UnitVec m_enabledUnits;
};

View file

@ -221,7 +221,7 @@ Item {
NumericalEdit {
id: airspeedSpinbox
label: qsTr("Airspeed:")
unitsMode: Units.SpeedOnlyKnots
unitsMode: Units.SpeedWithoutMach
enabled: _location.speedEnabled && onFinalBox.enableOnFinal
quantity: _location.airspeed
onCommit: _location.airspeed = newValue

View file

@ -8,6 +8,7 @@ Row {
height: childrenRect.height
spacing: Style.margin
property bool enabled: true
property alias unitsMode: edit.unitsMode
ToggleSwitch {
id: altitudeToggle
@ -23,9 +24,11 @@ Row {
readonly property bool __rowEnabled: root.enabled && _location.altitudeEnabled
NumericalEdit {
id: edit
label: qsTr("Altitude:")
enabled: __rowEnabled
quantity: _location.altitude
onCommit: _location.altitude = newValue
unitsMode: Units.AltitudeIncludingMetersAndAboveField
}
}

View file

@ -120,6 +120,7 @@ Item {
LocationAltitudeRow
{
width: parent.width
unitsMode: Units.AltitudeIncludingMeters
}
// offset row

View file

@ -102,7 +102,10 @@ FocusScope {
}
Component.onCompleted: {
if (quantity.unit === Units.NoUnits) {
// ensure any initial value is accepted by our mode.
// this stops people passing in completely wrong quantities
if (!units.isUnitInMode(quantity.unit)) {
console.warn("NumericalEdit: was inited with incorrect unit");
var q = quantity;
q.unit = units.selectedUnit;
commit(q);
@ -110,8 +113,16 @@ FocusScope {
}
onQuantityChanged: {
// ensure our units model is in sync
units.selectedUnit = quantity.unit
if (units.isUnitInMode(quantity.unit)) {
// ensure our units model is in sync
units.selectedUnit = quantity.unit
} else {
console.warn("Passed illegal quantity");
// reset back to something permitted
var q = quantity;
q.unit = units.selectedUnit;
commit(q);
}
}
TextMetrics {