Skip to content

Release v0.0.14: Web SDK, Manipulation, Evals Framework, and Recording

Latest

Choose a tag to compare

@dimos-release-bot dimos-release-bot released this 19 Sep 16:56
· 63 commits to main since this release
0885b14
banner_bordered_trimmed
The Agentive Operating System for Physical Space

Highlights

421 commits, 23 contributors, 2,003 files changed since v0.0.13.post1.

A new web stack ships with --local-relay: a browser Cockpit with video, 2D map with click-to-goal, keyboard teleop, agent chat with push-to-talk, and stats, plus a @dimos/sdk web SDK for building your own pages. Manipulation is rebuilt around a single robot model with planning groups, so bimanual and mobile manipulators plan and execute as one coordinated model: RoboPlan is the default backend, Cartesian and free-space planning are selectable in Viser, a planar base can be planned together with arms and torso, and the xarm-grasp stack runs scene registration, heuristic or GraspGenX grasp proposals, and feedback-verified pick and place on hardware or in a headless MuJoCo sim. A new dimos evals framework scores agents against recordings and live sims, with deterministic VQA dataset generation. dimos --record taps every published topic of any blueprint into a memory store, and dimos login plus dimos data upload push recordings to Dimensional cloud. Zenoh is now the default transport on every platform, with native Zenoh RPC and Zenoh support in Rust and C++ native modules, and TF is an ordinary tf stream with new bidirectional IO[T] ports. The 3D navigation stack reaches the real G1, Deep Robotics M20, Alfred, and Habitat photorealistic sim, relocalization works with any lidar, and the legacy CMU nav stack is removed. New robots include Boston Dynamics Spot (experimental), Galaxea R1 Pro and A1Z, OpenYAM, and OpenArm on a shared Damiao adapter.

⚠️ Breaking Changes

This release has many breaking changes. Read this section before upgrading.

