37namespace etsi_its_cpm_ts_msgs::access {
50inline void setItsPduHeader(CollectivePerceptionMessage& cpm,
const uint32_t station_id,
51 const uint8_t protocol_version = 0) {
52 setItsPduHeader(cpm.header, MessageId::CPM, station_id, protocol_version);
67 CollectivePerceptionMessage& cpm,
const uint64_t unix_nanosecs,
71 throwIfOutOfRange(t_its.value, TimestampIts::MIN, TimestampIts::MAX,
"TimestampIts");
72 cpm.payload.management_container.reference_time = t_its;
86inline void setReferencePosition(CollectivePerceptionMessage& cpm,
const double latitude,
const double longitude,
87 const double altitude = AltitudeValue::UNAVAILABLE) {
103inline void setFromUTMPosition(CollectivePerceptionMessage& cpm,
const gm::PointStamped& utm_position,
const int& zone,
104 const bool& northp) {
105 setFromUTMPosition(cpm.payload.management_container.reference_position, utm_position, zone, northp);
117 object.object_id.value = id;
118 object.object_id_is_present =
true;
133 if (delta_time < DeltaTimeMilliSecondSigned::MIN || delta_time > DeltaTimeMilliSecondSigned::MAX) {
134 throw std::invalid_argument(
"MeasurementDeltaTime out of range");
136 object.measurement_delta_time.value = delta_time;
154 const double confidence = std::numeric_limits<double>::infinity()) {
156 if (value < CartesianCoordinateLarge::NEGATIVE_OUT_OF_RANGE) {
157 coordinate.value.value = CartesianCoordinateLarge::NEGATIVE_OUT_OF_RANGE;
158 }
else if (value > CartesianCoordinateLarge::POSITIVE_OUT_OF_RANGE) {
159 coordinate.value.value = CartesianCoordinateLarge::POSITIVE_OUT_OF_RANGE;
161 coordinate.value.value =
static_cast<int32_t
>(value);
165 if (confidence == std::numeric_limits<double>::infinity()) {
166 coordinate.confidence.value = CoordinateConfidence::UNAVAILABLE;
167 }
else if (confidence > CoordinateConfidence::MAX || confidence < CoordinateConfidence::MIN) {
168 coordinate.confidence.value = CoordinateConfidence::OUT_OF_RANGE;
170 coordinate.confidence.value =
static_cast<uint16_t
>(confidence);
186 const double x_std = std::numeric_limits<double>::infinity(),
187 const double y_std = std::numeric_limits<double>::infinity(),
188 const double z_std = std::numeric_limits<double>::infinity()) {
191 if (point.z != 0.0) {
193 object.position.z_coordinate_is_present =
true;
213 const gm::PointStamped& utm_position,
214 const double x_std = std::numeric_limits<double>::infinity(),
215 const double y_std = std::numeric_limits<double>::infinity(),
216 const double z_std = std::numeric_limits<double>::infinity()) {
218 if (utm_position.header.frame_id != reference_position.header.frame_id) {
219 throw std::invalid_argument(
"UTM-Position frame_id (" + utm_position.header.frame_id +
220 ") does not match the reference position frame_id (" + reference_position.header.frame_id +
223 setCartesianCoordinateWithConfidence(
object.position.x_coordinate,
224 (utm_position.point.x - reference_position.point.x) * 100, x_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
225 setCartesianCoordinateWithConfidence(
object.position.y_coordinate,
226 (utm_position.point.y - reference_position.point.y) * 100, y_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
227 if (utm_position.point.z != 0.0) {
228 setCartesianCoordinateWithConfidence(
object.position.z_coordinate,
229 (utm_position.point.z - reference_position.point.z) * 100, z_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
230 object.position.z_coordinate_is_present =
true;
246 const double confidence = std::numeric_limits<double>::infinity()) {
248 if (value < VelocityComponentValue::NEGATIVE_OUT_OF_RANGE) {
249 velocity.value.value = VelocityComponentValue::NEGATIVE_OUT_OF_RANGE;
250 }
else if (value > VelocityComponentValue::POSITIVE_OUT_OF_RANGE) {
251 velocity.value.value = VelocityComponentValue::POSITIVE_OUT_OF_RANGE;
253 velocity.value.value =
static_cast<int16_t
>(value);
257 if(confidence == std::numeric_limits<double>::infinity()) {
258 velocity.confidence.value = SpeedConfidence::UNAVAILABLE;
259 }
else if (confidence > SpeedConfidence::MAX || confidence < SpeedConfidence::MIN) {
260 velocity.confidence.value = SpeedConfidence::OUT_OF_RANGE;
262 velocity.confidence.value =
static_cast<uint8_t
>(confidence);
279 const double x_std = std::numeric_limits<double>::infinity(),
280 const double y_std = std::numeric_limits<double>::infinity(),
281 const double z_std = std::numeric_limits<double>::infinity()) {
282 object.velocity.choice = Velocity3dWithConfidence::CHOICE_CARTESIAN_VELOCITY;
283 setVelocityComponent(
object.velocity.cartesian_velocity.x_velocity, cartesian_velocity.x * 100, x_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
284 setVelocityComponent(
object.velocity.cartesian_velocity.y_velocity, cartesian_velocity.y * 100, y_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
285 if (cartesian_velocity.z != 0.0) {
286 setVelocityComponent(
object.velocity.cartesian_velocity.z_velocity, cartesian_velocity.z * 100, z_std * 100 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
287 object.velocity.cartesian_velocity.z_velocity_is_present =
true;
289 object.velocity_is_present =
true;
304 const double confidence = std::numeric_limits<double>::infinity()) {
306 if (value < AccelerationValue::NEGATIVE_OUT_OF_RANGE) {
307 acceleration.value.value = AccelerationValue::NEGATIVE_OUT_OF_RANGE;
308 }
else if (value > AccelerationValue::POSITIVE_OUT_OF_RANGE) {
309 acceleration.value.value = AccelerationValue::POSITIVE_OUT_OF_RANGE;
311 acceleration.value.value =
static_cast<int16_t
>(value);
315 if(confidence == std::numeric_limits<double>::infinity()) {
316 acceleration.confidence.value = AccelerationConfidence::UNAVAILABLE;
317 }
else if (confidence > AccelerationConfidence::MAX || confidence < AccelerationConfidence::MIN) {
318 acceleration.confidence.value = AccelerationConfidence::OUT_OF_RANGE;
320 acceleration.confidence.value =
static_cast<uint8_t
>(confidence);
337 const double x_std = std::numeric_limits<double>::infinity(),
338 const double y_std = std::numeric_limits<double>::infinity(),
339 const double z_std = std::numeric_limits<double>::infinity()) {
340 object.acceleration.choice = Acceleration3dWithConfidence::CHOICE_CARTESIAN_ACCELERATION;
342 x_std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
344 y_std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
345 if (cartesian_acceleration.z != 0.0) {
347 z_std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
348 object.acceleration.cartesian_acceleration.z_acceleration_is_present =
true;
350 object.acceleration_is_present =
true;
364 double yaw_std = std::numeric_limits<double>::infinity()) {
366 double yaw_in_degrees = yaw * 180 / M_PI;
367 while (yaw_in_degrees >= 360.0) yaw_in_degrees -= 360.0;
368 while (yaw_in_degrees < 0.0) yaw_in_degrees += 360.0;
369 object.angles.z_angle.value.value = yaw_in_degrees * 10;
371 if(yaw_std == std::numeric_limits<double>::infinity()) {
372 object.angles.z_angle.confidence.value = AngleConfidence::UNAVAILABLE;
374 yaw_std *= 180.0 / M_PI;
375 yaw_std *= 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR;
377 if (yaw_std > AngleConfidence::MAX || yaw_std < AngleConfidence::MIN) {
378 object.angles.z_angle.confidence.value = AngleConfidence::OUT_OF_RANGE;
380 object.angles.z_angle.confidence.value =
static_cast<uint8_t
>(yaw_std);
383 object.angles_is_present =
true;
397inline void setYawRateOfPerceivedObject(PerceivedObject&
object,
const double yaw_rate,
398 double yaw_rate_std = std::numeric_limits<double>::infinity()) {
399 double yaw_rate_in_degrees = yaw_rate * 180.0 / M_PI;
401 if (yaw_rate_in_degrees < CartesianAngularVelocityComponentValue::NEGATIVE_OUTOF_RANGE) {
402 yaw_rate_in_degrees = CartesianAngularVelocityComponentValue::NEGATIVE_OUTOF_RANGE;
403 }
else if (yaw_rate_in_degrees > CartesianAngularVelocityComponentValue::POSITIVE_OUT_OF_RANGE) {
404 yaw_rate_in_degrees = CartesianAngularVelocityComponentValue::POSITIVE_OUT_OF_RANGE;
407 object.z_angular_velocity.value.value = yaw_rate_in_degrees;
409 if(yaw_rate_std == std::numeric_limits<double>::infinity()) {
410 object.z_angular_velocity.confidence.value = AngularSpeedConfidence::UNAVAILABLE;
412 yaw_rate_std *= 180.0 / M_PI;
413 yaw_rate_std *= etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR;
415 static const std::map<double, uint8_t> confidence_map = {
416 {1.0, AngularSpeedConfidence::DEG_SEC_01},
417 {2.0, AngularSpeedConfidence::DEG_SEC_02},
418 {5.0, AngularSpeedConfidence::DEG_SEC_05},
419 {10.0, AngularSpeedConfidence::DEG_SEC_10},
420 {20.0, AngularSpeedConfidence::DEG_SEC_20},
421 {50.0, AngularSpeedConfidence::DEG_SEC_50},
422 {std::numeric_limits<double>::infinity(), AngularSpeedConfidence::OUT_OF_RANGE},
424 for(
const auto& [thresh, conf_val] : confidence_map) {
425 if (yaw_rate_std <= thresh) {
426 object.z_angular_velocity.confidence.value = conf_val;
432 object.z_angular_velocity_is_present =
true;
450 const double confidence = std::numeric_limits<double>::infinity()) {
452 if (value < ObjectDimensionValue::MIN || value > ObjectDimensionValue::MAX) {
453 dimension.value.value = ObjectDimensionValue::OUT_OF_RANGE;
455 dimension.value.value =
static_cast<uint16_t
>(value);
459 if (confidence == std::numeric_limits<double>::infinity()) {
460 dimension.confidence.value = ObjectDimensionConfidence::UNAVAILABLE;
461 }
else if (confidence > ObjectDimensionConfidence::MAX || confidence < ObjectDimensionConfidence::MIN) {
462 dimension.confidence.value = ObjectDimensionConfidence::OUT_OF_RANGE;
464 dimension.confidence.value =
static_cast<uint8_t
>(confidence);
480 const double std = std::numeric_limits<double>::infinity()) {
481 setObjectDimension(
object.object_dimension_x, value * 10, std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
482 object.object_dimension_x_is_present =
true;
495inline void setYDimensionOfPerceivedObject(PerceivedObject&
object,
const double value,
496 const double std = std::numeric_limits<double>::infinity()) {
497 setObjectDimension(
object.object_dimension_y, value * 10, std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
498 object.object_dimension_y_is_present =
true;
512 const double std = std::numeric_limits<double>::infinity()) {
513 setObjectDimension(
object.object_dimension_z, value * 10, std * 10 * etsi_its_msgs::ONE_D_GAUSSIAN_FACTOR);
514 object.object_dimension_z_is_present =
true;
528inline void setDimensionsOfPerceivedObject(PerceivedObject&
object,
const gm::Vector3& dimensions,
529 const double x_std = std::numeric_limits<double>::infinity(),
530 const double y_std = std::numeric_limits<double>::infinity(),
531 const double z_std = std::numeric_limits<double>::infinity()) {
532 setXDimensionOfPerceivedObject(
object, dimensions.x, x_std);
533 setYDimensionOfPerceivedObject(
object, dimensions.y, y_std);
534 setZDimensionOfPerceivedObject(
object, dimensions.z, z_std);
546inline void initPerceivedObject(PerceivedObject&
object,
const gm::Point& point,
const int16_t delta_time = 0) {
547 setPositionOfPerceivedObject(
object, point);
548 setMeasurementDeltaTimeOfPerceivedObject(
object, delta_time);
563inline void initPerceivedObjectWithUTMPosition(CollectivePerceptionMessage& cpm, PerceivedObject&
object,
564 const gm::PointStamped& point,
const int16_t delta_time = 0) {
565 setUTMPositionOfPerceivedObject(cpm,
object, point);
566 setMeasurementDeltaTimeOfPerceivedObject(
object, delta_time);
579 container.container_id.value = WrappedCpmContainer::CHOICE_CONTAINER_DATA_PERCEIVED_OBJECT_CONTAINER;
580 container.container_data_perceived_object_container.number_of_perceived_objects.value = n_objects;
596inline void addPerceivedObjectToContainer(WrappedCpmContainer& container,
const PerceivedObject& perceived_object) {
597 if (container.container_id.value == WrappedCpmContainer::CHOICE_CONTAINER_DATA_PERCEIVED_OBJECT_CONTAINER) {
598 container.container_data_perceived_object_container.perceived_objects.array.push_back(perceived_object);
599 container.container_data_perceived_object_container.number_of_perceived_objects.value =
600 container.container_data_perceived_object_container.perceived_objects.array.size();
602 throw std::invalid_argument(
"Container is not a PerceivedObjectContainer");
618inline void addContainerToCPM(CollectivePerceptionMessage& cpm,
const WrappedCpmContainer& container) {
620 if (cpm.payload.cpm_containers.value.array.size() < WrappedCpmContainers::MAX_SIZE) {
621 cpm.payload.cpm_containers.value.array.push_back(container);
623 throw std::invalid_argument(
"Maximum number of CPM-Containers reached");
635inline void setWGSRefPosConfidence(CollectivePerceptionMessage& cpm,
const std::array<double, 4>& covariance_matrix) {
Setter functions for the ETSI ITS Common Data Dictionary (CDD) v2.1.1.
Sanity-check functions etc.
File containing constants that are used in the context of ETIS ITS Messages.
gm::PointStamped getUTMPosition(const T &reference_position, int &zone, bool &northp)
Get the UTM Position defined by the given ReferencePosition.
void setReferencePosition(T &ref_position, const double latitude, const double longitude, const double altitude=AltitudeValue::UNAVAILABLE)
Sets the reference position in the given ReferencePostion object.
void setVelocityOfPerceivedObject(PerceivedObject &object, const gm::Vector3 &cartesian_velocity, const double x_std=std::numeric_limits< double >::infinity(), const double y_std=std::numeric_limits< double >::infinity(), const double z_std=std::numeric_limits< double >::infinity())
void setWGSPosConfidenceEllipse(PosConfidenceEllipse &position_confidence_ellipse, const std::array< double, 4 > &covariance_matrix)
Set the Pos Confidence Ellipse object.
void setAccelerationComponent(AccelerationComponent &acceleration, const double value, const double confidence=std::numeric_limits< double >::infinity())
Sets the value and confidence of a AccelerationComponent.
void setAccelerationOfPerceivedObject(PerceivedObject &object, const gm::Vector3 &cartesian_acceleration, const double x_std=std::numeric_limits< double >::infinity(), const double y_std=std::numeric_limits< double >::infinity(), const double z_std=std::numeric_limits< double >::infinity())
Sets the acceleration of a perceived object.
void initPerceivedObjectContainer(WrappedCpmContainer &container, const uint8_t n_objects=0)
Initializes a WrappedCpmContainer as a PerceivedObjectContainer with the given number of objects.
void setWGSRefPosConfidence(CollectivePerceptionMessage &cpm, const std::array< double, 4 > &covariance_matrix)
Set the confidence of the reference position.
void setVelocityComponent(VelocityComponent &velocity, const double value, const double confidence=std::numeric_limits< double >::infinity())
Sets the value and confidence of a VelocityComponent.
void setItsPduHeader(ItsPduHeader &header, const uint8_t message_id, const uint32_t station_id, const uint8_t protocol_version=0)
Set the Its Pdu Header object.
void setFromUTMPosition(T &reference_position, const gm::PointStamped &utm_position, const int zone, const bool northp)
Set the ReferencePosition from a given UTM-Position.
void setYawOfPerceivedObject(PerceivedObject &object, const double yaw, double yaw_std=std::numeric_limits< double >::infinity())
Sets the yaw angle of a perceived object.
void setUTMPositionOfPerceivedObject(CollectivePerceptionMessage &cpm, PerceivedObject &object, const gm::PointStamped &utm_position, const double x_std=std::numeric_limits< double >::infinity(), const double y_std=std::numeric_limits< double >::infinity(), const double z_std=std::numeric_limits< double >::infinity())
Sets the position of a perceived object based on a UTM position.
void addContainerToCPM(CollectivePerceptionMessage &cpm, const WrappedCpmContainer &container)
Adds a container to the Collective Perception Message (CPM).
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.
void setIdOfPerceivedObject(PerceivedObject &object, const uint16_t id)
Set the ID of a PerceivedObject.
void setObjectDimension(ObjectDimension &dimension, const double value, const double confidence=std::numeric_limits< double >::infinity())
Sets the object dimension with the given value and confidence.
void setXDimensionOfPerceivedObject(PerceivedObject &object, const double value, const double std=std::numeric_limits< double >::infinity())
Sets the x-dimension of a perceived object.
void setZDimensionOfPerceivedObject(PerceivedObject &object, const double value, const double std=std::numeric_limits< double >::infinity())
Sets the z-dimension of a perceived object.
void setCartesianCoordinateWithConfidence(CartesianCoordinateWithConfidence &coordinate, const double value, const double confidence=std::numeric_limits< double >::infinity())
Sets the value and confidence of a CartesianCoordinateWithConfidence object.
void setPositionOfPerceivedObject(PerceivedObject &object, const gm::Point &point, const double x_std=std::numeric_limits< double >::infinity(), const double y_std=std::numeric_limits< double >::infinity(), const double z_std=std::numeric_limits< double >::infinity())
Sets the position of a perceived object (relative to the CPM's reference position).
void setMeasurementDeltaTimeOfPerceivedObject(PerceivedObject &object, const int16_t delta_time=0)
Sets the measurement delta time of a PerceivedObject.
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 setReferenceTime(CollectivePerceptionMessage &cpm, const uint64_t unix_nanosecs, const uint16_t n_leap_seconds=etsi_its_msgs::LEAP_SECOND_INSERTIONS_SINCE_2004.rbegin() ->second)
Sets the reference time in a CPM.
void setTimestampITS(TimestampIts ×tamp_its, const uint64_t unix_nanosecs, const uint16_t n_leap_seconds=etsi_its_msgs::LEAP_SECOND_INSERTIONS_SINCE_2004.rbegin() ->second)
Set the TimestampITS object.