Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
bed678f
feat: include dimsim
paul-nechifor May 14, 2026
8492bac
skip lfs
paul-nechifor May 14, 2026
e762c65
feat(dimsim): DIMSIM_LOCAL env, headless toggle, apartment as default…
Viswa4599 May 19, 2026
b71516b
Merge Paul's PR #2081 — vendor DimSim under misc/DimSim/
Viswa4599 May 19, 2026
8d5661a
misc/DimSim: sync from standalone (apartment decompose, loadLevel)
Viswa4599 May 19, 2026
290d8e9
misc/DimSim: cleanup pass — drop unused tests, JSR artifacts, docker,…
Viswa4599 May 19, 2026
7bd2ade
misc/DimSim: strip in-browser VLM agent stack (dimos integration path)
Viswa4599 May 19, 2026
f162668
misc/DimSim: slim AiAvatar to visual+physics+pose only
Viswa4599 May 19, 2026
e6057ca
misc/DimSim: strip legacy JSON-scene cli paths (setup/scene/list/buil…
Viswa4599 May 19, 2026
7ce0693
misc/DimSim: drop redundant LCM cross-language test pair
Viswa4599 May 19, 2026
9d25006
dimsim-check: drop refs to removed files (mod.ts, setup.ts, scenes.te…
Viswa4599 May 19, 2026
d6ad970
dimsim-check: strip the dimsim-check.yml steps that referenced the re…
Viswa4599 May 19, 2026
a5cbf94
fix(dimsim): re-enable agent visibility on dimos embodiment swap; coe…
Viswa4599 May 19, 2026
0206623
rename agent-model/robot.glb → dimsim_unitree_stub.glb
Viswa4599 May 19, 2026
ae90f64
dimos+dimsim: point avatarUrl refs at dimsim_unitree_stub.glb
Viswa4599 May 19, 2026
ed4d552
fix(dimsim): default agent to visible + stub-glb in dimos mode
Viswa4599 May 19, 2026
0608168
misc/DimSim: JS-native eval workflows + flat src/ structure
Viswa4599 May 19, 2026
1fb3498
misc/DimSim: eval workflows are now runnable JS programs, not config …
Viswa4599 May 19, 2026
29c475d
misc/DimSim: drop eval-api.js proxy; pin harness chunk so importmap t…
Viswa4599 May 19, 2026
04ed6e8
misc/DimSim: positional workflow arg for `dimsim eval`
Viswa4599 May 20, 2026
f2c572c
misc/DimSim: workflow files are directly executable via `deno run`
Viswa4599 May 20, 2026
d3a0073
misc/DimSim: collapse eval folders + rename dimos-cli/ → cli/
Viswa4599 May 20, 2026
d646ac0
misc/DimSim: cleanup + write proper docs for the new setup
Viswa4599 May 20, 2026
bbde1c8
docs: rewrite scenes.md as pure how-to + drop architecture.md
Viswa4599 May 20, 2026
388d3ce
docs(scenes): drop the interactive-objects section per request
Viswa4599 May 20, 2026
f294289
apartment: demonstrate threejs dev cycle on top of the loaded scene
Viswa4599 May 20, 2026
6a38e64
apartment: drop the noisy section-header comments
Viswa4599 May 20, 2026
719651c
apartment: revert demo additions; back to clean loadLevel
Viswa4599 May 20, 2026
6ea4d7e
misc/DimSim: strip HMR plumbing; make loadLevel/loadJson idempotent
Viswa4599 May 20, 2026
d6ac33c
misc/DimSim: scene-side setEmbodiment(config) API + docs
Viswa4599 May 20, 2026
c3b8dd9
fix(sceneApi): defer setEmbodiment() when bridge isn't up yet
Viswa4599 May 20, 2026
aaba685
warehouse: drop the experimental setEmbodiment(drone) line
Viswa4599 May 20, 2026
78f9207
[autofix.ci] apply automated fixes
autofix-ci[bot] May 20, 2026
355115d
Update misc/DimSim/cli/bridge/server.ts
Viswa4599 May 20, 2026
767560b
scenes/dungeon: third-party GLB map demo + LFS rule for scenes/**/*.glb
Viswa4599 May 20, 2026
4beea81
apartment: convert data/* to pure Three.js + structure.glb
Viswa4599 May 20, 2026
e15b5de
dimsim: cleanups and small infra
Viswa4599 May 20, 2026
69f6c06
apartment: re-embed textures into each GLB (drop _textures/ shared dir)
Viswa4599 May 20, 2026
87a8c29
remove obsolete one-shot decompose pipeline
Viswa4599 May 20, 2026
0a5b661
fix LFS rule for embodiment/ folder
Viswa4599 May 20, 2026
a1f4162
Potential fix for pull request finding 'CodeQL / Binding a socket to …
Viswa4599 May 20, 2026
b59d121
Potential fix for pull request finding 'CodeQL / Use of externally-co…
Viswa4599 May 20, 2026
c040c59
fix: address greptile review findings
Viswa4599 May 20, 2026
cb1f78d
fix: default to user camera; add physics.kinematicCollider
Viswa4599 May 20, 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
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@
*.foxe filter=lfs diff=lfs merge=lfs -text binary
docs/capabilities/memory/assets/** filter=lfs diff=lfs merge=lfs -text
docs/capabilities/memory/assets/.gitattributes -filter -diff -merge text
# DimSim scene data and agent model
misc/DimSim/public/sims/*.json filter=lfs diff=lfs merge=lfs -text
misc/DimSim/public/embodiment/*.glb filter=lfs diff=lfs merge=lfs -text
misc/DimSim/scenes/**/*.glb filter=lfs diff=lfs merge=lfs -text
misc/DimSim/scenes/**/*.gltf filter=lfs diff=lfs merge=lfs -text
45 changes: 45 additions & 0 deletions .github/workflows/dimsim-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: dimsim-check

on:
push:
branches: [main]
paths:
- 'misc/DimSim/**'
- '.github/workflows/dimsim-check.yml'
pull_request:
paths:
- 'misc/DimSim/**'
- '.github/workflows/dimsim-check.yml'

permissions: {}

jobs:
check:
timeout-minutes: 15
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: misc/DimSim
steps:
- uses: actions/checkout@v6
with:
lfs: true

- uses: actions/setup-node@v4
with:
node-version: 20

- uses: denoland/setup-deno@v2
with:
deno-version: v2.x

- name: Install npm deps
run: npm ci

- name: Build frontend
run: npm run build

- name: Type-check CLI
run: cd cli && deno check cli.ts
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ __pycache__

# node env (used by devcontainers cli)
node_modules
package.json
package-lock.json
!docs/package.json
!docs/package-lock.json
/package.json
/package-lock.json

# Ignore build artifacts
dist/
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ repos:
args: [--fix=lf]
exclude: \.patch$ # keep patch files byte-identical to upstream diffs
- id: check-json
exclude: ^misc/DimSim/public/sims/ # LFS-tracked
- id: check-toml
- id: check-yaml
- id: pretty-format-json
name: format json
args: [ --autofix, --no-sort-keys ]
exclude: ^misc/DimSim/public/sims/ # LFS-tracked

- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 3.4.1
Expand Down
3 changes: 2 additions & 1 deletion dimos/core/global_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ class GlobalConfig(BaseSettings):
obstacle_avoidance: bool = True
detection_model: VlModelName = "moondream"
listen_host: str = "127.0.0.1"
dimsim_scene: str = "apt"
dimsim_scene: str = "apartment"
dimsim_port: int = 8090
dimsim_headless: bool = True

model_config = SettingsConfigDict(
env_file=".env",
Expand Down
62 changes: 34 additions & 28 deletions dimos/simulation/dimsim/dimsim_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import time
from typing import IO

from dimos.constants import STATE_DIR
from dimos.core.global_config import GlobalConfig
from dimos.simulation.dimsim.deno_utils import ensure_deno, ensure_playwright_chromium
from dimos.utils.logging_config import setup_logger
Expand All @@ -28,8 +27,7 @@

_VIDEO_RATE = 50
_LIDAR_RATE = 1000
_DIMSIM_REPO_URL = "https://github.com/paul-nechifor/DimSim.git"
_DIMSIM_REPO_BRANCH = "run-from-repo"
_DIMSIM_DIR = Path(__file__).resolve().parents[3] / "misc" / "DimSim"


class DimSimProcess:
Expand All @@ -39,13 +37,14 @@ def __init__(self, global_config: GlobalConfig) -> None:

def start(self) -> None:
deno_path = ensure_deno()
repo_dir = _ensure_repo()
base_cmd = _deno_cmd(deno_path, repo_dir)
base_cmd = _deno_cmd(deno_path, _resolve_dimsim_dir())

scene = self.global_config.dimsim_scene
port = self.global_config.dimsim_port
headless = self.global_config.dimsim_headless

ensure_playwright_chromium(deno_path)
if headless:
ensure_playwright_chromium(deno_path)
_kill_port_holder(port)

render = os.environ.get("DIMSIM_RENDER", "gpu").strip()
Expand All @@ -60,7 +59,7 @@ def start(self) -> None:
"--port",
str(port),
"--no-depth",
"--headless",
*(("--headless",) if headless else ()),
"--render",
render,
"--image-rate",
Expand All @@ -69,6 +68,11 @@ def start(self) -> None:
str(_LIDAR_RATE),
]

if not headless:
logger.info(
f"Open http://localhost:{port} in your browser; sensors won't publish until that tab is loaded."
)

self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

self._start_log_reader()
Expand Down Expand Up @@ -126,28 +130,30 @@ def _kill_port_holder(port: int) -> None:
logger.warning(f"Failed to check/kill port {port}: {e}")


def _ensure_repo() -> Path:
repo_dir = STATE_DIR / "dimsim_repo"
if (repo_dir / ".git").exists():
return repo_dir
STATE_DIR.mkdir(parents=True, exist_ok=True)
logger.info(f"Cloning DimSim into {repo_dir}")
subprocess.run(
[
"git",
"clone",
"--depth",
"1",
"--branch",
_DIMSIM_REPO_BRANCH,
_DIMSIM_REPO_URL,
str(repo_dir),
],
check=True,
)
return repo_dir
def _resolve_dimsim_dir() -> Path:
"""Pick the DimSim directory to run. DIMSIM_LOCAL env overrides the
vendored misc/DimSim/ copy — handy when iterating on DimSim itself.

DIMSIM_LOCAL=1 → ../DimSim sibling of the dimos repo
DIMSIM_LOCAL=/some/path → that path
(unset) → vendored misc/DimSim/
"""
local = os.environ.get("DIMSIM_LOCAL", "").strip()
if not local:
return _DIMSIM_DIR
if local == "1":
dimos_root = Path(__file__).resolve().parents[3]
path = dimos_root.parent / "DimSim"
else:
path = Path(local).expanduser().resolve()
if not (path / "cli" / "cli.ts").exists():
raise RuntimeError(
f"DIMSIM_LOCAL={local} resolved to {path}, but {path}/cli/cli.ts does not exist"
)
logger.info(f"Using local DimSim from {path}")
return path


def _deno_cmd(deno_path: str, repo_dir: Path) -> list[str]:
cli_ts = repo_dir / "dimos-cli" / "cli.ts"
cli_ts = repo_dir / "cli" / "cli.ts"
return [deno_path, "run", "--allow-all", "--unstable-net", str(cli_ts)]
18 changes: 9 additions & 9 deletions dimos/simulation/dimsim/scene_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"halfHeight": 0.25,
"lidarMountHeight": 0.35,
"embodimentType": "quadruped",
"avatarUrl": ["/agent-model/unitree_go2.glb", "/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
# Physics
"maxSpeed": 3.0,
"turnRate": 3.0,
Expand All @@ -54,7 +54,7 @@
"halfHeight": 0.25,
"lidarMountHeight": 0.35,
"embodimentType": "quadruped",
"avatarUrl": ["/agent-model/unitree_go2.glb", "/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 3.0,
"turnRate": 3.0,
"gravity": -9.81,
Expand All @@ -66,7 +66,7 @@
"halfHeight": 0.2,
"lidarMountHeight": 0.35,
"embodimentType": "quadruped", # ground physics
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 2.0,
"turnRate": 2.5, # differential drive turns by wheel speed diff
"gravity": -9.81,
Expand All @@ -78,7 +78,7 @@
"halfHeight": 0.4,
"lidarMountHeight": 0.8,
"embodimentType": "quadruped", # ground physics
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 5.0,
"turnRate": 1.2, # car-like: slow turn rate (limited steering angle)
"gravity": -9.81,
Expand All @@ -90,7 +90,7 @@
"halfHeight": 0.25,
"lidarMountHeight": 0.4,
"embodimentType": "quadruped", # ground physics (strafing via cmd_vel.linear.y)
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 2.5,
"turnRate": 4.0, # omnidirectional: fast rotation
"gravity": -9.81,
Expand All @@ -102,7 +102,7 @@
"halfHeight": 0.8,
"lidarMountHeight": 1.6,
"embodimentType": "quadruped", # ground physics
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 1.5,
"turnRate": 2.0,
"gravity": -9.81,
Expand All @@ -114,7 +114,7 @@
"halfHeight": 0.15,
"lidarMountHeight": 0.25,
"embodimentType": "quadruped",
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 1.0,
"turnRate": 3.0,
"gravity": -9.81,
Expand All @@ -127,7 +127,7 @@
"halfHeight": 0.1,
"lidarMountHeight": 0.15,
"embodimentType": "drone",
"avatarUrl": ["/agent-model/robot.glb"],
"avatarUrl": ["/agent-model/dimsim_unitree_stub.glb"],
"maxSpeed": 5.0,
"turnRate": 4.0,
"gravity": 0, # no gravity in flight
Expand Down Expand Up @@ -723,7 +723,7 @@ def set_embodiment(
- ``"flight"`` — 6DoF, optional gravity, altitude ceiling

**Avatar URL** can be:
- Built-in: ``"/agent-model/robot.glb"``
- Built-in: ``"/agent-model/dimsim_unitree_stub.glb"``
- Local asset: ``"/local-assets/my-drone.glb"`` (see :meth:`upload_asset`)
- Any URL: ``"https://example.com/robot.glb"``

Expand Down
26 changes: 16 additions & 10 deletions dimos/visualization/rerun/websocket_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,19 @@ def _dispatch(self, raw: str | bytes) -> None:

msg_type = msg.get("type")

# dict.get's default is only used when the key is missing — if Rerun
# sends a 2D-panel click the "z" key is present with value None, and
# `float(None)` raises. Coerce explicitly.
def _num(v: Any) -> float:
return float(v) if v is not None else 0.0

if msg_type == "click":
self.clicked_point.publish(
PointStamped(
x=float(msg.get("x", 0)),
y=float(msg.get("y", 0)),
z=float(msg.get("z", 0)),
ts=float(msg.get("timestamp_ms", 0)) / 1000.0,
x=_num(msg.get("x")),
y=_num(msg.get("y")),
z=_num(msg.get("z")),
ts=_num(msg.get("timestamp_ms")) / 1000.0,
frame_id=str(msg.get("entity_path", "")),
)
)
Expand All @@ -166,14 +172,14 @@ def _dispatch(self, raw: str | bytes) -> None:
self.tele_cmd_vel.publish(
Twist(
linear=Vector3(
float(msg.get("linear_x", 0)),
float(msg.get("linear_y", 0)),
float(msg.get("linear_z", 0)),
_num(msg.get("linear_x")),
_num(msg.get("linear_y")),
_num(msg.get("linear_z")),
),
angular=Vector3(
float(msg.get("angular_x", 0)),
float(msg.get("angular_y", 0)),
float(msg.get("angular_z", 0)),
_num(msg.get("angular_x")),
_num(msg.get("angular_y")),
_num(msg.get("angular_z")),
),
)
)
Expand Down
9 changes: 9 additions & 0 deletions misc/DimSim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules/
*.tar.gz
dist/
.DS_Store
**/.DS_Store
.deno/
scenes.json
scenes/**/apt.json
scripts/
54 changes: 54 additions & 0 deletions misc/DimSim/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# DimSim

Browser-based 3D simulator (Three.js + Rapier) plus a Deno bridge that talks LCM/WS to [dimos](https://github.com/dimensionalOS/dimos). Lives inside dimos as `misc/DimSim/`.

```
src/ — browser engine (vite-bundled)
cli/ — Deno CLI + bridge server + headless launcher + LCM vendor
evals/ — eval harness (browser) + runner (Deno) + rubrics
scenes/ — user-authored scenes (JS) + per-scene eval workflows
public/ — static assets (agent GLB, logo)
docs/ — guides
```

## Run

dimsim is launched by dimos directly when you pick `--simulation dimsim`:

```bash
cd <dimos-repo>
.venv/bin/dimos --simulation dimsim --dimsim-scene=apartment run unitree-go2-agentic
```

On first run, `cli/cli.ts` will build `dist/` via Vite (dimsim ships its frontend as source — Deno+Vite materializes it in ~20s).

## Docs

- [docs/getting-started.md](docs/getting-started.md) — 5-minute tour
- [docs/scenes.md](docs/scenes.md) — create + edit scenes
- [docs/evals.md](docs/evals.md) — write eval workflows

## Install the CLI (optional)

If you want `dimsim` as a global command:

```bash
cd misc/DimSim/cli
deno install -gAf --unstable-net --name=dimsim --config=./deno.json ./cli.ts
```

After install:

```bash
dimsim dev --scene apartment # standalone dev server + browser
dimsim eval list # list workflows under scenes/*/evals/
dimsim eval go-to-couch # run one workflow against an open sim
dimsim eval --headless --scene apartment # full headless run (CI)
```

## Build manually

```bash
npm install # browser deps (three, rapier, spark, vite)
npm run build # → dist/
```
Loading
Loading