Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
carma_cooperative_perception Namespace Reference

Classes

struct  AccelerationSet4Way
 
struct  DDateTime
 
class  DetectionListVizNode
 
class  ExternalObjectListToDetectionListNode
 
class  ExternalObjectListToSdsmNode
 
struct  Heading
 
class  HostVehicleFilterNode
 
struct  MapCoordinate
 
struct  MeasurementTimeOffset
 
struct  MetricSe2
 Calculates distance between a point and detection in SE(2) (special Euclidean) space. More...
 
class  Month
 
struct  MotionModelMapping
 
class  MultipleObjectTrackerNode
 
struct  Position3D
 
struct  PositionOffsetXYZ
 
class  SdsmToDetectionListConfig
 
class  SdsmToDetectionListNode
 
struct  SemanticDistance2dScore
 Calculate 2D Euclidean distance between track and detection. More...
 
struct  Speed
 
class  TrackListToExternalObjectListNode
 
struct  UtmCoordinate
 Represents a position using UTM coordinates. More...
 
struct  UtmDisplacement
 Represent a displacement from a UTM coordinate. More...
 
struct  UtmZone
 
struct  Wgs84Coordinate
 Represents a position using WGS-84 coordinates. More...
 

Typedefs

using Detection = std::variant< multiple_object_tracking::CtrvDetection, multiple_object_tracking::CtraDetection >
 
using Track = std::variant< multiple_object_tracking::CtrvTrack, multiple_object_tracking::CtraTrack >
 

Enumerations

enum class  Hemisphere { kNorth , kSouth }
 

Functions

auto transform_from_map_to_utm (carma_cooperative_perception_interfaces::msg::DetectionList detection_list, const std::string &map_origin) -> carma_cooperative_perception_interfaces::msg::DetectionList
 
constexpr auto operator+= (UtmCoordinate &coordinate, const UtmDisplacement &displacement) -> UtmCoordinate &
 Addition-assignment operator overload. More...
 
constexpr auto operator+ (UtmCoordinate coordinate, const UtmDisplacement &displacement) -> UtmCoordinate
 Addition operator overload. More...
 
constexpr auto operator+ (const UtmDisplacement &displacement, UtmCoordinate coordinate) -> UtmCoordinate
 Addition operator overload. More...
 
constexpr auto operator-= (UtmCoordinate &coordinate, const UtmDisplacement &displacement) -> UtmCoordinate &
 Subtraction-assignment operator overload. More...
 
constexpr auto operator- (UtmCoordinate coordinate, const UtmDisplacement &displacement) -> UtmCoordinate
 Subtraction operator overload. More...
 
constexpr auto operator- (const UtmDisplacement &displacement, UtmCoordinate coordinate) -> UtmCoordinate
 Subtraction operator overload. More...
 
auto calculate_utm_zone (const Wgs84Coordinate &coordinate) -> UtmZone
 Get the UTM zone number from a WGS-84 coordinate. More...
 
auto project_to_carma_map (const Wgs84Coordinate &coordinate, std::string_view proj_string) -> MapCoordinate
 
auto project_to_utm (const Wgs84Coordinate &coordinate) -> UtmCoordinate
 Projects a Wgs84Coordinate to its corresponding UTM zone. More...
 
auto calculate_grid_convergence (const Wgs84Coordinate &position, const UtmZone &zone) -> units::angle::degree_t
 Calculate grid convergence at a given position. More...
 
auto calculate_grid_convergence (const Wgs84Coordinate &position, std::string_view georeference) -> units::angle::degree_t
 
auto euclidean_distance_squared (const geometry_msgs::msg::Pose &a, const geometry_msgs::msg::Pose &b) -> double
 
auto to_time_msg (const DDateTime &d_date_time, bool is_simulation) -> builtin_interfaces::msg::Time
 
auto calc_detection_time_stamp (DDateTime d_date_time, const MeasurementTimeOffset &offset) -> DDateTime
 
auto to_ddate_time_msg (const builtin_interfaces::msg::Time &builtin_time) -> j2735_v2x_msgs::msg::DDateTime
 
auto calc_sdsm_time_offset (const builtin_interfaces::msg::Time &external_object_list_time, const builtin_interfaces::msg::Time &external_object_time) -> carma_v2x_msgs::msg::MeasurementTimeOffset
 
auto to_position_msg (const UtmCoordinate &position_utm) -> geometry_msgs::msg::Point
 
auto heading_to_enu_yaw (const units::angle::degree_t &heading) -> units::angle::degree_t
 
auto calc_relative_position (const geometry_msgs::msg::PoseStamped &current_pose, const carma_v2x_msgs::msg::PositionOffsetXYZ &detected_object_data) -> carma_v2x_msgs::msg::PositionOffsetXYZ
 
