Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
334433f
Basic structure
aclauer May 22, 2026
b1fe692
Mesh loader
aclauer May 22, 2026
6d0ca54
Add scenarios and render start and goal
aclauer May 22, 2026
21110ac
Setup
aclauer May 22, 2026
7d0d2ce
The floor is purp and assume cube
aclauer May 22, 2026
2aba8e5
Basic surface detection
aclauer May 22, 2026
d9d6c5b
Dilation and erosion
aclauer May 22, 2026
662bf55
Way point graph
aclauer May 23, 2026
1f7c90b
Merge branch 'main' into andrew/feat/dev-path-planning
aclauer May 25, 2026
39cbf69
Rename to nodes
aclauer May 25, 2026
7014f79
Refactor into node place and edge add
aclauer May 25, 2026
6bbf294
Perf improvements
aclauer May 25, 2026
696e163
We live in a predetermined simulation
aclauer May 25, 2026
b266e19
Validate connected surface components
aclauer May 25, 2026
d3a530c
Better node placement and edge connection
aclauer May 25, 2026
51e40d9
Perf improvement
aclauer May 25, 2026
8253b82
Path planning
aclauer May 25, 2026
f446cb9
Refactor and run tests
aclauer May 26, 2026
07086ea
Avoid walls
aclauer May 26, 2026
d9270b2
Don't dilate on walls
aclauer May 26, 2026
44b24b2
Some nice pastel colors
aclauer May 26, 2026
e6633c9
Point and click for start and goal
aclauer May 26, 2026
dce2be9
Bug fix
aclauer May 26, 2026
94c6697
Color edges by cost
aclauer May 26, 2026
143cdfc
Bug fix
aclauer May 26, 2026
3ac4a16
Better adjacency criteria
aclauer May 26, 2026
8122836
Merge changes
aclauer May 28, 2026
e9674bf
Router for start and goal clicks
aclauer May 29, 2026
125d4ee
Rust framework
aclauer May 29, 2026
33d80db
Voxels
aclauer May 29, 2026
e074bb3
Adjacency
aclauer May 29, 2026
2c83399
Surfaces
aclauer May 29, 2026
cac8a70
Nodes
aclauer May 29, 2026
8d5c17e
Edges via Dijkstra
aclauer May 29, 2026
4d832e7
Planner
aclauer May 29, 2026
6d8b8ee
Wire to main
aclauer May 29, 2026
8482e75
Surface rewrite
aclauer May 29, 2026
dd74e05
Delete bad code, implement good code (hashmap for surface adjacency)
aclauer May 29, 2026
1080e0c
Fix edge detection
aclauer May 29, 2026
6c7d420
Fix morphology
aclauer May 29, 2026
2be8969
Move publishes and timing
aclauer May 29, 2026
8a6f3d1
Fix start and goal snapping
aclauer May 29, 2026
aca32f4
Optimizations
aclauer May 29, 2026
176af2d
Fix scenarios
aclauer May 29, 2026
dcd70bc
Merge branch 'main' into andrew/feat/dev-path-planning
aclauer May 29, 2026
462585e
Remove Python code
aclauer May 29, 2026
c9168e5
Remove unused code
aclauer May 29, 2026
6424a05
Remove unused code
aclauer May 29, 2026
0a7e3bf
Rename file
aclauer May 29, 2026
8deb4d1
Remove old gitignores for other rust crates
aclauer May 29, 2026
db7f3b0
Rayon
aclauer May 30, 2026
734382e
Fix typing
aclauer Jun 1, 2026
40af60a
Merge branch 'main' into andrew/feat/dev-path-planning
aclauer Jun 1, 2026
0f3149f
Switch to vectors and ids
aclauer May 30, 2026
1385a91
Clean up
aclauer Jun 1, 2026
c9f28dd
Move to 3d nav
aclauer Jun 1, 2026
13536d7
Type maxing
aclauer Jun 1, 2026
4a42f95
Fix
aclauer Jun 1, 2026
da7ef7d
Merge branch 'main' into andrew/feat/dev-path-planning
aclauer Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ package-lock.json
dist/
build/

