VOXL OpenVINS Server 0.7.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 Joao Leonardo Silva Cotta (@zauberflote1)
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 // No fusion thread: cameras push straight into the estimator's lock-free per-camera rings
168 // and the IMU feed releases frames in global timestamp order (ov_msckf AsyncCameraBuffer)
169
170 initialized_ = true;
171 return true;
172 }
173
174 /**
175 * @brief Shut down all cameras and clean up resources
176 *
177 * Performs a clean shutdown of all camera instances, disconnecting
178 * them from their data sources and freeing allocated resources.
179 *
180 * The shutdown process includes:
181 * - Checking if the manager is already shut down
182 * - Disconnecting each camera in a separate thread to avoid blocking
183 * - Waiting for disconnect operations to complete with timeout
184 * - Clearing the camera collection
185 * - Resetting the initialized flag
186 *
187 * The method uses detached threads for camera disconnection to
188 * prevent blocking the main thread during shutdown.
189 */
191 {
192 std::lock_guard<std::mutex> lock(mutex_);
193
194 if (!initialized_)
195 return;
196
197 std::cout << "Shutting down CameraManager..." << std::endl;
198
199 try
200 {
201 for (auto &[id, camera] : cameras_)
202 {
203 std::cout << "Disconnecting Camera " << id << std::endl;
204 bool success = false;
205
206 std::thread disconnect_thread([&camera, &success]()
207 {
208 try {
209 camera->disconnect();
210 success = true;
211 } catch (const std::exception& e) {
212 std::cerr << "Error disconnecting camera: " << e.what() << std::endl;
213 } });
214
215 disconnect_thread.detach();
216
217 for (int i = 0; i < 10 && !success; i++)
218 {
219 usleep(10000); // 10ms
220 }
221
222 if (!success)
223 {
224 std::cerr << "Camera disconnect timeout" << std::endl;
225 }
226 }
227 }
228 catch (const std::exception &e)
229 {
230 std::cerr << "Shutdown exception: " << e.what() << std::endl;
231 }
232
233 cameras_.clear();
234 initialized_ = false;
235 std::cout << "CameraManager shutdown complete" << std::endl;
236 }
237
238 /**
239 * @brief Get all cameras
240 *
241 * Returns a vector containing all managed camera instances.
242 * The method is thread-safe and returns a copy of the camera
243 * collection to prevent external modification.
244 *
245 * @return Vector of camera shared pointers
246 */
247 std::vector<std::shared_ptr<CameraBase>> CameraManager::getAllCameras()
248 {
249 std::lock_guard<std::mutex> lock(mutex_);
250 std::vector<std::shared_ptr<CameraBase>> result;
251 for (const auto &[id, cam] : cameras_)
252 {
253 result.push_back(cam);
254 }
255 return result;
256 }
257
258
259} // 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.
Manages all camera instances in the system.
void shutdown()
Shut down all cameras and clean up resources.
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:146
char name[128]
Camera name identifier.
Definition VoxlCommon.h:147
camera_mode mode
Camera operation mode.
Definition VoxlCommon.h:149
size_t cam_id
Unique camera identifier.
Definition VoxlCommon.h:151