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  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) -> 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) -> carma_cooperative_perception_interfaces::msg::DetectionList
 
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
 
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 74 of file msg_conversion.cpp.

76{
77 sdsm_time.second.value() += offset.measurement_time_offset;
78
79 return sdsm_time;
80}

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 209 of file msg_conversion.cpp.

213{
214 carma_v2x_msgs::msg::PositionOffsetXYZ adjusted_offset;
215
216 adjusted_offset.offset_x.object_distance =
217 position_offset.offset_x.object_distance - source_pose.pose.position.x;
218 adjusted_offset.offset_y.object_distance =
219 position_offset.offset_y.object_distance - source_pose.pose.position.y;
220 adjusted_offset.offset_z.object_distance =
221 position_offset.offset_z.object_distance - source_pose.pose.position.z;
222 adjusted_offset.presence_vector = carma_v2x_msgs::msg::PositionOffsetXYZ::HAS_OFFSET_Z;
223
224 return adjusted_offset;
225}

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 132 of file msg_conversion.cpp.

136{
137 carma_v2x_msgs::msg::MeasurementTimeOffset time_offset;
138
139 boost::posix_time::ptime external_object_list_time =
140 boost::posix_time::from_time_t(external_object_list_stamp.sec) +
141 boost::posix_time::nanosec(external_object_list_stamp.nanosec);
142
143 boost::posix_time::ptime external_object_time =
144 boost::posix_time::from_time_t(external_object_stamp.sec) +
145 boost::posix_time::nanosec(external_object_stamp.nanosec);
146
147 boost::posix_time::time_duration offset_duration =
148 (external_object_list_time - external_object_time);
149
150 time_offset.measurement_time_offset = offset_duration.total_seconds();
151
152 return time_offset;
153}

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:

◆ 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 182 of file msg_conversion.cpp.

186{
187 // Get object geodetic position
188 lanelet::GPSPoint wgs_obj_pose = map_projection->reverse(obj_pose);
189
190 // Get WGS84 Heading
191 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
192 gsl::owner<PJ *> transform = proj_create(context, map_projection->ECEF_PROJ_STR);
193 units::angle::degree_t grid_heading{std::fmod(90 - yaw + 360, 360)};
194
195 const auto factors = proj_factors(
196 transform, proj_coord(proj_torad(wgs_obj_pose.lon), proj_torad(wgs_obj_pose.lat), 0, 0));
197 units::angle::degree_t grid_convergence{proj_todeg(factors.meridian_convergence)};
198
199 auto wgs_heading = grid_convergence + grid_heading;
200
201 proj_destroy(transform);
202 proj_context_destroy(context);
203
204 return wgs_heading;
205}

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 177 of file msg_conversion.cpp.

178{
179 return units::angle::degree_t{std::fmod(-(remove_units(heading) - 90.0) + 360.0, 360.0)};
180}

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 82 of file msg_conversion.cpp.

83{
84 auto offset_enu{offset_ned};
85
86 // NED to ENU: swap x and y axis and negate z axis
87 offset_enu.offset_x = offset_ned.offset_y;
88 offset_enu.offset_y = offset_ned.offset_x;
89
90 if (offset_enu.offset_z) {
91 offset_enu.offset_z.value() *= -1;
92 }
93
94 return offset_enu;
95}

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 451 of file multiple_object_tracker_component.cpp.

452{
453 for (auto & track : tracks) {
454 mot::propagate_to_time(track, end_time, mot::default_unscented_transform);
455 }
456
457 return tracks;
458}

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 443 of file multiple_object_tracker_component.cpp.

445{
446 for (auto & detection : detections) {
447 mot::propagate_to_time(detection, end_time, mot::default_unscented_transform);
448 }
449}

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 97 of file msg_conversion.cpp.

