17#include <rclcpp_components/register_node_macro.hpp>
28 carma_cooperative_perception_interfaces::msg::DetectionList detection_list,
29 const std::string & map_origin) -> carma_cooperative_perception_interfaces::msg::DetectionList
31 gsl::owner<PJ_CONTEXT *> context = proj_context_create();
32 proj_log_level(context, PJ_LOG_NONE);
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 +
'.');
39 gsl::owner<PJ *> map_transformation = proj_create(context, map_origin.c_str());
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 +
'.');
47 std::vector<carma_cooperative_perception_interfaces::msg::Detection> new_detections;
48 for (
auto detection : detection_list.detections) {
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)};
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}};
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);
64 new_detections.push_back(std::move(detection));
67 std::swap(detection_list.detections, new_detections);
69 proj_destroy(map_transformation);
70 proj_context_destroy(context);
72 return detection_list;
76 const rclcpp::NodeOptions & options)
77: CarmaLifecycleNode{options}
84 const rclcpp_lifecycle::State & ) -> carma_ros2_utils::CallbackReturn
86 publisher_ = create_publisher<output_msg_type>(
"output/detections", 1);
88 external_objects_subscription_ = create_subscription<input_msg_type>(
90 const auto current_state{this->get_current_state().label()};
92 if (current_state ==
"active") {
93 publish_as_detection_list(*msg_ptr);
97 "Trying to receive message on the topic '%s', but the containing node is not activated. "
98 "Current node state: '%s'",
99 this->external_objects_subscription_->get_topic_name(), current_state.c_str());
103 georeference_subscription_ = create_subscription<std_msgs::msg::String>(
104 "input/georeference", 1, [
this](std_msgs::msg::String::SharedPtr msg_ptr) {
105 const auto current_state{this->get_current_state().label()};
107 if (current_state ==
"active") {
108 update_georeference(*msg_ptr);
112 "Trying to receive message on the topic '%s', but the containing node is not activated. "
113 "Current node state: '%s'",
114 this->georeference_subscription_->get_topic_name(), current_state.c_str());
118 on_set_parameters_callback_ =
119 add_on_set_parameters_callback([
this](
const std::vector<rclcpp::Parameter> & parameters) {
120 rcl_interfaces::msg::SetParametersResult result;
121 result.successful =
true;
122 result.reason =
"success";
124 for (
const auto & parameter : parameters) {
125 if (parameter.get_name() ==
"small_vehicle_motion_model") {
126 this->motion_model_mapping_.small_vehicle_model =
127 static_cast<std::uint8_t>(parameter.as_int());
128 }
else if (parameter.get_name() ==
"large_vehicle_motion_model") {
129 this->motion_model_mapping_.large_vehicle_model =
130 static_cast<std::uint8_t>(parameter.as_int());
131 }
else if (parameter.get_name() ==
"motorcycle_motion_model") {
132 this->motion_model_mapping_.motorcycle_model =
133 static_cast<std::uint8_t>(parameter.as_int());
134 }
else if (parameter.get_name() ==
"pedestrian_motion_model") {
135 this->motion_model_mapping_.pedestrian_model =
136 static_cast<std::uint8_t>(parameter.as_int());
137 }
else if (parameter.get_name() ==
"unknown_motion_model") {
138 this->motion_model_mapping_.unknown_model = static_cast<std::uint8_t>(parameter.as_int());
140 result.successful = false;
141 result.reason =
"Unexpected parameter name '" + parameter.get_name() +
'\'';
155 declare_parameter(
"small_vehicle_motion_model", motion_model_mapping_.small_vehicle_model);
156 declare_parameter(
"large_vehicle_motion_model", motion_model_mapping_.large_vehicle_model);
157 declare_parameter(
"motorcycle_motion_model", motion_model_mapping_.motorcycle_model);
158 declare_parameter(
"pedestrian_motion_model", motion_model_mapping_.pedestrian_model);
159 declare_parameter(
"unknown_motion_model", motion_model_mapping_.unknown_model);
161 return carma_ros2_utils::CallbackReturn::SUCCESS;
165 const rclcpp_lifecycle::State & ) -> carma_ros2_utils::CallbackReturn
168 external_objects_subscription_.reset();
169 georeference_subscription_.reset();
171 return carma_ros2_utils::CallbackReturn::SUCCESS;
175 const rclcpp_lifecycle::State & ) -> carma_ros2_utils::CallbackReturn
178 external_objects_subscription_.reset();
179 georeference_subscription_.reset();
181 return carma_ros2_utils::CallbackReturn::SUCCESS;
189 }
catch (
const std::invalid_argument & e) {
191 this->get_logger(),
"Could not convert external object list to detection list: %s", e.what());
198 map_georeference_ = msg.data;
207RCLCPP_COMPONENTS_REGISTER_NODE(
auto handle_on_cleanup(const rclcpp_lifecycle::State &) -> carma_ros2_utils::CallbackReturn override
auto handle_on_configure(const rclcpp_lifecycle::State &) -> carma_ros2_utils::CallbackReturn override
auto update_georeference(const std_msgs::msg::String &msg) -> void
auto handle_on_shutdown(const rclcpp_lifecycle::State &) -> carma_ros2_utils::CallbackReturn override
carma_perception_msgs::msg::ExternalObjectList input_msg_type
OnSetParametersCallbackHandle::SharedPtr on_set_parameters_callback_
typename input_msg_type::SharedPtr input_msg_shared_pointer
rclcpp_lifecycle::LifecyclePublisher< output_msg_type >::SharedPtr publisher_
ExternalObjectListToDetectionListNode(const rclcpp::NodeOptions &options)
auto publish_as_detection_list(const input_msg_type &msg) const -> void
auto to_detection_list_msg(const carma_v2x_msgs::msg::SensorDataSharingMessage &sdsm, std::string_view georeference) -> carma_cooperative_perception_interfaces::msg::DetectionList
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
auto to_string(const UtmZone &zone) -> std::string
auto calculate_utm_zone(const Wgs84Coordinate &coordinate) -> UtmZone
Get the UTM zone number from a WGS-84 coordinate.
constexpr auto remove_units(const T &value)
auto project_to_utm(const Wgs84Coordinate &coordinate) -> UtmCoordinate
Projects a Wgs84Coordinate to its corresponding UTM zone.
Represents a position using WGS-84 coordinates.