13namespace etsi_its_mcm_uulm_msgs::access {
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;
41 MCM& mcm,
const uint64_t unix_nanosecs,
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;
58 throwIfOutOfRange(value, TrafficParticipantType::MIN, TrafficParticipantType::MAX,
"StationType");
59 mcm.mcm.mcm_parameters.basic_container.station_type.value = value;
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;
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;
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;
110 altitude.altitude_confidence.value = AltitudeConfidence::UNAVAILABLE;
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);
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;
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;
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 +
"'!");
165 double latitude, longitude;
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());
183 auto speed_val = std::round(value * 1e2);
185 speed.value =
static_cast<decltype(speed.value)
>(speed_val);
197 int64_t deg = (int64_t)std::round(value * 1e1);
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;
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);
250 auto coord_value = std::round(value * 1e2);
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;
256 coordinate.value =
static_cast<decltype(coordinate.value)
>(coord_value);
266inline void setWaypoint(Waypoint& waypoint,
const double x,
const double y) {
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.
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...
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.
void setAltitude(Altitude &altitude, const double value)
Set the Altitude object.
void setLatitude(Latitude &latitude, const double deg)
Set the Latitude object.
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.
void setAltitudeValue(AltitudeValue &altitude, const double value)
Set the AltitudeValue object.
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.
void setStationType(MCM &mcm, const int value)
Set the StationType for a MCM.