Makes this node consumable by dora-image-view, which now takes std/media/v1/Image.
Two things were broken. dora's compatibility graph has no edge from std/core/v1/UInt8 to std/media/v1/Image, so wiring the two failed dora validate whatever the node actually sent:
- node "view": type mismatch on input "image": upstream zed-camera/image
declares "std/core/v1/UInt8", but expected "std/media/v1/Image"
And the viewer's flat-buffer fallback would not have decoded these frames anyway: it reads width/height metadata, and this node only published shape.
Every payload is now a typed Arrow array, built against the Arrow C data interface in src/arrow so the node still links no Arrow C++ — a heavy dependency on Jetson for a producer that exports one array per output and never reads one.
Breaking, hence 0.3.0:image_bgr is renamed to image, every payload changes shape, and the metadata that the payload now describes itself with is gone.
Related issues
None — requested directly.
Changes
src/arrow/array.{h,cc}: builds the exported arrays. image() packs an std/media/v1/Image row; float32() and string() the primitive payloads. Payload bytes are borrowed, not copied: dora IPC-encodes into shared memory inside send_arrow_output and then releases.
src/main.cc: image and depth go out as Image structs (bgr8 / 32FC1 with units=mm), camera_info and point_cloud as Float32 arrays, camera_state as a string. shape, dtype, layout and encoding metadata are dropped where the struct carries them; intrinsics, frame_id and both timestamps are unchanged.
dora-node.yml: retyped and renamed outputs, plus dora: ">=1.0" and an example: block, matching the sibling node manifests.
dataflow_view.yml replaces dataflow_plot.yml: the camera into dora-image-view on image, depth and camera_info. A git: node's manifest is not read at validate time, so the file repeats the viewer's contract in input_types: and both sides get checked now rather than at runtime.
tests/run.sh: new. Each exported array is round-tripped through pyarrow's C data interface to check the values a consumer reads back, and rebuilt under the address and undefined-behaviour sanitizers to check that releasing one frees the whole tree. Covers src/arrow only, so it needs no camera, no ZED SDK and no CUDA — CI runs it as a second job.
README: restructured to the shape of the sibling repositories, 1742 → 1430 words. The tick description was wrong in the README, the manifest and AGENTS.md: it does not trigger a grab. Capture is free-running at ZED_FPS and a tick forwards the newest frame there is, so the tick sets the publish rate and frames captured between two ticks are dropped — worth knowing, since the default 100 ms tick against the default 15 fps keeps two frames out of every three. The usage snippet also listed four of the five outputs.
Validation
tests/run.sh passes (and the leak check was confirmed to fail when release is broken)
dora validate (dora-cli 1.0.1) passes on dataflow.yml and dataflow_view.yml, and fails as expected when the manifest is reverted to std/core/v1/UInt8
src/main.cc compiles against the generated dora-node-api.h and the ZED SDK headers
Not run: the full build and a dataflow against a real camera. The machine this was written on has no OpenCV, which src/zed/capture.cc needs, so scripts/build.sh stops at configure. dataflow_view.yml has not been run end to end.
dataflow_view.yml pins the viewer at tag: v0.1.0 — the newest tag pushed to dora-image-view. Its README advertises v0.1.1, which is not on the remote yet; worth bumping here once it is.
# Summary
Makes this node consumable by [dora-image-view](https://gitea.liria.cl/liria/dora-image-view), which now takes `std/media/v1/Image`.
Two things were broken. dora's compatibility graph has no edge from `std/core/v1/UInt8` to `std/media/v1/Image`, so wiring the two failed `dora validate` whatever the node actually sent:
```
- node "view": type mismatch on input "image": upstream zed-camera/image
declares "std/core/v1/UInt8", but expected "std/media/v1/Image"
```
And the viewer's flat-buffer fallback would not have decoded these frames anyway: it reads `width`/`height` metadata, and this node only published `shape`.
Every payload is now a typed Arrow array, built against the Arrow C data interface in `src/arrow` so the node still links no Arrow C++ — a heavy dependency on Jetson for a producer that exports one array per output and never reads one.
**Breaking, hence 0.3.0:** `image_bgr` is renamed to `image`, every payload changes shape, and the metadata that the payload now describes itself with is gone.
## Related issues
None — requested directly.
## Changes
- `src/arrow/array.{h,cc}`: builds the exported arrays. `image()` packs an `std/media/v1/Image` row; `float32()` and `string()` the primitive payloads. Payload bytes are borrowed, not copied: dora IPC-encodes into shared memory inside `send_arrow_output` and then releases.
- `src/main.cc`: `image` and `depth` go out as `Image` structs (`bgr8` / `32FC1` with `units=mm`), `camera_info` and `point_cloud` as `Float32` arrays, `camera_state` as a string. `shape`, `dtype`, `layout` and `encoding` metadata are dropped where the struct carries them; intrinsics, `frame_id` and both timestamps are unchanged.
- `dora-node.yml`: retyped and renamed outputs, plus `dora: ">=1.0"` and an `example:` block, matching the sibling node manifests.
- `dataflow_view.yml` replaces `dataflow_plot.yml`: the camera into dora-image-view on `image`, `depth` and `camera_info`. A `git:` node's manifest is not read at validate time, so the file repeats the viewer's contract in `input_types:` and both sides get checked now rather than at runtime.
- `tests/run.sh`: new. Each exported array is round-tripped through pyarrow's C data interface to check the values a consumer reads back, and rebuilt under the address and undefined-behaviour sanitizers to check that releasing one frees the whole tree. Covers `src/arrow` only, so it needs no camera, no ZED SDK and no CUDA — CI runs it as a second job.
- README: restructured to the shape of the sibling repositories, 1742 → 1430 words. The tick description was wrong in the README, the manifest and AGENTS.md: it does not trigger a grab. Capture is free-running at `ZED_FPS` and a tick forwards the newest frame there is, so the tick sets the publish rate and frames captured between two ticks are dropped — worth knowing, since the default 100 ms tick against the default 15 fps keeps two frames out of every three. The usage snippet also listed four of the five outputs.
## Validation
- [x] `tests/run.sh` passes (and the leak check was confirmed to fail when `release` is broken)
- [x] `dora validate` (`dora-cli 1.0.1`) passes on `dataflow.yml` and `dataflow_view.yml`, and fails as expected when the manifest is reverted to `std/core/v1/UInt8`
- [x] `src/main.cc` compiles against the generated `dora-node-api.h` and the ZED SDK headers
- [ ] **Not run:** the full build and a dataflow against a real camera. The machine this was written on has no OpenCV, which `src/zed/capture.cc` needs, so `scripts/build.sh` stops at configure. `dataflow_view.yml` has not been run end to end.
`dataflow_view.yml` pins the viewer at `tag: v0.1.0` — the newest tag pushed to dora-image-view. Its README advertises `v0.1.1`, which is not on the remote yet; worth bumping here once it is.
dora-image-view takes std/media/v1/Image, and dora's compatibility graph
has no edge from std/core/v1/UInt8 to it, so wiring the two failed
`dora validate` whatever the node actually sent. Its flat-buffer fallback
would not have decoded these frames either: it reads width/height
metadata, and this node only published shape.
image and depth now go out as the Image struct, camera_info and
point_cloud as Float32 arrays and camera_state as a string, all built
against the Arrow C data interface in src/arrow so the node still links
no Arrow C++. Shape, dtype and encoding metadata are dropped where the
payload describes itself; intrinsics, frame_id and both timestamps are
unchanged. tests/run.sh covers the packing without a camera or the SDK,
round-tripping each array through pyarrow and rebuilding it under the
sanitizers.
Breaking: image_bgr is renamed to image and every payload changes shape.
dataflow_plot.yml is replaced by dataflow_view.yml, which wires the
viewer from a tag and repeats its contract in input_types so validate
checks both sides of the wiring.
The README carried explanations that belong in AGENTS.md; it now follows
the shape of the sibling node repositories and is a quarter shorter.
The tick description was also wrong: it does not trigger a grab. Capture
is free-running at ZED_FPS and a tick forwards the newest frame there is,
so the tick sets the publish rate, and frames captured between two ticks
are dropped. The usage snippet listed four of the five outputs, which
read as an omission rather than the choice it is.
This PR switches every output from raw byte slices with typed metadata to hand-built Arrow arrays against the C data interface (std/media/v1/Image for image/depth, Float32/String for the rest), renames image_bgr to image, and replaces the plot dataflow with one wired to dora-image-view. The C data interface usage checks out: buffer counts and formats (+s, I, u, Z, f) match the spec, borrowed payloads outlive send_arrow_output because the frame is held across each call and the release callbacks free the whole tree, and the new tests cover both the round-trip and the leak path. Blocking findings: none.
Findings
None.
Recommendation
Approve -- the packed arrays are spec-correct and lifecycle-safe, the manifest/dataflow/CI/docs move together with the payload change, and the only unverified piece (a live-camera run of dataflow_view.yml) is already disclosed in the PR validation list.
## Summary
This PR switches every output from raw byte slices with typed metadata to hand-built Arrow arrays against the C data interface (`std/media/v1/Image` for `image`/`depth`, `Float32`/`String` for the rest), renames `image_bgr` to `image`, and replaces the plot dataflow with one wired to dora-image-view. The C data interface usage checks out: buffer counts and formats (`+s`, `I`, `u`, `Z`, `f`) match the spec, borrowed payloads outlive `send_arrow_output` because the frame is held across each call and the release callbacks free the whole tree, and the new tests cover both the round-trip and the leak path. Blocking findings: none.
## Findings
None.
## Recommendation
**Approve** -- the packed arrays are spec-correct and lifecycle-safe, the manifest/dataflow/CI/docs move together with the payload change, and the only unverified piece (a live-camera run of `dataflow_view.yml`) is already disclosed in the PR validation list.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Makes this node consumable by dora-image-view, which now takes
std/media/v1/Image.Two things were broken. dora's compatibility graph has no edge from
std/core/v1/UInt8tostd/media/v1/Image, so wiring the two faileddora validatewhatever the node actually sent:And the viewer's flat-buffer fallback would not have decoded these frames anyway: it reads
width/heightmetadata, and this node only publishedshape.Every payload is now a typed Arrow array, built against the Arrow C data interface in
src/arrowso the node still links no Arrow C++ — a heavy dependency on Jetson for a producer that exports one array per output and never reads one.Breaking, hence 0.3.0:
image_bgris renamed toimage, every payload changes shape, and the metadata that the payload now describes itself with is gone.Related issues
None — requested directly.
Changes
src/arrow/array.{h,cc}: builds the exported arrays.image()packs anstd/media/v1/Imagerow;float32()andstring()the primitive payloads. Payload bytes are borrowed, not copied: dora IPC-encodes into shared memory insidesend_arrow_outputand then releases.src/main.cc:imageanddepthgo out asImagestructs (bgr8/32FC1withunits=mm),camera_infoandpoint_cloudasFloat32arrays,camera_stateas a string.shape,dtype,layoutandencodingmetadata are dropped where the struct carries them; intrinsics,frame_idand both timestamps are unchanged.dora-node.yml: retyped and renamed outputs, plusdora: ">=1.0"and anexample:block, matching the sibling node manifests.dataflow_view.ymlreplacesdataflow_plot.yml: the camera into dora-image-view onimage,depthandcamera_info. Agit:node's manifest is not read at validate time, so the file repeats the viewer's contract ininput_types:and both sides get checked now rather than at runtime.tests/run.sh: new. Each exported array is round-tripped through pyarrow's C data interface to check the values a consumer reads back, and rebuilt under the address and undefined-behaviour sanitizers to check that releasing one frees the whole tree. Coverssrc/arrowonly, so it needs no camera, no ZED SDK and no CUDA — CI runs it as a second job.ZED_FPSand a tick forwards the newest frame there is, so the tick sets the publish rate and frames captured between two ticks are dropped — worth knowing, since the default 100 ms tick against the default 15 fps keeps two frames out of every three. The usage snippet also listed four of the five outputs.Validation
tests/run.shpasses (and the leak check was confirmed to fail whenreleaseis broken)dora validate(dora-cli 1.0.1) passes ondataflow.ymlanddataflow_view.yml, and fails as expected when the manifest is reverted tostd/core/v1/UInt8src/main.cccompiles against the generateddora-node-api.hand the ZED SDK headerssrc/zed/capture.ccneeds, soscripts/build.shstops at configure.dataflow_view.ymlhas not been run end to end.dataflow_view.ymlpins the viewer attag: v0.1.0— the newest tag pushed to dora-image-view. Its README advertisesv0.1.1, which is not on the remote yet; worth bumping here once it is./bot review
Summary
This PR switches every output from raw byte slices with typed metadata to hand-built Arrow arrays against the C data interface (
std/media/v1/Imageforimage/depth,Float32/Stringfor the rest), renamesimage_bgrtoimage, and replaces the plot dataflow with one wired to dora-image-view. The C data interface usage checks out: buffer counts and formats (+s,I,u,Z,f) match the spec, borrowed payloads outlivesend_arrow_outputbecause the frame is held across each call and the release callbacks free the whole tree, and the new tests cover both the round-trip and the leak path. Blocking findings: none.Findings
None.
Recommendation
Approve -- the packed arrays are spec-correct and lifecycle-safe, the manifest/dataflow/CI/docs move together with the payload change, and the only unverified piece (a live-camera run of
dataflow_view.yml) is already disclosed in the PR validation list.