From 455763be6a1915bbee6857d2ebf220aa379c9bcd Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:19:57 +0800 Subject: [PATCH 01/15] feat(hackathon): add __init__.py --- dimos/robot/unitree/go2/blueprints/hackathon/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/__init__.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/__init__.py b/dimos/robot/unitree/go2/blueprints/hackathon/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 3c8801d248281d3e7e8ece273d481d3a934b5efe Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:19:59 +0800 Subject: [PATCH 02/15] feat(hackathon): add blueprint.py --- .../go2/blueprints/hackathon/blueprint.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/blueprint.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/blueprint.py b/dimos/robot/unitree/go2/blueprints/hackathon/blueprint.py new file mode 100644 index 0000000000..a69e8457b3 --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/blueprint.py @@ -0,0 +1,50 @@ +"""unitree-go2-hackathon blueprint. + +Build chain (avoids SecurityModule which requires CUDA/EdgeTAM): + unitree_go2_basic → unitree_go2 → +SpatialMemory +PerceiveLoopSkill + (SecurityModule intentionally excluded) +Then adds: McpServer + hackathon skill containers. +""" + +from dimos.agents.mcp.mcp_client import McpClient +from dimos.agents.mcp.mcp_server import McpServer +from dimos.agents.skills.navigation import NavigationSkillContainer +from dimos.agents.skills.speak_skill import SpeakSkill +from dimos.agents.web_human_input import WebInput +from dimos.core.coordination.blueprints import autoconnect +from dimos.perception.perceive_loop_skill import PerceiveLoopSkill +from dimos.perception.spatial_perception import SpatialMemory +from dimos.robot.unitree.go2.blueprints.smart.unitree_go2 import unitree_go2 +from dimos.robot.unitree.go2.connection import GO2Connection +from dimos.robot.unitree.unitree_skill_container import UnitreeSkillContainer +from dimos.robot.unitree.go2.blueprints.hackathon.dog_mode import DogModeModule +from dimos.robot.unitree.go2.blueprints.hackathon.find import FindSkillContainer +from dimos.robot.unitree.go2.blueprints.hackathon.perception_loop import PerceptionLoopModule +from dimos.robot.unitree.go2.blueprints.hackathon.smart_follow import SmartFollowSkillContainer + +# Spatial layer without SecurityModule (no CUDA required) +_unitree_go2_spatial_no_security = autoconnect( + unitree_go2, + SpatialMemory.blueprint(), + PerceiveLoopSkill.blueprint(), +).global_config(n_workers=8) + +_hackathon_agentic = autoconnect( + NavigationSkillContainer.blueprint(), + PerceptionLoopModule.blueprint(camera_info=GO2Connection.camera_info_static), + SmartFollowSkillContainer.blueprint(camera_info=GO2Connection.camera_info_static), + FindSkillContainer.blueprint(), + DogModeModule.blueprint(camera_info=GO2Connection.camera_info_static), + UnitreeSkillContainer.blueprint(), + WebInput.blueprint(), + SpeakSkill.blueprint(), +) + +unitree_go2_hackathon = autoconnect( + _unitree_go2_spatial_no_security, + McpServer.blueprint(), + McpClient.blueprint(), + _hackathon_agentic, +) + +__all__ = ["unitree_go2_hackathon"] From 4926799e823c49434032c709608b89e23c28ba9a Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:01 +0800 Subject: [PATCH 03/15] feat(hackathon): add frame_writer.py --- .../go2/blueprints/hackathon/frame_writer.py | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/frame_writer.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/frame_writer.py b/dimos/robot/unitree/go2/blueprints/hackathon/frame_writer.py new file mode 100644 index 0000000000..4c43878aa6 --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/frame_writer.py @@ -0,0 +1,97 @@ +"""Shared annotated frame writer for dashboard visualization. + +Modules call write_annotated_frame() to push an OpenCV-annotated JPEG to +/tmp/go2_hackathon_frame.jpg, which the dashboard MJPEG stream reads. +""" + +from __future__ import annotations + +import json +import time +from pathlib import Path +from typing import Any + +import cv2 +import numpy as np + +FRAME_PATH = Path("/tmp/go2_hackathon_frame.jpg") +STATE_PATH = Path("/tmp/go2_hackathon_state.json") + +# Threat level colors: BGR +_COLORS = { + "aggressive": (0, 0, 220), # red + "cautious": (0, 160, 255), # orange + "curious": (0, 200, 80), # green + "tracking": (255, 200, 0), # cyan + "approach": (255, 80, 200), # purple + "unknown": (180, 180, 180), # grey +} + +_FONT = cv2.FONT_HERSHEY_SIMPLEX +_FONT_SCALE = 0.5 +_THICKNESS = 1 + + +def _threat_label(threat: float | None) -> tuple[str, tuple]: + if threat is None: + return "tracking", _COLORS["tracking"] + if threat >= 0.7: + return f"THREAT {threat:.0%}", _COLORS["aggressive"] + if threat >= 0.4: + return f"cautious {threat:.0%}", _COLORS["cautious"] + return f"curious {threat:.0%}", _COLORS["curious"] + + +def write_annotated_frame( + image_bgr: np.ndarray, + detections: list[dict], # [{"bbox":(x1,y1,x2,y2), "track_id":int, "threat":float|None, "label":str}] + overlay_text: str = "", + quality: int = 75, +) -> None: + """Draw bboxes + labels on frame and write to shared JPEG path.""" + frame = image_bgr.copy() + h, w = frame.shape[:2] + + for det in detections: + x1, y1, x2, y2 = [int(v) for v in det["bbox"]] + tid = det.get("track_id", -1) + threat = det.get("threat") + label_text, color = _threat_label(threat) + custom = det.get("label") + if custom: + label_text = custom + + cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2) + + tag = f"#{tid} {label_text}" + (tw, th), _ = cv2.getTextSize(tag, _FONT, _FONT_SCALE, _THICKNESS) + ty = max(y1 - 6, th + 4) + cv2.rectangle(frame, (x1, ty - th - 4), (x1 + tw + 4, ty + 2), color, -1) + cv2.putText(frame, tag, (x1 + 2, ty), _FONT, _FONT_SCALE, (255, 255, 255), _THICKNESS, cv2.LINE_AA) + + # Overlay text (state label) in top-left + if overlay_text: + lines = overlay_text.split("\n") + y0 = 22 + for line in lines: + (lw, lh), _ = cv2.getTextSize(line, _FONT, 0.6, 2) + cv2.rectangle(frame, (8, y0 - lh - 4), (14 + lw, y0 + 4), (30, 30, 30), -1) + cv2.putText(frame, line, (10, y0), _FONT, 0.6, (0, 255, 180), 2, cv2.LINE_AA) + y0 += lh + 10 + + ok, buf = cv2.imencode(".jpg", frame, [cv2.IMWRITE_JPEG_QUALITY, quality]) + if ok: + FRAME_PATH.write_bytes(buf.tobytes()) + + +def write_state(state: dict[str, Any]) -> None: + """Write current module state as JSON for dashboard polling.""" + state["ts"] = time.time() + STATE_PATH.write_text(json.dumps(state)) + + +def read_state() -> dict[str, Any]: + try: + return json.loads(STATE_PATH.read_text()) + except Exception: + return {} From 0ea99be97c76dfcec966cb3ad33505af1adb746d Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:11 +0800 Subject: [PATCH 04/15] feat(hackathon): add perception_loop.py --- .../blueprints/hackathon/perception_loop.py | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py b/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py new file mode 100644 index 0000000000..f9cd8acbec --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py @@ -0,0 +1,325 @@ +"""PerceptionLoopModule — always-on L2 shared perception layer. + +Runs YOLO at ~15fps. Maintains a rolling SceneBuffer (2s TTL) with MobileCLIP +embeddings. Exposes a process-singleton so smart_follow / find / dog_mode all +read from *one* YOLO pass instead of each running their own detector. + +Cache hierarchy role: + HDD Claude via MCP — novel situations only + SSD dimOS SQLite map — spatial memory + RAM BehaviorFSMs — smart_follow, dog_mode recovery + L2 This module — always-on YOLO+MobileCLIP, SceneBuffer <50ms + L1 VisualServoing2D — servo math <1ms + +Module-level API (used by smart_follow / find / dog_mode): + get_shared_detections() → (list[Detection], timestamp_float) + get_shared_buffer() → dict[track_id, TrackedObject] + set_active_mode(str|None) — active mode suppresses idle frame-writing +""" + +from __future__ import annotations + +import time +from dataclasses import dataclass, field +from threading import Event, RLock, Thread +from typing import Any + +import numpy as np +from reactivex.disposable import Disposable + +from dimos.agents.annotation import skill +from dimos.constants import DEFAULT_THREAD_JOIN_TIMEOUT +from dimos.core.core import rpc +from dimos.core.module import Module, ModuleConfig +from dimos.core.stream import In +from dimos.models.embedding.mobileclip import MobileCLIPModel +from dimos.msgs.sensor_msgs.CameraInfo import CameraInfo +from dimos.msgs.sensor_msgs.Image import Image +from dimos.perception.detection.detectors.yolo import Yolo2DDetector +from dimos.utils.logging_config import setup_logger +from dimos.robot.unitree.go2.blueprints.hackathon.frame_writer import write_annotated_frame, write_state + +logger = setup_logger() + +_BUFFER_TTL = 2.0 # seconds before a track expires +_CLIP_INTERVAL = 5 # MobileCLIP every N frames (~3fps on CPU) +_DET_FRESHNESS = 0.12 # shared detection max age in seconds +_LOOP_HZ = 15.0 +_CLIP_THRESHOLD = 0.20 + +# ── Process-singleton shared state ─────────────────────────────────────────── +_shared_lock = RLock() +_shared_detections: list = [] +_shared_det_ts: float = 0.0 +_shared_buffer: dict = {} # track_id → TrackedObject +_active_mode: str | None = None # "follow" | "find" | "dog" | None + + +def get_shared_detections() -> tuple[list, float]: + """Return (detections, monotonic_ts) from the shared YOLO pass.""" + with _shared_lock: + return list(_shared_detections), _shared_det_ts + + +def get_shared_buffer() -> dict: + """Return a snapshot of the current SceneBuffer.""" + with _shared_lock: + return dict(_shared_buffer) + + +def set_active_mode(mode: str | None) -> None: + """Signal that a behaviour module is active (suppresses idle frame-writing).""" + global _active_mode + with _shared_lock: + _active_mode = mode + + +def shared_detections_fresh() -> bool: + """True if the shared YOLO pass ran within the freshness window.""" + with _shared_lock: + return (time.monotonic() - _shared_det_ts) <= _DET_FRESHNESS + + +# ───────────────────────────────────────────────────────────────────────────── + + +@dataclass +class TrackedObject: + track_id: int + name: str + bbox: tuple + confidence: float + last_seen: float + clip_emb: Any | None = field(default=None, repr=False) # Embedding | None + + +class Config(ModuleConfig): + camera_info: CameraInfo + + +class PerceptionLoopModule(Module): + """Always-on L2 perception: YOLO+MobileCLIP, shared SceneBuffer, query_scene skill.""" + + config: Config + color_image: In[Image] + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + self._detector = Yolo2DDetector() + self._clip = MobileCLIPModel() + self._lock = RLock() + self._latest_image: Image | None = None + self._last_fast_write: float = 0.0 # gate for _on_image dashboard writes + self._should_stop = Event() + self._thread: Thread | None = None + + @rpc + def start(self) -> None: + super().start() + self.register_disposable(Disposable(self.color_image.subscribe(self._on_image))) + self._should_stop.clear() + self._thread = Thread(target=self._perception_loop, daemon=True, name="PerceptionLoop") + self._thread.start() + logger.info("PerceptionLoopModule started.") + + @rpc + def stop(self) -> None: + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + super().stop() + + def _on_image(self, image: Image) -> None: + with self._lock: + self._latest_image = image + + # ── Shared-CLIP RPCs (so SmartFollow/Find don't each load their own) ── + + @rpc + def embed_text(self, text: str) -> list[float]: + """Embed a text query using the SHARED MobileCLIP (no duplicate model loads). + Returns the embedding as a plain list[float] (RPC-serializable).""" + emb = self._clip.embed_text(text) + return emb.vector.detach().cpu().float().tolist() + + @rpc + def match_text(self, text: str, class_filter: str | None = None) -> list[dict]: + """Score tracked objects against `text` using the shared CLIP. + Returns [{track_id, bbox, name, score}] sorted by score desc. + Uses cached track embeddings — zero extra inference per frame. + Optional class_filter narrows to a YOLO class (e.g. 'person').""" + text_emb = self._clip.embed_text(text) + now = time.monotonic() + out = [] + with _shared_lock: + for t in _shared_buffer.values(): + if now - t.last_seen > _BUFFER_TTL: + continue + if class_filter and t.name.lower() != class_filter.lower(): + continue + if t.clip_emb is None: + continue + try: + score = float(text_emb @ t.clip_emb) + except Exception: + continue + out.append({ + "track_id": int(t.track_id), + "bbox": [float(v) for v in t.bbox], + "name": t.name, + "score": score, + }) + out.sort(key=lambda m: m["score"], reverse=True) + return out + + @rpc + def current_detections(self, class_filter: str | None = None) -> list[dict]: + """Snapshot of the live YOLO detections (fresh-window only). + Returns [{track_id, bbox, name, confidence}].""" + with _shared_lock: + dets = list(_shared_detections) + ts = _shared_det_ts + if (time.monotonic() - ts) > _DET_FRESHNESS: + return [] + out = [] + for d in dets: + name = getattr(d, "name", "") + if class_filter and name.lower() != class_filter.lower(): + continue + bbox = getattr(d, "bbox", None) + if bbox is None: + continue + out.append({ + "track_id": int(getattr(d, "track_id", -1) or -1), + "bbox": [float(v) for v in bbox], + "name": name, + "confidence": float(getattr(d, "confidence", 0.0) or 0.0), + }) + return out + + # ── Skill ───────────────────────────────────────────────────────────────── + + @skill + def query_scene(self, description: str = "") -> str: + """Ask what the robot's camera currently sees — no new inference triggered. + + Reads directly from the live SceneBuffer (updated at ~15fps). Use this + before making follow/find decisions — it's cheap and instant. + + Args: + description: Optional text to filter by similarity (e.g. "person with + red shirt", "dog", "chair"). Leave empty to list everything. + """ + now = time.monotonic() + with _shared_lock: + tracks = [t for t in _shared_buffer.values() if now - t.last_seen <= _BUFFER_TTL] + + if not tracks: + return "Nothing detected in current frame." + + if description: + text_emb = self._clip.embed_text(description) + scored = [] + for t in tracks: + if t.clip_emb is not None: + score = float(text_emb @ t.clip_emb) + scored.append((score, t)) + scored.sort(key=lambda x: x[0], reverse=True) + matches = [(s, t) for s, t in scored if s >= _CLIP_THRESHOLD] + if not matches: + names = ", ".join(sorted({t.name for t in tracks})) + return f"No match for '{description}'. Visible: {names}." + lines = [f"Matches for '{description}':"] + for score, t in matches[:5]: + x1, _, x2, _ = t.bbox + cx = (x1 + x2) / 2 + side = "left" if cx < 0.4 else "right" if cx > 0.6 else "center" + lines.append(f" #{t.track_id} {t.name} ({score:.0%}) — {side} of frame") + return "\n".join(lines) + + by_class: dict[str, list] = {} + for t in tracks: + by_class.setdefault(t.name, []).append(t) + lines = [f"{len(tracks)} object(s) visible:"] + for name, objs in sorted(by_class.items()): + ids = ", ".join(f"#{o.track_id}" for o in objs) + lines.append(f" {name} × {len(objs)} [{ids}]") + return "\n".join(lines) + + # ── Main loop ───────────────────────────────────────────────────────────── + + def _perception_loop(self) -> None: + global _shared_detections, _shared_det_ts, _shared_buffer + + frame_count = 0 + period = 1.0 / _LOOP_HZ + next_t = time.monotonic() + + while not self._should_stop.is_set(): + next_t += period + frame_count += 1 + now = time.monotonic() + + with self._lock: + image = self._latest_image + + if image is None: + time.sleep(period) + continue + + # YOLO every frame + result = self._detector.process_image(image) + valid = [d for d in result.detections if d.is_valid()] + + # MobileCLIP every N frames + embs: list = [None] * len(valid) + if valid and frame_count % _CLIP_INTERVAL == 0: + try: + crops = [d.cropped_image() for d in valid] + raw = self._clip.embed(*crops) if len(crops) > 1 else [self._clip.embed(crops[0])] + embs = raw + except Exception: + pass + + # Write into shared singleton + with _shared_lock: + _shared_detections = valid + _shared_det_ts = now + for det, emb in zip(valid, embs): + tid = det.track_id + existing = _shared_buffer.get(tid) + _shared_buffer[tid] = TrackedObject( + track_id = tid, + name = getattr(det, "name", "object"), + bbox = det.bbox, + confidence = float(getattr(det, "confidence", 0.0)), + last_seen = now, + clip_emb = emb if emb is not None else (existing.clip_emb if existing else None), + ) + _shared_buffer = {k: v for k, v in _shared_buffer.items() + if now - v.last_seen <= _BUFFER_TTL} + + # Frame annotation — every loop iteration (was throttled to every + # 3rd, which capped the dashboard camera at ~5fps; YOLO is the real + # gate so writing every frame just keeps up with the loop). + if True: + with _shared_lock: + mode = _active_mode + if mode is None: + try: + snap = [t for t in _shared_buffer.values() if now - t.last_seen <= _BUFFER_TTL] + det_list = [{"bbox": t.bbox, "track_id": t.track_id, "label": t.name} for t in snap] + write_annotated_frame(image.to_opencv(), det_list, overlay_text="PERCEPTION\nACTIVE") + write_state({ + "mode": "perception", + "state": "ACTIVE", + "objects": len(det_list), + "classes": list({t.name for t in snap}), + }) + except Exception: + pass + + sleep_dur = next_t - time.monotonic() + if sleep_dur > 0: + time.sleep(sleep_dur) From 1d5c72a138e93324860dfb3885976cb51e6d4a12 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:14 +0800 Subject: [PATCH 05/15] feat(hackathon): add smart_follow.py --- .../go2/blueprints/hackathon/smart_follow.py | 421 ++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py b/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py new file mode 100644 index 0000000000..f10859c3d7 --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py @@ -0,0 +1,421 @@ +"""SmartFollowSkillContainer — multi-target YOLO+MobileCLIP person/object follower. + +L2: reads shared YOLO detections from PerceptionLoopModule (zero duplicate inference). + Falls back to its own Yolo2DDetector if the shared pass is stale. +RAM: active_track_ids set, SpinSearch recovery, nearest-target servo. +L1: VisualServoing2D control loop. + +Design: +- YOLO servo uses shared detections (already running in PerceptionLoopModule) +- CLIP re-scoring reads embeddings from SceneBuffer — no redundant CLIP calls +- Multi-target: servo toward nearest active match (largest bbox = closest) +- Class-only fast path: if query is a YOLO class name, skip CLIP entirely +""" + +from __future__ import annotations + +import time +from threading import Event, RLock, Thread +from typing import Any + +from reactivex.disposable import Disposable + +from dimos.agents.annotation import skill +from dimos.constants import DEFAULT_THREAD_JOIN_TIMEOUT +from dimos.core.core import rpc +from dimos.core.module import Module, ModuleConfig +from dimos.core.stream import In, Out +from dimos.robot.unitree.go2.blueprints.hackathon.perception_loop import PerceptionLoopModule +from dimos.msgs.geometry_msgs.Twist import Twist +from dimos.msgs.geometry_msgs.Vector3 import Vector3 +from dimos.msgs.sensor_msgs.CameraInfo import CameraInfo +from dimos.msgs.sensor_msgs.Image import Image +from dimos.navigation.visual_servoing.visual_servoing_2d import VisualServoing2D +from dimos.utils.logging_config import setup_logger +from dimos.robot.unitree.go2.blueprints.hackathon.frame_writer import write_annotated_frame, write_state +from dimos.robot.unitree.go2.blueprints.hackathon.perception_loop import get_shared_buffer, set_active_mode + +logger = setup_logger() + +_YOLO_CLASSES = { + "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", + "boat", "cat", "dog", "horse", "sheep", "cow", "bear", "zebra", "giraffe", + "backpack", "umbrella", "handbag", "tie", "suitcase", "sports ball", "bottle", + "cup", "chair", "couch", "potted plant", "bed", "tv", "laptop", "phone", + "keyboard", "mouse", "remote", "microwave", "oven", "sink", "refrigerator", "book", +} + +_MATCH_THRESHOLD = 0.22 +_REACQUIRE_THRESHOLD = 0.20 + + +class Config(ModuleConfig): + camera_info: CameraInfo + + +class _Det: + """Lightweight wrapper around dict-returned detections from PerceptionLoop. + Exposes the .track_id / .bbox / .name / .bbox_2d_volume() API the rest of + this module already expects, so we can swap detector source without + rewriting the follow loop.""" + __slots__ = ("track_id", "bbox", "name", "confidence") + def __init__(self, m: dict) -> None: + self.track_id = m.get("track_id", -1) + self.bbox = tuple(m["bbox"]) + self.name = m.get("name", "") + self.confidence = m.get("score", m.get("confidence", 0.0)) + def bbox_2d_volume(self) -> float: + x1, y1, x2, y2 = self.bbox + return max(0.0, x2 - x1) * max(0.0, y2 - y1) + def is_valid(self) -> bool: + return True + + +class SmartFollowSkillContainer(Module): + """Multi-target person/object follower using shared L2 perception.""" + + config: Config + color_image: In[Image] + cmd_vel: Out[Twist] + # Shared inference: ONE MobileCLIP + ONE YOLO lives in PerceptionLoop. + # We don't load our own; all detection + text matching is RPC'd. + _perception: PerceptionLoopModule + + _frequency: float = 15.0 + _clip_interval: int = 5 # re-score from SceneBuffer every N frames + _max_lost_frames: int = 20 + _spin_speed: float = 0.45 + _spin_timeout_s: float = 12.0 + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + # No more own MobileCLIP / Yolo2DDetector — both come from PerceptionLoop + # via RPC. Saves ~1.8 GB of duplicated model weights per skill module. + self._visual_servo = VisualServoing2D(self.config.camera_info) + + self._latest_image: Image | None = None + self._active_ids: set[int] = set() + self._query: str = "" + self._text_emb = None + self._class_mode: bool = False + self._class_name: str = "" + + self._thread: Thread | None = None + self._should_stop = Event() + self._lock = RLock() + + @rpc + def start(self) -> None: + super().start() + # CLIP loads lazily on first embed (see _clip cached model) — eager + # start() here caused concurrent multi-process model loads to stall. + self.register_disposable(Disposable(self.color_image.subscribe(self._on_image))) + + @rpc + def stop(self) -> None: + self._should_stop.set() + set_active_mode(None) + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + super().stop() + + def _on_image(self, image: Image) -> None: + with self._lock: + self._latest_image = image + + def _get_detections(self, image: Image, class_filter: str | None = None) -> list: + """Pull detections from the shared PerceptionLoop (RPC). image param + retained for signature compatibility; not used now (PerceptionLoop has + its own subscription to the same color_image stream).""" + try: + raw = self._perception.current_detections(class_filter=class_filter) + except Exception: + return [] + return [_Det(m) for m in raw] + + # ── Skills ──────────────────────────────────────────────────────────────── + + @skill + def smart_follow_person(self, query: str) -> str: + """Follow one or more people matching a description. + + YOLO+MobileCLIP instead of QwenVL — faster lock-on, auto SpinSearch recovery. + If multiple people match, follows the nearest. Switches target automatically. + + Args: + query: e.g. "gray pants", "black shirt", "woman with backpack" + """ + return self._start_follow(query, mode="person") + + @skill + def smart_follow_object(self, class_name: str) -> str: + """Follow any YOLO-detectable object by class name (no CLIP — pure fast path). + + Args: + class_name: YOLO class: "dog", "cat", "chair", "bottle", "person", etc. + """ + return self._start_follow(class_name, mode="object") + + @skill + def smart_approach(self, query: str, stop_distance_m: float = 0.8) -> str: + """Move toward a person or object and stop when close enough. + + Args: + query: Description or YOLO class name. + stop_distance_m: Stop distance in meters (default 0.8m). + """ + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._should_stop.clear() + + with self._lock: + image = self._latest_image + if image is None: + return "No camera image yet." + + if query.lower() in _YOLO_CLASSES: + self._class_mode = True + self._class_name = query.lower() + self._text_emb = None + self._query = query + matches = self._get_detections(image, class_filter=self._class_name) + else: + self._class_mode = False + self._query = query + self._text_emb = None # PerceptionLoop holds the embedding + ranked = self._perception.match_text(query, class_filter="person") + matches = [_Det(m) for m in ranked if m["score"] >= _MATCH_THRESHOLD] + if not matches: + return "No persons matching that description in current scene." + + if not matches: + return f"Cannot see '{query}' — use smart_find first." + + self._active_ids = {d.track_id for d in matches} + set_active_mode("follow") + self.start_tool("smart_approach") + self._thread = Thread(target=self._approach_loop, args=(stop_distance_m,), daemon=True, name="SmartApproach") + self._thread.start() + return f"Approaching '{query}', stopping at {stop_distance_m}m." + + @skill + def stop_following(self) -> str: + """Stop following or approaching.""" + self._should_stop.set() + set_active_mode(None) + self.cmd_vel.publish(Twist.zero()) + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + return "Stopped." + + # ── Loops ───────────────────────────────────────────────────────────────── + + def _approach_loop(self, stop_distance_m: float) -> None: + lost_count = 0 + period = 1.0 / self._frequency + next_time = time.monotonic() + + while not self._should_stop.is_set(): + next_time += period + with self._lock: + image = self._latest_image + assert image is not None + + if self._class_mode: + candidates = self._get_detections(image, class_filter=self._class_name) + self._active_ids = {d.track_id for d in candidates} + else: + candidates = self._get_detections(image, class_filter="person") + + active = [d for d in candidates if d.track_id in self._active_ids] + + if active: + lost_count = 0 + target = max(active, key=lambda d: d.bbox_2d_volume()) + dist = self._visual_servo._estimate_distance(target.bbox) + if dist is not None and dist <= stop_distance_m: + self.cmd_vel.publish(Twist.zero()) + self.tool_update("smart_approach", f"Arrived. Distance: {dist:.2f}m.") + self.stop_tool("smart_approach") + set_active_mode(None) + return + self.cmd_vel.publish(self._visual_servo.compute_twist(target.bbox, image.width)) + else: + lost_count += 1 + self.cmd_vel.publish(Twist.zero()) + if lost_count > self._max_lost_frames * 2: + self.tool_update("smart_approach", "Lost target during approach.") + self.stop_tool("smart_approach") + set_active_mode(None) + return + + sleep_dur = next_time - time.monotonic() + if sleep_dur > 0: + time.sleep(sleep_dur) + + self.cmd_vel.publish(Twist.zero()) + set_active_mode(None) + self.stop_tool("smart_approach") + + def _start_follow(self, query: str, mode: str) -> str: + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._should_stop.clear() + + with self._lock: + image = self._latest_image + if image is None: + return "No camera image yet — is DimOS running?" + + if mode == "object" or query.lower() in _YOLO_CLASSES: + self._class_mode = True + self._class_name = query.lower() + self._text_emb = None + self._query = query + # Use the SceneBuffer (2s TTL) instead of current_detections() (120ms TTL) + # so MCP round-trip + thread-join latency don't produce a false "not visible" + # result for objects that were clearly in frame when the user clicked. + _now = time.monotonic() + _buf = get_shared_buffer() + _cls = query.lower() + buf_matches = [t for t in _buf.values() + if t.name.lower() == _cls and (_now - t.last_seen) <= 2.0] + self._active_ids = {t.track_id for t in buf_matches} + set_active_mode("follow") + self.start_tool("smart_follow_person") + self._thread = Thread(target=self._follow_loop, daemon=True, name="SmartFollow") + self._thread.start() + if not buf_matches: + return f"No '{query}' visible — will search when spinning." + return f"Tracking {len(buf_matches)} '{query}' (ids={list(self._active_ids)}). Following nearest." + + # Person mode: use shared CLIP via PerceptionLoop.match_text — scores + # cached track embeddings (zero extra inference) and returns ranked + # candidates with bbox/score. Same effective semantics as the old + # SceneBuffer fast path, just across-process instead of broken local. + self._class_mode = False + self._query = query + self._text_emb = None + + ranked = self._perception.match_text(query, class_filter="person") + matches = [_Det(m) for m in ranked if m["score"] >= _MATCH_THRESHOLD] + self._active_ids = {d.track_id for d in matches} + + set_active_mode("follow") + self.start_tool("smart_follow_person") + self._thread = Thread(target=self._follow_loop, daemon=True, name="SmartFollow") + self._thread.start() + + if not matches: + if ranked: + return (f"No match for '{query}' (best={ranked[0]['score']:.2f}, " + f"need {_MATCH_THRESHOLD}). Spinning to search.") + return "No persons in frame — spinning to search." + return f"Locked {len(matches)} match(es) for '{query}' (ids={list(self._active_ids)})." + + def _follow_loop(self) -> None: + lost_count = 0 + spin_start: float | None = None + frame_count = 0 + period = 1.0 / self._frequency + next_time = time.monotonic() + + while not self._should_stop.is_set(): + next_time += period + frame_count += 1 + + with self._lock: + image = self._latest_image + assert image is not None + + # Get detections — shared YOLO pass when fresh + if self._class_mode: + candidates = self._get_detections(image, class_filter=self._class_name) + self._active_ids = {d.track_id for d in candidates} + else: + candidates = self._get_detections(image, class_filter="person") + # Re-score conditions: + # 1) IMMEDIATE if we have candidates but none of them match our + # current active_ids. This is what stops the 360 spin the + # moment the target comes into view (was: only every 5 + # frames, so the bot would happily rotate past the target). + # 2) Periodic during steady tracking to keep active_ids + # refreshed against shape/lighting changes. + _none_active_visible = candidates and not any( + d.track_id in self._active_ids for d in candidates + ) + _should_rescore = candidates and self._query and ( + _none_active_visible or frame_count % self._clip_interval == 0 + ) + if _should_rescore: + try: + ranked = self._perception.match_text(self._query, class_filter="person") + except Exception: + ranked = [] + if ranked: + new_active = {m["track_id"] for m in ranked if m["score"] >= _MATCH_THRESHOLD} + ranked_ids = {m["track_id"] for m in ranked} + # Only swap if PerceptionLoop has scored any of our candidates. + if any(d.track_id in ranked_ids for d in candidates): + self._active_ids = new_active + + active = [d for d in candidates if d.track_id in self._active_ids] + # If we just (re)acquired the target while spinning, kill the spin + # immediately — don't finish the rotation before reacting. + if active and spin_start is not None: + spin_start = None + lost_count = 0 + self.cmd_vel.publish(Twist.zero()) + + if active: + target = max(active, key=lambda d: d.bbox_2d_volume()) + self.cmd_vel.publish(self._visual_servo.compute_twist(target.bbox, image.width)) + lost_count = 0 + spin_start = None + else: + lost_count += 1 + self.cmd_vel.publish(Twist.zero()) + + if lost_count > self._max_lost_frames: + if spin_start is None: + spin_start = time.monotonic() + self.tool_update("smart_follow_person", f"Lost '{self._query}' — spinning to search.") + + if time.monotonic() - spin_start > self._spin_timeout_s: + self.tool_update("smart_follow_person", + f"Full 360° search failed. Could not re-acquire '{self._query}'.") + self.stop_tool("smart_follow_person") + set_active_mode(None) + self.cmd_vel.publish(Twist.zero()) + return + + self.cmd_vel.publish( + Twist(linear=Vector3(0.0, 0.0, 0.0), angular=Vector3(0.0, 0.0, self._spin_speed)) + ) + + # Dashboard frame every 3 ticks + if frame_count % 3 == 0: + try: + state_label = "LOST" if lost_count > self._max_lost_frames else "FOLLOWING" + det_list = [{"bbox": d.bbox, "track_id": d.track_id, + "label": "TARGET" if d.track_id in self._active_ids else None} + for d in candidates] + write_annotated_frame(image.to_opencv(), det_list, + overlay_text=f"FOLLOW\n{state_label}\n{self._query}") + write_state({"mode": "follow", "state": state_label, + "query": self._query, "targets": len(active)}) + except Exception: + pass + + sleep_dur = next_time - time.monotonic() + if sleep_dur > 0: + time.sleep(sleep_dur) + + self.cmd_vel.publish(Twist.zero()) + set_active_mode(None) + self.tool_update("smart_follow_person", "Following stopped.") + self.stop_tool("smart_follow_person") From 5c033c0d7c2b7e31f20e9cc2c393eb174a21708e Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:16 +0800 Subject: [PATCH 06/15] feat(hackathon): add find.py --- .../unitree/go2/blueprints/hackathon/find.py | 299 ++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/find.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/find.py b/dimos/robot/unitree/go2/blueprints/hackathon/find.py new file mode 100644 index 0000000000..3e37192c33 --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/find.py @@ -0,0 +1,299 @@ +"""FindSkillContainer — explore + find anything using YOLO+CLIP in the background. + +Architecture: + - Declares explore_cmd / stop_explore_cmd Out streams → auto-wires to WavefrontFrontierExplorer + - Declares odom In stream → knows where it found the target + - YOLO+CLIP runs in background while the robot is moving + - Found → stops exploration, reports position, optionally hands off to SmartFollow +""" + +from __future__ import annotations + +import time +from threading import Event, RLock, Thread +from typing import Any + +from reactivex.disposable import Disposable + +from dimos.agents.annotation import skill +from dimos.constants import DEFAULT_THREAD_JOIN_TIMEOUT +from dimos.core.core import rpc +from dimos.core.module import Module, ModuleConfig +from dimos.core.stream import In, Out +from dimos.msgs.geometry_msgs.PoseStamped import PoseStamped +from dimos.msgs.sensor_msgs.Image import Image +from dimos.utils.logging_config import setup_logger +from dimos_lcm.std_msgs import Bool +from dimos.robot.unitree.go2.blueprints.hackathon.frame_writer import write_annotated_frame, write_state +from dimos.robot.unitree.go2.blueprints.hackathon.perception_loop import PerceptionLoopModule, set_active_mode + +logger = setup_logger() + +_MATCH_THRESHOLD = 0.22 + +# Full YOLO11 COCO class list — these skip CLIP, pure class filter +_YOLO_CLASSES = { + "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", + "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", + "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", + "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", + "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", + "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", + "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", + "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", + "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", + "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", + "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", + "toothbrush", +} + + +class Config(ModuleConfig): + pass + + +class _Det: + """Wrap dict-returned detections from PerceptionLoop with the small attr + surface the rest of this module needs (.track_id / .bbox / .name).""" + __slots__ = ("track_id", "bbox", "name", "confidence") + def __init__(self, m: dict) -> None: + self.track_id = m.get("track_id", -1) + self.bbox = tuple(m["bbox"]) + self.name = m.get("name", "") + self.confidence = m.get("score", m.get("confidence", 0.0)) + def bbox_2d_volume(self) -> float: + x1, y1, x2, y2 = self.bbox + return max(0.0, x2 - x1) * max(0.0, y2 - y1) + + +class FindSkillContainer(Module): + """Find + explore skill. + + Starts autonomous frontier exploration while watching the camera for a target. + When found, stops exploration and reports position to Claude via tool_update. + Shares CLIP + YOLO with PerceptionLoop via RPC (no local model loads). + """ + + color_image: In[Image] + odom: In[PoseStamped] + # Shared inference layer — ONE MobileCLIP + ONE YOLO across all skills. + _perception: PerceptionLoopModule + + # These wire directly to WavefrontFrontierExplorer via name+type matching + explore_cmd: Out[Bool] + stop_explore_cmd: Out[Bool] + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + # No own MobileCLIP / YOLO — both come from PerceptionLoop via RPC. + # Saves ~1.85 GB of duplicated model weights per skill module. + self._latest_image: Image | None = None + self._latest_odom: PoseStamped | None = None + self._thread: Thread | None = None + self._should_stop = Event() + self._lock = RLock() + + @rpc + def start(self) -> None: + super().start() + # CLIP loads lazily on first embed — eager start() caused concurrent + # multi-process model loads to stall startup. + self.register_disposable(Disposable(self.color_image.subscribe(self._on_image))) + self.register_disposable(Disposable(self.odom.subscribe(self._on_odom))) + + @rpc + def stop(self) -> None: + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + super().stop() + + def _on_image(self, image: Image) -> None: + with self._lock: + self._latest_image = image + + def _on_odom(self, odom: PoseStamped) -> None: + with self._lock: + self._latest_odom = odom + + @skill + def smart_find(self, query: str, explore: bool = True, then_approach: bool = False, timeout_s: float = 0.0) -> str: + """Explore the environment while searching for a specific person or object. + + Starts autonomous frontier exploration and watches the camera for the target. + When found, stops exploration and reports back. If then_approach=True, the robot + will also move close to the object after finding it. + + Works for people ("person with red shirt"), YOLO objects ("chair", "dog", "bottle"), + or any visual description. + + Args: + query: What to look for, e.g. "red chair", "dog", "person with backpack" + explore: If True (default), start autonomous exploration while searching. + then_approach: If True, automatically approach and get close after finding. + timeout_s: Give up after this many seconds (default 120s). + + Returns: + Immediate confirmation. Will send tool_update when found or timed out. + """ + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + self._should_stop.clear() + + with self._lock: + image = self._latest_image + + if image is None: + return "No camera image yet — is DimOS running?" + + if explore: + cmd = Bool() + cmd.data = True + self.explore_cmd.publish(cmd) + + set_active_mode("find") + self.start_tool("smart_find") + self._thread = Thread( + target=self._find_loop, + args=(query, explore, then_approach, timeout_s), + daemon=True, + name="SmartFind", + ) + self._thread.start() + + return ( + f"Searching for '{query}'. " + + ("Exploration started. " if explore else "Watching without moving. ") + + f"Timeout: {int(timeout_s)}s. Will update you when found." + ) + + @skill + def stop_find(self) -> str: + """Stop an active find/explore mission and halt exploration.""" + self._should_stop.set() + set_active_mode(None) + self._send_stop_explore() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + return "Find mission stopped." + + def _send_stop_explore(self) -> None: + cmd = Bool() + cmd.data = True + self.stop_explore_cmd.publish(cmd) + + def _get_detections(self, image: Image, class_filter: str | None = None) -> list: + """Pull detections from the shared PerceptionLoop (RPC).""" + try: + raw = self._perception.current_detections(class_filter=class_filter) + except Exception: + return [] + return [_Det(m) for m in raw] + + def _find_loop(self, query: str, exploring: bool, then_approach: bool, timeout_s: float) -> None: + class_mode = query.lower() in _YOLO_CLASSES + + start_time = time.monotonic() + frame_count = 0 + clip_interval = 5 + + unbounded = timeout_s <= 0 + while not self._should_stop.is_set(): + elapsed = time.monotonic() - start_time + if not unbounded and elapsed > timeout_s: + if exploring: + self._send_stop_explore() + self.tool_update("smart_find", f"Search timed out after {int(elapsed)}s. '{query}' not found.") + set_active_mode(None) + self.stop_tool("smart_find") + return + + with self._lock: + image = self._latest_image + odom = self._latest_odom + + if image is None: + time.sleep(0.1) + continue + + frame_count += 1 + + if class_mode: + matches = self._get_detections(image, class_filter=query.lower()) + if matches: + best = max(matches, key=lambda d: d.bbox_2d_volume()) + try: + all_dets = self._get_detections(image) + det_list = [{"bbox": d.bbox, "track_id": d.track_id, + "label": "FOUND" if d.track_id == best.track_id else None} + for d in all_dets] + write_annotated_frame(image.to_opencv(), det_list, overlay_text=f"FIND\nFOUND\n{query}") + write_state({"mode": "find", "state": "FOUND", "query": query}) + except Exception: + pass + set_active_mode(None) + self._report_found(query, best, odom, exploring, then_approach) + return + + elif frame_count % clip_interval == 0: + # Shared-CLIP scoring via PerceptionLoop — no local inference, + # no duplicate MobileCLIP load. + try: + ranked = self._perception.match_text(query) + except Exception: + ranked = [] + if ranked and ranked[0]["score"] >= _MATCH_THRESHOLD: + best = _Det(ranked[0]) + try: + all_dets = self._get_detections(image) + det_list = [{"bbox": d.bbox, "track_id": d.track_id, + "label": "FOUND" if d.track_id == best.track_id else None} + for d in all_dets] + write_annotated_frame(image.to_opencv(), det_list, overlay_text=f"FIND\nFOUND\n{query}") + write_state({"mode": "find", "state": "FOUND", "query": query}) + except Exception: + pass + set_active_mode(None) + self._report_found(query, best, odom, exploring, then_approach) + return + + # Annotate searching frames every 3 ticks + if frame_count % 3 == 0: + try: + cur_dets = self._get_detections(image) + det_list = [{"bbox": d.bbox, "track_id": d.track_id} for d in cur_dets] + write_annotated_frame(image.to_opencv(), det_list, overlay_text=f"FIND\nSEARCHING\n{query}") + write_state({"mode": "find", "state": "SEARCHING", "query": query}) + except Exception: + pass + + time.sleep(1.0 / 15.0) + + if exploring: + self._send_stop_explore() + set_active_mode(None) + self.tool_update("smart_find", f"Find mission for '{query}' was stopped.") + self.stop_tool("smart_find") + + def _report_found(self, query: str, detection: Any, odom: PoseStamped | None, exploring: bool, then_approach: bool) -> None: + if exploring: + self._send_stop_explore() + + pos_str = ( + f"x={odom.x:.2f}, y={odom.y:.2f}" if odom is not None else "position unknown" + ) + x1, y1, x2, y2 = detection.bbox + center_x = (x1 + x2) / 2 + img_w = detection.image.width if hasattr(detection, "image") else 1280 + side = "left" if center_x < img_w * 0.4 else "right" if center_x > img_w * 0.6 else "center" + + approach_hint = f" Now call smart_approach('{query}') to move close." if then_approach else "" + self.tool_update( + "smart_find", + f"Found '{query}'! Robot at {pos_str}, target is {side} of frame.{approach_hint}", + ) + self.stop_tool("smart_find") From 0ae84a3902ce8af54eed35150a9118a21efb9ec6 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:20 +0800 Subject: [PATCH 07/15] feat(hackathon): add dog_mode.py --- .../go2/blueprints/hackathon/dog_mode.py | 354 ++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py b/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py new file mode 100644 index 0000000000..e819232a63 --- /dev/null +++ b/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py @@ -0,0 +1,354 @@ +"""DogModeModule — autonomous dog behavior for Unitree Go2. + +State machine: + WANDERING — explore environment, periodic sniff animation + ALERT — person detected, face them, bark randomly based on threat level + CLOSE — person within growl range, track and growl, stop moving + +Threat levels (assigned per track_id on first detection, random): + 0.0–0.4 curious: occasional soft bark, no growl + 0.4–0.7 cautious: bark after short delay, growl at 2.0m + 0.7–1.0 aggressive: bark immediately, growl at 2.5m +""" + +from __future__ import annotations + +import random +import subprocess +import time +from pathlib import Path +from threading import Event, RLock, Thread +from typing import Any + +from reactivex.disposable import Disposable +from unitree_webrtc_connect.constants import RTC_TOPIC, SPORT_CMD + +from dimos.agents.annotation import skill +from dimos.constants import DEFAULT_THREAD_JOIN_TIMEOUT +from dimos.core.core import rpc +from dimos.core.module import Module, ModuleConfig +from dimos.core.stream import In, Out +from dimos.msgs.geometry_msgs.Twist import Twist +from dimos.msgs.geometry_msgs.Vector3 import Vector3 +from dimos.msgs.sensor_msgs.CameraInfo import CameraInfo +from dimos.msgs.sensor_msgs.Image import Image +from dimos.navigation.visual_servoing.visual_servoing_2d import VisualServoing2D +from dimos.perception.detection.detectors.person.yolo import YoloPersonDetector +from dimos.robot.unitree.go2.connection_spec import GO2ConnectionSpec +from dimos.utils.logging_config import setup_logger +from dimos_lcm.std_msgs import Bool +from dimos.robot.unitree.go2.blueprints.hackathon.frame_writer import write_annotated_frame, write_state +from dimos.robot.unitree.go2.blueprints.hackathon.perception_loop import get_shared_detections, set_active_mode, shared_detections_fresh + +logger = setup_logger() + +SOUNDS_DIR = Path(__file__).parent / "sounds" +SOUND_FILES = { + "bark": SOUNDS_DIR / "minecraft-dog-bark.mp3", + "deepbark": SOUNDS_DIR / "deepbark.mp3", + "growl": SOUNDS_DIR / "dog-growling-and-barking.mp3", + "perry": SOUNDS_DIR / "perry-the-platypuss-growl.mp3", +} + +# Threat thresholds +_AGGRESSIVE_THRESHOLD = 0.7 +_CAUTIOUS_THRESHOLD = 0.4 + +# Distance thresholds (meters, estimated from bbox width) +_CLOSE_AGGRESSIVE = 2.5 # growl distance for aggressive +_CLOSE_CAUTIOUS = 2.0 # growl distance for cautious +_FACE_RANGE = 5.0 # start facing at this distance + +# Timing +_SNIFF_INTERVAL_MIN = 20.0 # minimum seconds between sniffs +_SNIFF_INTERVAL_MAX = 45.0 +_BARK_COOLDOWN = 4.0 # minimum seconds between barks +_LOOP_HZ = 10.0 # main loop frequency + + +def _play_sound(name: str) -> None: + path = SOUND_FILES.get(name) + if path and path.exists(): + try: + import sounddevice as sd + import soundfile as sf + data, sr = sf.read(str(path)) + sd.play(data.astype("float32"), sr) + sd.wait() + except Exception as e: + logger.warning(f"Sound playback failed: {e}") + + +class Config(ModuleConfig): + camera_info: CameraInfo + + +class DogModeModule(Module): + """Autonomous dog behavior module.""" + + config: Config + + color_image: In[Image] + cmd_vel: Out[Twist] + explore_cmd: Out[Bool] + stop_explore_cmd: Out[Bool] + + _connection: GO2ConnectionSpec # injected by dimOS — used for sport commands + + def __init__(self, **kwargs: Any) -> None: + super().__init__(**kwargs) + self._detector = YoloPersonDetector() # fallback only + self._servo = VisualServoing2D(self.config.camera_info) + + self._latest_image: Image | None = None + self._thread: Thread | None = None + self._should_stop = Event() + self._lock = RLock() + + # Threat memory: track_id → threat float [0,1] + self._threats: dict[int, float] = {} + self._state = "IDLE" + + @rpc + def start(self) -> None: + super().start() + self.register_disposable(Disposable(self.color_image.subscribe(self._on_image))) + + @rpc + def stop(self) -> None: + self._should_stop.set() + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + self._detector.stop() + super().stop() + + def _on_image(self, image: Image) -> None: + with self._lock: + self._latest_image = image + + @skill + def start_dog_mode(self) -> str: + """Start autonomous dog mode. + + The robot will: + - Roam and explore the environment + - Periodically sniff the ground (StandDown animation) + - Detect people and assess threat level (random, per person) + - Bark at people based on threat level + - Growl and track anyone who gets close + - Face people when they move toward it + """ + if self._thread and self._thread.is_alive(): + return "Dog mode is already running." + + self._should_stop.clear() + self._threats.clear() + self._state = "WANDERING" + set_active_mode("dog") + + self._thread = Thread(target=self._dog_loop, daemon=True, name="DogMode") + self._thread.start() + + return "Woof. Dog mode activated. I'll explore, sniff around, and keep an eye on people." + + @skill + def stop_dog_mode(self) -> str: + """Stop dog mode and return the robot to idle.""" + self._should_stop.set() + set_active_mode(None) + self._send_stop_explore() + self.cmd_vel.publish(Twist.zero()) + if self._thread is not None: + self._thread.join(timeout=DEFAULT_THREAD_JOIN_TIMEOUT) + self._thread = None + self._state = "IDLE" + return "Dog mode stopped." + + # ────────────────────────────────────────────── + # Internal helpers + # ────────────────────────────────────────────── + + def _sport(self, name: str) -> None: + try: + cmd_id = SPORT_CMD[name] + self._connection.publish_request(RTC_TOPIC["SPORT_MOD"], {"api_id": cmd_id}) + except Exception as e: + logger.warning(f"Sport command '{name}' failed: {e}") + + def _send_explore(self) -> None: + msg = Bool(); msg.data = True + self.explore_cmd.publish(msg) + + def _send_stop_explore(self) -> None: + msg = Bool(); msg.data = True + self.stop_explore_cmd.publish(msg) + + def _threat_for(self, track_id: int) -> float: + if track_id not in self._threats: + self._threats[track_id] = random.random() + logger.info(f"DogMode: new person track_id={track_id} threat={self._threats[track_id]:.2f}") + return self._threats[track_id] + + def _growl_distance(self, threat: float) -> float: + if threat >= _AGGRESSIVE_THRESHOLD: + return _CLOSE_AGGRESSIVE + if threat >= _CAUTIOUS_THRESHOLD: + return _CLOSE_CAUTIOUS + return 0.0 # curious — no growl + + def _face_person(self, bbox: tuple, image_width: int) -> None: + """Publish angular-only twist to face person (no linear movement).""" + x1, _, x2, _ = bbox + cx = (x1 + x2) / 2.0 + fx = self.config.camera_info.K[0] + optical_cx = self.config.camera_info.K[2] + x_norm = (cx - optical_cx) / fx + angular_z = float(-x_norm * 1.2) + angular_z = max(-0.6, min(0.6, angular_z)) + if abs(angular_z) > 0.05: + self.cmd_vel.publish( + Twist(linear=Vector3(0.0, 0.0, 0.0), angular=Vector3(0.0, 0.0, angular_z)) + ) + else: + self.cmd_vel.publish(Twist.zero()) + + def _do_sniff(self) -> None: + """StandDown → pause → RecoveryStand in a background thread.""" + def _sniff() -> None: + self.cmd_vel.publish(Twist.zero()) + self._sport("StandDown") + time.sleep(2.0) + self._sport("RecoveryStand") + time.sleep(1.0) + Thread(target=_sniff, daemon=True).start() + + # ────────────────────────────────────────────── + # Main loop + # ────────────────────────────────────────────── + + def _dog_loop(self) -> None: + last_sniff = time.monotonic() - random.uniform(0, _SNIFF_INTERVAL_MIN) + last_bark = 0.0 + next_sniff_in = random.uniform(_SNIFF_INTERVAL_MIN, _SNIFF_INTERVAL_MAX) + sniffing = False + frame_count = 0 + + # Start exploring + self._send_explore() + + period = 1.0 / _LOOP_HZ + next_t = time.monotonic() + + while not self._should_stop.is_set(): + next_t += period + now = time.monotonic() + + with self._lock: + image = self._latest_image + + if image is None: + time.sleep(period) + continue + + frame_count += 1 + + # ── Detect people — use shared YOLO pass when fresh ── + if shared_detections_fresh(): + all_dets, _ = get_shared_detections() + persons = [d for d in all_dets if getattr(d, "name", "") == "person"] + else: + dets = self._detector.process_image(image) + persons = [d for d in dets.detections if d.is_valid()] + + if not persons: + # Nobody around — wander + if self._state != "WANDERING": + self._state = "WANDERING" + self._send_explore() + + # Sniff periodically + if not sniffing and (now - last_sniff) >= next_sniff_in: + sniffing = True + last_sniff = now + next_sniff_in = random.uniform(_SNIFF_INTERVAL_MIN, _SNIFF_INTERVAL_MAX) + self._do_sniff() + time.sleep(3.2) # wait for animation to complete + sniffing = False + + else: + # ── Person(s) detected ── + # Pick the most prominent (nearest) + target = max(persons, key=lambda d: d.bbox_2d_volume()) + tid = target.track_id + threat = self._threat_for(tid) + dist = self._servo._estimate_distance(target.bbox) + growl_dist = self._growl_distance(threat) + + # Stop exploration while attending to person + if self._state == "WANDERING": + self._send_stop_explore() + self._state = "ALERT" + + is_close = dist is not None and growl_dist > 0 and dist <= growl_dist + + if is_close: + # ── CLOSE: growl and face, stop moving ── + if self._state != "CLOSE": + self._state = "CLOSE" + Thread(target=_play_sound, args=("growl",), daemon=True).start() + self._face_person(target.bbox, image.width) + + else: + # ── ALERT: face person, decide whether to bark ── + self._state = "ALERT" + + # Face if within range + if dist is None or dist <= _FACE_RANGE: + self._face_person(target.bbox, image.width) + else: + self.cmd_vel.publish(Twist.zero()) + + # Bark logic by threat level + if now - last_bark >= _BARK_COOLDOWN: + if threat >= _AGGRESSIVE_THRESHOLD: + # Aggressive: always bark on sight + last_bark = now + sound = "deepbark" if random.random() < 0.5 else "bark" + Thread(target=_play_sound, args=(sound,), daemon=True).start() + elif threat >= _CAUTIOUS_THRESHOLD: + # Cautious: 40% chance each cycle (at 10Hz → ~0.5Hz effective) + if random.random() < 0.04: + last_bark = now + Thread(target=_play_sound, args=("bark",), daemon=True).start() + else: + # Curious: occasional soft bark (10% per cycle) + if random.random() < 0.01: + last_bark = now + Thread(target=_play_sound, args=("bark",), daemon=True).start() + + # ── Annotate frame every 3 ticks for dashboard (~3fps) ── + if frame_count % 3 == 0: + try: + bgr = image.to_opencv() + det_list = [] + for p in persons: + tid = p.track_id + det_list.append({ + "bbox": p.bbox, + "track_id": tid, + "threat": self._threats.get(tid), + }) + write_annotated_frame(bgr, det_list, overlay_text=f"DOG MODE\n{self._state}") + write_state({"mode": "dog", "state": self._state, "persons": len(persons), + "threats": {str(k): round(v, 2) for k, v in self._threats.items()}}) + except Exception: + pass + + # Pace loop + sleep_dur = next_t - time.monotonic() + if sleep_dur > 0: + time.sleep(sleep_dur) + + self.cmd_vel.publish(Twist.zero()) + self._send_stop_explore() From 4175716f72b361facd8423492790a8b138fc6399 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:29 +0800 Subject: [PATCH 08/15] feat(hackathon): add sounds/deepbark.mp3 --- .../go2/blueprints/hackathon/sounds/deepbark.mp3 | Bin 0 -> 5421 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/sounds/deepbark.mp3 diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/sounds/deepbark.mp3 b/dimos/robot/unitree/go2/blueprints/hackathon/sounds/deepbark.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..bc578343282b08e3e269b05ddf4f06ac7e2ca3ff GIT binary patch literal 5421 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 V$g?I(0ANoC0O)@^_+Rkd{{Yk4w}Jow literal 0 HcmV?d00001 From 0331b67f7a74ea0d9c9f9175f393da7e357db19b Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:20:37 +0800 Subject: [PATCH 09/15] feat(hackathon): add sounds/dog-growling-and-barking.mp3 --- .../sounds/dog-growling-and-barking.mp3 | Bin 0 -> 101442 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/sounds/dog-growling-and-barking.mp3 diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/sounds/dog-growling-and-barking.mp3 b/dimos/robot/unitree/go2/blueprints/hackathon/sounds/dog-growling-and-barking.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..e937653895fadc76f7cd472fce0a3a8ed76e00a6 GIT binary patch literal 101442 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