99{
100 j2735_v2x_msgs::msg::DDateTime ddate_time_output;
101
102 // Add the time components from epoch seconds
103 boost::posix_time::ptime posix_time = boost::posix_time::from_time_t(builtin_time.sec) +
104 boost::posix_time::nanosec(builtin_time.nanosec);
105
106 const auto time_stamp_year = posix_time.date().year();
107 const auto time_stamp_month = posix_time.date().month();
108 const auto time_stamp_day = posix_time.date().day();
109
110 const auto hours_of_day = posix_time.time_of_day().hours();
111 const auto minutes_of_hour = posix_time.time_of_day().minutes();
112 const auto seconds_of_minute = posix_time.time_of_day().seconds();
113
114 ddate_time_output.presence_vector = 0;
115
116 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::YEAR;
117 ddate_time_output.year.year = time_stamp_year;
118 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::MONTH;
119 ddate_time_output.month.month = time_stamp_month;
120 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::DAY;
121 ddate_time_output.day.day = time_stamp_day;
122 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::HOUR;
123 ddate_time_output.hour.hour = hours_of_day;
124 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::MINUTE;
125 ddate_time_output.minute.minute = minutes_of_hour;
126 ddate_time_output.presence_vector |= j2735_v2x_msgs::msg::DDateTime::SECOND;
127 ddate_time_output.second.millisecond = seconds_of_minute;
128
129 return ddate_time_output;
130}

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 586 of file msg_conversion.cpp.

