Skip to content

Commit fced520

Browse files
committed
Refactor fusion_node.hpp and fusion_node.cpp for improved code organization and readability
1 parent 93d0e00 commit fced520

File tree

2 files changed

+40
-45
lines changed

2 files changed

+40
-45
lines changed

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_node.hpp

+4-9
Original file line numberDiff line numberDiff line change
@@ -131,28 +131,23 @@ class FusionNode : public rclcpp::Node
131131
// camera_info
132132
std::vector<Det2dManager<Msg2D>> det2d_list_;
133133

134-
std::vector<rclcpp::Subscription<sensor_msgs::msg::CameraInfo>::SharedPtr> camera_info_subs_;
135134
// camera projection
136-
137135
float approx_grid_cell_w_size_;
138136
float approx_grid_cell_h_size_;
139137

138+
// timer
140139
rclcpp::TimerBase::SharedPtr timer_;
141140
double timeout_ms_{};
142141
double match_threshold_ms_{};
143142

144143
/** \brief A vector of subscriber. */
145144
typename rclcpp::Subscription<TargetMsg3D>::SharedPtr sub_;
146145
std::vector<typename rclcpp::Subscription<Msg2D>::SharedPtr> rois_subs_;
147-
148-
// offsets between cameras and the lidars
149-
std::vector<double> input_offset_ms_;
146+
std::vector<rclcpp::Subscription<sensor_msgs::msg::CameraInfo>::SharedPtr> camera_info_subs_;
150147

151148
// cache for fusion
152-
std::vector<bool> is_fused_;
153-
std::pair<int64_t, typename TargetMsg3D::SharedPtr>
154-
cached_msg_; // first element is the timestamp in nanoseconds, second element is the message
155-
std::vector<std::map<int64_t, typename Msg2D::ConstSharedPtr>> cached_det2d_msgs_;
149+
int64_t cached_det3d_msg_timestamp_;
150+
typename TargetMsg3D::SharedPtr cached_det3d_msg_ptr_;
156151
std::mutex mutex_cached_msgs_;
157152

158153
// output publisher

perception/autoware_image_projection_based_fusion/src/fusion_node.cpp

+36-36
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@ FusionNode<TargetMsg3D, ObjType, Msg2D>::FusionNode(
8383
"/sensing/camera/camera" + std::to_string(roi_i) + "/camera_info");
8484
}
8585

86-
input_offset_ms_ = declare_parameter<std::vector<double>>("input_offset_ms");
87-
if (!input_offset_ms_.empty() && rois_number_ > input_offset_ms_.size()) {
88-
throw std::runtime_error("The number of offsets does not match the number of topics.");
89-
}
90-
91-
// sub camera info
86+
// subscribe camera info
9287
camera_info_subs_.resize(rois_number_);
9388
for (std::size_t roi_i = 0; roi_i < rois_number_; ++roi_i) {
9489
std::function<void(const sensor_msgs::msg::CameraInfo::ConstSharedPtr msg)> fnc =
@@ -97,18 +92,16 @@ FusionNode<TargetMsg3D, ObjType, Msg2D>::FusionNode(
9792
input_camera_info_topics.at(roi_i), rclcpp::QoS{1}.best_effort(), fnc);
9893
}
9994

100-
// sub rois
95+
// subscribe rois
10196
rois_subs_.resize(rois_number_);
102-
cached_det2d_msgs_.resize(rois_number_);
103-
is_fused_.resize(rois_number_, false);
10497
for (std::size_t roi_i = 0; roi_i < rois_number_; ++roi_i) {
10598
std::function<void(const typename Msg2D::ConstSharedPtr msg)> roi_callback =
10699
std::bind(&FusionNode::roiCallback, this, std::placeholders::_1, roi_i);
107100
rois_subs_.at(roi_i) = this->create_subscription<Msg2D>(
108101
input_rois_topics.at(roi_i), rclcpp::QoS{1}.best_effort(), roi_callback);
109102
}
110103

