Skip to content

Trajectory controller and navigation structure - #3731

Closed
leshy wants to merge 7 commits into
mainfrom
fix/ivan/motion_stability
Closed

leshy wants to merge 7 commits into
mainfrom
fix/ivan/motion_stability

Conversation

@leshy

@leshy leshy commented Aug 27, 2026

Copy link
Copy Markdown
Member

there are a few things here that can be split into separate PRs but nav team is the only consumer so keeping here unless we decide otherwise

restructure of navigation/ much cleaner folder, new specs

class GlobalPlanner(Protocol):
    tf: In[TFMessage]
    goal: In[PointStamped]

    path: Out[Path]

class LocalPlanner(Protocol):
    tf: IO[TFMessage]
    planner_path: In[Path]
    local_map: In[PointCloud2]

    path: Out[Path]


class TrajectoryFollower(Protocol):
    tf: IO[TFMessage]
    path: In[Path]

    nav_cmd_vel: Out[Twist]

generic mcap mem2 decoder of all dimos msgs + tests

bridge hacky feature

we need to be able to explicitly subscribe to just SOME topics not all, so that they are not sent over network or decoded by py

module introspection fixes

module.io() hides default internal RPCs

lidar module config

removed global env reading, switched to local module config

distributed architecture for nav

we run go2-zenoh-motion-pointlio on go2 jetson and dimos --robot-ip go22 run go2-viewer on the laptop