590{
591 carma_v2x_msgs::msg::DetectedObjectData detected_object_data;
592 detected_object_data.presence_vector = 0;
593
594 carma_v2x_msgs::msg::DetectedObjectCommonData detected_object_common_data;
595 detected_object_common_data.presence_vector = 0;
596
597 // common data //////////
598
599 // obj_type_conf - convert from percentile, cast to proper uint type
600 if (external_object.presence_vector & external_object.OBJECT_TYPE_PRESENCE_VECTOR) {
601 detected_object_common_data.obj_type_cfd.classification_confidence =
602 static_cast<std::uint8_t>(external_object.confidence * 100);
603 }
604
605 // detected_id - cast proper type
606 if (external_object.presence_vector & external_object.ID_PRESENCE_VECTOR) {
607 detected_object_common_data.detected_id.object_id =
608 static_cast<std::uint16_t>(external_object.id);
609 }
610
611 // pos - Add offset to ref_pos to get object position
612 // in map frame -> convert to WGS84 coordinates for sdsm
613
614 // To get offset: Subtract the external object pose from
615 // the current vehicle location given by the current_pose topic
616 if (external_object.presence_vector & external_object.POSE_PRESENCE_VECTOR) {
617 detected_object_common_data.pos.offset_x.object_distance =
618 static_cast<float>(external_object.pose.pose.position.x);
619 detected_object_common_data.pos.offset_y.object_distance =
620 static_cast<float>(external_object.pose.pose.position.y);
621 detected_object_common_data.pos.offset_z.object_distance =
622 static_cast<float>(external_object.pose.pose.position.z);
623 }
624
625 // speed/speed_z - convert vector velocity to scalar speed val given x/y components
626 if (external_object.presence_vector & external_object.VELOCITY_PRESENCE_VECTOR) {
627 detected_object_common_data.speed.speed =
628 std::hypot(external_object.velocity.twist.linear.x, external_object.velocity.twist.linear.y);
629
630 detected_object_common_data.presence_vector |=
631 carma_v2x_msgs::msg::DetectedObjectCommonData::HAS_SPEED_Z;
632 detected_object_common_data.speed_z.speed = external_object.velocity.twist.linear.z;
633
634 // heading - convert ang vel to scale heading
635 lanelet::BasicPoint3d external_object_position{
636 external_object.pose.pose.position.x, external_object.pose.pose.position.y,
637 external_object.pose.pose.position.z};
638 // Get yaw from orientation
639 auto obj_orientation = external_object.pose.pose.orientation;
640 tf2::Quaternion q(obj_orientation.x, obj_orientation.y, obj_orientation.z, obj_orientation.w);
641 tf2::Matrix3x3 m(q);
642 double roll, pitch, yaw;
643 m.getRPY(roll, pitch, yaw);
644
645 detected_object_common_data.heading.heading =
646 remove_units(enu_orientation_to_true_heading(yaw, external_object_position, map_projection));
647 }
648
649 // optional data (determine based on object type)
650 // use object type struct for better control
651 carma_v2x_msgs::msg::DetectedObjectOptionalData detected_object_optional_data;
652
653 switch (external_object.object_type) {
654 case external_object.SMALL_VEHICLE:
655 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
656
657 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
658 detected_object_optional_data.det_veh.presence_vector =
659 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
660 detected_object_optional_data.det_veh.presence_vector |=
661 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
662
663 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
664 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
665 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
666 }
667 break;
668 case external_object.LARGE_VEHICLE:
669 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
670
671 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
672 detected_object_optional_data.det_veh.presence_vector =
673 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
674 detected_object_optional_data.det_veh.presence_vector |=
675 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
676
677 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
678 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
679 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
680 }
681 break;
682 case external_object.MOTORCYCLE:
683 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VEHICLE;
684
685 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
686 detected_object_optional_data.det_veh.presence_vector =
687 carma_v2x_msgs::msg::DetectedVehicleData::HAS_SIZE;
688 detected_object_optional_data.det_veh.presence_vector |=
689 carma_v2x_msgs::msg::DetectedVehicleData::HAS_HEIGHT;
690
691 detected_object_optional_data.det_veh.size.vehicle_width = external_object.size.y;
692 detected_object_optional_data.det_veh.size.vehicle_length = external_object.size.x;
693 detected_object_optional_data.det_veh.height.vehicle_height = external_object.size.z;
694 }
695 break;
696 case external_object.PEDESTRIAN:
697 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::VRU;
698
699 detected_object_optional_data.det_vru.presence_vector =
700 carma_v2x_msgs::msg::DetectedVRUData::HAS_BASIC_TYPE;
701 detected_object_optional_data.det_vru.basic_type.type |=
702 j2735_v2x_msgs::msg::PersonalDeviceUserType::A_PEDESTRIAN;
703
704 break;
705 case external_object.UNKNOWN:
706 default:
707 detected_object_common_data.obj_type.object_type = j3224_v2x_msgs::msg::ObjectType::UNKNOWN;
708
709 if (external_object.presence_vector & external_object.SIZE_PRESENCE_VECTOR) {
710 detected_object_optional_data.det_obst.obst_size.width.size_value = external_object.size.y;
711 detected_object_optional_data.det_obst.obst_size.length.size_value = external_object.size.x;
712
713 detected_object_optional_data.det_obst.obst_size.presence_vector =
714 carma_v2x_msgs::msg::ObstacleSize::HAS_HEIGHT;
715 detected_object_optional_data.det_obst.obst_size.height.size_value = external_object.size.z;
716 }
717 }
718
719 detected_object_data.detected_object_common_data = std::move(detected_object_common_data);
720 detected_object_data.detected_object_optional_data = std::move(detected_object_optional_data);
721
722 return detected_object_data;
723}
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 446 of file msg_conversion.cpp.

450{
451 carma_cooperative_perception_interfaces::msg::DetectionList detection_list;
452
453 std::transform(
454 std::cbegin(object_list.objects), std::cend(object_list.objects),
455 std::back_inserter(detection_list.detections),
456 [&motion_model_mapping = std::as_const(motion_model_mapping)](const auto & object) {
457 return to_detection_msg(object, motion_model_mapping);
458 });
459
460 return detection_list;
461}

◆ 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 
) -> carma_cooperative_perception_interfaces::msg::DetectionList

Definition at line 246 of file msg_conversion.cpp.

