41 static void release_cl_mem(
void *mem)
45 cl_int err = clReleaseMemObject((cl_mem)mem);
46 if (err != CL_SUCCESS)
48 fprintf(stderr,
"Failed to release cl_mem object %p, err=%d\n", mem, err);
79 if (!is_system_ready())
81 if (img_type == voxl::ImageType::CL_MEM)
82 release_cl_mem(frame);
90 if (img_type == voxl::ImageType::CL_MEM)
91 release_cl_mem(frame);
101 if (img_type == voxl::ImageType::CL_MEM)
102 release_cl_mem(frame);
106 std::lock_guard<std::mutex> lk(
reset_mtx);
117 const bool vio_ready_for_throttling =
vio_manager &&
120 vio_state.load(std::memory_order_acquire) == VIO_STATE_OK;
126 const bool is_static = !(
non_static.load(std::memory_order_acquire));
127 const bool acc_no_jerk = !(
has_acc_jerk.load(std::memory_order_acquire));
131 printf(
"is_static: %d, acc_no_jerk: %d, drop_frames: %d\n",
135 if (is_static || acc_no_jerk)
141 printf(
"normal frame\n");
146 if (img_type == voxl::ImageType::CL_MEM)
147 release_cl_mem(frame);
150 printf(
"dropping frame\n");
153 std::lock_guard<std::mutex> lk(
reset_mtx);
160 else if (!vio_ready_for_throttling &&
en_debug)
163 printf(
"[INIT] VIO not stable - processing ALL frames (no throttling)\n");
166 current_height = meta.height;
167 current_width = meta.width;
169 if (img_type == voxl::ImageType::CV_MAT)
172 if (meta.format == IMAGE_FORMAT_RAW8)
174 process_raw8(meta, (
char *)frame);
179 fprintf(stderr,
"Unsupported image format: %d\n", meta.format);
183 if (img_type == voxl::ImageType::CL_MEM)
186 if (meta.format == IMAGE_FORMAT_RAW8)
188 process_device_buf_raw8(meta, (cl_mem)frame);
193 fprintf(stderr,
"Unsupported image format: %d\n", meta.format);
202 std::lock_guard<std::mutex> lk(
reset_mtx);
225 void MonoCamera::process_raw8(
const camera_image_metadata_t &meta,
char *frame)
237 const bool dimensions_changed = (
use_mask_.rows != current_height ||
use_mask_.cols != current_width);
238 if (dimensions_changed)
240 mask_dimensions_changed_ =
true;
248 occlusion_threshold_passed_ =
true;
252 update_mask_if_needed(should_mask);
254 ov_core::CameraData message;
255 message.timestamp = (meta.timestamp_ns) * 1e-09;
256 message.sensor_ids.push_back(
get_id());
259 message.images.emplace_back(image.clone());
262 modal_flow::ImageView iv{{meta.width, meta.height, modal_flow::PixelFormat::R8, meta.stride}, message.images[0].data, modal_flow::ExternalType::None, 0};
263 modal_flow::Frame img_frame({
get_id(), 0, iv});
264 message.img_frames.push_back(img_frame);
275 void MonoCamera::process_device_buf_raw8(
const camera_image_metadata_t &meta, cl_mem frame)
281 const bool dimensions_changed = (
use_mask_.rows != current_height ||
use_mask_.cols != current_width);
282 if (dimensions_changed)
284 mask_dimensions_changed_ =
true;
292 occlusion_threshold_passed_ =
true;
296 update_mask_if_needed(should_mask);
298 ov_core::CameraData message;
299 message.timestamp = (meta.timestamp_ns) * 1e-09;
300 message.sensor_ids.push_back(
get_id());
304 modal_flow::ImageView iv{{meta.width, meta.height, modal_flow::PixelFormat::R8, meta.stride},
nullptr, modal_flow::ExternalType::ClMem,
static_cast<uint64_t
>(
reinterpret_cast<std::uintptr_t
>(frame))};
305 modal_flow::Frame img_frame({
get_id(), 0, iv});
307 message.cl_images.emplace_back(frame);
309 message.img_frames.push_back(img_frame);
311 message.images.emplace_back(cv::Mat::zeros(meta.height, meta.width, CV_8UC1));
324 release_cl_mem(frame);
328 void MonoCamera::update_mask_if_needed(
bool should_mask)
331 const bool needs_update = !current_mask_state_.has_value() ||
332 current_mask_state_.value() != should_mask ||
333 mask_dimensions_changed_;
341 current_mask_state_ = should_mask;
342 mask_dimensions_changed_ =
false;
348 use_mask_ = cv::Mat(current_height, current_width, CV_8UC1, cv::Scalar(255));
353 use_mask_ = cv::Mat(current_height, current_width, CV_8UC1, cv::Scalar(0));
367 bool MonoCamera::is_system_ready()
const
Monocular camera implementation for VOXL OpenVINS.
volatile int64_t last_cam_time
Timestamp of last camera data (nanoseconds)
volatile int main_running
Main process running flag.
std::atomic< uint32_t > active_callbacks
Number of callbacks inside the system.
ov_msckf::VioManagerOptions vio_manager_options
VIO manager options.
voxl::FrameTransform frame_transform
Global frame transform instance.
std::mutex reset_mtx
Mutex used by reset thread.
float takeoff_alt_threshold
Takeoff altitude threshold.
std::unique_ptr< ov_msckf::VioManager > vio_manager
Main VIO manager instance.
int en_debug
Enable debug output.
std::condition_variable reset_cv
Reset conditional variable.
std::atomic< bool > non_static
Non-static flag for jerk detection.
std::atomic< bool > is_resetting
VIO reset state flag.
std::atomic< uint8_t > vio_state
Current VIO system state.
std::atomic< float > alt_z
Altitude z.
std::atomic< bool > has_acc_jerk
Flag indicating if accelerometer jerk is detected.
std::atomic< uint32_t > vio_error_codes
VIO error codes.
std::atomic< bool > is_imu_connected
IMU connection state.
std::atomic< bool > is_cam_connected
Camera connection state.
Base class for all camera implementations.
bool drop_frames
Indicates if frames should be dropped.
cv::Mat use_mask_
Per-instance reusable mask for feature tracking.
int get_channel() const
Pop camera data from the queue.
cam_info camera_info_
Camera configuration information.
bool skip_jerk_detection
Indicates if jerk detection should be skipped.
size_t get_id() const
Get the camera identifier.
img_ringbuf_packet curr_message_
Lock-free SPSC queue for camera data.
MonoCamera(const cam_info &camera_info)
Constructor.
void process_image(const camera_image_metadata_t &meta, voxl::ImageType type, void *frame) override
Process incoming image data.
Main namespace for VOXL OpenVINS server components.
Camera information and calibration data.
bool is_occluded_on_takeoff
Flag indicating if camera is occluded on takeoff.
uint8_t image_pixels[MAX_IMAGE_SIZE]
Raw image pixel data.
camera_image_metadata_t metadata
Image metadata (timestamp, format, etc.)
int camid
Camera identifier.