auto transform_pose_from_map_to_wgs84 (const geometry_msgs::msg::PoseStamped &source_pose, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> carma_v2x_msgs::msg::Position3D
 
auto to_detection_list_msg (const carma_v2x_msgs::msg::SensorDataSharingMessage &sdsm, std::string_view georeference, bool is_simulation, const std::optional< SdsmToDetectionListConfig > &conversion_adjustment) -> carma_cooperative_perception_interfaces::msg::DetectionList
 Converts a carma_v2x_msgs::msg::SensorDataSharingMessage (SDSM) to carma_cooperative_perception_interfaces::msg::DetectionList format. More...
 
auto to_detection_msg (const carma_perception_msgs::msg::ExternalObject &object, const MotionModelMapping &motion_model_mapping) -> carma_cooperative_perception_interfaces::msg::Detection
 
auto to_detection_list_msg (const carma_perception_msgs::msg::ExternalObjectList &object_list, const MotionModelMapping &motion_model_mapping) -> carma_cooperative_perception_interfaces::msg::DetectionList
 
auto to_external_object_msg (const carma_cooperative_perception_interfaces::msg::Track &track) -> carma_perception_msgs::msg::ExternalObject
 
auto to_external_object_list_msg (const carma_cooperative_perception_interfaces::msg::TrackList &track_list) -> carma_perception_msgs::msg::ExternalObjectList
 
auto to_sdsm_msg (const carma_perception_msgs::msg::ExternalObjectList &external_object_list, const geometry_msgs::msg::PoseStamped &current_pose, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> carma_v2x_msgs::msg::SensorDataSharingMessage
 
auto to_detected_object_data_msg (const carma_perception_msgs::msg::ExternalObject &external_object, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> carma_v2x_msgs::msg::DetectedObjectData
 
auto enu_orientation_to_true_heading (double yaw, const lanelet::BasicPoint3d &obj_pose, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> units::angle::degree_t
 
auto make_detection (const carma_cooperative_perception_interfaces::msg::Detection &msg) -> Detection
 
template<typename T >
constexpr auto remove_units (const T &value)
 
constexpr auto operator== (const UtmZone &lhs, const UtmZone &rhs) -> bool
 
constexpr auto operator!= (const UtmZone &lhs, const UtmZone &rhs) -> bool
 
auto to_string (const UtmZone &zone) -> std::string
 
auto ned_to_enu (const PositionOffsetXYZ &offset_ned) noexcept
 
auto to_position_msg (const MapCoordinate &position_map) -> geometry_msgs::msg::Point
 
std::string to_string (const std::vector< std::uint8_t > &temporary_id)
 
void convert_object_type (carma_cooperative_perception_interfaces::msg::Detection &detection, const j3224_v2x_msgs::msg::ObjectType &j3224_obj_type)
 
void convert_covariances (carma_cooperative_perception_interfaces::msg::Detection &detection, const carma_v2x_msgs::msg::DetectedObjectCommonData &common_data, const std::optional< SdsmToDetectionListConfig > &conversion_adjustment)
 
auto make_semantic_class (std::size_t numeric_value)
 
auto semantic_class_to_numeric_value (mot::SemanticClass semantic_class)
 
auto make_ctrv_detection (const carma_cooperative_perception_interfaces::msg::Detection &msg) -> Detection
 
auto make_ctra_detection (const carma_cooperative_perception_interfaces::msg::Detection &msg) -> Detection
 
static auto to_ros_msg (const mot::CtraTrack &track)
 
static auto to_ros_msg (const mot::CtrvTrack &track)
 
static auto to_ros_msg (const Track &track)
 
static auto temporally_align_detections (std::vector< Detection > &detections, units::time::second_t end_time) -> void
 
static auto predict_track_states (std::vector< Track > tracks, units::time::second_t end_time)
 

Variables

constexpr Month January {1}
 
constexpr Month February {2}
 
constexpr Month March {3}
 
constexpr Month April {4}
 
constexpr Month May {5}
 
constexpr Month June {6}
 
constexpr Month July {7}
 
constexpr Month August {8}
 
constexpr Month September {9}
 
constexpr Month October {10}
 
constexpr Month November {11}
 
constexpr Month December {12}
 

Detailed Description

This file contains functions and helper structs to facilitate transforming WGS-84 coordinates to UTM ones.

This file contains a Month class implementation that should be source-compatible with std::chrono::month. Until CARMA targets C++20, we will have to use this instead of the standard library.

Typedef Documentation

◆ Detection

using carma_cooperative_perception::Detection = typedef std::variant<multiple_object_tracking::CtrvDetection, multiple_object_tracking::CtraDetection>

Definition at line 34 of file multiple_object_tracker_component.hpp.

◆ Track

using carma_cooperative_perception::Track = typedef std::variant<multiple_object_tracking::CtrvTrack, multiple_object_tracking::CtraTrack>

Definition at line 36 of file multiple_object_tracker_component.hpp.

Enumeration Type Documentation

◆ Hemisphere

Enumerator
kNorth 
kSouth 

Definition at line 23 of file utm_zone.hpp.

Function Documentation

◆ calc_detection_time_stamp()

auto carma_cooperative_perception::calc_detection_time_stamp ( DDateTime  d_date_time,
const MeasurementTimeOffset offset 
) -> DDateTime

Definition at line 170 of file msg_conversion.cpp.

172{
173 sdsm_time.second.value() += offset.measurement_time_offset;
174
175 return sdsm_time;
176}

References carma_cooperative_perception::DDateTime::second.

Referenced by to_detection_list_msg().

Here is the caller graph for this function:

◆ calc_relative_position()

auto carma_cooperative_perception::calc_relative_position ( const geometry_msgs::msg::PoseStamped &  current_pose,
const carma_v2x_msgs::msg::PositionOffsetXYZ &  detected_object_data 
) -> carma_v2x_msgs::msg::PositionOffsetXYZ

Definition at line 305 of file msg_conversion.cpp.

309{
310 carma_v2x_msgs::msg::PositionOffsetXYZ adjusted_offset;
311
312 adjusted_offset.offset_x.object_distance =
313 position_offset.offset_x.object_distance - source_pose.pose.position.x;
314 adjusted_offset.offset_y.object_distance =
315 position_offset.offset_y.object_distance - source_pose.pose.position.y;
316 adjusted_offset.offset_z.object_distance =
317 position_offset.offset_z.object_distance - source_pose.pose.position.z;
318 adjusted_offset.presence_vector = carma_v2x_msgs::msg::PositionOffsetXYZ::HAS_OFFSET_Z;
319
320 return adjusted_offset;
321}

Referenced by to_sdsm_msg().

Here is the caller graph for this function:

◆ calc_sdsm_time_offset()

auto carma_cooperative_perception::calc_sdsm_time_offset ( const builtin_interfaces::msg::Time &  external_object_list_time,
const builtin_interfaces::msg::Time &  external_object_time 
) -> carma_v2x_msgs::msg::MeasurementTimeOffset

Definition at line 228 of file msg_conversion.cpp.

232{
233 carma_v2x_msgs::msg::MeasurementTimeOffset time_offset;
234
235 boost::posix_time::ptime external_object_list_time =
236 boost::posix_time::from_time_t(external_object_list_stamp.sec) +
237 boost::posix_time::nanosec(external_object_list_stamp.nanosec);
238
239 boost::posix_time::ptime external_object_time =
240 boost::posix_time::from_time_t(external_object_stamp.sec) +
241 boost::posix_time::nanosec(external_object_stamp.nanosec);
242
243 boost::posix_time::time_duration offset_duration =
244 (external_object_list_time - external_object_time);
245
246 time_offset.measurement_time_offset = offset_duration.total_seconds();
247
248 return time_offset;
249}

Referenced by to_sdsm_msg().

Here is the caller graph for this function:

◆ calculate_grid_convergence() [1/2]

auto carma_cooperative_perception::calculate_grid_convergence ( const Wgs84Coordinate position,
const UtmZone zone 
) -> units::angle::degree_t

Calculate grid convergence at a given position.

This function calculates the grid convergence at a specific coordinate with respect to a specified UTM zone. Grid convergence is the angle between true north and grid north.

Parameters
[in]positionPosition represented in WGS-84 coordinates
[in]zoneThe UTM zone
Returns
Grid convergence angle

Definition at line 154 of file geodetic.cpp.

156{
157 // N.B. developers: PROJ and the related geodetic calculations seem particularly sensitive
158 // to the parameters in this PROJ string. If you run into problems with you calculation
159 // results, carefully check this or any other PROJ string.
160 std::string proj_string{
161 "+proj=utm +zone=" + std::to_string(zone.number) + " +datum=WGS84 +units=m +no_defs"};
162
163 if (zone.hemisphere == Hemisphere::kSouth) {
164 proj_string += " +south";
165 }
166
167 return calculate_grid_convergence(position, proj_string.c_str());
168}
auto calculate_grid_convergence(const Wgs84Coordinate &position, const UtmZone &zone) -> units::angle::degree_t
Calculate grid convergence at a given position.
Definition: geodetic.cpp:154
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21

References calculate_grid_convergence(), kSouth, and to_string().

Referenced by calculate_grid_convergence(), and to_detection_list_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_grid_convergence() [2/2]

auto carma_cooperative_perception::calculate_grid_convergence ( const Wgs84Coordinate position,
std::string_view  georeference 
) -> units::angle::degree_t

Definition at line 125 of file geodetic.cpp.

127{
128 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
129 proj_log_level(context, PJ_LOG_NONE);
130
131 if (context == nullptr) {
132 const std::string error_string{proj_errno_string(proj_context_errno(context))};
133 throw std::invalid_argument("Could not create PROJ context: " + error_string + '.');
134 }
135
136 gsl::owner<PJ *> transform = proj_create(context, georeference.data());
137
138 const auto factors = proj_factors(
139 transform, proj_coord(
141 proj_torad(carma_cooperative_perception::remove_units(position.latitude)), 0, 0));
142
143 if (proj_context_errno(context) != 0) {
144 const std::string error_string{proj_errno_string(proj_context_errno(context))};
145 throw std::invalid_argument("Could not calculate PROJ factors: " + error_string + '.');
146 }
147
148 proj_destroy(transform);
149 proj_context_destroy(context);
150
151 return units::angle::degree_t{proj_todeg(factors.meridian_convergence)};
152}
constexpr auto remove_units(const T &value)

References remove_units().

Here is the call graph for this function:

◆ calculate_utm_zone()

auto carma_cooperative_perception::calculate_utm_zone ( const Wgs84Coordinate coordinate) -> UtmZone

Get the UTM zone number from a WGS-84 coordinate.

Note: This function will not work for coordinates in the special UTM zones Svalbard and Norway.

Parameters
[in]coordinateWGS-84 coordinate
Returns
The UTM zone containing the coordinate

Definition at line 27 of file geodetic.cpp.

28{
29 // Note: std::floor prevents this function from being constexpr (until C++23)
30
31 static constexpr std::size_t zone_width{6};
32 static constexpr std::size_t max_zones{60};
33
34 // Works for longitudes [-180, 360). Longitude of 360 will assign 61.
35 const auto number{
36 static_cast<std::size_t>(
37 (std::floor(carma_cooperative_perception::remove_units(coordinate.longitude) + 180) /
38 zone_width)) +
39 1};
40
41 UtmZone zone;
42
43 // std::min is used to handle the "UTM Zone 61" case.
44 zone.number = std::min(number, max_zones);
45
46 if (coordinate.latitude < units::angle::degree_t{0.0}) {
47 zone.hemisphere = Hemisphere::kSouth;
48 } else {
49 zone.hemisphere = Hemisphere::kNorth;
50 }
51
52 return zone;
53}

References carma_cooperative_perception::UtmZone::hemisphere, kNorth, kSouth, carma_cooperative_perception::UtmZone::number, and remove_units().

Referenced by project_to_utm(), and transform_from_map_to_utm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_covariances()

void carma_cooperative_perception::convert_covariances ( carma_cooperative_perception_interfaces::msg::Detection &  detection,
const carma_v2x_msgs::msg::DetectedObjectCommonData &  common_data,
const std::optional< SdsmToDetectionListConfig > &  conversion_adjustment 
)

Definition at line 382 of file msg_conversion.cpp.

385{
386 // Variables to store original covariance values for debugging
387 double original_pose_covariance_x = 0.0;
388 double original_pose_covariance_y = 0.0;
389 double original_pose_covariance_z = 0.0;
390 double original_pose_covariance_yaw = 0.0;
391 double original_twist_covariance_x = 0.0;
392 double original_twist_covariance_z = 0.0;
393 double original_twist_covariance_yaw = 0.0;
394
395 // Calculate and log original pose covariance values
396 try {
397 original_pose_covariance_x =
398 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.pos_confidence.pos).value(), 2);
399 original_pose_covariance_y = original_pose_covariance_x;
400
401 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
402 "Original pose covariance X/Y: " << original_pose_covariance_x);
403 } catch (const std::bad_optional_access &) {
404 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
405 "Missing position confidence");
406 }
407
408 try {
409 original_pose_covariance_z =
410 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.pos_confidence.elevation).value(), 2);
411
412 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
413 "Original pose covariance Z: " << original_pose_covariance_z);
414 } catch (const std::bad_optional_access &) {
415 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
416 "Missing elevation confidence");
417 }
418
419 try {
420 // Get original heading/yaw covariance
421 original_pose_covariance_yaw =
422 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.heading_conf).value(), 2);
423
424 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
425 "Original pose covariance yaw: " << original_pose_covariance_yaw);
426 } catch (const std::bad_optional_access &) {
427 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
428 "Missing heading confidence");
429 }
430
431 try {
432 // Get original linear x velocity covariance
433 original_twist_covariance_x =
434 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.speed_confidence).value(), 2);
435
436 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
437 "Original twist covariance X: " << original_twist_covariance_x);
438 } catch (const std::bad_optional_access &) {
439 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
440 "Missing speed confidence");
441 }
442
443 if (!common_data.speed_z.unavailable){
444 try {
445 // Get original linear z velocity covariance
446 original_twist_covariance_z =
447 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.speed_confidence_z).value(), 2);
448
449 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
450 "Original twist covariance Z: " << original_twist_covariance_z);
451 } catch (const std::bad_optional_access &) {
452 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
453 "Missing z-speed confidence");
454 }
455 }
456 else{
457 original_twist_covariance_z = 0.0;
458 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
459 "Original twist covariance Z: 0.0 (speed_z not provided)");
460 }
461
462 // Having non-zero value means available
463 if(static_cast<bool>(common_data.accel_4_way.yaw_rate)){
464 try {
465 // Get original angular z velocity (yaw rate) covariance
466 original_twist_covariance_yaw =
467 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.acc_cfd_yaw).value(), 2);
468
469 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
470 "Original twist covariance yaw: " << original_twist_covariance_yaw);
471 } catch (const std::bad_optional_access &) {
472 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
473 "Missing yaw-rate confidence");
474 }
475 }
476 else{
477 original_twist_covariance_yaw = 0.0;
478 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
479 "Original twist covariance yaw: 0.0 (yaw_rate not provided)");
480 }
481
482 if (conversion_adjustment && conversion_adjustment.value().overwrite_covariance)
483 {
484 // Hardcoded pose covariance
485 detection.pose.covariance[0] = conversion_adjustment.value().pose_covariance_x;
486 detection.pose.covariance[7] = conversion_adjustment.value().pose_covariance_y;
487 detection.pose.covariance[14] = conversion_adjustment.value().pose_covariance_z;
488 detection.pose.covariance[35] = conversion_adjustment.value().pose_covariance_yaw;
489
490 // Hardcoded twist covariance
491 detection.twist.covariance[0] = conversion_adjustment.value().twist_covariance_x;
492 detection.twist.covariance[14] = conversion_adjustment.value().twist_covariance_z;
493 detection.twist.covariance[35] = conversion_adjustment.value().twist_covariance_yaw;
494
495 // Print comparison between original and hardcoded values
496 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
497 "POSE COVARIANCE COMPARISON - Original vs Hardcoded: " <<
498 "X: " << original_pose_covariance_x << " -> " << detection.pose.covariance[0] << ", " <<
499 "Y: " << original_pose_covariance_y << " -> " << detection.pose.covariance[7] << ", " <<
500 "Z: " << original_pose_covariance_z << " -> " << detection.pose.covariance[14] << ", " <<
501 "Yaw: " << original_pose_covariance_yaw << " -> " << detection.pose.covariance[35]);
502
503 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"),
504 "TWIST COVARIANCE COMPARISON - Original vs Hardcoded: " <<
505 "X: " << original_twist_covariance_x << " -> , " << detection.twist.covariance[0] << ", " <<
506 "Z: " << original_twist_covariance_z << " -> , " << detection.twist.covariance[14] << ", " <<
507 "Yaw: " << original_twist_covariance_yaw << " -> " << detection.twist.covariance[35]);
508 }
509 else
510 {
511 // Original pose covariance
512 detection.pose.covariance[0] = original_pose_covariance_x;
513 detection.pose.covariance[7] = original_pose_covariance_y;
514 detection.pose.covariance[14] = original_pose_covariance_z;
515 detection.pose.covariance[35] = original_pose_covariance_yaw;
516
517 // Original twist covariance
518 detection.twist.covariance[0] = original_twist_covariance_x;
519 detection.twist.covariance[14] = original_twist_covariance_z;
520 detection.twist.covariance[35] = original_twist_covariance_yaw;
521 }
522
523 // Fill zeros for all other twist covariance values
524 for (size_t i = 0; i < 36; ++i) {
525 if (i != 0 && i != 14 && i != 35) {
526 detection.twist.covariance[i] = 0.0;
527 }
528 }
529
530 // Fill zeros for all other pose covariance values
531 for (size_t i = 0; i < 36; ++i) {
532 if (i != 0 && i != 7 && i != 14 && i != 35) {
533 detection.pose.covariance[i] = 0.0;
534 }
535 }
536}

References process_bag::i.

Referenced by to_detection_list_msg().

Here is the caller graph for this function:

◆ convert_object_type()

void carma_cooperative_perception::convert_object_type ( carma_cooperative_perception_interfaces::msg::Detection &  detection,
const j3224_v2x_msgs::msg::ObjectType &  j3224_obj_type 
)

Definition at line 359 of file msg_conversion.cpp.

361{
362 switch (j3224_obj_type.object_type) {
363 case j3224_obj_type.ANIMAL:
364 detection.motion_model = detection.MOTION_MODEL_CTRV;
365 // We don't have a good semantic class mapping for animals
366 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
367 break;
368 case j3224_obj_type.VRU:
369 detection.motion_model = detection.MOTION_MODEL_CTRV;
370 detection.semantic_class = detection.SEMANTIC_CLASS_PEDESTRIAN;
371 break;
372 case j3224_obj_type.VEHICLE:
373 detection.motion_model = detection.MOTION_MODEL_CTRV;
374 detection.semantic_class = detection.SEMANTIC_CLASS_SMALL_VEHICLE;
375 break;
376 default:
377 detection.motion_model = detection.MOTION_MODEL_CTRV;
378 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
379 }
380}

