36namespace etsi_its_mcm_uulm_msgs::access {
49inline void setItsPduHeader(MCM& mcm,
const uint32_t station_id,
const uint8_t protocol_version = 2) {
50 mcm.header.message_id.value = MessageId::MCM;
51 mcm.header.station_id.value = station_id;
52 throwIfOutOfRange(protocol_version, OrdinalNumber1B::MIN, OrdinalNumber1B::MAX,
"ProtocolVersion");
53 mcm.header.protocol_version.value = protocol_version;
64 MCM& mcm,
const uint64_t unix_nanosecs,
66 uint64_t t_its = unix_nanosecs * 1e-6 + (uint64_t)(n_leap_seconds * 1e3) - etsi_its_msgs::UNIX_SECONDS_2004 * 1e3;
67 uint16_t gdt_value = t_its % 65536;
68 throwIfOutOfRange(gdt_value, GenerationDeltaTime::MIN, GenerationDeltaTime::MAX,
"GenerationDeltaTime");
69 mcm.mcm.generation_delta_time.value = gdt_value;
81 throwIfOutOfRange(value, TrafficParticipantType::MIN, TrafficParticipantType::MAX,
"StationType");
82 mcm.mcm.mcm_parameters.basic_container.station_type.value = value;
91inline void setLatitude(Latitude& latitude,
const double deg) {
92 int64_t angle_in_10_micro_degree = (int64_t)std::round(deg * 1e7);
93 throwIfOutOfRange(angle_in_10_micro_degree, Latitude::MIN, Latitude::MAX,
"Latitude");
94 latitude.value = angle_in_10_micro_degree;
104 int64_t angle_in_10_micro_degree = (int64_t)std::round(deg * 1e7);
105 throwIfOutOfRange(angle_in_10_micro_degree, Longitude::MIN, Longitude::MAX,
"Longitude");
106 longitude.value = angle_in_10_micro_degree;
116 int64_t alt_in_cm = (int64_t)std::round(value * 1e2);
117 if (alt_in_cm >= AltitudeValue::MIN && alt_in_cm <= AltitudeValue::MAX) {
118 altitude.value = alt_in_cm;
119 }
else if (alt_in_cm < AltitudeValue::MIN) {
120 altitude.value = AltitudeValue::MIN;
121 }
else if (alt_in_cm > AltitudeValue::MAX) {
122 altitude.value = AltitudeValue::MAX;
133 altitude.altitude_confidence.value = AltitudeConfidence::UNAVAILABLE;
149 const double altitude = AltitudeValue::UNAVAILABLE) {
150 setLatitude(mcm.mcm.mcm_parameters.basic_container.reference_position.latitude, latitude);
151 setLongitude(mcm.mcm.mcm_parameters.basic_container.reference_position.longitude, longitude);
152 if (altitude != AltitudeValue::UNAVAILABLE) {
153 setAltitude(mcm.mcm.mcm_parameters.basic_container.reference_position.altitude, altitude);
155 mcm.mcm.mcm_parameters.basic_container.reference_position.altitude.altitude_value.value =
156 AltitudeValue::UNAVAILABLE;
157 mcm.mcm.mcm_parameters.basic_container.reference_position.altitude.altitude_confidence.value =
158 AltitudeConfidence::UNAVAILABLE;
162 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_major_axis_length.value =
163 SemiAxisLength::UNAVAILABLE;
164 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_minor_axis_length.value =
165 SemiAxisLength::UNAVAILABLE;
166 mcm.mcm.mcm_parameters.basic_container.reference_position.position_confidence_ellipse.semi_major_axis_orientation
167 .value = Wgs84AngleValue::UNAVAILABLE;
182inline void setFromUTMPosition(MCM& mcm,
const gm::PointStamped& utm_position,
const int zone,
const bool northp) {
183 std::string required_frame_prefix =
"utm_";
184 if (utm_position.header.frame_id.rfind(required_frame_prefix, 0) != 0) {
185 throw std::invalid_argument(
"Frame-ID of UTM Position '" + utm_position.header.frame_id +
186 "' does not start with required prefix '" + required_frame_prefix +
"'!");
188 double latitude, longitude;
190 GeographicLib::UTMUPS::Reverse(zone, northp, utm_position.point.x, utm_position.point.y, latitude, longitude);
191 }
catch (GeographicLib::GeographicErr& e) {
192 throw std::invalid_argument(e.what());
206 auto speed_val = std::round(value * 1e2);
208 speed.value =
static_cast<decltype(speed.value)
>(speed_val);
220 int64_t deg = (int64_t)std::round(value * 1e1);
236 int64_t dim_value = (int64_t)std::round(value * 1e1);
237 throwIfOutOfRange(dim_value, T::MIN, T::MAX,
"RoadUserDimension (Width/Length)");
238 dim.value = dim_value;
254inline void setRoadUserState(RoadUserContainer& road_user_container,
const uint8_t type,
const double speed,
255 const double heading,
const double length,
const double width) {
256 road_user_container.road_user_state.road_user_type.value = type;
257 setSpeedValue(road_user_container.road_user_state.speed, speed);
273 auto coord_value = std::round(value * 1e2);
274 if (coord_value < CartesianCoordinateLarge::MIN) {
275 coord_value = CartesianCoordinateLarge::NEGATIVE_OUT_OF_RANGE;
276 }
else if (coord_value > CartesianCoordinateLarge::MAX) {
277 coord_value = CartesianCoordinateLarge::POSITIVE_OUT_OF_RANGE;
279 coordinate.value =
static_cast<decltype(coordinate.value)
>(coord_value);
289inline 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.