feat(pj_base): add GridMap canonical builtin object (SDK 0.26.0) - #185
Merged
Conversation
sdk::GridMap is a 2D grid whose cells carry named channels: the layered, generic-valued sibling of OccupancyGrid for elevation maps and multi-layer costmaps (grid_map_msgs/GridMap, foxglove.Grid). Row-major fixed-size cell records described by the shared PointField channel model, mirroring foxglove.Grid plus an explicit row_count so producers with that layout hand `data` over zero-copy; a NaN in a float channel means "no data". - grid_map.hpp + PJ.GridMap wire format (data = field 10) + grid_map_codec: decode rejects a layout the cell math could not index safely (zero stride with cells, row shorter than its columns, data shorter than row_count * row_stride, field past cell_stride) - kGridMap = 20 / PJ_BUILTIN_OBJECT_TYPE_GRID_MAP, splice-table entry, type-erased dispatcher cases - sdk::Vector2 in the geometry vocabulary (PJ.Vector2 already on the wire) - docs: builtin_type.md section, proto README, builtin counts; CHANGELOG; VERSION 0.26.0 (MINOR: additions only) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d ObjectWriter builder Review follow-up for the GridMap builtin: - The functional-v2 splice path decodes the canonical wire before the bulk bytes are attached, so a decode-time data-length check rejected every spliced GridMap. A wire without `data` now decodes with an empty span and the full layout check lives in validateGridMap(), run once bytes are in place. Field validation is unconditional and rejects unknown datatypes and zero counts (bytesPerElement instead of a local size table). - Both host splice-attachment switches gain the kGridMap case, and the parser-module ObjectWriter gains GridMapBuilder / gridMap() (object type 20, data field 10), with builder, splice and host-path tests for each. - PointField wire helpers shared by the PointCloud, VoxelGrid and GridMap codecs move to one private header (point_field_codec.hpp). - Docs: the packed cell layout matches foxglove.Grid, not the wire format or field descriptors (PackedElementField datatype numbering differs, count is always 1); cell_stride bound is the largest field end; pose composition wording; dispatcher invariant tests and the plugin guide count 18 builtins. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
sdk::GridMap, a 2D grid whose cells carry named channels: the layered, generic-valued sibling ofOccupancyGridfor elevation maps and multi-layer costmaps (grid_map_msgs/GridMap,foxglove.Grid). First of three PRs for rendering grid maps as a lit, colormapped heightfield in PlotJuggler 4's 3D view; the PJ4 renderer and the parser mappings follow once this is released.Design: row-major fixed-size cell records described by the shared
PointFieldchannel model, mirroringfoxglove.Gridplus an explicitrow_count, so Foxglove producers handdataover zero-copy and only ROSgrid_mapneeds a one-time transcode. A NaN in a float channel means "no data". Which channel is height, which drives color, and the colormap are viewer-side; the type carries no styling. Conventional channel names documented:elevation, andred/green/blue/alphafor RGBA.Changes
pj_base/builtin/grid_map.hppandGridMap.proto(data= field 10)grid_map_codec.{hpp,cpp}: decode rejects a layout the cell math could not index safely (zero stride with cells declared, row shorter than its columns,datashorter thanrow_count * row_stride, a field reaching pastcell_stride)BuiltinObjectType::kGridMap = 20,PJ_BUILTIN_OBJECT_TYPE_GRID_MAP = 20, splice-table entry, type-erased dispatcher casessdk::Vector2in the geometry vocabulary with wire helpers (PJ.Vector2already existed on the wire)builtin_type.mdsection plus classification and conversion rows, proto README, builtin counts in both CLAUDE.md filesVERSION0.26.0 and CHANGELOG entry. MINOR per the release policy: additions only, no existing struct, slot, or wire format changes.Test plan
GridMapCodecTestcases (round trip with NaN preserved, ownership, empty grid, four rejections) plus the enum, ABI-sentinel, metadata and splice-table tests extended; they failed onkGridMapundeclared before the implementation./build.sh --debug && ./test.sh(ASAN): 84/84abi_check(abigail not installed locally; additions only)After merge
Release 0.26.0. Not included, deliberately: a
GridMapBuilderin the WASM parser-module kit and a validity-mask (basic_fields) extension; both are additive if wanted later.🤖 Generated with Claude Code