From eb643da81de11fc5ed8359b4263ca7c39ad40aa4 Mon Sep 17 00:00:00 2001 From: Paul Nechifor Date: Sat, 14 Mar 2026 02:02:21 +0200 Subject: [PATCH] chore(comments): remove section markers --- dimos/agents/mcp/mcp_adapter.py | 20 --- dimos/agents/mcp/mcp_server.py | 19 --- dimos/agents_deprecated/agent.py | 16 -- .../agents_deprecated/prompt_builder/impl.py | 2 - dimos/control/blueprints.py | 37 ----- dimos/control/coordinator.py | 34 ----- dimos/control/task.py | 9 -- dimos/control/tasks/cartesian_ik_task.py | 4 - dimos/control/tasks/servo_task.py | 4 - dimos/control/tasks/teleop_task.py | 4 - dimos/control/tasks/trajectory_task.py | 4 - dimos/control/tasks/velocity_task.py | 4 - dimos/control/test_control.py | 39 ----- dimos/control/tick_loop.py | 7 - dimos/core/daemon.py | 14 -- dimos/core/test_cli_stop_status.py | 10 -- dimos/core/test_daemon.py | 21 --- dimos/core/test_e2e_daemon.py | 19 --- dimos/core/test_mcp_integration.py | 15 -- dimos/core/tests/demo_devex.py | 33 ---- .../hardware/drive_trains/flowbase/adapter.py | 24 --- dimos/hardware/drive_trains/mock/adapter.py | 24 --- dimos/hardware/drive_trains/spec.py | 10 -- dimos/hardware/manipulators/mock/adapter.py | 40 ----- dimos/hardware/manipulators/piper/adapter.py | 36 ----- dimos/hardware/manipulators/spec.py | 26 ---- dimos/hardware/manipulators/xarm/adapter.py | 36 ----- dimos/manipulation/blueprints.py | 19 --- .../control/coordinator_client.py | 17 --- .../cartesian_motion_controller.py | 12 -- .../joint_trajectory_controller.py | 12 -- dimos/manipulation/manipulation_interface.py | 4 - dimos/manipulation/manipulation_module.py | 28 ---- dimos/manipulation/pick_and_place_module.py | 28 ---- .../planning/kinematics/jacobian_ik.py | 2 +- .../planning/kinematics/pinocchio_ik.py | 28 ---- .../planning/monitor/world_monitor.py | 22 +-- .../monitor/world_obstacle_monitor.py | 2 +- .../planning/planners/rrt_planner.py | 2 +- dimos/manipulation/planning/spec/types.py | 11 -- .../planning/world/drake_world.py | 22 ++- dimos/manipulation/test_manipulation_unit.py | 29 ---- dimos/memory/timeseries/base.py | 2 - dimos/memory/timeseries/legacy.py | 2 - .../temporal_memory/entity_graph_db.py | 14 +- .../frame_window_accumulator.py | 12 -- .../temporal_memory/temporal_memory.py | 28 ---- .../temporal_memory/temporal_state.py | 8 - .../test_temporal_memory_module.py | 45 ------ .../temporal_memory/window_analyzer.py | 16 -- dimos/protocol/pubsub/impl/shmpubsub.py | 11 +- dimos/protocol/pubsub/shm/ipc_factory.py | 20 --- .../service/system_configurator/base.py | 6 +- .../service/system_configurator/lcm.py | 6 +- dimos/protocol/service/test_lcmservice.py | 8 +- .../service/test_system_configurator.py | 16 +- dimos/skills/skills.py | 21 --- dimos/stream/frame_processor.py | 2 - dimos/teleop/phone/phone_teleop_module.py | 32 ---- dimos/teleop/quest/blueprints.py | 8 - dimos/teleop/quest/quest_teleop_module.py | 28 ---- dimos/test_no_sections.py | 143 ++++++++++++++++++ dimos/utils/cli/dtop.py | 23 --- dimos/utils/simple_controller.py | 6 - dimos/utils/test_data.py | 5 - docker/navigation/.env.hardware | 36 ----- docker/navigation/Dockerfile | 19 --- docker/navigation/docker-compose.dev.yml | 7 - .../manipulation/adding_a_custom_arm.md | 34 ----- 69 files changed, 196 insertions(+), 1111 deletions(-) create mode 100644 dimos/test_no_sections.py diff --git a/dimos/agents/mcp/mcp_adapter.py b/dimos/agents/mcp/mcp_adapter.py index 9b8cc5c4b9..213bf71e23 100644 --- a/dimos/agents/mcp/mcp_adapter.py +++ b/dimos/agents/mcp/mcp_adapter.py @@ -63,10 +63,6 @@ def __init__(self, url: str | None = None, timeout: int = DEFAULT_TIMEOUT) -> No self.url = url self.timeout = timeout - # ------------------------------------------------------------------ - # Low-level JSON-RPC - # ------------------------------------------------------------------ - def call(self, method: str, params: dict[str, Any] | None = None) -> dict[str, Any]: """Send a JSON-RPC request and return the parsed response. @@ -87,10 +83,6 @@ def call(self, method: str, params: dict[str, Any] | None = None) -> dict[str, A raise McpError(f"HTTP {resp.status_code}: {e}") from e return resp.json() # type: ignore[no-any-return] - # ------------------------------------------------------------------ - # MCP standard methods - # ------------------------------------------------------------------ - def initialize(self) -> dict[str, Any]: """Send ``initialize`` and return server info.""" return self.call("initialize") @@ -112,10 +104,6 @@ def call_tool_text(self, name: str, arguments: dict[str, Any] | None = None) -> return "" return content[0].get("text", str(content[0])) # type: ignore[no-any-return] - # ------------------------------------------------------------------ - # Readiness probes - # ------------------------------------------------------------------ - def wait_for_ready(self, timeout: float = 10.0, interval: float = 0.5) -> bool: """Poll until the MCP server responds, or return False on timeout.""" deadline = time.monotonic() + timeout @@ -148,10 +136,6 @@ def wait_for_down(self, timeout: float = 10.0, interval: float = 0.5) -> bool: time.sleep(interval) return False - # ------------------------------------------------------------------ - # Class methods for discovery - # ------------------------------------------------------------------ - @classmethod def from_run_entry(cls, entry: Any | None = None, timeout: int = DEFAULT_TIMEOUT) -> McpAdapter: """Create an adapter from a RunEntry, or discover the latest one. @@ -173,10 +157,6 @@ def from_run_entry(cls, entry: Any | None = None, timeout: int = DEFAULT_TIMEOUT url = f"http://localhost:{global_config.mcp_port}/mcp" return cls(url=url, timeout=timeout) - # ------------------------------------------------------------------ - # Internals - # ------------------------------------------------------------------ - @staticmethod def _unwrap(response: dict[str, Any]) -> dict[str, Any]: """Extract the ``result`` from a JSON-RPC response, raising on error.""" diff --git a/dimos/agents/mcp/mcp_server.py b/dimos/agents/mcp/mcp_server.py index e5697542fb..9149de06ec 100644 --- a/dimos/agents/mcp/mcp_server.py +++ b/dimos/agents/mcp/mcp_server.py @@ -50,11 +50,6 @@ app.state.rpc_calls = {} -# --------------------------------------------------------------------------- -# JSON-RPC helpers -# --------------------------------------------------------------------------- - - def _jsonrpc_result(req_id: Any, result: Any) -> dict[str, Any]: return {"jsonrpc": "2.0", "id": req_id, "result": result} @@ -67,11 +62,6 @@ def _jsonrpc_error(req_id: Any, code: int, message: str) -> dict[str, Any]: return {"jsonrpc": "2.0", "id": req_id, "error": {"code": code, "message": message}} -# --------------------------------------------------------------------------- -# JSON-RPC handlers (standard MCP protocol only) -# --------------------------------------------------------------------------- - - def _handle_initialize(req_id: Any) -> dict[str, Any]: return _jsonrpc_result( req_id, @@ -177,11 +167,6 @@ async def mcp_endpoint(request: Request) -> Response: return JSONResponse(result) -# --------------------------------------------------------------------------- -# McpServer Module -# --------------------------------------------------------------------------- - - class McpServer(Module): _uvicorn_server: uvicorn.Server | None = None _serve_future: concurrent.futures.Future[None] | None = None @@ -215,10 +200,6 @@ def on_system_modules(self, modules: list[RPCClient]) -> None: for skill_info in app.state.skills } - # ------------------------------------------------------------------ - # Introspection skills (exposed as MCP tools via tools/list) - # ------------------------------------------------------------------ - @skill def server_status(self) -> str: """Get MCP server status: main process PID, deployed modules, and skill count.""" diff --git a/dimos/agents_deprecated/agent.py b/dimos/agents_deprecated/agent.py index 0443b2cc94..1d48ce2fa4 100644 --- a/dimos/agents_deprecated/agent.py +++ b/dimos/agents_deprecated/agent.py @@ -68,9 +68,6 @@ _MAX_SAVED_FRAMES = 100 # Maximum number of frames to save -# ----------------------------------------------------------------------------- -# region Agent Base Class -# ----------------------------------------------------------------------------- class Agent: """Base agent that manages memory and subscriptions.""" @@ -105,12 +102,6 @@ def dispose_all(self) -> None: logger.info("No disposables to dispose.") -# endregion Agent Base Class - - -# ----------------------------------------------------------------------------- -# region LLMAgent Base Class (Generic LLM Agent) -# ----------------------------------------------------------------------------- class LLMAgent(Agent): """Generic LLM agent containing common logic for LLM-based agents. @@ -689,12 +680,6 @@ def dispose_all(self) -> None: self.response_subject.on_completed() -# endregion LLMAgent Base Class (Generic LLM Agent) - - -# ----------------------------------------------------------------------------- -# region OpenAIAgent Subclass (OpenAI-Specific Implementation) -# ----------------------------------------------------------------------------- class OpenAIAgent(LLMAgent): """OpenAI agent implementation that uses OpenAI's API for processing. @@ -914,4 +899,3 @@ def stream_query(self, query_text: str) -> Observable: # type: ignore[type-arg] ) -# endregion OpenAIAgent Subclass (OpenAI-Specific Implementation) diff --git a/dimos/agents_deprecated/prompt_builder/impl.py b/dimos/agents_deprecated/prompt_builder/impl.py index 35c864062a..354057464f 100644 --- a/dimos/agents_deprecated/prompt_builder/impl.py +++ b/dimos/agents_deprecated/prompt_builder/impl.py @@ -148,7 +148,6 @@ def build( # type: ignore[no-untyped-def] # print("system_prompt: ", system_prompt) # print("rag_context: ", rag_context) - # region Token Counts if not override_token_limit: rag_token_cnt = self.tokenizer.token_count(rag_context) system_prompt_token_cnt = self.tokenizer.token_count(system_prompt) @@ -163,7 +162,6 @@ def build( # type: ignore[no-untyped-def] system_prompt_token_cnt = 0 user_query_token_cnt = 0 image_token_cnt = 0 - # endregion Token Counts # Create a component dictionary for dynamic allocation components = { diff --git a/dimos/control/blueprints.py b/dimos/control/blueprints.py index 0384c69160..7c6036b20c 100644 --- a/dimos/control/blueprints.py +++ b/dimos/control/blueprints.py @@ -49,10 +49,6 @@ _XARM7_MODEL_PATH = LfsPath("xarm_description/urdf/xarm7/xarm7.urdf") -# ============================================================================= -# Single Arm Blueprints -# ============================================================================= - # Mock 7-DOF arm (for testing) coordinator_mock = control_coordinator( tick_rate=100.0, @@ -168,10 +164,6 @@ ) -# ============================================================================= -# Dual Arm Blueprints -# ============================================================================= - # Dual mock arms (7-DOF left, 6-DOF right) coordinator_dual_mock = control_coordinator( tick_rate=100.0, @@ -298,10 +290,6 @@ ) -# ============================================================================= -# Streaming Control Blueprints -# ============================================================================= - # XArm6 teleop - streaming position control coordinator_teleop_xarm6 = control_coordinator( tick_rate=100.0, @@ -399,11 +387,6 @@ ) -# ============================================================================= -# Cartesian IK Blueprints (internal Pinocchio IK solver) -# ============================================================================= - - # Mock 6-DOF arm with CartesianIK coordinator_cartesian_ik_mock = control_coordinator( tick_rate=100.0, @@ -471,10 +454,6 @@ ) -# ============================================================================= -# Teleop IK Blueprints (VR teleoperation with internal Pinocchio IK) -# ============================================================================= - # Single XArm7 with TeleopIK coordinator_teleop_xarm7 = control_coordinator( tick_rate=100.0, @@ -605,10 +584,6 @@ ) -# ============================================================================= -# Twist Base Blueprints (velocity-commanded platforms) -# ============================================================================= - # Mock holonomic twist base (3-DOF: vx, vy, wz) _base_joints = make_twist_base_joints("base") coordinator_mock_twist_base = control_coordinator( @@ -636,10 +611,6 @@ ) -# ============================================================================= -# Mobile Manipulation Blueprints (arm + twist base) -# ============================================================================= - # Mock arm (7-DOF) + mock holonomic base (3-DOF) _mm_base_joints = make_twist_base_joints("base") coordinator_mobile_manip_mock = control_coordinator( @@ -679,10 +650,6 @@ ) -# ============================================================================= -# Raw Blueprints (for programmatic setup) -# ============================================================================= - coordinator_basic = control_coordinator( tick_rate=100.0, publish_joint_state=True, @@ -694,10 +661,6 @@ ) -# ============================================================================= -# Exports -# ============================================================================= - __all__ = [ # Raw "coordinator_basic", diff --git a/dimos/control/coordinator.py b/dimos/control/coordinator.py index 73e036e873..16f4e53f46 100644 --- a/dimos/control/coordinator.py +++ b/dimos/control/coordinator.py @@ -68,11 +68,6 @@ logger = setup_logger() -# ============================================================================= -# Configuration -# ============================================================================= - - @dataclass class TaskConfig: """Configuration for a control task. @@ -124,11 +119,6 @@ class ControlCoordinatorConfig(ModuleConfig): tasks: list[TaskConfig] = field(default_factory=lambda: []) -# ============================================================================= -# ControlCoordinator Module -# ============================================================================= - - class ControlCoordinator(Module[ControlCoordinatorConfig]): """Centralized control coordinator with per-joint arbitration. @@ -201,10 +191,6 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: logger.info(f"ControlCoordinator initialized at {self.config.tick_rate}Hz") - # ========================================================================= - # Config-based Setup - # ========================================================================= - def _setup_from_config(self) -> None: """Create hardware and tasks from config (called on start).""" hardware_added: list[str] = [] @@ -343,10 +329,6 @@ def _create_task_from_config(self, cfg: TaskConfig) -> ControlTask: else: raise ValueError(f"Unknown task type: {task_type}") - # ========================================================================= - # Hardware Management (RPC) - # ========================================================================= - @rpc def add_hardware( self, @@ -446,10 +428,6 @@ def get_joint_positions(self) -> dict[str, float]: positions[joint_name] = joint_state.position return positions - # ========================================================================= - # Task Management (RPC) - # ========================================================================= - @rpc def add_task(self, task: ControlTask) -> bool: """Register a task with the coordinator.""" @@ -492,10 +470,6 @@ def get_active_tasks(self) -> list[str]: with self._task_lock: return [name for name, task in self._tasks.items() if task.is_active()] - # ========================================================================= - # Streaming Control - # ========================================================================= - def _on_joint_command(self, msg: JointState) -> None: """Route incoming JointState to streaming tasks by joint name. @@ -603,10 +577,6 @@ def task_invoke( return getattr(task, method)(**kwargs) - # ========================================================================= - # Gripper - # ========================================================================= - @rpc def set_gripper_position(self, hardware_id: str, position: float) -> bool: """Set gripper position on a specific hardware device. @@ -640,10 +610,6 @@ def get_gripper_position(self, hardware_id: str) -> float | None: return None return hw.adapter.read_gripper_position() - # ========================================================================= - # Lifecycle - # ========================================================================= - @rpc def start(self) -> None: """Start the coordinator control loop.""" diff --git a/dimos/control/task.py b/dimos/control/task.py index ecdf9ab7f4..c9ef03fbf0 100644 --- a/dimos/control/task.py +++ b/dimos/control/task.py @@ -37,10 +37,6 @@ from dimos.msgs.geometry_msgs import Pose, PoseStamped from dimos.teleop.quest.quest_types import Buttons -# ============================================================================= -# Data Types -# ============================================================================= - @dataclass(frozen=True) class ResourceClaim: @@ -168,11 +164,6 @@ def get_values(self) -> list[float] | None: return None -# ============================================================================= -# ControlTask Protocol -# ============================================================================= - - @runtime_checkable class ControlTask(Protocol): """Protocol for passive tasks that run within the coordinator. diff --git a/dimos/control/tasks/cartesian_ik_task.py b/dimos/control/tasks/cartesian_ik_task.py index 6ea5ddc55b..67d4e4ed52 100644 --- a/dimos/control/tasks/cartesian_ik_task.py +++ b/dimos/control/tasks/cartesian_ik_task.py @@ -255,10 +255,6 @@ def on_preempted(self, by_task: str, joints: frozenset[str]) -> None: f"CartesianIKTask {self._name} preempted by {by_task} on joints {joints}" ) - # ========================================================================= - # Task-specific methods - # ========================================================================= - def on_cartesian_command(self, pose: Pose | PoseStamped, t_now: float) -> bool: """Handle incoming cartesian command (target EE pose). diff --git a/dimos/control/tasks/servo_task.py b/dimos/control/tasks/servo_task.py index b69b4dd099..50805bfa2c 100644 --- a/dimos/control/tasks/servo_task.py +++ b/dimos/control/tasks/servo_task.py @@ -159,10 +159,6 @@ def on_preempted(self, by_task: str, joints: frozenset[str]) -> None: if joints & self._joint_names: logger.warning(f"JointServoTask {self._name} preempted by {by_task} on joints {joints}") - # ========================================================================= - # Task-specific methods - # ========================================================================= - def set_target(self, positions: list[float], t_now: float) -> bool: """Set target joint positions. diff --git a/dimos/control/tasks/teleop_task.py b/dimos/control/tasks/teleop_task.py index ce63dc4006..115b455fe6 100644 --- a/dimos/control/tasks/teleop_task.py +++ b/dimos/control/tasks/teleop_task.py @@ -295,10 +295,6 @@ def on_preempted(self, by_task: str, joints: frozenset[str]) -> None: if joints & self._joint_names: logger.warning(f"TeleopIKTask {self._name} preempted by {by_task} on joints {joints}") - # ========================================================================= - # Task-specific methods - # ========================================================================= - def on_buttons(self, msg: Buttons) -> bool: """Press-and-hold engage: hold primary button to track, release to stop.""" is_left = self._config.hand == "left" diff --git a/dimos/control/tasks/trajectory_task.py b/dimos/control/tasks/trajectory_task.py index 4d2eaa188b..16a271018a 100644 --- a/dimos/control/tasks/trajectory_task.py +++ b/dimos/control/tasks/trajectory_task.py @@ -171,10 +171,6 @@ def on_preempted(self, by_task: str, joints: frozenset[str]) -> None: if joints & self._joint_names: self._state = TrajectoryState.ABORTED - # ========================================================================= - # Task-specific methods - # ========================================================================= - def execute(self, trajectory: JointTrajectory) -> bool: """Start executing a trajectory. diff --git a/dimos/control/tasks/velocity_task.py b/dimos/control/tasks/velocity_task.py index 163bc09827..5da475114d 100644 --- a/dimos/control/tasks/velocity_task.py +++ b/dimos/control/tasks/velocity_task.py @@ -191,10 +191,6 @@ def on_preempted(self, by_task: str, joints: frozenset[str]) -> None: f"JointVelocityTask {self._name} preempted by {by_task} on joints {joints}" ) - # ========================================================================= - # Task-specific methods - # ========================================================================= - def set_velocities(self, velocities: list[float], t_now: float) -> bool: """Set target joint velocities. diff --git a/dimos/control/test_control.py b/dimos/control/test_control.py index 656678d167..a4b7e0a5bc 100644 --- a/dimos/control/test_control.py +++ b/dimos/control/test_control.py @@ -40,10 +40,6 @@ from dimos.hardware.manipulators.spec import ManipulatorAdapter from dimos.msgs.trajectory_msgs import JointTrajectory, TrajectoryPoint -# ============================================================================= -# Fixtures -# ============================================================================= - @pytest.fixture def mock_adapter(): @@ -112,11 +108,6 @@ def coordinator_state(): return CoordinatorState(joints=joints, t_now=time.perf_counter(), dt=0.01) -# ============================================================================= -# Test JointCommandOutput -# ============================================================================= - - class TestJointCommandOutput: def test_position_output(self): output = JointCommandOutput( @@ -153,11 +144,6 @@ def test_no_values_returns_none(self): assert output.get_values() is None -# ============================================================================= -# Test JointStateSnapshot -# ============================================================================= - - class TestJointStateSnapshot: def test_get_position(self): snapshot = JointStateSnapshot( @@ -171,11 +157,6 @@ def test_get_position(self): assert snapshot.get_position("nonexistent") is None -# ============================================================================= -# Test ConnectedHardware -# ============================================================================= - - class TestConnectedHardware: def test_joint_names_prefixed(self, connected_hardware): names = connected_hardware.joint_names @@ -206,11 +187,6 @@ def test_write_command(self, connected_hardware, mock_adapter): mock_adapter.write_joint_positions.assert_called() -# ============================================================================= -# Test JointTrajectoryTask -# ============================================================================= - - class TestJointTrajectoryTask: def test_initial_state(self, trajectory_task): assert trajectory_task.name == "test_traj" @@ -314,11 +290,6 @@ def test_progress(self, trajectory_task, simple_trajectory, coordinator_state): assert trajectory_task.get_progress(t_start + 1.0) == pytest.approx(1.0, abs=0.01) -# ============================================================================= -# Test Arbitration Logic -# ============================================================================= - - class TestArbitration: def test_single_task_wins(self): outputs = [ @@ -422,11 +393,6 @@ def test_non_overlapping_joints(self): assert winners["j4"][3] == "task2" -# ============================================================================= -# Test TickLoop -# ============================================================================= - - class TestTickLoop: def test_tick_loop_starts_and_stops(self, mock_adapter): component = HardwareComponent( @@ -498,11 +464,6 @@ def test_tick_loop_calls_compute(self, mock_adapter): assert mock_task.compute.call_count > 0 -# ============================================================================= -# Integration Test -# ============================================================================= - - class TestIntegration: def test_full_trajectory_execution(self, mock_adapter): component = HardwareComponent( diff --git a/dimos/control/tick_loop.py b/dimos/control/tick_loop.py index e0020a34da..e45a17030b 100644 --- a/dimos/control/tick_loop.py +++ b/dimos/control/tick_loop.py @@ -172,26 +172,19 @@ def _tick(self) -> None: self._last_tick_time = t_now self._tick_count += 1 - # === PHASE 1: READ ALL HARDWARE === joint_states = self._read_all_hardware() state = CoordinatorState(joints=joint_states, t_now=t_now, dt=dt) - # === PHASE 2: COMPUTE ALL ACTIVE TASKS === commands = self._compute_all_tasks(state) - # === PHASE 3: ARBITRATE (with mode validation) === joint_commands, preemptions = self._arbitrate(commands) - # === PHASE 4: NOTIFY PREEMPTIONS (once per task) === self._notify_preemptions(preemptions) - # === PHASE 5: ROUTE TO HARDWARE === hw_commands = self._route_to_hardware(joint_commands) - # === PHASE 6: WRITE TO HARDWARE === self._write_all_hardware(hw_commands) - # === PHASE 7: PUBLISH AGGREGATED STATE === if self._publish_callback: self._publish_joint_state(joint_states) diff --git a/dimos/core/daemon.py b/dimos/core/daemon.py index f4a19c9403..61060b2a73 100644 --- a/dimos/core/daemon.py +++ b/dimos/core/daemon.py @@ -31,10 +31,6 @@ logger = setup_logger() -# --------------------------------------------------------------------------- -# Health check (delegates to ModuleCoordinator.health_check) -# --------------------------------------------------------------------------- - def health_check(coordinator: ModuleCoordinator) -> bool: """Verify all coordinator workers are alive after build. @@ -45,11 +41,6 @@ def health_check(coordinator: ModuleCoordinator) -> bool: return coordinator.health_check() -# --------------------------------------------------------------------------- -# Daemonize (double-fork) -# --------------------------------------------------------------------------- - - def daemonize(log_dir: Path) -> None: """Double-fork daemonize the current process. @@ -83,11 +74,6 @@ def daemonize(log_dir: Path) -> None: devnull.close() -# --------------------------------------------------------------------------- -# Signal handler for clean shutdown -# --------------------------------------------------------------------------- - - def install_signal_handlers(entry: RunEntry, coordinator: ModuleCoordinator) -> None: """Install SIGTERM/SIGINT handlers that stop the coordinator and clean the registry.""" diff --git a/dimos/core/test_cli_stop_status.py b/dimos/core/test_cli_stop_status.py index c04d8d2499..5c628f6d92 100644 --- a/dimos/core/test_cli_stop_status.py +++ b/dimos/core/test_cli_stop_status.py @@ -72,11 +72,6 @@ def _entry(run_id: str, pid: int, blueprint: str = "test", **kwargs) -> RunEntry return e -# --------------------------------------------------------------------------- -# STATUS -# --------------------------------------------------------------------------- - - class TestStatusCLI: """Tests for `dimos status` command.""" @@ -132,11 +127,6 @@ def test_status_filters_dead_pids(self): assert "No running" in result.output -# --------------------------------------------------------------------------- -# STOP -# --------------------------------------------------------------------------- - - class TestStopCLI: """Tests for `dimos stop` command.""" diff --git a/dimos/core/test_daemon.py b/dimos/core/test_daemon.py index bd7c6b9ad8..f6dae51433 100644 --- a/dimos/core/test_daemon.py +++ b/dimos/core/test_daemon.py @@ -24,9 +24,6 @@ import pytest -# --------------------------------------------------------------------------- -# Registry tests -# --------------------------------------------------------------------------- from dimos.core import run_registry from dimos.core.run_registry import ( RunEntry, @@ -158,10 +155,6 @@ def test_port_conflict_no_false_positive(self, tmp_registry: Path): assert conflict is None -# --------------------------------------------------------------------------- -# Health check tests -# --------------------------------------------------------------------------- - from dimos.core.module_coordinator import ModuleCoordinator @@ -212,10 +205,6 @@ def test_partial_death(self): assert coord.health_check() is False -# --------------------------------------------------------------------------- -# Daemon tests -# --------------------------------------------------------------------------- - from dimos.core.daemon import daemonize, install_signal_handlers @@ -275,11 +264,6 @@ def test_signal_handler_tolerates_stop_error(self, tmp_registry: Path): assert not entry.registry_path.exists() -# --------------------------------------------------------------------------- -# dimos status tests -# --------------------------------------------------------------------------- - - class TestStatusCommand: """Tests for `dimos status` CLI command.""" @@ -327,11 +311,6 @@ def test_status_filters_dead(self, tmp_path, monkeypatch): assert len(entries) == 0 -# --------------------------------------------------------------------------- -# dimos stop tests -# --------------------------------------------------------------------------- - - class TestStopCommand: """Tests for `dimos stop` CLI command.""" diff --git a/dimos/core/test_e2e_daemon.py b/dimos/core/test_e2e_daemon.py index 7043d0384e..d8ac016faa 100644 --- a/dimos/core/test_e2e_daemon.py +++ b/dimos/core/test_e2e_daemon.py @@ -35,10 +35,6 @@ from dimos.core.stream import Out from dimos.robot.cli.dimos import main -# --------------------------------------------------------------------------- -# Lightweight test modules -# --------------------------------------------------------------------------- - class PingModule(Module): data: Out[str] @@ -54,11 +50,6 @@ def start(self): super().start() -# --------------------------------------------------------------------------- -# Fixtures -# --------------------------------------------------------------------------- - - @pytest.fixture(autouse=True) def _ci_env(monkeypatch): """Set CI=1 to skip sysctl interactive prompt — scoped per test, not module.""" @@ -114,11 +105,6 @@ def registry_entry(): entry.remove() -# --------------------------------------------------------------------------- -# Tests -# --------------------------------------------------------------------------- - - @pytest.mark.slow class TestDaemonE2E: """End-to-end daemon lifecycle with real workers.""" @@ -216,11 +202,6 @@ def test_stale_cleanup(self, coordinator, registry_entry): assert remaining[0].run_id == registry_entry.run_id -# --------------------------------------------------------------------------- -# E2E: CLI status + stop against real running blueprint -# --------------------------------------------------------------------------- - - @pytest.fixture() def live_blueprint(): """Build PingPong and register. Yields (coord, entry). Cleans up on teardown.""" diff --git a/dimos/core/test_mcp_integration.py b/dimos/core/test_mcp_integration.py index 543b9a7fbd..d7527e31f8 100644 --- a/dimos/core/test_mcp_integration.py +++ b/dimos/core/test_mcp_integration.py @@ -55,11 +55,6 @@ MCP_URL = f"http://localhost:{global_config.mcp_port}/mcp" -# --------------------------------------------------------------------------- -# Fixtures -# --------------------------------------------------------------------------- - - @pytest.fixture(autouse=True) def _ci_env(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("CI", "1") @@ -121,11 +116,6 @@ def _adapter() -> McpAdapter: return McpAdapter() -# --------------------------------------------------------------------------- -# Tests -- read-only against a shared MCP server -# --------------------------------------------------------------------------- - - @pytest.mark.slow class TestMCPLifecycle: """MCP server lifecycle: start -> respond -> stop -> dead.""" @@ -323,11 +313,6 @@ def test_agent_send_cli(self, mcp_shared: ModuleCoordinator) -> None: assert "hello from CLI" in result.output -# --------------------------------------------------------------------------- -# Tests -- lifecycle management (own setup/teardown per test) -# --------------------------------------------------------------------------- - - @pytest.mark.slow class TestDaemonMCPRecovery: """Test MCP recovery after daemon crashes and restarts.""" diff --git a/dimos/core/tests/demo_devex.py b/dimos/core/tests/demo_devex.py index b9ac1393d7..243c870fab 100644 --- a/dimos/core/tests/demo_devex.py +++ b/dimos/core/tests/demo_devex.py @@ -98,9 +98,6 @@ def main() -> None: print(" Simulating: OpenClaw agent using DimOS") print("=" * 60) - # --------------------------------------------------------------- - # Step 1: dimos run stress-test --daemon - # --------------------------------------------------------------- section("Step 1: dimos run stress-test --daemon") result = run_dimos("run", "stress-test", "--daemon", timeout=60) print(f" stdout: {result.stdout.strip()[:200]}") @@ -131,9 +128,6 @@ def main() -> None: print(" Cannot continue without MCP. Exiting.") sys.exit(1) - # --------------------------------------------------------------- - # Step 2: dimos status - # --------------------------------------------------------------- section("Step 2: dimos status") result = run_dimos("status") print(f" output: {result.stdout.strip()[:300]}") @@ -145,9 +139,6 @@ def main() -> None: p(f"Status unclear (exit={result.returncode})", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 3: dimos mcp list-tools - # --------------------------------------------------------------- section("Step 3: dimos mcp list-tools") result = run_dimos("mcp", "list-tools") if result.returncode == 0: @@ -167,9 +158,6 @@ def main() -> None: p(f"list-tools failed (exit={result.returncode}): {result.stdout[:100]}", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 4: dimos mcp call echo --arg message=hello - # --------------------------------------------------------------- section("Step 4: dimos mcp call echo --arg message=hello") result = run_dimos("mcp", "call", "echo", "--arg", "message=hello-from-devex-test") if result.returncode == 0 and "hello-from-devex-test" in result.stdout: @@ -178,9 +166,6 @@ def main() -> None: p(f"echo call failed (exit={result.returncode}): {result.stdout[:100]}", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 5: dimos mcp status - # --------------------------------------------------------------- section("Step 5: dimos mcp status") result = run_dimos("mcp", "status") if result.returncode == 0: @@ -196,9 +181,6 @@ def main() -> None: p(f"mcp status failed (exit={result.returncode})", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 6: dimos mcp modules - # --------------------------------------------------------------- section("Step 6: dimos mcp modules") result = run_dimos("mcp", "modules") if result.returncode == 0: @@ -213,9 +195,6 @@ def main() -> None: p(f"mcp modules failed (exit={result.returncode})", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 7: dimos agent-send "hello" - # --------------------------------------------------------------- section("Step 7: dimos agent-send 'what tools do you have?'") result = run_dimos("agent-send", "what tools do you have?") if result.returncode == 0: @@ -224,9 +203,6 @@ def main() -> None: p(f"agent-send failed (exit={result.returncode}): {result.stdout[:100]}", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 8: Check logs - # --------------------------------------------------------------- section("Step 8: Check per-run logs") log_base = os.path.expanduser("~/.local/state/dimos/logs") if os.path.isdir(log_base): @@ -257,9 +233,6 @@ def main() -> None: p(f"Log base dir not found: {log_base}", ok=False) failures += 1 - # --------------------------------------------------------------- - # Step 9: dimos stop - # --------------------------------------------------------------- section("Step 9: dimos stop") result = run_dimos("stop") print(f" output: {result.stdout.strip()[:200]}") @@ -272,9 +245,6 @@ def main() -> None: # Wait for shutdown time.sleep(2) - # --------------------------------------------------------------- - # Step 10: dimos status (verify stopped) - # --------------------------------------------------------------- section("Step 10: dimos status (verify stopped)") result = run_dimos("status") print(f" output: {result.stdout.strip()[:200]}") @@ -288,9 +258,6 @@ def main() -> None: p(f"Unexpected status after stop (exit={result.returncode})", ok=False) failures += 1 - # --------------------------------------------------------------- - # Summary - # --------------------------------------------------------------- print("\n" + "=" * 60) if failures == 0: print(" \u2705 FULL DEVELOPER EXPERIENCE TEST PASSED") diff --git a/dimos/hardware/drive_trains/flowbase/adapter.py b/dimos/hardware/drive_trains/flowbase/adapter.py index 5b5563792d..ec96365c78 100644 --- a/dimos/hardware/drive_trains/flowbase/adapter.py +++ b/dimos/hardware/drive_trains/flowbase/adapter.py @@ -62,10 +62,6 @@ def __init__(self, dof: int = 3, address: str | None = None, **_: object) -> Non # Last commanded velocities (in standard frame, before negation) self._last_velocities = [0.0, 0.0, 0.0] - # ========================================================================= - # Connection - # ========================================================================= - def connect(self) -> bool: """Connect to FlowBase controller via Portal RPC.""" try: @@ -98,18 +94,10 @@ def is_connected(self) -> bool: """Check if connected to FlowBase.""" return self._connected - # ========================================================================= - # Info - # ========================================================================= - def get_dof(self) -> int: """FlowBase is always 3 DOF (vx, vy, wz).""" return 3 - # ========================================================================= - # State Reading - # ========================================================================= - def read_velocities(self) -> list[float]: """Return last commanded velocities (FlowBase doesn't report actual).""" with self._lock: @@ -134,10 +122,6 @@ def read_odometry(self) -> list[float] | None: logger.error(f"Error reading FlowBase odometry: {e}") return None - # ========================================================================= - # Control - # ========================================================================= - def write_velocities(self, velocities: list[float]) -> bool: """Send velocity command to FlowBase. @@ -165,10 +149,6 @@ def write_stop(self) -> bool: return False return self._send_velocity(0.0, 0.0, 0.0) - # ========================================================================= - # Enable/Disable - # ========================================================================= - def write_enable(self, enable: bool) -> bool: """Enable/disable the platform (FlowBase is always enabled when connected).""" self._enabled = enable @@ -178,10 +158,6 @@ def read_enabled(self) -> bool: """Check if platform is enabled.""" return self._enabled - # ========================================================================= - # Internal - # ========================================================================= - def _send_velocity(self, vx: float, vy: float, wz: float) -> bool: """Send raw velocity to FlowBase via Portal RPC.""" try: diff --git a/dimos/hardware/drive_trains/mock/adapter.py b/dimos/hardware/drive_trains/mock/adapter.py index 2091ec59d0..d6131305e6 100644 --- a/dimos/hardware/drive_trains/mock/adapter.py +++ b/dimos/hardware/drive_trains/mock/adapter.py @@ -48,10 +48,6 @@ def __init__(self, dof: int = 3, **_: object) -> None: self._enabled = False self._connected = False - # ========================================================================= - # Connection - # ========================================================================= - def connect(self) -> bool: """Simulate connection.""" self._connected = True @@ -65,18 +61,10 @@ def is_connected(self) -> bool: """Check mock connection status.""" return self._connected - # ========================================================================= - # Info - # ========================================================================= - def get_dof(self) -> int: """Return DOF.""" return self._dof - # ========================================================================= - # State Reading - # ========================================================================= - def read_velocities(self) -> list[float]: """Return mock velocities.""" return self._velocities.copy() @@ -87,10 +75,6 @@ def read_odometry(self) -> list[float] | None: return None return self._odometry.copy() - # ========================================================================= - # Control - # ========================================================================= - def write_velocities(self, velocities: list[float]) -> bool: """Set mock velocities.""" if len(velocities) != self._dof: @@ -103,10 +87,6 @@ def write_stop(self) -> bool: self._velocities = [0.0] * self._dof return True - # ========================================================================= - # Enable/Disable - # ========================================================================= - def write_enable(self, enable: bool) -> bool: """Enable/disable mock platform.""" self._enabled = enable @@ -116,10 +96,6 @@ def read_enabled(self) -> bool: """Check mock enable state.""" return self._enabled - # ========================================================================= - # Test Helpers (not part of Protocol) - # ========================================================================= - def set_odometry(self, odometry: list[float] | None) -> None: """Set odometry directly for testing.""" self._odometry = list(odometry) if odometry is not None else None diff --git a/dimos/hardware/drive_trains/spec.py b/dimos/hardware/drive_trains/spec.py index 0b288edfd4..1380ef1fa9 100644 --- a/dimos/hardware/drive_trains/spec.py +++ b/dimos/hardware/drive_trains/spec.py @@ -35,8 +35,6 @@ class TwistBaseAdapter(Protocol): - Angle: radians """ - # --- Connection --- - def connect(self) -> bool: """Connect to hardware. Returns True on success.""" ... @@ -49,14 +47,10 @@ def is_connected(self) -> bool: """Check if connected.""" ... - # --- Info --- - def get_dof(self) -> int: """Get number of velocity DOFs (e.g., 3 for holonomic, 2 for differential).""" ... - # --- State Reading --- - def read_velocities(self) -> list[float]: """Read current velocities in virtual joint order (m/s or rad/s).""" ... @@ -69,8 +63,6 @@ def read_odometry(self) -> list[float] | None: """ ... - # --- Control --- - def write_velocities(self, velocities: list[float]) -> bool: """Command velocities in virtual joint order. Returns success.""" ... @@ -79,8 +71,6 @@ def write_stop(self) -> bool: """Stop all motion immediately (zero velocities).""" ... - # --- Enable/Disable --- - def write_enable(self, enable: bool) -> bool: """Enable or disable the platform. Returns success.""" ... diff --git a/dimos/hardware/manipulators/mock/adapter.py b/dimos/hardware/manipulators/mock/adapter.py index ff299669f7..53c53c722d 100644 --- a/dimos/hardware/manipulators/mock/adapter.py +++ b/dimos/hardware/manipulators/mock/adapter.py @@ -66,10 +66,6 @@ def __init__(self, dof: int = 6, **_: object) -> None: self._error_code: int = 0 self._error_message: str = "" - # ========================================================================= - # Connection - # ========================================================================= - def connect(self) -> bool: """Simulate connection.""" self._connected = True @@ -83,10 +79,6 @@ def is_connected(self) -> bool: """Check mock connection status.""" return self._connected - # ========================================================================= - # Info - # ========================================================================= - def get_info(self) -> ManipulatorInfo: """Return mock info.""" return ManipulatorInfo( @@ -109,10 +101,6 @@ def get_limits(self) -> JointLimits: velocity_max=[1.0] * self._dof, ) - # ========================================================================= - # Control Mode - # ========================================================================= - def set_control_mode(self, mode: ControlMode) -> bool: """Set mock control mode.""" self._control_mode = mode @@ -122,10 +110,6 @@ def get_control_mode(self) -> ControlMode: """Get mock control mode.""" return self._control_mode - # ========================================================================= - # State Reading - # ========================================================================= - def read_joint_positions(self) -> list[float]: """Return mock joint positions.""" return self._positions.copy() @@ -151,10 +135,6 @@ def read_error(self) -> tuple[int, str]: """Return mock error.""" return self._error_code, self._error_message - # ========================================================================= - # Motion Control - # ========================================================================= - def write_joint_positions( self, positions: list[float], @@ -178,10 +158,6 @@ def write_stop(self) -> bool: self._velocities = [0.0] * self._dof return True - # ========================================================================= - # Servo Control - # ========================================================================= - def write_enable(self, enable: bool) -> bool: """Enable/disable mock servos.""" self._enabled = enable @@ -197,10 +173,6 @@ def write_clear_errors(self) -> bool: self._error_message = "" return True - # ========================================================================= - # Cartesian Control (Optional) - # ========================================================================= - def read_cartesian_position(self) -> dict[str, float] | None: """Return mock cartesian position.""" return self._cartesian_position.copy() @@ -214,10 +186,6 @@ def write_cartesian_position( self._cartesian_position.update(pose) return True - # ========================================================================= - # Gripper (Optional) - # ========================================================================= - def read_gripper_position(self) -> float | None: """Return mock gripper position.""" return self._gripper_position @@ -227,18 +195,10 @@ def write_gripper_position(self, position: float) -> bool: self._gripper_position = position return True - # ========================================================================= - # Force/Torque (Optional) - # ========================================================================= - def read_force_torque(self) -> list[float] | None: """Return mock F/T sensor data (not supported in mock).""" return None - # ========================================================================= - # Test Helpers (not part of Protocol) - # ========================================================================= - def set_error(self, code: int, message: str) -> None: """Inject an error for testing error handling.""" self._error_code = code diff --git a/dimos/hardware/manipulators/piper/adapter.py b/dimos/hardware/manipulators/piper/adapter.py index 68b5769a95..49ed68bcf9 100644 --- a/dimos/hardware/manipulators/piper/adapter.py +++ b/dimos/hardware/manipulators/piper/adapter.py @@ -75,10 +75,6 @@ def __init__( self._enabled: bool = False self._control_mode: ControlMode = ControlMode.POSITION - # ========================================================================= - # Connection - # ========================================================================= - def connect(self) -> bool: """Connect to Piper via CAN bus.""" try: @@ -139,10 +135,6 @@ def is_connected(self) -> bool: except Exception: return False - # ========================================================================= - # Info - # ========================================================================= - def get_info(self) -> ManipulatorInfo: """Get Piper information.""" firmware_version = None @@ -176,10 +168,6 @@ def get_limits(self) -> JointLimits: velocity_max=max_vel, ) - # ========================================================================= - # Control Mode - # ========================================================================= - def set_control_mode(self, mode: ControlMode) -> bool: """Set Piper control mode via MotionCtrl_2.""" if not self._sdk: @@ -207,10 +195,6 @@ def get_control_mode(self) -> ControlMode: """Get current control mode.""" return self._control_mode - # ========================================================================= - # State Reading - # ========================================================================= - def read_joint_positions(self) -> list[float]: """Read joint positions (Piper units -> radians).""" if not self._sdk: @@ -295,10 +279,6 @@ def read_error(self) -> tuple[int, str]: return 0, "" - # ========================================================================= - # Motion Control (Joint Space) - # ========================================================================= - def write_joint_positions( self, positions: list[float], @@ -366,10 +346,6 @@ def write_stop(self) -> bool: # Fallback: disable arm return self.write_enable(False) - # ========================================================================= - # Servo Control - # ========================================================================= - def write_enable(self, enable: bool) -> bool: """Enable or disable servos.""" if not self._sdk: @@ -427,10 +403,6 @@ def write_clear_errors(self) -> bool: time.sleep(0.1) return self.write_enable(True) - # ========================================================================= - # Cartesian Control (Optional) - # ========================================================================= - def read_cartesian_position(self) -> dict[str, float] | None: """Read end-effector pose. @@ -470,10 +442,6 @@ def write_cartesian_position( # Cartesian control not commonly supported in Piper SDK return False - # ========================================================================= - # Gripper (Optional) - # ========================================================================= - def read_gripper_position(self) -> float | None: """Read gripper position (percentage -> meters).""" if not self._sdk: @@ -508,10 +476,6 @@ def write_gripper_position(self, position: float) -> bool: return False - # ========================================================================= - # Force/Torque Sensor (Optional) - # ========================================================================= - def read_force_torque(self) -> list[float] | None: """Read F/T sensor data. diff --git a/dimos/hardware/manipulators/spec.py b/dimos/hardware/manipulators/spec.py index ff4d38c54f..ed63a21e82 100644 --- a/dimos/hardware/manipulators/spec.py +++ b/dimos/hardware/manipulators/spec.py @@ -28,10 +28,6 @@ from dimos.msgs.geometry_msgs import Quaternion, Transform, Vector3 -# ============================================================================ -# SHARED TYPES -# ============================================================================ - class DriverStatus(Enum): """Status returned by driver operations.""" @@ -83,11 +79,6 @@ def default_base_transform() -> Transform: ) -# ============================================================================ -# ADAPTER PROTOCOL -# ============================================================================ - - @runtime_checkable class ManipulatorAdapter(Protocol): """Protocol for hardware-specific IO. @@ -100,8 +91,6 @@ class ManipulatorAdapter(Protocol): - Force: Newtons """ - # --- Connection --- - def connect(self) -> bool: """Connect to hardware. Returns True on success.""" ... @@ -114,8 +103,6 @@ def is_connected(self) -> bool: """Check if connected.""" ... - # --- Info --- - def get_info(self) -> ManipulatorInfo: """Get manipulator info (vendor, model, DOF).""" ... @@ -128,8 +115,6 @@ def get_limits(self) -> JointLimits: """Get joint limits.""" ... - # --- Control Mode --- - def set_control_mode(self, mode: ControlMode) -> bool: """Set control mode (position, velocity, torque, cartesian, etc). @@ -152,8 +137,6 @@ def get_control_mode(self) -> ControlMode: """ ... - # --- State Reading --- - def read_joint_positions(self) -> list[float]: """Read current joint positions (radians).""" ... @@ -174,8 +157,6 @@ def read_error(self) -> tuple[int, str]: """Read error code and message. (0, '') means no error.""" ... - # --- Motion Control (Joint Space) --- - def write_joint_positions( self, positions: list[float], @@ -192,8 +173,6 @@ def write_stop(self) -> bool: """Stop all motion immediately.""" ... - # --- Servo Control --- - def write_enable(self, enable: bool) -> bool: """Enable or disable servos. Returns success.""" ... @@ -206,7 +185,6 @@ def write_clear_errors(self) -> bool: """Clear error state. Returns success.""" ... - # --- Optional: Cartesian Control --- # Return None/False if not supported def read_cartesian_position(self) -> dict[str, float] | None: @@ -234,8 +212,6 @@ def write_cartesian_position( """ ... - # --- Optional: Gripper --- - def read_gripper_position(self) -> float | None: """Read gripper position (meters). None if no gripper.""" ... @@ -244,8 +220,6 @@ def write_gripper_position(self, position: float) -> bool: """Command gripper position. False if no gripper.""" ... - # --- Optional: Force/Torque Sensor --- - def read_force_torque(self) -> list[float] | None: """Read F/T sensor [fx, fy, fz, tx, ty, tz]. None if no sensor.""" ... diff --git a/dimos/hardware/manipulators/xarm/adapter.py b/dimos/hardware/manipulators/xarm/adapter.py index 80cc8edb38..3e24c530d1 100644 --- a/dimos/hardware/manipulators/xarm/adapter.py +++ b/dimos/hardware/manipulators/xarm/adapter.py @@ -64,10 +64,6 @@ def __init__(self, address: str, dof: int = 6, **_: object) -> None: self._control_mode: ControlMode = ControlMode.POSITION self._gripper_enabled: bool = False - # ========================================================================= - # Connection - # ========================================================================= - def connect(self) -> bool: """Connect to XArm via TCP/IP.""" try: @@ -98,10 +94,6 @@ def is_connected(self) -> bool: """Check if connected to XArm.""" return self._arm is not None and self._arm.connected - # ========================================================================= - # Info - # ========================================================================= - def get_info(self) -> ManipulatorInfo: """Get XArm information.""" return ManipulatorInfo( @@ -124,10 +116,6 @@ def get_limits(self) -> JointLimits: velocity_max=[math.pi] * self._dof, # ~180 deg/s ) - # ========================================================================= - # Control Mode - # ========================================================================= - def set_control_mode(self, mode: ControlMode) -> bool: """Set XArm control mode. @@ -161,10 +149,6 @@ def get_control_mode(self) -> ControlMode: """Get current control mode.""" return self._control_mode - # ========================================================================= - # State Reading - # ========================================================================= - def read_joint_positions(self) -> list[float]: """Read joint positions (degrees -> radians).""" if not self._arm: @@ -214,10 +198,6 @@ def read_error(self) -> tuple[int, str]: return 0, "" return code, f"XArm error {code}" - # ========================================================================= - # Motion Control (Joint Space) - # ========================================================================= - def write_joint_positions( self, positions: list[float], @@ -263,10 +243,6 @@ def write_stop(self) -> bool: code: int = self._arm.emergency_stop() return code == 0 - # ========================================================================= - # Servo Control - # ========================================================================= - def write_enable(self, enable: bool) -> bool: """Enable or disable servos.""" if not self._arm: @@ -289,10 +265,6 @@ def write_clear_errors(self) -> bool: code: int = self._arm.clean_error() return code == 0 - # ========================================================================= - # Cartesian Control (Optional) - # ========================================================================= - def read_cartesian_position(self) -> dict[str, float] | None: """Read end-effector pose (mm -> meters, degrees -> radians).""" if not self._arm: @@ -331,10 +303,6 @@ def write_cartesian_position( ) return code == 0 - # ========================================================================= - # Gripper (Optional) - # ========================================================================= - def read_gripper_position(self) -> float | None: """Read gripper position (mm -> meters).""" if not self._arm: @@ -359,10 +327,6 @@ def write_gripper_position(self, position: float) -> bool: code: int = self._arm.set_gripper_position(pos_mm, wait=False) return code == 0 - # ========================================================================= - # Force/Torque Sensor (Optional) - # ========================================================================= - def read_force_torque(self) -> list[float] | None: """Read F/T sensor data if available.""" if not self._arm: diff --git a/dimos/manipulation/blueprints.py b/dimos/manipulation/blueprints.py index 97657b9cae..7a0eefb37a 100644 --- a/dimos/manipulation/blueprints.py +++ b/dimos/manipulation/blueprints.py @@ -45,10 +45,6 @@ from dimos.robot.foxglove_bridge import foxglove_bridge # TODO: migrate to rerun from dimos.utils.data import get_data -# ============================================================================= -# Pose Helpers -# ============================================================================= - def _make_base_pose( x: float = 0.0, @@ -70,11 +66,6 @@ def _make_base_pose( ) -# ============================================================================= -# URDF Helpers -# ============================================================================= - - def _get_xarm_urdf_path() -> Path: """Get path to xarm URDF.""" return get_data("xarm_description") / "urdf/xarm_device.urdf.xacro" @@ -133,11 +124,6 @@ def _get_piper_package_paths() -> dict[str, Path]: ] -# ============================================================================= -# Robot Configs -# ============================================================================= - - def _make_xarm6_config( name: str = "arm", y_offset: float = 0.0, @@ -283,11 +269,6 @@ def _make_piper_config( ) -# ============================================================================= -# Blueprints -# ============================================================================= - - # Single XArm6 planner (standalone, no coordinator) xarm6_planner_only = manipulation_module( robots=[_make_xarm6_config()], diff --git a/dimos/manipulation/control/coordinator_client.py b/dimos/manipulation/control/coordinator_client.py index 4e277fae97..cbaad28df2 100644 --- a/dimos/manipulation/control/coordinator_client.py +++ b/dimos/manipulation/control/coordinator_client.py @@ -98,10 +98,6 @@ def stop(self) -> None: """Stop the RPC client.""" self._rpc.stop_rpc_client() - # ========================================================================= - # Query methods (RPC calls) - # ========================================================================= - def list_hardware(self) -> list[str]: """List all hardware IDs.""" return self._rpc.list_hardware() or [] @@ -129,10 +125,6 @@ def get_trajectory_status(self, task_name: str) -> dict[str, Any]: return {"state": int(result), "task": task_name} return {} - # ========================================================================= - # Trajectory execution (via task_invoke) - # ========================================================================= - def execute_trajectory(self, task_name: str, trajectory: JointTrajectory) -> bool: """Execute a trajectory on a task via task_invoke.""" result = self._rpc.task_invoke(task_name, "execute", {"trajectory": trajectory}) @@ -143,10 +135,6 @@ def cancel_trajectory(self, task_name: str) -> bool: result = self._rpc.task_invoke(task_name, "cancel", {}) return bool(result) - # ========================================================================= - # Task selection and setup - # ========================================================================= - def select_task(self, task_name: str) -> bool: """ Select a task and setup its trajectory generator. @@ -248,11 +236,6 @@ def set_acceleration_limit(self, acceleration: float, task_name: str | None = No gen.set_limits(gen.max_velocity, acceleration) -# ============================================================================= -# Interactive CLI -# ============================================================================= - - def parse_joint_input(line: str, num_joints: int) -> list[float] | None: """Parse joint positions from user input (degrees by default, 'r' suffix for radians).""" parts = line.strip().split() diff --git a/dimos/manipulation/control/servo_control/cartesian_motion_controller.py b/dimos/manipulation/control/servo_control/cartesian_motion_controller.py index 7dd7e8c119..a12fb44a96 100644 --- a/dimos/manipulation/control/servo_control/cartesian_motion_controller.py +++ b/dimos/manipulation/control/servo_control/cartesian_motion_controller.py @@ -272,10 +272,6 @@ def stop(self) -> None: super().stop() logger.info("CartesianMotionController stopped") - # ========================================================================= - # RPC Methods - High-level control - # ========================================================================= - @rpc def set_target_pose( self, position: list[float], orientation: list[float], frame_id: str = "world" @@ -349,10 +345,6 @@ def is_converged(self) -> bool: and ori_error < self.config.orientation_tolerance ) - # ========================================================================= - # Private Methods - Callbacks - # ========================================================================= - def _on_joint_state(self, msg: JointState) -> None: """Callback when new joint state is received.""" logger.debug(f"Received joint_state: {len(msg.position)} joints") @@ -372,10 +364,6 @@ def _on_target_pose(self, msg: PoseStamped) -> None: self._is_tracking = True logger.debug(f"New target received: {msg}") - # ========================================================================= - # Private Methods - Control Loop - # ========================================================================= - def _control_loop(self) -> None: """ Main control loop running at control_frequency Hz. diff --git a/dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py b/dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py index ebc6f3f53c..ed62a7345e 100644 --- a/dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py +++ b/dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py @@ -153,10 +153,6 @@ def stop(self) -> None: super().stop() logger.info("JointTrajectoryController stopped") - # ========================================================================= - # RPC Methods - Action-server-like interface - # ========================================================================= - @rpc def execute_trajectory(self, trajectory: JointTrajectory) -> bool: """ @@ -270,10 +266,6 @@ def get_status(self) -> TrajectoryStatus: error=self._error_message, ) - # ========================================================================= - # Callbacks - # ========================================================================= - def _on_joint_state(self, msg: JointState) -> None: """Callback for joint state feedback.""" self._latest_joint_state = msg @@ -289,10 +281,6 @@ def _on_trajectory(self, msg: JointTrajectory) -> None: ) self.execute_trajectory(msg) - # ========================================================================= - # Execution Loop - # ========================================================================= - def _execution_loop(self) -> None: """ Main execution loop running at control_frequency Hz. diff --git a/dimos/manipulation/manipulation_interface.py b/dimos/manipulation/manipulation_interface.py index 524562520d..c60cbfd9c6 100644 --- a/dimos/manipulation/manipulation_interface.py +++ b/dimos/manipulation/manipulation_interface.py @@ -157,8 +157,6 @@ def update_task_result(self, task_id: str, result: dict[str, Any]) -> Manipulati return task return None - # === Perception stream methods === - def _setup_perception_subscription(self) -> None: """ Set up subscription to perception stream if available. @@ -239,8 +237,6 @@ def cleanup_perception_subscription(self) -> None: self.stream_subscription.dispose() self.stream_subscription = None - # === Utility methods === - def clear(self) -> None: """ Clear all manipulation tasks and agent constraints. diff --git a/dimos/manipulation/manipulation_module.py b/dimos/manipulation/manipulation_module.py index cab6c9f173..f064130965 100644 --- a/dimos/manipulation/manipulation_module.py +++ b/dimos/manipulation/manipulation_module.py @@ -278,10 +278,6 @@ def _tf_publish_loop(self) -> None: self._tf_stop_event.wait(period) - # ========================================================================= - # RPC Methods - # ========================================================================= - @rpc def get_state(self) -> str: """Get current manipulation state name.""" @@ -356,10 +352,6 @@ def is_collision_free(self, joints: list[float], robot_name: RobotName | None = return self._world_monitor.is_state_valid(robot_id, joint_state) return False - # ========================================================================= - # Plan/Preview/Execute Workflow RPC Methods - # ========================================================================= - def _begin_planning( self, robot_name: RobotName | None = None ) -> tuple[RobotName, WorldRobotID] | None: @@ -630,10 +622,6 @@ def set_init_joints_to_current(self, robot_name: RobotName | None = None) -> boo ) return True - # ========================================================================= - # Coordinator Integration RPC Methods - # ========================================================================= - def _get_coordinator_client(self) -> RPCClient | None: """Get or create coordinator RPC client (lazy init).""" if not any( @@ -780,10 +768,6 @@ def remove_obstacle(self, obstacle_id: str) -> bool: return False return self._world_monitor.remove_obstacle(obstacle_id) - # ========================================================================= - # Gripper Methods - # ========================================================================= - def _get_gripper_hardware_id(self, robot_name: RobotName | None = None) -> str | None: """Get gripper hardware ID for a robot.""" robot = self._get_robot(robot_name) @@ -856,10 +840,6 @@ def close_gripper(self, robot_name: str | None = None) -> str: return "Gripper closed" return "Error: Failed to close gripper" - # ========================================================================= - # Skill Helpers (internal) - # ========================================================================= - def _wait_for_trajectory_completion( self, robot_name: RobotName | None = None, timeout: float = 60.0, poll_interval: float = 0.2 ) -> bool: @@ -944,10 +924,6 @@ def _preview_execute_wait( return None - # ========================================================================= - # Short-Horizon Skills — Single-step actions - # ========================================================================= - @skill def get_robot_state(self, robot_name: str | None = None) -> str: """Get current robot state: joint positions, end-effector pose, and gripper. @@ -1132,10 +1108,6 @@ def go_init(self, robot_name: str | None = None) -> str: return "Reached init position" - # ========================================================================= - # Lifecycle - # ========================================================================= - @rpc def stop(self) -> None: """Stop the manipulation module.""" diff --git a/dimos/manipulation/pick_and_place_module.py b/dimos/manipulation/pick_and_place_module.py index 2016abeb4f..6d6ad1042e 100644 --- a/dimos/manipulation/pick_and_place_module.py +++ b/dimos/manipulation/pick_and_place_module.py @@ -102,10 +102,6 @@ def __init__(self, **kwargs: Any) -> None: # so pick/place use this stable snapshot instead. self._detection_snapshot: list[DetObject] = [] - # ========================================================================= - # Lifecycle (perception integration) - # ========================================================================= - @rpc def start(self) -> None: """Start the pick-and-place module (adds perception subscriptions).""" @@ -130,10 +126,6 @@ def _on_objects(self, objects: list[DetObject]) -> None: except Exception as e: logger.error(f"Exception in _on_objects: {e}") - # ========================================================================= - # Perception RPC Methods - # ========================================================================= - @rpc def refresh_obstacles(self, min_duration: float = 0.0) -> list[dict[str, Any]]: """Refresh perception obstacles. Returns the list of obstacles added. @@ -182,10 +174,6 @@ def list_added_obstacles(self) -> list[dict[str, Any]]: return [] return self._world_monitor.list_added_obstacles() - # ========================================================================= - # GraspGen - # ========================================================================= - def _get_graspgen(self) -> DockerRunner: """Get or create GraspGen Docker module (lazy init, thread-safe).""" # Fast path: already initialized (no lock needed for read) @@ -250,10 +238,6 @@ def generate_grasps( logger.error(f"Grasp generation failed: {e}") return None - # ========================================================================= - # Pick/Place Helpers - # ========================================================================= - def _compute_pre_grasp_pose(self, grasp_pose: Pose, offset: float = 0.10) -> Pose: """Compute a pre-grasp pose offset along the approach direction (local -Z). @@ -321,10 +305,6 @@ def _generate_grasps_for_pick( logger.info(f"Heuristic grasp for '{object_name}' at ({c.x:.3f}, {c.y:.3f}, {c.z:.3f})") return [grasp_pose] - # ========================================================================= - # Perception Skills - # ========================================================================= - @skill def get_scene_info(self, robot_name: str | None = None) -> str: """Get current robot state, detected objects, and scene information. @@ -410,10 +390,6 @@ def scan_objects(self, min_duration: float = 1.0, robot_name: str | None = None) return "\n".join(lines) - # ========================================================================= - # Long-Horizon Skills — Pick and Place - # ========================================================================= - @skill def pick( self, @@ -602,10 +578,6 @@ def pick_and_place( # Place phase return self.place(place_x, place_y, place_z, robot_name) - # ========================================================================= - # Lifecycle - # ========================================================================= - @rpc def stop(self) -> None: """Stop the pick-and-place module (cleanup GraspGen + delegate to base).""" diff --git a/dimos/manipulation/planning/kinematics/jacobian_ik.py b/dimos/manipulation/planning/kinematics/jacobian_ik.py index 5f80642058..c756045d36 100644 --- a/dimos/manipulation/planning/kinematics/jacobian_ik.py +++ b/dimos/manipulation/planning/kinematics/jacobian_ik.py @@ -395,7 +395,7 @@ def solve_differential_position_only( return JointState(name=joint_names, velocity=q_dot.tolist()) -# ============= Result Helpers ============= +# Result Helpers def _create_success_result( diff --git a/dimos/manipulation/planning/kinematics/pinocchio_ik.py b/dimos/manipulation/planning/kinematics/pinocchio_ik.py index 4224dda556..ff1c2dcc2a 100644 --- a/dimos/manipulation/planning/kinematics/pinocchio_ik.py +++ b/dimos/manipulation/planning/kinematics/pinocchio_ik.py @@ -49,11 +49,6 @@ logger = setup_logger() -# ============================================================================= -# Configuration -# ============================================================================= - - @dataclass class PinocchioIKConfig: """Configuration for the Pinocchio IK solver. @@ -73,11 +68,6 @@ class PinocchioIKConfig: max_velocity: float = 10.0 -# ============================================================================= -# PinocchioIK Solver -# ============================================================================= - - class PinocchioIK: """Pinocchio-based damped least-squares IK solver. @@ -162,10 +152,6 @@ def ee_joint_id(self) -> int: """End-effector joint ID.""" return self._ee_joint_id - # ========================================================================= - # Core IK - # ========================================================================= - def solve( self, target_pose: pinocchio.SE3, @@ -208,10 +194,6 @@ def solve( return q, False, final_err - # ========================================================================= - # Forward Kinematics - # ========================================================================= - def forward_kinematics(self, joint_positions: NDArray[np.floating[Any]]) -> pinocchio.SE3: """Compute end-effector pose from joint positions. @@ -225,11 +207,6 @@ def forward_kinematics(self, joint_positions: NDArray[np.floating[Any]]) -> pino return self._data.oMi[self._ee_joint_id].copy() -# ============================================================================= -# Pose Conversion Helpers -# ============================================================================= - - def pose_to_se3(pose: Pose | PoseStamped) -> pinocchio.SE3: """Convert Pose or PoseStamped to pinocchio SE3""" @@ -239,11 +216,6 @@ def pose_to_se3(pose: Pose | PoseStamped) -> pinocchio.SE3: return pinocchio.SE3(rotation, position) -# ============================================================================= -# Safety Utilities -# ============================================================================= - - def check_joint_delta( q_new: NDArray[np.floating[Any]], q_current: NDArray[np.floating[Any]], diff --git a/dimos/manipulation/planning/monitor/world_monitor.py b/dimos/manipulation/planning/monitor/world_monitor.py index 33017957dc..cca2dda013 100644 --- a/dimos/manipulation/planning/monitor/world_monitor.py +++ b/dimos/manipulation/planning/monitor/world_monitor.py @@ -66,7 +66,7 @@ def __init__( self._viz_stop_event = threading.Event() self._viz_rate_hz: float = 10.0 - # ============= Robot Management ============= + # Robot Management def add_robot(self, config: RobotModelConfig) -> WorldRobotID: """Add a robot. Returns robot_id.""" @@ -93,7 +93,7 @@ def get_joint_limits( with self._lock: return self._world.get_joint_limits(robot_id) - # ============= Obstacle Management ============= + # Obstacle Management def add_obstacle(self, obstacle: Obstacle) -> str: """Add an obstacle. Returns obstacle_id.""" @@ -110,7 +110,7 @@ def clear_obstacles(self) -> None: with self._lock: self._world.clear_obstacles() - # ============= Monitor Control ============= + # Monitor Control def start_state_monitor( self, @@ -181,7 +181,7 @@ def stop_all_monitors(self) -> None: self._world.close() - # ============= Message Handlers ============= + # Message Handlers def on_joint_state(self, msg: JointState, robot_id: WorldRobotID | None = None) -> None: """Handle joint state message. Broadcasts to all monitors if robot_id is None.""" @@ -252,7 +252,7 @@ def list_added_obstacles(self) -> list[dict[str, Any]]: return self._obstacle_monitor.list_added_obstacles() return [] - # ============= State Access ============= + # State Access def get_current_joint_state(self, robot_id: WorldRobotID) -> JointState | None: """Get current joint state. Returns None if not yet received.""" @@ -294,7 +294,7 @@ def is_state_stale(self, robot_id: WorldRobotID, max_age: float = 1.0) -> bool: return self._state_monitors[robot_id].is_state_stale(max_age) return True - # ============= Context Management ============= + # Context Management @contextmanager def scratch_context(self) -> Generator[Any, None, None]: @@ -306,7 +306,7 @@ def get_live_context(self) -> Any: """Get live context. Prefer scratch_context() for planning.""" return self._world.get_live_context() - # ============= Collision Checking ============= + # Collision Checking def is_state_valid(self, robot_id: WorldRobotID, joint_state: JointState) -> bool: """Check if configuration is collision-free.""" @@ -340,7 +340,7 @@ def get_min_distance(self, robot_id: WorldRobotID) -> float: with self._world.scratch_context() as ctx: return self._world.get_min_distance(ctx, robot_id) - # ============= Kinematics ============= + # Kinematics def get_ee_pose( self, robot_id: WorldRobotID, joint_state: JointState | None = None @@ -394,7 +394,7 @@ def get_jacobian(self, robot_id: WorldRobotID, joint_state: JointState) -> NDArr self._world.set_joint_state(ctx, robot_id, joint_state) return self._world.get_jacobian(ctx, robot_id) - # ============= Lifecycle ============= + # Lifecycle def finalize(self) -> None: """Finalize world. Must be called before collision checking.""" @@ -407,7 +407,7 @@ def is_finalized(self) -> bool: """Check if world is finalized.""" return self._world.is_finalized - # ============= Visualization ============= + # Visualization def get_visualization_url(self) -> str | None: """Get visualization URL or None if not enabled.""" @@ -466,7 +466,7 @@ def _visualization_loop(self) -> None: logger.debug(f"Visualization publish failed: {e}") time.sleep(period) - # ============= Direct World Access ============= + # Direct World Access @property def world(self) -> WorldSpec: diff --git a/dimos/manipulation/planning/monitor/world_obstacle_monitor.py b/dimos/manipulation/planning/monitor/world_obstacle_monitor.py index a96d3efaf6..4f69afad68 100644 --- a/dimos/manipulation/planning/monitor/world_obstacle_monitor.py +++ b/dimos/manipulation/planning/monitor/world_obstacle_monitor.py @@ -406,7 +406,7 @@ def remove_obstacle_callback( if callback in self._obstacle_callbacks: self._obstacle_callbacks.remove(callback) - # ============= Object-Based Perception (from ObjectDB) ============= + # Object-Based Perception (from ObjectDB) def on_objects(self, objects: list[object]) -> None: """Cache objects from ObjectDB (preserves stable object_id). diff --git a/dimos/manipulation/planning/planners/rrt_planner.py b/dimos/manipulation/planning/planners/rrt_planner.py index f2be8736d5..71204488c4 100644 --- a/dimos/manipulation/planning/planners/rrt_planner.py +++ b/dimos/manipulation/planning/planners/rrt_planner.py @@ -315,7 +315,7 @@ def _simplify_path( return simplified -# ============= Result Helpers ============= +# Result Helpers def _create_success_result( diff --git a/dimos/manipulation/planning/spec/types.py b/dimos/manipulation/planning/spec/types.py index a38cc0da26..2683db7814 100644 --- a/dimos/manipulation/planning/spec/types.py +++ b/dimos/manipulation/planning/spec/types.py @@ -32,9 +32,6 @@ from dimos.msgs.geometry_msgs import PoseStamped from dimos.msgs.sensor_msgs import JointState -# ============================================================================= -# Semantic ID Types (documentation only, not enforced at runtime) -# ============================================================================= RobotName: TypeAlias = str """User-facing robot name (e.g., 'left_arm', 'right_arm')""" @@ -45,19 +42,11 @@ JointPath: TypeAlias = "list[JointState]" """List of joint states forming a path (each waypoint has names + positions)""" -# ============================================================================= -# Numeric Array Types -# ============================================================================= Jacobian: TypeAlias = "NDArray[np.float64]" """6 x n Jacobian matrix (rows: [vx, vy, vz, wx, wy, wz])""" -# ============================================================================= -# Data Classes -# ============================================================================= - - @dataclass class Obstacle: """Obstacle specification for collision avoidance. diff --git a/dimos/manipulation/planning/world/drake_world.py b/dimos/manipulation/planning/world/drake_world.py index 2ab996f410..147e1e3ad3 100644 --- a/dimos/manipulation/planning/world/drake_world.py +++ b/dimos/manipulation/planning/world/drake_world.py @@ -124,8 +124,6 @@ def _call(self, fn: Any, *args: Any, **kwargs: Any) -> Any: return fn(*args, **kwargs) return self._executor.submit(fn, *args, **kwargs).result() - # --- Meshcat proxies --- - def SetObject(self, *args: Any, **kwargs: Any) -> Any: return self._call(self._inner.SetObject, *args, **kwargs) @@ -327,7 +325,7 @@ def get_joint_limits( np.full(n_joints, np.pi), ) - # ============= Obstacle Management ============= + # Obstacle Management def add_obstacle(self, obstacle: Obstacle) -> str: """Add an obstacle to the world.""" @@ -536,7 +534,7 @@ def clear_obstacles(self) -> None: for obs_id in obstacle_ids: self.remove_obstacle(obs_id) - # ============= Preview Robot Setup ============= + # Preview Robot Setup def _set_preview_colors(self) -> None: """Set all preview robot visual geometries to yellow/semi-transparent.""" @@ -565,7 +563,7 @@ def _remove_preview_collision_roles(self) -> None: for geom_id in self._plant.GetCollisionGeometriesForBody(body): self._scene_graph.RemoveRole(source_id, geom_id, Role.kProximity) - # ============= Lifecycle ============= + # Lifecycle def finalize(self) -> None: """Finalize world - locks robot topology, enables collision checking.""" @@ -683,7 +681,7 @@ def _exclude_body_pair(self, body1: Any, body2: Any) -> None: ) ) - # ============= Context Management ============= + # Context Management def get_live_context(self) -> Context: """Get the live context (mirrors current robot state). @@ -736,7 +734,7 @@ def sync_from_joint_state(self, robot_id: WorldRobotID, joint_state: JointState) # Calling ForcedPublish from the LCM callback thread blocks message processing. # Visualization can be updated via publish_to_meshcat() from non-callback contexts. - # ============= State Operations (context-based) ============= + # State Operations (context-based) def set_joint_state( self, ctx: Context, robot_id: WorldRobotID, joint_state: JointState @@ -782,7 +780,7 @@ def get_joint_state(self, ctx: Context, robot_id: WorldRobotID) -> JointState: positions = [float(full_positions[idx]) for idx in robot_data.joint_indices] return JointState(name=robot_data.config.joint_names, position=positions) - # ============= Collision Checking (context-based) ============= + # Collision Checking (context-based) def is_collision_free(self, ctx: Context, robot_id: WorldRobotID) -> bool: """Check if current configuration in context is collision-free.""" @@ -812,7 +810,7 @@ def get_min_distance(self, ctx: Context, robot_id: WorldRobotID) -> float: return float(min(pair.distance for pair in signed_distance_pairs)) - # ============= Collision Checking (context-free, for planning) ============= + # Collision Checking (context-free, for planning) def check_config_collision_free(self, robot_id: WorldRobotID, joint_state: JointState) -> bool: """Check if a joint state is collision-free (manages context internally). @@ -859,7 +857,7 @@ def check_edge_collision_free( return True - # ============= Forward Kinematics (context-based) ============= + # Forward Kinematics (context-based) def get_ee_pose(self, ctx: Context, robot_id: WorldRobotID) -> PoseStamped: """Get end-effector pose.""" @@ -944,7 +942,7 @@ def get_jacobian(self, ctx: Context, robot_id: WorldRobotID) -> NDArray[np.float return J_reordered - # ============= Visualization ============= + # Visualization def get_visualization_url(self) -> str | None: """Get visualization URL if enabled.""" @@ -1029,7 +1027,7 @@ def close(self) -> None: if self._meshcat is not None: self._meshcat.close() - # ============= Direct Access (use with caution) ============= + # Direct Access (use with caution) @property def plant(self) -> MultibodyPlant: diff --git a/dimos/manipulation/test_manipulation_unit.py b/dimos/manipulation/test_manipulation_unit.py index 4aa232c74f..cfd6e35fda 100644 --- a/dimos/manipulation/test_manipulation_unit.py +++ b/dimos/manipulation/test_manipulation_unit.py @@ -30,10 +30,6 @@ from dimos.msgs.geometry_msgs import PoseStamped, Quaternion, Vector3 from dimos.msgs.trajectory_msgs import JointTrajectory, TrajectoryPoint -# ============================================================================= -# Fixtures -# ============================================================================= - @pytest.fixture def robot_config(): @@ -103,11 +99,6 @@ def _make_module(): return module -# ============================================================================= -# Test State Machine -# ============================================================================= - - class TestStateMachine: """Test state transitions.""" @@ -167,11 +158,6 @@ def test_begin_planning_state_checks(self, robot_config): assert module._begin_planning() is None -# ============================================================================= -# Test Robot Selection -# ============================================================================= - - class TestRobotSelection: """Test robot selection logic.""" @@ -201,11 +187,6 @@ def test_multiple_robots_require_name(self, robot_config): assert result[0] == "left" -# ============================================================================= -# Test Joint Name Translation (for coordinator integration) -# ============================================================================= - - class TestJointNameTranslation: """Test trajectory joint name translation for coordinator.""" @@ -227,11 +208,6 @@ def test_mapping_translates_names(self, robot_config_with_mapping, simple_trajec assert len(result.points) == 2 # Points preserved -# ============================================================================= -# Test Execute Method -# ============================================================================= - - class TestExecute: """Test coordinator execution.""" @@ -288,11 +264,6 @@ def test_execute_rejected(self, robot_config, simple_trajectory): assert module._state == ManipulationState.FAULT -# ============================================================================= -# Test RobotModelConfig Mapping Helpers -# ============================================================================= - - class TestRobotModelConfigMapping: """Test RobotModelConfig joint name mapping helpers.""" diff --git a/dimos/memory/timeseries/base.py b/dimos/memory/timeseries/base.py index 0d88355b5b..2831836020 100644 --- a/dimos/memory/timeseries/base.py +++ b/dimos/memory/timeseries/base.py @@ -92,8 +92,6 @@ def _find_after(self, timestamp: float) -> tuple[float, T] | None: """Find the first (ts, data) strictly after the given timestamp.""" ... - # --- Collection API (built on abstract methods) --- - def __len__(self) -> int: return self._count() diff --git a/dimos/memory/timeseries/legacy.py b/dimos/memory/timeseries/legacy.py index 15a4ff90fa..a98b0baddf 100644 --- a/dimos/memory/timeseries/legacy.py +++ b/dimos/memory/timeseries/legacy.py @@ -232,8 +232,6 @@ def _find_after(self, timestamp: float) -> tuple[float, T] | None: return (ts, data) return None - # === Backward-compatible API (TimedSensorReplay/SensorReplay) === - @property def files(self) -> list[Path]: """Return list of pickle files (backward compatibility with SensorReplay).""" diff --git a/dimos/perception/experimental/temporal_memory/entity_graph_db.py b/dimos/perception/experimental/temporal_memory/entity_graph_db.py index a2f5b41cbf..11c90cda87 100644 --- a/dimos/perception/experimental/temporal_memory/entity_graph_db.py +++ b/dimos/perception/experimental/temporal_memory/entity_graph_db.py @@ -122,7 +122,7 @@ def _init_schema(self) -> None: conn.commit() - # ==================== Entity Operations ==================== + # Entity Operations def upsert_entity( self, @@ -216,7 +216,7 @@ def get_entities_by_time( for row in cursor.fetchall() ] - # ==================== Relation Operations ==================== + # Relation Operations def add_relation( self, @@ -290,7 +290,7 @@ def get_recent_relations(self, limit: int = 50) -> list[dict[str, Any]]: for row in cursor.fetchall() ] - # ==================== Distance Operations ==================== + # Distance Operations def add_distance( self, @@ -424,7 +424,7 @@ def get_nearby_entities( for row in cursor.fetchall() ] - # ==================== Neighborhood Query ==================== + # Neighborhood Query def get_entity_neighborhood( self, @@ -471,7 +471,7 @@ def get_entity_neighborhood( "num_hops": max_hops, } - # ==================== Stats / Summary ==================== + # Stats / Summary def get_stats(self) -> dict[str, Any]: conn = self._get_connection() @@ -491,7 +491,7 @@ def get_summary(self, recent_relations_limit: int = 5) -> dict[str, Any]: "recent_relations": self.get_recent_relations(limit=recent_relations_limit), } - # ==================== Bulk Save ==================== + # Bulk Save def save_window_data( self, @@ -608,7 +608,7 @@ def estimate_and_save_distances( except Exception as e: logger.warning(f"Failed to estimate distances: {e}", exc_info=True) - # ==================== Lifecycle ==================== + # Lifecycle def commit(self) -> None: if hasattr(self._local, "conn"): diff --git a/dimos/perception/experimental/temporal_memory/frame_window_accumulator.py b/dimos/perception/experimental/temporal_memory/frame_window_accumulator.py index 7af13ad9c2..fc2c9c8a79 100644 --- a/dimos/perception/experimental/temporal_memory/frame_window_accumulator.py +++ b/dimos/perception/experimental/temporal_memory/frame_window_accumulator.py @@ -72,10 +72,6 @@ def __init__( self.stride_s = stride_s self.fps = fps - # ------------------------------------------------------------------ - # Ingest - # ------------------------------------------------------------------ - def set_start_time(self, wall_time: float) -> None: with self._lock: if self._video_start_wall_time is None: @@ -103,10 +99,6 @@ def add_frame(self, image: Image, wall_time: float) -> None: self._buffer.append(frame) self._frame_count += 1 - # ------------------------------------------------------------------ - # Window extraction - # ------------------------------------------------------------------ - def try_extract_window(self) -> list[Frame] | None: """Try to extract a window of frames. @@ -131,10 +123,6 @@ def mark_analysis_time(self, t: float) -> None: with self._lock: self._last_analysis_time = t - # ------------------------------------------------------------------ - # Accessors - # ------------------------------------------------------------------ - @property def frame_count(self) -> int: with self._lock: diff --git a/dimos/perception/experimental/temporal_memory/temporal_memory.py b/dimos/perception/experimental/temporal_memory/temporal_memory.py index 7d01522417..8841d3a6b0 100644 --- a/dimos/perception/experimental/temporal_memory/temporal_memory.py +++ b/dimos/perception/experimental/temporal_memory/temporal_memory.py @@ -203,10 +203,6 @@ def __init__(self, **kwargs: Any) -> None: f"window={self.config.window_s}s, stride={self.config.stride_s}s" ) - # ------------------------------------------------------------------ - # VLM access (lazy) - # ------------------------------------------------------------------ - @property def vlm(self) -> VlModel[Any]: if self._vlm_raw is None: @@ -230,10 +226,6 @@ def _analyzer(self) -> WindowAnalyzer: ) return self.__analyzer - # ------------------------------------------------------------------ - # JSONL logging - # ------------------------------------------------------------------ - def _log_jsonl(self, record: dict[str, Any]) -> None: line = json.dumps(record, ensure_ascii=False) + "\n" # Write to per-run JSONL @@ -250,10 +242,6 @@ def _log_jsonl(self, record: dict[str, Any]) -> None: except Exception as e: logger.warning(f"persistent jsonl log failed: {e}") - # ------------------------------------------------------------------ - # Rerun visualization - # ------------------------------------------------------------------ - def _publish_entity_markers(self) -> None: """Publish entity positions as 3D markers for Rerun overlay on the map.""" if not self.config.visualize: @@ -288,10 +276,6 @@ def _publish_entity_markers(self) -> None: except Exception as e: logger.debug(f"entity marker publish error: {e}") - # ------------------------------------------------------------------ - # Lifecycle - # ------------------------------------------------------------------ - @rpc def start(self) -> None: super().start() @@ -374,10 +358,6 @@ def stop(self) -> None: logger.info("TemporalMemory stopped") - # ------------------------------------------------------------------ - # Core loop - # ------------------------------------------------------------------ - def _analyze_window(self) -> None: if self._stopped: return @@ -518,10 +498,6 @@ def _update_rolling_summary(self, w_end: float) -> None: ) logger.info(f"[temporal-memory] SUMMARY: {sr.summary_text[:300]}") - # ------------------------------------------------------------------ - # Query (agent skill) - # ------------------------------------------------------------------ - @skill def query(self, question: str) -> str: """Answer a question about the video stream using temporal memory and graph knowledge. @@ -611,10 +587,6 @@ def query(self, question: str) -> str: ) return qr.answer - # ------------------------------------------------------------------ - # RPC accessors (backward compat) - # ------------------------------------------------------------------ - @rpc def clear_history(self) -> bool: try: diff --git a/dimos/perception/experimental/temporal_memory/temporal_state.py b/dimos/perception/experimental/temporal_memory/temporal_state.py index 64914761b1..dfc440872d 100644 --- a/dimos/perception/experimental/temporal_memory/temporal_state.py +++ b/dimos/perception/experimental/temporal_memory/temporal_state.py @@ -39,10 +39,6 @@ class TemporalState: _lock: threading.Lock = field(default_factory=threading.Lock, repr=False, compare=False) - # ------------------------------------------------------------------ - # Snapshot - # ------------------------------------------------------------------ - def snapshot(self) -> TemporalState: """Return a deep-copy snapshot (safe to read outside the lock).""" with self._lock: @@ -65,10 +61,6 @@ def to_dict(self) -> dict[str, Any]: "last_present": copy.deepcopy(self.last_present), } - # ------------------------------------------------------------------ - # Mutators - # ------------------------------------------------------------------ - def update_from_window( self, parsed: dict[str, Any], diff --git a/dimos/perception/experimental/temporal_memory/test_temporal_memory_module.py b/dimos/perception/experimental/temporal_memory/test_temporal_memory_module.py index abaa99dede..5b37b66770 100644 --- a/dimos/perception/experimental/temporal_memory/test_temporal_memory_module.py +++ b/dimos/perception/experimental/temporal_memory/test_temporal_memory_module.py @@ -64,11 +64,6 @@ def _make_image(value: int = 128, shape: tuple[int, ...] = (64, 64, 3)) -> Image return Image.from_numpy(data) -# ====================================================================== -# 1. FrameWindowAccumulator tests -# ====================================================================== - - class TestFrameWindowAccumulator: def test_bounded_buffer(self) -> None: acc = FrameWindowAccumulator(max_buffer_frames=5, window_s=1.0, stride_s=1.0, fps=1.0) @@ -125,11 +120,6 @@ def test_clear(self) -> None: assert acc.buffer_size == 0 -# ====================================================================== -# 2. TemporalState tests -# ====================================================================== - - class TestTemporalState: def test_update_and_snapshot(self) -> None: state = TemporalState(next_summary_at_s=10.0) @@ -226,11 +216,6 @@ def test_auto_add_referenced(self) -> None: assert "E2" in ids -# ====================================================================== -# 3. extract_time_window (regex-only) tests -# ====================================================================== - - class TestExtractTimeWindow: def test_keyword_patterns(self) -> None: assert extract_time_window("just now") == 60 @@ -248,11 +233,6 @@ def test_no_time_reference(self) -> None: assert extract_time_window("is there a person?") is None -# ====================================================================== -# 4. EntityGraphDB tests -# ====================================================================== - - class TestEntityGraphDB: @pytest.fixture def db(self, tmp_path: Path) -> EntityGraphDB: @@ -315,11 +295,6 @@ def test_stats(self, db: EntityGraphDB) -> None: assert "semantic_relations" not in stats -# ====================================================================== -# 5. Persistence test (new_memory flag) -# ====================================================================== - - class TestPersistence: def test_new_memory_clears_db(self, tmp_path: Path) -> None: db_dir = tmp_path / "memory" / "temporal" @@ -372,11 +347,6 @@ def test_persistent_memory_survives(self, tmp_path: Path) -> None: tm.stop() -# ====================================================================== -# 6. Per-run JSONL logging test -# ====================================================================== - - class TestJSONLLogging: def test_log_entries(self, tmp_path: Path) -> None: db_dir = tmp_path / "db" @@ -415,11 +385,6 @@ def test_log_entries(self, tmp_path: Path) -> None: tm.stop() -# ====================================================================== -# 7. Rerun visualization test -# ====================================================================== - - class TestEntityMarkers: def test_publish_entity_markers(self, tmp_path: Path) -> None: db_dir = tmp_path / "db" @@ -482,11 +447,6 @@ def test_markers_to_rerun(self) -> None: assert isinstance(archetype, rr.Points3D) -# ====================================================================== -# 8. WindowAnalyzer mock tests -# ====================================================================== - - class TestWindowAnalyzer: def test_analyze_window_calls_vlm(self) -> None: from dimos.perception.experimental.temporal_memory.window_analyzer import WindowAnalyzer @@ -555,11 +515,6 @@ def test_answer_query(self) -> None: assert result.answer == "The answer is 42" -# ====================================================================== -# 9. Integration test with ModuleCoordinator -# ====================================================================== - - class VideoReplayModule(Module): """Module that replays synthetic video data for tests.""" diff --git a/dimos/perception/experimental/temporal_memory/window_analyzer.py b/dimos/perception/experimental/temporal_memory/window_analyzer.py index 70bfec8d74..cd01a3056d 100644 --- a/dimos/perception/experimental/temporal_memory/window_analyzer.py +++ b/dimos/perception/experimental/temporal_memory/window_analyzer.py @@ -79,10 +79,6 @@ def __init__( def vlm(self) -> VlModel[Any]: return self._vlm - # ------------------------------------------------------------------ - # VLM Call #1: Window analysis - # ------------------------------------------------------------------ - def analyze_window( self, frames: list[Frame], @@ -116,16 +112,8 @@ def analyze_window( parsed = tu.parse_window_response(raw, w_start, w_end, len(frames)) return AnalysisResult(parsed=parsed, raw_vlm_response=raw, w_start=w_start, w_end=w_end) - # ------------------------------------------------------------------ - # VLM Call #2: Distance estimation (delegated to EntityGraphDB) - # ------------------------------------------------------------------ - # Distance estimation is handled by EntityGraphDB.estimate_and_save_distances. # It's called from the orchestrator, not here. - # ------------------------------------------------------------------ - # VLM Call #3: Rolling summary - # ------------------------------------------------------------------ - def update_summary( self, latest_frame: Image, @@ -148,10 +136,6 @@ def update_summary( logger.error(f"summary update failed: {e}", exc_info=True) return None - # ------------------------------------------------------------------ - # VLM Call #5: Query answer - # ------------------------------------------------------------------ - def answer_query( self, question: str, diff --git a/dimos/protocol/pubsub/impl/shmpubsub.py b/dimos/protocol/pubsub/impl/shmpubsub.py index db0a91e579..883afcdcc0 100644 --- a/dimos/protocol/pubsub/impl/shmpubsub.py +++ b/dimos/protocol/pubsub/impl/shmpubsub.py @@ -13,9 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# --------------------------------------------------------------------------- -# SharedMemory Pub/Sub over unified IPC channels (CPU/CUDA) -# --------------------------------------------------------------------------- from __future__ import annotations @@ -101,7 +98,7 @@ def __init__(self, channel, capacity: int, cp_mod) -> None: # type: ignore[no-u # Lock for thread-safe publish buffer access self.publish_lock = threading.Lock() - # ----- init / lifecycle ------------------------------------------------- + # init / lifecycle def __init__( self, @@ -146,7 +143,7 @@ def stop(self) -> None: self._topics.clear() logger.debug("SharedMemory PubSub stopped.") - # ----- PubSub API (bytes on the wire) ---------------------------------- + # PubSub API (bytes on the wire) def publish(self, topic: str, message: bytes) -> None: if not isinstance(message, bytes | bytearray | memoryview): @@ -212,7 +209,7 @@ def _unsub() -> None: return _unsub - # ----- Capacity mgmt ---------------------------------------------------- + # Capacity mgmt def reconfigure(self, topic: str, *, capacity: int) -> dict: # type: ignore[type-arg] """Change payload capacity (bytes) for a topic; returns new descriptor.""" @@ -229,7 +226,7 @@ def reconfigure(self, topic: str, *, capacity: int) -> dict: # type: ignore[typ st.publish_buffer = np.zeros(new_shape, dtype=np.uint8) return desc # type: ignore[no-any-return] - # ----- Internals -------------------------------------------------------- + # Internals def _ensure_topic(self, topic: str) -> _TopicState: with self._lock: diff --git a/dimos/protocol/pubsub/shm/ipc_factory.py b/dimos/protocol/pubsub/shm/ipc_factory.py index fbf98d379e..29ed682f8d 100644 --- a/dimos/protocol/pubsub/shm/ipc_factory.py +++ b/dimos/protocol/pubsub/shm/ipc_factory.py @@ -54,11 +54,6 @@ def _open_shm_with_retry(name: str) -> SharedMemory: raise FileNotFoundError(f"SHM not found after {tries} retries: {name}") from last -# --------------------------- -# 1) Abstract interface -# --------------------------- - - class FrameChannel(ABC): """Single-slot 'freshest frame' IPC channel with a tiny control block. - Double-buffered to avoid torn reads. @@ -125,11 +120,6 @@ def _safe_unlink(name: str) -> None: pass -# --------------------------- -# 2) CPU shared-memory backend -# --------------------------- - - class CpuShmChannel(FrameChannel): def __init__( # type: ignore[no-untyped-def] self, @@ -300,11 +290,6 @@ def close(self) -> None: pass -# --------------------------- -# 3) Factories -# --------------------------- - - class CPU_IPC_Factory: """Creates/attaches CPU shared-memory channels.""" @@ -318,11 +303,6 @@ def attach(desc: dict) -> CpuShmChannel: # type: ignore[type-arg] return CpuShmChannel.attach(desc) # type: ignore[arg-type, no-any-return] -# --------------------------- -# 4) Runtime selector -# --------------------------- - - def make_frame_channel( # type: ignore[no-untyped-def] shape, dtype=np.uint8, prefer: str = "auto", device: int = 0 ) -> FrameChannel: diff --git a/dimos/protocol/service/system_configurator/base.py b/dimos/protocol/service/system_configurator/base.py index c221af890f..e5f65bdc18 100644 --- a/dimos/protocol/service/system_configurator/base.py +++ b/dimos/protocol/service/system_configurator/base.py @@ -25,7 +25,7 @@ logger = logging.getLogger(__name__) -# ----------------------------- sudo helpers ----------------------------- +# sudo helpers @cache @@ -66,7 +66,7 @@ def _write_sysctl_int(name: str, value: int) -> None: sudo_run("sysctl", "-w", f"{name}={value}", check=True, text=True, capture_output=False) -# -------------------------- base class for system config checks/requirements -------------------------- +# base class for system config checks/requirements class SystemConfigurator(ABC): @@ -91,7 +91,7 @@ def fix(self) -> None: raise NotImplementedError -# ----------------------------- generic enforcement of system configs ----------------------------- +# generic enforcement of system configs def configure_system(checks: list[SystemConfigurator], check_only: bool = False) -> None: diff --git a/dimos/protocol/service/system_configurator/lcm.py b/dimos/protocol/service/system_configurator/lcm.py index 6599f97407..9e1b3e5c61 100644 --- a/dimos/protocol/service/system_configurator/lcm.py +++ b/dimos/protocol/service/system_configurator/lcm.py @@ -25,7 +25,7 @@ sudo_run, ) -# ------------------------------ specific checks: multicast ------------------------------ +# specific checks: multicast class MulticastConfiguratorLinux(SystemConfigurator): @@ -182,7 +182,7 @@ def fix(self) -> None: sudo_run(*self.add_route_cmd, check=True, text=True, capture_output=True) -# ------------------------------ specific checks: buffers ------------------------------ +# specific checks: buffers IDEAL_RMEM_SIZE = 67_108_864 # 64MB @@ -254,7 +254,7 @@ def fix(self) -> None: _write_sysctl_int(key, target) -# ------------------------------ specific checks: ulimit ------------------------------ +# specific checks: ulimit class MaxFileConfiguratorMacOS(SystemConfigurator): diff --git a/dimos/protocol/service/test_lcmservice.py b/dimos/protocol/service/test_lcmservice.py index a647c89c86..78085e2363 100644 --- a/dimos/protocol/service/test_lcmservice.py +++ b/dimos/protocol/service/test_lcmservice.py @@ -34,7 +34,7 @@ MulticastConfiguratorMacOS, ) -# ----------------------------- autoconf tests ----------------------------- +# autoconf tests class TestConfigureSystemForLcm: @@ -87,7 +87,7 @@ def test_logs_error_on_unsupported_system(self) -> None: assert "Windows" in mock_logger.error.call_args[0][0] -# ----------------------------- LCMConfig tests ----------------------------- +# LCMConfig tests class TestLCMConfig: @@ -103,7 +103,7 @@ def test_custom_url(self) -> None: assert config.url == custom_url -# ----------------------------- Topic tests ----------------------------- +# Topic tests class TestTopic: @@ -118,7 +118,7 @@ def test_str_with_lcm_type(self) -> None: assert str(topic) == "my_topic#TestMessage" -# ----------------------------- LCMService tests ----------------------------- +# LCMService tests class TestLCMService: diff --git a/dimos/protocol/service/test_system_configurator.py b/dimos/protocol/service/test_system_configurator.py index 62de2a61ea..1bd44aa5e2 100644 --- a/dimos/protocol/service/test_system_configurator.py +++ b/dimos/protocol/service/test_system_configurator.py @@ -37,7 +37,7 @@ _write_sysctl_int, ) -# ----------------------------- Helper function tests ----------------------------- +# Helper function tests class TestIsRootUser: @@ -122,7 +122,7 @@ def test_calls_sudo_run_with_correct_args(self) -> None: ) -# ----------------------------- configure_system tests ----------------------------- +# configure_system tests class MockConfigurator(SystemConfigurator): @@ -186,7 +186,7 @@ def test_exits_on_no_with_critical_check(self, mocker) -> None: assert exc_info.value.code == 1 -# ----------------------------- MulticastConfiguratorLinux tests ----------------------------- +# MulticastConfiguratorLinux tests class TestMulticastConfiguratorLinux: @@ -259,7 +259,7 @@ def test_fix_runs_needed_commands(self) -> None: assert mock_run.call_count == 2 -# ----------------------------- MulticastConfiguratorMacOS tests ----------------------------- +# MulticastConfiguratorMacOS tests class TestMulticastConfiguratorMacOS: @@ -311,7 +311,7 @@ def test_fix_runs_route_command(self) -> None: assert "224.0.0.0/4" in add_args -# ----------------------------- BufferConfiguratorLinux tests ----------------------------- +# BufferConfiguratorLinux tests class TestBufferConfiguratorLinux: @@ -354,7 +354,7 @@ def test_fix_writes_needed_values(self) -> None: mock_write.assert_called_once_with("net.core.rmem_max", IDEAL_RMEM_SIZE) -# ----------------------------- BufferConfiguratorMacOS tests ----------------------------- +# BufferConfiguratorMacOS tests class TestBufferConfiguratorMacOS: @@ -398,7 +398,7 @@ def test_fix_writes_needed_values(self) -> None: ) -# ----------------------------- MaxFileConfiguratorMacOS tests ----------------------------- +# MaxFileConfiguratorMacOS tests class TestMaxFileConfiguratorMacOS: @@ -489,7 +489,7 @@ def test_fix_raises_on_setrlimit_error(self) -> None: configurator.fix() -# ----------------------------- ClockSyncConfigurator tests ----------------------------- +# ClockSyncConfigurator tests class TestClockSyncConfigurator: diff --git a/dimos/skills/skills.py b/dimos/skills/skills.py index 94f8b3726f..1fbf6266ef 100644 --- a/dimos/skills/skills.py +++ b/dimos/skills/skills.py @@ -30,12 +30,8 @@ logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) -# region SkillLibrary - class SkillLibrary: - # ==== Flat Skill Library ==== - def __init__(self) -> None: self.registered_skills: list[AbstractSkill] = [] self.class_skills: list[AbstractSkill] = [] @@ -111,8 +107,6 @@ def __contains__(self, skill: AbstractSkill) -> bool: def __getitem__(self, index): # type: ignore[no-untyped-def] return self.registered_skills[index] - # ==== Calling a Function ==== - _instances: dict[str, dict] = {} # type: ignore[type-arg] def create_instance(self, name: str, **kwargs) -> None: # type: ignore[no-untyped-def] @@ -154,8 +148,6 @@ def call(self, name: str, **args): # type: ignore[no-untyped-def] logger.error(error_msg) return error_msg - # ==== Tools ==== - def get_tools(self) -> Any: tools_json = self.get_list_of_skills_as_json(list_of_skills=self.registered_skills) # print(f"{Colors.YELLOW_PRINT_COLOR}Tools JSON: {tools_json}{Colors.RESET_COLOR}") @@ -250,11 +242,6 @@ def terminate_skill(self, name: str): # type: ignore[no-untyped-def] return f"No running skill found with name: {name}" -# endregion SkillLibrary - -# region AbstractSkill - - class AbstractSkill(BaseModel): def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] print("Initializing AbstractSkill Class") @@ -289,7 +276,6 @@ def unregister_as_running(self, name: str, skill_library: SkillLibrary) -> None: """ skill_library.unregister_running_skill(name) - # ==== Tools ==== def get_tools(self) -> Any: tools_json = self.get_list_of_skills_as_json(list_of_skills=self._list_of_skills) # print(f"Tools JSON: {tools_json}") @@ -299,10 +285,6 @@ def get_list_of_skills_as_json(self, list_of_skills: list[AbstractSkill]) -> lis return list(map(pydantic_function_tool, list_of_skills)) # type: ignore[arg-type] -# endregion AbstractSkill - -# region Abstract Robot Skill - if TYPE_CHECKING: from dimos.robot.robot import Robot else: @@ -338,6 +320,3 @@ def __call__(self): # type: ignore[no-untyped-def] print( f"{Colors.BLUE_PRINT_COLOR}Robot Instance provided to Robot Skill: {self.__class__.__name__}{Colors.RESET_COLOR}" ) - - -# endregion Abstract Robot Skill diff --git a/dimos/stream/frame_processor.py b/dimos/stream/frame_processor.py index ab18400c88..c2db47dc23 100644 --- a/dimos/stream/frame_processor.py +++ b/dimos/stream/frame_processor.py @@ -154,8 +154,6 @@ def visualize_flow(self, flow): # type: ignore[no-untyped-def] rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) return rgb - # ============================== - def process_stream_edge_detection(self, frame_stream): # type: ignore[no-untyped-def] return frame_stream.pipe( ops.map(self.edge_detection), diff --git a/dimos/teleop/phone/phone_teleop_module.py b/dimos/teleop/phone/phone_teleop_module.py index f13842811b..cc55f1f180 100644 --- a/dimos/teleop/phone/phone_teleop_module.py +++ b/dimos/teleop/phone/phone_teleop_module.py @@ -69,10 +69,6 @@ class PhoneTeleopModule(Module[PhoneTeleopConfig]): # Output: velocity command to robot twist_output: Out[TwistStamped] - # ------------------------------------------------------------------------- - # Initialization - # ------------------------------------------------------------------------- - def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) @@ -98,10 +94,6 @@ def __init__(self, **kwargs: Any) -> None: self._setup_routes() - # ------------------------------------------------------------------------- - # Web Server Routes - # ------------------------------------------------------------------------- - def _setup_routes(self) -> None: """Register teleop routes on the embedded web server.""" @@ -133,10 +125,6 @@ async def websocket_endpoint(ws: WebSocket) -> None: except Exception: logger.exception("WebSocket error") - # ------------------------------------------------------------------------- - # Lifecycle - # ------------------------------------------------------------------------- - @rpc def start(self) -> None: super().start() @@ -149,10 +137,6 @@ def stop(self) -> None: self._stop_server() super().stop() - # ------------------------------------------------------------------------- - # Internal engage / disengage (assumes lock is held) - # ------------------------------------------------------------------------- - def _engage(self) -> bool: """Engage: capture current sensors as initial""" if self._current_sensors is None: @@ -169,10 +153,6 @@ def _disengage(self) -> None: self._initial_sensors = None logger.info("Phone teleop disengaged") - # ------------------------------------------------------------------------- - # WebSocket Message Decoders - # ------------------------------------------------------------------------- - def _on_sensors_bytes(self, data: bytes) -> None: """Decode raw LCM bytes into TwistStamped and update sensor state.""" msg = TwistStamped.lcm_decode(data) @@ -185,10 +165,6 @@ def _on_button_bytes(self, data: bytes) -> None: with self._lock: self._teleop_button = bool(msg.data) - # ------------------------------------------------------------------------- - # Embedded Web Server - # ------------------------------------------------------------------------- - def _start_server(self) -> None: """Start the embedded FastAPI server with HTTPS in a daemon thread.""" if self._web_server_thread is not None and self._web_server_thread.is_alive(): @@ -212,10 +188,6 @@ def _stop_server(self) -> None: self._web_server_thread = None logger.info("Phone teleop web server stopped") - # ------------------------------------------------------------------------- - # Control Loop - # ------------------------------------------------------------------------- - def _start_control_loop(self) -> None: if self._control_loop_thread is not None and self._control_loop_thread.is_alive(): return @@ -254,10 +226,6 @@ def _control_loop(self) -> None: if sleep_time > 0: self._stop_event.wait(sleep_time) - # ------------------------------------------------------------------------- - # Control Loop Internal Methods - # ------------------------------------------------------------------------- - def _handle_engage(self) -> None: """ Override to customize engagement logic. diff --git a/dimos/teleop/quest/blueprints.py b/dimos/teleop/quest/blueprints.py index 5672a2bea0..ac86a0325f 100644 --- a/dimos/teleop/quest/blueprints.py +++ b/dimos/teleop/quest/blueprints.py @@ -26,10 +26,6 @@ from dimos.teleop.quest.quest_extensions import arm_teleop_module, visualizing_teleop_module from dimos.teleop.quest.quest_types import Buttons -# ----------------------------------------------------------------------------- -# Quest Teleop Blueprints -# ----------------------------------------------------------------------------- - # Arm teleop with press-and-hold engage arm_teleop = autoconnect( arm_teleop_module(), @@ -53,10 +49,6 @@ ) -# ----------------------------------------------------------------------------- -# Teleop wired to Coordinator (TeleopIK) -# ----------------------------------------------------------------------------- - # Single XArm7 teleop: right controller -> xarm7 # Usage: dimos run arm-teleop-xarm7 diff --git a/dimos/teleop/quest/quest_teleop_module.py b/dimos/teleop/quest/quest_teleop_module.py index 9beaf0da3e..3c8e6e9812 100644 --- a/dimos/teleop/quest/quest_teleop_module.py +++ b/dimos/teleop/quest/quest_teleop_module.py @@ -98,10 +98,6 @@ class QuestTeleopModule(Module[_Config]): right_controller_output: Out[PoseStamped] buttons: Out[Buttons] - # ------------------------------------------------------------------------- - # Initialization - # ------------------------------------------------------------------------- - def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) @@ -131,10 +127,6 @@ def __init__(self, **kwargs: Any) -> None: self._setup_routes() - # ------------------------------------------------------------------------- - # Web Server Routes - # ------------------------------------------------------------------------- - def _setup_routes(self) -> None: """Register teleop routes on the embedded web server.""" @@ -166,10 +158,6 @@ async def websocket_endpoint(ws: WebSocket) -> None: except Exception: logger.exception("WebSocket error") - # ------------------------------------------------------------------------- - # Lifecycle - # ------------------------------------------------------------------------- - @rpc def start(self) -> None: super().start() @@ -183,10 +171,6 @@ def stop(self) -> None: self._stop_server() super().stop() - # ------------------------------------------------------------------------- - # Internal engage/disengage (assumes lock is held) - # ------------------------------------------------------------------------- - def _engage(self, hand: Hand | None = None) -> bool: """Engage a hand. Assumes self._lock is held.""" hands = [hand] if hand is not None else list(Hand) @@ -219,10 +203,6 @@ def get_status(self) -> QuestTeleopStatus: buttons=Buttons.from_controllers(left, right), ) - # ------------------------------------------------------------------------- - # WebSocket Message Decoders - # ------------------------------------------------------------------------- - @staticmethod def _resolve_hand(frame_id: str) -> Hand: if frame_id == "left": @@ -253,10 +233,6 @@ def _on_joy_bytes(self, data: bytes) -> None: with self._lock: self._controllers[hand] = controller - # ------------------------------------------------------------------------- - # Embedded Web Server - # ------------------------------------------------------------------------- - def _start_server(self) -> None: """Start the embedded FastAPI server with HTTPS in a daemon thread.""" if self._web_server_thread is not None and self._web_server_thread.is_alive(): @@ -335,10 +311,6 @@ def _control_loop(self) -> None: if sleep_time > 0: self._stop_event.wait(sleep_time) - # ------------------------------------------------------------------------- - # Control Loop Internals - # ------------------------------------------------------------------------- - def _handle_engage(self) -> None: """Check for engage button press and update per-hand engage state. diff --git a/dimos/test_no_sections.py b/dimos/test_no_sections.py new file mode 100644 index 0000000000..9523c0aae2 --- /dev/null +++ b/dimos/test_no_sections.py @@ -0,0 +1,143 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re + +from dimos.constants import DIMOS_PROJECT_ROOT + +REPO_ROOT = str(DIMOS_PROJECT_ROOT) + +# Matches lines that are purely separator characters (=== or ---) with optional +# whitespace, e.g.: # ============= or # --------------- +SEPARATOR_LINE = re.compile(r"^\s*#\s*[-=]{10,}\s*$") + +# Matches section headers wrapped in separators, e.g.: +# # === My Section === or # ===== My Section ===== +INLINE_SECTION = re.compile(r"^\s*#\s*[-=]{3,}.+[-=]{3,}\s*$") + +# VS Code-style region markers +REGION_MARKER = re.compile(r"^\s*#\s*(region|endregion)\b") + +SCANNED_EXTENSIONS = { + ".py", + ".yml", + ".yaml", +} + +SCANNED_PREFIXES = { + "Dockerfile", +} + +IGNORED_DIRS = { + ".venv", + "venv", + "__pycache__", + "node_modules", + ".git", + "dist", + "build", + ".egg-info", + ".tox", + # third-party vendored code + "gtsam", +} + +# Lines that match section patterns but are actually programmatic / intentional. +# Each entry is (relative_path, line_substring) — if both match, the line is skipped. +WHITELIST = [ + # Sentinel marker used at runtime to detect already-converted Dockerfiles + ("dimos/core/docker_build.py", "DIMOS_SENTINEL"), +] + + +def _should_scan(path: str) -> bool: + basename = os.path.basename(path) + _, ext = os.path.splitext(basename) + if ext in SCANNED_EXTENSIONS: + return True + for prefix in SCANNED_PREFIXES: + if basename.startswith(prefix): + return True + return False + + +def _is_ignored_dir(dirpath: str) -> bool: + parts = dirpath.split(os.sep) + return bool(IGNORED_DIRS.intersection(parts)) + + +def _is_whitelisted(rel_path: str, line: str) -> bool: + for allowed_path, allowed_substr in WHITELIST: + if rel_path == allowed_path and allowed_substr in line: + return True + return False + + +def find_section_markers() -> list[tuple[str, int, str]]: + """Return a list of (file, line_number, line_text) for every section marker.""" + violations: list[tuple[str, int, str]] = [] + + for dirpath, dirnames, filenames in os.walk(REPO_ROOT): + # Prune ignored directories in-place + dirnames[:] = [d for d in dirnames if d not in IGNORED_DIRS] + + if _is_ignored_dir(dirpath): + continue + + rel_dir = os.path.relpath(dirpath, REPO_ROOT) + + for fname in filenames: + full_path = os.path.join(dirpath, fname) + rel_path = os.path.join(rel_dir, fname) + + if not _should_scan(full_path): + continue + + try: + with open(full_path, encoding="utf-8", errors="replace") as f: + for lineno, line in enumerate(f, start=1): + stripped = line.rstrip("\n") + if _is_whitelisted(rel_path, stripped): + continue + if ( + SEPARATOR_LINE.match(stripped) + or INLINE_SECTION.match(stripped) + or REGION_MARKER.match(stripped) + ): + violations.append((rel_path, lineno, stripped)) + except (OSError, UnicodeDecodeError): + continue + + return violations + + +def test_no_section_markers(): + """ + Fail if any file contains section-style comment markers. + + If a file is too complicated to be understood without sections, then the + sections should be files. We don't need "subfiles". + """ + violations = find_section_markers() + if violations: + report_lines = [ + f"Found {len(violations)} section marker(s). " + "If a file is too complicated to be understood without sections, " + 'then the sections should be files. We don\'t need "subfiles".', + "", + ] + for path, lineno, text in violations: + report_lines.append(f" {path}:{lineno}: {text.strip()}") + raise AssertionError("\n".join(report_lines)) diff --git a/dimos/utils/cli/dtop.py b/dimos/utils/cli/dtop.py index fa463c15d6..64529a6bc3 100644 --- a/dimos/utils/cli/dtop.py +++ b/dimos/utils/cli/dtop.py @@ -40,10 +40,6 @@ if TYPE_CHECKING: from collections.abc import Callable -# --------------------------------------------------------------------------- -# Color helpers -# --------------------------------------------------------------------------- - def _heat(ratio: float) -> str: """Map 0..1 ratio to a cyan → yellow → red gradient.""" @@ -96,11 +92,6 @@ def _rel_style(value: float, lo: float, hi: float) -> str: return _heat(min((value - lo) / (hi - lo), 1.0)) -# --------------------------------------------------------------------------- -# Metric formatters (plain strings — color applied separately via _rel_style) -# --------------------------------------------------------------------------- - - def _fmt_pct(v: float) -> str: return f"{v:3.0f}%" @@ -128,11 +119,6 @@ def _fmt_io(v: float) -> str: return f"{v / 1048576:.0f} MB" -# --------------------------------------------------------------------------- -# Metric definitions — add a tuple here to add a new field -# (label, dict_key, format_fn) -# --------------------------------------------------------------------------- - _LINE1: list[tuple[str, str, Callable[[float], str]]] = [ ("CPU", "cpu_percent", _fmt_pct), ("PSS", "pss", _fmt_mem), @@ -162,11 +148,6 @@ def _compute_ranges(data_dicts: list[dict[str, Any]]) -> dict[str, tuple[float, return ranges -# --------------------------------------------------------------------------- -# App -# --------------------------------------------------------------------------- - - class ResourceSpyApp(App[None]): CSS_PATH = "dimos.tcss" @@ -367,10 +348,6 @@ def _make_lines( return [line1, line2] -# --------------------------------------------------------------------------- -# Preview -# --------------------------------------------------------------------------- - _PREVIEW_DATA: dict[str, Any] = { "coordinator": { "cpu_percent": 12.3, diff --git a/dimos/utils/simple_controller.py b/dimos/utils/simple_controller.py index f95350552c..c8a6ade19d 100644 --- a/dimos/utils/simple_controller.py +++ b/dimos/utils/simple_controller.py @@ -20,9 +20,6 @@ def normalize_angle(angle: float): # type: ignore[no-untyped-def] return math.atan2(math.sin(angle), math.cos(angle)) -# ---------------------------- -# PID Controller Class -# ---------------------------- class PIDController: def __init__( # type: ignore[no-untyped-def] self, @@ -120,9 +117,6 @@ def _apply_deadband_compensation(self, error): # type: ignore[no-untyped-def] return error -# ---------------------------- -# Visual Servoing Controller Class -# ---------------------------- class VisualServoingController: def __init__(self, distance_pid_params, angle_pid_params) -> None: # type: ignore[no-untyped-def] """ diff --git a/dimos/utils/test_data.py b/dimos/utils/test_data.py index e55c8b20f3..9970fc5912 100644 --- a/dimos/utils/test_data.py +++ b/dimos/utils/test_data.py @@ -132,11 +132,6 @@ def test_pull_dir() -> None: assert sha256 == expected_hash -# ============================================================================ -# LfsPath Tests -# ============================================================================ - - def test_lfs_path_lazy_creation() -> None: """Test that creating LfsPath doesn't trigger download.""" lfs_path = LfsPath("test_data_file") diff --git a/docker/navigation/.env.hardware b/docker/navigation/.env.hardware index 234e58545c..fc0e34581e 100644 --- a/docker/navigation/.env.hardware +++ b/docker/navigation/.env.hardware @@ -1,16 +1,8 @@ # Hardware Configuration Environment Variables # Copy this file to .env and customize for your hardware setup -# ============================================ -# NVIDIA GPU Support -# ============================================ -# Set the Docker runtime to nvidia for GPU support (it's runc by default) #DOCKER_RUNTIME=nvidia -# ============================================ -# ROS Configuration -# ============================================ -# ROS domain ID for multi-robot setups ROS_DOMAIN_ID=42 # Robot configuration ('mechanum_drive', 'unitree/unitree_g1', 'unitree/unitree_g1', etc) @@ -21,10 +13,6 @@ ROBOT_CONFIG_PATH=mechanum_drive # This can be found in the unitree app under Device settings or via network scan ROBOT_IP= -# ============================================ -# Mid-360 Lidar Configuration -# ============================================ -# Network interface connected to the lidar (e.g., eth0, enp0s3) # Find with: ip addr show LIDAR_INTERFACE=eth0 @@ -43,24 +31,12 @@ LIDAR_GATEWAY=192.168.1.1 # LIDAR_IP=192.168.123.120 # FOR UNITREE G1 EDU LIDAR_IP=192.168.1.116 -# ============================================ -# Motor Controller Configuration -# ============================================ -# Serial device for motor controller # Check with: ls /dev/ttyACM* or ls /dev/ttyUSB* MOTOR_SERIAL_DEVICE=/dev/ttyACM0 -# ============================================ -# Network Communication (for base station) -# ============================================ -# Enable WiFi buffer optimization for data transmission # Set to true if using wireless base station ENABLE_WIFI_BUFFER=false -# ============================================ -# Unitree Robot Configuration -# ============================================ -# Enable Unitree WebRTC control (for Go2, G1) #USE_UNITREE=true # Unitree robot IP address @@ -69,10 +45,6 @@ UNITREE_IP=192.168.12.1 # Unitree connection method (LocalAP or Ethernet) UNITREE_CONN=LocalAP -# ============================================ -# Navigation Options -# ============================================ -# Enable route planner (FAR planner for goal navigation) USE_ROUTE_PLANNER=false # Enable RViz visualization @@ -83,10 +55,6 @@ USE_RVIZ=false # The system will load: MAP_PATH.pcd for SLAM, MAP_PATH_tomogram.pickle for PCT planner MAP_PATH= -# ============================================ -# Device Group IDs -# ============================================ -# Group ID for /dev/input devices (joystick) # Find with: getent group input | cut -d: -f3 INPUT_GID=995 @@ -94,8 +62,4 @@ INPUT_GID=995 # Find with: getent group dialout | cut -d: -f3 DIALOUT_GID=20 -# ============================================ -# Display Configuration -# ============================================ -# X11 display (usually auto-detected) # DISPLAY=:0 diff --git a/docker/navigation/Dockerfile b/docker/navigation/Dockerfile index fa51fd621c..dc2ce54f39 100644 --- a/docker/navigation/Dockerfile +++ b/docker/navigation/Dockerfile @@ -1,39 +1,23 @@ -# ============================================================================= -# DimOS Navigation Docker Image -# ============================================================================= -# # Multi-stage build for ROS 2 navigation with SLAM support. # Includes both arise_slam and FASTLIO2 - select at runtime via LOCALIZATION_METHOD. -# # Supported configurations: # - ROS distributions: humble, jazzy # - SLAM methods: arise_slam (default), fastlio (set LOCALIZATION_METHOD=fastlio) -# # Build: # ./build.sh --humble # Build for ROS 2 Humble # ./build.sh --jazzy # Build for ROS 2 Jazzy -# # Run: # ./start.sh --hardware --route-planner # Uses arise_slam # LOCALIZATION_METHOD=fastlio ./start.sh --hardware --route-planner # Uses FASTLIO2 -# -# ============================================================================= # Build argument for ROS distribution (default: humble) ARG ROS_DISTRO=humble ARG TARGETARCH -# ----------------------------------------------------------------------------- -# Platform-specific base images # - amd64: Use osrf/ros desktop-full (includes Gazebo, full GUI) -# - arm64: Use ros-base (desktop-full not available for ARM) -# ----------------------------------------------------------------------------- FROM osrf/ros:${ROS_DISTRO}-desktop-full AS base-amd64 FROM ros:${ROS_DISTRO}-ros-base AS base-arm64 -# ----------------------------------------------------------------------------- -# STAGE 1: Build Stage - compile all C++ dependencies -# ----------------------------------------------------------------------------- FROM base-${TARGETARCH} AS builder ARG ROS_DISTRO @@ -200,9 +184,6 @@ RUN /bin/bash -c "source /opt/ros/${ROS_DISTRO}/setup.bash && \ echo 'Building with both arise_slam and FASTLIO2' && \ colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release" -# ----------------------------------------------------------------------------- -# STAGE 2: Runtime Stage - minimal image for running -# ----------------------------------------------------------------------------- ARG ROS_DISTRO ARG TARGETARCH FROM base-${TARGETARCH} AS runtime diff --git a/docker/navigation/docker-compose.dev.yml b/docker/navigation/docker-compose.dev.yml index defbdae846..537e00581d 100644 --- a/docker/navigation/docker-compose.dev.yml +++ b/docker/navigation/docker-compose.dev.yml @@ -1,13 +1,6 @@ -# ============================================================================= -# DEVELOPMENT OVERRIDES - Mount source for live editing -# ============================================================================= -# # Usage: docker compose -f docker-compose.yml -f docker-compose.dev.yml up -# # This file adds development-specific volume mounts for editing ROS configs # without rebuilding the image. -# -# ============================================================================= services: dimos_simulation: diff --git a/docs/capabilities/manipulation/adding_a_custom_arm.md b/docs/capabilities/manipulation/adding_a_custom_arm.md index 2b435a50fe..3e931a7f73 100644 --- a/docs/capabilities/manipulation/adding_a_custom_arm.md +++ b/docs/capabilities/manipulation/adding_a_custom_arm.md @@ -116,9 +116,6 @@ class YourArmAdapter: self._sdk: YourArmSDK | None = None self._control_mode: ControlMode = ControlMode.POSITION - # ========================================================================= - # Connection - # ========================================================================= def connect(self) -> bool: """Connect to hardware. Returns True on success.""" @@ -144,9 +141,6 @@ class YourArmAdapter: """Check if connected.""" return self._sdk is not None and self._sdk.is_alive() - # ========================================================================= - # Info - # ========================================================================= def get_info(self) -> ManipulatorInfo: """Get manipulator info (vendor, model, DOF).""" @@ -173,9 +167,6 @@ class YourArmAdapter: velocity_max=[math.pi] * self._dof, # rad/s ) - # ========================================================================= - # Control Mode - # ========================================================================= def set_control_mode(self, mode: ControlMode) -> bool: """Set control mode. @@ -206,9 +197,6 @@ class YourArmAdapter: """Get current control mode.""" return self._control_mode - # ========================================================================= - # State Reading - # ========================================================================= def read_joint_positions(self) -> list[float]: """Read current joint positions in radians. @@ -262,9 +250,6 @@ class YourArmAdapter: return 0, "" return code, f"YourArm error {code}" - # ========================================================================= - # Motion Control (Joint Space) - # ========================================================================= def write_joint_positions( self, @@ -300,9 +285,6 @@ class YourArmAdapter: return False return self._sdk.emergency_stop() - # ========================================================================= - # Servo Control - # ========================================================================= def write_enable(self, enable: bool) -> bool: """Enable or disable servos.""" @@ -322,10 +304,6 @@ class YourArmAdapter: return False return self._sdk.clear_errors() - # ========================================================================= - # Optional: Cartesian Control - # Return None/False if not supported by your arm. - # ========================================================================= def read_cartesian_position(self) -> dict[str, float] | None: """Read end-effector pose. @@ -343,9 +321,6 @@ class YourArmAdapter: """Command end-effector pose. Return False if not supported.""" return False - # ========================================================================= - # Optional: Gripper - # ========================================================================= def read_gripper_position(self) -> float | None: """Read gripper position in meters. Return None if no gripper.""" @@ -355,9 +330,6 @@ class YourArmAdapter: """Command gripper position in meters. Return False if no gripper.""" return False - # ========================================================================= - # Optional: Force/Torque Sensor - # ========================================================================= def read_force_torque(self) -> list[float] | None: """Read F/T sensor data [fx, fy, fz, tx, ty, tz]. None if no sensor.""" @@ -470,9 +442,6 @@ from dimos.control.coordinator import TaskConfig, control_coordinator from dimos.core.transport import LCMTransport from dimos.msgs.sensor_msgs import JointState -# ============================================================================= -# Coordinator Blueprints -# ============================================================================= # YourArm (6-DOF) — real hardware coordinator_yourarm = control_coordinator( @@ -589,9 +558,6 @@ def _make_yourarm_config( Add this to your `dimos/robot/yourarm/blueprints.py` alongside the coordinator blueprint: ```python -# ============================================================================= -# Planner Blueprints (requires URDF) -# ============================================================================= yourarm_planner = manipulation_module( robots=[_make_yourarm_config("arm", joint_prefix="arm_", coordinator_task="traj_arm")],