Skip to content

feat(sim): add xArm GraspGenX simulation - #3366

Draft
TomCC7 wants to merge 17 commits into
feat/grasp-04-visualizationfrom
feat/grasp-05-xarm-sim
Draft

feat(sim): add xArm GraspGenX simulation#3366
TomCC7 wants to merge 17 commits into
feat/grasp-04-visualizationfrom
feat/grasp-05-xarm-sim

Conversation

@TomCC7

@TomCC7 TomCC7 commented Aug 5, 2026

Copy link
Copy Markdown
Member

Contribution path

Problem

The full GraspGenX pick path needs a reproducible xArm simulation environment with object ground truth, planning obstacles, calibrated frames, gripper state, and live visualization.

Solution

  • Add the xarm-grasp-sim scene, blueprints, and test guide.
  • Publish simulated object ground truth and MuJoCo body poses.
  • Add xArm frame calibration, mesh obstacles, pick diagnostics, and target-only obstacle suppression.
  • Preserve simulated gripper state and wire live grasp visualization.

The legacy gravity-sag tolerance patch is intentionally omitted: it modified a stored-plan freshness gate that no longer exists in the current PlanExecutionManager architecture.

This is stack 5 of 5. Previous: #3365. Review the diff against feat/grasp-04-visualization.

How to Test

uv run dimos run xarm-grasp-sim-agent

Setup and operator steps are in XARM_GRASP_SIM_README.md. Verified: 235 consolidated tests passed with 7 deselected; blueprint registry checks passed with 3 optional-dependency skips and 42 deselected; Ruff and git diff --check passed across the complete stack.

AI assistance

OpenAI Codex with GPT-5 was used extensively for branch extraction, implementation cleanup, verification, and this description.

Checklist

  • I have read and approved the CLA.

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

❌ 7 Tests Failed:

Tests completed Failed Passed Skipped
3635 7 3628 175
View the top 3 failed test(s) by shortest run time
::dimos.robot.manipulators.xarm.blueprints.test_graspgenx
Stack Traces | 0s run time
.../xarm/blueprints/test_graspgenx.py:29: in <module>
    from dimos.robot.manipulators.xarm.blueprints.agentic import (
        Any        = typing.Any
        Blueprint  = <class 'dimos.core.coordination.blueprints.Blueprint'>
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        McpClient  = <class 'dimos.agents.mcp.mcp_client.McpClient'>
        McpServer  = <class 'dimos.agents.mcp.mcp_server.McpServer'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        PickAndPlaceModuleConfig = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModuleConfig'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/test_graspgenx.cpython-312.pyc'
        __doc__    = None
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/test_graspgenx.py'
        __loader__ = <_pytest.assertion.rewrite.AssertionRewritingHook object at 0xfffb0d430470>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.test_graspgenx'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.test_graspgenx', loader=<_pytest.assertion.rewrite.Assertion... at 0xfffb0d430470>, origin='.../work/dimos/dimos/.../xarm/blueprints/test_graspgenx.py')
