Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions components/libs/zed_sdk/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ impl Camera {
self.retrieve_measure_raw(sys::SL_MEASURE::SL_MEASURE_DEPTH, target)
}

/// Retrieves a compact depth map in millimeters.
///
/// Invalid values are zero and valid depths are clamped to 65000 millimeters
/// by the ZED SDK.
pub fn retrieve_depth_u16_mm(&mut self, target: &mut Mat<u16>) -> Result<()> {
self.retrieve_measure_raw(sys::SL_MEASURE::SL_MEASURE_DEPTH_U16_MM, target)
}

/// Retrieves the depth confidence map.
pub fn retrieve_confidence(&mut self, target: &mut Mat<f32>) -> Result<()> {
self.retrieve_measure_raw(sys::SL_MEASURE::SL_MEASURE_CONFIDENCE, target)
Expand Down
14 changes: 8 additions & 6 deletions components/sources/cu_zed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ The demo in this directory wires both together and streams the result to Rerun:
`cu_zed::Zed` is a `CuSrcTask` with this output tuple:

1. `cu_zed::ZedStereoImages`
2. `cu_zed::ZedDepthMap<Vec<f32>>`
2. `cu_zed::ZedDepthMap`, a generic integer depth map specialized as
`CuDepthInteger<u16, CuDepthMillimeter>`
3. `cu_zed::ZedConfidenceMap<Vec<f32>>`
4. `cu29::prelude::CuLatchedStateUpdate<cu_zed::ZedCalibrationBundle>`
5. `cu29::prelude::CuLatchedStateUpdate<cu_zed::ZedRigTransforms>`
Expand All @@ -29,7 +30,8 @@ The demo in this directory wires both together and streams the result to Rerun:
Semantics:

- Stereo images are left/right RGBA frames in pooled host memory.
- Depth is a dense `f32` raster in pooled host memory.
- Depth is a dense `u16` millimeter raster in pooled host memory. Zero is invalid,
and the ZED SDK clamps valid values at 65000 millimeters.
- Confidence is optional and only emitted when enabled in config.
- Calibration and rig transforms are latched state updates:
the source publishes `Set(...)` when the task starts, then `NoChange` after that.
Expand Down Expand Up @@ -204,7 +206,7 @@ These are designed to be consumed as Copper latched state. A downstream task sho

`ZedDepthToPointCloud<const MAX_POINTS: usize>` is a pure `CuTask` that consumes:

- `cu_zed::ZedDepthMap<Vec<f32>>`
- `cu_zed::ZedDepthMap` (`CuDepthInteger<u16, CuDepthMillimeter>`)
- `cu29::prelude::CuLatchedStateUpdate<cu_zed::ZedCalibrationBundle>`

and produces:
Expand All @@ -215,8 +217,8 @@ The task:

- caches the latest calibration bundle
- rescales intrinsics if the depth raster size differs from the calibration image size
- converts the ZED depth unit into meters
- skips invalid depth samples (`NaN`, non-finite, or `<= 0`)
- converts millimeter samples into typed lengths/meters
- skips invalid zero-valued depth samples
- writes a standard Copper point cloud with:
- `x`, `y`, `z` in meters
- `i = 0%`
Expand Down Expand Up @@ -294,7 +296,7 @@ This is the standard graph shape:
(
src: "zed",
dst: "pointcloud",
msg: "cu_zed::ZedDepthMap<Vec<f32>>",
msg: "cu_sensor_payloads::CuDepthMap<Vec<u16>, cu_sensor_payloads::CuDepthInteger<u16, cu_sensor_payloads::CuDepthMillimeter>>",
),
(
src: "zed",
Expand Down
6 changes: 3 additions & 3 deletions components/sources/cu_zed/examples/zed_rerun_demo.ron
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
(
src: "zed",
dst: "rerun",
msg: "cu_zed::ZedDepthMap<Vec<f32>>",
msg: "cu_sensor_payloads::CuDepthMap<Vec<u16>, cu_sensor_payloads::CuDepthInteger<u16, cu_sensor_payloads::CuDepthMillimeter>>",
),
(
src: "zed",
Expand All @@ -59,7 +59,7 @@
(
src: "zed",
dst: "pointcloud",
msg: "cu_zed::ZedDepthMap<Vec<f32>>",
msg: "cu_sensor_payloads::CuDepthMap<Vec<u16>, cu_sensor_payloads::CuDepthInteger<u16, cu_sensor_payloads::CuDepthMillimeter>>",
),
(
src: "zed",
Expand Down Expand Up @@ -92,4 +92,4 @@
msg: "cu_zed::ZedFrameMeta",
),
],
)
)
95 changes: 38 additions & 57 deletions components/sources/cu_zed/examples/zed_rerun_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl CuSinkTask for ZedRerunSink {
type Input<'m> = input_msg!(
'm,
ZedStereoImages,
ZedDepthMap<Vec<f32>>,
ZedDepthMap,
ZedConfidenceMap<Vec<f32>>,
CuLatchedStateUpdate<ZedCalibrationBundle>,
CuLatchedStateUpdate<ZedRigTransforms>,
Expand Down Expand Up @@ -83,12 +83,12 @@ impl CuSinkTask for ZedRerunSink {

if let Some(depth) = depth_msg.payload() {
apply_tov(&self.rec, &depth_msg.tov);
log_depth_map(&self.rec, "zed/left_camera/depth", depth)?;
log_u16_depth_map(&self.rec, "zed/left_camera/depth", depth)?;
}

if let Some(confidence) = confidence_msg.payload() {
apply_tov(&self.rec, &confidence_msg.tov);
log_depth_map(&self.rec, "zed/left_camera/confidence", confidence)?;
log_float_raster(&self.rec, "zed/left_camera/confidence", confidence)?;
}

if let Some(pointcloud) = pointcloud_msg.payload() {
Expand Down Expand Up @@ -353,69 +353,45 @@ fn log_axes(rec: &RecordingStream, path: &str, axis_len: f32) -> CuResult<()> {
.map_err(|e| CuError::new_with_cause("Failed to log axes", e))
}

fn log_depth_map<T>(rec: &RecordingStream, path: &str, payload: &T) -> CuResult<()>
where
T: ZedFloatRaster,
{
let bytes = payload.packed_bytes();
fn log_u16_depth_map(rec: &RecordingStream, path: &str, payload: &ZedDepthMap) -> CuResult<()> {
let bytes = payload.with_samples(|samples, format| {
pack_raster_bytes(samples, format.width, format.height, format.stride)
});
let image = DepthImage::from_data_type_and_bytes(
bytes,
[payload.width(), payload.height()],
rerun::ChannelDatatype::F32,
[payload.format.width, payload.format.height],
rerun::ChannelDatatype::U16,
)
.with_meter(1.0)
.with_meter(ZedDepthMap::encoding_descriptor().units_per_meter)
.with_colormap(rerun::components::Colormap::Turbo);

rec.log(path, &image)
.map_err(|e| CuError::new_with_cause("Failed to log depth image", e))
}

trait ZedFloatRaster {
fn width(&self) -> u32;
fn height(&self) -> u32;
fn packed_bytes(&self) -> Vec<u8>;
}

impl ZedFloatRaster for ZedDepthMap<Vec<f32>> {
fn width(&self) -> u32 {
self.format.width
}

fn height(&self) -> u32 {
self.format.height
}

fn packed_bytes(&self) -> Vec<u8> {
self.buffer_handle.with_inner(|inner| {
pack_f32_raster_bytes(
&inner[..],
self.format.width,
self.format.height,
self.format.stride,
)
})
}
}

impl ZedFloatRaster for ZedConfidenceMap<Vec<f32>> {
fn width(&self) -> u32 {
self.format.width
}

fn height(&self) -> u32 {
self.format.height
}
fn log_float_raster(
rec: &RecordingStream,
path: &str,
payload: &ZedConfidenceMap<Vec<f32>>,
) -> CuResult<()> {
let bytes = payload.buffer_handle.with_inner(|inner| {
pack_raster_bytes(
&inner[..],
payload.format.width,
payload.format.height,
payload.format.stride,
)
});
let image = DepthImage::from_data_type_and_bytes(
bytes,
[payload.format.width, payload.format.height],
rerun::ChannelDatatype::F32,
)
.with_meter(1.0)
.with_colormap(rerun::components::Colormap::Turbo);

fn packed_bytes(&self) -> Vec<u8> {
self.buffer_handle.with_inner(|inner| {
pack_f32_raster_bytes(
&inner[..],
self.format.width,
self.format.height,
self.format.stride,
)
})
}
rec.log(path, &image)
.map_err(|e| CuError::new_with_cause("Failed to log float raster", e))
}

fn log_rgba_image(
Expand Down Expand Up @@ -443,7 +419,12 @@ fn log_rgba_image(
.map_err(|e| CuError::new_with_cause("Failed to log RGBA image", e))
}

fn pack_f32_raster_bytes(values: &[f32], width: u32, height: u32, stride: u32) -> Vec<u8> {
fn pack_raster_bytes<T: bytemuck::Pod>(
values: &[T],
width: u32,
height: u32,
stride: u32,
) -> Vec<u8> {
let width = width as usize;
let height = height as usize;
let stride = stride as usize;
Expand Down
Loading