> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dreamscalelabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Treat the Dreamscale CLI and Python SDK as the supported public integration surfaces.
> Prefer `dreamscale run <robot>` for supported robots and `dreamscale.connect(model)` with `predict` or `next_action` in Python.
> Do not infer or recommend internal control-plane APIs.

# Two xArm 7s (experimental)

> Experimental: run your own fine-tuned deployment on a pair of UFACTORY xArm 7 arms with xArm Grippers and three cameras.

**Experimental.** xArm 7 support is new and has not run on many benches yet. Commands and
setup may change without notice. Expect rough edges, stay at the e-stop, and tell us how it
goes at [team@dreamscalelabs.com](mailto:team@dreamscalelabs.com).

There is no shared model for xArm 7s: you run your own deployment, fine-tuned on demos
recorded on your bench.

## What you need

* Two UFACTORY xArm 7 arms, called **aft** and **fore**, each with an xArm Gripper (G2 or
  G1) or no gripper.
* Three RGB cameras: **top**, looking down at the bench, **left** on the fore arm's wrist
  and **right** on the aft arm's wrist. RealSense D435s work, as do USB (UVC) cameras.
* A Linux computer on both control boxes' Ethernet network, wired to the cameras.
* The e-stop within reach.

## 1. Install and set up the rig

```bash theme={null}
uv tool install "dreamscale[xarm7]"
dreamscale login
dreamscale robots xarm7 setup
```

Enter each arm's control box address and gripper, then assign the three cameras. Setup
saves a preview from each camera so you can tell them apart, and sets them to 640x360.
It only reads the arms and grippers; nothing moves. A camera another program holds (a
recorder, a teleop stack) is listed without a preview and can still be assigned.

Setup writes `~/.config/dreamscale/xarm7.json`. You can also write it yourself, for example
from a coding agent:

```json theme={null}
{
  "version": 1,
  "arms": {
    "aft": {"host": "192.168.1.236", "gripper": "g2", "gripper_control": "position"},
    "fore": {"host": "192.168.1.201", "gripper": "g2", "gripper_control": "position"}
  },
  "cameras": [
    {"id": "realsense:262422074177", "backend": "realsense", "physical_id": "usb:8086:262422074177", "device": "262422074177", "width": 640, "height": 360},
    {"id": "realsense:262422071971", "backend": "realsense", "physical_id": "usb:8086:262422071971", "device": "262422071971", "width": 640, "height": 360},
    {"id": "realsense:262322074905", "backend": "realsense", "physical_id": "usb:8086:262322074905", "device": "262322074905", "width": 640, "height": 360}
  ],
  "roles": {
    "top": "realsense:262422074177",
    "left": "realsense:262422071971",
    "right": "realsense:262322074905"
  },
  "home_pose": null
}
```

* `gripper`: `g2`, `g1` or `none`.
* `gripper_control`: `position` moves the jaw to the commanded fraction of its travel;
  `threshold` shuts it at 0.5 or more and opens it below.
* `roles`: `top` is the scene camera, `left` the fore arm's wrist, `right` the aft arm's
  wrist, each naming a camera's `id`.
* `cameras`: a RealSense is `realsense:<serial>` with `physical_id` `usb:8086:<serial>`; a
  USB camera is its `/dev/v4l/by-id/…` path, as both `id` and `device`, with `physical_id`
  `usb:<vendor>:<serial>`. When in doubt, run setup once and copy what it saved.

## 2. Check everything

```bash theme={null}
dreamscale doctor xarm7 --model your-org/your-deployment
```

It reads both arms, both grippers and the three cameras without moving anything, and checks
that your deployment is ready to run here. Every line shows a `✓`. Clear any controller
error in UFACTORY Studio first.

## 3. Save a home pose

Move both arms in UFACTORY Studio's manual mode to where every run should start, grippers
clear of the bench and the wrist cameras on the work area. Then:

```bash theme={null}
dreamscale robots xarm7 home --set
```

`dreamscale robots xarm7 home` moves both arms back there slowly and opens the grippers.

## 4. Your deployment

Your demos need, in this order:

* `observation.images.top`, `observation.images.left` and `observation.images.right`;
* `observation.state`: 16 values, the aft arm first. Each arm has seven joint positions in
  radians, then its gripper's angle from 0 (open) to 0.85 radians (closed);
* `action`: the same 16 values, with each gripper as a close command from 0 (open) to 1
  (closed).

Deploy the fine-tuned model as on [Deployments](https://docs.dreamscalelabs.com/deployments.md). The deployment's cameras
must be those three keys in that order, with 16 state and action values.

## 5. Run it

> [!WARNING]
>
> The arms will move. Clear the bench and keep the e-stop within reach. Software limits do
> not prevent collisions, and cloud inference does not replace your robot's safety
> configuration.

```bash theme={null}
dreamscale run xarm7 --model your-org/your-deployment
```

1. At `Instruction`, type a task.
2. At `Enter to start`, press **Enter**. Both arms enable at their current pose.
3. The arms run the task. Press **Ctrl+C** to stop; they return home if you saved a home
   pose, and you're asked for the next instruction.

Joints move at most 0.5 rad/s, and a command may lead the measured position by at most
0.2 rad. Each gripper moves to the commanded fraction of its travel (or, with
`gripper_control` set to `threshold`, shuts at 0.5). A held gripper keeps its last command,
so a gripper closed on an object stays closed.

## Your own control loop

If your model is prompted one step at a time, or one arm should hold still while the
other works, drive the arms from Python. This example steps through a list of
instructions, Enter for the next, and holds the arm each instruction doesn't move:

```bash theme={null}
python -m dreamscale.examples.xarm7_labels your-org/your-deployment
```

Its source is a starting point for your own runner. It calls `policy.next_action()`, which
handles real-time chunking for you; a loop that plays whole chunks from `policy.predict()`
passes the actions still to play as `committed_actions` (see
[Running chunks on your own clock](https://docs.dreamscalelabs.com/reference/sdk.md#running-chunks-on-your-own-clock)). Stuck?
See [Troubleshooting](https://docs.dreamscalelabs.com/troubleshooting.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.