Skip to content

Commit dd0d6a7

Browse files
committed
remove logviz dependency
1 parent 74e9c6d commit dd0d6a7

4 files changed

Lines changed: 187 additions & 14 deletions

File tree

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ repository = "https://github.com/copper-project/zed"
2020

2121
[workspace.dependencies]
2222
cu29 = { git = "https://github.com/copper-project/copper-rs.git", branch = "master" }
23-
cu29-logviz = { git = "https://github.com/copper-project/copper-rs.git", branch = "master" }
2423
cu-sensor-payloads = { git = "https://github.com/copper-project/copper-rs.git", branch = "master" }
2524
cu-transform = { git = "https://github.com/copper-project/copper-rs.git", branch = "master" }
2625

components/sources/cu_zed/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ zed-sdk = { path = "../../libs/zed_sdk" }
3232

3333
[dev-dependencies]
3434
bytemuck = { workspace = true }
35-
cu29-logviz = { workspace = true }
3635
rerun = { workspace = true }
36+
serde_json = "1.0"
3737

3838
[[example]]
3939
name = "zed_rerun_demo"

components/sources/cu_zed/examples/zed_rerun_demo.rs

Lines changed: 142 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ use cu_zed::{
55
};
66
use cu29::clock::Tov;
77
use cu29::prelude::*;
8-
use cu29_logviz::{apply_tov, log_as_components, log_fallback_payload, log_imu, log_pointcloud};
9-
use rerun::{Arrows3D, DepthImage, Image, RecordingStream, RecordingStreamBuilder};
8+
use rerun::components::TransformMat3x3;
9+
use rerun::datatypes::Mat3x3;
10+
use rerun::{
11+
Arrows3D, DepthImage, Image, Points3D, RecordingStream, RecordingStreamBuilder, Scalars,
12+
TextDocument, Transform3D as RerunTransform3D,
13+
};
14+
use serde::Serialize;
15+
use std::collections::BTreeMap;
1016
use std::path::PathBuf;
1117