Referenced by to_detection_list_msg().

Here is the caller graph for this function:

◆ enu_orientation_to_true_heading()

auto carma_cooperative_perception::enu_orientation_to_true_heading ( double  yaw,
const lanelet::BasicPoint3d &  obj_pose,
const std::shared_ptr< lanelet::projection::LocalFrameProjector > &  map_projection 
) -> units::angle::degree_t

Definition at line 278 of file msg_conversion.cpp.

282{
283 // Get object geodetic position
284 lanelet::GPSPoint wgs_obj_pose = map_projection->reverse(obj_pose);
285
286 // Get WGS84 Heading
287 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
288 gsl::owner<PJ *> transform = proj_create(context, map_projection->ECEF_PROJ_STR);
289 units::angle::degree_t grid_heading{std::fmod(90 - yaw + 360, 360)};
290
291 const auto factors = proj_factors(
292 transform, proj_coord(proj_torad(wgs_obj_pose.lon), proj_torad(wgs_obj_pose.lat), 0, 0));
293 units::angle::degree_t grid_convergence{proj_todeg(factors.meridian_convergence)};
294
295 auto wgs_heading = grid_convergence + grid_heading;
296
297 proj_destroy(transform);
298 proj_context_destroy(context);
299
300 return wgs_heading;
301}

Referenced by to_detected_object_data_msg().

Here is the caller graph for this function:

◆ euclidean_distance_squared()

auto carma_cooperative_perception::euclidean_distance_squared ( const geometry_msgs::msg::Pose &  a,
const geometry_msgs::msg::Pose &  b 
) -> double

Definition at line 189 of file host_vehicle_filter_component.cpp.

191{
192 return std::pow(a.position.x - b.position.x, 2) + std::pow(a.position.y - b.position.y, 2) +
193 std::pow(a.position.z - b.position.z, 2);
194}

Referenced by carma_cooperative_perception::HostVehicleFilterNode::attempt_filter_and_republish().

Here is the caller graph for this function:

◆ heading_to_enu_yaw()

auto carma_cooperative_perception::heading_to_enu_yaw ( const units::angle::degree_t &  heading) -> units::angle::degree_t

Definition at line 273 of file msg_conversion.cpp.

274{
275 return units::angle::degree_t{std::fmod(-(remove_units(heading) - 90.0) + 360.0, 360.0)};
276}

References remove_units().

Referenced by to_detection_list_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_ctra_detection()

auto carma_cooperative_perception::make_ctra_detection ( const carma_cooperative_perception_interfaces::msg::Detection &  msg) -> Detection

Definition at line 115 of file multiple_object_tracker_component.cpp.

117{
118 const auto timestamp{
119 units::time::second_t{static_cast<double>(msg.header.stamp.sec)} +
120 units::time::nanosecond_t{static_cast<double>(msg.header.stamp.nanosec)}};
121
122 tf2::Quaternion orientation;
123 orientation.setX(msg.pose.pose.orientation.x);
124 orientation.setY(msg.pose.pose.orientation.y);
125 orientation.setZ(msg.pose.pose.orientation.z);
126 orientation.setW(msg.pose.pose.orientation.w);
127
128 double roll{0.0};
129 double pitch{0.0};
130 double yaw{0.0};
131
132 tf2::Matrix3x3 matrix{orientation};
133 matrix.getRPY(roll, pitch, yaw);
134
135 const mot::CtraState state{
136 units::length::meter_t{msg.pose.pose.position.x},
137 units::length::meter_t{msg.pose.pose.position.y},
138 units::velocity::meters_per_second_t{msg.twist.twist.linear.x},
139 mot::Angle{units::angle::radian_t{yaw}},
140 units::angular_velocity::radians_per_second_t{msg.twist.twist.angular.z},
141 units::acceleration::meters_per_second_squared_t{msg.accel.accel.linear.x}};
142
143 mot::CtraStateCovariance covariance = mot::CtraStateCovariance::Zero();
144 covariance(0, 0) = msg.pose.covariance.at(0);
145 covariance(1, 1) = msg.pose.covariance.at(7);
146 covariance(2, 2) = msg.twist.covariance.at(0);
147 covariance(3, 3) = msg.pose.covariance.at(35);
148 covariance(4, 4) = msg.twist.covariance.at(35);
149 covariance(5, 5) = msg.accel.covariance.at(0);
150
151 return mot::CtraDetection{
152 timestamp, state, covariance, mot::Uuid{msg.id}, make_semantic_class(msg.semantic_class)};
153}
auto make_semantic_class(std::size_t numeric_value)

References make_semantic_class().

Referenced by make_detection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_ctrv_detection()

auto carma_cooperative_perception::make_ctrv_detection ( const carma_cooperative_perception_interfaces::msg::Detection &  msg) -> Detection

Definition at line 77 of file multiple_object_tracker_component.cpp.

79{
80 const auto timestamp{
81 units::time::second_t{static_cast<double>(msg.header.stamp.sec)} +
82 units::time::nanosecond_t{static_cast<double>(msg.header.stamp.nanosec)}};
83
84 tf2::Quaternion orientation;
85 orientation.setX(msg.pose.pose.orientation.x);
86 orientation.setY(msg.pose.pose.orientation.y);
87 orientation.setZ(msg.pose.pose.orientation.z);
88 orientation.setW(msg.pose.pose.orientation.w);
89
90 double roll{0.0};
91 double pitch{0.0};
92 double yaw{0.0};
93
94 tf2::Matrix3x3 matrix{orientation};
95 matrix.getRPY(roll, pitch, yaw);
96
97 const mot::CtrvState state{
98 units::length::meter_t{msg.pose.pose.position.x},
99 units::length::meter_t{msg.pose.pose.position.y},
100 units::velocity::meters_per_second_t{msg.twist.twist.linear.x},
101 mot::Angle{units::angle::radian_t{yaw}},
102 units::angular_velocity::radians_per_second_t{msg.twist.twist.angular.z}};
103
104 mot::CtrvStateCovariance covariance = mot::CtrvStateCovariance::Zero();
105 covariance(0, 0) = msg.pose.covariance.at(0);
106 covariance(1, 1) = msg.pose.covariance.at(7);
107 covariance(2, 2) = msg.twist.covariance.at(0);
108 covariance(3, 3) = msg.pose.covariance.at(35);
109 covariance(4, 4) = msg.twist.covariance.at(35);
110
111 return mot::CtrvDetection{
112 timestamp, state, covariance, mot::Uuid{msg.id}, make_semantic_class(msg.semantic_class)};
113}

References make_semantic_class().

Referenced by make_detection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_detection()

auto carma_cooperative_perception::make_detection ( const carma_cooperative_perception_interfaces::msg::Detection &  msg) -> Detection

Definition at line 155 of file multiple_object_tracker_component.cpp.

157{
158 switch (msg.motion_model) {
159 case msg.MOTION_MODEL_CTRV:
160 return make_ctrv_detection(msg);
161
162 case msg.MOTION_MODEL_CTRA:
163 return make_ctra_detection(msg);
164
165 case msg.MOTION_MODEL_CV:
166 throw std::runtime_error("unsupported motion model type '3: constant velocity (CV)'");
167 }
168
169 throw std::runtime_error("unkown motion model type '" + std::to_string(msg.motion_model) + "'");
170}
auto make_ctra_detection(const carma_cooperative_perception_interfaces::msg::Detection &msg) -> Detection
auto make_ctrv_detection(const carma_cooperative_perception_interfaces::msg::Detection &msg) -> Detection

References make_ctra_detection(), make_ctrv_detection(), and to_string().

Referenced by carma_cooperative_perception::MultipleObjectTrackerNode::store_new_detections().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_semantic_class()

auto carma_cooperative_perception::make_semantic_class ( std::size_t  numeric_value)

Definition at line 41 of file multiple_object_tracker_component.cpp.

42{
43 switch (numeric_value) {
44 case 0:
45 return mot::SemanticClass::kUnknown;
46 case 1:
47 return mot::SemanticClass::kSmallVehicle;
48 case 2:
49 return mot::SemanticClass::kLargeVehicle;
50 case 3:
51 return mot::SemanticClass::kPedestrian;
52 case 4:
53 return mot::SemanticClass::kMotorcycle;
54 }
55
56 return mot::SemanticClass::kUnknown;
57}

Referenced by make_ctra_detection(), and make_ctrv_detection().

Here is the caller graph for this function:

◆ ned_to_enu()

auto carma_cooperative_perception::ned_to_enu ( const PositionOffsetXYZ offset_ned)
noexcept

Definition at line 178 of file msg_conversion.cpp.

179{
180 auto offset_enu{offset_ned};
181
182 // NED to ENU: swap x and y axis and negate z axis
183 offset_enu.offset_x = offset_ned.offset_y;
184 offset_enu.offset_y = offset_ned.offset_x;
185
186 if (offset_enu.offset_z) {
187 offset_enu.offset_z.value() *= -1;
188 }
189
190 return offset_enu;
191}

Referenced by to_detection_list_msg().

Here is the caller graph for this function:

◆ operator!=()

constexpr auto carma_cooperative_perception::operator!= ( const UtmZone lhs,
const UtmZone rhs 
) -> bool
inlineconstexpr

Definition at line 40 of file utm_zone.hpp.

41{
42 return !(lhs == rhs);
43}

◆ operator+() [1/2]

constexpr auto carma_cooperative_perception::operator+ ( const UtmDisplacement displacement,
UtmCoordinate  coordinate 
) -> UtmCoordinate
inlineconstexpr

Addition operator overload.

Parameters
[in]displacementDisplacement from coordinate
[in]coordinatePosition represented in UTM coordinates
Returns
A new UtmCoordinate representing the new position

Definition at line 107 of file geodetic.hpp.

109{
110 return coordinate += displacement;
111}

◆ operator+() [2/2]

constexpr auto carma_cooperative_perception::operator+ ( UtmCoordinate  coordinate,
const UtmDisplacement displacement 
) -> UtmCoordinate
inlineconstexpr

Addition operator overload.

Parameters
[in]coordinatePosition represented in UTM coordinates
[in]displacementDisplacement form coordinate
Returns
A new UtmCoordinate representing the new position

Definition at line 93 of file geodetic.hpp.

95{
96 return coordinate += displacement;
97}

◆ operator+=()

constexpr auto carma_cooperative_perception::operator+= ( UtmCoordinate coordinate,
const UtmDisplacement displacement 
) -> UtmCoordinate &
inlineconstexpr

Addition-assignment operator overload.

Parameters
[in]coordinatePosition represented in UTM coordinates
[in]displacementDisplacement from coordinate
Returns
Reference to the coordinate's updated position

Definition at line 75 of file geodetic.hpp.

77{
78 coordinate.easting += displacement.easting;
79 coordinate.northing += displacement.northing;
80 coordinate.elevation += displacement.elevation;
81
82 return coordinate;
83}

References carma_cooperative_perception::UtmCoordinate::easting.

◆ operator-() [1/2]

constexpr auto carma_cooperative_perception::operator- ( const UtmDisplacement displacement,
UtmCoordinate  coordinate 
) -> UtmCoordinate
inlineconstexpr

Subtraction operator overload.

Parameters
[in]displacementDisplacement from coordinate
[in]coordinatePosition represented in UTM coordinates
Returns
A new UtmCoordinate representing the new position

Definition at line 153 of file geodetic.hpp.

155{
156 return coordinate -= displacement;
157}

