etsi_its_messages v3.1.0
 
Loading...
Searching...
No Matches
spatem_ts_utils.h
Go to the documentation of this file.
1/*
2=============================================================================
3MIT License
4
5Copyright (c) 2023-2025 Institute for Automotive Engineering (ika), RWTH Aachen University
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24=============================================================================
25*/
26
31
32#include <ctime>
33
34#pragma once
35
36namespace etsi_its_spatem_ts_msgs {
37
38namespace access {
39
40 const std::array<float, 4> color_grey {0.5, 0.5, 0.5, 1.0};
41 const std::array<float, 4> color_green {0.18, 0.79, 0.21, 1.0};
42 const std::array<float, 4> color_orange {0.9, 0.7, 0.09, 1.0};
43 const std::array<float, 4> color_red {0.8, 0.2, 0.2, 1.0};
44
45 enum time_mark_value_interpretation { normal, undefined, over_an_hour, leap_second };
46
53 inline uint64_t getUnixSecondsOfYear(const uint64_t unixSecond) {
54
55 // Get current time as a time_point
56 time_t ts = static_cast<time_t>(unixSecond); // Convert uint64_t to time_t
57
58 struct tm* timeinfo;
59 timeinfo = gmtime(&ts);
60
61 // Set the timeinfo to the beginning of the year
62 timeinfo->tm_sec = 0;
63 timeinfo->tm_min = 0;
64 timeinfo->tm_hour = 0;
65 timeinfo->tm_mday = 1;
66 timeinfo->tm_mon = 0;
67
68 return timegm(timeinfo); // Convert struct tm back to Unix timestamp
69 }
70
78 inline uint64_t getUnixNanosecondsFromMinuteOfTheYear(const MinuteOfTheYear& moy, const uint64_t unix_nanoseconds_estimate) {
79 return ((uint64_t)(moy.value*60) + getUnixSecondsOfYear(unix_nanoseconds_estimate*1e-9))*1e9;
80 }
81
88 inline float interpretTimeIntervalConfidenceAsFloat(const uint16_t encoded_probability) {
89 float probability = 0;
90
91 switch (encoded_probability)
92 {
93 case 0:
94 probability = 0.21;
95 break;
96 case 1:
97 probability = 0.36;
98 break;
99 case 2:
100 probability = 0.47;
101 break;
102 case 3:
103 probability = 0.56;
104 break;
105 case 4:
106 probability = 0.62;
107 break;
108 case 5:
109 probability = 0.68;
110 break;
111 case 6:
112 probability = 0.73;
113 break;
114 case 7:
115 probability = 0.77;
116 break;
117 case 8:
118 probability = 0.81;
119 break;
120 case 9:
121 probability = 0.85;
122 break;
123 case 10:
124 probability = 0.88;
125 break;
126 case 11:
127 probability = 0.91;
128 break;
129 case 12:
130 probability = 0.94;
131 break;
132 case 13:
133 probability = 0.96;
134 break;
135 case 14:
136 probability = 0.98;
137 break;
138 case 15:
139 probability = 1.0;
140 break;
141 }
142
143 return probability;
144 }
145
152 inline std::array<float, 4> interpretMovementPhaseStateAsColor(const uint8_t value)
153 {
154 std::array<float, 4> color;
155
156 switch (value) {
157
158 case MovementPhaseState::UNAVAILABLE:
159 color = color_grey;
160 break;
161
162 case MovementPhaseState::DARK:
163 color = color_grey;
164 break;
165 case MovementPhaseState::STOP_THEN_PROCEED:
166 color = color_red;
167 break;
168 case MovementPhaseState::STOP_AND_REMAIN:
169 color = color_red;
170 break;
171 case MovementPhaseState::PRE_MOVEMENT:
172 color = color_orange;
173 break;
174 case MovementPhaseState::PERMISSIVE_MOVEMENT_ALLOWED:
175 color = color_green;
176 break;
177 case MovementPhaseState::PROTECTED_MOVEMENT_ALLOWED:
178 color = color_green;
179 break;
180 case MovementPhaseState::PERMISSIVE_CLEARANCE:
181 color = color_orange;
182 break;
183 case MovementPhaseState::PROTECTED_CLEARANCE:
184 color = color_orange;
185 break;
186 case MovementPhaseState::CAUTION_CONFLICTING_TRAFFIC:
187 color = color_orange;
188 break;
189 default:
190 color = color_grey;
191 break;
192 }
193
194 return color;
195}
196
203time_mark_value_interpretation interpretTimeMarkValueType(const uint16_t time) {
204 time_mark_value_interpretation type;
205
206 if (time == 36001) {
207 // value is undefined or unknown
208 type = time_mark_value_interpretation::undefined;
209 } else if (time == 36000) {
210 // used to indicate time >3600 seconds
211 type = time_mark_value_interpretation::over_an_hour;
212 } else if (time >= 35991 && time <= 35999) {
213 // leap second
214 type = time_mark_value_interpretation::leap_second;
215 } else { // time >= 0 && time <= 36000
216 type = time_mark_value_interpretation::normal;
217 }
218
219 return type;
220}
221
230float interpretTimeMarkValueAsSeconds(const uint16_t time, const int32_t seconds, const uint32_t nanosec) {
231 // calculate elapsed seconds since the start of the last full hour
232 float abs_time_hour = ((int)(seconds)) % 3600 + (float)nanosec * 1e-9;
233 float rel_time_until_change = (float)time * 0.1f - abs_time_hour;
234
235 return rel_time_until_change;
236}
237
246std::string parseTimeMarkValueToString(const uint16_t time, const int32_t seconds, const uint32_t nanosec)
247{
248 time_mark_value_interpretation time_type = interpretTimeMarkValueType(time);
249
250 std::string text_content;
251
252 switch (time_type) {
253 case time_mark_value_interpretation::undefined:
254 text_content = "undefined";
255 break;
256 case time_mark_value_interpretation::over_an_hour:
257 text_content = ">36000s";
258 break;
259 case time_mark_value_interpretation::leap_second:
260 text_content = "leap second";
261 break;
262 case time_mark_value_interpretation::normal:
263 float rel_time_until_change = interpretTimeMarkValueAsSeconds(time, seconds, nanosec);
264
265 // set displayed precision to 0.1
266 std::stringstream ss;
267 ss << std::fixed << std::setprecision(1) << rel_time_until_change << "s";
268 text_content = ss.str();
269 break;
270 }
271
272 return text_content;
273}
274
275
276} // namespace etsi_its_spatem_ts_msgs
277} // namespace access
uint64_t getUnixSecondsOfYear(const uint64_t unixSecond)
Get the unix seconds of the beginning of a year that corresponds to a given unix timestamp.
std::array< float, 4 > interpretMovementPhaseStateAsColor(const uint8_t value)
Interprets the MovementPhaseState type as a color (see etsi definition)
uint64_t getUnixNanosecondsFromMinuteOfTheYear(const MinuteOfTheYear &moy, const uint64_t unix_nanoseconds_estimate)
Get the unix nanoseconds from MinuteOfTheYear object.
float interpretTimeMarkValueAsSeconds(const uint16_t time, const int32_t seconds, const uint32_t nanosec)
Calculate the amount of seconds until the given time is reached.
time_mark_value_interpretation interpretTimeMarkValueType(const uint16_t time)
Interprets the type of a TimeMark message See etsi ASNI1 - IS TS 103 301 documentation for for the en...
std::string parseTimeMarkValueToString(const uint16_t time, const int32_t seconds, const uint32_t nanosec)
Converts a value from message type TimeMarkValue into a string representation.
float interpretTimeIntervalConfidenceAsFloat(const uint16_t encoded_probability)
Interprets the TimeIntervalConfidence type as a float value (see etsi definition)