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
lcmeverywhere except macOS). The default session is pinned to localhost: it listens ontcp/127.0.0.1:0and scouts over loopback only. Reach off the machine with--robot-ip,ZENOH_CONNECT=tcp/host:7447,ZENOH_SCOUTING=1, orZENOH_INTERFACE=<iface>; a newzenoh_scout_addrmoves a session onto a private discovery group. Use--transport=lcmorDIMOS_TRANSPORT=lcmto keep the legacy path. (#3617) by @leshy - TF service retired: the lazily attached
self.tfservice,TFSpec,TFConfig,PubSubTF,LCMTF,ZenohTF,tf_backend(), andModuleConfig.tf_transportare removed. TF is now a normalTFMessagestream namedtf: declaretf: Out[TFMessage]to publish,tf: In[TFMessage]to look up viaself.tfbuffer, ortf: IO[TFMessage]for both, using the new bidirectionalIO[T]port kind. Outside modules useTF(stream). Wire format is unchanged, andtfis prefixed by namespaces like any other stream. (#3169) by @leshy memory2package renamed tomemory:dimos.memory2.*imports becomedimos.memory.*, andMemory2ReplayAdapterbecomesMemoryReplayAdapter(theTimedSensorReplayalias is unchanged). Pure rename, no behavior change. (#3413) by @spomichter~/.config/dimosis now a directory: the default--configfile is~/.config/dimos/configanddimos loginwrites~/.config/dimos/credentials. If a legacy flat file exists at~/.config/dimos,dimos runexits with the one-linemvcommand to migrate it and changes nothing on disk. (#3550) by @spomichter- Python package layout changed; update imports.
dimos.learningis nowdimos.imitation,dimos.core.testsis nowdimos.core.demos, agent test helpers moved todimos.agents.testing, and CLI code moved fromdimos.robot.cli/dimos.utils.clitodimos.cli(mapping tools todimos.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 underdimensional/. Usedimensional/dev:latestanddimensional/ros-dev:latestinstead ofghcr.io/dimensionalos/devandghcr.io/dimensionalos/ros-dev; the devcontainer andbin/devpoint at the new images. (#3724) by @Dreamsorcerer WrenchStampedis flat: the reading moved fromws.wrench.force/ws.wrench.torquetows.force/ws.torque, matchingPoseStampedandTwistStamped.WrenchandWrenchStampedare rebuilt on the generated LCM classes and gainlcm_encode/lcm_decode, so they can be used as stream types. (#3389) by @mustafab0
Manipulation & control
ManipulationModuleConfig.robotsis replaced by one preparedmodel. Planning, IK, collision, execution, and visualization use canonical model joint names (for exampleleft/joint1) and declared planning-group IDs such asleft_arm,right_arm, andboth_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 @TomCC7ManipulationModuleRPCs 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, andcancel, returning typedPlanResult/ExecutionResult/MoveResultvalues. The@skillmethods moved out ofManipulationModuleintoManipulationSkills. (#3447) by @TomCC7- Plan execution goes through a new
PlanExecutionManagerand always dispatches the complete stored plan in one coordinator RPC.execute(robot_name=...)andexecute_plan(plan, robot_name=...)lose the robot selector,get_trajectory_statusandRobotModelConfig.coordinator_task_nameare removed, andCoordinatorClient.execute_trajectory/cancel_trajectorydrop the task name and return typed results. EveryManipulationModuleblueprint must include aControlCoordinatorwith exactly oneJointTrajectoryTask(a second raisesValueError). Thexarm6-planner-onlyanddual-xarm6-plannerblueprints are removed; usexarm7-planner-coordinatorordual-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
GripperControlTaskowns 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 withstream_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_commandpositions now run through the joint trajectory task as one-point trajectories with per-joint velocity bounds (1 rad/s unless limits are configured). Blueprintcoordinator-servo-xarm6is renamed tocoordinator-trajectory-xarm6. (#3610) by @TomCC7 - xArm grasping blueprints renamed:
xarm-perceptionis nowxarm-graspandxarm-perception-agentis nowxarm-grasp-agent.xarm-perception-simandxarm-perception-sim-agentare unchanged. (#3873) by @mustafab0 XArmAdapterno longer drives the arm to a hardcoded joint pose onactivate()anddeactivate(). Pass an explicitinitial_positionsargument 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 theContourPolygons3D/GraphNodes3Dmessages. Use the ray-tracing + MLS planner stack instead (unitree-go2-nav-3d,alfred-mls-nav, G1 nav inunitree-g1-groot-wbc). (#3576) by @paul-nechifor - Ray tracing and the MLS planner take poses from TF instead of odometry streams.
RayTracingVoxelMapreplaces itsodometryinput withtf(clouds are registered by aworld_frame -> cloud frame_idlookup, tolerancetf_match_tolerance_s);MLSPlannerNativereplacesstart_pose/goal_posewith agoal: PointStampedinput plustf, plans frombase_frame(defaultbase_link), and its defaultworld_framechanges frommaptoodom;BasicPathFollowerdrops itsodometryinput;GoalRelayis replaced byStartRelayanddimos/navigation/tf_pose.pyis 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_idconfig is removed and odometry's child frame is nowsensor_frame_id(e.g.odom -> mid360_link). Point-LIO now builds from thedimos-module-pointliorepo. (#2700) by @leshy
Teleoperation
- Quest teleop stack renamed to WebXR, with no compatibility aliases. Blueprints
teleop-quest-*are nowteleop-webxr-*(e.g.teleop-webxr-xarm7,teleop-webxr-go2,teleop-webxr-piper,teleop-webxr-dual-openyam),learning-collect-quest-xarm7/-piperare nowlearning-collect-webxr-xarm7/-piper, the packagedimos.teleop.questis nowdimos.teleop.webxr, andQuestTeleopModuleis nowWebXRTeleopModule. (#3676) by @TomCC7 - Legacy hosted teleop package
dimos/teleop/quest_hosted/removed, includingHostedTeleopModule,HostedArmTeleopModule,HostedTwistTeleopModule,HostedTeleopRecorderand theteleop-hosted-go2/teleop-hosted-module-xarm7blueprints. Use the transport-based blueprints indimos/teleop/hosted/(teleop-hosted-go2-transport,teleop-hosted-xarm7) and the genericteleop-recorder. The broker API key is set throughtransports.broker.api_key/TRANSPORTS__BROKER__API_KEY; theTELEOP_API_KEYenv fallback is gone. (#3173) by @ruthwikdasyam - Hosted teleop default broker changed:
BrokerConfig.broker_urlnow defaults tohttps://api.dimensional.orginstead ofhttps://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 withTRANSPORTS__BROKER__ROBOT_ID. To keep using the old broker, setTRANSPORTS__BROKER__BROKER_URL=https://teleop.dimensionalos.com. (#4063) by @spomichter
Agents, perception & simulation
- Agent skill
relative_move(forward, left, degrees)replaced bymove_to(x, y, degrees, relative): world-frame coordinates by default,relative=Truefor 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
ObserveSkillcontainer (observe-skill,dimos/agents/skills/observe_skill.py) that subscribes tocolor_image. The per-robotobserve()skills onGO2Connectionand the drone connection module andtake_a_picture()on the camera module are removed; addObserveSkillto custom agentic blueprints instead. This also fixesobserveunder 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 underdimos/perception/experimental/, world belief underdimos/experimental/world_belief/, anddimos/perception/common/utils.pyis 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-simblueprint andUnityBridgeModuleare gone. Use--simulation=mujocoor--simulation=dimsiminstead. (#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 needsworld_backend="drake"andplanner_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
manipulationextra. The singularplan_to_poseRPC and the standalone manipulation client runner are removed.hold_position_when_idleis removed. (#2992, #3944, #3969) dimos piper can-activateis replaced bydimos hardware can setup/status. The per-side and mock OpenArm blueprints collapse intocoordinator-openarmandopenarm-planner-coordinator, andkeyboard-teleop-openarmis removed. (#3129, #3388)- RealSense
camera_nameis replaced byframe_id/frame_id_prefix, the camera no longer emits mount transforms, andRealSenseCamerais a native Rust module that needs a native build. (#3746) - Relocalization option
publish_loaded_mapis replaced byrepublish_loaded_mapandtf_interval. (#3890) - Stamped messages take
ts: float | None = None, sots=0.0is a real timestamp instead of meaning "stamp with now". (#3376) dimos map summarymoved todimos mem summary;dimos.utils.benchmarkingmoved todimos.control.benchmarking;lcmspyis a deprecated alias fordimos 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:
PlanarBaseDefinitionadds 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 preparedJointSpace. Abase_trajectorycoordinator 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_basegroups) withdimos 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-robotbase_poseand collision exclusions, and coordinated cross-robot planning groups (dimos run dual-xarm6-planner-coordinator).world_backend="roboplan"andplanner_name="roboplan"are now the manipulation defaults; Drake remains available withworld_backend="drake"andplanner_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
HeuristicGraspModuleprovides 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/GraspCandidateArraymessages and a GraspGenX provider that imports safely when the optional runtime is missing, wired into the grasping stack asxarm-grasp-graspgenxandxarm-grasp-graspgenx-agent.pick_objectwalks up tomax_grasp_attemptsranked 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
UNSUPPORTEDinstead of substituting a free-space path. RoboPlan is upgraded to 0.6.x andtime_optimalis the default Cartesian speed mode, withboundedstill available. (#3240, #3370) by @TomCC7 - Startup-selectable trajectory parametrization via
TrajectoryParametrizerSpec:roboplan_toppra(TOPP-RA, default withworld_backend=roboplan) orsimple_trapezoid(default with Drake), set withtrajectory_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
ManipulationModuleRPCs and the interactive client (update_obstacle, shape helpers such asupdate_box, andupdate_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:
PointCloudSelfFilterdrops the arm's own returns and emits a clear mask,RayTracingVoxelMapgains avoxel_clear_maskinput so the arm can erase its own ghost voxels, andManipulationModuletakes the map on a newvoxel_mapinput as a singleObstacleType.OCTREEobstacle (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
RoboPlanWorldinto a separateRoboPlanPlannerwith its ownRoboPlanPlannerConfig. (#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
manipulationextra gives an install instruction. (#2992) by @TomCC7 - Client-side
ArmSDK (dimos.manipulation.sdk) for scripting one arm fromdimos shellorDimos.connect():Arm.from_app(app),move_joints,move_pose,move_linear,home,move_to_preset, gripper open/close/position, withspeed_scale=/timeout=andMotionErroron failure. The obsolete singularplan_to_poseRPC 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 --forcediscards cached checkouts). A single immutableRobotModelhandles 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
JointStatestream per robot by declaring{hardware_id}_joints: Out[JointState](seecoordinator-dual-mock), and the remaining single-robot consumers now read those instead of the mergedcoordinator_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
cancelis exposed as a manipulation skill, andresetis restored as both a skill and an RPC so a module inFAULTcan 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 listprints the available interfaces or serials, and ateleop-webxr-openyamblueprint 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 spottakescmd_veland publishes all sensor data plus static TF, anddimos run spot-recordrecords it with lossless depth. The IP auto-detects (WiFi AP192.168.80.3, then Ethernet10.0.0.3) or can be forced with--spothighlevel.ip=.... Aspot_small_loopdataset with all depth and greyscale cameras and intrinsics is included. (#3058, #3048) by @jeff-hykin spot-replayblueprint 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-navrunning cuVSLAM + wheel odometry (DimSlam) into the MLS planner, plusalfred-mls-nav-lidarandalfred-keyboard-teleopblueprints. Needsuv 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 anOpenYamDamiaoAdapter. Blueprints:openyam-planner-coordinator,coordinator-openyam,keyboard-teleop-openyam,keyboard-teleop-openyam-planner. CAN setup is nowdimos hardware can setup can0anddimos 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 intocoordinator-openarmandopenarm-planner-coordinator(the latter uses the mock whole-body adapter when no CAN ports are given); the old OpenArm adapter, driver, CAN scripts, andkeyboard-teleop-openarmblueprints 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_gripperflag selecting the G1Z gripper or bare-flange model. Blueprintsa1z-planner-coordinator,coordinator-a1z, andkeyboard-teleop-a1zrun 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 userspacegs_usb; host bring-up isdimos a1z setupanddimos 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-navconnects to a Go2 running the go2webdimos-helperwith no robot IP needed (Zenoh auto-discovery), alongsidego2-zenoh-basic,go2-zenoh-htc, andgo2-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 toWIRELESS_CONTROLLERstick axes. Off by default. (#2859) by @bogwi
Web, cockpit & SDK
- New web stack:
--local-relayondimos runspawns a local Deno relay athttp://127.0.0.1:7780and adds aRelayBridgeModulethat 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-relayopens 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_imageasjpeg.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-dtopstill 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/Colsplits over panels such asVideo,Map2D,Teleop,ChatandStats(seeunitree-go2-cockpitandunitree-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 newunitree-go2-agentic-cockpitblueprint 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
VoiceInputmodule 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.jsand--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 withsession.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-urltakes the relay's HTTP URL (for examplehttp://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/--keyserve HTTPS and robot data on one port for access from other machines, with--relay-caon 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/CloudflareVideoTransportbind directly to blueprint streams and share one broker session per process, configured throughtransports.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, optionallatency_stamp),MapCompressModule(operator minimap) andHostedStatsModule(link latency/jitter, battery and robot state telemetry). (#2048, #2798) by @spomichter, @ruthwikdasyam - Hosted arm teleop:
teleop-hosted-xarm6/teleop-hosted-xarm7let 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.ArmCommandModulehandles EE-twist, gripper and E-STOP;EEFTwistTaskholds pose when idle and outputs gripper commands; the coordinator gains agripper_commandinput. (#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, withauto/enabled/disabledspeaker modes for Go2 Pro vs Go2 Air (-o go2audiobridgemodule.speaker=enabled). (#3268) by @ruthwikdasyam robot_typeinBrokerConfig, 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 withenable_ui_scaling, and the operator UI sets it with ateleop_scalecommand 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,TeleopIKTaskmoves from the legacy Pinocchio solver to Pink, and a sharedPoseTargetIKTaskcore backsCartesianIKTask,EEFTwistTaskandTeleopIKTaskwith bounded per-step velocity, joint-limit and tracking-error checks.TeleopIKTasksupports one or two hand bindings with optional gripper joints, andteleop-webxr-openarmdrives both OpenArm arms in one bimanual solve (fake hardware by default,--left-can-port/--right-can-portfor 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
HandTeleopModuletoggles each hand on a pinch (teleop-webxr-hand-xarm7). (#3394) by @ruthwikdasyam - PICO WebXR body tracking: a device-neutral
BodyTrackingSnapshotoutput, off by default withoptional/requiredsession modes, support for PICO's six-button controller packets, and ademo-pico-body-trackingAPI-test blueprint with a live monitor. (#3695) by @TomCC7
Navigation
- Navigation on the real G1 in the
unitree-g1-groot-wbcblueprint: MID-360 -> Point-LIO -> ray-tracing voxel map -> height costmap -> replanning A*, driven through the coordinator'stwist_command(no sport mode). The firmware-reportedmode_machineis 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 aDanLocalPlannerwith path smoothing and an optionallock_replandistance to stabilize MLS paths. Run withdimos --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
Pathwhose waypoints carry a commanded yaw decoupled from travel direction, and re-projects on replan without ramping from rest. Run it standalone withunitree-go2-holonomic-controlleror benchmark it withunitree-go2-holonomic-benchmark(RPP equivalents:unitree-go2-rpp-controller/unitree-go2-rpp-benchmark). Benchmarking utils moved fromdimos.utils.benchmarkingtodimos.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_minoccupied neighbors, clouds with no odometry within a configurable range are dropped instead of misregistered, the MLS planner ignores voxels more thanmax_overhead_mabove the sensor, and string pulling gives smoother paths.export DIMOS_NAV_RECORD=1turns 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 newCloudRelocalization,LidarWindowRelocalization,LocalMapRelocalization, andGo2Relocalizationmodules, adimos map viewcommand, and a tuning guide andtune.pytool for new lidars. Thepublish_loaded_mapoption is replaced byrepublish_loaded_mapandtf_interval. (#3890) by @leshy - cuVSLAM stereo visual odometry with loop closure (
dimos --viewer rerun run demo-dim-slam-realsensewith a RealSense D455 / D435i), and theDimSlamnative 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_finepublisheslocal_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 themid360_athens_stairsdataset. (#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_IPto set the sensor address) or a pcap (demo-mid360-pcap-replay). (#3852) by @aclauer dimos map global --denoiseremoves stray points (e.g. returns in the sky) from the reconstructed global map; adds themid360_athens_stairsPoint-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), withhabitat-teleop,habitat-raycaster, andhabitat-voxelas 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.jsexportingasync 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 adimsimCLI shipsdimsim dev,dimsim eval list, anddimsim eval <workflow>(with--headless). (#2187) by @Viswa4599 - Headless MuJoCo xArm grasping sim on
data/xarm_grasp_simwith a simulated wrist camera and owlv2 + yolo perception. It runs the same stack as the real arm: use thexarm-graspblueprint with--simulation mujoco. (#3760) by @mustafab0 - Scene cooking (experimental,
dimos.experimental.scene_cooking): an offline pipeline that turns a.blend,.glb, or.usdsource plus an optional sidecar into a scene package withscene.meta.json, Rerun/Babylon browser visuals, collision/raycast geometry, MuJoCo collision XML, and optional.mjbbinaries. (#2544) by @Nabla7
Perception
- RealSense is now a native Rust module:
RealSenseCameraruns all streams at 30 fps, publishes colored pointclouds, and drops the voxelizer that capped it at 5 fps.camera_nameis replaced by the standardframe_id/frame_id_prefix, so multiple cameras compose with.namespace("front"); the camera no longer emits mount transforms (useRealSenseMountTfin 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_kitchenandxarm6_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. ADanDetectorwrapper exposesembed()andlocalize()over recorded or live stores. (#3422, #3496) by @bogwi - Object scene registration: opt-in OWLv2 detection and EdgeTAM segmentation backends, a request-driven
scan_sceneAPI onObjectSceneRegistrationSpecthat returns pending objects with stable IDs and point clouds, and adetector_confidenceconfig key (default0.6). YOLOE/YOLO defaults are unchanged. (#3713, #3755) by @ruthwikdasyam, @mustafab0 dimos/perception/memory/tool_localize.pylocalizes a text-queried object (e.g."coke can") over a time window of a memory2 recording and writeslocalize.rrdfor the viewer; ships xArm6 + RealSense D435i example recordings. (#3279) by @leshydimos apriltag --3dgenerates 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 replayplays 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 ascamera_inforepublished at 1 Hz. A bare dataset name resolves like--replay. (#3738) by @spomichterdimos --record run <blueprint>records every published stream of any blueprint intorecordings/<run-id>/memory.dbwithout wiring a recorder module;--record-topicsselects streams by comma-separated globs. An experimental Rust engine (--record-engine rust, with--record-encoding-threads) adds--record mcap; bare--recordstays on Python SQLite. (#3710, #3924) by @spomichter, @TomCC7dimos datauploads recordings (or any file) to Dimensional cloud:dimos data upload [--since 1h] [--kind log --robot <id>] [--no-compress], plusls,pull,status, andquota. 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 lsopens an interactive TUI on a terminal (plain table when piped), shows upload times in local time, and adds an uploader column for org datasets;quotashows 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, binarydimos-memory-recorder) writes SQLite (lcm,jpeg,lz4+lcmcodecs) or Zstd-chunked MCAP with a configurableencoding_threadspool; both artifacts stay readable through the stableSqliteStore/McapStorePython APIs. (#3615) by @TomCC7 StreamTF: TF lookups backed by a recordedtfstream (StreamTF.from_store(store)), answering the same queries as live TF;dimos mapuses it to build global maps from sensor-frame recordings. (#2707) by @leshyunitree-g1-recordblueprint records Point-LIO, RealSense, and TF from the G1, with a dynamic torso to base-link transform from joint states; adds ag1_sf_officerecording. (#3527) by @aclauer- memory2 CLI:
dimos mem summary(moved fromdimos map summary) with stream sizes and shared progress bars,dimos mem rerunresolves datasets by bare name and takes--rootto nest streams under an entity path, and Go2 DDS.mcapdecoding covers more message types. Go2--replayresolvesgo2_lidar/go2_odomstreams with fallback tolidar/odom. (#2730, #2521) by @leshy - New
sf_office_stairsrecording (Mid-360 Point-LIO + D455 stereo, two floors, start and stop at the same location) for smoke tests, and an updatedchina_officerecording. (#3349, #2702) by @jeff-hykin
Evals
- New
dimos/evalspackage with two case types:PassiveEval(scored against a frozen memory2 recording over any replay window) andInteractiveEval(live sim or robot, scored by sampling the live recorder store everyinterval_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/openevalsinputs/reference_outputsformat. Runnable viadimos evals run <suite>,EvalModuleMCP skills, and pytest; aMoondreamChatadapter runs suites locally without API keys. Each run writesresults.jsonl,summary.json, and per-case transcripts to~/.local/state/dimos/evals/run-*/. (#3411) by @spomichter - Eval agents and environments are configurable: a single
EvalCasetype takes an environment (dataset, sim, or image) and the agent is chosen at run time withdimos evals run <suite> --agent <agent> --set <key=value>. Bundled agents includedimos.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"]'), anddimos.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>anddimos evals vqa run <dataset>. Image-only families (presence, horizontal detection, object count) take answers from Moondream detections; recordings withcamera_info,tf, and LiDAR (pointlio_lidarorlidar) 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-evalfor automated navigation tests:runexecutes the cases on the datasets,ingestadds test cases for a new dataset automatically, andpick-caseadds 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>)indimos.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 newmcp_timeoutconfig 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.5orROBOT0_GO2CONNECTION__IP. Newunitree-go2-multiandunitree-go2-multi-teleopblueprints (ROBOT_IPS=... dimos run unitree-go2-multi-teleop; with--simulationeach 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-sizeor--robot0/go2connection.ip=...for namespaces, with "did you mean" suggestions for unknown options. Parsing is centralized inBlueprintConfigParser. (#3305) by @paul-nechifor - External blueprint registration: packages expose blueprints or modules through the
dimos.blueprintsentry-point group and users run them by namespaced name (dimos run my-robot-stack.go2, combinable with built-ins);dimos listshows them. (#2517) by @TomCC7 dimos shell: an IPython shell that attaches to a running coordinator (foreground, daemon, orblueprint.build().loop()) to discover modules and call their RPCs, withguide(),modules(),rpcs(), anddescribe()helpers, tab completion of RPC names, andapp.find_module_by_spec(MySpec)to find a module by its Spec. NoMcpServerrequired. (#3236, #4009) by @TomCC7dimos spy: a live table of every topic across LCM and Zenoh with per-topic rate, bandwidth, size, and liveness (dimos spy --transport zenohto filter).lcmspyremains as a deprecated alias fordimos spy --transport lcm. (#2735) by @leshydimos login,dimos logout, anddimos 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 with0600permissions.DIMOS_API_KEYoverrides the stored key;dimos_cloud_urldefaults tohttps://api.dimensional.org. (#3522, #3549, #3730) by @spomichterdimos cache cleanremoves all regenerable caches, which now live under one platformCACHE_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--yesfor non-interactive use. (#3178) by @TomCC7CompressedImageis 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 toImagewith timestamp and frame_id preserved, andto_rerun()as an encoded image. Useformat="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, withget_latest(),.at(),.tolerance(), and.within()lookups; also addsIOports and a toggle to disable the Go2base_linkTF 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 bakelinks several Rust native modules into one host binary (dimos bake ray-tracing mls-planner -o <host>), with--list,--dry-run,--suppressto keep a topic inside the host,--remap,--target, and--emit-config. Newgo2-zenoh-nav-bakedandgo2-zenoh-nav-remoteblueprints use it;zenoh_gossipnow defaults to on. (#3490) by @aclauerControlCoordinatortasks are declarative: each task declares its input streams and RPC-invokable methods in a_registry.pycard, and the coordinator builds its route table and command allowlist from the registry, so adding a task no longer means editing the coordinator.task_invokeonly dispatches methods a task lists inTASK_EXPOSES. Twist, cartesian, velocity, teleop, servo, and G1 GR00T tasks are migrated. (#2959) by @mustafab0ControlCoordinatoraccepts arbitrary input streams: subclass it and declare extra inputs (e.g.wrench: In[WrenchStamped]) instead of the five hardcoded ones;TaskConfig.stream_bindmaps a task input to a port per instance, and a newdirectrouting rule delivers unconditionally. (#3110) by @mustafab0PointCloud2supports per-point fields beyondx,y,z,intensity, includingoffset_time,tag,line, andtimestamp. (#3103) by @jeff-hykindimos graph <blueprint> --output <file>.svgrenders 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_axesoption), andgo2-zenoh-navtakes 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 --inexactnow installs everything the shipped manipulation blueprints need: themanipulationextra composesplanning,base,sim, andcpu, and new narrowercontrol(coordinators, arm adapters, keyboard/Cartesian control, xArm SDK) andplanning(Drake, RoboPlan, visualization) extras are available for smaller installs. EdgeTAM andtimmmoved frommisctoperception, andpython-socketiois declared inweb. (#4066) by @TomCC7- Fresh clones no longer download the large
data/.lfs/*.tar.gzarchives (lfs.fetchexcludein.lfsconfig); they arrive as pointer files and are pulled on demand, while other LFS assets still pull normally. (#3147) by @leshy test_*.pyfiles are no longer shipped in the published package. (#2706) by @paul-nechifor
🐛 Bug Fixes
dimos mem rerunprojects the camera image into 3D: the recordedcamera_infois logged as a Pinhole on its image entity, parented into the tf frame graph, so the camera follows the robot; Go2camera_infois 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_lcmtwist 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_idleis removed. (#3969) by @TomCC7 KeyboardTeleoppublishes only while a key is held (publish_only_when_activedefaults toTrue), so an idle keyboard window no longer fights Rerun or command-center teleop oncmd_veland freezes the Go2 (dimos run unitree-go2 keyboard-teleop). (#4119) by @KrishnaH96unitree-g1-simnow moves:unitree_g1_basic_simgets aMovementManagerso 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_transporttimeout. (#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/shmsegment 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; raisesShmNotReadyErroron timeout. (#3672) by @mustafab0 - Lidar messages are no longer dropped at startup: message types can define an
lcm_warmuphook that runs at subscribe time, andPointCloud2uses 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-wbcfailing to deployRerunBridgeModule. (#4141) by @christiefhyang - Partial dotted CLI overrides merge into nested module config instead of replacing blueprint defaults, and
dimos run <blueprint> --helpno 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.envcopied fromdefault.envno longer fails withUnknown 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
NoSolutionFoundfor one seed, so reachable grasp poses no longer reportNO_SOLUTION. (#3674) by @mustafab0 ManipulationModuleconsumes 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_linkhas a parent and RealSense output resolves intoworldusing the hand-eye calibration. (#3871) by @mustafab0 - Viser leaves
EXECUTINGwhen 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
ObjectSceneRegistrationcaptures the camera transform before detector inference, so slow (CPU) inference no longer outlives the TF buffer and drops valid 3D detections;ObjectDBnow 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-installedpycuda, 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-instructtoqwen-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 inspectreports 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_DIRlike every other recorder, instead of a hardcodedSTATE_DIR / "recordings". (#3546) by @spomichter - Recorder tags each observation with a
reception_tsingress timestamp (for command-link latency) and no longer logs a "no pose" warning per message on poseless streams such ascmd_vel_stamped. (#2927) by @ruthwikdasyam - Go2 recorders (
Go2Memory,Go2Mid360Recorder) record thecamera_infostream so recordings are self-contained. (#3748) by @ruthwikdasyam - Simulation camera images, TF, and
camera_infoare stamped at render time and paced on the monotonic clock, removing a 4.5 to 101.7 ms timestamp skew. (#3690) by @mustafab0 demo-camerashows the webcam image in Rerun again:Webcamreports 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_timetimeline was removed. (#2810) by @Nabla7 - Go2
stop_movementsends its zero twist on the connection's event loop thread. (#2977) by @ruthwikdasyam unitree-go2-multiandunitree-go2-multi-teleopfail immediately with a configuration error whenROBOT_IPS/--robot-ipsis empty, instead ofNo modules deployed. (#4140) by @christiefhyangcv2.imshowno longer hangs at 100% CPU afterDimos.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 @KrishnaH96humanclidisplays tool-call messages again (it assumed string message content) and prints a notice when a message cannot be rendered. (#4015) by @paul-nechifordtopreports memory on macOS by falling back to RSS when PSS is unavailable. (#3054) by @jmnie- Python 3.10: CLI imports work again (
Selfimported fromtyping_extensions). (#3932) by @mustafab0 - The Rust LCM transport honors
LCM_DEFAULT_URL. (#3740) by @jeff-hykin --build-nativetriggers a rebuild again, and native module build output streams to the log as it happens instead of appearing stuck. (#3323, #3258) by @aclauerget_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 @TomCC7dimos data pullno longer fails on files whose name already ends in the codec suffix (e.g.*.lz4):content_encodingis only stamped when compression actually ran. (#3882) by @spomichter- Packaging:
edgetam-dimosbumped 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 syncfailed on older uv because it could not parse the cooldown opt-outs inpyproject.toml. (#3941) by @omarespejel dimosCLI starts withoutonnxruntimeinstalled; 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 missingmujoco_playgroundpoints touv sync --extra sim --inexact. (#3577, #3654) by @paul-nechifor, @christiefhyang dimos topic sendworks again for all message types. (#2760) by @paul-nechifor- Conflicting OpenCV packages resolved: only
opencv-contrib-pythonis installed and plainopencv-pythonis 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:
dimossetsOMP_WAIT_POLICY=PASSIVEandKMP_BLOCKTIME=0by default (user environment overrides win), stopping OpenMP spin-wait in Open3D workers.dimos --replay run unitree-go2dropped from about 100% to 16% CPU and 33 W to 12 W in the PR's measurement. (#3190) by @bogwi - Message construction in
dimos/msgsis 5x to 48x faster after droppingplummultiple dispatch from__init__(e.g.Pose()48.9 µs to 1.0 µs; a 207-posePath11.7 ms to 0.76 ms). Stamped messages now takets: float | None = None, sots=0.0is a real timestamp instead of meaning "stamp with now". (#3376) by @leshy LineSegments3Dencoding, 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
imageprocdependency 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.organd made agent-readable:llms.txt, raw Markdown by appending.mdto 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 docsserves them locally athttp://localhost:8000, and CI deploys them to dimensionalos.github.io. (#3645) by @leshy - New guide for cloud data uploads (
dimos dataupload/ls/pull/status/quota): codec selection with measured ratios, the fullGlobalConfigtable, and staging behavior;dimos loginanddimos dataadded 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 withdimos mem summaryand--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
- @jhengyilin made their first contribution in #2665
- @Viswa4599 made their first contribution in #2187
- @xiaoyaoqilan made their first contribution in #3060
- @Danny024 made their first contribution in #2546
- @mc856 made their first contribution in #3210
- @hvent90 made their first contribution in #3689
- @jmnie made their first contribution in #3054
- @poorwym made their first contribution in #3693
- @omarespejel made their first contribution in #3941
Full Changelog: v0.0.13.post1...v0.0.14