95dtCwIAkXQJ9GyY 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 Date: Fri, 29 May 2026 01:20:39 +0800 Subject: [PATCH 10/15] feat(hackathon): add sounds/minecraft-dog-bark.mp3 --- .../hackathon/sounds/minecraft-dog-bark.mp3 | Bin 0 -> 23542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/sounds/minecraft-dog-bark.mp3 diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/sounds/minecraft-dog-bark.mp3 b/dimos/robot/unitree/go2/blueprints/hackathon/sounds/minecraft-dog-bark.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6bcb504bdc780126db54634f6fad2fc2a759d269 GIT binary patch literal 23542 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 Date: Fri, 29 May 2026 01:20:42 +0800 Subject: [PATCH 11/15] feat(hackathon): add sounds/perry-the-platypuss-growl.mp3 --- .../sounds/perry-the-platypuss-growl.mp3 | Bin 0 -> 36290 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dimos/robot/unitree/go2/blueprints/hackathon/sounds/perry-the-platypuss-growl.mp3 diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/sounds/perry-the-platypuss-growl.mp3 b/dimos/robot/unitree/go2/blueprints/hackathon/sounds/perry-the-platypuss-growl.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..efa6f0fbe5379deef49d21055881ee7680748d54 GIT binary patch literal 36290 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 literal 0 HcmV?d00001 From 0d926e7ca9f45dab73b039490c8908f933a8e4d3 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:29:14 +0800 Subject: [PATCH 12/15] =?UTF-8?q?fix:=20address=20greptile=20review=20?= =?UTF-8?q?=E2=80=94=20smart=5Ffollow.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../go2/blueprints/hackathon/smart_follow.py | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py b/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py index f10859c3d7..1c8eeb6c8d 100644 --- a/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py +++ b/dimos/robot/unitree/go2/blueprints/hackathon/smart_follow.py @@ -103,6 +103,7 @@ def __init__(self, **kwargs: Any) -> None: self._thread: Thread | None = None self._should_stop = Event() self._lock = RLock() + self._tool_name: str = "smart_follow_person" @rpc def start(self) -> None: @@ -222,7 +223,9 @@ def _approach_loop(self, stop_distance_m: float) -> None: next_time += period with self._lock: image = self._latest_image - assert image is not None + if image is None: + time.sleep(period) + continue if self._class_mode: candidates = self._get_detections(image, class_filter=self._class_name) @@ -285,8 +288,9 @@ def _start_follow(self, query: str, mode: str) -> str: buf_matches = [t for t in _buf.values() if t.name.lower() == _cls and (_now - t.last_seen) <= 2.0] self._active_ids = {t.track_id for t in buf_matches} + self._tool_name = "smart_follow_object" set_active_mode("follow") - self.start_tool("smart_follow_person") + self.start_tool(self._tool_name) self._thread = Thread(target=self._follow_loop, daemon=True, name="SmartFollow") self._thread.start() if not buf_matches: @@ -305,8 +309,9 @@ def _start_follow(self, query: str, mode: str) -> str: matches = [_Det(m) for m in ranked if m["score"] >= _MATCH_THRESHOLD] self._active_ids = {d.track_id for d in matches} + self._tool_name = "smart_follow_person" set_active_mode("follow") - self.start_tool("smart_follow_person") + self.start_tool(self._tool_name) self._thread = Thread(target=self._follow_loop, daemon=True, name="SmartFollow") self._thread.start() @@ -330,7 +335,9 @@ def _follow_loop(self) -> None: with self._lock: image = self._latest_image - assert image is not None + if image is None: + time.sleep(period) + continue # Get detections — shared YOLO pass when fresh if self._class_mode: @@ -383,12 +390,12 @@ def _follow_loop(self) -> None: if lost_count > self._max_lost_frames: if spin_start is None: spin_start = time.monotonic() - self.tool_update("smart_follow_person", f"Lost '{self._query}' — spinning to search.") + self.tool_update(self._tool_name, f"Lost '{self._query}' — spinning to search.") if time.monotonic() - spin_start > self._spin_timeout_s: - self.tool_update("smart_follow_person", + self.tool_update(self._tool_name, f"Full 360° search failed. Could not re-acquire '{self._query}'.") - self.stop_tool("smart_follow_person") + self.stop_tool(self._tool_name) set_active_mode(None) self.cmd_vel.publish(Twist.zero()) return @@ -417,5 +424,5 @@ def _follow_loop(self) -> None: self.cmd_vel.publish(Twist.zero()) set_active_mode(None) - self.tool_update("smart_follow_person", "Following stopped.") - self.stop_tool("smart_follow_person") + self.tool_update(self._tool_name, "Following stopped.") + self.stop_tool(self._tool_name) From 0fb5302a19f4e971ff32edfcef544e5803bd54d6 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:29:20 +0800 Subject: [PATCH 13/15] =?UTF-8?q?fix:=20address=20greptile=20review=20?= =?UTF-8?q?=E2=80=94=20dog=5Fmode.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py b/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py index e819232a63..d66135f075 100644 --- a/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py +++ b/dimos/robot/unitree/go2/blueprints/hackathon/dog_mode.py @@ -14,7 +14,6 @@ from __future__ import annotations import random -import subprocess import time from pathlib import Path from threading import Event, RLock, Thread @@ -273,7 +272,7 @@ def _dog_loop(self) -> None: last_sniff = now next_sniff_in = random.uniform(_SNIFF_INTERVAL_MIN, _SNIFF_INTERVAL_MAX) self._do_sniff() - time.sleep(3.2) # wait for animation to complete + self._should_stop.wait(timeout=3.2) sniffing = False else: From 3837179d43ef8fe7b8a427f231e8247b65a8b888 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:29:25 +0800 Subject: [PATCH 14/15] =?UTF-8?q?fix:=20address=20greptile=20review=20?= =?UTF-8?q?=E2=80=94=20perception=5Floop.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blueprints/hackathon/perception_loop.py | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py b/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py index f9cd8acbec..cb5360e91c 100644 --- a/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py +++ b/dimos/robot/unitree/go2/blueprints/hackathon/perception_loop.py @@ -300,25 +300,21 @@ def _perception_loop(self) -> None: _shared_buffer = {k: v for k, v in _shared_buffer.items() if now - v.last_seen <= _BUFFER_TTL} - # Frame annotation — every loop iteration (was throttled to every - # 3rd, which capped the dashboard camera at ~5fps; YOLO is the real - # gate so writing every frame just keeps up with the loop). - if True: - with _shared_lock: - mode = _active_mode - if mode is None: - try: - snap = [t for t in _shared_buffer.values() if now - t.last_seen <= _BUFFER_TTL] - det_list = [{"bbox": t.bbox, "track_id": t.track_id, "label": t.name} for t in snap] - write_annotated_frame(image.to_opencv(), det_list, overlay_text="PERCEPTION\nACTIVE") - write_state({ - "mode": "perception", - "state": "ACTIVE", - "objects": len(det_list), - "classes": list({t.name for t in snap}), - }) - except Exception: - pass + with _shared_lock: + mode = _active_mode + if mode is None: + try: + snap = [t for t in _shared_buffer.values() if now - t.last_seen <= _BUFFER_TTL] + det_list = [{"bbox": t.bbox, "track_id": t.track_id, "label": t.name} for t in snap] + write_annotated_frame(image.to_opencv(), det_list, overlay_text="PERCEPTION\nACTIVE") + write_state({ + "mode": "perception", + "state": "ACTIVE", + "objects": len(det_list), + "classes": list({t.name for t in snap}), + }) + except Exception: + pass sleep_dur = next_t - time.monotonic() if sleep_dur > 0: From 43b4876761b4a87d523a713f573bf2eb2f4998a9 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 29 May 2026 01:29:30 +0800 Subject: [PATCH 15/15] =?UTF-8?q?fix:=20address=20greptile=20review=20?= =?UTF-8?q?=E2=80=94=20find.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dimos/robot/unitree/go2/blueprints/hackathon/find.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dimos/robot/unitree/go2/blueprints/hackathon/find.py b/dimos/robot/unitree/go2/blueprints/hackathon/find.py index 3e37192c33..f26b99d818 100644 --- a/dimos/robot/unitree/go2/blueprints/hackathon/find.py +++ b/dimos/robot/unitree/go2/blueprints/hackathon/find.py @@ -132,7 +132,7 @@ def smart_find(self, query: str, explore: bool = True, then_approach: bool = Fal query: What to look for, e.g. "red chair", "dog", "person with backpack" explore: If True (default), start autonomous exploration while searching. then_approach: If True, automatically approach and get close after finding. - timeout_s: Give up after this many seconds (default 120s). + timeout_s: Give up after this many seconds (0 = no timeout, runs until found or stopped). Returns: Immediate confirmation. Will send tool_update when found or timed out.