111-
// subscribers
104+
// subscribe 3d detection
112105
std::function<void(const typename TargetMsg3D::ConstSharedPtr msg)> sub_callback =
113106
std::bind(&FusionNode::subCallback, this, std::placeholders::_1);
114107
sub_ =
@@ -123,8 +116,11 @@ FusionNode<TargetMsg3D, ObjType, Msg2D>::FusionNode(
123116
timer_ = rclcpp::create_timer(
124117
this, get_clock(), period_ns, std::bind(&FusionNode::timer_callback, this));
125118

126-
// camera manager initialization
127-
det2d_list_.resize(rois_number_);
119+
// camera offset settings
120+
std::vector<double> input_offset_ms = declare_parameter<std::vector<double>>("input_offset_ms");
121+
if (!input_offset_ms.empty() && rois_number_ > input_offset_ms.size()) {
122+
throw std::runtime_error("The number of offsets does not match the number of topics.");
123+
}
128124

129125
// camera projection settings
130126
std::vector<bool> point_project_to_unrectified_image =
@@ -150,16 +146,19 @@ FusionNode<TargetMsg3D, ObjType, Msg2D>::FusionNode(
150146
}
151147
}
152148
}
149+
approx_grid_cell_w_size_ = declare_parameter<float>("approximation_grid_cell_width");
150+
approx_grid_cell_h_size_ = declare_parameter<float>("approximation_grid_cell_height");
151+
152+
// camera manager initialization
153+
det2d_list_.resize(rois_number_);
153154
for (std::size_t roi_i = 0; roi_i < rois_number_; ++roi_i) {
154155
det2d_list_.at(roi_i).id = roi_i;
155156
det2d_list_.at(roi_i).project_to_unrectified_image =
156157
point_project_to_unrectified_image.at(roi_i);
157158
det2d_list_.at(roi_i).approximate_camera_projection = approx_camera_projection.at(roi_i);
159+
det2d_list_.at(roi_i).input_offset_ms = input_offset_ms.at(roi_i);
158160
}
159161

160-
approx_grid_cell_w_size_ = declare_parameter<float>("approximation_grid_cell_width");
161-
approx_grid_cell_h_size_ = declare_parameter<float>("approximation_grid_cell_height");
162-
163162
// debugger
164163
if (declare_parameter("debug_mode", false)) {
165164
std::vector<std::string> input_camera_topics;
@@ -231,16 +230,16 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::exportProcess()
231230
{
232231
timer_->cancel();
233232

234-
postprocess(*(cached_msg_.second));
235-
publish(*(cached_msg_.second));
233+
postprocess(*(cached_det3d_msg_ptr_));
234+
publish(*(cached_det3d_msg_ptr_));
236235

237236
// add processing time for debug
238237
if (debug_publisher_) {
239238
const double cyclic_time_ms = stop_watch_ptr_->toc("cyclic_time", true);
240239
const double pipeline_latency_ms =
241240
std::chrono::duration<double, std::milli>(
242241
std::chrono::nanoseconds(
243-
(this->get_clock()->now() - cached_msg_.second->header.stamp).nanoseconds()))
242+
(this->get_clock()->now() - cached_det3d_msg_ptr_->header.stamp).nanoseconds()))
244243
.count();
245244
debug_publisher_->publish<tier4_debug_msgs::msg::Float64Stamped>(
246245
"debug/cyclic_time_ms", cyclic_time_ms);
@@ -256,19 +255,19 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::exportProcess()
256255
for (auto & det_2d : det2d_list_) {
257256
det_2d.is_fused = false;
258257
}
259-
cached_msg_.second = nullptr;
258+
cached_det3d_msg_ptr_ = nullptr;
260259
}
261260