249{
250 carma_cooperative_perception_interfaces::msg::DetectionList detection_list;
251
252 const auto ref_pos_3d{Position3D::from_msg(sdsm.ref_pos)};
253 const Wgs84Coordinate ref_pos_wgs84{
254 ref_pos_3d.latitude, ref_pos_3d.longitude, ref_pos_3d.elevation.value()};
255 const auto ref_pos_map{project_to_carma_map(ref_pos_wgs84, georeference)};
256
257 for (const auto & object_data : sdsm.objects.detected_object_data) {
258 const auto common_data{object_data.detected_object_common_data};
259
261 detection.header.frame_id = "map";
262
263 const auto detection_time{calc_detection_time_stamp(
264 DDateTime::from_msg(sdsm.sdsm_time_stamp),
265 MeasurementTimeOffset::from_msg(common_data.measurement_time))};
266
267 detection.header.stamp = to_time_msg(detection_time);
268
269 // TemporaryID and octet string terms come from the SAE J2735 message definitions
270 static constexpr auto to_string = [](const std::vector<std::uint8_t> & temporary_id) {
271 std::string str;
272 str.reserve(2 * std::size(temporary_id)); // Two hex characters per octet string
273
274 std::array<char, 2> buffer;
275 for (const auto & octet_string : temporary_id) {
276 std::to_chars(std::begin(buffer), std::end(buffer), octet_string, 16);
277 str.push_back(std::toupper(std::get<0>(buffer)));
278 str.push_back(std::toupper(std::get<1>(buffer)));
279 }
280
281 return str;
282 };
283
284 detection.id =
285 to_string(sdsm.source_id.id) + "-" + std::to_string(common_data.detected_id.object_id);
286
287 const auto pos_offset_enu{ned_to_enu(PositionOffsetXYZ::from_msg(common_data.pos))};
288 detection.pose.pose.position = to_position_msg(MapCoordinate{
289 ref_pos_map.easting + pos_offset_enu.offset_x, ref_pos_map.northing + pos_offset_enu.offset_y,
290 ref_pos_map.elevation + pos_offset_enu.offset_z.value_or(units::length::meter_t{0.0})});
291
292 // Pose covariance is flattened 6x6 matrix with rows/columns of x, y, z, roll, pitch, yaw
293 try {
294 detection.pose.covariance.at(0) =
295 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.pos_confidence.pos).value(), 2);
296 detection.pose.covariance.at(7) =
297 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.pos_confidence.pos).value(), 2);
298 } catch (const std::bad_optional_access &) {
299 throw std::runtime_error("missing position confidence");
300 }
301
302 try {
303 detection.pose.covariance.at(14) =
304 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.pos_confidence.elevation).value(), 2);
305 } catch (const std::bad_optional_access &) {
306 throw std::runtime_error("missing elevation confidence");
307 }
308
309 const auto true_heading{units::angle::degree_t{Heading::from_msg(common_data.heading).heading}};
310
311 // Note: This should really use the detection's WGS-84 position, so the
312 // convergence will be off slightly. TODO
313 const units::angle::degree_t grid_convergence{
314 calculate_grid_convergence(ref_pos_wgs84, georeference)};
315
316 const auto grid_heading{true_heading - grid_convergence};
317 const auto enu_yaw{heading_to_enu_yaw(grid_heading)};
318
319 tf2::Quaternion quat_tf;
320 quat_tf.setRPY(0, 0, remove_units(units::angle::radian_t{enu_yaw}));
321 detection.pose.pose.orientation = tf2::toMsg(quat_tf);
322
323 try {
324 // Pose covariance is flattened 6x6 matrix with rows/columns of x, y, z, roll, pitch, yaw
325 detection.pose.covariance.at(35) =
326 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.heading_conf).value(), 2);
327 } catch (const std::bad_optional_access &) {
328 throw std::runtime_error("missing heading confidence");
329 }
330
331 const auto speed{Speed::from_msg(common_data.speed)};
332 detection.twist.twist.linear.x =
333 remove_units(units::velocity::meters_per_second_t{speed.speed});
334
335 const auto speed_z{Speed::from_msg(common_data.speed_z)};
336 detection.twist.twist.linear.z =
337 remove_units(units::velocity::meters_per_second_t{speed_z.speed});
338
339 try {
340 // Twist covariance is flattened 6x6 matrix with rows/columns of x, y, z, roll, pitch, yaw
341 detection.twist.covariance.at(0) =
342 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.speed_confidence).value(), 2);
343 } catch (const std::bad_optional_access &) {
344 throw std::runtime_error("missing speed confidence");
345 }
346
347 try {
348 detection.twist.covariance.at(14) =
349 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.speed_confidence_z).value(), 2);
350 } catch (const std::bad_optional_access &) {
351 throw std::runtime_error("missing z-speed confidence");
352 }
353
354 const auto accel_set{AccelerationSet4Way::from_msg(common_data.accel_4_way)};
355 detection.twist.twist.angular.z =
356 remove_units(units::angular_velocity::degrees_per_second_t{accel_set.yaw_rate});
357
358 try {
359 detection.twist.covariance.at(35) =
360 0.5 * std::pow(j2735_v2x_msgs::to_double(common_data.acc_cfd_yaw).value(), 2);
361 } catch (const std::bad_optional_access &) {
362 throw std::runtime_error("missing yaw-rate confidence");
363 }
364
365 switch (common_data.obj_type.object_type) {
366 case common_data.obj_type.ANIMAL:
367 detection.motion_model = detection.MOTION_MODEL_CTRV;
368 // We don't have a good semantic class mapping for animals
369 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
370 break;
371 case common_data.obj_type.VRU:
372 detection.motion_model = detection.MOTION_MODEL_CTRV;
373 detection.semantic_class = detection.SEMANTIC_CLASS_PEDESTRIAN;
374 break;
375 case common_data.obj_type.VEHICLE:
376 detection.motion_model = detection.MOTION_MODEL_CTRV;
377 detection.semantic_class = detection.SEMANTIC_CLASS_SMALL_VEHICLE;
378 break;
379 default:
380 detection.motion_model = detection.MOTION_MODEL_CTRV;
381 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
382 }
383
384 detection_list.detections.push_back(std::move(detection));
385 }
386
387 return detection_list;
388}
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 ned_to_enu(const PositionOffsetXYZ &offset_ned) noexcept
auto to_time_msg(const DDateTime &d_date_time) -> builtin_interfaces::msg::Time
auto heading_to_enu_yaw(const units::angle::degree_t &heading) -> units::angle::degree_t

