etsi_its_messages v3.4.0
Loading...
Searching...
No Matches
mcm_setters.h
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Copyright Institute for Automotive Engineering (ika), RWTH Aachen University
3
8
9#pragma once
10
12
13namespace etsi_its_mcm_uulm_msgs::access {
14
15// ---------- header ----------
16
26inline void setItsPduHeader(MCM& mcm, const uint32_t station_id, const uint8_t protocol_version = 2) {
27 mcm.header.message_id.value = MessageId::MCM;
28 mcm.header.station_id.value = station_id;
29 throwIfOutOfRange(protocol_version, OrdinalNumber1B::MIN, OrdinalNumber1B::MAX, "ProtocolVersion");
30 mcm.header.protocol_version.value = protocol_version;
31}
32
41 MCM& mcm, const uint64_t unix_nanosecs,
42 const uint16_t n_leap_seconds = etsi_its_msgs::LEAP_SECOND_INSERTIONS_SINCE_2004.rbegin()->second) {
43 uint64_t t_its = unix_nanosecs * 1e-6 + (uint64_t)(n_leap_seconds * 1e3) - etsi_its_msgs::UNIX_SECONDS_2004 * 1e3;
44 uint16_t gdt_value = t_its % 65536;
45 throwIfOutOfRange(gdt_value, GenerationDeltaTime::MIN, GenerationDeltaTime::MAX, "GenerationDeltaTime");
46 mcm.mcm.generation_delta_time.value = gdt_value;
47}
48
49// ---------- basic_container ----------
50
57inline void setStationType(MCM& mcm, const int value) {
58 throwIfOutOfRange(value, TrafficParticipantType::MIN, TrafficParticipantType::MAX, "StationType");
59 mcm.mcm.mcm_parameters.basic_container.station_type.value = value;
60}
61
68inline void setLatitude(Latitude& latitude, const double deg) {
69 int64_t angle_in_10_micro_degree = (int64_t)std::round(deg * 1e7);
70 throwIfOutOfRange(angle_in_10_micro_degree, Latitude::MIN, Latitude::MAX, "Latitude");
71 latitude.value = angle_in_10_micro_degree;
72}
73
80inline void setLongitude(Longitude& longitude, const double deg) {
81 int64_t angle_in_10_micro_degree = (int64_t)std::round(deg * 1e7);
82 throwIfOutOfRange(angle_in_10_micro_degree, Longitude::MIN, Longitude::MAX, "Longitude");
83 longitude.value = angle_in_10_micro_degree;
84}
85
92inline void setAltitudeValue(AltitudeValue& altitude, const double value) {
93 int64_t alt_in_cm = (int64_t)std::round(value * 1e2);
94 if (alt_in_cm >= AltitudeValue::MIN && alt_in_cm <= AltitudeValue::MAX) {
95 altitude.value = alt_in_cm;
96 } else if (alt_in_cm < AltitudeValue::MIN) {
97 altitude.value = AltitudeValue::MIN;
98 } else if (alt_in_cm > AltitudeValue::MAX) {
99 altitude.value = AltitudeValue::MAX;
100 }
101}
102
109inline void setAltitude(Altitude& altitude, const double value) {
110 altitude.altitude_confidence.value = AltitudeConfidence::UNAVAILABLE;
111 setAltitudeValue(altitude.altitude_value, value);
112}
113
125inline void setReferencePosition(MCM& mcm, const double latitude, const double longitude,
126 const double altitude = AltitudeValue::UNAVAILABLE) {
127 setLatitude(mcm.mcm.mcm_parameters.basic_container.reference_position.latitude, latitude);
128 setLongitude(mcm.mcm.mcm_parameters.basic_container.reference_position.longitude, longitude);
129 if (altitude != AltitudeValue::UNAVAILABLE) {
130 setAltitude(mcm.mcm.mcm_parameters.basic_container.reference_position.altitude, altitude);
131 } else {
132 mcm.mcm.mcm_parameters.basic_container.reference_position.altitude.altitude_value.value =
133 AltitudeValue::UNAVAILABLE;
134 mcm.mcm.mcm_parameters.basic_container.reference_position.altitude.altitude_confidence.value =
135 AltitudeConfidence::UNAVAILABLE;
136 }
137
138 // reset PositionConfidenceEllipse to unavailable
139 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_major_axis_length.value =
140 SemiAxisLength::UNAVAILABLE;
141 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_minor_axis_length.value =
142 SemiAxisLength::UNAVAILABLE;
143 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_major_axis_orientation
144 .value = Wgs84AngleValue::UNAVAILABLE;
145}
146
159inline void setFromUTMPosition(MCM& mcm, const gm::PointStamped& utm_position, const int zone, const bool northp) {
160 std::string required_frame_prefix = "utm_";
161 if (utm_position.header.frame_id.rfind(required_frame_prefix, 0) != 0) {
162 throw std::invalid_argument("Frame-ID of UTM Position '" + utm_position.header.frame_id +
163 "' does not start with required prefix '" + required_frame_prefix + "'!");
164 }
165 double latitude, longitude;
166 try {
167 GeographicLib::UTMUPS::Reverse(zone, northp, utm_position.point.x, utm_position.point.y, latitude, longitude);
168 } catch (GeographicLib::GeographicErr& e) {
169 throw std::invalid_argument(e.what());
170 }
171 setReferencePosition(mcm, latitude, longitude, utm_position.point.z);
172}
173
174// ---------- road_user_container ----------
175
182inline void setSpeedValue(SpeedValue& speed, const double value) {
183 auto speed_val = std::round(value * 1e2);
184 throwIfOutOfRange(speed_val, SpeedValue::MIN, SpeedValue::MAX, "SpeedValue");
185 speed.value = static_cast<decltype(speed.value)>(speed_val);
186}
187
196inline void setHeadingValue(HeadingValue& heading, const double value) {
197 int64_t deg = (int64_t)std::round(value * 1e1);
198 throwIfOutOfRange(deg, HeadingValue::MIN, HeadingValue::MAX, "HeadingValue");
199 heading.value = deg;
200}
201
211template <typename T>
212inline void setRoadUserDimension(T& dim, const double value) {
213 int64_t dim_value = (int64_t)std::round(value * 1e1);
214 throwIfOutOfRange(dim_value, T::MIN, T::MAX, "RoadUserDimension (Width/Length)");
215 dim.value = dim_value;
216}
217
231inline void setRoadUserState(RoadUserContainer& road_user_container, const uint8_t type, const double speed,
232 const double heading, const double length, const double width) {
233 road_user_container.road_user_state.road_user_type.value = type;
234 setSpeedValue(road_user_container.road_user_state.speed, speed);
235 setHeadingValue(road_user_container.road_user_state.heading, heading);
236 setRoadUserDimension(road_user_container.road_user_state.length, length);
237 setRoadUserDimension(road_user_container.road_user_state.width, width);
238}
239
249inline void setCartesianCoordinateLarge(CartesianCoordinateLarge& coordinate, const double value) {
250 auto coord_value = std::round(value * 1e2); // convert m to cm
251 if (coord_value < CartesianCoordinateLarge::MIN) {
252 coord_value = CartesianCoordinateLarge::NEGATIVE_OUT_OF_RANGE;
253 } else if (coord_value > CartesianCoordinateLarge::MAX) {
254 coord_value = CartesianCoordinateLarge::POSITIVE_OUT_OF_RANGE;
255 }
256 coordinate.value = static_cast<decltype(coordinate.value)>(coord_value);
257}
258
266inline void setWaypoint(Waypoint& waypoint, const double x, const double y) {
267 setCartesianCoordinateLarge(waypoint.x_distance, x);
268 setCartesianCoordinateLarge(waypoint.y_distance, y);
269}
270
271} // namespace etsi_its_mcm_uulm_msgs::access
Sanity-check functions etc.
void throwIfOutOfRange(const T1 &val, const T2 &min, const T2 &max, const std::string val_desc)
Throws an exception if a given value is out of a defined range.
Definition mcm_access.h:24
const std::map< uint64_t, uint16_t > LEAP_SECOND_INSERTIONS_SINCE_2004
std::map that stores all leap second insertions since 2004 with the corresponding unix-date of the in...
Definition mcm_access.h:23
void setFromUTMPosition(MCM &mcm, const gm::PointStamped &utm_position, const int zone, const bool northp)
Set the ReferencePosition of a MCM from a given UTM-Position.
void setGenerationDeltaTime(MCM &mcm, const uint64_t unix_nanosecs, const uint16_t n_leap_seconds=etsi_its_msgs::LEAP_SECOND_INSERTIONS_SINCE_2004.rbegin() ->second)
Set the Generation Delta Time object.
Definition mcm_setters.h:40
void setAltitude(Altitude &altitude, const double value)
Set the Altitude object.
void setLatitude(Latitude &latitude, const double deg)
Set the Latitude object.
Definition mcm_setters.h:68
void setRoadUserState(RoadUserContainer &road_user_container, const uint8_t type, const double speed, const double heading, const double length, const double width)
Sets the state of a road user in the given container.
void setHeadingValue(HeadingValue &heading, const double value)
Set the HeadingValue object.
void setSpeedValue(SpeedValue &speed, const double value)
Set the SpeedValue object.
void setReferencePosition(MCM &mcm, const double latitude, const double longitude, const double altitude=AltitudeValue::UNAVAILABLE)
Set the ReferencePosition for an MCM.
void setWaypoint(Waypoint &waypoint, const double x, const double y)
Sets the coordinates of a Waypoint object.
void setLongitude(Longitude &longitude, const double deg)
Set the Longitude object.
Definition mcm_setters.h:80
void setAltitudeValue(AltitudeValue &altitude, const double value)
Set the AltitudeValue object.
Definition mcm_setters.h:92
void setRoadUserDimension(T &dim, const double value)
Sets the dimension value for a road user (width or length).
void setCartesianCoordinateLarge(CartesianCoordinateLarge &coordinate, const double value)
Sets the value of a CartesianCoordinateLarge object.
void setItsPduHeader(MCM &mcm, const uint32_t station_id, const uint8_t protocol_version=2)
Sets the ITS PDU header for the given MCM message.
Definition mcm_setters.h:26
void setStationType(MCM &mcm, const int value)
Set the StationType for a MCM.
Definition mcm_setters.h:57