ifw-fcf 8.0.2
 
Loading...
Searching...
No Matches
unitConversion.hpp
Go to the documentation of this file.
1
7
8#ifndef FCF_DEVMGR_COMMON_UNIT_CONVERSION_HPP_
9#define FCF_DEVMGR_COMMON_UNIT_CONVERSION_HPP_
10
11
12#include <iostream>
13#include <stdexcept>
14#include <string>
15#include <string_view>
16#include <vector>
17#include <type_traits>
18#include <unordered_map>
19#include <variant>
20
21#include <ifw/fnd/defs/iCommAdapter.hpp>
22
23
24// Utility function to convert device values to SI units
25
27{
28 enum class QuantityKind
29 {
34 };
35
36 struct SIValue
37 {
38 double value;
40 };
41
42template<typename T>
43struct is_std_vector : std::false_type {};
44
45template<typename T, typename Alloc>
46struct is_std_vector<std::vector<T, Alloc>> : std::true_type {};
47
48template<typename T>
49inline constexpr bool is_std_vector_v = is_std_vector<std::decay_t<T>>::value;
50
51// Convert an ifw-fnd Value (a std::variant) to a double. Throws on
52// non-numeric variants (vectors, strings, monostate). Same semantics
53// as the old core::protocol::base::Variant version — just a different
54// concrete std::variant flavour.
55inline double variant_to_double(const ifw::fnd::defs::Value& value)
56{
57 return std::visit(
58 [](const auto& v) -> double
59 {
60 using T = std::decay_t<decltype(v)>;
61
62 if constexpr (std::is_same_v<T, std::monostate>)
63 {
64 throw std::invalid_argument("Cannot convert empty variant to double");
65 }
66 else if constexpr (std::is_arithmetic_v<T>)
67 {
68 return static_cast<double>(v);
69 }
70 else if constexpr (is_std_vector_v<T>)
71 {
72 throw std::invalid_argument("Cannot convert vector variant to double");
73 }
74 else if constexpr (std::is_same_v<T, std::string>)
75 {
76 throw std::invalid_argument("Cannot convert string variant to double");
77 }
78 else
79 {
80 // PropertyMap and any other non-numeric alternative.
81 throw std::invalid_argument(
82 "Cannot convert non-numeric variant alternative to double");
83 }
84 },
85 value);
86}
87
88 struct UnitInfo
89 {
90 double factor;
92 };
93
94 // lookup table for units
95 inline const UnitInfo &lookup_unit(std::string_view unit)
96 {
97 static const std::unordered_map<std::string, UnitInfo> table = {
98 // length -> SI base: meter
99
100 {"", {1.0, QuantityKind::Empty}},
101 {"UNKNOWN", {1.0, QuantityKind::Empty}},
102 {"m", {1.0, QuantityKind::Length}},
103 {"mm", {1e-3, QuantityKind::Length}},
104 {"cm", {1e-2, QuantityKind::Length}},
105 {"dm", {1e-1, QuantityKind::Length}},
106 {"um", {1e-6, QuantityKind::Length}},
107 {"nm", {1e-9, QuantityKind::Length}},
108 {"km", {1e3, QuantityKind::Length}},
109
110 // angle -> SI base: radian
111 {"rad", {1.0, QuantityKind::Angle}},
112 {"mrad", {1e-3, QuantityKind::Angle}},
113 {"urad", {1e-6, QuantityKind::Angle}},
114 {"deg", {3.14159265358979323846 / 180.0, QuantityKind::Angle}},
115 {"degrees", {3.14159265358979323846 / 180.0, QuantityKind::Angle}},
116 {"Degree", {3.14159265358979323846 / 180.0, QuantityKind::Angle}},
117 {"°", {3.14159265358979323846 / 180.0, QuantityKind::Angle}},
118 {"arcmin", {3.14159265358979323846 / 10800.0, QuantityKind::Angle}},
119 {"arcsec", {3.14159265358979323846 / 648000.0, QuantityKind::Angle}},
120
121 // time -> SI base: second
122 {"s", {1.0, QuantityKind::Time}},
123 {"ms", {1e-3, QuantityKind::Time}},
124 {"us", {1e-6, QuantityKind::Time}},
125 {"ns", {1e-9, QuantityKind::Time}},
126 {"min", {60.0, QuantityKind::Time}},
127 {"h", {3600.0, QuantityKind::Time}}};
128
129 auto it = table.find(std::string(unit));
130 if (it == table.end())
131 {
132 throw std::runtime_error("Unknown unit: " + std::string(unit));
133 }
134 return it->second;
135 }
136
137 // Function to convert value to a SI value
138 SIValue to_si(const ifw::fnd::defs::Value &value, std::string_view unit);
139
140 const char *kind_to_string(QuantityKind kind);
141
142 const char *si_unit_name(QuantityKind kind);
143
144} // namespace
145
146#endif // FCF_DEVMGR_COMMON_UNIT_CONVERSION_HPP_
ActionMgr class source file.
Definition actionMgr.cpp:28
const char * si_unit_name(QuantityKind kind)
Definition unitConversion.cpp:36
constexpr bool is_std_vector_v
Definition unitConversion.hpp:49
const char * kind_to_string(QuantityKind kind)
Definition unitConversion.cpp:20
double variant_to_double(const ifw::fnd::defs::Value &value)
Definition unitConversion.hpp:55
SIValue to_si(const ifw::fnd::defs::Value &value, std::string_view unit)
Definition unitConversion.cpp:10
const UnitInfo & lookup_unit(std::string_view unit)
Definition unitConversion.hpp:95
QuantityKind
Definition unitConversion.hpp:29
@ Angle
Definition unitConversion.hpp:31
@ Time
Definition unitConversion.hpp:32
@ Length
Definition unitConversion.hpp:30
@ Empty
Definition unitConversion.hpp:33
Definition unitConversion.hpp:37
QuantityKind kind
Definition unitConversion.hpp:39
double value
Definition unitConversion.hpp:38
Definition unitConversion.hpp:89
double factor
Definition unitConversion.hpp:90
QuantityKind kind
Definition unitConversion.hpp:91
Definition unitConversion.hpp:43