References calc_detection_time_stamp(), calculate_grid_convergence(), 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 390 of file msg_conversion.cpp.

394{
396
397 detection.header = object.header;
398
399 if (object.presence_vector & object.BSM_ID_PRESENCE_VECTOR) {
400 detection.id = "";
401 std::transform(
402 std::cbegin(object.bsm_id), std::cend(object.bsm_id), std::back_inserter(detection.id),
403 [](const auto & i) { return i + '0'; });
404 }
405
406 if (object.presence_vector & object.ID_PRESENCE_VECTOR) {
407 detection.id += '-' + std::to_string(object.id);
408 }
409
410 if (object.presence_vector & object.POSE_PRESENCE_VECTOR) {
411 detection.pose = object.pose;
412 }
413
414 if (object.presence_vector & object.VELOCITY_PRESENCE_VECTOR) {
415 detection.twist = object.velocity;
416 }
417
418 if (object.presence_vector & object.OBJECT_TYPE_PRESENCE_VECTOR) {
419 switch (object.object_type) {
420 case object.SMALL_VEHICLE:
421 detection.motion_model = motion_model_mapping.small_vehicle_model;
422 detection.semantic_class = detection.SEMANTIC_CLASS_SMALL_VEHICLE;
423 break;
424 case object.LARGE_VEHICLE:
425 detection.motion_model = motion_model_mapping.large_vehicle_model;
426 detection.semantic_class = detection.SEMANTIC_CLASS_LARGE_VEHICLE;
427 break;
428 case object.MOTORCYCLE:
429 detection.motion_model = motion_model_mapping.motorcycle_model;
430 detection.semantic_class = detection.SEMANTIC_CLASS_MOTORCYCLE;
431 break;
432 case object.PEDESTRIAN:
433 detection.motion_model = motion_model_mapping.pedestrian_model;
434 detection.semantic_class = detection.SEMANTIC_CLASS_PEDESTRIAN;
435 break;
436 case object.UNKNOWN:
437 default:
438 detection.motion_model = motion_model_mapping.unknown_model;
439 detection.semantic_class = detection.SEMANTIC_CLASS_UNKNOWN;
440 }
441 }
442
443 return detection;
444}

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 534 of file msg_conversion.cpp.

