VOXL OpenVINS Server 1.0
Visual Inertial Odometry Server for VOXL Platform
Loading...
Searching...
No Matches
CameraManager.cpp
Go to the documentation of this file.
1/**
2 * @file CameraManager.cpp
3 * @brief Camera management system implementation for VOXL OpenVINS
4 * @author Zauberflote
5 * @date 2025
6 * @version 1.0
7 *
8 * This file implements the CameraManager class, which provides centralized
9 * management of all camera instances in the VOXL OpenVINS system. It handles
10 * camera creation, initialization, and lifecycle management.
11 *
12 * The implementation provides:
13 * - Singleton pattern for global camera management
14 * - Template-based camera creation for extensibility
15 * - Thread-safe operations with mutex protection
16 * - Automatic camera type detection and creation
17 * - Resource cleanup and shutdown management
18 * - Camera fusion system integration
19 */
20
21#include "CameraManager.h"
22
23namespace voxl
24{
25
26 /**
27 * @brief Get the singleton instance of the CameraManager
28 *
29 * Returns the single instance of the CameraManager, creating it
30 * if it doesn't exist (lazy initialization). This ensures that
31 * only one camera manager exists throughout the application lifecycle.
32 *
33 * @return Reference to the CameraManager instance
34 */
36 {
37 static CameraManager instance;
38 return instance;
39 }
40
41 /**
42 * @brief Destructor for CameraManager
43 *
44 * Performs cleanup by calling the shutdown method to ensure proper
45 * resource deallocation and camera disconnection.
46 */
47 CameraManager::~CameraManager()
48 {
49 shutdown();
50 }
51
52 /**
53 * @brief Create and connect a specific type of camera
54 *
55 * Template method that creates and connects a camera of the specified
56 * type. This allows for extensibility to support different camera
57 * implementations while maintaining a consistent interface.
58 *
59 * The method performs the following operations:
60 * - Creates a new camera instance of the specified type
61 * - Stores the camera in the internal map by camera ID
62 * - Attempts to connect the camera to its data source
63 * - Logs success or failure information
64 *
65 * @tparam CameraType The type of camera to create (MonoCamera, StereoCamera, etc.)
66 * @param config Camera configuration information
67 * @return true if camera was successfully created and connected, false otherwise
68 */
69 template <typename CameraType>
70 bool CameraManager::createAndConnectCamera(const cam_info &config)
71 {
72 auto camera = std::make_shared<CameraType>(config);
73 cameras_[config.cam_id] = camera;
74
75 if (true)
76 {
77 std::cout << "Created camera: " << config.name
78 << " in " << camera_mode_as_string(config.mode) << " mode" << std::endl;
79 }
80
81 if (!camera->connect())
82 {
83 std::cerr << "Failed to connect camera: " << config.name << std::endl;
84 vio_error_codes |= ERROR_CODE_CAM_MISSING;
85 return false;
86 }
87
88 return true;
89 }
90
91 /**
92 * @brief Initialize the camera manager with camera configurations
93 *
94 * Sets up the camera manager with the provided camera configurations.
95 * This method creates and initializes all cameras based on their
96 * configuration information.
97 *
98 * The initialization process includes:
99 * - Validating that the manager is not already initialized
100 * - Checking that camera configurations are provided
101 * - Filtering cameras by supported modes (currently only MONO)
102 * - Creating and connecting each camera
103 * - Starting the camera fusion system
104 * - Setting the initialized flag
105 *
106 * If any camera fails to initialize, the method performs a clean
107 * shutdown and returns false.
108 *
109 * @param camera_configs Vector of camera configurations
110 * @return true if successful, false otherwise
111 */
112 bool CameraManager::initialize(const std::vector<cam_info> &camera_configs)
113 {
114 std::lock_guard<std::mutex> lock(mutex_);
115
116 if (initialized_)
117 {
118 std::cerr << "CameraManager already initialized" << std::endl;
119 return true;
120 }
121
122 if (camera_configs.empty())
123 {
124 std::cerr << "No camera configurations provided" << std::endl;
125 vio_error_codes |= ERROR_CODE_CAM_MISSING;
126 return false;
127 }
128
129 std::vector<cam_info> cameras;
130 for (const auto &config : camera_configs)
131 {
132 if (config.mode == MONO)
133 {
134 if (!createAndConnectCamera<MonoCamera>(config))
135 {
136 shutdown();
137 return false;
138 }
139 }
140 else if (config.mode == STEREO)
141 {
142 if (!createAndConnectCamera<StereoCamera>(config))
143 {
144 shutdown();
145 return false;
146 }
147 }
148 else
149 {
150 std::cerr << "Unsupported or disabled camera mode: " << camera_mode_as_string(config.mode)
151 << " for camera: " << config.name << std::endl;
152 }
153 }
154
155 if (cameras_.empty())
156 {
157 std::cerr << "No valid mono cameras found." << std::endl;
158 vio_error_codes |= ERROR_CODE_LOW_FEATURES;
159 return false;
160 }
161
162 if (true)
163 {
164 std::cout << "Successfully initialized " << cameras_.size() << " cameras" << std::endl;
165 }
166
167 // Start the camera fusion thread once all cameras are initialized
168 // This ensures that camera frames are actively consumed and fused
169 CameraQueueFusion::getInstance().start(cameras_.size());
170
171 initialized_ = true;
172 return true;
173 }
174
175 /**
176 * @brief Shut down all cameras and clean up resources
177 *
178 * Performs a clean shutdown of all camera instances, disconnecting
179 * them from their data sources and freeing allocated resources.
180 *
181 * The shutdown process includes:
182 * - Checking if the manager is already shut down
183 * - Disconnecting each camera in a separate thread to avoid blocking
184 * - Waiting for disconnect operations to complete with timeout
185 * - Clearing the camera collection
186 * - Resetting the initialized flag
187 *
188 * The method uses detached threads for camera disconnection to
189 * prevent blocking the main thread during shutdown.
190 */
192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194
195 if (!initialized_)
196 return;
197
198 std::cout << "Shutting down CameraManager..." << std::endl;
199
200 try
201 {
202 for (auto &[id, camera] : cameras_)
203 {
204 std::cout << "Disconnecting Camera " << id << std::endl;
205 bool success = false;
206
207 std::thread disconnect_thread([&camera, &success]()
208 {
209 try {
210 camera->disconnect();
211 success = true;
212 } catch (const std::exception& e) {
213 std::cerr << "Error disconnecting camera: " << e.what() << std::endl;
214 } });
215
216 disconnect_thread.detach();
217
218 for (int i = 0; i < 10 && !success; i++)
219 {
220 usleep(10000); // 10ms
221 }
222
223 if (!success)
224 {
225 std::cerr << "Camera disconnect timeout" << std::endl;
226 }
227 }
228 }
229 catch (const std::exception &e)
230 {
231 std::cerr << "Shutdown exception: " << e.what() << std::endl;
232 }
233
234 cameras_.clear();
235 initialized_ = false;
236 std::cout << "CameraManager shutdown complete" << std::endl;
237 }
238
239 /**
240 * @brief Get all cameras
241 *
242 * Returns a vector containing all managed camera instances.
243 * The method is thread-safe and returns a copy of the camera
244 * collection to prevent external modification.
245 *
246 * @return Vector of camera shared pointers
247 */
248 std::vector<std::shared_ptr<CameraBase>> CameraManager::getAllCameras()
249 {
250 std::lock_guard<std::mutex> lock(mutex_);
251 std::vector<std::shared_ptr<CameraBase>> result;
252 for (const auto &[id, cam] : cameras_)
253 {
254 result.push_back(cam);
255 }
256 return result;
257 }
258
259 /**
260 * @brief Get the number of cameras
261 *
262 * Returns the total number of cameras currently managed by the system.
263 * The method is thread-safe and provides a consistent count.
264 *
265 * @return Number of cameras managed
266 */
268 {
269 std::lock_guard<std::mutex> lock(mutex_);
270 return cameras_.size();
271 }
272
273 /**
274 * @brief Check if the camera manager is initialized
275 *
276 * Determines whether the camera manager has been successfully
277 * initialized with camera configurations. The method is thread-safe
278 * and provides a consistent state check.
279 *
280 * @return true if initialized, false otherwise
281 */
283 {
284 std::lock_guard<std::mutex> lock(mutex_);
285 return initialized_;
286 }
287
288} // namespace voxl
Camera management system for VOXL OpenVINS.
@ MONO
Single camera mode.
Definition VoxlCommon.h:92
@ STEREO
Stereo camera mode (both cameras active)
Definition VoxlCommon.h:93
std::atomic< uint32_t > vio_error_codes
VIO error codes.
static CameraQueueFusion & getInstance()
Get singleton instance.
void start(size_t num_cams)
Start the fusion system.
Manages all camera instances in the system.
void shutdown()
Shut down all cameras and clean up resources.
size_t getCameraCount() const
Get the number of cameras.
bool isInitialized() const
Check if the camera manager is initialized.
std::vector< std::shared_ptr< CameraBase > > getAllCameras()
Get all cameras.
bool initialize(const std::vector< cam_info > &camera_configs)
Initialize the camera manager with camera configurations.
static CameraManager & getInstance()
Get the singleton instance of the CameraManager.
Main namespace for VOXL OpenVINS server components.
Camera information and calibration data.
Definition VoxlCommon.h:198
char name[128]
Camera name identifier.
Definition VoxlCommon.h:199
camera_mode mode
Camera operation mode.
Definition VoxlCommon.h:202
size_t cam_id
Unique camera identifier.
Definition VoxlCommon.h:209