isaac_sim_bridge/camera/
depth.rs1use std::sync::OnceLock;
3
4use crate::channel::{channel_singleton, Channel};
5use crate::ffi::CameraDepthMeta;
6use crate::sensor::Sensor;
7
8pub struct CameraDepth;
10
11impl Sensor for CameraDepth {
12 const NAME: &'static str = "camera_depth";
13}
14
15pub type Callback = Box<dyn Fn(&str, &[f32], &CameraDepthMeta) + Send + Sync + 'static>;
16
17#[unsafe(no_mangle)]
18pub extern "C" fn isaac_sim_bridge_channel_camera_depth() -> *const Channel<Callback> {
19 static SLOT: OnceLock<Box<Channel<Callback>>> = OnceLock::new();
20 channel_singleton(&SLOT)
21}
22
23fn channel() -> &'static Channel<Callback> {
24 unsafe { &*isaac_sim_bridge_channel_camera_depth() }
25}
26
27pub fn register_camera_depth_consumer<F>(cb: F)
30where
31 F: Fn(&str, &[f32], &CameraDepthMeta) + Send + Sync + 'static,
32{
33 channel().register(Box::new(cb));
34}
35
36pub fn dispatch_camera_depth(source_id: &str, depths: &[f32], meta: &CameraDepthMeta) {
38 channel().for_each(|cb| cb(source_id, depths, meta));
39}
40
41pub fn camera_depth_consumer_count() -> usize {
43 channel().count()
44}
45
46pub fn forward_camera_depth(source_id: &str, depths: &[f32], meta: &CameraDepthMeta) {
48 log::debug!(
49 "[isaac-sim-rs] forward_camera_depth: source='{}' wxh={}x{} samples={}",
50 source_id,
51 meta.width,
52 meta.height,
53 depths.len()
54 );
55 dispatch_camera_depth(source_id, depths, meta);
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use std::sync::atomic::{AtomicUsize, Ordering};
62 use std::sync::Arc;
63
64 fn fake_meta(w: i32, h: i32) -> CameraDepthMeta {
65 CameraDepthMeta {
66 width: w,
67 height: h,
68 fx: 0.0,
69 fy: 0.0,
70 cx: 0.0,
71 cy: 0.0,
72 timestamp_ns: 0,
73 }
74 }
75
76 #[test]
77 fn registered_consumer_receives_dispatch_with_source() {
78 let count = Arc::new(AtomicUsize::new(0));
79 let count_clone = Arc::clone(&count);
80 let n_baseline = camera_depth_consumer_count();
81
82 register_camera_depth_consumer(move |src, depths, meta| {
83 assert_eq!(src, "/World/Camera/depth");
84 assert_eq!(meta.width, 2);
85 assert_eq!(meta.height, 2);
86 assert_eq!(depths.len(), 4);
87 count_clone.fetch_add(1, Ordering::SeqCst);
88 });
89
90 assert_eq!(camera_depth_consumer_count(), n_baseline + 1);
91
92 let depths = [0.5_f32, 1.0, 1.5, 2.0];
93 dispatch_camera_depth("/World/Camera/depth", &depths, &fake_meta(2, 2));
94
95 assert_eq!(count.load(Ordering::SeqCst), 1);
96 }
97}