537{
538 carma_perception_msgs::msg::ExternalObjectList external_object_list;
539
540 for (const auto & track : track_list.tracks) {
541 external_object_list.objects.push_back(to_external_object_msg(track));
542 }
543
544 return external_object_list;
545}
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 463 of file msg_conversion.cpp.

465{
466 carma_perception_msgs::msg::ExternalObject external_object;
467 external_object.header = track.header;
468 external_object.presence_vector = 0;
469
470 const auto to_numeric_id = [](std::string string_id) -> std::optional<uint32_t> {
471 auto non_digit_start = std::remove_if(
472 std::begin(string_id), std::end(string_id),
473 [](const auto & ch) { return !std::isdigit(ch); });
474
475 std::uint32_t numeric_id;
476 const auto digit_substr_size{std::distance(std::begin(string_id), non_digit_start)};
477 if (
478 std::from_chars(string_id.c_str(), string_id.c_str() + digit_substr_size, numeric_id).ec ==
479 std::errc{}) {
480 return numeric_id;
481 }
482
483 return std::nullopt;
484 };
485
486 if (const auto numeric_id{to_numeric_id(track.id)}) {
487 external_object.presence_vector |= external_object.ID_PRESENCE_VECTOR;
488 external_object.id = numeric_id.value();
489 } else {
490 external_object.presence_vector &= ~external_object.ID_PRESENCE_VECTOR;
491 }
492
493 external_object.presence_vector |= external_object.POSE_PRESENCE_VECTOR;
494 external_object.pose = track.pose;
495
496 external_object.presence_vector |= external_object.VELOCITY_PRESENCE_VECTOR;
497
498 const auto track_longitudinal_velocity{track.twist.twist.linear.x};
499 const auto track_orientation = track.pose.pose.orientation;
500
501 tf2::Quaternion q(
502 track_orientation.x, track_orientation.y, track_orientation.z, track_orientation.w);
503 tf2::Matrix3x3 m(q);
504 double roll, pitch, yaw;
505 m.getRPY(roll, pitch, yaw);
506
507 external_object.velocity.twist.linear.x = track_longitudinal_velocity * std::cos(yaw);
508 external_object.velocity.twist.linear.y = track_longitudinal_velocity * std::sin(yaw);
509
510 external_object.object_type = track.semantic_class;
511
512 external_object.presence_vector |= external_object.OBJECT_TYPE_PRESENCE_VECTOR;
513 switch (track.semantic_class) {
514 case track.SEMANTIC_CLASS_SMALL_VEHICLE:
515 external_object.object_type = external_object.SMALL_VEHICLE;
516 break;
517 case track.SEMANTIC_CLASS_LARGE_VEHICLE:
518 external_object.object_type = external_object.LARGE_VEHICLE;
519 break;
520 case track.SEMANTIC_CLASS_MOTORCYCLE:
521 external_object.object_type = external_object.MOTORCYCLE;
522 break;
523 case track.SEMANTIC_CLASS_PEDESTRIAN:
524 external_object.object_type = external_object.PEDESTRIAN;
525 break;
526 case track.SEMANTIC_CLASS_UNKNOWN:
527 default:
528 external_object.object_type = external_object.UNKNOWN;
529 }
530
531 return external_object;
532}

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 166 of file msg_conversion.cpp.

