50 inline 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;
86 inline void setReferencePosition(CollectivePerceptionMessage& cpm,
const double latitude,
const double longitude,
87 const double altitude = AltitudeValue::UNAVAILABLE) {
88 setReferencePosition(cpm.payload.management_container.reference_position, latitude, longitude, altitude);
103 inline 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 +
227 if (utm_position.point.z != 0.0) {
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;
285 if (cartesian_velocity.z != 0.0) {
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;
345 if (cartesian_acceleration.z != 0.0) {
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;
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;
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;
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()) {
482 object.object_dimension_x_is_present =
true;
496 const double std = std::numeric_limits<double>::infinity()) {
498 object.object_dimension_y_is_present =
true;
512 const double std = std::numeric_limits<double>::infinity()) {
514 object.object_dimension_z_is_present =
true;
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()) {
546 inline void initPerceivedObject(PerceivedObject&
object,
const gm::Point& point,
const int16_t delta_time = 0) {
564 const gm::PointStamped& point,
const int16_t delta_time = 0) {
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;
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");
618 inline 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");
649 container.container_id.value = WrappedCpmContainer::CHOICE_CONTAINER_DATA_SENSOR_INFORMATION_CONTAINER;
650 container.container_data_sensor_information_container.array = std::vector<SensorInformation>();
663 inline void setSensorID(SensorInformation& sensor_information,
const uint8_t sensor_id = 0) {
665 sensor_information.sensor_id.value = sensor_id;
678 inline void setSensorType(SensorInformation& sensor_information,
const uint8_t sensor_type = SensorType::UNDEFINED) {
680 sensor_information.sensor_type.value = sensor_type;
702 if (container.container_id.value == WrappedCpmContainer::CHOICE_CONTAINER_DATA_SENSOR_INFORMATION_CONTAINER) {
704 if (container.container_data_sensor_information_container.array.size() < SensorInformationContainer::MAX_SIZE ) {
705 throwIfOutOfRange(sensor_information.sensor_id.value, Identifier1B::MIN, Identifier1B::MAX,
"SensorID");
706 throwIfOutOfRange(sensor_information.sensor_type.value, SensorType::MIN, SensorType::MAX,
"SensorType");
707 container.container_data_sensor_information_container.array.push_back(sensor_information);
709 throw std::invalid_argument(
"Maximum number of entries SensorInformationContainers reached");
712 throw std::invalid_argument(
"Container is not a SensorInformationContainer");
731 if (container.container_id.value == WrappedCpmContainer::CHOICE_CONTAINER_DATA_SENSOR_INFORMATION_CONTAINER) {
732 throwIfOutOfRange(container.container_data_sensor_information_container.array.size(),
733 SensorInformationContainer::MIN_SIZE, SensorInformationContainer::MAX_SIZE,
"SensorInformationContainer array size"
737 throw std::invalid_argument(
"Container is not a SensorInformationContainer");