Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(autoware_image_based_projection_fusion): redesign image based projection fusion node #10016

Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
68e1474
feat: initialize the new fusion algorithm
vividf Jan 24, 2025
1d58565
chore: fix constructor
vividf Jan 27, 2025
470f535
feat: add diagnostic updater
vividf Jan 29, 2025
057e1cc
feat: add automatic offset calculation
vividf Jan 30, 2025
5280d82
chore: pass rois_number as parameters
vividf Jan 31, 2025
15f506b
feat: timeout parameters for rois and msg3d
vividf Feb 3, 2025
cb277ef
chore: clean code
vividf Feb 5, 2025
9661ac8
feat: reuse collector
vividf Feb 6, 2025
0d16ab3
chore: rename variable
vividf Feb 6, 2025
58516e4
chore: load camera projector
vividf Feb 6, 2025
b1e9e9b
chore: remove double unlock and reset collector list when there are t…
vividf Feb 7, 2025
9959d76
feat: init collector list
vividf Feb 12, 2025
2dc3f62
chore: fix processing time record
vividf Feb 12, 2025
124848e
chore: fix naive logic
vividf Feb 12, 2025
a5d99b2
chore: clean code
vividf Feb 13, 2025
9769b0e
chore: add more description in readme
vividf Feb 20, 2025
b598ea3
Merge branch 'main' into feature/redesign_image_based_projection_node
vividf Feb 20, 2025
4b67499
chore: move dianositc after pub in concat
vividf Feb 20, 2025
08f2443
chore: fix spell errors
vividf Feb 20, 2025
fe091d5
chore: fix spelling error
vividf Feb 21, 2025
5cb0714
chore: fix readme
vividf Feb 21, 2025
ba69ed4
Merge branch 'main' into feature/redesign_image_based_projection_node
technolojin Feb 25, 2025
28778df
Merge branch 'main' into feature/redesign_image_based_projection_node
technolojin Feb 26, 2025
7f2d370
chore: update parameters
vividf Feb 26, 2025
d2a7a4c
Merge branch 'feature/redesign_image_based_projection_node' of github…
vividf Feb 26, 2025
8acfd30
chore: fix schema
vividf Feb 26, 2025
2e474de
chore: fix misleading variables
vividf Feb 26, 2025
42b01fb
chore: fix schema
vividf Feb 26, 2025
4265ffb
chore: add lidar camera sync image in readme
vividf Feb 26, 2025
c934f2d
Merge branch 'main' into feature/redesign_image_based_projection_node
vividf Feb 27, 2025
888be4c
style(pre-commit): autofix
pre-commit-ci[bot] Feb 27, 2025
60c2809
chore: add more explanation for readme
vividf Feb 27, 2025
842eabc
chore: update parameters
vividf Feb 27, 2025
0f4c027
chore: comment for parameters
vividf Feb 27, 2025
01b076b
chore: fix parameter setting mistake
vividf Feb 27, 2025
48e52af
chore: fix schema
vividf Feb 27, 2025
e1d1d8e
chore: fix schema
vividf Feb 27, 2025
f5172fc
style(pre-commit): autofix
pre-commit-ci[bot] Feb 27, 2025
27a967c
chore: fix schema
vividf Feb 27, 2025
e5e67c3
Merge branch 'feature/redesign_image_based_projection_node' of github…
vividf Feb 27, 2025
ac52b2f
chore: revert to previous topic
vividf Mar 3, 2025
9213beb
chore: fix logic for updating value in set
vividf Mar 3, 2025
3ba2da8
Merge branch 'main' into feature/redesign_image_based_projection_node
vividf Mar 3, 2025
010d748
chore: fix cpp check
vividf Mar 3, 2025
3f01fcf
Merge branch 'feature/redesign_image_based_projection_node' of github…
vividf Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ endif()
# Build non-CUDA dependent nodes
ament_auto_add_library(${PROJECT_NAME} SHARED
src/camera_projection.cpp
src/fusion_collector.cpp
src/fusion_matching_strategy.cpp
src/fusion_node.cpp
src/debugger.cpp
src/utils/geometry.cpp
Expand Down
246 changes: 202 additions & 44 deletions perception/autoware_image_projection_based_fusion/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/**:
ros__parameters:
input_offset_ms: [61.67, 111.67, 45.0, 28.33, 78.33, 95.0]
timeout_ms: 70.0
match_threshold_ms: 50.0
# Example of how to set offset parameters (Check the readme for more information), both lidar and camera run in 10 hz.
# msg3d's header timestamp: 0.000
# rois's header timestamp (camera 0-5): 0.059, 0.010, 0.026, 0.042, 0.076, 0.093
# offset = rois_timestamp- msg3d_timestamp
rois_timestamp_offsets: [0.059, 0.010, 0.026, 0.042, 0.076, 0.093]
rois_timeout_sec: 0.5
msg3d_timeout_sec: 0.05
image_buffer_size: 15
# projection setting for each ROI whether unrectify image
point_project_to_unrectified_image: [false, false, false, false, false, false]
debug_mode: false
filter_scope_min_x: -100.0
filter_scope_min_y: -100.0
filter_scope_min_z: -100.0
Expand All @@ -21,4 +24,16 @@
approximation_grid_cell_height: 1.0

# debug parameters
debug_mode: false
collector_debug_mode: false
publish_processing_time_detail: false

publish_previous_but_late_output_msg: false
rosbag_length: 10.0
# matching strategy
matching_strategy:
type: advanced
msg3d_noise_window: 0.02
rois_timestamp_noise_window: [0.01, 0.01, 0.01, 0.01, 0.01, 0.01]
# type: naive
# threshold: 0.05
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2025 TIER IV, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "autoware/image_projection_based_fusion/camera_projection.hpp"

#include <rclcpp/rclcpp.hpp>

#include <cstddef>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <vector>

namespace autoware::image_projection_based_fusion
{
using autoware::image_projection_based_fusion::CameraProjection;

template <class Msg3D, class Msg2D, class ExportObj>
class FusionNode;

template <class Msg2D>
struct Det2dStatus

Check warning on line 35 in perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp

View check run for this annotation

Codecov / codecov/patch

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp#L35

Added line #L35 was not covered by tests
{
// camera index
std::size_t id{0};
// camera projection
std::shared_ptr<CameraProjection> camera_projector_ptr{nullptr};
bool project_to_unrectified_image{false};
bool approximate_camera_projection{false};
};

struct FusionCollectorInfoBase
{
virtual ~FusionCollectorInfoBase() = default;
};

struct NaiveCollectorInfo : public FusionCollectorInfoBase
{
double timestamp;
double threshold;

explicit NaiveCollectorInfo(double timestamp = 0.0, double threshold = 0.0)
: timestamp(timestamp), threshold(threshold)

Check warning on line 56 in perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp

View check run for this annotation

Codecov / codecov/patch

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp#L56

Added line #L56 was not covered by tests
{
}
};

struct AdvancedCollectorInfo : public FusionCollectorInfoBase
{
double timestamp;
double noise_window;

explicit AdvancedCollectorInfo(double timestamp = 0.0, double noise_window = 0.0)
: timestamp(timestamp), noise_window(noise_window)

Check warning on line 67 in perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp

View check run for this annotation

Codecov / codecov/patch

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_collector.hpp#L67

Added line #L67 was not covered by tests
{
}
};

enum class CollectorStatus { Idle, Processing, Finished };

template <class Msg3D, class Msg2D, class ExportObj>
class FusionCollector
{
public:
FusionCollector(
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> && ros2_parent_node,
std::size_t rois_number, const std::vector<Det2dStatus<Msg2D>> & det2d_status_list,
bool debug_mode);
void process_msg3d(const typename Msg3D::ConstSharedPtr msg3d, double msg3d_timeout);
void process_rois(
const std::size_t & rois_id, const typename Msg2D::ConstSharedPtr rois_msg,
double rois_timeout);
void fusion_callback();

[[nodiscard]] CollectorStatus get_status();

void set_info(std::shared_ptr<FusionCollectorInfoBase> collector_info);
[[nodiscard]] std::shared_ptr<FusionCollectorInfoBase> get_info() const;
bool ready_to_fuse();
bool rois_exists(const std::size_t & rois_id);
bool msg3d_exists();
void add_camera_projection(
std::size_t rois_id, std::shared_ptr<CameraProjection> camera_projector_ptr);
void set_period(const std::chrono::nanoseconds period);
void reset();
void show_debug_message();

private:
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> ros2_parent_node_;
rclcpp::TimerBase::SharedPtr timer_;
std::size_t rois_number_;
typename Msg3D::ConstSharedPtr msg3d_{nullptr};
std::vector<Det2dStatus<Msg2D>> det2d_status_list_;
std::unordered_map<std::size_t, typename Msg2D::ConstSharedPtr> id_to_rois_map_;
bool is_first_msg3d_{false};
bool debug_mode_;
std::mutex fusion_mutex_;
std::shared_ptr<FusionCollectorInfoBase> fusion_collector_info_;
CollectorStatus status_;
};

} // namespace autoware::image_projection_based_fusion
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright 2025 TIER IV, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "autoware/image_projection_based_fusion/fusion_collector.hpp"

#include <rclcpp/rclcpp.hpp>

#include <cstddef>
#include <list>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <unordered_map>

namespace autoware::image_projection_based_fusion
{

template <class Msg3D, class Msg2D, class ExportObj>
class FusionNode;

struct MatchingContextBase
{
virtual ~MatchingContextBase() = default;
};

struct Msg3dMatchingContext : public MatchingContextBase
{
double msg3d_timestamp;

explicit Msg3dMatchingContext(double msg3d_timestamp = 0.0) : msg3d_timestamp(msg3d_timestamp) {}

Check warning on line 44 in perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_matching_strategy.hpp

View check run for this annotation

Codecov / codecov/patch

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_matching_strategy.hpp#L44

Added line #L44 was not covered by tests
};

struct RoisMatchingContext : public MatchingContextBase
{
double rois_timestamp;
std::size_t rois_id;

explicit RoisMatchingContext(double rois_timestamp = 0.0, std::size_t rois_id = 0)
: rois_timestamp(rois_timestamp), rois_id(rois_id)

Check warning on line 53 in perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_matching_strategy.hpp

View check run for this annotation

Codecov / codecov/patch

perception/autoware_image_projection_based_fusion/include/autoware/image_projection_based_fusion/fusion_matching_strategy.hpp#L53

Added line #L53 was not covered by tests
{
}
};

template <class Msg3D, class Msg2D, class ExportObj>
class FusionMatchingStrategy
{
public:
virtual ~FusionMatchingStrategy() = default;

[[nodiscard]] virtual std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_rois_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<RoisMatchingContext> & matching_context) const = 0;

[[nodiscard]] virtual std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_msg3d_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<Msg3dMatchingContext> & matching_context) = 0;
virtual void set_collector_info(
std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>> & collector,
const std::shared_ptr<MatchingContextBase> & matching_context) = 0;
};

template <class Msg3D, class Msg2D, class ExportObj>
class NaiveMatchingStrategy : public FusionMatchingStrategy<Msg3D, Msg2D, ExportObj>
{
public:
explicit NaiveMatchingStrategy(
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> && ros2_parent_node,
const std::unordered_map<std::size_t, double> & id_to_offset_map);

[[nodiscard]] std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_rois_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<RoisMatchingContext> & matching_context) const override;

[[nodiscard]] std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_msg3d_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<Msg3dMatchingContext> & matching_context) override;

void set_collector_info(
std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>> & collector,
const std::shared_ptr<MatchingContextBase> & matching_context) override;

private:
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> ros2_parent_node_;
std::unordered_map<std::size_t, double> id_to_offset_map_;
double threshold_;
};

template <class Msg3D, class Msg2D, class ExportObj>
class AdvancedMatchingStrategy : public FusionMatchingStrategy<Msg3D, Msg2D, ExportObj>
{
public:
explicit AdvancedMatchingStrategy(
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> && ros2_parent_node,
const std::unordered_map<std::size_t, double> & id_to_offset_map);

[[nodiscard]] std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_rois_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<RoisMatchingContext> & matching_context) const override;

[[nodiscard]] std::optional<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>>
match_msg3d_to_collector(
const std::list<std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>>> & fusion_collectors,
const std::shared_ptr<Msg3dMatchingContext> & matching_context) override;
void set_collector_info(
std::shared_ptr<FusionCollector<Msg3D, Msg2D, ExportObj>> & collector,
const std::shared_ptr<MatchingContextBase> & matching_context) override;

double get_concatenated_offset(
const double & msg3d_timestamp,
const std::optional<std::unordered_map<std::string, std::string>> & concatenated_status);

double extract_fractional(double timestamp);
void update_fractional_timestamp_set(double new_timestamp);
double compute_offset(double input_timestamp);

private:
std::shared_ptr<FusionNode<Msg3D, Msg2D, ExportObj>> ros2_parent_node_;
std::unordered_map<std::size_t, double> id_to_offset_map_;
std::unordered_map<std::size_t, double> id_to_noise_window_map_;
double msg3d_noise_window_;
std::set<double> fractional_timestamp_set_; // Use set to store unique fractional timestamps
int success_status_counter_{0};
static constexpr int success_threshold{100};
bool database_created_{false};
};
} // namespace autoware::image_projection_based_fusion
Loading
Loading