this means zenoh (network robust) subs go over network, and rerun rendering and RPC happens locally on the laptop

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (140 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

❌ 7 Tests Failed:

Tests completed Failed Passed Skipped
5390 7 5383 191
View the top 3 failed test(s) by shortest run time
dimos.navigation.motion.adapter.test_planner::test_hold_publishes_single_pose_stub_at_the_current_pose
Stack Traces | 0.005s run time
emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
>           import dimos_motion2_target  # noqa: F401
E           ModuleNotFoundError: No module named 'dimos_motion2_target'

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:144: ModuleNotFoundError

The above exception was the direct cause of the following exception:

    def test_hold_publishes_single_pose_stub_at_the_current_pose():
>       planner, published = _holding_planner()


.../motion/adapter/test_planner.py:111: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../motion/adapter/test_planner.py:104: in _holding_planner
    planner = _planner()
.../motion/adapter/test_planner.py:61: in _planner
    planner = MotionPlanner(**config)
        config     = {}
.../motion/adapter/planner.py:241: in __init__
    self._episode: PlannerEpisode = self.config.planner(self._emb)
        __class__  = <class 'dimos.navigation.motion.adapter.planner.MotionPlanner'>
        kwargs     = {}
        self       = <dimos.navigation.motion.adapter.planner.MotionPlanner object at 0xff8adc060cb0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
            import dimos_motion2_target  # noqa: F401
        except ImportError as e:
>           raise ImportError(f"dimos_motion2_target is not built; run: {BUILD_CMD}") from e
E           ImportError: dimos_motion2_target is not built; run: uv run maturin develop --uv --release -m .../planner/rust/Cargo.toml

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:146: ImportError
dimos.navigation.motion.adapter.test_planner::test_a_map_with_a_non_finite_return_still_plans
Stack Traces | 0.006s run time
emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
>           import dimos_motion2_target  # noqa: F401
E           ModuleNotFoundError: No module named 'dimos_motion2_target'

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:144: ModuleNotFoundError

The above exception was the direct cause of the following exception:

    def test_a_map_with_a_non_finite_return_still_plans():
        # one NaN x used to reach the search as a NaN grid corner: every tick
        # raised, "keeping the last published path" forever
>       planner, published = _holding_planner()


.../motion/adapter/test_planner.py:236: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../motion/adapter/test_planner.py:104: in _holding_planner
    planner = _planner()
.../motion/adapter/test_planner.py:61: in _planner
    planner = MotionPlanner(**config)
        config     = {}
.../motion/adapter/planner.py:241: in __init__
    self._episode: PlannerEpisode = self.config.planner(self._emb)
        __class__  = <class 'dimos.navigation.motion.adapter.planner.MotionPlanner'>
        kwargs     = {}
        self       = <dimos.navigation.motion.adapter.planner.MotionPlanner object at 0xff8adc105c70>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
            import dimos_motion2_target  # noqa: F401
        except ImportError as e:
>           raise ImportError(f"dimos_motion2_target is not built; run: {BUILD_CMD}") from e
E           ImportError: dimos_motion2_target is not built; run: uv run maturin develop --uv --release -m .../planner/rust/Cargo.toml

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:146: ImportError
dimos.navigation.motion.adapter.test_planner::test_hold_warns_once_per_stale_episode
Stack Traces | 0.006s run time
emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
>           import dimos_motion2_target  # noqa: F401
E           ModuleNotFoundError: No module named 'dimos_motion2_target'

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:144: ModuleNotFoundError

The above exception was the direct cause of the following exception:

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xff8adc0b2b40>

    def test_hold_warns_once_per_stale_episode(monkeypatch):
        warnings = []
        monkeypatch.setattr(
            planner_module.logger, "warning", lambda msg, **kw: warnings.append(msg), raising=False
        )
>       planner, _published = _holding_planner()

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xff8adc0b2b40>
warnings   = []

.../motion/adapter/test_planner.py:143: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../motion/adapter/test_planner.py:104: in _holding_planner
    planner = _planner()
.../motion/adapter/test_planner.py:61: in _planner
    planner = MotionPlanner(**config)
        config     = {}
.../motion/adapter/planner.py:241: in __init__
    self._episode: PlannerEpisode = self.config.planner(self._emb)
        __class__  = <class 'dimos.navigation.motion.adapter.planner.MotionPlanner'>
        kwargs     = {}
        self       = <dimos.navigation.motion.adapter.planner.MotionPlanner object at 0xff8adc062f00>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
            import dimos_motion2_target  # noqa: F401
        except ImportError as e:
>           raise ImportError(f"dimos_motion2_target is not built; run: {BUILD_CMD}") from e
E           ImportError: dimos_motion2_target is not built; run: uv run maturin develop --uv --release -m .../planner/rust/Cargo.toml

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:146: ImportError
dimos.navigation.motion.adapter.test_planner::test_a_stale_pose_is_a_missing_pose
Stack Traces | 0.008s run time
emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
>           import dimos_motion2_target  # noqa: F401
E           ModuleNotFoundError: No module named 'dimos_motion2_target'

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:144: ModuleNotFoundError

The above exception was the direct cause of the following exception:

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xff8adc0c9c70>

    def test_a_stale_pose_is_a_missing_pose(monkeypatch):
        # the pose is the world_frame -> base_frame edge on tf, read per tick; an
        # edge whose stamp stopped advancing is no pose at all, and the tick says so
        waiting = []
        monkeypatch.setattr(
            "dimos.navigation.motion.adapter.diagnostics.logger.warning",
            lambda msg, **kw: waiting.append(kw.get("on", "")),
            raising=False,
        )
>       planner, published = _holding_planner()

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xff8adc0c9c70>
waiting    = []

.../motion/adapter/test_planner.py:167: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../motion/adapter/test_planner.py:104: in _holding_planner
    planner = _planner()
.../motion/adapter/test_planner.py:61: in _planner
    planner = MotionPlanner(**config)
        config     = {}
.../motion/adapter/planner.py:241: in __init__
    self._episode: PlannerEpisode = self.config.planner(self._emb)
        __class__  = <class 'dimos.navigation.motion.adapter.planner.MotionPlanner'>
        kwargs     = {}
        self       = <dimos.navigation.motion.adapter.planner.MotionPlanner object at 0xff8adc0c9d90>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
            import dimos_motion2_target  # noqa: F401
        except ImportError as e:
>           raise ImportError(f"dimos_motion2_target is not built; run: {BUILD_CMD}") from e
E           ImportError: dimos_motion2_target is not built; run: uv run maturin develop --uv --release -m .../planner/rust/Cargo.toml

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:146: ImportError
dimos.navigation.motion.adapter.test_planner::test_hold_stub_stops_the_controller
Stack Traces | 0.008s run time
emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
>           import dimos_motion2_target  # noqa: F401
E           ModuleNotFoundError: No module named 'dimos_motion2_target'

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:144: ModuleNotFoundError

The above exception was the direct cause of the following exception:

    def test_hold_stub_stops_the_controller():
>       planner, published = _holding_planner()


.../motion/adapter/test_planner.py:131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../motion/adapter/test_planner.py:104: in _holding_planner
    planner = _planner()
.../motion/adapter/test_planner.py:61: in _planner
    planner = MotionPlanner(**config)
        config     = {}
.../motion/adapter/planner.py:241: in __init__
    self._episode: PlannerEpisode = self.config.planner(self._emb)
        __class__  = <class 'dimos.navigation.motion.adapter.planner.MotionPlanner'>
        kwargs     = {}
        self       = <dimos.navigation.motion.adapter.planner.MotionPlanner object at 0xff8b462c2db0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

emb = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1, _ = {}

    def make(emb: Embodiment, resolution: float = RESOLUTION, **_: Any) -> RustTargetEpisode:
        try:
            import dimos_motion2_target  # noqa: F401
        except ImportError as e:
>           raise ImportError(f"dimos_motion2_target is not built; run: {BUILD_CMD}") from e
E           ImportError: dimos_motion2_target is not built; run: uv run maturin develop --uv --release -m .../planner/rust/Cargo.toml

_          = {}
emb        = Embodiment(length=0.883, width=0.593, comfort=0.4, precision=0.05, max_speed=0.95, min_speed=0.2, speed_clearance=0.35...0.463, -0.039, -0.001), (153.4, 0.781, 0.422, -0.039, -0.003), (180.0, 0.781, 0.416, -0.039, 0.0)), arc_inflate=0.0334)
resolution = 0.1