167{
168 geometry_msgs::msg::Point msg;
169
170 msg.x = remove_units(position_map.easting);
171 msg.y = remove_units(position_map.northing);
172 msg.z = remove_units(position_map.elevation);
173
174 return msg;
175}

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 155 of file msg_conversion.cpp.

156{
157 geometry_msgs::msg::Point msg;
158
159 msg.x = remove_units(position_utm.easting);
160 msg.y = remove_units(position_utm.northing);
161 msg.z = remove_units(position_utm.elevation);
162
163 return msg;
164}

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 547 of file msg_conversion.cpp.

552{
553 carma_v2x_msgs::msg::SensorDataSharingMessage sdsm;
554 carma_v2x_msgs::msg::DetectedObjectList detected_object_list;
555
556 sdsm.sdsm_time_stamp = to_ddate_time_msg(external_object_list.header.stamp);
557
558 sdsm.ref_pos = transform_pose_from_map_to_wgs84(current_pose, map_projection);
559
560 // Convert external objects within the list to detected_object_data
561 for (const auto & external_object : external_object_list.objects) {
562 auto sdsm_detected_object = to_detected_object_data_msg(external_object, map_projection);
563
564 // Calculate the time offset between individual objects and the respective SDSM container msg
565 sdsm_detected_object.detected_object_common_data.measurement_time =
566 calc_sdsm_time_offset(external_object.header.stamp, external_object.header.stamp);
567
568 // Calculate the position offset from the current reference pose (in m)
569 sdsm_detected_object.detected_object_common_data.pos =
570 calc_relative_position(current_pose, sdsm_detected_object.detected_object_common_data.pos);
571
572 detected_object_list.detected_object_data.push_back(sdsm_detected_object);
573 }
574
575 std::vector<uint8_t> id = {0x00, 0x00, 0x00, 0x01};
576 sdsm.source_id.id = id;
577 sdsm.equipment_type.equipment_type = j3224_v2x_msgs::msg::EquipmentType::OBU;
578 sdsm.ref_pos_xy_conf.semi_major = j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_UNAVAILABLE;
579 sdsm.ref_pos_xy_conf.semi_minor = j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_UNAVAILABLE;
580 sdsm.ref_pos_xy_conf.orientation = j2735_v2x_msgs::msg::PositionalAccuracy::ACCURACY_ORIENTATION_UNAVAILABLE;
581 sdsm.objects = detected_object_list;
582
583 return sdsm;
584}
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()

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(), platoon_strategic_ihp::PlatoonManager::changeFromFollowerToLeader(), mobilitypath_publisher::MobilityPathPublication::compose_mobility_header(), lci_strategic_plugin::LCIStrategicPlugin::composeIntersectionTransitMessage(), sci_strategic_plugin::SCIStrategicPlugin::composeIntersectionTransitMessage(), mobilitypath_visualizer::MobilityPathVisualizer::composeLabelMarker(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::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(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::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(), lci_strategic_plugin::LCIStrategicPlugin::extractInitialState(), sci_strategic_plugin::SCIStrategicPlugin::extractInitialState(), stop_and_dwell_strategic_plugin::StopAndDwellStrategicPlugin::extractInitialState(), yield_plugin::YieldPlugin::generate_JMT_trajectory(), approaching_emergency_vehicle_plugin::ApproachingEmergencyVehiclePlugin::generateApproachingErvStatusMessage(), lci_strategic_plugin::LCIStrategicPlugin::generateMobilityOperation(), sci_strategic_plugin::SCIStrategicPlugin::generateMobilityOperation(), 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(), lci_strategic_plugin::LCIStrategicPlugin::handleFailureCaseHelper(), lci_strategic_plugin::LCIStrategicPlugin::handleGreenSignalScenario(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::is_lanechange_possible(), yield_plugin::YieldPlugin::is_object_behind_vehicle(), plan_delegator::PlanDelegator::isManeuverExpired(), make_detection(), carma_wm::CARMAWorldModel::min_end_time_converter_minute_of_year(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_op_cb_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_op_cb_preparetojoin(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leadwithoperation(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::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::planTrajectoryCB(), lci_strategic_plugin::LCIStrategicPlugin::planWhenAPPROACHING(), lci_strategic_plugin::LCIStrategicPlugin::planWhenWAITING(), carma_wm::CARMAWorldModel::pointFromRouteTrackPos(), lci_strategic_plugin::LCIStrategicPlugin::print_params(), carma_wm::CARMAWorldModel::processSpatFromMsg(), project_to_utm(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_follower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_aborting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::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(), to_detection_list_msg(), to_detection_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(), and lci_strategic_plugin::LCIStrategicPlugin::validLightState().

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) -> builtin_interfaces::msg::Time

Definition at line 58 of file msg_conversion.cpp.

59{
60 double seconds;
61 const auto fractional_secs{std::modf(
62 remove_units(units::time::second_t{d_date_time.hour.value_or(units::time::second_t{0.0})}) +
63 remove_units(units::time::second_t{d_date_time.minute.value_or(units::time::second_t{0.0})}) +
64 remove_units(units::time::second_t{d_date_time.second.value_or(units::time::second_t{0.0})}),
65 &seconds)};
66
67 builtin_interfaces::msg::Time msg;
68 msg.sec = static_cast<std::int32_t>(seconds);
69 msg.nanosec = static_cast<std::int32_t>(fractional_secs * 1e9);
70
71 return msg;
72}
std::optional< units::time::hour_t > hour
Definition: j2735_types.hpp:41
std::optional< units::time::minute_t > minute
Definition: j2735_types.hpp:42
std::optional< units::time::second_t > second
Definition: j2735_types.hpp:43

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 227 of file msg_conversion.cpp.

231{
232 carma_v2x_msgs::msg::Position3D ref_pos;
233 lanelet::BasicPoint3d source_pose_basicpoint{
234 source_pose.pose.position.x, source_pose.pose.position.y, 0.0};
235
236 lanelet::GPSPoint wgs84_ref_pose = map_projection->reverse(source_pose_basicpoint);
237
238 ref_pos.longitude = wgs84_ref_pose.lon;
239 ref_pos.latitude = wgs84_ref_pose.lat;
240 ref_pos.elevation = wgs84_ref_pose.ele;
241 ref_pos.elevation_exists = true;
242
243 return ref_pos;
244}

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 232 of file month.hpp.

◆ August

constexpr Month carma_cooperative_perception::August {8}
inlineconstexpr

Definition at line 236 of file month.hpp.

◆ December

constexpr Month carma_cooperative_perception::December {12}
inlineconstexpr

Definition at line 240 of file month.hpp.

◆ February

constexpr Month carma_cooperative_perception::February {2}
inlineconstexpr

Definition at line 230 of file month.hpp.

◆ January

constexpr Month carma_cooperative_perception::January {1}
inlineconstexpr

Definition at line 229 of file month.hpp.

◆ July

constexpr Month carma_cooperative_perception::July {7}
inlineconstexpr

Definition at line 235 of file month.hpp.

◆ June

constexpr Month carma_cooperative_perception::June {6}
inlineconstexpr

Definition at line 234 of file month.hpp.

◆ March

constexpr Month carma_cooperative_perception::March {3}
inlineconstexpr

Definition at line 231 of file month.hpp.

◆ May

constexpr Month carma_cooperative_perception::May {5}
inlineconstexpr

Definition at line 233 of file month.hpp.

◆ November

constexpr Month carma_cooperative_perception::November {11}
inlineconstexpr

Definition at line 239 of file month.hpp.

◆ October

constexpr Month carma_cooperative_perception::October {10}
inlineconstexpr

Definition at line 238 of file month.hpp.

◆ September

constexpr Month carma_cooperative_perception::September {9}
inlineconstexpr

Definition at line 237 of file month.hpp.