From 319e5b2952a5f03f7a71295f1a4a230632200105 Mon Sep 17 00:00:00 2001 From: Sven Czarnian Date: Mon, 22 Nov 2021 16:18:16 +0100 Subject: [PATCH] build the geographic coordinates --- include/aman/types/Quantity.hpp | 406 ++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 10 +- 2 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 include/aman/types/Quantity.hpp diff --git a/include/aman/types/Quantity.hpp b/include/aman/types/Quantity.hpp new file mode 100644 index 0000000..05a8906 --- /dev/null +++ b/include/aman/types/Quantity.hpp @@ -0,0 +1,406 @@ +/* + * @brief Defines and implements classes to define physical SI units + * @file types/Quantity.hpp + * @author Sven Czarnian + * @copyright Copyright 2020-2021 Sven Czarnian + * @license This project is published under the GNU General Public License v3 (GPLv3) + */ + +#pragma once + +#include +#include + +#include + +namespace aman { + /** + * @brief Defines the base class to define different physical SI units + * @ingroup types + * + * The template arguments are used to define the exponent of the SI unit. + * These Quantity definitions are the base to describe all physical relations. + * + * By use of this implementation is it possible to ensure, that the SI units + * are as expected after the calculations. + * + * This avoids logical errors and it is useful to avoid the auto-keyword otherwise + * is it not possible to check the correctness of the SI units. + * + * @tparam M The exponent of the mass parts + * @tparam L The exponent of the length parts + * @tparam T The exponent of the time parts + * @tparam A The exponent of the angular parts + */ + template + class Quantity { + private: + float m_value; + + public: + /** + * @brief Initializes a quantity with the default value + */ + constexpr Quantity() noexcept : m_value(0.0f) { } + /** + * @brief Initializes the quantity with a given value + * @param[in] value The set value + */ + explicit constexpr Quantity(float value) : m_value(value) { } + + /** + * @brief Adds rhs into this instance and returns the updated instance + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + constexpr Quantity const& operator+=(const Quantity& rhs) { + this->m_value += rhs.m_value; + return *this; + } + /** + * @brief Substracts rhs into this instance and returns the updated instance + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + constexpr Quantity const& operator-=(const Quantity& rhs) { + this->m_value -= rhs.m_value; + return *this; + } + + /** + * @brief Returns the value in SI units + * @return The contained value + */ + constexpr float value() const { + return this->m_value; + } + /** + * @brief Sets the value in SI units + * @param[in] value The new SI unit based value + */ + constexpr void setValue(float value) { + this->m_value = value; + } + /** + * @brief Converts the value into a specific unit + * @param[in] rhs The scaling factor to convert the value + * @return The converted value + */ + constexpr float convert(const Quantity& rhs) const { + return this->m_value / rhs.m_value; + } + /** + * @brief Calculates the square-root and updates the SI units as well + * @return The resulting instance with updated template arguments + */ + constexpr Quantity>, std::ratio_divide>, + std::ratio_divide>, std::ratio_divide>> sqrt() const { + return Quantity>, std::ratio_divide>, + std::ratio_divide>, std::ratio_divide>>(std::sqrtf(this->m_value)); + } + /** + * @brief Calculates the absolute of the contained value and returns it as a new Quantity instance + * @return The absolute value instance + */ + constexpr Quantity abs() const { + return Quantity(std::abs(this->m_value)); + } + }; + + /** The mass specialization [kg] */ + typedef Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>> Mass; + /** The length specialization [m] */ + typedef Quantity, std::ratio<1>, std::ratio<0>, std::ratio<0>> Length; + /** The time specialization [s] */ + typedef Quantity, std::ratio<0>, std::ratio<1>, std::ratio<0>> Time; + /** The angle specialization [rad] */ + typedef Quantity, std::ratio<0>, std::ratio<0>, std::ratio<1>> Angle; + /** The velocity specialization [m/s] */ + typedef Quantity, std::ratio<1>, std::ratio<-1>, std::ratio<0>> Velocity; + /** The acceleration specialization [m/(s*s)] */ + typedef Quantity, std::ratio<1>, std::ratio<-2>, std::ratio<0>> Acceleration; + /** The angular velocity specialization [1/s] */ + typedef Quantity, std::ratio<0>, std::ratio<-1>, std::ratio<1>> AngularVelocity; + /** The angular acceleration specialization [1/(s*s)] */ + typedef Quantity, std::ratio<0>, std::ratio<-2>, std::ratio<1>> AngularAcceleration; + + /** + * @brief Adds rhs to lhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity operator+(const Quantity& lhs, const Quantity& rhs) { + return Quantity(lhs.value() + rhs.value()); + } + /** + * @brief Substracts rhs to lhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity operator-(const Quantity& lhs, const Quantity& rhs) { + return Quantity(lhs.value() - rhs.value()); + } + /** + * @brief Multiplies rhs to lhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity, std::ratio_add, + std::ratio_add, std::ratio_add> + operator*(const Quantity& lhs, const Quantity& rhs) { + return Quantity, std::ratio_add, + std::ratio_add, std::ratio_add>(lhs.value() * rhs.value()); + } + /** + * @brief Multiplies lhs to rhs and returns a new instance + * @param[in] lhs The SI-unit free factor + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity operator*(const float& lhs, const Quantity& rhs) { + return Quantity(lhs * rhs.value()); + } + /** + * @brief Multiplies rhs to lhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The SI-unit free factor + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity operator*(const Quantity& lhs, const float& rhs) { + return Quantity(lhs.value() * rhs); + } + /** + * @brief Divides rhs from lhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity, std::ratio_subtract, + std::ratio_subtract, std::ratio_subtract> + operator/(const Quantity& lhs, const Quantity& rhs) { + return Quantity, std::ratio_subtract, + std::ratio_subtract, std::ratio_subtract>(lhs.value() / rhs.value()); + } + /** + * @brief Divides rhs from lhs and returns a new instance + * @param[in] lhs The SI-unit free factor + * @param[in] rhs The right-hand-side component + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity, M>, std::ratio_subtract, L>, + std::ratio_subtract, T>, std::ratio_subtract, A>> + operator/(const float& lhs, const Quantity& rhs) { + return Quantity, M>, std::ratio_subtract, L>, + std::ratio_subtract, T>, std::ratio_subtract, A>>(lhs / rhs.value()); + } + /** + * @brief Multiplies lhs from rhs and returns a new instance + * @param[in] lhs The left-hand-side component + * @param[in] rhs The SI-unit free factor + * @return The resulting quantity with the updated value + */ + template + constexpr Quantity operator/(const Quantity& lhs, const float& rhs) { + return Quantity(lhs.value() / rhs); + } + + /** + * @brief Compares if two instance are equal or almost equal + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if the instances are almost equal, else false + */ + template + constexpr bool operator==(const Quantity& lhs, const Quantity& rhs) { + return true == Math::almostEqual(lhs.value(), rhs.value(), 1e-8f); + } + /** + * @brief Compares if two instance are not equal + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if the instances are not equal + */ + template + constexpr bool operator!=(const Quantity& lhs, const Quantity& rhs) { + return false == Math::almostEqual(lhs.value(), rhs.value(), 1e-8f); + } + /** + * @brief Compares if lhs is smaller or equal compared to rhs + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if lhs is smaller or equal compared to rhs + */ + template + constexpr bool operator<=(const Quantity& lhs, const Quantity& rhs) { + return lhs.value() <= rhs.value(); + } + /** + * @brief Compares if lhs is smaller compared to rhs + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if lhs is smaller compared to rhs + */ + template + constexpr bool operator<(const Quantity& lhs, const Quantity& rhs) { + return lhs.value() < rhs.value(); + } + /** + * @brief Compares if lhs is greater or equal compared to rhs + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if lhs is greater or equal compared to rhs + */ + template + constexpr bool operator>=(const Quantity& lhs, const Quantity& rhs) { + return lhs.value() >= rhs.value(); + } + /** + * @brief Compares if lhs is greater compared to rhs + * @param[in] lhs The left-hand-side component + * @param[in] rhs The right-hand-side component + * @return True if lhs is greater compared to rhs + */ + template + constexpr bool operator>(const Quantity& lhs, const Quantity& rhs) { + return lhs.value() > rhs.value(); + } + + /**< Defines a kilogram */ + constexpr Mass kilogram(1.0f); + constexpr Mass pound = 0.453592f * kilogram; + /**< Defines the literal of kilograms */ + constexpr Mass operator"" _kg(long double value) { return Mass(static_cast(value)); } + /**< Defines the literal of kilograms */ + constexpr Mass operator"" _kg(unsigned long long int value) { return Mass(static_cast(value)); } + /**< Defines the literal of pounds */ + constexpr Mass operator"" _lbs(long double value) { return static_cast(value) * pound; } + /**< Defines the literal of pounds */ + constexpr Mass operator"" _lbs(unsigned long long int value) { return static_cast(value) * pound; } + + /**< Defines a metres */ + constexpr Length metre(1.0f); + /**< Defines a feet */ + constexpr Length feet = 0.3048f * metre; + /**< Defines a kilometres */ + constexpr Length kilometre = 1000.0f * metre; + /**< Defines a nautical mile */ + constexpr Length nauticmile = 1852.0f * metre; + /**< Defines the literal of metres */ + constexpr Length operator"" _m(long double value) { return Length(static_cast(value)); } + /**< Defines the literal of metres */ + constexpr Length operator"" _m(unsigned long long int value) { return Length(static_cast(value)); } + /**< Defines the literal of feets */ + constexpr Length operator"" _ft(long double value) { return static_cast(value) * feet; } + /**< Defines the literal of feets */ + constexpr Length operator"" _ft(unsigned long long int value) { return static_cast(value) * feet; } + /**< Defines the literal of kilometres */ + constexpr Length operator"" _km(long double value) { return static_cast(value)* kilometre; } + /**< Defines the literal of kilometres */ + constexpr Length operator"" _km(unsigned long long int value) { return static_cast(value)* kilometre; } + /**< Defines the literal of nautical miles */ + constexpr Length operator"" _nm(long double value) { return static_cast(value)* nauticmile; } + /**< Defines the literal of nautical miles */ + constexpr Length operator"" _nm(unsigned long long int value) { return static_cast(value)* nauticmile; } + + /**< Defines a second */ + constexpr Time second(1.0f); + /**< Defines a millisecond */ + constexpr Time millisecond = second / 1000.0f; + /**< Defines a minute */ + constexpr Time minute = 60.0f * second; + /**< Defines a hour */ + constexpr Time hour = 60.0f * minute; + /**< Defines the literal of milliseconds */ + constexpr Time operator"" _ms(long double value) { return static_cast(value) * millisecond; } + /**< Defines the literal of milliseconds */ + constexpr Time operator"" _ms(unsigned long long int value) { return static_cast(value) * millisecond; } + /**< Defines the literal of seconds */ + constexpr Time operator"" _s(long double value) { return static_cast(value) * second; } + /**< Defines the literal of seconds */ + constexpr Time operator"" _s(unsigned long long int value) { return static_cast(value) * second; } + /**< Defines the literal of minutes */ + constexpr Time operator"" _min(long double value) { return static_cast(value) * minute; } + /**< Defines the literal of minutes */ + constexpr Time operator"" _min(unsigned long long int value) { return static_cast(value) * minute; } + /**< Defines the literal of hours */ + constexpr Time operator"" _h(long double value) { return static_cast(value) * hour; } + /**< Defines the literal of hours */ + constexpr Time operator"" _h(unsigned long long int value) { return static_cast(value) * hour; } + + /**< Defines the literal of PI */ + constexpr float operator"" _pi(long double value) { return static_cast(value) * 3.1415926535897932384626433832795f; } + /**< Defines the literal of PI */ + constexpr float operator"" _pi(unsigned long long int value) { return static_cast(value) * 3.1415926535897932384626433832795f; } + /**< Defines a degree */ + constexpr Angle degree = Angle(1.0f); + /**< Defines a radian */ + constexpr Angle radian = 180.0f / 1_pi * degree; + /**< Defines the literal of radians */ + constexpr Angle operator"" _rad(long double value) { return static_cast(value) * radian; } + /**< Defines the literal of radians */ + constexpr Angle operator"" _rad(unsigned long long int value) { return static_cast(value) * radian; } + /**< Defines the literal of degrees */ + constexpr Angle operator"" _deg(long double value) { return static_cast(value) * degree; } + /**< Defines the literal of degrees */ + constexpr Angle operator"" _deg(unsigned long long int value) { return static_cast(value) * degree; } + + /**< Defines a knot */ + constexpr Velocity knot = 0.51444f * metre / second; + /**< Defines the literal of metre per second */ + constexpr Velocity operator"" _mps(long double value) { return Velocity(static_cast(value)); } + /**< Defines the literal of metre per second */ + constexpr Velocity operator"" _mps(unsigned long long int value) { return Velocity(static_cast(value)); } + /**< Defines the literal of feet per minute */ + constexpr Velocity operator"" _ftpmin(long double value) { return static_cast(value) * feet / minute; } + /**< Defines the literal of feet per minute */ + constexpr Velocity operator"" _ftpmin(unsigned long long int value) { return static_cast(value) * feet / minute; } + /**< Defines the literal of kilometre per hour */ + constexpr Velocity operator"" _kmph(long double value) { return static_cast(value) * kilometre / hour; } + /**< Defines the literal of kilometre per hour */ + constexpr Velocity operator"" _kmph(unsigned long long int value) { return static_cast(value) * kilometre / hour; } + /**< Defines the literal of knots */ + constexpr Velocity operator"" _kn(long double value) { return static_cast(value) * knot; } + /**< Defines the literal of knots */ + constexpr Velocity operator"" _kn(unsigned long long int value) { return static_cast(value) * knot; } + + /**< Defines the gravity */ + constexpr Acceleration G = 9.80665f * metre / (second* second); + /**< Defines the literal of metre per square-second */ + constexpr Acceleration operator"" _mps2(long double value) { return Acceleration(static_cast(value)); } + /**< Defines the literal of metre per square-second */ + constexpr Acceleration operator"" _mps2(unsigned long long int value) { return Acceleration(static_cast(value)); } + /**< Defines the literal of gravities */ + constexpr Acceleration operator"" _g(long double value) { return static_cast(value) * G; } + /**< Defines the literal of gravities */ + constexpr Acceleration operator"" _g(unsigned long long int value) { return static_cast(value) * G; } + + /**< Defines the literal of radian per second */ + constexpr AngularVelocity operator"" _radps(long double value) { return AngularVelocity(static_cast(value)); } + /**< Defines the literal of radian per second */ + constexpr AngularVelocity operator"" _radps(unsigned long long int value) { return AngularVelocity(static_cast(value)); } + /**< Defines the literal of degree per second */ + constexpr AngularVelocity operator"" _degps(long double value) { return static_cast(value) * degree / second; } + /**< Defines the literal of degree per second */ + constexpr AngularVelocity operator"" _degps(unsigned long long int value) { return static_cast(value) * degree / second; } + + /**< Defines the literal of radian per square-second */ + constexpr AngularAcceleration operator"" _radps2(long double value) { return AngularAcceleration(static_cast(value)); } + /**< Defines the literal of radian per square-second */ + constexpr AngularAcceleration operator"" _radps2(unsigned long long int value) { return AngularAcceleration(static_cast(value)); } + /**< Defines the literal of degree per square-second */ + constexpr AngularAcceleration operator"" _degps2(long double value) { return static_cast(value) * degree / (second * second); } + /**< Defines the literal of degree per square-second */ + constexpr AngularAcceleration operator"" _degps2(unsigned long long int value) { return static_cast(value) * degree / (second * second); } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c9962da..7a3e0a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,10 @@ SET(SOURCE_CONFIG_FILES config/IdentifierFileFormat.cpp ) +SET(SOURCE_TYPES_FILES + types/GeoCoordinate.cpp +) + SET(SOURCE_FILES_RES ${CMAKE_BINARY_DIR}/ArrivalMANager.rc ${CMAKE_SOURCE_DIR}/res/resource.h @@ -69,6 +73,8 @@ SET(INCLUDE_HELPER_FILES SET(INCLUDE_TYPES_FILES ${CMAKE_SOURCE_DIR}/include/aman/types/Communication.h + ${CMAKE_SOURCE_DIR}/include/aman/types/GeoCoordinate.h + ${CMAKE_SOURCE_DIR}/include/aman/types/Quantity.hpp ) # define the plug in @@ -77,6 +83,7 @@ ADD_LIBRARY( ${SOURCE_FILES_RES} ${SOURCE_COM_FILES} ${SOURCE_CONFIG_FILES} + ${SOURCE_TYPES_FILES} ${SOURCE_FILES} ${PROTO_SOURCE_FILES} ${PROTO_FILES} @@ -89,7 +96,7 @@ ADD_LIBRARY( # define the dependencies TARGET_INCLUDE_DIRECTORIES(ArrivalMANager INTERFACE EuroScope) TARGET_LINK_LIBRARIES(ArrivalMANager EuroScope libcurl GSL Shlwapi) -TARGET_LINK_LIBRARIES(ArrivalMANager cppzmq protobuf jsoncpp) +TARGET_LINK_LIBRARIES(ArrivalMANager cppzmq protobuf jsoncpp GeographicLib) # configure the debugger and update the linker flags IF(MSVC) @@ -109,6 +116,7 @@ SOURCE_GROUP("Protocol Files" FILES ${PROTO_FILES}) SOURCE_GROUP("Source Files" FILES ${SOURCE_FILES}) SOURCE_GROUP("Source Files\\com" FILES ${SOURCE_COM_FILES}) SOURCE_GROUP("Source Files\\config" FILES ${SOURCE_CONFIG_FILES}) +SOURCE_GROUP("Source Files\\types" FILES ${SOURCE_TYPES_FILES}) SOURCE_GROUP("Source Files\\res" FILES ${SOURCE_FILES_RES}) SOURCE_GROUP("Header Files\\com" FILES ${INCLUDE_COM_FILES}) SOURCE_GROUP("Header Files\\config" FILES ${INCLUDE_CONFIG_FILES})