.../planner/planners/target.py:146: ImportError
dimos.codebase_checks.test_no_sections::test_no_section_markers
Stack Traces | 0.884s run time
def test_no_section_markers():
        """
        Fail if any file contains section-style comment markers.
    
        If a file is too complicated to be understood without sections, then the
        sections should be files. We don't need "subfiles".
        """
        violations = find_section_markers()
        if violations:
            report_lines = [
                f"Found {len(violations)} section marker(s). "
                "If a file is too complicated to be understood without sections, "
                'then the sections should be files. We don\'t need "subfiles".',
                "",
            ]
            for path, lineno, text in violations:
                report_lines.append(f"  {path}:{lineno}: {text.strip()}")
>           raise AssertionError("\n".join(report_lines))
E           AssertionError: Found 1 section marker(s). If a file is too complicated to be understood without sections, then the sections should be files. We don't need "subfiles".
E           
E             .../go2/zenoh/blueprints.py:443: # region box -- all of them either already drawn as the raytraced map or not worth

lineno     = 443
path       = '.../go2/zenoh/blueprints.py'
report_lines = ['Found 1 section marker(s). If a file is too complicated to be understood without sections, then the sections should ....../go2/zenoh/blueprints.py:443: # region box -- all of them either already drawn as the raytraced map or not worth']
text       = '    # region box -- all of them either already drawn as the raytraced map or not worth'
violations = [('.../go2/zenoh/blueprints.py', 443, '    # region box -- all of them either already drawn as the raytraced map or not worth')]

dimos/codebase_checks/test_no_sections.py:145: AssertionError
dimos.codebase_checks.test_no_dunder_new::test_no_dunder_new
Stack Traces | 2.46s run time
def test_no_dunder_new() -> None:
        """Fail if any test file calls `__new__` to bypass `__init__`."""
        dimos_dir = DIMOS_PROJECT_ROOT / "dimos"
        hits = find_dunder_new_calls()
        if hits:
            listing = "\n".join(
                f"  - {p.relative_to(dimos_dir)}:{lineno}: {line.strip()}" for p, lineno, line in hits
            )