262261
template <class TargetMsg3D, class Obj, class Msg2D>
263262
void FusionNode<TargetMsg3D, Obj, Msg2D>::subCallback(
264-
const typename TargetMsg3D::ConstSharedPtr input_msg)
263+
const typename TargetMsg3D::ConstSharedPtr det3d_msg)
265264
{
266265
std::unique_ptr<ScopedTimeTrack> st_ptr;
267266
if (time_keeper_) st_ptr = std::make_unique<ScopedTimeTrack>(__func__, *time_keeper_);
268267

269268
std::lock_guard<std::mutex> lock(mutex_cached_msgs_);
270269

271-
if (cached_msg_.second != nullptr) {
270+
if (cached_det3d_msg_ptr_ != nullptr) {
272271
// PROCESS: if the main message is remained (and roi is not collected all) publish the main
273272
// message may processed partially with arrived 2d rois
274273
stop_watch_ptr_->toc("processing_time", true);
@@ -289,7 +288,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::subCallback(
289288
stop_watch_ptr_->toc("processing_time", true);
290289

291290
// PROCESS: preprocess the main message
292-
typename TargetMsg3D::SharedPtr output_msg = std::make_shared<TargetMsg3D>(*input_msg);
291+
typename TargetMsg3D::SharedPtr output_msg = std::make_shared<TargetMsg3D>(*det3d_msg);
293292
preprocess(*output_msg);
294293

295294
// PROCESS: fuse the main message with the cached roi messages
@@ -338,7 +337,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::subCallback(
338337
debugger_->clear();
339338
}
340339

341-
fuseOnSingleImage(*input_msg, roi_i, *(roi_msgs[matched_stamp]), *output_msg);
340+
fuseOnSingleImage(*det3d_msg, roi_i, *(roi_msgs[matched_stamp]), *output_msg);
342341
roi_msgs.erase(matched_stamp);
343342
det_2d.is_fused = true;
344343

@@ -353,8 +352,8 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::subCallback(
353352
}
354353
}
355354
}
356-
cached_msg_.first = timestamp_nsec;
357-
cached_msg_.second = output_msg;
355+
cached_det3d_msg_timestamp_ = timestamp_nsec;
356+
cached_det3d_msg_ptr_ = output_msg;
358357

359358
// PROCESS: if all camera fused, postprocess and publish the main message
360359
if (checkAllDet2dFused(det2d_list_)) {
@@ -368,7 +367,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::subCallback(
368367

369368
template <class TargetMsg3D, class Obj, class Msg2D>
370369
void FusionNode<TargetMsg3D, Obj, Msg2D>::roiCallback(
371-
const typename Msg2D::ConstSharedPtr input_roi_msg, const std::size_t roi_i)
370+
const typename Msg2D::ConstSharedPtr det2d_msg, const std::size_t roi_i)
372371
{
373372
std::unique_ptr<ScopedTimeTrack> st_ptr;
374373
if (time_keeper_) st_ptr = std::make_unique<ScopedTimeTrack>(__func__, *time_keeper_);
@@ -377,12 +376,13 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::roiCallback(
377376

378377
auto & det_2d = det2d_list_.at(roi_i);
379378

380-
int64_t timestamp_nsec = (*input_roi_msg).header.stamp.sec * static_cast<int64_t>(1e9) +
381-
(*input_roi_msg).header.stamp.nanosec;
379+
int64_t timestamp_nsec =
380+
(*det2d_msg).header.stamp.sec * static_cast<int64_t>(1e9) + (*det2d_msg).header.stamp.nanosec;
382381

383382
// if cached Msg exist, try to match
384-
if (cached_msg_.second != nullptr) {
385-
int64_t new_stamp = cached_msg_.first + det_2d.input_offset_ms * static_cast<int64_t>(1e6);
383+
if (cached_det3d_msg_ptr_ != nullptr) {
384+
int64_t new_stamp =
385+
cached_det3d_msg_timestamp_ + det_2d.input_offset_ms * static_cast<int64_t>(1e6);
386386
int64_t interval = abs(timestamp_nsec - new_stamp);
387387

388388
// PROCESS: if matched, fuse the main message with the roi message
@@ -391,19 +391,19 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::roiCallback(
391391
if (det_2d.camera_projector_ptr == nullptr) {
392392
RCLCPP_WARN_THROTTLE(
393393
this->get_logger(), *this->get_clock(), 5000, "no camera info. id is %zu", roi_i);
394-
(cached_det2d_msgs_.at(roi_i))[timestamp_nsec] = input_roi_msg;
394+
det_2d.cached_det2d_msgs[timestamp_nsec] = det2d_msg;
395395
return;
396396
}
397397

398398
if (debugger_) {
399399
debugger_->clear();
400400
}
401401
// PROCESS: fuse the main message with the roi message
402-
fuseOnSingleImage(*(cached_msg_.second), roi_i, *input_roi_msg, *(cached_msg_.second));
402+
fuseOnSingleImage(*(cached_det3d_msg_ptr_), roi_i, *det2d_msg, *(cached_det3d_msg_ptr_));
403403
det_2d.is_fused = true;
404404

405405
if (debug_publisher_) {
406-
double timestamp_interval_ms = (timestamp_nsec - cached_msg_.first) / 1e6;
406+
double timestamp_interval_ms = (timestamp_nsec - cached_det3d_msg_timestamp_) / 1e6;
407407
debug_publisher_->publish<tier4_debug_msgs::msg::Float64Stamped>(
408408
"debug/roi" + std::to_string(roi_i) + "/timestamp_interval_ms", timestamp_interval_ms);
409409
debug_publisher_->publish<tier4_debug_msgs::msg::Float64Stamped>(
@@ -421,7 +421,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::roiCallback(
421421
}
422422
}
423423
// store roi msg if not matched
424-
det_2d.cached_det2d_msgs[timestamp_nsec] = input_roi_msg;
424+
det_2d.cached_det2d_msgs[timestamp_nsec] = det2d_msg;
425425
}
426426

427427
template <class TargetMsg3D, class Obj, class Msg2D>
@@ -441,7 +441,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::timer_callback()
441441
timer_->cancel();
442442
if (mutex_cached_msgs_.try_lock()) {
443443
// PROCESS: if timeout, postprocess cached msg
444-
if (cached_msg_.second != nullptr) {
444+
if (cached_det3d_msg_ptr_ != nullptr) {
445445
stop_watch_ptr_->toc("processing_time", true);
446446
exportProcess();
447447
}
@@ -450,7 +450,7 @@ void FusionNode<TargetMsg3D, Obj, Msg2D>::timer_callback()
450450
for (auto & det_2d : det2d_list_) {
451451
det_2d.is_fused = false;
452452
}
453-
cached_msg_.second = nullptr;
453+
cached_det3d_msg_ptr_ = nullptr;
454454

455455
mutex_cached_msgs_.unlock();
456456
} else {

0 commit comments

Comments
 (0)