Skip to content

feat(pj_base): add CameraInfo + OccupancyGridUpdate canonical builtin types#98

Open
facontidavide wants to merge 6 commits into
mainfrom
feat/add-camera-info-occupancy-grid-update
Open

feat(pj_base): add CameraInfo + OccupancyGridUpdate canonical builtin types#98
facontidavide wants to merge 6 commits into
mainfrom
feat/add-camera-info-occupancy-grid-update

Conversation

@facontidavide
Copy link
Copy Markdown
Contributor

Summary

Closes the two remaining canonical-object gaps for the ROS → PJ4 pipeline. A full audit of parser_ros + data_load_mcap showed every common ROS 2 message maps onto an existing builtin type except these two, which had no home:

  • CameraInfo (kCameraInfo = 14, owned) — pinhole camera calibration (K/D/R/P + dimensions). Needed for camera frustums, depth deprojection, and AR overlays. Mirrors sensor_msgs/CameraInfo; sub-window fields (binning/ROI) intentionally omitted (additive later). Correlated to an image topic by name convention (<ns>/camera_info<ns>/image_raw); carries no topic linkage.
  • OccupancyGridUpdate (kOccupancyGridUpdate = 15, byte-backed) — incremental sub-rectangle patch for a previously-published OccupancyGrid (map_msgs/OccupancyGridUpdate). Deliberately carries no origin/resolution: a patch is not independently placeable. A stateful consumer pairs it with the base grid (<base>/costmap_updates<base>/costmap) and positions it at origin + (x, y) * resolution. Keeps the producer stateless/cross-topic-blind; each patch is a self-contained snapshot so it stores/decodes like any other object (no replay at decode time).

Both follow the established templates — CameraInfo mirrors the owned FrameTransforms (packed-double matrices), OccupancyGridUpdate mirrors the byte-backed OccupancyGrid (Span + BufferAnchor).

Changes

  • New SDK structs, codecs, .proto contracts, and round-trip tests for both types.
  • Wired into BuiltinObjectType (C++) + PJ_builtin_object_type_t (C ABI), name()/parseBuiltinObjectType()/typeOf(), abi_layout_sentinels_test, builtin_object_test, pj_base/CMakeLists.txt.
  • docs/builtin_type.md + proto/pj/README.md updated; deduped a pre-existing duplicate RobotDescription row in the conversion-examples table.

Implementation notes

  • OccupancyGridUpdate::x/y are signed int32 cell offsets, encoded as plain varints by round-tripping the 32-bit pattern (full int32 range preserved; pinned by NegativeOffsetsRoundTrip).
  • This adds the SDK contract only. Producers (parser_ros) and consumers (PJ4 renderers / gridmap surface-stack) are deferred follow-ups. Adding a builtin type is ABI-additive and forward-compatible (std::any; unknown types → kNone).

Verification

  • Full build: 100% (exit 0).
  • ctest: 5/5 pass — camera_info_codec_test, occupancy_grid_update_codec_test, builtin_object_test, abi_layout_sentinels_test, occupancy_grid_codec_test.

🤖 Generated with Claude Code

… types

Closes the two remaining canonical-object gaps for the ROS pipeline: every
common ROS 2 message now maps onto a builtin type. Both are wired end-to-end
(struct + codec + proto + enum/ABI/typeOf + tests + docs) at enum values 14/15,
following the existing owned (FrameTransforms) and byte-backed (OccupancyGrid)
templates.

- CameraInfo (owned): pinhole calibration K/D/R/P + dimensions, packed-double
  codec. Mirrors sensor_msgs/CameraInfo; binning/ROI omitted (additive later).
  Correlated to an image topic by name convention; carries no topic linkage.
- OccupancyGridUpdate (byte-backed): incremental sub-rectangle patch for an
  OccupancyGrid. Deliberately no origin/resolution — a stateful consumer pairs
  it with the base grid (<base>/costmap_updates <-> <base>/costmap) and places
  it. Signed int32 cell offsets round-trip via the varint bit pattern.

Also dedups a duplicate RobotDescription row in the conversion-examples table.

Build 100%; ctest 5/5 (camera_info_codec, occupancy_grid_update_codec,
builtin_object, abi_layout_sentinels, occupancy_grid_codec).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Thank you for your contribution. Before we can merge it, please sign the Contributor License Agreement by posting a comment on this pull request with exactly the text below:


I have read the CLA Document and I hereby sign the CLA


Davide Faconti seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@facontidavide
Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

facontidavide and others added 5 commits May 27, 2026 22:20
Extends the SceneEntities canonical type so it can losslessly represent
visualization_msgs/Marker:

- ModelPrimitive (mesh asset by url or inline data) on SceneEntity — covers
  MESH_RESOURCE markers, which previously had no home.
- deletions[] of SceneEntityDeletion{MATCHING_ID, ALL} on SceneEntities — lets
  a snapshot producer express the removal half of a stateful stream
  (Marker DELETE / DELETEALL) without an empty-entity sentinel.

Both mirror fields in Foxglove's SceneEntity/SceneUpdate that the original port
omitted. Additive only: new struct fields + proto field numbers (models=14,
deletions=2), updated hand-written codec + round-trip tests, docs. No new
BuiltinObjectType, so the C ABI and abi_layout_sentinels are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
No consumers exist yet, so renumber freely to match Foxglove's
SceneEntity/SceneUpdate 1:1:

- SceneEntity: add metadata=6 (new KeyValuePair message) and shift the
  primitive lists to 7..14 (arrows..models), matching Foxglove exactly.
- AxesPrimitive has no Foxglove counterpart; it moves to field 15, after the
  Foxglove range, as a documented PlotJuggler extension.
- SceneEntities: order deletions=1, entities=2 (Foxglove SceneUpdate order).

C++ struct member names are unchanged, so producers/consumers that build by
name are unaffected; only the wire numbering moves. Codec + round-trip tests
updated (metadata coverage added).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the per-occurrence info.D.clear() in the field-6 handler. readPackedDouble
appends, so a distortion-coefficient array split across multiple packed chunks
(valid protobuf, e.g. after message merge/concatenation) was losing all but the
last chunk. Now matches the DepthImage decoder. (Codex review P2.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SceneEntity.metadata referenced an inline KeyValuePair message duplicated in
SceneEntities.proto, but a canonical pj/KeyValuePair.proto already exists (and
is imported by the annotation schemas). Import it instead of redefining, so
PJ.KeyValuePair has a single definition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A small owned builtin for textual log messages (timestamp, level, message,
name), for a log/console panel. Mirrors the core of Foxglove's Log schema and
rcl_interfaces/Log; the source-location fields (file, line) are intentionally
omitted.

Wires kLog=16 through builtin_object_abi.h (C enum), builtin_object.hpp
(enum + name/parse/typeOf + include), abi_layout_sentinels + builtin_object
tests, and CMake (codec source + round-trip test). New log.hpp / log_codec.*
/ Log.proto follow the established owned-type pattern; docs + proto README
updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant