mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 23:45:35 +08:00
Individual (per object) conversion as well as per unit (class) now possible, this is required for sexagesimal conversion (degrees) and will be required for geo-positions. Further classed for avionics.
This commit is contained in:
66
src/blackmisc/aviobase.h
Normal file
66
src/blackmisc/aviobase.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef AVIOBASE_H
|
||||
#define AVIOBASE_H
|
||||
|
||||
#include "blackmisc/pqconstants.h"
|
||||
|
||||
namespace BlackMisc {
|
||||
|
||||
/*!
|
||||
* \brief Base class for avionics
|
||||
*/
|
||||
class CAvionicsBase
|
||||
{
|
||||
/*!
|
||||
* Stream operator for debugging
|
||||
* \brief operator <<
|
||||
* \param debug
|
||||
* \param avionic
|
||||
* \return
|
||||
* \remarks Has to be in the header files to avoid template link errors
|
||||
*/
|
||||
friend QDebug operator<<(QDebug debug, const CAvionicsBase &avionic) {
|
||||
QString v = avionic.stringForStreamingOperator();
|
||||
debug << v;
|
||||
return debug;
|
||||
}
|
||||
/*!
|
||||
* Stream operator for log messages
|
||||
* \brief operator <<
|
||||
* \param log
|
||||
* \param avionic
|
||||
* \return
|
||||
* \remarks Has to be in the header files to avoid template link errors
|
||||
*/
|
||||
friend CLogMessage operator<<(CLogMessage log, const CAvionicsBase &avionic) {
|
||||
QString v = avionic.stringForStreamingOperator();
|
||||
log << v;
|
||||
return log;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CAvionicsBase() {}
|
||||
/*!
|
||||
* \brief Meaningful string representation
|
||||
* \return
|
||||
*/
|
||||
virtual QString stringForStreamingOperator() const = 0;
|
||||
/*!
|
||||
* \brief Are the set values valid / in range
|
||||
* \return
|
||||
*/
|
||||
virtual bool validValues() { return true; }
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Virtual destructor
|
||||
*/
|
||||
virtual ~CAvionicsBase() {}
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // AVIOBASE_H
|
||||
146
src/blackmisc/aviocomsystem.h
Normal file
146
src/blackmisc/aviocomsystem.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef AVIOCOMUNIT_H
|
||||
#define AVIOCOMUNIT_H
|
||||
#include "blackmisc/aviomodulator.h"
|
||||
|
||||
namespace BlackMisc {
|
||||
|
||||
/*!
|
||||
* \brief COM system (aka "radio")
|
||||
*/
|
||||
class CComSystem : public CModulator<CComSystem>
|
||||
{
|
||||
private:
|
||||
/*!
|
||||
* \brief Valid civil aviation frequency?
|
||||
* \param f
|
||||
* \return
|
||||
*/
|
||||
bool isValidCivilAviationFrequency(CFrequency f) { double fr = f.valueRounded(CFrequencyUnit::MHz(), this->m_digits); return fr >= 118.0 && fr <= 136.975; }
|
||||
/*!
|
||||
* \brief Valid military aviation frequency?
|
||||
* \param f
|
||||
* \return
|
||||
*/
|
||||
bool isValidMilitaryFrequency(CFrequency f) { double fr = f.valueRounded(CFrequencyUnit::MHz(), this->m_digits); return fr >= 220.0 && fr <= 399.95; }
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
CComSystem() : CModulator() {}
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param otherUnit
|
||||
*/
|
||||
CComSystem(const CComSystem &otherUnit) : CModulator(otherUnit) {}
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param name
|
||||
* \param activeFrequency
|
||||
* \param standbyFrequency
|
||||
* \param digits
|
||||
*/
|
||||
CComSystem(const QString &name, const CFrequency &activeFrequency, const CFrequency &standbyFrequency, int digits =3):
|
||||
CModulator(name, activeFrequency, standbyFrequency, digits) {}
|
||||
/*!
|
||||
* \brief Set active frequency
|
||||
* \param frequencyMHz
|
||||
*/
|
||||
void setFrequencyActiveMHz(double frequencyMHz) { CModulator::setFrequencyActiveMHz(frequencyMHz); }
|
||||
/*!
|
||||
* \brief Set standby frequency
|
||||
* \param frequencyMHz
|
||||
*/
|
||||
void setFrequencyStandbyMHz(double frequencyMHz) { CModulator::setFrequencyStandbyMHz(frequencyMHz); }
|
||||
/*!
|
||||
* \brief Set UNICOM frequency as active
|
||||
*/
|
||||
void setActiveUnicom() { this->toggleActiveStandby(); this->setFrequencyActive(CPhysicalQuantitiesConstants::FrequencyUnicom());}
|
||||
/*!
|
||||
* \brief Set International Air Distress 121.5MHz
|
||||
*/
|
||||
void setActiveInternationalAirDistress() { this->toggleActiveStandby(); this->setFrequencyActive(CPhysicalQuantitiesConstants::FrequencyInternationalAirDistress());}
|
||||
/*!
|
||||
* \brief Assigment operator =
|
||||
* \param otherSystem
|
||||
* \return
|
||||
*/
|
||||
CComSystem& operator =(const CComSystem &otherSystem) { CModulator::operator =(otherSystem); return (*this); }
|
||||
/*!
|
||||
* \brief operator ==
|
||||
* \param otherSystem
|
||||
* \return
|
||||
*/
|
||||
bool operator ==(const CComSystem &otherSystem) const { return CModulator::operator ==(otherSystem); }
|
||||
/*!
|
||||
* \brief operator ==
|
||||
* \param otherSystem
|
||||
* \return
|
||||
*/
|
||||
bool operator !=(const CComSystem &otherSystem) const { return CModulator::operator !=(otherSystem); }
|
||||
|
||||
/*!
|
||||
* \brief Are the set values valid / in range?
|
||||
* \return
|
||||
*/
|
||||
virtual bool validValues() {
|
||||
return
|
||||
this->isValidCivilAviationFrequency(this->getFrequencyActive()) &&
|
||||
this->isValidMilitaryFrequency(this->getFrequencyActive()) &&
|
||||
this->isValidCivilAviationFrequency(this->getFrequencyStandby()) &&
|
||||
this->isValidMilitaryFrequency(this->getFrequencyStandby());
|
||||
}
|
||||
/*!
|
||||
* \brief COM1 unit
|
||||
* \param activeFrequencyMHz
|
||||
* \param standbyFrequencyMHz
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom1Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
|
||||
return CComSystem(CModulator::NameCom1(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
|
||||
/*!
|
||||
* \brief COM1 unit
|
||||
* \param activeFrequency
|
||||
* \param standbyFrequency
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom1Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
|
||||
return CComSystem(CModulator::NameCom1(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
|
||||
/*!
|
||||
* \brief COM2 unit
|
||||
* \param activeFrequencyMHz
|
||||
* \param standbyFrequencyMHz
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom2Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
|
||||
return CComSystem(CModulator::NameCom2(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
|
||||
/*!
|
||||
* \brief COM2 unit
|
||||
* \param activeFrequency
|
||||
* \param standbyFrequency
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom2Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
|
||||
return CComSystem(CModulator::NameCom2(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
|
||||
/*!
|
||||
* \brief COM3 unit
|
||||
* \param activeFrequencyMHz
|
||||
* \param standbyFrequencyMHz
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom3Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
|
||||
return CComSystem(CModulator::NameCom3(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
|
||||
/*!
|
||||
* \brief COM3 unit
|
||||
* \param activeFrequency
|
||||
* \param standbyFrequency
|
||||
* \return
|
||||
*/
|
||||
static CComSystem getCom3Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
|
||||
return CComSystem(CModulator::NameCom3(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // AVIOCOMUNIT_H
|
||||
64
src/blackmisc/aviomodulator.cpp
Normal file
64
src/blackmisc/aviomodulator.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "blackmisc/aviomodulator.h"
|
||||
#include "blackmisc/aviocomsystem.h"
|
||||
|
||||
namespace BlackMisc {
|
||||
|
||||
/**
|
||||
* Toggle standby <-> active
|
||||
*/
|
||||
template <class AVIO> void CModulator<AVIO>::toggleActiveStandby()
|
||||
{
|
||||
CFrequency a = this->m_frequencyActive;
|
||||
this->m_frequencyActive = this->m_frequencyStandby;
|
||||
this->m_frequencyStandby = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation
|
||||
*/
|
||||
template <class AVIO> QString CModulator<AVIO>::stringForStreamingOperator() const
|
||||
{
|
||||
QString s(this->m_name);
|
||||
s.append(" Active: ").append(this->m_frequencyActive.unitValueRoundedWithUnit(3));
|
||||
s.append(" Standby: ").append(this->m_frequencyStandby.unitValueRoundedWithUnit(3));
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigment operator =
|
||||
*/
|
||||
template <class AVIO> CModulator<AVIO>& CModulator<AVIO>::operator=(const CModulator<AVIO> &otherModulator) {
|
||||
|
||||
if (this == &otherModulator) return *this; // Same object?
|
||||
this->m_frequencyActive = otherModulator.m_frequencyActive;
|
||||
this->m_frequencyStandby = otherModulator.m_frequencyStandby;
|
||||
this->m_name = otherModulator.m_name;
|
||||
this->m_digits = otherModulator.m_digits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal operator ==
|
||||
*/
|
||||
template <class AVIO> bool CModulator<AVIO>::operator ==(const CModulator<AVIO> &otherModulator) const
|
||||
{
|
||||
if(this == &otherModulator) return true;
|
||||
return (this->m_name == otherModulator.m_name &&
|
||||
this->m_frequencyActive == otherModulator.m_frequencyActive &&
|
||||
this->m_frequencyStandby == otherModulator.m_frequencyStandby);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal operator !=
|
||||
*/
|
||||
template <class AVIO> bool CModulator<AVIO>::operator !=(const CModulator<AVIO> &otherModulator) const
|
||||
{
|
||||
return !(otherModulator == (*this));
|
||||
}
|
||||
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CModulator<CComSystem>;
|
||||
|
||||
} // namespace
|
||||
167
src/blackmisc/aviomodulator.h
Normal file
167
src/blackmisc/aviomodulator.h
Normal file
@@ -0,0 +1,167 @@
|
||||
#ifndef AVIOMODULATORUNIT_H
|
||||
#define AVIOMODULATORUNIT_H
|
||||
#include "blackmisc/aviobase.h"
|
||||
|
||||
namespace BlackMisc {
|
||||
|
||||
/*!
|
||||
* \brief Base class for COM, NAV, Squawk units.
|
||||
*/
|
||||
template <class AVIO> class CModulator : public CAvionicsBase
|
||||
{
|
||||
private:
|
||||
CFrequency m_frequencyActive; //!< active frequency
|
||||
CFrequency m_frequencyStandby; //!< standby frequency
|
||||
QString m_name; //!< name of the unit
|
||||
|
||||
protected:
|
||||
int m_digits; //!< digits used
|
||||
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CModulator() {}
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param otherUnit
|
||||
*/
|
||||
CModulator(const CModulator &otherUnit) :
|
||||
m_frequencyActive(otherUnit.m_frequencyActive), m_frequencyStandby(otherUnit.m_frequencyStandby),
|
||||
m_name(otherUnit.m_name), m_digits(otherUnit.m_digits) {}
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param name
|
||||
* \param activeFrequency
|
||||
* \param standbyFrequency
|
||||
*/
|
||||
CModulator(const QString &name, const CFrequency &activeFrequency, const CFrequency &standbyFrequency, int digits) :
|
||||
m_name(name), m_frequencyActive(activeFrequency),
|
||||
m_digits(digits), m_frequencyStandby(standbyFrequency) {}
|
||||
/*!
|
||||
* \brief Meaningful string representation
|
||||
* \return
|
||||
*/
|
||||
virtual QString stringForStreamingOperator() const;
|
||||
/*!
|
||||
* \brief Set active frequency
|
||||
* \param frequencyKHz
|
||||
*/
|
||||
void setFrequencyActiveKHz(double frequencyKHz) { this->m_frequencyActive = CFrequency(frequencyKHz, CFrequencyUnit::kHz()); }
|
||||
/*!
|
||||
* \brief Set standby frequency
|
||||
* \param frequencyKHz
|
||||
*/
|
||||
void setFrequencyStandbyKHz(double frequencyKHz) { this->m_frequencyStandby = CFrequency(frequencyKHz, CFrequencyUnit::kHz()); }
|
||||
/*!
|
||||
* \brief Set active frequency
|
||||
* \param frequencyMHz
|
||||
*/
|
||||
void setFrequencyActiveMHz(double frequencyMHz) { this->m_frequencyActive = CFrequency(frequencyMHz, CFrequencyUnit::MHz()); }
|
||||
/*!
|
||||
* \brief Set standby frequency
|
||||
* \param frequencyMHz
|
||||
*/
|
||||
void setFrequencyStandbyMHz(double frequencyMHz) { this->m_frequencyStandby = CFrequency(frequencyMHz, CFrequencyUnit::MHz()); }
|
||||
/*!
|
||||
* \brief Assigment operator =
|
||||
* \param otherModulator
|
||||
* \return
|
||||
*/
|
||||
CModulator& operator =(const CModulator &otherModulator);
|
||||
/*!
|
||||
* \brief operator ==
|
||||
* \param otherModulator
|
||||
* \return
|
||||
*/
|
||||
bool operator ==(const CModulator &otherModulator) const;
|
||||
/*!
|
||||
* \brief operator !=
|
||||
* \param otherModulator
|
||||
* \return
|
||||
*/
|
||||
bool operator !=(const CModulator &otherModulator) const;
|
||||
/*!
|
||||
* \brief COM1
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameCom1() { static QString n("COM1"); return n; }
|
||||
/*!
|
||||
* \brief COM2
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameCom2() { static QString n("COM2"); return n; }
|
||||
/*!
|
||||
* \brief COM3
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameCom3() { static QString n("COM3"); return n; }
|
||||
/*!
|
||||
* \brief NAV1
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameNav1() { static QString n("NAV1"); return n; }
|
||||
/*!
|
||||
* \brief NAV2
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameNav2() { static QString n("NAV2"); return n; }
|
||||
/*!
|
||||
* \brief NAV2
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameNav3() { static QString n("NAV2"); return n; }
|
||||
/*!
|
||||
* \brief ADF1
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameAdf1() { static QString n("ADF1"); return n; }
|
||||
/*!
|
||||
* \brief ADF2
|
||||
* \return
|
||||
*/
|
||||
static const QString& NameAdf2() { static QString n("ADF2"); return n; }
|
||||
/*!
|
||||
* \brief Frequency not set
|
||||
* \return
|
||||
*/
|
||||
static const CFrequency& FrequencyNotSet() { static CFrequency f; return f; }
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
*/
|
||||
virtual ~CModulator() {}
|
||||
/*!
|
||||
* \brief Toggle active and standby frequencies
|
||||
*/
|
||||
void toggleActiveStandby();
|
||||
/*!
|
||||
* \brief Name
|
||||
* \return
|
||||
*/
|
||||
QString getName() const { return this->m_name; }
|
||||
/*!
|
||||
* \brief Active frequency
|
||||
* \return
|
||||
*/
|
||||
CFrequency getFrequencyActive() const { return this->m_frequencyActive; }
|
||||
/*!
|
||||
* \brief Standby frequency
|
||||
* \return
|
||||
*/
|
||||
CFrequency getFrequencyStandby() const { return this->m_frequencyActive; }
|
||||
/*!
|
||||
* \brief Set active frequency
|
||||
* \param frequency
|
||||
*/
|
||||
void setFrequencyActive(const CFrequency &frequency) { this->m_frequencyActive = frequency; }
|
||||
/*!
|
||||
* \brief Set standby frequency
|
||||
* \param frequency
|
||||
*/
|
||||
void setFrequencyStandby(const CFrequency &frequency) { this->m_frequencyStandby = frequency; }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // AVIOMODULATORUNIT_H
|
||||
12
src/blackmisc/avionbase.cpp
Normal file
12
src/blackmisc/avionbase.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "aviobase.h"
|
||||
|
||||
namespace BlackMisc {
|
||||
|
||||
/**
|
||||
* Defaultc
|
||||
*/
|
||||
CAvionicsBase::CAvionicsBase()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -52,7 +52,10 @@ HEADERS += \
|
||||
avheading.h \
|
||||
avtrack.h \
|
||||
avaltitude.h \
|
||||
avverticalpositions.h
|
||||
avverticalpositions.h \
|
||||
aviobase.h \
|
||||
aviomodulator.h \
|
||||
aviocomsystem.h
|
||||
|
||||
SOURCES += \
|
||||
logmessage.cpp \
|
||||
@@ -79,6 +82,7 @@ SOURCES += \
|
||||
avheading.cpp \
|
||||
avtrack.cpp \
|
||||
avaltitude.cpp \
|
||||
avverticalpositions.cpp
|
||||
avverticalpositions.cpp \
|
||||
aviomodulator.cpp
|
||||
|
||||
DESTDIR = ../../lib
|
||||
|
||||
@@ -94,9 +94,12 @@ CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier)
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon):
|
||||
m_name(name), m_unitName(unitName), m_type(type), m_isSIUnit(isSIUnit), m_isSIBaseUnit(isSIBaseUnit),m_displayDigits(displayDigits),m_conversionFactorToSIConversionUnit(conversionFactorToSI),
|
||||
m_epsilon(epsilon), m_multiplier(multiplier)
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit,
|
||||
double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon,
|
||||
UnitConverter toSiConverter, UnitConverter fromSiConverter):
|
||||
m_name(name), m_unitName(unitName), m_type(type), m_isSiUnit(isSIUnit), m_isSiBaseUnit(isSIBaseUnit), m_displayDigits(displayDigits),
|
||||
m_conversionFactorToSIConversionUnit(conversionFactorToSI),
|
||||
m_epsilon(epsilon), m_multiplier(multiplier), m_fromSiConverter(fromSiConverter), m_toSiConverter(toSiConverter)
|
||||
{
|
||||
// void
|
||||
}
|
||||
@@ -105,9 +108,9 @@ CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName,
|
||||
* Copy constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &otherUnit):
|
||||
m_name(otherUnit.m_name), m_unitName(otherUnit.m_unitName), m_type(otherUnit.m_type), m_isSIUnit(otherUnit.m_isSIUnit),
|
||||
m_isSIBaseUnit(otherUnit.m_isSIBaseUnit), m_displayDigits(otherUnit.m_displayDigits),m_conversionFactorToSIConversionUnit(otherUnit.m_conversionFactorToSIConversionUnit),
|
||||
m_epsilon(otherUnit.m_epsilon), m_multiplier(otherUnit.m_multiplier)
|
||||
m_name(otherUnit.m_name), m_unitName(otherUnit.m_unitName), m_type(otherUnit.m_type), m_isSiUnit(otherUnit.m_isSiUnit),
|
||||
m_isSiBaseUnit(otherUnit.m_isSiBaseUnit), m_displayDigits(otherUnit.m_displayDigits),m_conversionFactorToSIConversionUnit(otherUnit.m_conversionFactorToSIConversionUnit),
|
||||
m_epsilon(otherUnit.m_epsilon), m_multiplier(otherUnit.m_multiplier), m_fromSiConverter(otherUnit.m_fromSiConverter), m_toSiConverter(otherUnit.m_toSiConverter)
|
||||
{
|
||||
// void
|
||||
}
|
||||
@@ -121,12 +124,14 @@ CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &otherUnit
|
||||
this->m_name = otherUnit.m_name;
|
||||
this->m_unitName =otherUnit.m_unitName;
|
||||
this->m_type=otherUnit.m_type;
|
||||
this->m_isSIUnit =otherUnit.m_isSIUnit;
|
||||
this->m_isSIBaseUnit =otherUnit.m_isSIBaseUnit;
|
||||
this->m_isSiUnit =otherUnit.m_isSiUnit;
|
||||
this->m_isSiBaseUnit =otherUnit.m_isSiBaseUnit;
|
||||
this->m_conversionFactorToSIConversionUnit=otherUnit.m_conversionFactorToSIConversionUnit;
|
||||
this->m_multiplier = otherUnit.m_multiplier;
|
||||
this->m_displayDigits=otherUnit.m_displayDigits;
|
||||
this->m_epsilon= otherUnit.m_epsilon;
|
||||
this->m_fromSiConverter = otherUnit.m_fromSiConverter;
|
||||
this->m_toSiConverter = otherUnit.m_toSiConverter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -138,7 +143,7 @@ bool CMeasurementUnit::operator ==(const CMeasurementUnit &otherUnit) const
|
||||
if ( this == &otherUnit ) return true;
|
||||
if ( this->m_type != otherUnit.m_type) return false;
|
||||
return this->m_multiplier == otherUnit.m_multiplier && this->m_name == otherUnit.m_name
|
||||
&& this->m_isSIUnit==otherUnit.m_isSIUnit;
|
||||
&& this->m_isSiUnit==otherUnit.m_isSiUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -162,6 +162,7 @@ public:
|
||||
* Base class for all units, such as meter, hertz.
|
||||
*/
|
||||
class CMeasurementUnit {
|
||||
|
||||
/*!
|
||||
* \brief Stream << overload to be used in debugging messages
|
||||
* \param d
|
||||
@@ -179,18 +180,27 @@ class CMeasurementUnit {
|
||||
*/
|
||||
friend CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Points to a individual converter method
|
||||
*/
|
||||
typedef double(*UnitConverter)(const CMeasurementUnit&, double);
|
||||
|
||||
private:
|
||||
QString m_name; //!< name, e.g. "meter"
|
||||
QString m_unitName; //!< unit name, e.g. "m"
|
||||
QString m_type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons
|
||||
bool m_isSIUnit; //!< is this a SI unit?
|
||||
bool m_isSIBaseUnit; //!< SI base unit?
|
||||
bool m_isSiUnit; //!< is this a SI unit?
|
||||
bool m_isSiBaseUnit; //!< SI base unit?
|
||||
double m_conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature)
|
||||
double m_epsilon; //!< values with differences below epsilon are the equal
|
||||
qint32 m_displayDigits; //!< standard rounding for string conversions
|
||||
CMeasurementPrefix m_multiplier; //!< multiplier (kilo, Mega)
|
||||
UnitConverter m_toSiConverter;
|
||||
UnitConverter m_fromSiConverter;
|
||||
|
||||
protected:
|
||||
|
||||
/*!
|
||||
* Constructor by parameter
|
||||
* \param name
|
||||
@@ -202,7 +212,9 @@ protected:
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
*/
|
||||
CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1, const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2, double epsilon = 1E-10);
|
||||
CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1,
|
||||
const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2,
|
||||
double epsilon = 1E-10, UnitConverter toSiConverter = nullptr, UnitConverter fromSiConverter = nullptr);
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param otherUnit
|
||||
@@ -220,6 +232,20 @@ protected:
|
||||
* \return
|
||||
*/
|
||||
double getConversionFactorToSI() const { return this->m_conversionFactorToSIConversionUnit; }
|
||||
/*!
|
||||
* Given value to conversion SI conversion unit (e.g. meter, hertz).
|
||||
* Standard implementaion is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double conversionToSiConversionUnit(double value) const { return value * this->m_conversionFactorToSIConversionUnit; }
|
||||
/*!
|
||||
* \brief Value from SI conversion unit to this unit.
|
||||
* Standard implementaion is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double conversionFromSiConversionUnit(double value) const { return value / this->m_conversionFactorToSIConversionUnit; }
|
||||
|
||||
public:
|
||||
/*!
|
||||
@@ -238,17 +264,17 @@ public:
|
||||
* \brief Representing an SI unit? Examples: kilometer, meter, hertz
|
||||
* \return
|
||||
*/
|
||||
bool isSiUnit() const { return this->m_isSIUnit;}
|
||||
bool isSiUnit() const { return this->m_isSiUnit;}
|
||||
/*!
|
||||
* \brief Representing an base SI unit? Examples: second, meter
|
||||
* \return
|
||||
*/
|
||||
bool isSiBaseUnit() const { return this->m_isSIUnit;}
|
||||
bool isSiBaseUnit() const { return this->m_isSiUnit;}
|
||||
/*!
|
||||
* \brief Representing an SI base unit? Example: meter
|
||||
* \return
|
||||
*/
|
||||
bool isUnprefixedSiUnit() const { return this->m_isSIUnit && this->m_multiplier.getFactor() == 1; }
|
||||
bool isUnprefixedSiUnit() const { return this->m_isSiUnit && this->m_multiplier.getFactor() == 1; }
|
||||
/*!
|
||||
* \brief Name such as "meter"
|
||||
* \return
|
||||
@@ -264,20 +290,21 @@ public:
|
||||
* \return
|
||||
*/
|
||||
QString getType() const { return this->m_type; }
|
||||
|
||||
/*!
|
||||
* Given value to conversion SI conversion unit (e.g. meter, hertz).
|
||||
* Standard implementaion is simply factor based.
|
||||
* Standard implementation is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double convertToSiConversionUnit(double value) const { return value * this->m_conversionFactorToSIConversionUnit; }
|
||||
double convertToSiConversionUnit(double value) const { return (this->m_toSiConverter) ? this->m_toSiConverter((*this), value) : this->conversionToSiConversionUnit(value); }
|
||||
/*!
|
||||
* \brief Value from SI conversion unit to this unit.
|
||||
* Standard implementaion is simply factor based.
|
||||
* Value from SI conversion unit to this unit.
|
||||
* Standard implementation is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double convertFromSiConversionUnit(double value) const { return value / this->m_conversionFactorToSIConversionUnit; }
|
||||
double convertFromSiConversionUnit(double value) const { return (this->m_fromSiConverter) ? this->m_fromSiConverter((*this), value) : this->conversionFromSiConversionUnit(value); }
|
||||
/*!
|
||||
* Rounded string utility method, virtual so units can have
|
||||
* specialized formatting
|
||||
|
||||
@@ -39,6 +39,21 @@ public:
|
||||
* \return
|
||||
*/
|
||||
static const CLength& Length0ft() { static CLength l(0, CLengthUnit::ft()); return l;}
|
||||
/*!
|
||||
* \brief Unicom frequency
|
||||
* \return
|
||||
*/
|
||||
static const CFrequency& FrequencyUnicom() { static CFrequency f(122.8, CFrequencyUnit::MHz()); return f;}
|
||||
/*!
|
||||
* \brief Civil aircraft emergency frequency
|
||||
* \return
|
||||
*/
|
||||
static const CFrequency& FrequencyInternationalAirDistress() { static CFrequency f(121.5, CFrequencyUnit::MHz()); return f;}
|
||||
/*!
|
||||
* \brief Military aircraft emergency frequency
|
||||
* \return
|
||||
*/
|
||||
static const CFrequency& FrequencyMilitaryAirDistress() { static CFrequency f(243.0, CFrequencyUnit::MHz()); return f;}
|
||||
};
|
||||
} // namespace
|
||||
#endif // PQCONSTANTS_H
|
||||
|
||||
@@ -364,7 +364,7 @@ template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::convertedSiValueT
|
||||
}
|
||||
|
||||
|
||||
// see here for the reason of this forward instants
|
||||
// see here for the reason of thess forward instantiations
|
||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||
template class CPhysicalQuantity<CLengthUnit, CLength>;
|
||||
template class CPhysicalQuantity<CPressureUnit, CPressure>;
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace BlackMisc {
|
||||
/**
|
||||
* Convert to SI
|
||||
*/
|
||||
double CTemperatureUnit::convertToSiConversionUnit(double value) const
|
||||
double CTemperatureUnit::conversionToSiConversionUnit(double value) const
|
||||
{
|
||||
double v = value + this->m_conversionOffsetToSi;
|
||||
v *= this->getConversionFactorToSI();
|
||||
@@ -15,7 +15,7 @@ double CTemperatureUnit::convertToSiConversionUnit(double value) const
|
||||
/**
|
||||
* Convert from SI
|
||||
*/
|
||||
double CTemperatureUnit::convertFromSiConversionUnit(double value) const
|
||||
double CTemperatureUnit::conversionFromSiConversionUnit(double value) const
|
||||
{
|
||||
double v = value / this->getConversionFactorToSI();
|
||||
v -= this->m_conversionOffsetToSi;
|
||||
@@ -25,49 +25,34 @@ double CTemperatureUnit::convertFromSiConversionUnit(double value) const
|
||||
/**
|
||||
* Convert from SI
|
||||
*/
|
||||
double CAngleUnit::convertFromSiConversionUnit(double value) const
|
||||
double CAngleUnit::conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit, double value)
|
||||
{
|
||||
double v;
|
||||
// still a design flaw since I have to distinguish as per type
|
||||
// but an own converter per object was really too much
|
||||
if ((*this) == CAngleUnit::sexagesimalDeg()) {
|
||||
// using rounding here, since fractions can lead to ugly sexagesimal conversion
|
||||
// e.g. 185.499999 gives 185 29' 59.9999"
|
||||
value = this->epsilonRounding(value * 180 / M_PI); // degree
|
||||
v = floor(value);
|
||||
double c = value - v;
|
||||
double mr = c * 60.0;
|
||||
double m = floor(mr); // minutes
|
||||
double s = (mr-m) * 60; // seconds + rest fraction
|
||||
v = (v + (m/100) + (s/10000));
|
||||
} else {
|
||||
v = CMeasurementUnit::convertFromSiConversionUnit(value);
|
||||
}
|
||||
// using rounding here, since fractions can lead to ugly sexagesimal conversion
|
||||
// e.g. 185.499999 gives 185 29' 59.9999"
|
||||
value = angleUnit.epsilonRounding(value * 180 / M_PI); // degree
|
||||
double v = floor(value);
|
||||
double c = value - v;
|
||||
double mr = c * 60.0;
|
||||
double m = floor(mr); // minutes
|
||||
double s = (mr-m) * 60; // seconds + rest fraction
|
||||
v = (v + (m/100) + (s/10000));
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to SI
|
||||
*/
|
||||
double CAngleUnit::convertToSiConversionUnit(double value) const
|
||||
double CAngleUnit::conversionSexagesimalToSi(const CMeasurementUnit &, double value)
|
||||
{
|
||||
// still a design flaw since I have to distinguish as per type
|
||||
// but an own converter per object was really too much
|
||||
double v;
|
||||
if ((*this) == CAngleUnit::sexagesimalDeg()) {
|
||||
double v = floor(value); // degrees
|
||||
double c = value - v;
|
||||
c = c * 100.0;
|
||||
double m = floor(c);
|
||||
c = c - m;
|
||||
m /= 60.0; // minutes back to decimals
|
||||
double s = c / 36.0; // seconds back to decimals
|
||||
v = v + m + s;
|
||||
return v / 180.0 * M_PI;
|
||||
} else {
|
||||
v = CMeasurementUnit::convertToSiConversionUnit(value);
|
||||
}
|
||||
return v;
|
||||
double v = floor(value); // degrees
|
||||
double c = value - v;
|
||||
c = c * 100.0;
|
||||
double m = floor(c);
|
||||
c = c - m;
|
||||
m /= 60.0; // minutes back to decimals
|
||||
double s = c / 36.0; // seconds back to decimals
|
||||
v = v + m + s;
|
||||
return v / 180.0 * M_PI;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,4 +75,4 @@ QString CAngleUnit::toQStringRounded(double value, int digits) const
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
/*!
|
||||
* Specialized class for angles (degrees, radian).
|
||||
* \author KWB
|
||||
* \author KWB, MS
|
||||
*/
|
||||
class CAngleUnit : public CMeasurementUnit {
|
||||
private:
|
||||
@@ -79,29 +79,33 @@ private:
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
*/
|
||||
CAngleUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
|
||||
CMeasurementUnit(name, unitName, "angle", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon)
|
||||
CAngleUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0,
|
||||
const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2,
|
||||
double epsilon = 1E-9, UnitConverter converterToSi = nullptr, UnitConverter converterFromSi= nullptr) :
|
||||
CMeasurementUnit(name, unitName, "angle", isSIUnit, false, conversionFactorToSI,
|
||||
mulitplier, displayDigits, epsilon, converterToSi, converterFromSi)
|
||||
{
|
||||
// void
|
||||
}
|
||||
/*!
|
||||
* \brief Special conversion for sexagesimal degrees
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
static double conversionSexagesimalToSi(const CMeasurementUnit &angleUnit, double value);
|
||||
/*!
|
||||
* \brief Special conversion for sexagesimal degrees
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
static double conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit, double value);
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param otherUnit
|
||||
*/
|
||||
CAngleUnit(const CAngleUnit &otherUnit) : CMeasurementUnit(otherUnit) { }
|
||||
/*!
|
||||
* \brief Convert to SI conversion unit, specific for angle
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CAngleUnit::convertToSiConversionUnit(double value) const;
|
||||
/*!
|
||||
* \brief Convert from SI conversion unit, specific for angle
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CAngleUnit::convertFromSiConversionUnit(double value) const;
|
||||
/*!
|
||||
* \brief Special conversion to QString for sexagesimal degrees.
|
||||
* \param value
|
||||
@@ -123,12 +127,13 @@ public:
|
||||
* \brief Sexagesimal degree (degree, minute, seconds)
|
||||
* \return
|
||||
*/
|
||||
static const CAngleUnit& sexagesimalDeg() { static CAngleUnit deg("segadecimal degree", "°", false, M_PI/180); return deg;}
|
||||
static const CAngleUnit& sexagesimalDeg() { static CAngleUnit deg("segadecimal degree", "°", false, M_PI/180,
|
||||
CMeasurementPrefix::One(),0, 1E-9, CAngleUnit::conversionSexagesimalToSi, CAngleUnit::conversionSexagesimalFromSi); return deg;}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Specialized class for frequency (hertz, mega hertz, kilo hertz).
|
||||
* \author KWB
|
||||
* \author KWB, MS
|
||||
*/
|
||||
class CFrequencyUnit : public CMeasurementUnit {
|
||||
private:
|
||||
@@ -159,22 +164,22 @@ public:
|
||||
* \brief Kilohertz
|
||||
* \return
|
||||
*/
|
||||
static const CFrequencyUnit& kHz() { static CFrequencyUnit kHz("kilohertz", "kHz", true, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 0);return kHz;}
|
||||
static const CFrequencyUnit& kHz() { static CFrequencyUnit kHz("kilohertz", "kHz", true, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 1);return kHz;}
|
||||
/*!
|
||||
* \brief Megahertz
|
||||
* \return
|
||||
*/
|
||||
static const CFrequencyUnit& MHz() { static CFrequencyUnit MHz("megahertz", "MHz", false, CMeasurementPrefix::M().getFactor(), CMeasurementPrefix::M(), 0); return MHz;}
|
||||
static const CFrequencyUnit& MHz() { static CFrequencyUnit MHz("megahertz", "MHz", false, CMeasurementPrefix::M().getFactor(), CMeasurementPrefix::M(), 2); return MHz;}
|
||||
/*!
|
||||
* \brief Gigahertz
|
||||
* \return
|
||||
*/
|
||||
static const CFrequencyUnit& GHz() { static CFrequencyUnit GHz("gigahertz", "GHz", true, CMeasurementPrefix::G().getFactor(), CMeasurementPrefix::G(), 0);return GHz;}
|
||||
static const CFrequencyUnit& GHz() { static CFrequencyUnit GHz("gigahertz", "GHz", true, CMeasurementPrefix::G().getFactor(), CMeasurementPrefix::G(), 2);return GHz;}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Specialized class for mass units (kg, lbs).
|
||||
* \author KWB
|
||||
* \author KWB, MS
|
||||
*/
|
||||
class CMassUnit : public CMeasurementUnit {
|
||||
private:
|
||||
@@ -220,7 +225,7 @@ public:
|
||||
|
||||
/*!
|
||||
* Specialized class for pressure (psi, hPa, bar).
|
||||
* \author KWB
|
||||
* \author KWB, MS
|
||||
*/
|
||||
class CPressureUnit : public CMeasurementUnit {
|
||||
private:
|
||||
@@ -238,6 +243,10 @@ private:
|
||||
CPressureUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
|
||||
CMeasurementUnit(name, unitName, "frequency", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon) {}
|
||||
public:
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param otherUnit
|
||||
*/
|
||||
CPressureUnit(const CPressureUnit &otherUnit) : CMeasurementUnit(otherUnit)
|
||||
{
|
||||
// void
|
||||
@@ -301,6 +310,19 @@ private:
|
||||
*/
|
||||
CTemperatureUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, double temperatureOffsetToSI=0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
|
||||
CMeasurementUnit(name, unitName, "temperature", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon), m_conversionOffsetToSi(temperatureOffsetToSI) {}
|
||||
protected:
|
||||
/*!
|
||||
* \brief Convert to SI conversion unit, specific for temperature
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CTemperatureUnit::conversionToSiConversionUnit(double value) const;
|
||||
/*!
|
||||
* \brief Convert from SI conversion unit, specific for temperature
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CTemperatureUnit::conversionFromSiConversionUnit(double value) const;
|
||||
public:
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
@@ -317,18 +339,6 @@ public:
|
||||
this->m_conversionOffsetToSi = otherUnit.m_conversionOffsetToSi;
|
||||
return (*this);
|
||||
}
|
||||
/*!
|
||||
* \brief Convert to SI conversion unit, specific for temperature
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CTemperatureUnit::convertToSiConversionUnit(double value) const;
|
||||
/*!
|
||||
* \brief Convert from SI conversion unit, specific for temperature
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double CTemperatureUnit::convertFromSiConversionUnit(double value) const;
|
||||
/*!
|
||||
* \brief Kelvin
|
||||
* \return
|
||||
@@ -344,7 +354,6 @@ public:
|
||||
* \return
|
||||
*/
|
||||
static const CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0, 459.67);return F;}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user