Skip to content

feat(costmap): generic grid projection primitives and typed layer access#13

Merged
MJohnson459 merged 1 commit into
mainfrom
feat/projection-layer-primitives
Jun 16, 2026
Merged

feat(costmap): generic grid projection primitives and typed layer access#13
MJohnson459 merged 1 commit into
mainfrom
feat/projection-layer-primitives

Conversation

@MJohnson459

Copy link
Copy Markdown
Owner

Add the substrate needed to feed an arbitrary, caller-owned Grid2d (terrain class, learned traversability, instance ids, ...) into the u8 master costmap as a first-class layer, and to read it back for control — without putting any semantic/learned types in the crate itself.

  • project_into + MergePolicy (src/costmap/project.rs): the keystone generic projection of Grid2d -> master via a T -> Option closure. merge_overwrite/merge_max/merge_max_keep_unknown now delegate to it (one codepath; signatures unchanged).
  • Typed layer access (src/costmap/layered.rs): Layer: Any, LayerId, and add_layer returning a LayerId plus layer/layer_mut downcast accessors, so a layer can own its grid and the caller ingests/queries through &mut LayeredCostmap (no Arc/RwLock). Also makes every layer's internal grid inspectable.
  • ProjectionLayer (src/layers/projection.rs): an owned-source layer (nav2 CostmapLayer generalized over T + a projection closure). For rolling windows it re-centres the source in update_bounds so producers that fill during update_costs see an already-centred grid.
  • cost_from_unit/cost_from_range (src/types/cost.rs) and Grid2d::layout_matches (src/grid/grid2d.rs).
  • examples/learned_traversability.rs: end-to-end rolling-window demo (mock model -> ProjectionLayer -> inflation -> read-back control decision). SimLidarLayer in local_costmap_lidar.rs refactored to compose ProjectionLayer, validating the abstraction against the existing pattern.

Tests cover projection policies, layout_matches, cost conversion, typed access, update_bounds re-centring/extent, the rolling end-to-end path, and projection seeding inflation.

Add the substrate needed to feed an arbitrary, caller-owned Grid2d<T>
(terrain class, learned traversability, instance ids, ...) into the u8
master costmap as a first-class layer, and to read it back for control —
without putting any semantic/learned types in the crate itself.

- project_into + MergePolicy (src/costmap/project.rs): the keystone
  generic projection of Grid2d<T> -> master via a T -> Option<u8> closure.
  merge_overwrite/merge_max/merge_max_keep_unknown now delegate to it
  (one codepath; signatures unchanged).
- Typed layer access (src/costmap/layered.rs): Layer: Any, LayerId, and
  add_layer returning a LayerId plus layer/layer_mut downcast accessors,
  so a layer can own its grid and the caller ingests/queries through
  &mut LayeredCostmap (no Arc/RwLock). Also makes every layer's internal
  grid inspectable.
- ProjectionLayer<T> (src/layers/projection.rs): an owned-source layer
  (nav2 CostmapLayer generalized over T + a projection closure). For
  rolling windows it re-centres the source in update_bounds so producers
  that fill during update_costs see an already-centred grid.
- cost_from_unit/cost_from_range (src/types/cost.rs) and
  Grid2d::layout_matches (src/grid/grid2d.rs).
- examples/learned_traversability.rs: end-to-end rolling-window demo
  (mock model -> ProjectionLayer -> inflation -> read-back control
  decision). SimLidarLayer in local_costmap_lidar.rs refactored to
  compose ProjectionLayer<u8>, validating the abstraction against the
  existing pattern.

Tests cover projection policies, layout_matches, cost conversion, typed
access, update_bounds re-centring/extent, the rolling end-to-end path,
and projection seeding inflation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MJohnson459 MJohnson459 merged commit 711865a into main Jun 16, 2026
4 checks passed
@MJohnson459 MJohnson459 deleted the feat/projection-layer-primitives branch June 16, 2026 11:32
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