Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d4040f2
better native module debugging
jeff-hykin Mar 12, 2026
c581f9c
add unity sim, part 1
jeff-hykin Mar 12, 2026
e135fa2
clean up
jeff-hykin Mar 12, 2026
c3cf3e6
cleaning
jeff-hykin Mar 12, 2026
d511bf9
improve binary downloading (google drive)
jeff-hykin Mar 12, 2026
d335685
feat(unity-sim): use LFS for sim binary, remove Google Drive download
jeff-hykin Mar 12, 2026
23e81f5
Module config tweaks (#1510)
Dreamsorcerer Mar 12, 2026
8ff7377
chore(comments): remove section markers (#1546)
paul-nechifor Mar 14, 2026
c89ee5b
fix(imports): remove dunder init (#1545)
paul-nechifor Mar 14, 2026
1ec4227
fix(deps): skip pyrealsense2 on macOS (#1556)
jeff-hykin Mar 14, 2026
b3177fd
Feat/memory2 (#1536)
leshy Mar 15, 2026
e6267e1
docs(readme): add Trendshift trending badge (#1563)
spomichter Mar 15, 2026
9486a90
fix(ci): limit tests to 60 minutes max (#1557)
paul-nechifor Mar 16, 2026
3a5f000
fix(old-scripts): remove (#1561)
paul-nechifor Mar 16, 2026
ab081c1
docs: add Spec issue template (#1574)
spomichter Mar 16, 2026
e95e0d7
feat(patrol): add patrolling module (#1488)
paul-nechifor Mar 17, 2026
3afde01
fix: rename teleop blueprints, remove VisualizingTeleopModule (#1602)
ruthwikdasyam Mar 19, 2026
c6f1842
feat(test): add leaderboard (#1580)
paul-nechifor Mar 19, 2026
bdd06d4
fix(florence): fix text failure (#1582)
paul-nechifor Mar 19, 2026
b9cca6c
event based sub callback collector for tests (#1605)
leshy Mar 19, 2026
cb648f5
refactor: split control blueprints + added env variables (#1601)
ruthwikdasyam Mar 19, 2026
cdac06e
- (#1610)
jeff-hykin Mar 19, 2026
c8a7b7d
fix(cli): fix `dimos --help` (both bad imports and speed) (#1571)
jeff-hykin Mar 20, 2026
dc331b7
chore(blueprints): remove aliases (#1606)
paul-nechifor Mar 20, 2026
53a2fce
Merge branch 'main' into dev
spomichter Mar 21, 2026
1924b61
Feature: go2 webrtc TwistBase adapter for control coordinator (#1362)
mustafab0 Mar 21, 2026
349fc0b
merge: resolve all_blueprints.py conflict with dev
jeff-hykin Mar 21, 2026
c24c51c
data: add sim assets for xArm6 and Piper (#1642)
ruthwikdasyam Mar 21, 2026
bb16ea2
fix(unity-sim): use RerunBridgeModule.blueprint() after rerun_bridge …
jeff-hykin Mar 21, 2026
885b729
fix: update all_blueprints.py to include unity-bridge-module
jeff-hykin Mar 21, 2026
fe46e82
Merge remote-tracking branch 'origin/dev' into jeff/feat/untiy_sim
jeff-hykin Mar 21, 2026
49c5142
merge: pull latest dev
jeff-hykin Mar 21, 2026
0fe29f0
fix: remove @dataclass from UnityBridgeConfig (Pydantic compat), clea…
jeff-hykin Mar 21, 2026
7e69093
MuJoCo sim support for Manipulation (#1639)
ruthwikdasyam Mar 22, 2026
645cb0d
fix: address greptile review comments
jeff-hykin Mar 22, 2026
5d461c6
fix: address all paul-review issues on unity simulator
jeff-hykin Mar 22, 2026
fc65956
Merge remote-tracking branch 'origin/dev' into jeff/feat/untiy_sim
jeff-hykin Mar 22, 2026
d12407a
Merge remote-tracking branch 'origin/dev' into jeff/feat/untiy_sim
jeff-hykin Mar 22, 2026
002a419
fix: resolve merge conflicts + address Paul's review comments
jeff-hykin Mar 22, 2026
182cf28
refactor: remove unnecessary __getstate__/__setstate__ from UnityBrid…
jeff-hykin Mar 22, 2026
9b609bd
fix(unity): launch Unity in thread to avoid blocking start()
jeff-hykin Mar 22, 2026
47d99da
fix(unity): pipe Unity stderr to logger instead of discarding
jeff-hykin Mar 22, 2026
9f0f7b9
fix(unity): clear _unity_ready on disconnect
jeff-hykin Mar 22, 2026
258b0cc
test: remove pickle test (follows __getstate__/__setstate__ removal)
jeff-hykin Mar 22, 2026
66e1819
fix(unity): thread safety for _unity_process and stderr drain
jeff-hykin Mar 22, 2026
d6bf9fb
fix(lfs): repack unity_sim_x86 tarball with correct directory name
jeff-hykin Mar 22, 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
3 changes: 3 additions & 0 deletions data/.lfs/unity_sim_x86.tar.gz
Git LFS file not shown
40 changes: 35 additions & 5 deletions dimos/core/native_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MyCppModule(NativeModule):

from __future__ import annotations

import collections
import enum
import inspect
import json
Expand Down Expand Up @@ -131,9 +132,11 @@ class NativeModule(Module[_NativeConfig]):
_process: subprocess.Popen[bytes] | None = None
_watchdog: threading.Thread | None = None
_stopping: bool = False
_last_stderr_lines: collections.deque[str]

def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self._last_stderr_lines = collections.deque(maxlen=50)
self._resolve_paths()

@rpc
Expand All @@ -155,15 +158,25 @@ def start(self) -> None:
env = {**os.environ, **self.config.extra_env}
cwd = self.config.cwd or str(Path(self.config.executable).resolve().parent)

logger.info("Starting native process", cmd=" ".join(cmd), cwd=cwd)
module_name = type(self).__name__
logger.info(
f"Starting native process: {module_name}",
module=module_name,
cmd=" ".join(cmd),
cwd=cwd,
)
Copy link
Member Author

@jeff-hykin jeff-hykin Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to native modules here cause I'm testing the unity sim with the livox native modules and got VERY undescriptive error messages

self._process = subprocess.Popen(
cmd,
env=env,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
logger.info("Native process started", pid=self._process.pid)
logger.info(
f"Native process started: {module_name}",
module=module_name,
pid=self._process.pid,
)

self._stopping = False
self._watchdog = threading.Thread(target=self._watch_process, daemon=True)
Expand Down Expand Up @@ -202,10 +215,20 @@ def _watch_process(self) -> None:

if self._stopping:
return

module_name = type(self).__name__
exe_name = Path(self.config.executable).name if self.config.executable else "unknown"

# Use buffered stderr lines from the reader thread for the crash report.
last_stderr = "\n".join(self._last_stderr_lines)

logger.error(
"Native process died unexpectedly",
f"Native process crashed: {module_name} ({exe_name})",
module=module_name,
executable=exe_name,
pid=self._process.pid,
returncode=rc,
last_stderr=last_stderr[:500] if last_stderr else None,
)
self.stop()

Expand All @@ -219,10 +242,13 @@ def _read_log_stream(self, stream: IO[bytes] | None, level: str) -> None:
if stream is None:
return
log_fn = getattr(logger, level)
is_stderr = level == "warning"
for raw in stream:
line = raw.decode("utf-8", errors="replace").rstrip()
if not line:
continue
if is_stderr:
self._last_stderr_lines.append(line)
if self.config.log_format == LogFormat.JSON:
try:
data = json.loads(line)
Expand Down Expand Up @@ -274,12 +300,16 @@ def _maybe_build(self) -> None:
if line.strip():
logger.warning(line)
if proc.returncode != 0:
stderr_tail = stderr.decode("utf-8", errors="replace").strip()[-1000:]
raise RuntimeError(
f"Build command failed (exit {proc.returncode}): {self.config.build_command}"
f"Build command failed (exit {proc.returncode}): {self.config.build_command}\n"
f"stderr: {stderr_tail}"
)
if not exe.exists():
raise FileNotFoundError(
f"Build command succeeded but executable still not found: {exe}"
f"Build command succeeded but executable still not found: {exe}\n"
f"Build output may have been written to a different path. "
f"Check that build_command produces the executable at the expected location."
)

def _collect_topics(self) -> dict[str, str]:
Expand Down
1 change: 0 additions & 1 deletion dimos/models/segmentation/edge_tam.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

from collections.abc import Generator
from contextlib import contextmanager
import os
from pathlib import Path
import shutil
import tempfile
Expand Down
2 changes: 1 addition & 1 deletion dimos/models/vl/create.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any

from dimos.models.vl.types import VlModelName
from dimos.models.vl.base import VlModel
from dimos.models.vl.types import VlModelName


def create(name: VlModelName) -> VlModel[Any]:
Expand Down
2 changes: 2 additions & 0 deletions dimos/robot/all_blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"unitree-go2-temporal-memory": "dimos.robot.unitree.go2.blueprints.agentic.unitree_go2_temporal_memory:unitree_go2_temporal_memory",
"unitree-go2-vlm-stream-test": "dimos.robot.unitree.go2.blueprints.smart.unitree_go2_vlm_stream_test:unitree_go2_vlm_stream_test",
"unitree-go2-webrtc-keyboard-teleop": "dimos.robot.unitree.go2.blueprints.basic.unitree_go2_webrtc_keyboard_teleop:unitree_go2_webrtc_keyboard_teleop",
"unity-sim": "dimos.simulation.unity.blueprint:unity_sim",
"xarm-perception": "dimos.manipulation.blueprints:xarm_perception",
"xarm-perception-agent": "dimos.manipulation.blueprints:xarm_perception_agent",
"xarm6-planner-only": "dimos.manipulation.blueprints:xarm6_planner_only",
Expand Down Expand Up @@ -166,6 +167,7 @@
"twist-teleop-module": "dimos.teleop.quest.quest_extensions",
"unitree-g1-skill-container": "dimos.robot.unitree.g1.skill_container",
"unitree-skill-container": "dimos.robot.unitree.unitree_skill_container",
"unity-bridge-module": "dimos.simulation.unity.module",
"vlm-agent": "dimos.agents.vlm_agent",
"vlm-stream-tester": "dimos.agents.vlm_stream_tester",
"voxel-grid-mapper": "dimos.mapping.voxels",
Expand Down
61 changes: 61 additions & 0 deletions dimos/simulation/unity/blueprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 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.

"""Standalone Unity sim blueprint — interactive test of the Unity bridge.

Launches the Unity simulator, displays lidar + camera in Rerun, and accepts
keyboard teleop via TUI. No navigation stack — just raw sim data.

Usage:
dimos run unity-sim
"""

from __future__ import annotations

from typing import Any

from dimos.core.blueprints import autoconnect
from dimos.protocol.pubsub.impl.lcmpubsub import LCM
from dimos.simulation.unity.module import UnityBridgeModule
from dimos.visualization.rerun.bridge import RerunBridgeModule, _resolve_viewer_mode


def _rerun_blueprint() -> Any:
import rerun.blueprint as rrb

return rrb.Blueprint(
rrb.Vertical(
rrb.Spatial3DView(origin="world", name="3D"),
rrb.Spatial2DView(origin="world/color_image", name="Camera"),
row_shares=[2, 1],
),
)


rerun_config = {
"blueprint": _rerun_blueprint,
"pubsubs": [LCM()],
"visual_override": {
"world/camera_info": UnityBridgeModule.rerun_suppress_camera_info,
},
"static": {
"world/color_image": UnityBridgeModule.rerun_static_pinhole,
},
}


unity_sim = autoconnect(
UnityBridgeModule.blueprint(),
RerunBridgeModule.blueprint(viewer_mode=_resolve_viewer_mode(), **rerun_config),
)
Loading
Loading