◆ operator-() [2/2]

constexpr auto carma_cooperative_perception::operator- ( UtmCoordinate  coordinate,
const UtmDisplacement displacement 
) -> UtmCoordinate
inlineconstexpr

Subtraction operator overload.

Parameters
[in]coordinatePosition represented in UTM coordinates
[in]displacementDisplacement form coordinate
Returns
A new UtmCoordinate representing the new position

Definition at line 139 of file geodetic.hpp.

141{
142 return coordinate -= displacement;
143}

◆ operator-=()

constexpr auto carma_cooperative_perception::operator-= ( UtmCoordinate coordinate,
const UtmDisplacement displacement 
) -> UtmCoordinate &
inlineconstexpr

Subtraction-assignment operator overload.

Parameters
[in]coordinatePosition represented in UTM coordinates
[in]displacementDisplacement from coordinate
Returns
Reference to the coordinate's updated position

Definition at line 121 of file geodetic.hpp.

123{
124 coordinate.easting += displacement.easting;
125 coordinate.northing += displacement.northing;
126 coordinate.elevation += displacement.elevation;
127
128 return coordinate;
129}

References carma_cooperative_perception::UtmCoordinate::easting.

◆ operator==()

constexpr auto carma_cooperative_perception::operator== ( const UtmZone lhs,
const UtmZone rhs 
) -> bool
inlineconstexpr

Definition at line 35 of file utm_zone.hpp.

36{
37 return lhs.number == rhs.number && lhs.hemisphere == rhs.hemisphere;
38}

◆ predict_track_states()

static auto carma_cooperative_perception::predict_track_states ( std::vector< Track tracks,
units::time::second_t  end_time 
)
static

Definition at line 454 of file multiple_object_tracker_component.cpp.

455{
456 for (auto & track : tracks) {
457 mot::propagate_to_time(track, end_time, mot::default_unscented_transform);
458 }
459
460 return tracks;
461}

Referenced by carma_cooperative_perception::MultipleObjectTrackerNode::execute_pipeline().

Here is the caller graph for this function:

◆ project_to_carma_map()

auto carma_cooperative_perception::project_to_carma_map ( const Wgs84Coordinate coordinate,
std::string_view  proj_string 
) -> MapCoordinate

Definition at line 55 of file geodetic.cpp.