>           raise AssertionError(
                f"Found __new__ call(s) in test files:\n{listing}\n\n"
                "Tests must construct objects with the real constructor: __init__ is "
                "code under test too, and an object assembled by hand silently rots "
                "when the constructor changes. If __init__ does heavy work, mock the "
                "collaborators it needs instead of skipping it. Only if that is truly "
                "impossible, add the call to the WHITELIST in "
                "dimos/codebase_checks/test_no_dunder_new.py."
            )
E           AssertionError: Found __new__ call(s) in test files:
E             - visualization/rerun/test_bridge_topics.py:47: bridge = RerunBridgeModule.__new__(RerunBridgeModule)
E             - visualization/rerun/test_bridge_topics.py:74: coordinator = ModuleCoordinator.__new__(ModuleCoordinator)
E           
E           Tests must construct objects with the real constructor: __init__ is code under test too, and an object assembled by hand silently rots when the constructor changes. If __init__ does heavy work, mock the collaborators it needs instead of skipping it. Only if that is truly impossible, add the call to the WHITELIST in dimos/codebase_checks/test_no_dunder_new.py.

dimos_dir  = PosixPath('.../dimos/dimos/dimos')
hits       = [(PosixPath('.../dimos/dimos/di.../visualization/rerun/test_bridge_topics.py'), 47, '    bridge = RerunB....../visualization/rerun/test_bridge_topics.py'), 74, '    coordinator = ModuleCoordinator.__new__(ModuleCoordinator)')]
listing    = '  - visualization/rerun/test_bridge_topics.py:47: bridge = RerunBridgeModule.__new__(RerunBridgeModule)\n  - visualization/rerun/test_bridge_topics.py:74: coordinator = ModuleCoordinator.__new__(ModuleCoordinator)'

dimos/codebase_checks/test_no_dunder_new.py:67: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@leshy leshy changed the title Fix/ivan/motion stability Trajectory controller and navigation structure Sep 17, 2026
nav_3d/ is global_planner/. The Go2's own A* planner (and its RPC spec, the
agent skills' contract with it) go under go2/; dannav, frontier_exploration
and patrolling under experimental/; basic_path_follower becomes
trajectory_follower/basic/; the visual servoing, its bbox goal module and
navigation/visual/query join the skills that use them under
agents/skills/visual_servoing/. Renames and import rewrites only.
topics= subscribes one zenoh key per name so an unlisted topic never
crosses the link; serve_coordinator_rpc=False lets a viewer sit on a bus
whose Coordinator name another stack owns. Both for a viewer on the far
side of the robot's wifi.
local_planner/: an SE(2) search over the raycaster's local map, sliced
through the body's own z-band, replanning to a carrot along the MLS route.
trajectory_follower/fancy/: a pursuit law that reads the required precision
off the path's own stamps. Each is a python module with a rust native twin
(feature module) that is what runs; pyo3 (feature python) is test-only,
for the parity tests. spec.py says what a GlobalPlanner, a Blind/Map
LocalPlanner and a TrajectoryFollower are, as ports. An empty path is stop,
a single pose is hold. embodiment/ is the measured Go2; tf_pose.py reads
the body pose off tf with a deadman; cmd_vel_mux lets teleop preempt nav.

go2-zenoh-motion, go2-zenoh-motion-pointlio (the Jetson rig, with its own
Point-LIO and lidar addresses) and go2-viewer.
The config system feeds module fields from the environment (MID360__LIDAR_IP,
.env, --mid360.lidar-ip); the Mid-360, virtual Mid-360, Point-LIO and
FAST-LIO configs stop reading DIMOS_*_LIDAR_IP themselves.
The wire topic carries the message type in its last segment, so a dimos
channel needs no codec registry; injected codecs still win.
… build

A flake ref copies its whole source tree into the store; pointed at the repo
root that is the build dirs, .venv and the LFS blobs. This directory is two
files. The clippy hook skips the root flake for the same reason.
@leshy
leshy force-pushed the fix/ivan/motion_stability branch from d856048 to 7c6e5dc Compare September 17, 2026 11:11
@leshy

leshy commented Sep 17, 2026

Copy link
Copy Markdown
Member Author

#4203

@leshy leshy closed this Sep 17, 2026
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