Skip to content

fix(xarm): stop commanding the arm on every launch - #3869

Open
mustafab0 wants to merge 1 commit into
mb/grasp-01-realsense-validatorfrom
mb/grasp-02-no-motion-on-launch
Open

fix(xarm): stop commanding the arm on every launch#3869
mustafab0 wants to merge 1 commit into
mb/grasp-01-realsense-validatorfrom
mb/grasp-02-no-motion-on-launch

Conversation

@mustafab0

Copy link
Copy Markdown
Contributor

XArmAdapter.activate() unconditionally drove the arm to a hardcoded joint pose, and deactivate() drove it there again on the way out. The pose came from two module constants picked by axis count, _XARM6_INITIAL_JOINTS_DEG and _XARM7_INITIAL_JOINTS_DEG, the latter carrying a TODO (CC): change this once we have 7dof arm setup. Nothing asked for that motion: bringing a blueprint up is a connect, and the operator has no way to know the arm is about to sweep to a pose chosen inside the driver. It was redundant too, because ManipulationModule already adopts wherever the arm actually is as its init preset from the first joint state it receives.

The pose is now an explicit initial_positions argument, matching what the mock and a750 adapters already take, and rejected when its length does not match the arm's axis count the same way they reject it. With no argument the adapter commands nothing on either lifecycle edge. The existing activate test now asserts that no set_servo_angle reaches the SDK at all.

Verified on a headless launch of the hardware grasping blueprint further up this stack: every module comes up and the run stops only where it must, at the socket connect to the arm, with zero set_servo_angle calls in the log.

Second of nine in the xArm grasping re-landing stack.

XArmAdapter.activate() unconditionally drove the arm to a hardcoded joint pose
and deactivate() drove it there again on the way out. The pose was picked by
axis count from two module constants, _XARM6_INITIAL_JOINTS_DEG and
_XARM7_INITIAL_JOINTS_DEG, the latter carrying a "TODO change this once we have
7dof arm setup". Nothing asked for that motion: bringing a blueprint up is a
connect, and the operator has no way to know the arm is about to sweep to a pose
chosen in the driver. It was also redundant, because ManipulationModule adopts
wherever the arm actually is as its "init" preset from the first joint state it
receives.

The pose is now an explicit initial_positions argument, matching what the mock
and a750 adapters already take, and rejected when its length does not match the
arm's axis count the same way they reject it. With no argument the adapter
commands nothing on activate or deactivate.
@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change makes xArm lifecycle movement opt-in through configured initial joint positions and updates the associated adapter tests. It also changes the isolated RealSense Rust lockfile to dependency versions that no longer match its manifests. A locked Cargo check for the RealSense crate fails because Cargo must update the committed lockfile.

Merge safety: do not merge until dimos/hardware/sensors/camera/realsense/rust/Cargo.lock is regenerated from the isolated crate manifest and the locked Cargo check completes successfully.

Confidence Score: 4/5

The xArm behavior change is accompanied by focused tests, but the RealSense native crate cannot be built with its committed lockfile in locked mode.

A direct locked Cargo check reproduced one non-security build-breaking dependency-resolution issue.

Files Needing Attention: dimos/hardware/sensors/camera/realsense/rust/Cargo.lock needs to be regenerated against the crate's current manifests and local path dependencies.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding and linked it to the review comment.
  • The narrow lockfile validation script was executed to verify the project’s lockfile state.
  • Cargo reported that the lock file could not be updated because --locked was passed, indicating a required lockfile update.
  • The exact validation script and its output were captured to reproduce the run and inspect the failure.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 RealSense Rust lockfile is incompatible with its current manifest dependency graph

    • Bug
      • The isolated crate's locked Cargo check exits 101 because its lockfile must be updated. The crate requires validator 0.21 directly, while its local dimos-module dependency requires validator 0.21 and exactly zenoh 1.10.0; the committed lockfile instead resolves validator 0.20.0 and zenoh 1.9.0.
    • Cause
      • dimos/hardware/sensors/camera/realsense/rust/Cargo.lock is stale relative to unchanged manifests and local path dependency manifests.
    • Fix
      • Regenerate and commit the RealSense crate lockfile using its isolated manifest, resolving validator 0.21 and zenoh 1.10.0, then rerun cargo check --locked --manifest-path Cargo.toml from the crate directory.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "fix(xarm): stop commanding the arm on ev..." | Re-trigger Greptile