57{
58 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
59 proj_log_level(context, PJ_LOG_NONE);
60
61 if (!context) {
62 const std::string error_string{proj_errno_string(proj_context_errno(context))};
63 throw std::invalid_argument("Could not create PROJ context: " + error_string + '.');
64 }
65
66 gsl ::owner<PJ *> transformation =
67 proj_create_crs_to_crs(context, "EPSG:4326", proj_string.data(), nullptr);
68
69 if (!transformation) {
70 const std::string error_string{proj_errno_string(proj_context_errno(context))};
71 throw std::invalid_argument("Could not create PROJ transform: " + error_string + '.');
72 }
73
74 const auto coord_wgs84 = proj_coord(
77 const auto coord_projected = proj_trans(transformation, PJ_FWD, coord_wgs84);
78
79 proj_destroy(transformation);
80 proj_context_destroy(context);
81
82 return {
83 units::length::meter_t{coord_projected.enu.e}, units::length::meter_t{coord_projected.enu.n},
84 units::length::meter_t{coordinate.elevation}};
85}

References remove_units().

Referenced by to_detection_list_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ project_to_utm()

auto carma_cooperative_perception::project_to_utm ( const Wgs84Coordinate coordinate) -> UtmCoordinate

Projects a Wgs84Coordinate to its corresponding UTM zone.

Parameters
[in]coordinatePosition represented in WGS-84 coordinates
Returns
Coordinate's position represented in UTM coordinates

Definition at line 87 of file geodetic.cpp.

88{
89 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
90 proj_log_level(context, PJ_LOG_NONE);
91
92 if (context == nullptr) {
93 const std::string error_string{proj_errno_string(proj_context_errno(context))};
94 throw std::invalid_argument("Could not create PROJ context: " + error_string + '.');
95 }
96
97 const auto utm_zone{calculate_utm_zone(coordinate)};
98 std::string proj_string{"+proj=utm +zone=" + std::to_string(utm_zone.number) + " +datum=WGS84"};
99
100 if (utm_zone.hemisphere == Hemisphere::kSouth) {
101 proj_string += " +south";
102 }
103
104 gsl ::owner<PJ *> utm_transformation =
105 proj_create_crs_to_crs(context, "EPSG:4326", proj_string.c_str(), nullptr);
106
107 if (utm_transformation == nullptr) {
108 const std::string error_string{proj_errno_string(proj_context_errno(context))};
109 throw std::invalid_argument("Could not create PROJ transform: " + error_string + '.');
110 }
111
112 auto coord_wgs84 = proj_coord(
115 auto coord_utm = proj_trans(utm_transformation, PJ_FWD, coord_wgs84);
116
117 proj_destroy(utm_transformation);
118 proj_context_destroy(context);
119
120 return {
121 utm_zone, units::length::meter_t{coord_utm.enu.e}, units::length::meter_t{coord_utm.enu.n},
122 units::length::meter_t{coordinate.elevation}};
123}
auto calculate_utm_zone(const Wgs84Coordinate &coordinate) -> UtmZone
Get the UTM zone number from a WGS-84 coordinate.
Definition: geodetic.cpp:27

References calculate_utm_zone(), kSouth, remove_units(), and to_string().

Referenced by transform_from_map_to_utm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_units()

◆ semantic_class_to_numeric_value()

auto carma_cooperative_perception::semantic_class_to_numeric_value ( mot::SemanticClass  semantic_class)

Definition at line 59 of file multiple_object_tracker_component.cpp.

60{
61 switch (semantic_class) {
62 case mot::SemanticClass::kUnknown:
63 return 0;
64 case mot::SemanticClass::kSmallVehicle:
65 return 1;
66 case mot::SemanticClass::kLargeVehicle:
67 return 2;
68 case mot::SemanticClass::kPedestrian:
69 return 3;
70 case mot::SemanticClass::kMotorcycle:
71 return 4;
72 }
73
74 return 0;
75}

Referenced by to_ros_msg().

Here is the caller graph for this function:

◆ temporally_align_detections()

static auto carma_cooperative_perception::temporally_align_detections ( std::vector< Detection > &  detections,
units::time::second_t  end_time 
) -> void
static

Definition at line 446 of file multiple_object_tracker_component.cpp.

448{
449 for (auto & detection : detections) {
450 mot::propagate_to_time(detection, end_time, mot::default_unscented_transform);
451 }
452}

Referenced by carma_cooperative_perception::MultipleObjectTrackerNode::execute_pipeline().

Here is the caller graph for this function:

◆ to_ddate_time_msg()

auto carma_cooperative_perception::to_ddate_time_msg ( const builtin_interfaces::msg::Time &  builtin_time) -> j2735_v2x_msgs::msg::DDateTime

Definition at line 193 of file msg_conversion.cpp.

195{
196 j2735_v2x_msgs::msg::DDateTime ddate_time_output;
197
198 // Add the time components from epoch seconds
199 boost::posix_time::ptime posix_time = boost::posix_time::from_time_t(builtin_time.sec) +
200 boost::posix_time::nanosec(builtin_time.nanosec);
201
202 const auto time_stamp_year = posix_time.date().year();
203 const auto time_stamp_month = posix_time.date().month();
204 const auto time_stamp_day = posix_time.date().day();
205
206 const auto hours_of_day = posix_time.time_of_day().hours();
207 const auto minutes_of_hour = posix_time.time_of_day().minutes();
208 const auto seconds_of_minute = posix_time.time_of_day().seconds();
209
210 ddate_time_output.presence_vector = 0;
211
212 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::YEAR;
213 ddate_time_output.year.year = time_stamp_year;
214 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::MONTH;
215 ddate_time_output.month.month = time_stamp_month;
216 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::DAY;
217 ddate_time_output.day.day = time_stamp_day;
218 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::HOUR;
219 ddate_time_output.hour.hour = hours_of_day;
220 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::MINUTE;
221 ddate_time_output.minute.minute = minutes_of_hour;
222 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::SECOND;
223 ddate_time_output.second.millisecond = seconds_of_minute;
224
225 return ddate_time_output;
226}

Referenced by to_sdsm_msg().

Here is the caller graph for this function:

◆ to_detected_object_data_msg()

auto carma_cooperative_perception::to_detected_object_data_msg ( const carma_perception_msgs::msg::ExternalObject &  external_object,
const std::shared_ptr< lanelet::projection::LocalFrameProjector > &  map_projection 
) -> carma_v2x_msgs::msg::DetectedObjectData

Definition at line 879 of file msg_conversion.cpp.

883{
884 carma_v2x_msgs::msg::DetectedObjectData detected_object_data;
885 detected_object_data.presence_vector = 0;
886
887 carma_v2x_msgs::msg::DetectedObjectCommonData detected_object_common_data;
888 detected_object_common_data.presence_vector = 0;
889
890 // common data //////////
891
892 // obj_type_conf - convert from percentile, cast to proper uint type
893 if (external_object.presence_vector & external_object.OBJECT_TYPE_PRESENCE_VECTOR) {
894 detected_object_common_data.obj_type_cfd.classification_confidence =
895 static_cast<std::uint8_t>(external_object.confidence * 100);
896 }
897
898 // detected_id - cast proper type
899 if (external_object.presence_vector & external_object.ID_PRESENCE_VECTOR) {
900 detected_object_common_data.detected_id.object_id =
901 static_cast<std::uint16_t>(external_object.id);
902 }
903
904 // pos - Add offset to ref_pos to get object position
905 // in map frame -> convert to WGS84 coordinates for sdsm
906
907 // To get offset: Subtract the external object pose from
908 // the current vehicle location given by the current_pose topic
909 if (external_object.presence_vector & external_object.POSE_PRESENCE_VECTOR) {
910 detected_object_common_data.pos.offset_x.object_distance =
911 static_cast<float>(external_object.pose.pose.position.x);
912 detected_object_common_data.pos.offset_y.object_distance =
913 static_cast<float>(external_object.pose.pose.position.y);
914 detected_object_common_data.pos.offset_z.object_distance =
915 static_cast<float>(external_object.pose.pose.position.z);
916 }
917
918 // speed/speed_z - convert vector velocity to scalar speed val given x/y components
919 if (external_object.presence_vector & external_object.VELOCITY_PRESENCE_VECTOR) {
920 detected_object_common_data.speed.speed =
921 std::hypot(external_object.velocity.twist.linear.x, external_object.velocity.twist.linear.y);
922
923 detected_object_common_data.presence_vector |=
924 carma_v2x_msgs::msg::DetectedObjectCommonData::HAS_SPEED_Z;
925 detected_object_common_data.speed_z.speed = external_object.velocity.twist.linear.z;
926
927 // heading - convert ang vel to scale heading
928 lanelet::BasicPoint3d external_object_position{
929 external_object.pose.pose.position.x, external_object.pose.pose.position.y,
930 external_object.pose.pose.position.z};
931 // Get yaw from orientation
932 auto obj_orientation = external_object.pose.pose.orientation;
933 tf2::Quaternion q(obj_orientation.x, obj_orientation.y, obj_orientation.z, obj_orientation.w);
934 tf2::Matrix3x3 m(q);
935 double roll, pitch, yaw;
936 m.getRPY(roll, pitch, yaw);
937
938 detected_object_common_data.heading.heading =
939 remove_units(enu_orientation_to_true_heading(yaw, external_object_position, map_projection));
940 }
941
942 // optional data (determine based on object type)
943 // use object type struct for better control
944 carma_v2x_msgs::msg::DetectedObjectOptionalData detected_object_optional_data;
945
946 switch (external_object.object_type) {
947 case external_object.SMALL_VEHICLE:
948 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
949
950 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
951 detected_object_optional_data.det_veh.presence_vector =
952 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
953 detected_object_optional_data.det_veh.presence_vector |=
954 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
955
956 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
957 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
958 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
959 }
960 break;
961 case external_object.LARGE_VEHICLE:
962 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
963
964 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
965 detected_object_optional_data.det_veh.presence_vector =
966 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
967 detected_object_optional_data.det_veh.presence_vector |=
968 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
969
970 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
971 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
972 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
973 }
974 break;
975 case external_object.MOTORCYCLE:
976 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
977
978 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
979 detected_object_optional_data.det_veh.presence_vector =
980 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
981 detected_object_optional_data.det_veh.presence_vector |=
982 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
983
984 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
985 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
986 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
987 }
988 break;
989 case external_object.PEDESTRIAN:
990 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VRU;
991
992 detected_object_optional_data.det_vru.presence_vector =
993 carma_v2x_msgs::msg::DetectedVRUData::HAS_BASIC_TYPE;
994 detected_object_optional_data.det_vru.basic_type.type |=
995 j2735_v2x_msgs::msg::PersonalDeviceUserType::A_PEDESTRIAN;
996
997 break;
998 case external_object.UNKNOWN:
999 default:
1000 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::UNKNOWN;
1001
1002 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
1003 detected_object_optional_data.det_obst.obst_size.width.size_value = external_object.size.y;
1004 detected_object_optional_data.det_obst.obst_size.length.size_value = external_object.size.x;
1005
1006 detected_object_optional_data.det_obst.obst_size.presence_vector =
1007 carma_v2x_msgs::msg::ObstacleSize::HAS_HEIGHT;
1008 detected_object_optional_data.det_obst.obst_size.height.size_value = external_object.size.z;
1009 }
1010 }
1011
1012 detected_object_data.detected_object_common_data = std::move(detected_object_common_data);
1013 detected_object_data.detected_object_optional_data = std::move(detected_object_optional_data);
1014
1015 return detected_object_data;
1016}
auto enu_orientation_to_true_heading(double yaw, const lanelet::BasicPoint3d &obj_pose, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> units::angle::degree_t

References enu_orientation_to_true_heading(), and remove_units().

Referenced by to_sdsm_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_detection_list_msg() [1/2]

auto carma_cooperative_perception::to_detection_list_msg ( const carma_perception_msgs::msg::ExternalObjectList &  object_list,
const MotionModelMapping motion_model_mapping 
) -> carma_cooperative_perception_interfaces::msg::DetectionList

Definition at line 738 of file msg_conversion.cpp.

742{
743 carma_cooperative_perception_interfaces::msg::DetectionList detection_list;
744
745 std::transform(
746 std::cbegin(object_list.objects), std::cend(object_list.objects),
747 std::back_inserter(detection_list.detections),
748 [&motion_model_mapping = std::as_const(motion_model_mapping)](const auto & object) {
749 return to_detection_msg(object, motion_model_mapping);
750 });
751
752 return detection_list;
753}

◆ to_detection_list_msg() [2/2]

auto carma_cooperative_perception::to_detection_list_msg ( const carma_v2x_msgs::msg::SensorDataSharingMessage &  sdsm,
std::string_view  georeference,
bool  is_simulation,
const std::optional< SdsmToDetectionListConfig > &  conversion_adjustment 
) -> carma_cooperative_perception_interfaces::msg::DetectionList

Converts a carma_v2x_msgs::msg::SensorDataSharingMessage (SDSM) to carma_cooperative_perception_interfaces::msg::DetectionList format.

This function transforms data from the V2X SDSM format into the CARMA cooperative perception DetectionList format, handling the necessary coordinate transformations.

Important coordinate system transformations:

  • SDSM uses NED (North-East-Down) coordinate system for position offsets
  • SDSM heading is measured clockwise from true north (0° at north, 90° at east)
  • Output DetectionList uses ENU (East-North-Up) coordinate system
  • Output heading is converted to ENU yaw (0° at east, 90° at north)

The function performs the following key operations:

  1. Projects reference position from WGS84 to the local map frame
  2. Converts NED position offsets to ENU
  3. Handles heading conversion from true north to map grid
  4. Transforms detection confidence values to covariance values
  5. Maps object types to appropriate semantic classes
Parameters
sdsmThe input J3224 SDSM message containing detected objects
georeferenceString containing the georeference information for coordinate projection
is_simulationBoolean flag indicating if running in simulation mode (affects timestamps)
conversion_adjustmentOptional configuration for position and covariance adjustments
Returns
carma_cooperative_perception_interfaces::msg::DetectionList message containing the transformed detections in CARMA Platform format

Definition at line 566 of file msg_conversion.cpp.

570{
571 carma_cooperative_perception_interfaces::msg::DetectionList detection_list;
572 try{
573
574 const auto ref_pos_3d{Position3D::from_msg(sdsm.ref_pos)};
575
576 units::length::meter_t elevation(0.0);
577 if(ref_pos_3d.elevation){
578 elevation = ref_pos_3d.elevation.value();
579 }
580 const Wgs84Coordinate ref_pos_wgs84{
581 ref_pos_3d.latitude, ref_pos_3d.longitude, elevation};
582
583 const auto ref_pos_map{project_to_carma_map(ref_pos_wgs84, georeference)};
584
585 for (const auto & object_data : sdsm.objects.detected_object_data) {
586 const auto common_data{object_data.detected_object_common_data};
587
589 detection.header.frame_id = "map";
590
591 const auto detection_time{calc_detection_time_stamp(
592 DDateTime::from_msg(sdsm.sdsm_time_stamp),
593 MeasurementTimeOffset::from_msg(common_data.measurement_time))};
594
595 detection.header.stamp = to_time_msg(detection_time, is_simulation);
596
597 detection.id = fmt::format("{}-{}",
599 common_data.detected_id.object_id);
600
601 const auto pos_offset_enu{ned_to_enu(PositionOffsetXYZ::from_msg(common_data.pos))};
602 detection.pose.pose.position = to_position_msg(MapCoordinate{
603 ref_pos_map.easting + pos_offset_enu.offset_x, ref_pos_map.northing + pos_offset_enu.offset_y,
604 ref_pos_map.elevation + pos_offset_enu.offset_z.value_or(units::length::meter_t{0.0})});
605
606 // Adjust object's position to match vector map coordinates as sensor calibrations are not
607 // always reliable
608 if (conversion_adjustment && conversion_adjustment.value().adjust_pose)
609 {
610 detection.pose.pose.position.x += conversion_adjustment.value().x_offset;
611 detection.pose.pose.position.y += conversion_adjustment.value().y_offset;
612 }
613
614 const auto true_heading{units::angle::degree_t{Heading::from_msg(common_data.heading).heading}};
615
616 // Note: This should really use the detection's WGS-84 position, so the
617 // convergence will be off slightly. TODO
618 const units::angle::degree_t grid_convergence{
619 calculate_grid_convergence(ref_pos_wgs84, georeference)};
620
621 const auto grid_heading{true_heading - grid_convergence};
622 const auto enu_yaw{heading_to_enu_yaw(grid_heading)};
623
624 tf2::Quaternion quat_tf;
625
626 if (conversion_adjustment && conversion_adjustment.value().adjust_pose)
627 {
628 // Adjust object's heading to match vector map coordinates as sensor calibrations are not
629 // always reliable
630 auto yaw_with_offset = units::angle::radian_t{enu_yaw} +
631 units::angle::radian_t{units::angle::degree_t{conversion_adjustment.value().yaw_offset}};
632 auto new_yaw = std::fmod(remove_units(yaw_with_offset) + 2 * M_PI, 2 * M_PI);
633 quat_tf.setRPY(0, 0, new_yaw);
634 }
635 else
636 {
637 // No adjustment needed
638 quat_tf.setRPY(0, 0, remove_units(units::angle::radian_t{enu_yaw}));
639 }
640
641 detection.pose.pose.orientation = tf2::toMsg(quat_tf);
642
643 const auto speed{Speed::from_msg(common_data.speed)};
644 detection.twist.twist.linear.x =
645 remove_units(units::velocity::meters_per_second_t{speed.speed});
646
647 if (!common_data.speed_z.unavailable){
648 const auto speed_z{Speed::from_msg(common_data.speed_z)};
649 detection.twist.twist.linear.z =
650 remove_units(units::velocity::meters_per_second_t{speed_z.speed});
651 }
652 else{
653 detection.twist.twist.linear.z = remove_units(units::velocity::meters_per_second_t{0.0});
654 }
655
656 // NOTE: common_data.accel_4_way.longitudinal, lateral, vert not supported
657 // and not needed at the moment for multiple object tracking algorithm
658 // Having non-zero yaw_rate value means available
659 if(static_cast<bool>(common_data.accel_4_way.yaw_rate)){
660 const auto accel_set{AccelerationSet4Way::from_msg(common_data.accel_4_way)};
661 detection.twist.twist.angular.z =
662 remove_units(units::angular_velocity::degrees_per_second_t{accel_set.yaw_rate});
663 }
664 else{
665 detection.twist.twist.angular.z = 0.0;
666 }
667
668 convert_covariances(detection, common_data, conversion_adjustment);
669
670 convert_object_type(detection, common_data.obj_type);
671
672 detection_list.detections.push_back(std::move(detection));
673 }
674 }
675 catch (...) {
676 RCLCPP_ERROR_STREAM(rclcpp::get_logger("sdsm_to_detection_list_node"), "Error converting SDSM to object, ignoring sdsm message.");
677 }
678
679 return detection_list;
680}
void convert_covariances(carma_cooperative_perception_interfaces::msg::Detection &detection, const carma_v2x_msgs::msg::DetectedObjectCommonData &common_data, const std::optional< SdsmToDetectionListConfig > &conversion_adjustment)
auto to_position_msg(const MapCoordinate &position_map) -> geometry_msgs::msg::Point
auto calc_detection_time_stamp(DDateTime d_date_time, const MeasurementTimeOffset &offset) -> DDateTime
std::variant< multiple_object_tracking::CtrvDetection, multiple_object_tracking::CtraDetection > Detection
auto project_to_carma_map(const Wgs84Coordinate &coordinate, std::string_view proj_string) -> MapCoordinate
Definition: geodetic.cpp:55
auto to_time_msg(const DDateTime &d_date_time, bool is_simulation) -> builtin_interfaces::msg::Time
auto ned_to_enu(const PositionOffsetXYZ &offset_ned) noexcept
void convert_object_type(carma_cooperative_perception_interfaces::msg::Detection &detection, const j3224_v2x_msgs::msg::ObjectType &j3224_obj_type)
auto heading_to_enu_yaw(const units::angle::degree_t &heading) -> units::angle::degree_t

References calc_detection_time_stamp(), calculate_grid_convergence(), convert_covariances(), convert_object_type(), carma_cooperative_perception::MapCoordinate::easting, carma_cooperative_perception::AccelerationSet4Way::from_msg(), carma_cooperative_perception::DDateTime::from_msg(), carma_cooperative_perception::Heading::from_msg(), carma_cooperative_perception::Position3D::from_msg(), carma_cooperative_perception::Speed::from_msg(), carma_cooperative_perception::MeasurementTimeOffset::from_msg(), carma_cooperative_perception::PositionOffsetXYZ::from_msg(), heading_to_enu_yaw(), carma_cooperative_perception::Wgs84Coordinate::latitude, ned_to_enu(), project_to_carma_map(), remove_units(), to_position_msg(), to_string(), and to_time_msg().

Referenced by carma_cooperative_perception::ExternalObjectListToDetectionListNode::publish_as_detection_list(), and carma_cooperative_perception::SdsmToDetectionListNode::sdsm_msg_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_detection_msg()

auto carma_cooperative_perception::to_detection_msg ( const carma_perception_msgs::msg::ExternalObject &  object,
const MotionModelMapping motion_model_mapping 
) -> carma_cooperative_perception_interfaces::msg::Detection

Definition at line 682 of file msg_conversion.cpp.

686{
688
689 detection.header = object.header;
690
691 if (object.presence_vector & object.BSM_ID_PRESENCE_VECTOR) {
692 detection.id = "";
693 std::transform(
694 std::cbegin(object.bsm_id), std::cend(object.bsm_id), std::back_inserter(detection.id),
695 [](const auto & i) { return i + '0'; });
696 }
697
698 if (object.presence_vector & object.ID_PRESENCE_VECTOR) {
699 detection.id += '-' + std::to_string(object.id);
700 }
701
702 if (object.presence_vector & object.POSE_PRESENCE_VECTOR) {
703 detection.pose = object.pose;
704 }
705
706 if (object.presence_vector & object.VELOCITY_PRESENCE_VECTOR) {
707 detection.twist = object.velocity;
708 }
709
710 if (object.presence_vector & object.OBJECT_TYPE_PRESENCE_VECTOR) {
711 switch (object.object_type) {
712 case object.SMALL_VEHICLE:
713 detection.motion_model = motion_model_mapping.small_vehicle_model;
714 detection.semantic_class = detection.SEMANTIC_CLASS_SMALL_VEHICLE;
715 break;
716 case object.LARGE_VEHICLE:
717 detection.motion_model = motion_model_mapping.large_vehicle_model;
718 detection.semantic_class = detection.SEMANTIC_CLASS_LARGE_VEHICLE;
719 break;
720 case object.MOTORCYCLE:
721 detection.motion_model = motion_model_mapping.motorcycle_model;
722 detection.semantic_class = detection.SEMANTIC_CLASS_MOTORCYCLE;
723 break;
724 case object.PEDESTRIAN:
725 detection.motion_model = motion_model_mapping.pedestrian_model;
726 detection.semantic_class = detection.SEMANTIC_CLASS_PEDESTRIAN;
727 break;
728 case object.UNKNOWN:
729 default:
730 detection.motion_model = motion_model_mapping.unknown_model;
731 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
732 }
733 }
734
735 return detection;
736}
std::string to_string(const std::vector< std::uint8_t > &temporary_id)

References process_bag::i, and to_string().

Here is the call graph for this function:

◆ to_external_object_list_msg()

auto carma_cooperative_perception::to_external_object_list_msg ( const carma_cooperative_perception_interfaces::msg::TrackList &  track_list) -> carma_perception_msgs::msg::ExternalObjectList

Definition at line 826 of file msg_conversion.cpp.

829{
830 carma_perception_msgs::msg::ExternalObjectList external_object_list;
831
832 for (const auto & track : track_list.tracks) {
833 external_object_list.objects.push_back(to_external_object_msg(track));
834 }
835
836 return external_object_list;
837}
auto to_external_object_msg(const carma_cooperative_perception_interfaces::msg::Track &track) -> carma_perception_msgs::msg::ExternalObject

References to_external_object_msg().

Referenced by carma_cooperative_perception::TrackListToExternalObjectListNode::publish_as_external_object_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_external_object_msg()

auto carma_cooperative_perception::to_external_object_msg ( const carma_cooperative_perception_interfaces::msg::Track &  track) -> carma_perception_msgs::msg::ExternalObject

Definition at line 755 of file msg_conversion.cpp.

757{
758 carma_perception_msgs::msg::ExternalObject external_object;
759 external_object.header = track.header;
760 external_object.presence_vector = 0;
761
762 const auto to_numeric_id = [](std::string string_id) -> std::optional<uint32_t> {
763 auto non_digit_start = std::remove_if(
764 std::begin(string_id), std::end(string_id),
765 [](const auto & ch) { return !std::isdigit(ch); });
766
767 std::uint32_t numeric_id;
768 const auto digit_substr_size{std::distance(std::begin(string_id), non_digit_start)};
769 if (
770 std::from_chars(string_id.c_str(), string_id.c_str() + digit_substr_size, numeric_id).ec ==
771 std::errc{}) {
772 return numeric_id;
773 }
774
775 return std::nullopt;
776 };
777
778 if (const auto numeric_id{to_numeric_id(track.id)}) {
779 external_object.presence_vector |= external_object.ID_PRESENCE_VECTOR;
780 external_object.id = numeric_id.value();
781 } else {
782 external_object.presence_vector &= ~external_object.ID_PRESENCE_VECTOR;
783 }
784
785 external_object.presence_vector |= external_object.POSE_PRESENCE_VECTOR;
786 external_object.pose = track.pose;
787
788 external_object.presence_vector |= external_object.VELOCITY_PRESENCE_VECTOR;
789
790 const auto track_longitudinal_velocity{track.twist.twist.linear.x};
791 const auto track_orientation = track.pose.pose.orientation;
792
793 tf2::Quaternion q(
794 track_orientation.x, track_orientation.y, track_orientation.z, track_orientation.w);
795 tf2::Matrix3x3 m(q);
796 double roll, pitch, yaw;
797 m.getRPY(roll, pitch, yaw);
798
799 external_object.velocity.twist.linear.x = track_longitudinal_velocity * std::cos(yaw);
800 external_object.velocity.twist.linear.y = track_longitudinal_velocity * std::sin(yaw);
801
802 external_object.object_type = track.semantic_class;
803
804 external_object.presence_vector |= external_object.OBJECT_TYPE_PRESENCE_VECTOR;
805 switch (track.semantic_class) {
806 case track.SEMANTIC_CLASS_SMALL_VEHICLE:
807 external_object.object_type = external_object.SMALL_VEHICLE;
808 break;
809 case track.SEMANTIC_CLASS_LARGE_VEHICLE:
810 external_object.object_type = external_object.LARGE_VEHICLE;
811 break;
812 case track.SEMANTIC_CLASS_MOTORCYCLE:
813 external_object.object_type = external_object.MOTORCYCLE;
814 break;
815 case track.SEMANTIC_CLASS_PEDESTRIAN:
816 external_object.object_type = external_object.PEDESTRIAN;
817 break;
818 case track.SEMANTIC_CLASS_UNKNOWN:
819 default:
820 external_object.object_type = external_object.UNKNOWN;
821 }
822
823 return external_object;
824}

Referenced by to_external_object_list_msg().

Here is the caller graph for this function:

◆ to_position_msg() [1/2]

auto carma_cooperative_perception::to_position_msg ( const MapCoordinate position_map) -> geometry_msgs::msg::Point

Definition at line 262 of file msg_conversion.cpp.

263{
264 geometry_msgs::msg::Point msg;
265
266 msg.x = remove_units(position_map.easting);
267 msg.y = remove_units(position_map.northing);
268 msg.z = remove_units(position_map.elevation);
269
270 return msg;
271}

References remove_units().

Here is the call graph for this function:

◆ to_position_msg() [2/2]

auto carma_cooperative_perception::to_position_msg ( const UtmCoordinate position_utm) -> geometry_msgs::msg::Point

Definition at line 251 of file msg_conversion.cpp.

252{
253 geometry_msgs::msg::Point msg;
254
255 msg.x = remove_units(position_utm.easting);
256 msg.y = remove_units(position_utm.northing);
257 msg.z = remove_units(position_utm.elevation);
258
259 return msg;
260}

References remove_units().

Referenced by to_detection_list_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_ros_msg() [1/3]

static auto carma_cooperative_perception::to_ros_msg ( const mot::CtraTrack &  track)
static

Definition at line 172 of file multiple_object_tracker_component.cpp.

173{
175
176 msg.header.stamp.sec = mot::remove_units(units::math::floor(track.timestamp));
177 msg.header.stamp.nanosec = mot::remove_units(
178 units::time::nanosecond_t{units::math::fmod(track.timestamp, units::time::second_t{1.0})});
179 msg.header.frame_id = "map";
180
181 msg.id = track.uuid.value();
182 msg.motion_model = msg.MOTION_MODEL_CTRA;
183 msg.pose.pose.position.x = mot::remove_units(track.state.position_x);
184 msg.pose.pose.position.y = mot::remove_units(track.state.position_y);
185
186 tf2::Quaternion orientation;
187 orientation.setRPY(0, 0, mot::remove_units(track.state.yaw.get_angle()));
188 msg.pose.pose.orientation.x = orientation.getX();
189 msg.pose.pose.orientation.y = orientation.getY();
190 msg.pose.pose.orientation.z = orientation.getZ();
191 msg.pose.pose.orientation.w = orientation.getW();
192
193 msg.twist.twist.linear.x = mot::remove_units(track.state.velocity);
194 msg.twist.twist.angular.z = mot::remove_units(track.state.yaw_rate);
195
196 msg.accel.accel.linear.x = mot::remove_units(track.state.acceleration);
197
198 msg.semantic_class = semantic_class_to_numeric_value(mot::get_semantic_class(track));
199
200 return msg;
201}
auto semantic_class_to_numeric_value(mot::SemanticClass semantic_class)
std::variant< multiple_object_tracking::CtrvTrack, multiple_object_tracking::CtraTrack > Track

References remove_units(), and semantic_class_to_numeric_value().

Referenced by to_ros_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_ros_msg() [2/3]

static auto carma_cooperative_perception::to_ros_msg ( const mot::CtrvTrack &  track)
static

Definition at line 203 of file multiple_object_tracker_component.cpp.

204{
206
207 msg.header.stamp.sec = mot::remove_units(units::math::floor(track.timestamp));
208 msg.header.stamp.nanosec = mot::remove_units(
209 units::time::nanosecond_t{units::math::fmod(track.timestamp, units::time::second_t{1.0})});
210 msg.header.frame_id = "map";
211
212 msg.id = track.uuid.value();
213 msg.motion_model = msg.MOTION_MODEL_CTRV;
214 msg.pose.pose.position.x = mot::remove_units(track.state.position_x);
215 msg.pose.pose.position.y = mot::remove_units(track.state.position_y);
216
217 tf2::Quaternion orientation;
218 orientation.setRPY(0, 0, mot::remove_units(track.state.yaw.get_angle()));
219 msg.pose.pose.orientation.x = orientation.getX();
220 msg.pose.pose.orientation.y = orientation.getY();
221 msg.pose.pose.orientation.z = orientation.getZ();
222 msg.pose.pose.orientation.w = orientation.getW();
223
224 msg.twist.twist.linear.x = mot::remove_units(track.state.velocity);
225 msg.twist.twist.angular.z = mot::remove_units(track.state.yaw_rate);
226
227 msg.semantic_class = semantic_class_to_numeric_value(mot::get_semantic_class(track));
228
229 return msg;
230}

References remove_units(), and semantic_class_to_numeric_value().

Here is the call graph for this function:

◆ to_ros_msg() [3/3]

static auto carma_cooperative_perception::to_ros_msg ( const Track track)
static

Definition at line 232 of file multiple_object_tracker_component.cpp.

233{
234 static constexpr mot::Visitor visitor{
235 [](const mot::CtrvTrack & t) { return to_ros_msg(t); },
236 [](const mot::CtraTrack & t) { return to_ros_msg(t); },
237 [](const auto &) {
238 // Currently on support CTRV and CTRA
239 throw std::runtime_error{"cannot make ROS 2 message from track type"};
240 }};
241
242 return std::visit(visitor, track);
243}
static auto to_ros_msg(const Track &track)

References to_ros_msg().

Referenced by carma_cooperative_perception::MultipleObjectTrackerNode::execute_pipeline().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_sdsm_msg()

auto carma_cooperative_perception::to_sdsm_msg ( const carma_perception_msgs::msg::ExternalObjectList &  external_object_list,
const geometry_msgs::msg::PoseStamped &  current_pose,
const std::shared_ptr< lanelet::projection::LocalFrameProjector > &  map_projection 
) -> carma_v2x_msgs::msg::SensorDataSharingMessage

Definition at line 839 of file msg_conversion.cpp.

844{
845 carma_v2x_msgs::msg::SensorDataSharingMessage sdsm;
846 carma_v2x_msgs::msg::DetectedObjectList detected_object_list;
847
848 sdsm.sdsm_time_stamp = to_ddate_time_msg(external_object_list.header.stamp);
849
850 sdsm.ref_pos = transform_pose_from_map_to_wgs84(current_pose, map_projection);
851
852 // Convert external objects within the list to detected_object_data
853 for (const auto & external_object : external_object_list.objects) {
854 auto sdsm_detected_object = to_detected_object_data_msg(external_object, map_projection);
855
856 // Calculate the time offset between individual objects and the respective SDSM container msg
857 sdsm_detected_object.detected_object_common_data.measurement_time =
858 calc_sdsm_time_offset(external_object.header.stamp, external_object.header.stamp);
859
860 // Calculate the position offset from the current reference pose (in m)
861 sdsm_detected_object.detected_object_common_data.pos =
862 calc_relative_position(current_pose, sdsm_detected_object.detected_object_common_data.pos);
863
864 detected_object_list.detected_object_data.push_back(sdsm_detected_object);
865 }
866
867 std::vector<uint8_t> id = {0x00, 0x00, 0x00, 0x01};
868 sdsm.source_id.id = id;
869 sdsm.equipment_type.equipment_type = j3224_v2x_msgs::msg::EquipmentType::OBU;
870 sdsm.ref_pos_xy_conf.semi_major = j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_UNAVAILABLE;
871 sdsm.ref_pos_xy_conf.semi_minor = j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_UNAVAILABLE;
872 sdsm.ref_pos_xy_conf.orientation =
873 j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_ORIENTATION_UNAVAILABLE;
874 sdsm.objects = detected_object_list;
875
876 return sdsm;
877}
auto calc_sdsm_time_offset(const builtin_interfaces::msg::Time &external_object_list_time, const builtin_interfaces::msg::Time &external_object_time) -> carma_v2x_msgs::msg::MeasurementTimeOffset
auto to_ddate_time_msg(const builtin_interfaces::msg::Time &builtin_time) -> j2735_v2x_msgs::msg::DDateTime
auto to_detected_object_data_msg(const carma_perception_msgs::msg::ExternalObject &external_object, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> carma_v2x_msgs::msg::DetectedObjectData
auto calc_relative_position(const geometry_msgs::msg::PoseStamped &current_pose, const carma_v2x_msgs::msg::PositionOffsetXYZ &detected_object_data) -> carma_v2x_msgs::msg::PositionOffsetXYZ
auto transform_pose_from_map_to_wgs84(const geometry_msgs::msg::PoseStamped &source_pose, const std::shared_ptr< lanelet::projection::LocalFrameProjector > &map_projection) -> carma_v2x_msgs::msg::Position3D

References calc_relative_position(), calc_sdsm_time_offset(), to_ddate_time_msg(), to_detected_object_data_msg(), and transform_pose_from_map_to_wgs84().

Referenced by carma_cooperative_perception::ExternalObjectListToSdsmNode::publish_as_sdsm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_string() [1/2]

std::string carma_cooperative_perception::to_string ( const std::vector< std::uint8_t > &  temporary_id)

Definition at line 344 of file msg_conversion.cpp.

344 {
345 std::string str;
346 str.reserve(2 * std::size(temporary_id)); // Two hex characters per octet string
347
348 std::array<char, 2> buffer;
349 for (const auto & octet_string : temporary_id) {
350 std::to_chars(std::begin(buffer), std::end(buffer), octet_string, 16);
351 str.push_back(std::toupper(std::get<0>(buffer)));
352 str.push_back(std::toupper(std::get<1>(buffer)));
353 }
354
355 return str;
356};

References create_two_lane_map::str.

Referenced by to_detection_msg().

Here is the caller graph for this function:

◆ to_string() [2/2]

auto carma_cooperative_perception::to_string ( const UtmZone zone) -> std::string

Definition at line 21 of file utm_zone.cpp.

22{
23 if (zone.hemisphere == Hemisphere::kNorth) {
24 return std::to_string(zone.number) + "N";
25 }
26
27 return std::to_string(zone.number) + "S";
28}

References kNorth, and to_string().

Referenced by cooperative_lanechange::CooperativeLaneChangePlugin::add_trajectory_to_response(), carma_wm_ctrl::WMBroadcaster::addScheduleFromMsg(), route_following_plugin::RouteFollowingPlugin::addStopAndWaitAtRouteEnd(), lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_nocruise_maxspeed_decel(), lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_or_decel_complete_upper(), lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_nocruise_minspeed_accel_complete(), cooperative_lanechange::CooperativeLaneChangePlugin::bsmIDtoString(), yield_plugin::YieldPlugin::bsmIDtoString(), calculate_grid_convergence(), mobilitypath_visualizer::MobilityPathVisualizer::callbackMobilityPath(), lci_strategic_plugin::LCIStrategicPlugin::canArriveAtGreenWithCertainty(), platooning_strategic_ihp::PlatooningManager::changeFromFollowerToLeader(), mobilitypath_publisher::MobilityPathPublication::compose_mobility_header(), lci_strategic_plugin::LCIStrategicPlugin::composeIntersectionTransitMessage(), sci_strategic_plugin::SCIStrategicPlugin::composeIntersectionTransitMessage(), mobilitypath_visualizer::MobilityPathVisualizer::composeLabelMarker(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::composeLaneChangeManeuverMessage(), route_following_plugin::RouteFollowingPlugin::composeLaneChangeManeuverMessage(), approaching_emergency_vehicle_plugin::ApproachingEmergencyVehiclePlugin::composeLaneChangeManeuverMessage(), route_following_plugin::RouteFollowingPlugin::composeLaneFollowingManeuverMessage(), approaching_emergency_vehicle_plugin::ApproachingEmergencyVehiclePlugin::composeLaneFollowingManeuverMessage(), stop_and_dwell_strategic_plugin::StopAndDwellStrategicPlugin::composeLaneFollowingManeuverMessage(), sci_strategic_plugin::SCIStrategicPlugin::composeLaneFollowingManeuverMessage(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::composeManeuverMessage(), plan_delegator::PlanDelegator::composePlanTrajectoryRequest(), sci_strategic_plugin::SCIStrategicPlugin::composeStopAndWaitManeuverMessage(), stop_and_dwell_strategic_plugin::StopAndDwellStrategicPlugin::composeStopAndWaitManeuverMessage(), lci_strategic_plugin::LCIStrategicPlugin::composeStopAndWaitManeuverMessage(), route_following_plugin::RouteFollowingPlugin::composeStopAndWaitManeuverMessage(), approaching_emergency_vehicle_plugin::ApproachingEmergencyVehiclePlugin::composeStopAndWaitManeuverMessage(), carma_wm_ctrl::WMBroadcaster::composeTCRStatus(), lci_strategic_plugin::LCIStrategicPlugin::composeTrajectorySmoothingManeuverMessage(), carma_wm_ctrl::WMBroadcaster::controlRequestFromRoute(), trajectory_follower_wrapper::TrajectoryFollowerWrapperNode::convert_cmd(), pure_pursuit_wrapper::PurePursuitWrapperNode::convert_cmd(), carma_wm::SignalizedIntersectionManager::convertLaneToLaneletId(), basic_autonomy::waypoint_generation::create_lanechange_geometry(), cooperative_lanechange::CooperativeLaneChangePlugin::create_mobility_request(), carma_cooperative_perception::MultipleObjectTrackerNode::execute_pipeline(), object_visualizer::Node::external_objects_callback(), carma_wm::SignalizedIntersectionManager::extract_signal_states_from_movement_state(), lci_strategic_plugin::LCIStrategicPlugin::extractInitialState(), sci_strategic_plugin::SCIStrategicPlugin::extractInitialState(), stop_and_dwell_strategic_plugin::StopAndDwellStrategicPlugin::extractInitialState(), yield_plugin::YieldPlugin::generate_JMT_trajectory(), arbitrator::TreePlanner::generate_plan(), approaching_emergency_vehicle_plugin::ApproachingEmergencyVehiclePlugin::generateApproachingErvStatusMessage(), lci_strategic_plugin::LCIStrategicPlugin::generateMobilityOperation(), sci_strategic_plugin::SCIStrategicPlugin::generateMobilityOperation(), light_controlled_intersection_tactical_plugin::LightControlledIntersectionTacticalPlugin::generateNewTrajectory(), carma_wm_ctrl::WMBroadcaster::geofenceCallback(), yield_plugin::YieldPlugin::get_collision(), yield_plugin::YieldPlugin::get_collision_time(), lci_strategic_plugin::LCIStrategicPlugin::get_eet_or_tbd(), lci_strategic_plugin::LCIStrategicPlugin::get_final_entry_time_and_conditions(), lci_strategic_plugin::LCIStrategicPlugin::get_nearest_green_entry_time(), yield_plugin::YieldPlugin::get_predicted_velocity_at_time(), lci_strategic_plugin::LCIStrategicPlugin::get_ts_case(), carma_wm::IndexedDistanceMap::getElementIndexByDistance(), plan_delegator::PlanDelegator::getLaneChangeInformation(), lci_strategic_plugin::LCIStrategicPlugin::getLaneletsBetweenWithException(), sci_strategic_plugin::SCIStrategicPlugin::getLaneletsBetweenWithException(), stop_and_dwell_strategic_plugin::StopAndDwellStrategicPlugin::getLaneletsBetweenWithException(), carma_wm::SignalizedIntersectionManager::getTrafficSignal(), carma_wm::SignalizedIntersectionManager::getTrafficSignalId(), lci_strategic_plugin::LCIStrategicPlugin::handleFailureCaseHelper(), lci_strategic_plugin::LCIStrategicPlugin::handleGreenSignalScenario(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::is_lanechange_possible(), yield_plugin::YieldPlugin::is_object_behind_vehicle(), basic_autonomy::waypoint_generation::is_valid_yield_plan(), plan_delegator::PlanDelegator::isManeuverExpired(), light_controlled_intersection_tactical_plugin::LightControlledIntersectionTacticalPlugin::logDebugInfoAboutPreviousTrajectory(), make_detection(), carma_wm::SignalizedIntersectionManager::min_end_time_converter_minute_of_year(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::mob_op_cb_leader(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::mob_op_cb_preparetojoin(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::mob_req_cb_leadwithoperation(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::mob_resp_cb_preparetojoin(), carma_wm::query::nonConnectedAdjacentLeft(), route::RouteStateWorker::onRouteEvent(), intersection_transit_maneuvering::operator<<(), route_following_plugin::RouteFollowingPlugin::plan_maneuvers_callback(), inlanecruising_plugin::InLaneCruisingPlugin::plan_trajectory_callback(), yield_plugin::YieldPlugin::plan_trajectory_callback(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::plan_trajectory_callback(), platooning_tactical_plugin::PlatooningTacticalPlugin::plan_trajectory_cb(), stop_and_wait_plugin::StopandWait::plan_trajectory_cb(), light_controlled_intersection_tactical_plugin::LightControlledIntersectionTacticalPlugin::planTrajectorySmoothing(), lci_strategic_plugin::LCIStrategicPlugin::planWhenAPPROACHING(), lci_strategic_plugin::LCIStrategicPlugin::planWhenWAITING(), carma_wm::CARMAWorldModel::pointFromRouteTrackPos(), lci_strategic_plugin::LCIStrategicPlugin::print_params(), project_to_utm(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::run_candidate_follower(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::run_leader_aborting(), platooning_strategic_ihp::PlatooningStrategicIHPPlugin::run_prepare_to_join(), boost::serialization::save(), plan_delegator::anonymous_namespace{plan_delegator.cpp}::setManeuverEndingLaneletId(), route_following_plugin::anonymous_namespace{route_following_plugin.cpp}::setManeuverLaneletIds(), plan_delegator::anonymous_namespace{plan_delegator.cpp}::setManeuverStartingLaneletId(), carma_wm_ctrl::GeofenceScheduler::startGeofenceCallback(), to_detection_list_msg(), to_string(), transform_from_map_to_utm(), lci_strategic_plugin::LCIStrategicPlugin::ts_case1(), lci_strategic_plugin::LCIStrategicPlugin::ts_case2(), lci_strategic_plugin::LCIStrategicPlugin::ts_case3(), lci_strategic_plugin::LCIStrategicPlugin::ts_case4(), lci_strategic_plugin::LCIStrategicPlugin::ts_case6(), lci_strategic_plugin::LCIStrategicPlugin::ts_case7(), plan_delegator::PlanDelegator::updateManeuverParameters(), lci_strategic_plugin::LCIStrategicPlugin::validLightState(), and carma_cloud_client::CarmaCloudClient::XMLconversion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_time_msg()

auto carma_cooperative_perception::to_time_msg ( const DDateTime d_date_time,
bool  is_simulation 
) -> builtin_interfaces::msg::Time

Definition at line 61 of file msg_conversion.cpp.

62{
63 // Convert DDateTime to builtin_interfaces::msg::Time
64 builtin_interfaces::msg::Time msg;
65 if (!is_simulation) {
66 // Create a tm structure to hold the date and time components
67 std::tm timeinfo = {};
68
69 // Year
70 if (d_date_time.year){
71 if(remove_units(d_date_time.year.value()) >= 1970){
72 // std::tm is counted since 1900
73 timeinfo.tm_year = static_cast<int>(remove_units(d_date_time.year.value())) - 1900;
74 }
75 else{
76 throw std::invalid_argument(
77 "Year must be greater than 1970 for live date/time conversion");
78 }
79 }
80
81 // Month
82 if (d_date_time.month && static_cast<int>(d_date_time.month.value().get_value()) != 0)
83 {
84 // std::tm is counted from 0 to 11, J2735 is counted from 1 to 12
85 timeinfo.tm_mon = static_cast<int>(d_date_time.month.value().get_value()) - 1;
86 }
87
88 // Day
89 if (d_date_time.day && static_cast<int>(d_date_time.day.value()) != 0)
90 {
91 // Day is counted from 1 to 31 in both std::tm and J2735
92 timeinfo.tm_mday = static_cast<int>(d_date_time.day.value());
93 }
94 else{
95 timeinfo.tm_mday = 1; // Default to 1 if day is not provided as C++ initializes to 0
96 }
97
98 // Hour
99 if (d_date_time.hour && static_cast<int>(d_date_time.hour.value()) != 31)
100 {
101 // Hour is counted from 0 to 23 in both std::tm and J2735
102 timeinfo.tm_hour = static_cast<int>(d_date_time.hour.value());
103 }
104
105 // Minute
106 if (d_date_time.minute && static_cast<int>(d_date_time.minute.value()) != 60)
107 {
108 // Minute is counted from 0 to 59 in both std::tm and J2735
109 timeinfo.tm_min = static_cast<int>(d_date_time.minute.value());
110 }
111 // Set seconds field (which actually uses ms in j2735) to 0
112 // for now and add milliseconds later
113 timeinfo.tm_sec = 0;
114
115 std::time_t timeT; // Integer number of seconds since the Unix epoch
116
117 // Treat the time as UTC to adjust the timezone offset later
118 // which also works if no timezone offset is provided because SAE J3224 SDSM is in UTC
119 timeinfo.tm_gmtoff = 0; // Set to 0 for UTC
120 timeinfo.tm_isdst = 0; // UTC doesn't observe DST
121 std::time_t utc_time = timegm(&timeinfo); // func is available on GNU-based systems (ubuntu etc)
122
123 if (d_date_time.time_zone_offset) {
124 // Offset is in minutes, convert to seconds
125 // If offset is negative (e.g., -5 for EST), we add 5 hours to get UTC
126 // If offset is positive (e.g., +9 for JST), we subtract 9 hours to get UTC
127 int offset_seconds = static_cast<int>(d_date_time.time_zone_offset.value()) * 60;
128 timeT = utc_time - offset_seconds; // Subtract offset to get UTC
129 } else {
130 // No timezone offset provided, assume input is already UTC
131 timeT = utc_time;
132 }
133
134 // Convert time_t to system_clock::time_point
135 auto timePoint = std::chrono::system_clock::from_time_t(timeT);
136
137 // Add milliseconds
138 int milliseconds = 0;
139 if (d_date_time.second)
140 {
141 milliseconds = static_cast<int>(d_date_time.second.value());
142 }
143 timePoint += std::chrono::milliseconds(milliseconds);
144
145 // Extract seconds and nanoseconds since epoch
146 auto duration = timePoint.time_since_epoch();
147 auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
148 auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds);
149
150 msg.sec = static_cast<int32_t>(seconds.count());
151 msg.nanosec = static_cast<uint32_t>(nanoseconds.count());
152
153 return msg;
154 }
155
156 // if simulation, we ignore the date, month, year etc because the simulation won't be that long
157 double seconds;
158 const auto fractional_secs{std::modf(
159 remove_units(units::time::second_t{d_date_time.hour.value_or(units::time::second_t{0.0})}) +
160 remove_units(units::time::second_t{d_date_time.minute.value_or(units::time::second_t{0.0})}) +
161 remove_units(units::time::second_t{d_date_time.second.value_or(units::time::second_t{0.0})}),
162 &seconds)};
163
164 msg.sec = static_cast<std::int32_t>(seconds);
165 msg.nanosec = static_cast<std::int32_t>(fractional_secs * 1e9);
166
167 return msg;
168}
std::optional< units::time::millisecond_t > second
Definition: j2735_types.hpp:43
std::optional< units::time::hour_t > hour
Definition: j2735_types.hpp:41
std::optional< units::time::day_t > day
Definition: j2735_types.hpp:40
std::optional< units::time::minute_t > minute
Definition: j2735_types.hpp:42
std::optional< units::time::year_t > year
Definition: j2735_types.hpp:38
std::optional< units::time::minute_t > time_zone_offset
Definition: j2735_types.hpp:44

References remove_units().

Referenced by to_detection_list_msg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transform_from_map_to_utm()

auto carma_cooperative_perception::transform_from_map_to_utm ( carma_cooperative_perception_interfaces::msg::DetectionList  detection_list,
const std::string &  map_origin 
) -> carma_cooperative_perception_interfaces::msg::DetectionList

Definition at line 27 of file external_object_list_to_detection_list_component.cpp.

30{
31 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
32 proj_log_level(context, PJ_LOG_NONE);
33
34 if (context == nullptr) {
35 const std::string error_string{proj_errno_string(proj_context_errno(context))};
36 throw std::invalid_argument("Could not create PROJ context: " + error_string + '.');
37 }
38
39 gsl::owner<PJ *> map_transformation = proj_create(context, map_origin.c_str());
40
41 if (map_transformation == nullptr) {
42 const std::string error_string{proj_errno_string(proj_context_errno(context))};
43 throw std::invalid_argument(
44 "Could not create PROJ transform to origin '" + map_origin + "': " + error_string + '.');
45 }
46
47 std::vector<carma_cooperative_perception_interfaces::msg::Detection> new_detections;
48 for (auto detection : detection_list.detections) {
49 // Coordinate order is easting (meters), northing (meters)
50 const auto position_planar{
51 proj_coord(detection.pose.pose.position.x, detection.pose.pose.position.y, 0, 0)};
52 const auto proj_inverse{proj_trans(map_transformation, PJ_DIRECTION::PJ_INV, position_planar)};
53 const Wgs84Coordinate position_wgs84{
54 units::angle::radian_t{proj_inverse.lp.phi}, units::angle::radian_t{proj_inverse.lp.lam},
55 units::length::meter_t{detection.pose.pose.position.z}};
56
57 const auto utm_zone{calculate_utm_zone(position_wgs84)};
58 const auto position_utm{project_to_utm(position_wgs84)};
59
60 detection.header.frame_id = to_string(utm_zone);
61 detection.pose.pose.position.x = remove_units(position_utm.easting);
62 detection.pose.pose.position.y = remove_units(position_utm.northing);
63
64 new_detections.push_back(std::move(detection));
65 }
66
67 std::swap(detection_list.detections, new_detections);
68
69 proj_destroy(map_transformation);
70 proj_context_destroy(context);
71
72 return detection_list;
73}
auto project_to_utm(const Wgs84Coordinate &coordinate) -> UtmCoordinate
Projects a Wgs84Coordinate to its corresponding UTM zone.
Definition: geodetic.cpp:87

References calculate_utm_zone(), project_to_utm(), remove_units(), and to_string().

Here is the call graph for this function:

◆ transform_pose_from_map_to_wgs84()

auto carma_cooperative_perception::transform_pose_from_map_to_wgs84 ( const geometry_msgs::msg::PoseStamped &  source_pose,
const std::shared_ptr< lanelet::projection::LocalFrameProjector > &  map_projection 
) -> carma_v2x_msgs::msg::Position3D

Definition at line 323 of file msg_conversion.cpp.

327{
328 carma_v2x_msgs::msg::Position3D ref_pos;
329 lanelet::BasicPoint3d source_pose_basicpoint{
330 source_pose.pose.position.x, source_pose.pose.position.y, 0.0};
331
332 lanelet::GPSPoint wgs84_ref_pose = map_projection->reverse(source_pose_basicpoint);
333
334 ref_pos.longitude = wgs84_ref_pose.lon;
335 ref_pos.latitude = wgs84_ref_pose.lat;
336 ref_pos.elevation = wgs84_ref_pose.ele;
337 ref_pos.elevation_exists = true;
338
339 return ref_pos;
340}

Referenced by to_sdsm_msg().

Here is the caller graph for this function:

Variable Documentation

◆ April

constexpr Month carma_cooperative_perception::April {4}
inlineconstexpr

Definition at line 234 of file month.hpp.

◆ August

constexpr Month carma_cooperative_perception::August {8}
inlineconstexpr

Definition at line 238 of file month.hpp.

◆ December

constexpr Month carma_cooperative_perception::December {12}
inlineconstexpr

Definition at line 242 of file month.hpp.

◆ February

constexpr Month carma_cooperative_perception::February {2}
inlineconstexpr

Definition at line 232 of file month.hpp.

◆ January

constexpr Month carma_cooperative_perception::January {1}
inlineconstexpr

Definition at line 231 of file month.hpp.

◆ July

constexpr Month carma_cooperative_perception::July {7}
inlineconstexpr

Definition at line 237 of file month.hpp.

◆ June

constexpr Month carma_cooperative_perception::June {6}
inlineconstexpr

Definition at line 236 of file month.hpp.

◆ March

constexpr Month carma_cooperative_perception::March {3}
inlineconstexpr

Definition at line 233 of file month.hpp.

◆ May

constexpr Month carma_cooperative_perception::May {5}
inlineconstexpr

Definition at line 235 of file month.hpp.

◆ November

constexpr Month carma_cooperative_perception::November {11}
inlineconstexpr

Definition at line 241 of file month.hpp.

◆ October

constexpr Month carma_cooperative_perception::October {10}
inlineconstexpr

Definition at line 240 of file month.hpp.

◆ September

constexpr Month carma_cooperative_perception::September {9}
inlineconstexpr

Definition at line 239 of file month.hpp.