1218
#[copper_runtime(config = "examples/zed_rerun_demo.ron")]
@@ -69,10 +75,10 @@ impl CuSinkTask for ZedRerunSink {
6975
self.update_calibration(calibration_msg)?;
7076
self.update_transforms(transforms_msg)?;
7177

72-
if let Some((left, right)) = stereo_msg.payload() {
78+
if let Some(stereo) = stereo_msg.payload() {
7379
apply_tov(&self.rec, &stereo_msg.tov);
74-
log_rgba_image(&self.rec, "zed/left_camera/image", left)?;
75-
log_rgba_image(&self.rec, "zed/right_camera/image", right)?;
80+
log_rgba_image(&self.rec, "zed/left_camera/image", &stereo.left)?;
81+
log_rgba_image(&self.rec, "zed/right_camera/image", &stereo.right)?;
7682
}
7783

7884
if let Some(depth) = depth_msg.payload() {
@@ -163,7 +169,7 @@ impl ZedRerunSink {
163169

164170
fn log_rig_transforms(&self, transforms: &ZedRigTransforms, tov: &Tov) -> CuResult<()> {
165171
apply_tov(&self.rec, tov);
166-
log_as_components(
172+
log_transform(
167173
&self.rec,
168174
"zed/right_camera",
169175
&transforms.left_to_right.to_transform3d(),
@@ -176,7 +182,7 @@ impl ZedRerunSink {
176182
log_axes(&self.rec, "zed/right_camera", 0.08)?;
177183

178184
if transforms.has_camera_to_imu {
179-
log_as_components(
185+
log_transform(
180186
&self.rec,
181187
"zed/imu",
182188
&transforms.camera_to_imu.to_transform3d(),
@@ -193,6 +199,135 @@ impl ZedRerunSink {
193199
}
194200
}
195201

202+
fn tov_to_secs(tov: &Tov) -> Option<f64> {
203+
match tov {
204+
Tov::Time(t) => Some(t.0 as f64 / 1_000_000_000.0),
205+
Tov::Range(r) => Some(r.start.0 as f64 / 1_000_000_000.0),
206+
Tov::None => None,
207+
}
208+
}
209+
210+
fn apply_tov(rec: &RecordingStream, tov: &Tov) {
211+
if let Some(secs) = tov_to_secs(tov) {
212+
rec.set_duration_secs("tov", secs);
213+
} else {
214+
rec.reset_time();
215+
}
216+
}
217+
218+
fn log_scalar(rec: &RecordingStream, path: &str, value: f64) -> CuResult<()> {
219+
rec.log(path, &Scalars::new([value]))
220+
.map_err(|e| CuError::new_with_cause("Failed to log scalar", e))
221+
}
222+
223+
fn log_pointcloud<const N: usize>(
224+
rec: &RecordingStream,
225+
path: &str,
226+
pointcloud: &cu_sensor_payloads::PointCloudSoa<N>,
227+
) -> CuResult<()> {
228+
let len = pointcloud.len.min(N);
229+
let points = (0..len)
230+
.map(|i| {
231+
[
232+
pointcloud.x[i].value,
233+
pointcloud.y[i].value,
234+
pointcloud.z[i].value,
235+
]
236+
})
237+
.collect::<Vec<_>>();
238+
239+
rec.log(path, &Points3D::new(points))
240+
.map_err(|e| CuError::new_with_cause("Failed to log point cloud", e))
241+
}
242+
243+
fn log_imu(rec: &RecordingStream, base: &str, imu: &ImuPayload) -> CuResult<()> {
244+
log_scalar(rec, &format!("{}/accel_x", base), imu.accel_x.value as f64)?;
245+
log_scalar(rec, &format!("{}/accel_y", base), imu.accel_y.value as f64)?;
246+
log_scalar(rec, &format!("{}/accel_z", base), imu.accel_z.value as f64)?;
247+
log_scalar(rec, &format!("{}/gyro_x", base), imu.gyro_x.value as f64)?;
248+
log_scalar(rec, &format!("{}/gyro_y", base), imu.gyro_y.value as f64)?;
249+
log_scalar(rec, &format!("{}/gyro_z", base), imu.gyro_z.value as f64)?;
250+
log_scalar(
251+
rec,
252+
&format!("{}/temperature_c", base),
253+
imu.temperature
254+
.get::<cu29::units::si::thermodynamic_temperature::degree_celsius>() as f64,
255+
)?;
256+
Ok(())
257+
}
258+
259+
fn log_transform(
260+
rec: &RecordingStream,
261+
path: &str,
262+
transform: &cu_transform::Transform3D<f32>,
263+
) -> CuResult<()> {
264+
let matrix = transform.to_matrix();
265+
let translation = [matrix[3][0], matrix[3][1], matrix[3][2]];
266+
let mat3 = [
267+
matrix[0][0],
268+
matrix[0][1],
269+
matrix[0][2],
270+
matrix[1][0],
271+
matrix[1][1],
272+
matrix[1][2],
273+
matrix[2][0],
274+
matrix[2][1],
275+
matrix[2][2],
276+
];
277+
let transform = RerunTransform3D::new()
278+
.with_translation(translation)
279+
.with_mat3x3(TransformMat3x3::from(Mat3x3(mat3)));
280+
281+
rec.log(path, &transform)
282+
.map_err(|e| CuError::new_with_cause("Failed to log transform", e))
283+
}
284+
285+
fn flatten_json(prefix: &str, value: &serde_json::Value) -> BTreeMap<String, serde_json::Value> {
286+
let mut out = BTreeMap::new();
287+
match value {
288+
serde_json::Value::Object(map) => {
289+
for (key, value) in map {
290+
let path = format!("{}/{}", prefix, key);
291+
out.extend(flatten_json(&path, value));
292+
}
293+
}
294+
serde_json::Value::Array(values) => {
295+
for (idx, value) in values.iter().enumerate() {
296+
let path = format!("{}/{}", prefix, idx);
297+
out.extend(flatten_json(&path, value));
298+
}
299+
}
300+
_ => {
301+
out.insert(prefix.to_string(), value.clone());
302+
}
303+
}
304+
out
305+
}
306+
307+
fn log_fallback_payload<T: Serialize>(
308+
rec: &RecordingStream,
309+
base: &str,
310+
payload: &T,
311+
) -> CuResult<()> {
312+
let value = serde_json::to_value(payload)
313+
.map_err(|e| CuError::new_with_cause("Failed to serialize payload", e))?;
314+
let flat = flatten_json(base, &value);
315+
for (path, value) in flat {
316+
if let Some(num) = value.as_f64() {
317+
log_scalar(rec, &path, num)?;
318+
} else if let Some(value_bool) = value.as_bool() {
319+
log_scalar(rec, &path, if value_bool { 1.0 } else { 0.0 })?;
320+
} else if let Some(text) = value.as_str() {
321+
rec.log(path.as_str(), &TextDocument::new(text))
322+
.map_err(|e| CuError::new_with_cause("Failed to log text", e))?;
323+
} else if !value.is_null() {
324+
rec.log(path.as_str(), &TextDocument::new(value.to_string()))
325+
.map_err(|e| CuError::new_with_cause("Failed to log text", e))?;
326+
}
327+
}
328+
Ok(())
329+
}
330+
196331
fn pinhole_from_intrinsics(intrinsics: &cu_zed::ZedCameraIntrinsics) -> rerun::Pinhole {
197332
let projection = rerun::components::PinholeProjection::from_focal_length_and_principal_point(
198333
[intrinsics.fx, intrinsics.fy],

components/sources/cu_zed/src/lib.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,54 @@ mod payloads;
22

33
pub use payloads::*;
44

5+
use bincode::de::Decoder;
6+
use bincode::error::DecodeError;
7+
use bincode::{Decode, Encode};
58
use cu_sensor_payloads::{
69
BarometerPayload, CuImage, Distance, ImuPayload, MagnetometerPayload, PointCloudSoa,
710
Reflectivity,
811
};
912
use cu29::prelude::*;
1013
use cu29::units::si::length::meter;
1114
use cu29::units::si::ratio::percent;
15+
use serde::{Deserialize, Serialize};
1216

13-
pub type ZedStereoImages = (CuImage<Vec<u8>>, CuImage<Vec<u8>>);
17+
#[derive(Default, Debug, Clone, Encode, Serialize, Deserialize, Reflect)]
18+
#[reflect(from_reflect = false, no_field_bounds, type_path = false)]
19+
pub struct ZedStereoImages {
20+
pub left: CuImage<Vec<u8>>,
21+
pub right: CuImage<Vec<u8>>,
22+
}
23+
24+
impl TypePath for ZedStereoImages {
25+
fn type_path() -> &'static str {
26+
"cu_zed::ZedStereoImages"
27+
}
28+
29+
fn short_type_path() -> &'static str {
30+
"ZedStereoImages"
31+
}
32+
33+
fn type_ident() -> Option<&'static str> {
34+
Some("ZedStereoImages")
35+
}
36+
37+
fn crate_name() -> Option<&'static str> {
38+
Some("cu_zed")
39+
}
40+
41+
fn module_path() -> Option<&'static str> {
42+
Some("cu_zed")
43+
}
44+
}
45+
46+
impl Decode<()> for ZedStereoImages {
47+
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
48+
let left: CuImage<Vec<u8>> = Decode::decode(decoder)?;
49+
let right: CuImage<Vec<u8>> = Decode::decode(decoder)?;
50+
Ok(Self { left, right })
51+
}
52+
}
1453

1554
pub type ZedSourceOutputs = (
1655
CuMsg<ZedStereoImages>,
@@ -458,10 +497,10 @@ mod linux_impl {
458497
.retrieve_depth(&mut slot.depth.mat)
459498
.map_err(|e| CuError::new_with_cause("Could not retrieve ZED depth map", e))?;
460499

461-
stereo.set_payload((
462-
image_payload_from_handle(seq, &slot.left.handle, self.left_format),
463-
image_payload_from_handle(seq, &slot.right.handle, self.right_format),
464-
));
500+
stereo.set_payload(ZedStereoImages {
501+
left: image_payload_from_handle(seq, &slot.left.handle, self.left_format),
502+
right: image_payload_from_handle(seq, &slot.right.handle, self.right_format),
503+
});
465504
stereo.tov = Tov::Time(frame_tov);
466505

467506
depth.set_payload(raster_payload_from_handle(

0 commit comments

Comments
 (0)