.../xarm/blueprints/agentic.py:29: in <module>
    from dimos.robot.manipulators.xarm.blueprints.simulation import (
        BASE_MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm.\n\nAvailable skills:\n- get_robot_state: Get... FAULT, call reset before retrying.\nAfter a planning failure, call reset before attempting more planning or motion.\n'
        MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm with an eye-in-hand RealSense camera and a gr...s only when they are known to be stale. After any robot motion fault, call **reset** before more planning or motion.\n'
        McpClient  = <class 'dimos.agents.mcp.mcp_client.McpClient'>
        McpServer  = <class 'dimos.agents.mcp.mcp_server.McpServer'>
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/agentic.cpython-312.pyc'
        __doc__    = 'Agentic xArm manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/agentic.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xfffa24429a30>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.agentic'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.agentic', loader=<_frozen_importlib_external.SourceFileLoader object at 0xfffa24429a30>, origin='.../work/dimos/dimos/.../xarm/blueprints/agentic.py')
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xfffaf40dd800>
        xarm7_planner_coordinator = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa24434410>
        xarm_graspgenx = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa244386b0>
        xarm_perception = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa248160c0>
.../xarm/blueprints/simulation.py:73: in <module>
    name: str(_XARM_GRASP_MESH_DIR / f"{name}.obj")
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        LfsPath    = <class 'dimos.utils.data.LfsPath'>
        MujocoSimModule = <class 'dimos.simulation.engines.mujoco_sim_module.MujocoSimModule'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        RerunBridgeModule = <class 'dimos.visualization.rerun.bridge.RerunBridgeModule'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        XARM7_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm7.tar.gz after 3 attempts: Command...ude', 'data/.lfs/xarm7.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484a0d0>
        XARM_GRASP_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484b4d0>
        _XARM_GRASPGENX = GraspGenXConfig(rpc_transport=<class 'dimos.protocol.rpc.pubsubrpc.LCMRPC'>, default_rpc_timeout=120.0, rpc_timeouts={...to_tcp=((0.0, -1.0, 0.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.172), (0.0, 0.0, 0.0, 1.0)), max_candidates=100)
        _XARM_GRASP_MESH_DIR = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa178adb50>
        _XARM_GRASP_TABLE = {'center': (0.47, 0.0, 0.065), 'name': 'table', 'size': (0.38, 0.6, 0.13)}
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/simulation.cpython-312.pyc'
        __doc__    = 'Simulation xArm perception manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/simulation.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xfffa244388f0>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.simulation', loader=<_frozen_importlib_external.SourceFileLo...ject at 0xfffa244388f0>, origin='.../work/dimos/dimos/.../xarm/blueprints/simulation.py')
        _xarm7_perception_sim = <function _xarm7_perception_sim at 0xfffa17864ea0>
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xfffaf40dd800>
        coordinator = <function coordinator at 0xfffa24bcbe20>
        make_xarm7_sim_hardware = <function make_xarm7_sim_hardware at 0xfffa2482dee0>
        make_xarm7_sim_module_kwargs = <function make_xarm7_sim_module_kwargs at 0xfffa2482df80>
        make_xarm7_sim_robot_config = <function make_xarm7_sim_robot_config at 0xfffa2482de40>
        make_xarm_graspgenx_config = <function make_xarm_graspgenx_config at 0xfffa178677e0>
        trajectory_task = <function trajectory_task at 0xfffa24bcb880>
        xarm_perception_sim = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa2443ec30>
dimos/utils/data.py:369: in __str__
    return str(self._ensure_downloaded())
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa178adbd0>
dimos/utils/data.py:347: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = '.../assets/manip/bottle.obj'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa178adbd0>
dimos/utils/data.py:304: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'xarm_grasp_sim'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/.../assets/manip/bottle.obj')
        name       = '.../assets/manip/bottle.obj'
        nested_path = PosixPath('assets/manip/bottle.obj')
        path_parts = ('xarm_grasp_sim', 'assets', 'manip', 'bottle.obj')
dimos/utils/data.py:248: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        filename   = 'xarm_grasp_sim'
        repo_root  = PosixPath('.../work/dimos/dimos')
dimos/utils/data.py:216: in _lfs_pull
    raise RuntimeError(
E   RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.
        attempt    = 3
        env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'd9ee6b3b-bc20-4518-90c4-af872cc775ec.tests.ubuntu-24_04-arm_3_14_fal', ...}
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz'])
        relative_path = PosixPath('data/.lfs/xarm_grasp_sim.tar.gz')
        repo_root  = PosixPath('.../work/dimos/dimos')
        retries    = 2
dimos.codebase_checks.test_inline_heavy_imports::test_heavy_imports_are_inline
Stack Traces | 2.31s run time
def test_heavy_imports_are_inline() -> None:
        """Fail if any file imports cv2/open3d/rerun at module level."""
        hits = find_eager_heavy_imports()
        if hits:
            listing = "\n".join(
                f"  - dimos/{f}:{line}: `{module}`"
                for f, lines in sorted(hits.items())
                for line, module in lines
            )
>           raise AssertionError(
                f"Found module-level import(s) of {'/'.join(HEAVY_MODULES)}:\n{listing}\n\n"
                "These libraries load large native extensions into every process that "
                "transitively imports the module. Import them inside the function or "
                "method that uses them; imports needed only for type annotations go "
                "under `if TYPE_CHECKING:`."
            )
E           AssertionError: Found module-level import(s) of cv2/open3d/rerun:
E             - dimos/perception/sim_object_scene.py:30: `open3d`
E           
E           These libraries load large native extensions into every process that transitively imports the module. Import them inside the function or method that uses them; imports needed only for type annotations go under `if TYPE_CHECKING:`.

hits       = {'perception/sim_object_scene.py': [(30, 'open3d')]}
listing    = '  - dimos/perception/sim_object_scene.py:30: `open3d`'

dimos/codebase_checks/test_inline_heavy_imports.py:92: AssertionError
dimos.codebase_checks.test_blueprint_kwargs::test_blueprint_atom_kwargs_match_module_config[xarm-grasp-sim-agent]
Stack Traces | 3.14s run time
blueprint_name = 'xarm-grasp-sim-agent'

    @pytest.mark.parametrize("blueprint_name", _blueprint_params())
    def test_blueprint_atom_kwargs_match_module_config(blueprint_name: str) -> None:
        """Fail when blueprint kwargs cannot be consumed by their target module."""
>       blueprint = _get_blueprint_or_skip(blueprint_name)

blueprint_name = 'xarm-grasp-sim-agent'

dimos/codebase_checks/test_blueprint_kwargs.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/codebase_checks/test_blueprint_kwargs.py:36: in _get_blueprint_or_skip
    return get_blueprint_by_name(blueprint_name)
        blueprint_name = 'xarm-grasp-sim-agent'
        message    = "Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1."
dimos/robot/get_all_blueprints.py:51: in get_blueprint_by_name
    module = __import__(module_path, fromlist=[attr])
        attr       = 'xarm_grasp_sim_agent'
        module_path = 'dimos.robot.manipulators.xarm.blueprints.agentic'
        name       = 'xarm-grasp-sim-agent'
.../xarm/blueprints/agentic.py:29: in <module>
    from dimos.robot.manipulators.xarm.blueprints.simulation import (
        BASE_MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm.\n\nAvailable skills:\n- get_robot_state: Get... FAULT, call reset before retrying.\nAfter a planning failure, call reset before attempting more planning or motion.\n'
        MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm with an eye-in-hand RealSense camera and a gr...s only when they are known to be stale. After any robot motion fault, call **reset** before more planning or motion.\n'
        McpClient  = <class 'dimos.agents.mcp.mcp_client.McpClient'>
        McpServer  = <class 'dimos.agents.mcp.mcp_server.McpServer'>
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/agentic.cpython-312.pyc'
        __doc__    = 'Agentic xArm manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/agentic.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xfffa14a98170>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.agentic'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.agentic', loader=<_frozen_importlib_external.SourceFileLoader object at 0xfffa14a98170>, origin='.../work/dimos/dimos/.../xarm/blueprints/agentic.py')
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xfffaf40dd800>
        xarm7_planner_coordinator = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa24434410>
        xarm_graspgenx = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa244386b0>
        xarm_perception = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa248160c0>
.../xarm/blueprints/simulation.py:73: in <module>
    name: str(_XARM_GRASP_MESH_DIR / f"{name}.obj")
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        LfsPath    = <class 'dimos.utils.data.LfsPath'>
        MujocoSimModule = <class 'dimos.simulation.engines.mujoco_sim_module.MujocoSimModule'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        RerunBridgeModule = <class 'dimos.visualization.rerun.bridge.RerunBridgeModule'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        XARM7_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm7.tar.gz after 3 attempts: Command...ude', 'data/.lfs/xarm7.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484a0d0>
        XARM_GRASP_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484b4d0>
        _XARM_GRASPGENX = GraspGenXConfig(rpc_transport=<class 'dimos.protocol.rpc.pubsubrpc.LCMRPC'>, default_rpc_timeout=120.0, rpc_timeouts={...to_tcp=((0.0, -1.0, 0.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.172), (0.0, 0.0, 0.0, 1.0)), max_candidates=100)
        _XARM_GRASP_MESH_DIR = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14ac78d0>
        _XARM_GRASP_TABLE = {'center': (0.47, 0.0, 0.065), 'name': 'table', 'size': (0.38, 0.6, 0.13)}
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/simulation.cpython-312.pyc'
        __doc__    = 'Simulation xArm perception manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/simulation.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xfffa14a99850>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.simulation', loader=<_frozen_importlib_external.SourceFileLo...ject at 0xfffa14a99850>, origin='.../work/dimos/dimos/.../xarm/blueprints/simulation.py')
        _xarm7_perception_sim = <function _xarm7_perception_sim at 0xfffa14a499e0>
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xfffaf40dd800>
        coordinator = <function coordinator at 0xfffa24bcbe20>
        make_xarm7_sim_hardware = <function make_xarm7_sim_hardware at 0xfffa2482dee0>
        make_xarm7_sim_module_kwargs = <function make_xarm7_sim_module_kwargs at 0xfffa2482df80>
        make_xarm7_sim_robot_config = <function make_xarm7_sim_robot_config at 0xfffa2482de40>
        make_xarm_graspgenx_config = <function make_xarm_graspgenx_config at 0xfffa178677e0>
        trajectory_task = <function trajectory_task at 0xfffa24bcb880>
        xarm_perception_sim = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa14a9b020>
dimos/utils/data.py:369: in __str__
    return str(self._ensure_downloaded())
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14ac7850>
dimos/utils/data.py:347: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = '.../assets/manip/bottle.obj'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14ac7850>
dimos/utils/data.py:304: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'xarm_grasp_sim'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/.../assets/manip/bottle.obj')
        name       = '.../assets/manip/bottle.obj'
        nested_path = PosixPath('assets/manip/bottle.obj')
        path_parts = ('xarm_grasp_sim', 'assets', 'manip', 'bottle.obj')
dimos/utils/data.py:248: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        filename   = 'xarm_grasp_sim'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    ["git", "lfs", "pull", "--include", str(relative_path)],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'd9ee6b3b-bc20-4518-90c4-af872cc775ec.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz'])
relative_path = PosixPath('data/.lfs/xarm_grasp_sim.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:216: RuntimeError
dimos.robot.test_all_blueprints::test_blueprint_is_valid[xarm-grasp-sim-agent]
Stack Traces | 3.14s run time
blueprint_name = 'xarm-grasp-sim-agent'

    @pytest.mark.parametrize("blueprint_name", UBUNTU_BLUEPRINTS)
    def test_blueprint_is_valid(blueprint_name: str) -> None:
        """Validate blueprints that should import on the ubuntu-latest runner."""
>       _check_blueprint(blueprint_name)

blueprint_name = 'xarm-grasp-sim-agent'

dimos/robot/test_all_blueprints.py:107: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/robot/test_all_blueprints.py:83: in _check_blueprint
    blueprint = get_blueprint_by_name(blueprint_name)
        blueprint_name = 'xarm-grasp-sim-agent'
        message    = "Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1."
dimos/robot/get_all_blueprints.py:51: in get_blueprint_by_name
    module = __import__(module_path, fromlist=[attr])
        attr       = 'xarm_grasp_sim_agent'
        module_path = 'dimos.robot.manipulators.xarm.blueprints.agentic'
        name       = 'xarm-grasp-sim-agent'
.../xarm/blueprints/agentic.py:29: in <module>
    from dimos.robot.manipulators.xarm.blueprints.simulation import (
        BASE_MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm.\n\nAvailable skills:\n- get_robot_state: Get... FAULT, call reset before retrying.\nAfter a planning failure, call reset before attempting more planning or motion.\n'
        MANIPULATION_AGENT_SYSTEM_PROMPT = 'You are a robotic manipulation assistant controlling an xArm7 robot arm with an eye-in-hand RealSense camera and a gr...s only when they are known to be stale. After any robot motion fault, call **reset** before more planning or motion.\n'
        McpClient  = <class 'dimos.agents.mcp.mcp_client.McpClient'>
        McpServer  = <class 'dimos.agents.mcp.mcp_server.McpServer'>
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/agentic.cpython-312.pyc'
        __doc__    = 'Agentic xArm manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/agentic.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xffa7d4574830>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.agentic'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.agentic', loader=<_frozen_importlib_external.SourceFileLoader object at 0xffa7d4574830>, origin='.../work/dimos/dimos/.../xarm/blueprints/agentic.py')
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xffa8b9fa5800>
        xarm7_planner_coordinator = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffa7de2f6240>
        xarm_graspgenx = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffa7de958710>
        xarm_perception = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffa7de7de7e0>
.../xarm/blueprints/simulation.py:73: in <module>
    name: str(_XARM_GRASP_MESH_DIR / f"{name}.obj")
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        LfsPath    = <class 'dimos.utils.data.LfsPath'>
        MujocoSimModule = <class 'dimos.simulation.engines.mujoco_sim_module.MujocoSimModule'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        RerunBridgeModule = <class 'dimos.visualization.rerun.bridge.RerunBridgeModule'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        XARM7_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm7.tar.gz after 3 attempts: Command...ude', 'data/.lfs/xarm7.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7de3d0cd0>
        XARM_GRASP_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7de3d2bd0>
        _XARM_GRASPGENX = GraspGenXConfig(rpc_transport=<class 'dimos.protocol.rpc.pubsubrpc.LCMRPC'>, default_rpc_timeout=120.0, rpc_timeouts={...to_tcp=((0.0, -1.0, 0.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.172), (0.0, 0.0, 0.0, 1.0)), max_candidates=100)
        _XARM_GRASP_MESH_DIR = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d458bcd0>
        _XARM_GRASP_TABLE = {'center': (0.47, 0.0, 0.065), 'name': 'table', 'size': (0.38, 0.6, 0.13)}
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/simulation.cpython-312.pyc'
        __doc__    = 'Simulation xArm perception manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/simulation.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xffa7d45748f0>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.simulation', loader=<_frozen_importlib_external.SourceFileLo...ject at 0xffa7d45748f0>, origin='.../work/dimos/dimos/.../xarm/blueprints/simulation.py')
        _xarm7_perception_sim = <function _xarm7_perception_sim at 0xffa7d4712020>
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xffa8b9fa5800>
        coordinator = <function coordinator at 0xffa7ddf31f80>
        make_xarm7_sim_hardware = <function make_xarm7_sim_hardware at 0xffa7de3c4040>
        make_xarm7_sim_module_kwargs = <function make_xarm7_sim_module_kwargs at 0xffa7de3c40e0>
        make_xarm7_sim_robot_config = <function make_xarm7_sim_robot_config at 0xffa7dd66bf60>
        make_xarm_graspgenx_config = <function make_xarm_graspgenx_config at 0xffa7dddf1760>
        trajectory_task = <function trajectory_task at 0xffa7ddf319e0>
        xarm_perception_sim = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffa7d4576390>
dimos/utils/data.py:369: in __str__
    return str(self._ensure_downloaded())
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d458bc50>
dimos/utils/data.py:347: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = '.../assets/manip/bottle.obj'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d458bc50>
dimos/utils/data.py:304: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'xarm_grasp_sim'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/.../assets/manip/bottle.obj')
        name       = '.../assets/manip/bottle.obj'
        nested_path = PosixPath('assets/manip/bottle.obj')
        path_parts = ('xarm_grasp_sim', 'assets', 'manip', 'bottle.obj')
dimos/utils/data.py:248: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        filename   = 'xarm_grasp_sim'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    ["git", "lfs", "pull", "--include", str(relative_path)],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'd9ee6b3b-bc20-4518-90c4-af872cc775ec.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz'])
relative_path = PosixPath('data/.lfs/xarm_grasp_sim.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:216: RuntimeError
dimos.codebase_checks.test_blueprint_kwargs::test_blueprint_atom_kwargs_match_module_config[xarm-grasp-sim]
Stack Traces | 3.14s run time
blueprint_name = 'xarm-grasp-sim'

    @pytest.mark.parametrize("blueprint_name", _blueprint_params())
    def test_blueprint_atom_kwargs_match_module_config(blueprint_name: str) -> None:
        """Fail when blueprint kwargs cannot be consumed by their target module."""
>       blueprint = _get_blueprint_or_skip(blueprint_name)

blueprint_name = 'xarm-grasp-sim'

dimos/codebase_checks/test_blueprint_kwargs.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/codebase_checks/test_blueprint_kwargs.py:36: in _get_blueprint_or_skip
    return get_blueprint_by_name(blueprint_name)
        blueprint_name = 'xarm-grasp-sim'
        message    = "Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1."
dimos/robot/get_all_blueprints.py:51: in get_blueprint_by_name
    module = __import__(module_path, fromlist=[attr])
        attr       = 'xarm_grasp_sim'
        module_path = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        name       = 'xarm-grasp-sim'
.../xarm/blueprints/simulation.py:73: in <module>
    name: str(_XARM_GRASP_MESH_DIR / f"{name}.obj")
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        LfsPath    = <class 'dimos.utils.data.LfsPath'>
        MujocoSimModule = <class 'dimos.simulation.engines.mujoco_sim_module.MujocoSimModule'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        RerunBridgeModule = <class 'dimos.visualization.rerun.bridge.RerunBridgeModule'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        XARM7_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm7.tar.gz after 3 attempts: Command...ude', 'data/.lfs/xarm7.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484a0d0>
        XARM_GRASP_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa2484b4d0>
        _XARM_GRASPGENX = GraspGenXConfig(rpc_transport=<class 'dimos.protocol.rpc.pubsubrpc.LCMRPC'>, default_rpc_timeout=120.0, rpc_timeouts={...to_tcp=((0.0, -1.0, 0.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.172), (0.0, 0.0, 0.0, 1.0)), max_candidates=100)
        _XARM_GRASP_MESH_DIR = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14a602d0>
        _XARM_GRASP_TABLE = {'center': (0.47, 0.0, 0.065), 'name': 'table', 'size': (0.38, 0.6, 0.13)}
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/simulation.cpython-312.pyc'
        __doc__    = 'Simulation xArm perception manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/simulation.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xfffa14a3b290>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.simulation', loader=<_frozen_importlib_external.SourceFileLo...ject at 0xfffa14a3b290>, origin='.../work/dimos/dimos/.../xarm/blueprints/simulation.py')
        _xarm7_perception_sim = <function _xarm7_perception_sim at 0xfffa14a484a0>
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xfffaf40dd800>
        coordinator = <function coordinator at 0xfffa24bcbe20>
        make_xarm7_sim_hardware = <function make_xarm7_sim_hardware at 0xfffa2482dee0>
        make_xarm7_sim_module_kwargs = <function make_xarm7_sim_module_kwargs at 0xfffa2482df80>
        make_xarm7_sim_robot_config = <function make_xarm7_sim_robot_config at 0xfffa2482de40>
        make_xarm_graspgenx_config = <function make_xarm_graspgenx_config at 0xfffa178677e0>
        trajectory_task = <function trajectory_task at 0xfffa24bcb880>
        xarm_perception_sim = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xfffa14a599d0>
dimos/utils/data.py:369: in __str__
    return str(self._ensure_downloaded())
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14a60350>
dimos/utils/data.py:347: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = '.../assets/manip/bottle.obj'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffa14a60350>
dimos/utils/data.py:304: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'xarm_grasp_sim'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/.../assets/manip/bottle.obj')
        name       = '.../assets/manip/bottle.obj'
        nested_path = PosixPath('assets/manip/bottle.obj')
        path_parts = ('xarm_grasp_sim', 'assets', 'manip', 'bottle.obj')
dimos/utils/data.py:248: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        filename   = 'xarm_grasp_sim'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    ["git", "lfs", "pull", "--include", str(relative_path)],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'd9ee6b3b-bc20-4518-90c4-af872cc775ec.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz'])
relative_path = PosixPath('data/.lfs/xarm_grasp_sim.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:216: RuntimeError
dimos.robot.test_all_blueprints::test_blueprint_is_valid[xarm-grasp-sim]
Stack Traces | 3.14s run time
blueprint_name = 'xarm-grasp-sim'

    @pytest.mark.parametrize("blueprint_name", UBUNTU_BLUEPRINTS)
    def test_blueprint_is_valid(blueprint_name: str) -> None:
        """Validate blueprints that should import on the ubuntu-latest runner."""
>       _check_blueprint(blueprint_name)

blueprint_name = 'xarm-grasp-sim'

dimos/robot/test_all_blueprints.py:107: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/robot/test_all_blueprints.py:83: in _check_blueprint
    blueprint = get_blueprint_by_name(blueprint_name)
        blueprint_name = 'xarm-grasp-sim'
        message    = "Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1."
dimos/robot/get_all_blueprints.py:51: in get_blueprint_by_name
    module = __import__(module_path, fromlist=[attr])
        attr       = 'xarm_grasp_sim'
        module_path = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        name       = 'xarm-grasp-sim'
.../xarm/blueprints/simulation.py:73: in <module>
    name: str(_XARM_GRASP_MESH_DIR / f"{name}.obj")
        GraspGenXModule = <class 'dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule'>
        LfsPath    = <class 'dimos.utils.data.LfsPath'>
        MujocoSimModule = <class 'dimos.simulation.engines.mujoco_sim_module.MujocoSimModule'>
        ObjectSceneRegistrationModule = <class 'dimos.perception.experimental.object_scene_registration.ObjectSceneRegistrationModule'>
        PickAndPlaceModule = <class 'dimos.manipulation.pick_and_place_module.PickAndPlaceModule'>
        RerunBridgeModule = <class 'dimos.visualization.rerun.bridge.RerunBridgeModule'>
        SimObjectScene = <class 'dimos.perception.sim_object_scene.SimObjectScene'>
        XARM7_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm7.tar.gz after 3 attempts: Command...ude', 'data/.lfs/xarm7.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7de3d0cd0>
        XARM_GRASP_SIM_PATH = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7de3d2bd0>
        _XARM_GRASPGENX = GraspGenXConfig(rpc_transport=<class 'dimos.protocol.rpc.pubsubrpc.LCMRPC'>, default_rpc_timeout=120.0, rpc_timeouts={...to_tcp=((0.0, -1.0, 0.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.172), (0.0, 0.0, 0.0, 1.0)), max_candidates=100)
        _XARM_GRASP_MESH_DIR = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d4728a50>
        _XARM_GRASP_TABLE = {'center': (0.47, 0.0, 0.065), 'name': 'table', 'size': (0.38, 0.6, 0.13)}
        __builtins__ = <builtins>
        __cached__ = '.../blueprints/__pycache__/simulation.cpython-312.pyc'
        __doc__    = 'Simulation xArm perception manipulation blueprints.'
        __file__   = '.../work/dimos/dimos/.../xarm/blueprints/simulation.py'
        __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0xffa7d4714590>
        __name__   = 'dimos.robot.manipulators.xarm.blueprints.simulation'
        __package__ = 'dimos.robot.manipulators.xarm.blueprints'
        __spec__   = ModuleSpec(name='dimos.robot.manipulators.xarm.blueprints.simulation', loader=<_frozen_importlib_external.SourceFileLo...ject at 0xffa7d4714590>, origin='.../work/dimos/dimos/.../xarm/blueprints/simulation.py')
        _xarm7_perception_sim = <function _xarm7_perception_sim at 0xffa7d4710cc0>
        annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
        autoconnect = <function autoconnect at 0xffa8b9fa5800>
        coordinator = <function coordinator at 0xffa7ddf31f80>
        make_xarm7_sim_hardware = <function make_xarm7_sim_hardware at 0xffa7de3c4040>
        make_xarm7_sim_module_kwargs = <function make_xarm7_sim_module_kwargs at 0xffa7de3c40e0>
        make_xarm7_sim_robot_config = <function make_xarm7_sim_robot_config at 0xffa7dd66bf60>
        make_xarm_graspgenx_config = <function make_xarm_graspgenx_config at 0xffa7dddf1760>
        trajectory_task = <function trajectory_task at 0xffa7ddf319e0>
        xarm_perception_sim = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_description.tar.gz after 3 attemp...lfs/xarm_description.tar.gz']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffa7d4716660>
dimos/utils/data.py:369: in __str__
    return str(self._ensure_downloaded())
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d4728ad0>
dimos/utils/data.py:347: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = '.../assets/manip/bottle.obj'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts...ta/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffa7d4728ad0>
dimos/utils/data.py:304: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'xarm_grasp_sim'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/.../assets/manip/bottle.obj')
        name       = '.../assets/manip/bottle.obj'
        nested_path = PosixPath('assets/manip/bottle.obj')
        path_parts = ('xarm_grasp_sim', 'assets', 'manip', 'bottle.obj')
dimos/utils/data.py:248: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
        filename   = 'xarm_grasp_sim'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    ["git", "lfs", "pull", "--include", str(relative_path)],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/xarm_grasp_sim.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'd9ee6b3b-bc20-4518-90c4-af872cc775ec.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/xarm_grasp_sim.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/xarm_grasp_sim.tar.gz'])