# Rust build artifacts
**/target/
**/*.rs.bk

# Ignore data directory but keep .lfs subdirectory
data/*
!data/.lfs/
Expand Down
1 change: 0 additions & 1 deletion dimos/mapping/ray_tracing/rust/.gitignore

This file was deleted.

120 changes: 120 additions & 0 deletions dimos/navigation/nav_3d/evaluator/blueprints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Copyright 2026 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Blueprint for the path-planner evaluator.

Wires the Evaluator and MLSPlannerNative together and bridges all streams to rerun.
Run with::

dimos run path-planner-eval
"""

from __future__ import annotations

import numpy as np
import rerun as rr
from rerun._baseclasses import Archetype

from dimos.core.coordination.blueprints import autoconnect
from dimos.msgs.geometry_msgs.PoseStamped import PoseStamped
from dimos.msgs.nav_msgs.LineSegments3D import LineSegments3D
from dimos.msgs.sensor_msgs.PointCloud2 import PointCloud2
from dimos.navigation.nav_3d.evaluator.evaluator import Evaluator
from dimos.navigation.nav_3d.mls_planner.mls_planner_native import MLSPlannerNative
from dimos.navigation.nav_stack.modules.click_start_goal_router.click_start_goal_router import (
ClickStartGoalRouter,
)
from dimos.visualization.rerun.bridge import RerunBridgeModule
from dimos.visualization.rerun.websocket_server import RerunWebSocketServer

_POSE_MARKER_RADIUS = 0.4
# Small lift so graph artifacts render visibly above the surface points instead of z-fighting.
_GRAPH_Z_LIFT = 0.05


def _render_start_pose(msg: PoseStamped) -> Archetype:
return rr.Points3D(
positions=[[msg.x, msg.y, msg.z]],
colors=[[0, 255, 0]],
radii=[_POSE_MARKER_RADIUS],
)


def _render_goal_pose(msg: PoseStamped) -> Archetype:
return rr.Points3D(
positions=[[msg.x, msg.y, msg.z]],
colors=[[255, 0, 0]],
radii=[_POSE_MARKER_RADIUS],
)


def _render_global_map(msg: PointCloud2) -> Archetype:
return msg.to_rerun(voxel_size=0.03, colors=[128, 128, 128])


def _render_surface_map(msg: PointCloud2) -> Archetype:
return msg.to_rerun(voxel_size=0.1, colors=[40, 75, 130])


def _render_nodes(msg: PointCloud2) -> Archetype:
pts, _ = msg.as_numpy()
if pts is None or len(pts) == 0:
return rr.Points3D([])
pts = pts.copy()
pts[:, 2] += _GRAPH_Z_LIFT
return rr.Points3D(positions=pts, colors=[[75, 156, 211]], radii=[0.15])


def _render_node_edges(msg: LineSegments3D) -> Archetype:
"""Color each segment by its safe-adj weight on a log-scale green->red gradient."""
if not msg._segments:
return rr.LineStrips3D([])
weights = np.asarray(msg._traversability, dtype=np.float64)
log_w = np.log10(np.maximum(weights, 1e-6))
lo, hi = float(log_w.min()), float(log_w.max())
norm = (log_w - lo) / (hi - lo) if hi > lo else np.zeros_like(log_w)
r = (255 * norm).astype(np.uint8)
g = (255 * (1.0 - norm)).astype(np.uint8)
b = np.full_like(r, 60)
a = np.full_like(r, 220)
colors = np.column_stack([r, g, b, a])
strips = [
[
[p1[0], p1[1], p1[2] + _GRAPH_Z_LIFT],
[p2[0], p2[1], p2[2] + _GRAPH_Z_LIFT],
]
for p1, p2 in msg._segments
]
return rr.LineStrips3D(strips, colors=colors, radii=[0.04] * len(strips))


path_planner_eval = autoconnect(
Evaluator.blueprint(),
MLSPlannerNative.blueprint(),
ClickStartGoalRouter.blueprint(),
RerunWebSocketServer.blueprint(),
RerunBridgeModule.blueprint(
visual_override={
"world/start_pose": _render_start_pose,
"world/goal_pose": _render_goal_pose,
"world/global_map": _render_global_map,
Comment thread
aclauer marked this conversation as resolved.
"world/surface_map": _render_surface_map,
"world/nodes": _render_nodes,
"world/node_edges": _render_node_edges,
}
),
)


__all__ = ["path_planner_eval"]
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from dimos.msgs.geometry_msgs.PoseStamped import PoseStamped
from dimos.msgs.nav_msgs.Path import Path
from dimos.msgs.sensor_msgs.PointCloud2 import PointCloud2
from dimos.navigation.nav_stack.evaluator.scenarios import (
from dimos.navigation.nav_3d.evaluator.scenarios import (
PlannerScenario,
default_scenarios,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from dimos.msgs.geometry_msgs.PoseStamped import PoseStamped
from dimos.msgs.sensor_msgs.PointCloud2 import PointCloud2
from dimos.navigation.nav_stack.evaluator.mesh_loader import load_voxelized_mesh
from dimos.navigation.nav_3d.evaluator.mesh_loader import load_voxelized_mesh
from dimos.utils.logging_config import setup_logger

logger = setup_logger()
Expand Down
56 changes: 56 additions & 0 deletions dimos/navigation/nav_3d/mls_planner/mls_planner_native.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2026 Dimensional Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Rust multi-level surface path planner."""

from __future__ import annotations

from dimos.core.native_module import NativeModule, NativeModuleConfig
from dimos.core.stream import In, Out
from dimos.msgs.geometry_msgs.PoseStamped import PoseStamped
from dimos.msgs.nav_msgs.LineSegments3D import LineSegments3D
from dimos.msgs.nav_msgs.Path import Path
from dimos.msgs.sensor_msgs.PointCloud2 import PointCloud2


class MLSPlannerNativeConfig(NativeModuleConfig):
cwd: str | None = "rust"
executable: str = "target/release/mls_planner"
build_command: str | None = "cargo build --release"
stdin_config: bool = True

world_frame: str = "map"
voxel_size: float = 0.1
robot_height: float = 1.5

surface_dilation_passes: int = 3
surface_erosion_passes: int = 3
node_spacing_m: float = 1.0
node_wall_buffer_m: float = 0.3
node_step_threshold_m: float = 0.25


class MLSPlannerNative(NativeModule):
"""Rust-backed MLS planner."""

config: MLSPlannerNativeConfig

global_map: In[PointCloud2]
start_pose: In[PoseStamped]
goal_pose: In[PoseStamped]

path: Out[Path]
surface_map: Out[PointCloud2]
nodes: Out[PointCloud2]
node_edges: Out[LineSegments3D]
Loading
Loading