# UFACTORY xArm7 · LeRobot (GELLO / Manual Drag) > [中文版本](README_ZH.md) UFACTORY xArm integration with the [LeRobot](https://github.com/huggingface/lerobot) framework, focused on two data-collection workflows: - **GELLO** — joint-space teleoperation with a Dynamixel leader arm - **Manual drag** — record demonstrations by freely moving the arm in xArm teach mode Collected data is stored in the standard LeRobot dataset format and can be used for imitation learning (ACT / Diffusion Policy, etc.) and real-time policy inference. ## Features - 🤖 UFACTORY xArm7 control - 🎮 GELLO joint-space teleoperation (Dynamixel leader arm) - ✋ Manual drag recording via xArm teach mode - 📷 Intel RealSense camera observation (D435 / D435i) - 📊 LeRobot-compatible dataset recording & management - 🧠 Imitation learning training and policy inference - ▶️ Episode replay for recorded manual demonstrations ## Requirements - Ubuntu 22.04 / 24.04 - Python >= 3.10 - CUDA >= 12.0 (recommended for GPU training) - UFACTORY xArm7 and its controller - GELLO arm (FTDI USB serial) - Intel RealSense D435 / D435i (for camera observations) ## Installation ```bash git clone https://git.weiyantech.cn/wangshuxun/Xarm-DataCollection.git lerobot_xarm7 cd lerobot_xarm7 uv venv --python 3.10 uv sync --extra gello ``` The base dependencies include `lerobot==0.4.3` (with Intel RealSense support), `xarm-python-sdk`, `numpy`, `pyyaml`, and `opencv-python`. The `gello` extra adds the GELLO software and Dynamixel SDK. ### Serial port permission The GELLO arm connects over a serial port, so add your user to the `dialout` group (re-login afterwards): ```bash sudo usermod -aG dialout $USER ``` Find the GELLO serial port path (used as `teleop.port` in the configs): ```bash ls /dev/serial/by-id/ ``` ## Configuration Predefined configs are provided under `config/`: | Workflow | Config | |---|---| | GELLO · xArm7 | `config/gello/xarm7_gello_record_config.yaml` | | Manual drag · xArm7 | `config/manual_mode/xarm7_manual_record_config.yaml` | ### GELLO config - `robot.robot_ip` — xArm controller IP (e.g. `192.168.1.245`) - `robot.robot_dof` — `7` - `robot.gripper_type` — `2` for the xArm Gripper G2 - `robot.gripper_speed` — G2 opening/closing speed in mm/s (`15`–`225`; configured as `100`) - `robot.gripper_force` — G2 gripping force (`1`–`100`; configured as `50`) - `teleop.port` — GELLO serial port (`/dev/serial/by-id/...`) - `teleop.joint_ids` / `teleop.joint_signs` — per-arm servo mapping and direction - `teleop.start_joints` — GELLO calibration reference, should match the xArm SDK initial point (degrees) - `teleop.gripper_id` — GELLO gripper servo ID (`8`; `-1` disables it) - `teleop.gripper_open_deg` / `teleop.gripper_close_deg` — GELLO servo calibration angles; these are independent of the G2's 0–84 mm opening range - `teleop.realtime_control_fps` — independent GELLO-to-xArm command loop rate; it is separate from `dataset.fps` - `dataset.root` / `dataset.repo_id` — where the dataset is stored - `dataset.single_task` — task description saved with each frame - `dataset.fps` / `episode_time_s` / `reset_time_s` — recording timing > The xArm7 config already contains the correct joint mapping; only edit the port, IP, and dataset fields for your setup. ### Manual-drag config - `robot.manual_mode: true` — enable xArm teach mode (joint free-drive) - `robot.teach_sensitivity` — teaching sensitivity, valid range 1–5 - `robot.manual_gripper_speed` — gripper velocity in normalized position per second (default `0.5`) - `robot.observe_joint_vel` — record joint velocities in observations (`false` by default) - `robot.enable_logs` — enable optional per-cycle timing/diagnostic logs (`false` by default) - `robot.cameras.camera` — Intel RealSense camera (`serial_number_or_name`, resolution, fps) - `dataset.root` / `dataset.repo_id` / `single_task` / `fps` / `episode_time_s` / `reset_time_s` / `num_episodes` — dataset settings ### Camera configuration When adding a camera to the robot config, use the template in `config/manual_mode/xarm7_manual_record_config.yaml`: ```yaml robot: cameras: camera: type: intelrealsense # RealSense type, NOT opencv serial_number_or_name: "148522072685" width: 640 height: 480 fps: 30 ``` - `type` must be `intelrealsense` (RealSense), **not** `opencv` (generic USB camera). - `serial_number_or_name` must be filled with the actual RealSense serial number **obtained beforehand**, otherwise connecting/recording fails. Get it with: ```bash uv run uf-camera-view -l -T realsense # prints each camera's serial number ``` or with the librealsense tool `rs-enumerate-devices`. ## Usage ### 1. GELLO teleop test Test the GELLO → robot control loop without recording: ```bash uv run uf-robot-teleop --config_path config/gello/xarm7_gello_record_config.yaml uv run uf-robot-teleop --config_path config/gello/xarm7_gello_record_config.yaml --fps 60 # optional loop rate ``` `Space` reset & start, `←` reset, `Esc` exit. #### Guard latency experiment This command runs for 60 seconds with the `min_tcp_z_mm` guard enabled and records the loop period, GELLO read, safety guard, ServoJ, and complete `send_action` latency: ```bash uv run uf-robot-teleop \ --config_path config/gello/xarm7_gello_record_config.yaml \ --robot.enable_logs=true \ --fps 60 \ --guard_latency_experiment=true \ --experiment_duration_s 60 ``` Press `Space` to reset and start. While staying safe, include motion both far from and near the configured height floor. With `tcp_z_guard_backend: local_projection`, the CSV `guard_path` column marks `local_safe`, `local_projected`, `local_hold`, or `model_fault`. The terminal prints per-path summaries. Results are written to `logs/gello_guard_latency_