15#ifndef CARMA_COOPERATIVE_PERCEPTION__SDSM_TO_DETECTION_LIST_COMPONENT_HPP_
16#define CARMA_COOPERATIVE_PERCEPTION__SDSM_TO_DETECTION_LIST_COMPONENT_HPP_
20#include <carma_cooperative_perception_interfaces/msg/detection_list.hpp>
21#include <carma_ros2_utils/carma_lifecycle_node.hpp>
22#include <carma_v2x_msgs/msg/sensor_data_sharing_message.hpp>
23#include <rclcpp/rclcpp.hpp>
24#include <rosgraph_msgs/msg/clock.hpp>
25#include <std_msgs/msg/string.hpp>
36 using output_msg_type = carma_cooperative_perception_interfaces::msg::DetectionList;
40 -> carma_ros2_utils::CallbackReturn
override
71 [
this](
const std::vector<rclcpp::Parameter> & parameters) {
76 RCLCPP_INFO_STREAM(get_logger(),
"SdsmToDetectionListNode Configuration: " <<
config_);
78 return carma_ros2_utils::CallbackReturn::SUCCESS;
82 : CarmaLifecycleNode{options},
86 georeference_subscription_{create_subscription<std_msgs::msg::String>(
87 "input/georeference", 1,
88 [
this](std_msgs::msg::String::SharedPtr msg_ptr) { georeference_ = msg_ptr->data; })},
89 cdasim_clock_sub_{create_subscription<rosgraph_msgs::msg::Clock>(
90 "input/cdasim_clock", 1,
91 [
this](rosgraph_msgs::msg::Clock::ConstSharedPtr msg_ptr) { cdasim_time_ = msg_ptr->clock; })}
94 valid_parameter_names_ = {
95 "overwrite_covariance",
99 "pose_covariance_yaw",
100 "twist_covariance_x",
101 "twist_covariance_z",
102 "twist_covariance_yaw",
112 if (georeference_.empty()){
113 RCLCPP_WARN_STREAM(get_logger(),
"Georeference not defined yet, ignoring SDSM.");
118 std::optional<SdsmToDetectionListConfig> conversion_adjustment = std::nullopt;
119 if (config_.overwrite_covariance || config_.adjust_pose) {
120 conversion_adjustment = config_;
122 auto detection_list_msg{
124 conversion_adjustment)
129 const auto time_delta{now() - cdasim_time_.value()};
131 for (
auto & detection : detection_list_msg.detections) {
132 detection.header.stamp = rclcpp::Time(detection.header.stamp) + time_delta;
136 get_logger(),
"SDSM to detection list conversion: "
137 << detection_list_msg.detections.size() <<
" detections");
138 publisher_->publish(detection_list_msg);
139 }
catch (
const std::runtime_error & e) {
140 RCLCPP_ERROR_STREAM(get_logger(),
"Failed to convert SDSM to detection list: " << e.what());
150 std::optional<rclcpp::Time> cdasim_time_{std::nullopt};
152 std::string georeference_{
""};
157 OnSetParametersCallbackHandle::SharedPtr on_set_parameters_callback_{
nullptr};
161 const std::vector<rclcpp::Parameter> & parameters)
163 rcl_interfaces::msg::SetParametersResult result;
164 result.successful =
true;
165 result.reason =
"success";
167 for (
const auto & parameter : parameters) {
169 if (valid_parameter_names_.find(parameter.get_name()) == valid_parameter_names_.end()) {
170 result.successful =
false;
171 result.reason =
"Unexpected parameter name '" + parameter.get_name() +
"'";
172 RCLCPP_ERROR_STREAM(get_logger(),
"Cannot change parameter: " << result.reason);
177 if (parameter.get_name() !=
"adjust_pose" &&
178 parameter.get_name() !=
"overwrite_covariance") {
179 if (
const auto value{parameter.as_double()}; value < 0.0) {
180 result.successful =
false;
181 result.reason =
"Covariance parameter must be non-negative";
184 "Cannot change parameter '" << parameter.get_name() <<
"': " << result.reason);
188 update_config_double_parameter(parameter);
190 }
else if (parameter.get_name() ==
"overwrite_covariance"){
191 config_.overwrite_covariance = parameter.as_bool();
192 }
else if (parameter.get_name() ==
"adjust_pose"){
193 config_.adjust_pose = parameter.as_bool();
198 if (result.successful) {
199 RCLCPP_DEBUG_STREAM(get_logger(),
"Updated configuration: " << config_);
207 const std::string & name = parameter.get_name();
208 const double value = parameter.as_double();
210 if (name ==
"pose_covariance_x") {
211 config_.pose_covariance_x = value;
212 }
else if (name ==
"pose_covariance_y") {
213 config_.pose_covariance_y = value;
214 }
else if (name ==
"pose_covariance_z") {
215 config_.pose_covariance_z = value;
216 }
else if (name ==
"pose_covariance_yaw") {
217 config_.pose_covariance_yaw = value;
218 }
else if (name ==
"twist_covariance_x") {
219 config_.twist_covariance_x = value;
220 }
else if (name ==
"twist_covariance_z") {
221 config_.twist_covariance_z = value;
222 }
else if (name ==
"twist_covariance_yaw") {
223 config_.twist_covariance_yaw = value;
224 }
else if (name ==
"x_offset") {
225 config_.x_offset = value;
226 }
else if (name ==
"y_offset") {
227 config_.y_offset = value;
228 }
else if (name ==
"yaw_offset") {
229 config_.yaw_offset = value;
double twist_covariance_z
double pose_covariance_yaw
double twist_covariance_yaw
bool overwrite_covariance
double twist_covariance_x
void update_config_double_parameter(const rclcpp::Parameter ¶meter)
rclcpp::Subscription< input_msg_type >::SharedPtr subscription_
carma_cooperative_perception_interfaces::msg::DetectionList output_msg_type
rcl_interfaces::msg::SetParametersResult update_parameters(const std::vector< rclcpp::Parameter > ¶meters)
carma_v2x_msgs::msg::SensorDataSharingMessage input_msg_type
rclcpp::Subscription< std_msgs::msg::String >::SharedPtr georeference_subscription_
SdsmToDetectionListNode(const rclcpp::NodeOptions &options)
rclcpp::Publisher< output_msg_type >::SharedPtr publisher_
rclcpp::Subscription< rosgraph_msgs::msg::Clock >::SharedPtr cdasim_clock_sub_
auto handle_on_configure(const rclcpp_lifecycle::State &) -> carma_ros2_utils::CallbackReturn override
auto sdsm_msg_callback(const input_msg_type &msg) const -> void
OnSetParametersCallbackHandle::SharedPtr on_set_parameters_callback_
std::unordered_set< std::string > valid_parameter_names_
typename input_msg_type::SharedPtr input_msg_shared_pointer
SdsmToDetectionListConfig config_
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_inter...