Core, transport & config

  • Zenoh is the default transport on every platform (previously lcm everywhere except macOS). The default session is pinned to localhost: it listens on tcp/127.0.0.1:0 and scouts over loopback only. Reach off the machine with --robot-ip, ZENOH_CONNECT=tcp/host:7447, ZENOH_SCOUTING=1, or ZENOH_INTERFACE=<iface>; a new zenoh_scout_addr moves a session onto a private discovery group. Use --transport=lcm or DIMOS_TRANSPORT=lcm to keep the legacy path. (#3617) by @leshy
  • TF service retired: the lazily attached self.tf service, TFSpec, TFConfig, PubSubTF, LCMTF, ZenohTF, tf_backend(), and ModuleConfig.tf_transport are removed. TF is now a normal TFMessage stream named tf: declare tf: Out[TFMessage] to publish, tf: In[TFMessage] to look up via self.tfbuffer, or tf: IO[TFMessage] for both, using the new bidirectional IO[T] port kind. Outside modules use TF(stream). Wire format is unchanged, and tf is prefixed by namespaces like any other stream. (#3169) by @leshy
  • memory2 package renamed to memory: dimos.memory2.* imports become dimos.memory.*, and Memory2ReplayAdapter becomes MemoryReplayAdapter (the TimedSensorReplay alias is unchanged). Pure rename, no behavior change. (#3413) by @spomichter
  • ~/.config/dimos is now a directory: the default --config file is ~/.config/dimos/config and dimos login writes ~/.config/dimos/credentials. If a legacy flat file exists at ~/.config/dimos, dimos run exits with the one-line mv command to migrate it and changes nothing on disk. (#3550) by @spomichter
  • Python package layout changed; update imports. dimos.learning is now dimos.imitation, dimos.core.tests is now dimos.core.demos, agent test helpers moved to dimos.agents.testing, and CLI code moved from dimos.robot.cli / dimos.utils.cli to dimos.cli (mapping tools to dimos.mapping.cli). Console script names (dimos, lcmspy, agentspy, humancli, dtop) and blueprint names are unchanged. (#3194, #3256) by @paul-nechifor
  • Docker images moved from ghcr.io/dimensionalos/ to Docker Hub under dimensional/. Use dimensional/dev:latest and dimensional/ros-dev:latest instead of ghcr.io/dimensionalos/dev and ghcr.io/dimensionalos/ros-dev; the devcontainer and bin/dev point at the new images. (#3724) by @Dreamsorcerer
  • WrenchStamped is flat: the reading moved from ws.wrench.force / ws.wrench.torque to ws.force / ws.torque, matching PoseStamped and TwistStamped. Wrench and WrenchStamped are rebuilt on the generated LCM classes and gain lcm_encode / lcm_decode, so they can be used as stream types. (#3389) by @mustafab0

Manipulation & control

  • ManipulationModuleConfig.robots is replaced by one prepared model. Planning, IK, collision, execution, and visualization use canonical model joint names (for example left/joint1) and declared planning-group IDs such as left_arm, right_arm, and both_arms. Robot selectors, registries, lookup APIs, compatibility RPCs, robot-prefixed group parsing, and the model-wide end-effector property are removed; resolve tips through planning groups instead. (#3420, #3431, #3919) by @TomCC7
  • ManipulationModule RPCs are now planning-group native and take group IDs instead of robot names: list_planning_groups, get_state, plan_to_joints, plan_to_poses, execute, wait_for_execution, move_linear, set_gripper_position, and cancel, returning typed PlanResult / ExecutionResult / MoveResult values. The @skill methods moved out of ManipulationModule into ManipulationSkills. (#3447) by @TomCC7
  • Plan execution goes through a new PlanExecutionManager and always dispatches the complete stored plan in one coordinator RPC. execute(robot_name=...) and execute_plan(plan, robot_name=...) lose the robot selector, get_trajectory_status and RobotModelConfig.coordinator_task_name are removed, and CoordinatorClient.execute_trajectory / cancel_trajectory drop the task name and return typed results. Every ManipulationModule blueprint must include a ControlCoordinator with exactly one JointTrajectoryTask (a second raises ValueError). The xarm6-planner-only and dual-xarm6-planner blueprints are removed; use xarm7-planner-coordinator or dual-xarm6-planner-coordinator. (#3183) by @TomCC7
  • Gripper control moved into the control-task path: the coordinator's direct gripper RPC and the gripper handling inside arm motion tasks are removed. A new GripperControlTask owns the configured gripper joints (native or normalized targets), integrated grippers are ordinary entries in each adapter's joint arrays (get_dof(), reads, writes, and limits cover them), and units stay native at the adapter boundary (xArm 0-850, Piper and A1Z physical stroke). (#3381) by @jhengyilin
  • The shared coordinator input ports for Cartesian and EEF-twist commands are deleted, and tasks are no longer selected by writing the task name into a message's frame_id. Each task instance reads its own coordinator port, connected once in the blueprint (dual-arm Quest teleop binds one port per arm with stream_bind). Out-of-tree blueprints must declare the port on a coordinator subclass and point the producer remap at it. (#3407) by @mustafab0
  • The separate joint servo control task is removed; streamed joint_command positions now run through the joint trajectory task as one-point trajectories with per-joint velocity bounds (1 rad/s unless limits are configured). Blueprint coordinator-servo-xarm6 is renamed to coordinator-trajectory-xarm6. (#3610) by @TomCC7
  • xArm grasping blueprints renamed: xarm-perception is now xarm-grasp and xarm-perception-agent is now xarm-grasp-agent. xarm-perception-sim and xarm-perception-sim-agent are unchanged. (#3873) by @mustafab0
  • XArmAdapter no longer drives the arm to a hardcoded joint pose on activate() and deactivate(). Pass an explicit initial_positions argument to get a startup pose; with no argument the adapter commands no motion. (#3869) by @mustafab0

Navigation & mapping

  • The CMU nav stack (dimos/navigation/cmu_nav: FAR/TARE planners, terrain analysis, local planner, path follower, C++ PGO) is deleted, along with the blueprints built on it: alfred-nav, coordinator-flowbase-nav, unitree-g1-nav-onboard, unitree-g1-nav-sim, and the ContourPolygons3D / GraphNodes3D messages. Use the ray-tracing + MLS planner stack instead (unitree-go2-nav-3d, alfred-mls-nav, G1 nav in unitree-g1-groot-wbc). (#3576) by @paul-nechifor
  • Ray tracing and the MLS planner take poses from TF instead of odometry streams. RayTracingVoxelMap replaces its odometry input with tf (clouds are registered by a world_frame -> cloud frame_id lookup, tolerance tf_match_tolerance_s); MLSPlannerNative replaces start_pose / goal_pose with a goal: PointStamped input plus tf, plans from base_frame (default base_link), and its default world_frame changes from map to odom; BasicPathFollower drops its odometry input; GoalRelay is replaced by StartRelay and dimos/navigation/tf_pose.py is removed. Custom blueprints must publish the TF chain and rewire these ports. (#3603) by @aclauer
  • FAST-LIO and Point-LIO publish pointclouds and odometry in the IMU/sensor frame with no separate body frame: the child_frame_id config is removed and odometry's child frame is now sensor_frame_id (e.g. odom -> mid360_link). Point-LIO now builds from the dimos-module-pointlio repo. (#2700) by @leshy

Teleoperation

  • Quest teleop stack renamed to WebXR, with no compatibility aliases. Blueprints teleop-quest-* are now teleop-webxr-* (e.g. teleop-webxr-xarm7, teleop-webxr-go2, teleop-webxr-piper, teleop-webxr-dual-openyam), learning-collect-quest-xarm7 / -piper are now learning-collect-webxr-xarm7 / -piper, the package dimos.teleop.quest is now dimos.teleop.webxr, and QuestTeleopModule is now WebXRTeleopModule. (#3676) by @TomCC7
  • Legacy hosted teleop package dimos/teleop/quest_hosted/ removed, including HostedTeleopModule, HostedArmTeleopModule, HostedTwistTeleopModule, HostedTeleopRecorder and the teleop-hosted-go2 / teleop-hosted-module-xarm7 blueprints. Use the transport-based blueprints in dimos/teleop/hosted/ (teleop-hosted-go2-transport, teleop-hosted-xarm7) and the generic teleop-recorder. The broker API key is set through transports.broker.api_key / TRANSPORTS__BROKER__API_KEY; the TELEOP_API_KEY env fallback is gone. (#3173) by @ruthwikdasyam
  • Hosted teleop default broker changed: BrokerConfig.broker_url now defaults to https://api.dimensional.org instead of https://teleop.dimensionalos.com. Keys (dimos_sk_...) come from the Dimensional console (API keys, Create key), the operator UI is the console Teleop tab, and the robot identifies itself with TRANSPORTS__BROKER__ROBOT_ID. To keep using the old broker, set TRANSPORTS__BROKER__BROKER_URL=https://teleop.dimensionalos.com. (#4063) by @spomichter

Agents, perception & simulation

  • Agent skill relative_move(forward, left, degrees) replaced by move_to(x, y, degrees, relative): world-frame coordinates by default, relative=True for a body-relative offset. Update MCP calls (dimos mcp call move_to --arg x=0.5 --arg relative=true) and porcelain calls (app.skills.move_to(x=2.0, relative=True)). (#3716) by @hvent90
  • Observation skills unified into one ObserveSkill container (observe-skill, dimos/agents/skills/observe_skill.py) that subscribes to color_image. The per-robot observe() skills on GO2Connection and the drone connection module and take_a_picture() on the camera module are removed; add ObserveSkill to custom agentic blueprints instead. This also fixes observe under the dimsim simulator. (#3601) by @paul-nechifor
  • Outdated and experimental perception code moved: object tracking, object scene registration, ObjectDBModule, SpatialMemory, PerceiveLoopSkill, image embedding, and visual memory now live under dimos/perception/experimental/, world belief under dimos/experimental/world_belief/, and dimos/perception/common/utils.py is deleted. Blueprint and module names (e.g. spatial-memory, xarm6-worldbelief) are unchanged; update direct Python imports to the new paths. (#3275) by @leshy
  • Unity simulator removed: the unity-sim blueprint and UnityBridgeModule are gone. Use --simulation=mujoco or --simulation=dimsim instead. (#4116) by @paul-nechifor

Also changed (described under New Features, Fixes, or Performance)

  • RoboPlan is the manipulation default (world_backend="roboplan", planner_name="roboplan"); Drake needs world_backend="drake" and planner_name="rrt_connect". (#3155)
  • Robot descriptions (A1Z, A750, Piper, xArm) resolve from pinned Git sources instead of bundled LFS archives; the old model parser and legacy description fields are removed. (#2505)
  • The legacy Pinocchio control IK fallback is removed; Cartesian and EEF-twist tasks require Pink and the manipulation extra. The singular plan_to_pose RPC and the standalone manipulation client runner are removed. hold_position_when_idle is removed. (#2992, #3944, #3969)
  • dimos piper can-activate is replaced by dimos hardware can setup / status. The per-side and mock OpenArm blueprints collapse into coordinator-openarm and openarm-planner-coordinator, and keyboard-teleop-openarm is removed. (#3129, #3388)
  • RealSense camera_name is replaced by frame_id / frame_id_prefix, the camera no longer emits mount transforms, and RealSenseCamera is a native Rust module that needs a native build. (#3746)
  • Relocalization option publish_loaded_map is replaced by republish_loaded_map and tf_interval. (#3890)
  • Stamped messages take ts: float | None = None, so ts=0.0 is a real timestamp instead of meaning "stamp with now". (#3376)
  • dimos map summary moved to dimos mem summary; dimos.utils.benchmarking moved to dimos.control.benchmarking; lcmspy is a deprecated alias for dimos spy --transport lcm. (#2730, #2948, #2735)

✨ New Features

Manipulation

  • Planning groups, following the MoveIt/RoboPlan concept: multi-arm robots are planned as one model with selectable groups instead of planning each arm in sequence. (#2645) by @TomCC7
  • Mobile-base manipulation planning: PlanarBaseDefinition adds x/y prismatic and yaw joints to any robot model, with unbounded translation and continuous yaw (shortest-angle paths across the ±π boundary) handled by a prepared JointSpace. A base_trajectory coordinator task follows the planned x, y, and yaw on a twist base against odometry while arm and torso commands go to the joint trajectory task, and either side cancels when the other aborts. Try it on the Galaxea R1 Pro model (left_arm, right_arm, torso, moving_base groups) with dimos run r1pro-planar-preview. (#3784, #3844, #4096) by @TomCC7, @mustafab0
  • RoboPlan multi-robot planning: one composite scene with namespaced {robot_name}/{joint_name} joints, per-robot base_pose and collision exclusions, and coordinated cross-robot planning groups (dimos run dual-xarm6-planner-coordinator). world_backend="roboplan" and planner_name="roboplan" are now the manipulation defaults; Drake remains available with world_backend="drake" and planner_name="rrt_connect". (#3155) by @TomCC7
  • Pick and place rebuilt as a capability-composed module that coordinates object scene registration, grasp generation, and manipulation execution, with skills for stable-ID scan, explicit grasp selection, verified pick, and explicit place. A new HeuristicGraspModule provides a deterministic top-down parallel-jaw grasp from a segmented point cloud without the optional GraspGenX runtime. (#3715, #3709) by @ruthwikdasyam
  • GraspGenX grasp proposals: GraspCandidate / GraspCandidateArray messages and a GraspGenX provider that imports safely when the optional runtime is missing, wired into the grasping stack as xarm-grasp-graspgenx and xarm-grasp-graspgenx-agent. pick_object walks up to max_grasp_attempts ranked candidates, demoting only on planning failures, and the ranked proposals are drawn in Viser with a panel toggle. (#3367, #3874, #3876) by @TomCC7, @mustafab0
  • Straight-line Cartesian planning on the RoboPlan backend for approaches, retreats, and interactive moves, with a Viser Planning mode selector (Free-space / Linear Cartesian). Backends without support return UNSUPPORTED instead of substituting a free-space path. RoboPlan is upgraded to 0.6.x and time_optimal is the default Cartesian speed mode, with bounded still available. (#3240, #3370) by @TomCC7
  • Startup-selectable trajectory parametrization via TrajectoryParametrizerSpec: roboplan_toppra (TOPP-RA, default with world_backend=roboplan) or simple_trapezoid (default with Drake), set with trajectory_parametrization.backend. Viser gains a Next plan speed slider that applies to subsequent plans. (#3287) by @TomCC7
  • Planning-world obstacles are rendered in Viser with a visibility toggle, and obstacles can be replaced or moved atomically through ManipulationModule RPCs and the interactive client (update_obstacle, shape helpers such as update_box, and update_pose), so planning and collision queries never see a half-applied update. (#3108, #3164) by @TomCC7
  • The manipulation planner can avoid unregistered geometry using a live voxel map from a wrist camera: PointCloudSelfFilter drops the arm's own returns and emits a clear mask, RayTracingVoxelMap gains a voxel_clear_mask input so the arm can erase its own ghost voxels, and ManipulationModule takes the map on a new voxel_map input as a single ObstacleType.OCTREE obstacle (voxel_map_resolution, roboplan backend). The xArm grasp blueprint wires the chain end to end. (#3712, #3714, #3875) by @mustafab0
  • RoboPlan paths are shortcut with collision-aware path shortcutting (on by default, falls back to the original RRT path if shortcutting fails), and planning moves out of RoboPlanWorld into a separate RoboPlanPlanner with its own RoboPlanPlannerConfig. (#3325) by @TomCC7
  • Pink is now the only IK backend for Cartesian and EEF-twist control tasks. Every solve re-anchors to measured joint state and holds position on expected solve failures. The legacy Pinocchio control IK fallback and its self-collision logic are removed, all shipped manipulator teleop blueprints (including Piper) use direct URDF/Xacro models with named end-effector frames, and constructing a Pink task without the manipulation extra gives an install instruction. (#2992) by @TomCC7
  • Client-side Arm SDK (dimos.manipulation.sdk) for scripting one arm from dimos shell or Dimos.connect(): Arm.from_app(app), move_joints, move_pose, move_linear, home, move_to_preset, gripper open/close/position, with speed_scale= / timeout= and MotionError on failure. The obsolete singular plan_to_pose RPC and the standalone manipulation client runner are removed. (#3944) by @TomCC7
  • Robot asset manager: A1Z, A750, Piper, and xArm descriptions are no longer bundled LFS archives and instead resolve lazily from pinned Git sources (dimos cache clean --force discards cached checkouts). A single immutable RobotModel handles xacro expansion, package URIs, and joint-limit overrides in memory for Drake, RoboPlan, Pink, and Viser; the old model parser and legacy description fields are removed. A750 trajectory execution and Viser visualization are wired up. (#2505) by @TomCC7
  • Control coordinators can publish one JointState stream per robot by declaring {hardware_id}_joints: Out[JointState] (see coordinator-dual-mock), and the remaining single-robot consumers now read those instead of the merged coordinator_joint_state, which still publishes. (#3130, #3277) by @mustafab0
  • Viser robot display can switch between Visual, Collision, and Both meshes; robots without collision geometry show a translucent magenta substitute. (#3112) by @TomCC7
  • cancel is exposed as a manipulation skill, and reset is restored as both a skill and an RPC so a module in FAULT can recover and accept new plans. (#3872) by @mustafab0
  • Damiao-based arms (OpenYAM, Dual OpenYAM, OpenArm) work on macOS through a native gs_usb CAN bus alongside Linux SocketCAN; bus overrides are interface names on Linux and USB serials on macOS. dimos hardware can list prints the available interfaces or serials, and a teleop-webxr-openyam blueprint is added. (#3465) by @TomCC7

Robot support

  • Galaxea R1 Pro: ROS 2 connection, model, and coordinator with Zenoh for control, camera, lidar, and visualization streams, Rerun teleop routed into ControlCoordinator, and compressed camera frames passed through without re-encoding. Blueprints: r1pro-coordinator, r1pro-teleop, r1pro-nav, r1pro-manipulation. (#3933) by @mustafab0
  • Deep Robotics M20: native ROS/DDS command bridge, robot lifecycle control (M20Connection.standup() / liedown()), direct lidar and IMU ingestion into Point-LIO, ray-tracing mapping + MLS planning, and front/rear camera streams, all running onboard the RK3588 (dimos --transport lcm --rerun-host 0.0.0.0 run deeprobotics-m20-kronknav-control). Flat-terrain planning is reliable; stairs and dynamic obstacle avoidance are not yet, because the mapper runs behind on this device. (#3776) by @Nabla7
  • Boston Dynamics Spot (experimental): dimos run spot takes cmd_vel and publishes all sensor data plus static TF, and dimos run spot-record records it with lossless depth. The IP auto-detects (WiFi AP 192.168.80.3, then Ethernet 10.0.0.3) or can be forced with --spothighlevel.ip=.... A spot_small_loop dataset with all depth and greyscale cameras and intrinsics is included. (#3058, #3048) by @jeff-hykin
  • spot-replay blueprint plays a Spot recording back into Rerun with no robot (dimos run spot-replay --db-path=spot_small_loop.db), with camera pixels anchored to their capture-time pose. (#3433, #4071) by @jeff-hykin
  • Alfred wheeled base: wheel odometry, and alfred-mls-nav running cuVSLAM + wheel odometry (DimSlam) into the MLS planner, plus alfred-mls-nav-lidar and alfred-keyboard-teleop blueprints. Needs uv sync --extra misc. (#3620, #3634) by @jeff-hykin
  • OpenYAM arm: a gripper-equipped model (six arm joints plus gripper) for simulation and planning, and real hardware through a generic DamiaoWholeBodyAdapter (named CAN buses, multiple arm/gripper groups, normalized gripper, URDF-based gravity compensation) with an OpenYamDamiaoAdapter. Blueprints: openyam-planner-coordinator, coordinator-openyam, keyboard-teleop-openyam, keyboard-teleop-openyam-planner. CAN setup is now dimos hardware can setup can0 and dimos hardware can status can0. (#3049, #3129) by @TomCC7
  • OpenArm hardware support moved onto the Damiao whole-body adapter: both arms and both grippers are one device with fourteen arm joints (left_arm/joint1..7, right_arm/joint1..7) and two normalized gripper joints. The per-side and mock blueprints collapse into coordinator-openarm and openarm-planner-coordinator (the latter uses the mock whole-body adapter when no CAN ports are given); the old OpenArm adapter, driver, CAN scripts, and keyboard-teleop-openarm blueprints are removed. (#3388) by @TomCC7
  • Dual OpenYAM: a two-arm OpenYAM entity with mock and dual-CAN hardware support, coupled planning groups and Quest teleop (teleop-webxr-dual-openyam). (#3463) by @TomCC7
  • Galaxea A1Z 6-DOF arm in simulation, with a has_gripper flag selecting the G1Z gripper or bare-flange model. Blueprints a1z-planner-coordinator, coordinator-a1z, and keyboard-teleop-a1z run on the mock adapter; hardware support is a follow-up. (#2947) by @KrishnaH96
  • Galaxea A1Z real-hardware adapter (galaxea_a1z): staged safe startup, feedback validation, E-stop handling, position and servo-position modes, teaching/free-drive, and G1Z gripper support. Transport auto-selects Linux SocketCAN or macOS userspace gs_usb; host bring-up is dimos a1z setup and dimos a1z can-setup. (#3303) by @TomCC7
  • Piper arm over CAN with keyboard and Quest teleop: updated hardware adapter, model config and CAN activation helper, keyboard gripper control, and Viser plus trajectory-task wiring (dimos --can-port can0 run keyboard-teleop-piper). (#3101) by @TomCC7
  • Go2 over Zenoh: dimos --transport=zenoh run go2-zenoh-nav connects to a Go2 running the go2web dimos-helper with no robot IP needed (Zenoh auto-discovery), alongside go2-zenoh-basic, go2-zenoh-htc, and go2-zenoh-raycaster. Adds H264 video stream support (CompressedVideo) and a 3D planner blueprint. (#3141) by @leshy
  • Go2 metric velocity control: GO2Connection.blueprint(velocity_api=True) sends body-frame m/s twists through the Sport Move API instead of writing them to WIRELESS_CONTROLLER stick axes. Off by default. (#2859) by @bogwi

Web, cockpit & SDK

  • New web stack: --local-relay on dimos run spawns a local Deno relay at http://127.0.0.1:7780 and adds a RelayBridgeModule that bridges robot streams to browsers. The protocol carries the robot id and a per-robot channel manifest, uses one persistent stream per reliable channel, sends hello and snapshots on relay-opened streams, and bounds bridge ingress by bytes and per-encoding payload caps. (#3042, #3043, #3044, #3045, #3068, #3204, #3567, #3568) by @paul-nechifor
  • --local-relay opens the Cockpit, a React browser UI with a status bar (connection phase, reconnect countdown, robot name). The session client finds the robot, adopts its manifest, subscribes, and reconnects on its own when the relay or dimos restarts; rate and age are measured on the robot's clock. (#3205, #3206, #3909) by @paul-nechifor
  • Cockpit panels: Video (color_image as jpeg.v1, with FPS and staleness, encoded only while a viewer listens), a 2D costmap with the robot's position (global_costmap, zlib-compressed, downsampled when too large, newest grid cached for new viewers), keyboard teleop with the same WASD/QE controls (one controlling cockpit at a time), a dtop-style Stats panel that turns on resource monitoring automatically (--no-dtop still disables it), and a channel table behind a header tab. Also fixes the MuJoCo sim periodically stalling because its output pipe was never drained, and a video feed that could get stuck. (#3263, #3326, #3328, #3907, #3906, #4209) by @paul-nechifor
  • Robot blueprints describe their own cockpit with a layout API: Row / Col splits over panels such as Video, Map2D, Teleop, Chat and Stats (see unitree-go2-cockpit and unitree-go2-agentic-cockpit). (#3327) by @paul-nechifor
  • Navigate from the cockpit map: clicking the map panel sends a goal, planned paths are drawn on the map, and a cancel button stops the movement while navigating. (#4183) by @paul-nechifor
  • Chat() panel in the web cockpit to message the robot's agent from the browser, showing replies, tool activity, and a thinking indicator; the new unitree-go2-agentic-cockpit blueprint places chat alongside the existing panels. (#3901) by @paul-nechifor
  • Push-to-talk microphone in the cockpit chat panel: hold to record, release to send. A new VoiceInput module transcribes recordings with local Whisper, and spoken messages enter the same agent conversation as typed ones. (#3905) by @paul-nechifor
  • Web SDK extracted from the cockpit as @dimos/sdk (web/sdk, React bindings on @dimos/sdk/react, no React dependency otherwise). The local relay serves it at /sdk.js and --serve-dir <dir> serves your own page instead of the cockpit (loopback only by default). Any dimOS message can be sent to the web by registering converters with @web_encoder / @web_decoder, and browsers publish to the robot through shared input channels declared in the cockpit config with session.publish(), which is acknowledged once the bridge has published the message; incoming messages are validated and limited in size, rate and pending requests. (#3565, #3566, #3569, #3570, #3727) by @paul-nechifor
  • Standalone and shared relays: --relay-url takes the relay's HTTP URL (for example http://localhost:7780) and the robot reconnects after relay restarts; a robot picker (names, models, ids, plus a "switch robot" button) appears when several robots share a relay, each with its own panels and tabs; the relay's --cert / --key serve HTTPS and robot data on one port for access from other machines, with --relay-ca on the robot for a private CA. (#3950, #3951, #3952) by @paul-nechifor

Teleoperation

  • Hosted teleop is now a first-class WebRTC DataChannel transport backed by Cloudflare Realtime: CloudflareTransport / CloudflareVideoTransport bind directly to blueprint streams and share one broker session per process, configured through transports.broker.*. The Go2 stack (teleop-hosted-go2-transport, teleop-hosted-go2-multicam) is split into small modules: Go2CommandModule (robot-side command validation, E-STOP latch, stop on operator lost, click-to-navigate), CameraMuxModule (operator-selectable multi-camera, optional latency_stamp), MapCompressModule (operator minimap) and HostedStatsModule (link latency/jitter, battery and robot state telemetry). (#2048, #2798) by @spomichter, @ruthwikdasyam
  • Hosted arm teleop: teleop-hosted-xarm6 / teleop-hosted-xarm7 let a remote operator drive an xArm from Quest VR or the browser keyboard (WASD/QE, Space toggles the gripper) with two RealSense cameras in the mux. ArmCommandModule handles EE-twist, gripper and E-STOP; EEFTwistTask holds pose when idle and outputs gripper commands; the coordinator gains a gripper_command input. (#3004, #4085) by @ruthwikdasyam
  • Operator microphone audio is routed to the Go2 speaker during hosted teleop through a subscribe-only WebRTC audio transport and Go2AudioBridgeModule, with auto / enabled / disabled speaker modes for Go2 Pro vs Go2 Air (-o go2audiobridgemodule.speaker=enabled). (#3268) by @ruthwikdasyam
  • robot_type in BrokerConfig, pinned per blueprint, so the hosted teleop dashboard opens the matching operator view without a manual pick. (#3144) by @ruthwikdasyam
  • Runtime translation scaling for Quest teleop (default 1.0); hosted arms opt in with enable_ui_scaling, and the operator UI sets it with a teleop_scale command that scales controller position deltas and browser keyboard linear twists. (#3406) by @ruthwikdasyam
  • Arm teleop unified on a shared Pink IK core: keyboard teleop publishes EEF twist to a new EEFTwistTask, TeleopIKTask moves from the legacy Pinocchio solver to Pink, and a shared PoseTargetIKTask core backs CartesianIKTask, EEFTwistTask and TeleopIKTask with bounded per-step velocity, joint-limit and tracking-error checks. TeleopIKTask supports one or two hand bindings with optional gripper joints, and teleop-webxr-openarm drives both OpenArm arms in one bimanual solve (fake hardware by default, --left-can-port / --right-can-port for real hardware). (#2683, #3237, #3392) by @TomCC7
  • unitree-g1-teleop: G1 Quest arm teleop on the shared dual-arm IK stack, combined with GR00T locomotion, Viser, RealSense video and episode recording, on MuJoCo and real hardware, with guided hardware activation, ready-pose, status and disable commands. (#3436, #4148) by @TomCC7, @KrishnaH96
  • Controller-free Quest hand teleop: the Quest client publishes WebXR wrist poses and thumb-index pinch state, and HandTeleopModule toggles each hand on a pinch (teleop-webxr-hand-xarm7). (#3394) by @ruthwikdasyam
  • PICO WebXR body tracking: a device-neutral BodyTrackingSnapshot output, off by default with optional / required session modes, support for PICO's six-button controller packets, and a demo-pico-body-tracking API-test blueprint with a live monitor. (#3695) by @TomCC7

Navigation

  • Navigation on the real G1 in the unitree-g1-groot-wbc blueprint: MID-360 -> Point-LIO -> ray-tracing voxel map -> height costmap -> replanning A*, driven through the coordinator's twist_command (no sport mode). The firmware-reported mode_machine is adopted at first LowState, and the tick drops to 100 Hz so the Orin keeps up. (#2861) by @Nabla7
  • Holonomic trajectory controller (DanHolonomicTC) that strafes onto the path, keeps moving through corners, and profiles speed by curvature, plus a DanLocalPlanner with path smoothing and an optional lock_replan distance to stabilize MLS paths. Run with dimos --robot-ip <IP> run unitree-go2-mls-htc -o danholonomictc.run_profile=<walk|trot|run_conservative>. On-robot speed is uncalibrated until the Go2 driver gets a metric velocity API. (#2697) by @bogwi
  • Progress-indexed holonomic full-pose tracker for the Go2: follows a Path whose waypoints carry a commanded yaw decoupled from travel direction, and re-projects on replan without ramping from rest. Run it standalone with unitree-go2-holonomic-controller or benchmark it with unitree-go2-holonomic-benchmark (RPP equivalents: unitree-go2-rpp-controller / unitree-go2-rpp-benchmark). Benchmarking utils moved from dimos.utils.benchmarking to dimos.control.benchmarking, and heading error is now scored against the path's commanded yaw. (#2948) by @mustafab0
  • Voxel support filter and planner tuning for stairs: the local map only emits surface voxels with at least support_min occupied neighbors, clouds with no odometry within a configurable range are dropped instead of misregistered, the MLS planner ignores voxels more than max_overhead_m above the sensor, and string pulling gives smoother paths. export DIMOS_NAV_RECORD=1 turns on a Point-LIO recorder in the nav blueprint. (#2739) by @aclauer

Mapping, SLAM & relocalization

  • Generic lidar relocalization against a saved map, no longer Go2-specific: dimos run relocalize-mid360 --dataset <name> --map-file <name> replays a recording against a map, with new CloudRelocalization, LidarWindowRelocalization, LocalMapRelocalization, and Go2Relocalization modules, a dimos map view command, and a tuning guide and tune.py tool for new lidars. The publish_loaded_map option is replaced by republish_loaded_map and tf_interval. (#3890) by @leshy
  • cuVSLAM stereo visual odometry with loop closure (dimos --viewer rerun run demo-dim-slam-realsense with a RealSense D455 / D435i), and the DimSlam native module that enhances cuVSLAM with wheel odometry. (#3631, #3632) by @jeff-hykin
  • Dual-resolution voxel mapping: 9 cm macro voxels subdivided into 3 cm micro voxels, so rays trace on macro voxels and only descend into micro voxels on a hit. fine_divisor (default 3) sets the subdivision and sharpens ray clearing even when the fine map is not published; emit_fine publishes local_map_fine. MLS planner graph nodes are now sticky across updates. Cloud-in to path-out drops from 25.5 / 64.3 ms (p50 / p95) to 10.1 / 19.7 ms on the mid360_athens_stairs dataset. (#3454, #3687) by @aclauer
  • Rust Livox Mid-360 driver: parses the Livox UDP protocol into raw clouds from a live sensor (dimos run mid360, DIMOS_MID360_LIDAR_IP to set the sensor address) or a pcap (demo-mid360-pcap-replay). (#3852) by @aclauer
  • dimos map global --denoise removes stray points (e.g. returns in the sky) from the reconstructed global map; adds the mid360_athens_stairs Point-LIO recording. (#2811) by @leshy

Simulation

  • Habitat simulation: map and navigate inside photorealistic HM3D building scans with no robot. dimos run habitat-nav (ray-tracing map + MLS planner + click-to-goal), with habitat-teleop, habitat-raycaster, and habitat-voxel as smaller layers. The first run builds a habitat-sim conda env (about 3.5 GB); requires Linux x86_64, nix, and an NVIDIA driver with EGL. (#4011) by @leshy
  • DimSim moved into the repo at misc/DimSim/ and driven directly via --simulation dimsim. Scenes are authored in JS (scenes/<name>/index.js exporting async build(api)), the apartment scene is ported from a 97 MB JSON to ~6 MB of JS and textures, evals are one JS file per workflow runnable in the browser or Deno, and a dimsim CLI ships dimsim dev, dimsim eval list, and dimsim eval <workflow> (with --headless). (#2187) by @Viswa4599
  • Headless MuJoCo xArm grasping sim on data/xarm_grasp_sim with a simulated wrist camera and owlv2 + yolo perception. It runs the same stack as the real arm: use the xarm-grasp blueprint with --simulation mujoco. (#3760) by @mustafab0
  • Scene cooking (experimental, dimos.experimental.scene_cooking): an offline pipeline that turns a .blend, .glb, or .usd source plus an optional sidecar into a scene package with scene.meta.json, Rerun/Babylon browser visuals, collision/raycast geometry, MuJoCo collision XML, and optional .mjb binaries. (#2544) by @Nabla7

Perception

  • RealSense is now a native Rust module: RealSenseCamera runs all streams at 30 fps, publishes colored pointclouds, and drops the voxelizer that capped it at 5 fps. camera_name is replaced by the standard frame_id / frame_id_prefix, so multiple cameras compose with .namespace("front"); the camera no longer emits mount transforms (use RealSenseMountTf in the robot blueprint). Also adds D455 support, stereo IR streams (enable_infrared), and IMU output (enable_imu) with a workaround for Intel's IMU timing issue. (#3746, #3449, #3705, #3868, #4054) by @leshy, @jeff-hykin, @mustafab0
  • WorldBelief object identity layer for xArm6 manipulation (xarm6-worldbelief): YOLO-E prompt detections and RGB-D objects with CLIP and DINO crop embeddings are associated into stable object IDs with support windows and re-acquisition, pick and place reads the resulting present objects, identity evidence persists to a memory2 history DB and is rehydrated on restart, and a recorder writes a per-run memory2 DB. Two RealSense D435i recordings ship as LFS datasets: xarm6_worldbelief_realsense_d435i_kitchen and xarm6_worldbelief_realsense_d435i_stationery. (#2665, #3255) by @jhengyilin
  • Offline object perception over recordings: inventory() finds and names every object in view without a text prompt and deduplicates instances by geometry; localize() turns a text query into masks (SigLIP retrieval, OmDet boxes, EdgeTAM segmentation), lifts them through depth, verifies across views, and returns the latest point cloud and world position. A DanDetector wrapper exposes embed() and localize() over recorded or live stores. (#3422, #3496) by @bogwi
  • Object scene registration: opt-in OWLv2 detection and EdgeTAM segmentation backends, a request-driven scan_scene API on ObjectSceneRegistrationSpec that returns pending objects with stable IDs and point clouds, and a detector_confidence config key (default 0.6). YOLOE/YOLO defaults are unchanged. (#3713, #3755) by @ruthwikdasyam, @mustafab0
  • dimos/perception/memory/tool_localize.py localizes a text-queried object (e.g. "coke can") over a time window of a memory2 recording and writes localize.rrd for the viewer; ships xArm6 + RealSense D435i example recordings. (#3279) by @leshy
  • dimos apriltag --3d generates 3D-printable fiducial plates (e.g. dimos apriltag --3d --ids 0 --legs 250 --size-mm 75), with options for thickness, marker layer depth, mounting holes, back text, and legs. (#3166) by @leshy

Memory, recording & cloud

  • dimos --replay-db <memory.db> run replay plays any recording back onto the bus with the viewer: one output port per recorded stream, the recorded blueprint's viewer layout when the run directory names it, and single-timestamp streams such as camera_info republished at 1 Hz. A bare dataset name resolves like --replay. (#3738) by @spomichter
  • dimos --record run <blueprint> records every published stream of any blueprint into recordings/<run-id>/memory.db without wiring a recorder module; --record-topics selects streams by comma-separated globs. An experimental Rust engine (--record-engine rust, with --record-encoding-threads) adds --record mcap; bare --record stays on Python SQLite. (#3710, #3924) by @spomichter, @TomCC7
  • dimos data uploads recordings (or any file) to Dimensional cloud: dimos data upload [--since 1h] [--kind log --robot <id>] [--no-compress], plus ls, pull, status, and quota. Uploads are resumable (keyed on sha256, only missing parts are re-sent), lz4 compressed, skip live sessions, and refresh expired presigned part URLs during long uploads. dimos data ls opens an interactive TUI on a terminal (plain table when piped), shows upload times in local time, and adds an uploader column for org datasets; quota shows total and daily limits. Config keys: dimos_upload_retries, dimos_upload_compress. (#3548, #3881, #3895, #3897, #3893, #3913) by @spomichter
  • Experimental native recorder module rust-recorder (dimos.experimental.memory, binary dimos-memory-recorder) writes SQLite (lcm, jpeg, lz4+lcm codecs) or Zstd-chunked MCAP with a configurable encoding_threads pool; both artifacts stay readable through the stable SqliteStore / McapStore Python APIs. (#3615) by @TomCC7
  • StreamTF: TF lookups backed by a recorded tf stream (StreamTF.from_store(store)), answering the same queries as live TF; dimos map uses it to build global maps from sensor-frame recordings. (#2707) by @leshy
  • unitree-g1-record blueprint records Point-LIO, RealSense, and TF from the G1, with a dynamic torso to base-link transform from joint states; adds a g1_sf_office recording. (#3527) by @aclauer
  • memory2 CLI: dimos mem summary (moved from dimos map summary) with stream sizes and shared progress bars, dimos mem rerun resolves datasets by bare name and takes --root to nest streams under an entity path, and Go2 DDS .mcap decoding covers more message types. Go2 --replay resolves go2_lidar / go2_odom streams with fallback to lidar / odom. (#2730, #2521) by @leshy
  • New sf_office_stairs recording (Mid-360 Point-LIO + D455 stereo, two floors, start and stop at the same location) for smoke tests, and an updated china_office recording. (#3349, #2702) by @jeff-hykin

Evals

  • New dimos/evals package with two case types: PassiveEval (scored against a frozen memory2 recording over any replay window) and InteractiveEval (live sim or robot, scored by sampling the live recorder store every interval_s). memory2 streams are the eval input, scoring is plain functions with graded [0,1] credit (within, ramp, exact), and VQA cases use the langchain/openevals inputs / reference_outputs format. Runnable via dimos evals run <suite>, EvalModule MCP skills, and pytest; a MoondreamChat adapter runs suites locally without API keys. Each run writes results.jsonl, summary.json, and per-case transcripts to ~/.local/state/dimos/evals/run-*/. (#3411) by @spomichter
  • Eval agents and environments are configurable: a single EvalCase type takes an environment (dataset, sim, or image) and the agent is chosen at run time with dimos evals run <suite> --agent <agent> --set <key=value>. Bundled agents include dimos.evals.agents.question_answer, dimos.evals.agents.blind, dimos.evals.agents.mcp_client_adapter (the production MCP agent, e.g. --set 'modules=["unitree-go2-agentic"]'), and dimos.evals.agents.pi. Adds the first multi-step agent eval (count the rooms in the dimsim apartment scene) and saves agent trajectories in the Agent Trajectory Interchange Format. (#3774) by @hvent90
  • Deterministic multiple-choice VQA datasets from recorded camera frames with dimos evals vqa generate <recording.db> and dimos evals vqa run <dataset>. Image-only families (presence, horizontal detection, object count) take answers from Moondream detections; recordings with camera_info, tf, and LiDAR (pointlio_lidar or lidar) also get object distance, relative distance, image coverage, and largest visible area from EdgeTAM masks and projected point clouds. Outputs include lossless PNG assets and audit metadata. (#3488, #3492) by @ruthwikdasyam
  • dimos nav-eval for automated navigation tests: run executes the cases on the datasets, ingest adds test cases for a new dataset automatically, and pick-case adds cases manually with tags and negative cases. (#3344) by @aclauer

Agents, skills & MCP

  • Opt-in capture of raw LLM request/response bodies for the MCP client via tracing_http_client(<dir>) in dimos.agents.llm_trace (OpenAI requests only; auth headers are not saved). Off by default. (#3843) by @hvent90
  • MCP call timeout is set by the client: dimos mcp call <tool_name> --timeout <seconds> (-t), defaulting to the new mcp_timeout config key (30). (#3948) by @bogwi

Learning & datasets

  • Quest collection HUD: a world-locked in-headset panel shows episode state, take, elapsed time, saved/discarded counts and last action during data collection, so operators do not need to remove the headset. (#3608) by @ruthwikdasyam

Core, modules & tooling

  • Zenoh transport for streams, RPC, and tools (dimos --transport=zenoh ..., humancli --transport=zenoh), with RPC running on native Zenoh queries (ZenohRPC) instead of pub/sub. (#2362, #3176) by @paul-nechifor, @bogwi
  • Blueprint namespaces: a coordinator can run multiple instances of the same module class, and namespace(prefix, *blueprints, expose=...) prefixes instance names, stream topics, RPC topics, and TF frames so one blueprint can control several robots of the same type. Per-instance config via -o robot0/go2connection.ip=10.0.0.5 or ROBOT0_GO2CONNECTION__IP. New unitree-go2-multi and unitree-go2-multi-teleop blueprints (ROBOT_IPS=... dimos run unitree-go2-multi-teleop; with --simulation each robot gets its own MuJoCo process). (#2725) by @paul-nechifor
  • Blueprint config as plain CLI options: dimos run unitree-go2 --voxel-size 0.2, disambiguated as --voxelgridmapper.voxel-size or --robot0/go2connection.ip=... for namespaces, with "did you mean" suggestions for unknown options. Parsing is centralized in BlueprintConfigParser. (#3305) by @paul-nechifor
  • External blueprint registration: packages expose blueprints or modules through the dimos.blueprints entry-point group and users run them by namespaced name (dimos run my-robot-stack.go2, combinable with built-ins); dimos list shows them. (#2517) by @TomCC7
  • dimos shell: an IPython shell that attaches to a running coordinator (foreground, daemon, or blueprint.build().loop()) to discover modules and call their RPCs, with guide(), modules(), rpcs(), and describe() helpers, tab completion of RPC names, and app.find_module_by_spec(MySpec) to find a module by its Spec. No McpServer required. (#3236, #4009) by @TomCC7
  • dimos spy: a live table of every topic across LCM and Zenoh with per-topic rate, bandwidth, size, and liveness (dimos spy --transport zenoh to filter). lcmspy remains as a deprecated alias for dimos spy --transport lcm. (#2735) by @leshy
  • dimos login, dimos logout, and dimos whoami: device-code cloud auth that needs no browser on the robot; approve the 8-character code from any signed-in browser and the API key is stored with 0600 permissions. DIMOS_API_KEY overrides the stored key; dimos_cloud_url defaults to https://api.dimensional.org. (#3522, #3549, #3730) by @spomichter
  • dimos cache clean removes all regenerable caches, which now live under one platform CACHE_DIR. It keeps logs, recordings, datasets, and config, refuses while a run is active or a robot asset checkout has local changes unless --force, and supports --yes for non-interactive use. (#3178) by @TomCC7
  • CompressedImage is a first-class sensor message (JPEG/PNG bytes + timestamp + frame_id) that works as a typed LCM message on any transport: CompressedImage.from_image(img, format="jpeg", quality=75, max_width=None), decode() back to Image with timestamp and frame_id preserved, and to_rerun() as an encoded image. Use format="png" for 16-bit depth. 720p at q75 is about 19x smaller on the wire (2.76 MB to 142 KB); a sustained 14 Hz 720p feed over untuned LCM delivers 14.0 Hz compressed vs 0.8 Hz raw. (#2814) by @spomichter
  • Experimental IsolatedPythonModule: run a Python module from a sibling uv (or Pixi-provided uv) project whose dependencies conflict with the host environment, while keeping typed streams, RPCs, skills, module references, lifecycle, and restart behavior. (#3478) by @TomCC7
  • Rust native modules support Zenoh: the transport trait is now a pub/sub contract with a publish thread and QoS per topic, and the Zenoh transport accepts mode (peer/client/router), connect, listen, multicast, interface, and gossip settings. (#2753, #3464) by @aclauer
  • Transforms in Rust modules: a #[tf] attribute subscribes a module to the transform topic, with get_latest(), .at(), .tolerance(), and .within() lookups; also adds IO ports and a toggle to disable the Go2 base_link TF when another source provides it. (#2816) by @aclauer
  • C++ native module interface rewritten to match the Rust API, with selectable transports; existing C++ native modules are ported and now build as C++20. (#2944) by @aclauer
  • dimos bake links several Rust native modules into one host binary (dimos bake ray-tracing mls-planner -o <host>), with --list, --dry-run, --suppress to keep a topic inside the host, --remap, --target, and --emit-config. New go2-zenoh-nav-baked and go2-zenoh-nav-remote blueprints use it; zenoh_gossip now defaults to on. (#3490) by @aclauer
  • ControlCoordinator tasks are declarative: each task declares its input streams and RPC-invokable methods in a _registry.py card, and the coordinator builds its route table and command allowlist from the registry, so adding a task no longer means editing the coordinator. task_invoke only dispatches methods a task lists in TASK_EXPOSES. Twist, cartesian, velocity, teleop, servo, and G1 GR00T tasks are migrated. (#2959) by @mustafab0
  • ControlCoordinator accepts arbitrary input streams: subclass it and declare extra inputs (e.g. wrench: In[WrenchStamped]) instead of the five hardcoded ones; TaskConfig.stream_bind maps a task input to a port per instance, and a new direct routing rule delivers unconditionally. (#3110) by @mustafab0
  • PointCloud2 supports per-point fields beyond x,y,z,intensity, including offset_time, tag, line, and timestamp. (#3103) by @jeff-hykin
  • dimos graph <blueprint> --output <file>.svg renders a blueprint's topology as an SVG, including RPC dependencies as dashed edges. (#3693) by @poorwym
  • Rerun can display every frame in the TF tree with the correct hierarchy (tf_axes option), and go2-zenoh-nav takes Mid-360 mount presets (--mid360-mount=SF, --mid360-mount=ATHENS). (#3345) by @aclauer
  • Quieter startup logs: SpatialMemory, ChromaDB, and image-embedding info messages removed, the LangChain pending-deprecation warning silenced, expected TF lookup misses no longer warn, and "Starting DimOS" is logged first for immediate feedback. (#3612) by @paul-nechifor

Install & packaging

  • uv sync --extra manipulation --inexact now installs everything the shipped manipulation blueprints need: the manipulation extra composes planning, base, sim, and cpu, and new narrower control (coordinators, arm adapters, keyboard/Cartesian control, xArm SDK) and planning (Drake, RoboPlan, visualization) extras are available for smaller installs. EdgeTAM and timm moved from misc to perception, and python-socketio is declared in web. (#4066) by @TomCC7
  • Fresh clones no longer download the large data/.lfs/*.tar.gz archives (lfs.fetchexclude in .lfsconfig); they arrive as pointer files and are pulled on demand, while other LFS assets still pull normally. (#3147) by @leshy
  • test_*.py files are no longer shipped in the published package. (#2706) by @paul-nechifor

🐛 Bug Fixes

  • dimos mem rerun projects the camera image into 3D: the recorded camera_info is logged as a Pinhole on its image entity, parented into the tf frame graph, so the camera follows the robot; Go2 camera_info is stamped on each publish instead of once at import. (#3914, #4223) by @KrishnaH96
  • Go2 and G1 ignored teleop and path commands under the default Zenoh backend because the transport_lcm twist and whole-body adapters still built raw LCM transports; they now follow the active pub/sub backend. (#4070) by @mustafab0
  • Joint trajectory task no longer reuses stale commanded positions after another task (e.g. teleop) moved the joints, which caused dangerous jumps on the next execution; hold_position_when_idle is removed. (#3969) by @TomCC7
  • KeyboardTeleop publishes only while a key is held (publish_only_when_active defaults to True), so an idle keyboard window no longer fights Rerun or command-center teleop on cmd_vel and freezes the Go2 (dimos run unitree-go2 keyboard-teleop). (#4119) by @KrishnaH96
  • unitree-g1-sim now moves: unitree_g1_basic_sim gets a MovementManager so click-to-go and WASD velocities reach the sim connection (broken in 0.0.13). (#4150) by @KrishnaH96
  • Zenoh: a session waits for its links only once, so the first Rerun WASD key presses no longer stall for about 4 s on a WebRTC Go2. (#4144) by @KrishnaH96
  • Zenoh bumped to 1.10.1, fixing multicast scouting on macOS where local workers never discovered each other and runs died with a 120 s set_transport timeout. (#3963) by @bogwi
  • Coordinator RPC works with Zenoh in daemon mode: Zenoh sessions now start only after forking. (#3503) by @paul-nechifor
  • LCM segfaults on unsubscribe fixed: the LCM-level detach is deferred to the LCM loop thread, unsubscribe() no longer blocks on an in-flight callback, and no deliveries start after it returns. SHM RPC now uses a ring queue instead of the latest-wins frame channel, so concurrent RPC messages are all delivered. (#3291, #2717) by @Dreamsorcerer
  • SHM transport: new subscribers no longer receive a stale frame left in a /dev/shm segment by a killed process; they start at the segment's current sequence. (#4108) by @KrishnaH96
  • Shared-memory readers wait for the segment to be sized instead of crashing with ValueError: cannot mmap an empty file; raises ShmNotReadyError on timeout. (#3672) by @mustafab0
  • Lidar messages are no longer dropped at startup: message types can define an lcm_warmup hook that runs at subscribe time, and PointCloud2 uses it to import open3d before the first decode. (#3320) by @paul-nechifor
  • Callable objects in blueprint configuration are preserved instead of being serialized to dicts, fixing unitree-g1-groot-wbc failing to deploy RerunBridgeModule. (#4141) by @christiefhyang
  • Partial dotted CLI overrides merge into nested module config instead of replacing blueprint defaults, and dimos run <blueprint> --help no longer crashes on nested config models (e.g. keyboard-teleop-xarm7). (#2829, #2795) by @TomCC7
  • TRANSPORTS__<name>__* env vars for transports a blueprint does not declare are ignored, so a .env copied from default.env no longer fails with Unknown transport configuration section(s): broker. (#3445) by @KrishnaH96
  • Module references declared by concrete class now match subclasses; previously a subclass provider left the dependency silently unset. (#3408) by @mustafab0
  • Pick and place waits on measured gripper feedback instead of fixed sleeps and verifies the grasp before lifting, so a missed grasp no longer proceeds to the lift. Gripper arrival is judged by the open band, so opening an already-open gripper no longer times out with gripper did not settle, and the MuJoCo sim reports gripper readback on the same scale as the command. (#3701, #3870, #3697) by @mustafab0
  • Convex-hull mesh obstacles (use_mesh_obstacles=True) no longer overwrite each other's hull files and are placed at their build centroid, fixing a corrupted planner collision world. (#3668, #3669) by @mustafab0
  • Pink IK retries the remaining perturbed seeds when the QP solver raises NoSolutionFound for one seed, so reachable grasp poses no longer report NO_SOLUTION. (#3674) by @mustafab0
  • ManipulationModule consumes perception's objects stream again, so the planner sees detected objects as obstacles; adds explicit obstacle refresh/query RPCs to keep the world sync off the transport thread. (#3753) by @mustafab0
  • The xArm wrist camera mount transform is published, so camera_link has a parent and RealSense output resolves into world using the hand-eye calibration. (#3871) by @mustafab0
  • Viser leaves EXECUTING when a nonblocking trajectory finishes, and the plan is cleared on dispatch, so you can plan again without cancelling manually. (#3982) by @TomCC7
  • Agentic xArm simulation stabilized: the MCP HTTP server runs in a dedicated worker so it stays responsive during simulation and planning, simulated wrist-camera transforms are aligned to the configured robot base, scene registration is timestamp-aware with bounded TF lookup, the simulated xArm starts from a collision-safe joint pose, and IK/planner failure details are preserved for the agent. (#2999) by @TomCC7
  • ObjectSceneRegistration captures the camera transform before detector inference, so slow (CPU) inference no longer outlives the TF buffer and drops valid 3D detections; ObjectDB now promotes an object on its first sighting when the promotion threshold is one. (#3756, #3754) by @mustafab0
  • Perception detector imports are resolved when the module is constructed, fixing Could not import module 'AutoModelForCausalLM' under concurrent module startup; unselected optional detectors are still not imported. (#4008) by @TomCC7
  • is_cuda_available() now detects CUDA via torch instead of the never-installed pycuda, so YOLO detectors stop silently falling back to CPU on CUDA hosts. (#3673) by @mustafab0
  • Person follow works again: default VL model switched from the no-longer-hosted qwen2.5-vl-72b-instruct to qwen-vl-max. (#3448) by @paul-nechifor
  • Imitation collection: the recorder stops after camera, teleop, coordinator, and episode producers; an episode interrupted by shutdown is saved as an explicit discard; episode button mappings are validated at startup; and dimos dataprep inspect reports incomplete episodes separately. A Quest disconnect now clears controller engagement and publishes a zero-button safe command. (#3497) by @ruthwikdasyam
  • Collection session DBs are written under RECORDINGS_DIR like every other recorder, instead of a hardcoded STATE_DIR / "recordings". (#3546) by @spomichter
  • Recorder tags each observation with a reception_ts ingress timestamp (for command-link latency) and no longer logs a "no pose" warning per message on poseless streams such as cmd_vel_stamped. (#2927) by @ruthwikdasyam
  • Go2 recorders (Go2Memory, Go2Mid360Recorder) record the camera_info stream so recordings are self-contained. (#3748) by @ruthwikdasyam
  • Simulation camera images, TF, and camera_info are stamped at render time and paced on the monotonic clock, removing a 4.5 to 101.7 ms timestamp skew. (#3690) by @mustafab0
  • demo-camera shows the webcam image in Rerun again: Webcam reports a nominal pinhole (capture size, 60 degree horizontal FOV) when no intrinsics are configured. (#4153) by @KrishnaH96
  • Webcam accepts device paths as well as numeric indices and selects V4L2 for Linux /dev/ paths (including /dev/v4l/by-id/), so capture properties are applied. (#4159) by @TomCC7
  • Go2 replay in Rerun no longer updates the robot pose only once per second; the custom dimos_time timeline was removed. (#2810) by @Nabla7
  • Go2 stop_movement sends its zero twist on the connection's event loop thread. (#2977) by @ruthwikdasyam
  • unitree-go2-multi and unitree-go2-multi-teleop fail immediately with a configuration error when ROBOT_IPS / --robot-ips is empty, instead of No modules deployed. (#4140) by @christiefhyang
  • cv2.imshow no longer hangs at 100% CPU after Dimos.connect() / peek_stream() in the Python API: OpenCV is now loaded before PyAV, whose bundled libxcb was breaking OpenCV's Qt window plugin. (#4155) by @KrishnaH96
  • humancli displays tool-call messages again (it assumed string message content) and prints a notice when a message cannot be rendered. (#4015) by @paul-nechifor
  • dtop reports memory on macOS by falling back to RSS when PSS is unavailable. (#3054) by @jmnie
  • Python 3.10: CLI imports work again (Self imported from typing_extensions). (#3932) by @mustafab0
  • The Rust LCM transport honors LCM_DEFAULT_URL. (#3740) by @jeff-hykin
  • --build-native triggers a rebuild again, and native module build output streams to the log as it happens instead of appearing stuck. (#3323, #3258) by @aclauer
  • get_data() initializes Git LFS (git lfs install --local --skip-repo, scoped to the data repo) before on-demand pulls, so archives no longer stay as pointer files when the user's Git LFS filters were never set up. (#3661) by @TomCC7
  • dimos data pull no longer fails on files whose name already ends in the codec suffix (e.g. *.lz4): content_encoding is only stamped when compression actually ran. (#3882) by @spomichter
  • Packaging: edgetam-dimos bumped to 1.0.1, which ships the non-Python files (e.g. sam2/csrc/connected_components.cu) missing from the previous release. (#3456) by @paul-nechifor
  • Minimum uv version set to 0.9.25; uv sync failed on older uv because it could not parse the cooldown opt-outs in pyproject.toml. (#3941) by @omarespejel
  • dimos CLI starts without onnxruntime installed; G1 controller dependencies are no longer imported eagerly. (#4072) by @ruthwikdasyam
  • Clearer simulation setup errors: DimSim fails fast when its assets are Git LFS pointers (GIT_LFS_SKIP_SMUDGE=1) instead of a 90 s timeout, and a missing mujoco_playground points to uv sync --extra sim --inexact. (#3577, #3654) by @paul-nechifor, @christiefhyang
  • dimos topic send works again for all message types. (#2760) by @paul-nechifor
  • Conflicting OpenCV packages resolved: only opencv-contrib-python is installed and plain opencv-python is overridden out. (#2705) by @paul-nechifor
  • Nav recordings are saved to a gitignored recordings/ directory at the repo root. (#2796) by @aclauer
  • MLS planner builds on macOS. (#2836) by @jeff-hykin

⚡ Performance

  • Go2 stack CPU load cut: thread pools of imported libraries are capped (they were created before forking and pushed dimos past 1k threads), Open3D / OpenCV / Rerun imports are forced inline, Zenoh runs local-only by default with a system configurator for SHM transport, and the CPU voxelizer is faster. (#3272) by @leshy
  • Replay memory use cut by about 17x (2.8 GB to 162 MB for one minute of dimos --replay --replay-db=go2_bigoffice run unitree-go2). (#3149) by @bogwi
  • macOS: dimos sets OMP_WAIT_POLICY=PASSIVE and KMP_BLOCKTIME=0 by default (user environment overrides win), stopping OpenMP spin-wait in Open3D workers. dimos --replay run unitree-go2 dropped from about 100% to 16% CPU and 33 W to 12 W in the PR's measurement. (#3190) by @bogwi
  • Message construction in dimos/msgs is 5x to 48x faster after dropping plum multiple dispatch from __init__ (e.g. Pose() 48.9 µs to 1.0 µs; a 207-pose Path 11.7 ms to 0.76 ms). Stamped messages now take ts: float | None = None, so ts=0.0 is a real timestamp instead of meaning "stamp with now". (#3376) by @leshy
  • LineSegments3D encoding, decoding, and Rerun conversion are vectorized (60,000 segments: 404 ms to 0.5 ms), so large planner graphs visualize without stalling. (#3956) by @aclauer
  • MLS planner surface morphology is hand-written and runs per surface cluster instead of allocating a full 2D image per z level, which helps most in very large spaces; the imageproc dependency is removed. (#3741) by @aclauer

🔒 Security

  • Dependabot configured to keep pinned dependencies updated, with a cooldown on newly published Rust crates (supply-chain protection; the matching cargo config takes effect once cargo enforces it). (#1538, #3598) by @Dreamsorcerer

📚 Documentation

  • Docs site moved to docs.dimensional.org and made agent-readable: llms.txt, raw Markdown by appending .md to any docs URL, and a view/copy Markdown dropdown on each page; plus a theme refresh with header and copy-button fixes. (#3689, #3678, #3680, #3927) by @hvent90, @spomichter
  • Docs moved to MkDocs: dimos docs serves them locally at http://localhost:8000, and CI deploys them to dimensionalos.github.io. (#3645) by @leshy
  • New guide for cloud data uploads (dimos data upload/ls/pull/status/quota): codec selection with measured ratios, the full GlobalConfig table, and staging behavior; dimos login and dimos data added to the CLI reference. (#3865) by @spomichter
  • New recording guide for --record / --record-topics: what gets written and where, choosing streams, and inspecting or replaying the result with dimos mem summary and --replay-db. (#3737) by @spomichter
  • Hosted teleop docs rewritten around the operator journey (how it works, connect, drive, minimap nav, commands, E-STOP) with per-module config keys and the command allow-list; the page is renamed Remote Teleop, and key guidance now points to Dimensional console API keys (dimos_sk_...) with key-derived robot identity. (#2945, #2967, #4087) by @ruthwikdasyam, @spomichter
  • Navigation docs reworked into a workflow-driven set covering relocalization, with stale defaults fixed. (#2764) by @swstica
  • Web SDK tutorial (docs/usage/web_sdk.md). (#3648) by @paul-nechifor
  • CONTRIBUTING.md, AI_POLICY.md, and issue/PR templates for contributors and AI-assisted development. (#2347) by @swstica

👥 New Contributors

Full Changelog: v0.0.13.post1...v0.0.14