1515#ifndef CAMERA_SYNC__MULTI_CAMERA_SYNC_NODE_HPP_
1616#define CAMERA_SYNC__MULTI_CAMERA_SYNC_NODE_HPP_
1717
18- #include < message_filters/subscriber.h>
19- #include < message_filters/sync_policies/approximate_time.h>
20- #include < message_filters/synchronizer.h>
18+ #include < cv_bridge/cv_bridge.h>
2119
2220#include < chrono>
21+ #include < map>
2322#include < memory>
23+ #include < mutex>
2424#include < string>
2525#include < vector>
2626
27- #include < image_transport/image_transport.hpp>
2827#include < rclcpp/rclcpp.hpp>
2928#include < sensor_msgs/msg/compressed_image.hpp>
3029#include < sensor_msgs/msg/image.hpp>
@@ -47,11 +46,11 @@ namespace camera_sync
4746{
4847
4948/* *
50- * @brief Node that synchronizes N camera image messages using message filters
49+ * @brief Node that synchronizes N camera image messages using manual timestamp-based buffering
5150 *
5251 * This node can handle both raw images (sensor_msgs/Image) and compressed images
5352 * (sensor_msgs/CompressedImage) and synchronize them based on their timestamps.
54- * Supports 2-6 cameras with a compact implementation.
53+ * Supports 2-12 cameras with a unified manual synchronization implementation.
5554 */
5655#if USE_LIFECYCLE_NODE
5756class MultiCameraSyncNode : public rclcpp_lifecycle ::LifecycleNode
@@ -87,38 +86,8 @@ class MultiCameraSyncNode : public rclcpp::Node
8786 using CompressedImageMsg = sensor_msgs::msg::CompressedImage;
8887
8988 // Subscriber types
90- #if USE_LIFECYCLE_NODE
91- using ImageSubscriber = message_filters::Subscriber<ImageMsg, rclcpp_lifecycle::LifecycleNode>;
92- using CompressedImageSubscriber = message_filters::Subscriber<CompressedImageMsg, rclcpp_lifecycle::LifecycleNode>;
93- #else
94- using ImageSubscriber = message_filters::Subscriber<ImageMsg>;
95- using CompressedImageSubscriber = message_filters::Subscriber<CompressedImageMsg>;
96- #endif
97-
98- // Sync policies for raw images
99- using ImageSyncPolicy2 = message_filters::sync_policies::ApproximateTime<ImageMsg, ImageMsg>;
100- using ImageSyncPolicy3 = message_filters::sync_policies::ApproximateTime<ImageMsg, ImageMsg, ImageMsg>;
101- using ImageSyncPolicy4 = message_filters::sync_policies::ApproximateTime<ImageMsg, ImageMsg, ImageMsg, ImageMsg>;
102- using ImageSyncPolicy5 =
103- message_filters::sync_policies::ApproximateTime<ImageMsg, ImageMsg, ImageMsg, ImageMsg, ImageMsg>;
104- using ImageSyncPolicy6 =
105- message_filters::sync_policies::ApproximateTime<ImageMsg, ImageMsg, ImageMsg, ImageMsg, ImageMsg, ImageMsg>;
106-
107- // Sync policies for compressed images
108- using CompressedSyncPolicy2 = message_filters::sync_policies::ApproximateTime<CompressedImageMsg, CompressedImageMsg>;
109- using CompressedSyncPolicy3 =
110- message_filters::sync_policies::ApproximateTime<CompressedImageMsg, CompressedImageMsg, CompressedImageMsg>;
111- using CompressedSyncPolicy4 = message_filters::sync_policies::
112- ApproximateTime<CompressedImageMsg, CompressedImageMsg, CompressedImageMsg, CompressedImageMsg>;
113- using CompressedSyncPolicy5 = message_filters::sync_policies::
114- ApproximateTime<CompressedImageMsg, CompressedImageMsg, CompressedImageMsg, CompressedImageMsg, CompressedImageMsg>;
115- using CompressedSyncPolicy6 = message_filters::sync_policies::ApproximateTime<
116- CompressedImageMsg,
117- CompressedImageMsg,
118- CompressedImageMsg,
119- CompressedImageMsg,
120- CompressedImageMsg,
121- CompressedImageMsg>;
89+ using ImageSubscriber = rclcpp::Subscription<ImageMsg>;
90+ using CompressedImageSubscriber = rclcpp::Subscription<CompressedImageMsg>;
12291
12392 /* *
12493 * @brief Initialize the node parameters
@@ -140,61 +109,6 @@ class MultiCameraSyncNode : public rclcpp::Node
140109 */
141110 void setupCompressedSync (size_t num_cameras);
142111
143- /* *
144- * @brief Callback functions for synchronized raw images
145- */
146- void syncCallback2Raw (const ImageMsg::ConstSharedPtr & img1, const ImageMsg::ConstSharedPtr & img2);
147- void syncCallback3Raw (
148- const ImageMsg::ConstSharedPtr & img1,
149- const ImageMsg::ConstSharedPtr & img2,
150- const ImageMsg::ConstSharedPtr & img3);
151- void syncCallback4Raw (
152- const ImageMsg::ConstSharedPtr & img1,
153- const ImageMsg::ConstSharedPtr & img2,
154- const ImageMsg::ConstSharedPtr & img3,
155- const ImageMsg::ConstSharedPtr & img4);
156- void syncCallback5Raw (
157- const ImageMsg::ConstSharedPtr & img1,
158- const ImageMsg::ConstSharedPtr & img2,
159- const ImageMsg::ConstSharedPtr & img3,
160- const ImageMsg::ConstSharedPtr & img4,
161- const ImageMsg::ConstSharedPtr & img5);
162- void syncCallback6Raw (
163- const ImageMsg::ConstSharedPtr & img1,
164- const ImageMsg::ConstSharedPtr & img2,
165- const ImageMsg::ConstSharedPtr & img3,
166- const ImageMsg::ConstSharedPtr & img4,
167- const ImageMsg::ConstSharedPtr & img5,
168- const ImageMsg::ConstSharedPtr & img6);
169-
170- /* *
171- * @brief Callback functions for synchronized compressed images
172- */
173- void syncCallback2Compressed (
174- const CompressedImageMsg::ConstSharedPtr & img1, const CompressedImageMsg::ConstSharedPtr & img2);
175- void syncCallback3Compressed (
176- const CompressedImageMsg::ConstSharedPtr & img1,
177- const CompressedImageMsg::ConstSharedPtr & img2,
178- const CompressedImageMsg::ConstSharedPtr & img3);
179- void syncCallback4Compressed (
180- const CompressedImageMsg::ConstSharedPtr & img1,
181- const CompressedImageMsg::ConstSharedPtr & img2,
182- const CompressedImageMsg::ConstSharedPtr & img3,
183- const CompressedImageMsg::ConstSharedPtr & img4);
184- void syncCallback5Compressed (
185- const CompressedImageMsg::ConstSharedPtr & img1,
186- const CompressedImageMsg::ConstSharedPtr & img2,
187- const CompressedImageMsg::ConstSharedPtr & img3,
188- const CompressedImageMsg::ConstSharedPtr & img4,
189- const CompressedImageMsg::ConstSharedPtr & img5);
190- void syncCallback6Compressed (
191- const CompressedImageMsg::ConstSharedPtr & img1,
192- const CompressedImageMsg::ConstSharedPtr & img2,
193- const CompressedImageMsg::ConstSharedPtr & img3,
194- const CompressedImageMsg::ConstSharedPtr & img4,
195- const CompressedImageMsg::ConstSharedPtr & img5,
196- const CompressedImageMsg::ConstSharedPtr & img6);
197-
198112 /* *
199113 * @brief Process synchronized images (statistics and custom logic)
200114 * @param timestamps Vector of synchronized timestamps from all cameras
@@ -204,31 +118,13 @@ class MultiCameraSyncNode : public rclcpp::Node
204118 // Parameters
205119 std::vector<std::string> camera_topics_;
206120 std::vector<std::string> camera_names_;
207- std::vector<sensor_msgs::msg::Image::ConstSharedPtr> image_array;
208121 bool use_compressed_;
209122 double sync_tolerance_ms_;
210123 int queue_size_;
211- bool publish_sync_info_;
212124
213125 // Subscribers
214- std::vector<std::unique_ptr<ImageSubscriber>> image_subscribers_;
215- std::vector<std::unique_ptr<CompressedImageSubscriber>> compressed_subscribers_;
216-
217- // Synchronizers for raw images
218- std::unique_ptr<message_filters::Synchronizer<ImageSyncPolicy2>> sync2_raw_;
219- std::unique_ptr<message_filters::Synchronizer<ImageSyncPolicy3>> sync3_raw_;
220- std::unique_ptr<message_filters::Synchronizer<ImageSyncPolicy4>> sync4_raw_;
221- std::unique_ptr<message_filters::Synchronizer<ImageSyncPolicy5>> sync5_raw_;
222- std::unique_ptr<message_filters::Synchronizer<ImageSyncPolicy6>> sync6_raw_;
223-
224- // Synchronizers for compressed images
225- std::unique_ptr<message_filters::Synchronizer<CompressedSyncPolicy2>> sync2_compressed_;
226- std::unique_ptr<message_filters::Synchronizer<CompressedSyncPolicy3>> sync3_compressed_;
227- std::unique_ptr<message_filters::Synchronizer<CompressedSyncPolicy4>> sync4_compressed_;
228- std::unique_ptr<message_filters::Synchronizer<CompressedSyncPolicy5>> sync5_compressed_;
229- std::unique_ptr<message_filters::Synchronizer<CompressedSyncPolicy6>> sync6_compressed_;
230-
231- rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr sync_info_pub_;
126+ std::vector<std::shared_ptr<ImageSubscriber>> image_subscribers_;
127+ std::vector<std::shared_ptr<CompressedImageSubscriber>> compressed_subscribers_;
232128
233129 // Publishers for multi-image messages
234130 rclcpp::Publisher<deep_msgs::msg::MultiImage>::SharedPtr multi_image_raw_pub_;
@@ -238,6 +134,34 @@ class MultiCameraSyncNode : public rclcpp::Node
238134 int64_t sync_count_;
239135 rclcpp::Time last_sync_time_;
240136 std::chrono::steady_clock::time_point start_time_;
137+
138+ struct ImageBuffer
139+ {
140+ std::map<uint64_t , ImageMsg::ConstSharedPtr> buffer;
141+ std::shared_ptr<std::mutex> mutex;
142+
143+ ImageBuffer ()
144+ : mutex(std::make_shared<std::mutex>())
145+ {}
146+ };
147+
148+ struct CompressedImageBuffer
149+ {
150+ std::map<uint64_t , CompressedImageMsg::ConstSharedPtr> buffer;
151+ std::shared_ptr<std::mutex> mutex;
152+
153+ CompressedImageBuffer ()
154+ : mutex(std::make_shared<std::mutex>())
155+ {}
156+ };
157+
158+ std::vector<ImageBuffer> raw_image_buffers_;
159+ std::vector<CompressedImageBuffer> compressed_image_buffers_;
160+
161+ void handleRawImageCallback (size_t camera_idx, const ImageMsg::ConstSharedPtr & msg);
162+ void handleCompressedImageCallback (size_t camera_idx, const CompressedImageMsg::ConstSharedPtr & msg);
163+ void tryPublishSyncedRawImages ();
164+ void tryPublishSyncedCompressedImages ();
241165};
242166
243167} // namespace camera_sync
0 commit comments