Comment on lines 3313 to +3316
name = "validator"
version = "0.21.0"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d68c6633c483df6780cc5277a417c7c2d1bceee2649d06c8ab6b0fd2dd3c81"
checksum = "43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 RealSense lockfile cannot satisfy locked builds

The isolated RealSense crate’s manifests require validator 0.21 and, through the local dimos-module dependency, exactly zenoh 1.10.0, but this lockfile records validator 0.20.0 and zenoh 1.9.0. Running cargo check --locked --manifest-path Cargo.toml in this crate exits with Cargo’s “cannot update the lock file” error, so reproducible and CI-style locked builds fail until the lockfile is regenerated and committed.

Artifacts

Executed narrow lockfile validation script

  • The exact shell script executed the isolated crate's locked Cargo check and printed manifest and lockfile evidence; takeaway: the validation path was narrow, reproducible, and did not edit repository source files.

Locked Cargo check reports a required lockfile update

  • Captured output from the executed isolated `cargo check --locked --manifest-path Cargo.toml` command shows exit 101 and Cargo's lockfile-update error; takeaway: the candidate failure is directly reproduced.

View artifacts

T-Rex Ran code and verified through T-Rex

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
4741 1 4740 39
View the top 1 failed test(s) by shortest run time
dimos.utils.test_shm::test_create_or_attach_splits_owner_and_reader
Stack Traces | 0.564s run time
name = 'dimos_test_d35b88276a0f'
slow_ftruncate = <function slow_ftruncate.<locals>.delayed at 0x7fdb956da980>

    def test_create_or_attach_splits_owner_and_reader(name, slow_ftruncate):
        """Concurrent symmetric callers: exactly one owns, the other waits and attaches."""
        out: list[tuple[bool, int]] = []
        lock = threading.Lock()
        barrier = threading.Barrier(2)
    
        def racer() -> None:
            barrier.wait()
            shm, owner = create_or_attach_shm(name, SIZE, timeout=5.0)
            with lock:
                out.append((owner, shm.size))
            shm.close()
    
        threads = [threading.Thread(target=racer, daemon=True) for _ in range(2)]
        for t in threads:
            t.start()
        for t in threads:
            t.join(timeout=8)
    
        assert len(out) == 2, f"a racer did not finish: {out}"
        assert sorted(owner for owner, _ in out) == [False, True]
>       assert {size for _, size in out} == {SIZE}
E       assert {0, 65536} == {65536}
E         
E         Extra items in the left set:
E         #x1B[0m#x1B[94m0#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
E         
E         Full diff:
E         #x1B[0m#x1B[90m #x1B[39;49;00m {#x1B[90m#x1B[39;49;00m
E         #x1B[92m+     0,#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
E         #x1B[90m #x1B[39;49;00m     65536,#x1B[90m#x1B[39;49;00m
E         #x1B[90m #x1B[39;49;00m }#x1B[90m#x1B[39;49;00m

barrier    = <threading.Barrier at 0x7fdb954b0230: waiters=0/2>
lock       = <unlocked _thread.lock object at 0x7fdb1ca891c0>
name       = 'dimos_test_d35b88276a0f'
out        = [(True, 65536), (False, 0)]
racer      = <function test_create_or_attach_splits_owner_and_reader.<locals>.racer at 0x7fdb956da520>
slow_ftruncate = <function slow_ftruncate.<locals>.delayed at 0x7fdb956da980>
t          = <Thread(Thread-2540 (racer), stopped daemon 140578272564928)>
threads    = [<Thread(Thread-2539 (racer), stopped daemon 140576005547712)>, <Thread(Thread-2540 (racer), stopped daemon 140578272564928)>]

dimos/utils/test_shm.py:148: AssertionError

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

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.

1 participant