relative_path = PosixPath('data/.lfs/xarm_grasp_sim.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:216: RuntimeError
dimos.robot.test_all_blueprints_generation::test_all_blueprints_is_current
Stack Traces | 3.98s run time
def test_all_blueprints_is_current() -> None:
        root = DIMOS_PROJECT_ROOT / "dimos"
        all_blueprints, all_modules = _scan_for_blueprints(root)
    
        common = set(all_blueprints.keys()) & set(all_modules.keys())
        assert not common, (
            f"Names must be unique across blueprints and modules, "
            f"but these appear in both: {sorted(common)}"
        )
    
        generated_content = _generate_all_blueprints_content(all_blueprints, all_modules)
    
        file_path = root / "robot" / "all_blueprints.py"
    
        if "CI" in os.environ:
            if not file_path.exists():
                pytest.fail(f"all_blueprints.py does not exist at {file_path}")
    
            current_content = file_path.read_text()
            if current_content != generated_content:
                diff = difflib.unified_diff(
                    current_content.splitlines(keepends=True),
                    generated_content.splitlines(keepends=True),
                    fromfile="all_blueprints.py (current)",
                    tofile="all_blueprints.py (generated)",
                )
                diff_str = "".join(diff)
>               pytest.fail(
                    f"all_blueprints.py is out of date. Run "
                    f"`pytest dimos/robot/test_all_blueprints_generation.py` locally to update.\n\n"
                    f"Diff:\n{diff_str}"
                )
E               Failed: all_blueprints.py is out of date. Run `pytest dimos/robot/test_all_blueprints_generation.py` locally to update.
E               
E               Diff:
E               --- all_blueprints.py (current)
E               +++ all_blueprints.py (generated)
E               @@ -151,13 +151,12 @@
E                    "unitree-go2-webrtc-keyboard-teleop": "dimos.robot.unitree.go2.blueprints.basic.unitree_go2_webrtc_keyboard_teleop:unitree_go2_webrtc_keyboard_teleop",
E                    "unitree-go2-webrtc-rage-keyboard-teleop": "dimos.robot.unitree.go2.blueprints.basic.unitree_go2_webrtc_rage_keyboard_teleop:unitree_go2_webrtc_rage_keyboard_teleop",
E                    "unity-sim": "dimos.simulation.unity.blueprint:unity_sim",
E               +    "xarm-grasp-sim": "dimos.robot.manipulators.xarm.blueprints.simulation:xarm_grasp_sim",
E               +    "xarm-grasp-sim-agent": "dimos.robot.manipulators.xarm.blueprints.agentic:xarm_grasp_sim_agent",
E                    "xarm-graspgenx": "dimos.robot.manipulators.xarm.blueprints.graspgenx:xarm_graspgenx",
E                    "xarm-graspgenx-agent": "dimos.robot.manipulators.xarm.blueprints.agentic:xarm_graspgenx_agent",
E                    "xarm-perception": "dimos.robot.manipulators.xarm.blueprints.perception:xarm_perception",
E                    "xarm-perception-agent": "dimos.robot.manipulators.xarm.blueprints.agentic:xarm_perception_agent",
E               -    "xarm-grasp-sim": "dimos.robot.manipulators.xarm.blueprints.simulation:xarm_grasp_sim",
E               -    "xarm-grasp-sim-agent": "dimos.robot.manipulators.xarm.blueprints.agentic:xarm_grasp_sim_agent",
E               -    "xarm-perception-sim": "dimos.robot.manipulators.xarm.blueprints.simulation:xarm_perception_sim",
E                    "xarm-perception-sim-agent": "dimos.robot.manipulators.xarm.blueprints.agentic:xarm_perception_sim_agent",
E                    "xarm6-worldbelief": "dimos.experimental.world_belief.xarm6_blueprint:xarm6_worldbelief",
E                    "xarm7-planner-coordinator": "dimos.robot.manipulators.xarm.blueprints.basic:xarm7_planner_coordinator",
E               @@ -218,6 +217,7 @@
E                    "goal-relay": "dimos.navigation.nav_3d.mls_planner.goal_relay.GoalRelay",
E                    "google-maps-skill-container": "dimos.agents.skills.google_maps_skill_container.GoogleMapsSkillContainer",
E                    "gps-nav-skill-container": "dimos.agents.skills.gps_nav_skill.GpsNavSkillContainer",
E               +    "grasp-gen-x-module": "dimos.manipulation.grasping.grasp_gen_x.GraspGenXModule",
E                    "grasping-module": "dimos.manipulation.grasping.grasping.GraspingModule",
E                    "gstreamer-camera-module": "dimos.hardware.sensors.camera.gstreamer.gstreamer_camera.GstreamerCameraModule",
E                    "hosted-stats-module": "dimos.teleop.hosted.hosted_stats.HostedStatsModule",
E               @@ -275,6 +275,7 @@
E                    "rerun-web-socket-server": "dimos.visualization.rerun.websocket_server.RerunWebSocketServer",
E                    "security-module": "dimos.experimental.security_demo.security_module.SecurityModule",
E                    "semantic-search": "dimos.memory2.module.SemanticSearch",
E               +    "sim-object-scene": "dimos.perception.sim_object_scene.SimObjectScene",
E                    "simple-phone-teleop": "dimos.teleop.phone.phone_extensions.SimplePhoneTeleop",
E                    "simple-planner": "dimos.navigation.cmu_nav.modules.simple_planner.simple_planner.SimplePlanner",
E                    "spatial-memory": "dimos.perception.experimental.spatial_perception.SpatialMemory",

all_blueprints = {'a1z-planner-coordinator': 'dimos.robot.manipulators.a1z.blueprints.basic:a1z_planner_coordinator', 'alfred-nav': 'di...rs.a1z.blueprints.basic:coordinator_a1z', 'coordinator-basic': 'dimos.control.blueprints.basic:coordinator_basic', ...}
all_modules = {'alfred-high-level': 'dimos.robot.diy.alfred.effector_high_level.AlfredHighLevel', 'arm-command-module': 'dimos.teleo...t_extensions.ArmTeleopModule', 'b-box-navigation-module': 'dimos.navigation.bbox_navigation.BBoxNavigationModule', ...}
common     = set()
current_content = '# Copyright 2025-2026 Dimensional Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the "License");\n# you m...sted.blueprints.cloudflare.WristCamera",\n    "zed-camera": "dimos.hardware.sensors.camera.zed.camera.ZEDCamera",\n}\n'
diff       = <generator object unified_diff at 0xffa7d588aa80>
diff_str   = '--- all_blueprints.py (current)\n+++ all_blueprints.py (generated)\n@@ -151,13 +151,12 @@\n     "unitree-go2-webrtc-k...le_planner.SimplePlanner",\n     "spatial-memory": "dimos.perception.experimental.spatial_perception.SpatialMemory",\n'
file_path  = PosixPath('.../dimos/robot/all_blueprints.py')
generated_content = '# Copyright 2025-2026 Dimensional Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the "License");\n# you m...sted.blueprints.cloudflare.WristCamera",\n    "zed-camera": "dimos.hardware.sensors.camera.zed.camera.ZEDCamera",\n}\n'
root       = PosixPath('.../dimos/dimos/dimos')

dimos/robot/test_all_blueprints_generation.py:76: Failed

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

mustafab0 and others added 16 commits August 4, 2026 22:44
A PD-held arm rests 1e-4..1e-3 rad off target, so microradian equality
gates rejected every preview-then-execute pick and every plan requested
while the arm merely held position (INVALID_START / 'no longer matches
the stored plan start'). 0.01 rad absorbs hold jitter and still catches
a genuinely moved arm.
Compose GraspGenXModule into xarm-grasp-sim so pick's provider path runs
learned proposals (autoconnect fills the GraspGenSpec ref); CC's xArm gripper
config from grasp_config. xarm-perception-sim is unchanged.

Adds static_box_obstacles to ManipulationModuleConfig next to floor_z: startup
box obstacles for scene furniture the planner must always respect. The
grasp-sim table matches data/xarm_grasp_sim/scene.xml.
Convert MuJoCo's internal closing-joint feedback to aperture values and keep direct gripper RPCs in the coordinator's hold-last cache. This prevents arm trajectory commands from closing a gripper that pick just opened.

Increase the xArm simulation pre-grasp clearance from 5 cm to 10 cm and cover both regressions with focused tests.
pointcloud_to_convex_hull_obj centers the hull on the mean of the points,
but the obstacle was placed at obj.pose, which carries the bounding-box
centre. The two differ by ~1.6cm on tall asymmetric objects, so mesh
obstacles sat offset from the geometry they represent.
Plumb the existing WorldObstacleMonitor use_mesh_obstacles option through
start_obstacle_monitor and enable it for the grasp sim. Bounding boxes
envelop an object at every height, so a side approach collides with empty
space; the hull follows the observed geometry. Other blueprints keep boxes.
pointcloud_to_convex_hull_obj named its output hull_{id(points)}.obj. id() is
a memory address, and CPython reuses a freed address for the next same-sized
array, so sequential callers overwrote each other: five of six scene objects
collapsed onto one hull file and every obstacle took the shape of whichever
was written last. Intermittent, because it depends on allocator reuse.

The default name is now a uuid. The obstacle monitor passes an explicit path
per object instead, so rescanning overwrites in place rather than growing the
cache without bound.
Pick suppressed every object obstacle for the whole transaction, so the
approach was planned against an empty scene and swept through whatever stood
between the arm and the target.

Suppression is now staged. Candidate selection and the approach plan against
the full scene; only the legs that must reach into and carry the target -
grasp, close, retreat, and their feasibility check - hide the target, and
nothing else is ever hidden. A failed restore is recorded on the transaction
so it still surfaces, and pick_suppress_all_object_obstacles remains as a
diagnostic escape hatch.
@TomCC7
TomCC7 force-pushed the feat/grasp-05-xarm-sim branch from 8c7a8ae to a5a10cf Compare August 5, 2026 05:45
@TomCC7
TomCC7 force-pushed the feat/grasp-04-visualization branch from 74e7634 to 4cfb213 Compare August 5, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants