Add reset after manual mode in temp script

This commit is contained in:
Saberlve 2026-08-07 13:15:46 +08:00
parent 4dfed85048
commit 75bbbed689
4 changed files with 105 additions and 66 deletions

View File

@ -55,12 +55,9 @@ UFACTORY robot arm integration with the LeRobot framework for robot learning, da
git clone https://github.com/xArm-Developer/lerobot_robot_ufactory.git git clone https://github.com/xArm-Developer/lerobot_robot_ufactory.git
cd lerobot_robot_ufactory cd lerobot_robot_ufactory
# Create conda environment # Create a uv virtual environment and sync project dependencies
conda create -n uf_lerobot python=3.10 -y uv venv --python 3.10
conda activate uf_lerobot uv sync
# Install project
pip install -e .
``` ```
Includes: `lerobot==0.4.3`, `xarm-python-sdk`, `numpy`, `pyyaml`. LeRobot already pulls in torch, opencv, wandb, etc. Includes: `lerobot==0.4.3`, `xarm-python-sdk`, `numpy`, `pyyaml`. LeRobot already pulls in torch, opencv, wandb, etc.
@ -77,7 +74,7 @@ Dynamixel-based leader arm, joint-space control.
```bash ```bash
# 1. Install GELLO module # 1. Install GELLO module
pip install -e ".[gello]" uv sync --extra gello
# 2. Add serial port permissions (re-login required) # 2. Add serial port permissions (re-login required)
sudo usermod -aG dialout $USER sudo usermod -aG dialout $USER
@ -91,7 +88,7 @@ Pika Sense handheld + Vive Tracker, Cartesian-space control.
```bash ```bash
# 1. Install peripheral deps (skip transitive deps) # 1. Install peripheral deps (skip transitive deps)
pip install pysurvive agx-pypika --no-deps uv pip install pysurvive agx-pypika --no-deps
# 2. Install udev rules (re-plug devices afterwards) # 2. Install udev rules (re-plug devices afterwards)
sudo cp src/rules/*.rules /etc/udev/rules.d/ sudo cp src/rules/*.rules /etc/udev/rules.d/
@ -110,7 +107,7 @@ curl -sL https://raw.githubusercontent.com/xArm-Developer/ufactory_resources/mai
sudo apt install -y --fix-broken sudo apt install -y --fix-broken
# 2. Install peripheral deps # 2. Install peripheral deps
pip install pysurvive --no-deps uv pip install pysurvive --no-deps
# 3. Install udev rules (re-plug devices afterwards) # 3. Install udev rules (re-plug devices afterwards)
sudo cp src/rules/*.rules /etc/udev/rules.d/ sudo cp src/rules/*.rules /etc/udev/rules.d/
@ -135,7 +132,7 @@ sudo reboot
```bash ```bash
# 1. Install SpaceMouse module # 1. Install SpaceMouse module
pip install -e ".[spacemouse]" uv sync --extra spacemouse
# 2. Install udev rules (re-plug device afterwards) # 2. Install udev rules (re-plug device afterwards)
sudo cp src/rules/*.rules /etc/udev/rules.d/ sudo cp src/rules/*.rules /etc/udev/rules.d/
@ -151,36 +148,46 @@ Test teleop-to-robot control loop without recording.
```bash ```bash
# Generic usage # Generic usage
uf-robot-teleop --config_path path/to/config.yaml uv run uf-robot-teleop --config_path path/to/config.yaml
uf-robot-teleop --config_path path/to/config.yaml --fps 60 # specify frequency uv run uf-robot-teleop --config_path path/to/config.yaml --fps 60 # specify frequency
# Example: xArm6 + UMI teleop # Example: xArm6 + UMI teleop
uf-robot-teleop --config_path config/umi/xarm6_umi_record_config.yaml uv run uf-robot-teleop --config_path config/umi/xarm6_umi_record_config.yaml
``` ```
### 2. Data Collection ### 2. xArm Manual Drag Mode
Use xArm joint teaching mode (`mode=2`) for manual dragging:
```bash
uv run uf-xarm-manual-mode --config_path config/manual_mode/xarm_manual_mode_config.yaml
```
Set `manual_mode` to `true` to enter drag mode. Press Enter to restore normal mode; set it to `false` to restore normal mode directly. With `return_to_initial: true`, the script reads the saved initial point through the xArm Studio API and returns to it when drag mode exits.
### 3. Data Collection
Record datasets via teleop. Record datasets via teleop.
```bash ```bash
# Generic usage # Generic usage
uf-lerobot-record --config_path path/to/record_config.yaml uv run uf-lerobot-record --config_path path/to/record_config.yaml
uf-lerobot-record --config_path path/to/config.yaml --resume true # resume recording uv run uf-lerobot-record --config_path path/to/config.yaml --resume true # resume recording
# Example: xArm6 + UMI data collection # Example: xArm6 + UMI data collection
uf-lerobot-record --config_path config/umi/xarm6_umi_record_config.yaml uv run uf-lerobot-record --config_path config/umi/xarm6_umi_record_config.yaml
``` ```
### 3. Policy Training ### 4. Policy Training
Train imitation learning policies on collected data. Train imitation learning policies on collected data.
```bash ```bash
# Generic usage # Generic usage
lerobot-train --policy act --dataset your_dataset_name uv run lerobot-train --policy act --dataset your_dataset_name
# Example: train ACT on xArm6 UMI dataset # Example: train ACT on xArm6 UMI dataset
lerobot-train --policy act --dataset ufactory/xarm6_umi_datas uv run lerobot-train --policy act --dataset ufactory/xarm6_umi_datas
``` ```
Important parameters: Important parameters:
@ -189,7 +196,7 @@ Important parameters:
# Note: repo_id is the same as in the record config # Note: repo_id is the same as in the record config
# Policy type: ACT, training steps: 800k # Policy type: ACT, training steps: 800k
# Checkpoints saved every 20k steps, output to lerobot_datas/train (sibling of lerobot directory) # Checkpoints saved every 20k steps, output to lerobot_datas/train (sibling of lerobot directory)
lerobot-train \ uv run lerobot-train \
--dataset.root=../../../../lerobot_datas/record/ufactory/xarm6_umi_datas \ --dataset.root=../../../../lerobot_datas/record/ufactory/xarm6_umi_datas \
--dataset.repo_id=ufactory/xarm6_umi_datas \ --dataset.repo_id=ufactory/xarm6_umi_datas \
--policy.type=act \ --policy.type=act \
@ -202,16 +209,16 @@ lerobot-train \
--save_freq=20000 --save_freq=20000
``` ```
### 4. Inference & Evaluation ### 5. Inference & Evaluation
Run inference with a trained policy. Run inference with a trained policy.
```bash ```bash
# Generic usage # Generic usage
uf-lerobot-eval --config_path path/to/config.yaml --policy.path your_train_path uv run uf-lerobot-eval --config_path path/to/config.yaml --policy.path your_train_path
# Example: run inference with trained ACT policy # Example: run inference with trained ACT policy
uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.path ../../../../lerobot_datas/train/xarm6_umi_datas/checkpoints/last/pretrained_model/ uv run uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.path ../../../../lerobot_datas/train/xarm6_umi_datas/checkpoints/last/pretrained_model/
``` ```
## Tools ## Tools
@ -221,11 +228,11 @@ uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.p
View and stitch multiple camera feeds. View and stitch multiple camera feeds.
```bash ```bash
uf-camera-view -l # list all cameras uv run uf-camera-view -l # list all cameras
uf-camera-view -l -T xvisio # list XVisio cameras only uv run uf-camera-view -l -T xvisio # list XVisio cameras only
uf-camera-view -T xvisio # view XVisio cameras (default 1280x1280 YU12) uv run uf-camera-view -T xvisio # view XVisio cameras (default 1280x1280 YU12)
uf-camera-view -T xvisio -W 640 -H 1920 -F NV12 # specify format uv run uf-camera-view -T xvisio -W 640 -H 1920 -F NV12 # specify format
uf-camera-view -T other # view other camera types uv run uf-camera-view -T other # view other camera types
``` ```
### 2. LeRobot Dataset Tools ### 2. LeRobot Dataset Tools
@ -235,7 +242,7 @@ LeRobot provides dataset utilities for inspecting, editing and managing collecte
#### View an episode: #### View an episode:
e.g. view episode index 17: e.g. view episode index 17:
```bash ```bash
lerobot-dataset-viz \ uv run lerobot-dataset-viz \
--root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \ --root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \
--repo-id ufactory/xarm7_record_datas \ --repo-id ufactory/xarm7_record_datas \
--display-compressed-images true \ --display-compressed-images true \
@ -245,7 +252,7 @@ lerobot-dataset-viz \
#### Delete specific episodes: #### Delete specific episodes:
e.g. delete episodes 18 and 19: e.g. delete episodes 18 and 19:
```bash ```bash
lerobot-edit-dataset \ uv run lerobot-edit-dataset \
--root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \ --root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \
--repo_id ufactory/xarm7_record_datas \ --repo_id ufactory/xarm7_record_datas \
--new_repo_id ../xarm7_record_datas_new \ --new_repo_id ../xarm7_record_datas_new \
@ -255,7 +262,7 @@ lerobot-edit-dataset \
#### Merge datasets: #### Merge datasets:
```bash ```bash
lerobot-edit-dataset \ uv run lerobot-edit-dataset \
--root=../../../../lerobot_datas/record \ --root=../../../../lerobot_datas/record \
--repo_id ufactory/xarm7_record_datas_merge_1_2 \ --repo_id ufactory/xarm7_record_datas_merge_1_2 \
--operation.type merge \ --operation.type merge \

View File

@ -55,12 +55,9 @@ UFACTORY(深圳市众为创造科技有限公司) 机械臂与 LeRobot 框架集
git clone https://github.com/xArm-Developer/lerobot_robot_ufactory.git git clone https://github.com/xArm-Developer/lerobot_robot_ufactory.git
cd lerobot_robot_ufactory cd lerobot_robot_ufactory
# 创建 conda 环境 # 创建 uv 虚拟环境并同步项目依赖
conda create -n uf_lerobot python=3.10 -y uv venv --python 3.10
conda activate uf_lerobot uv sync
# 安装项目
pip install -e .
``` ```
包含:`lerobot==0.4.3`、`xarm-python-sdk`、`numpy`、`pyyaml`lerobot 已自动携带 torch、opencv、wandb 等训练相关依赖)。 包含:`lerobot==0.4.3`、`xarm-python-sdk`、`numpy`、`pyyaml`lerobot 已自动携带 torch、opencv、wandb 等训练相关依赖)。
@ -77,7 +74,7 @@ pip install -e .
```bash ```bash
# 1. 安装 GELLO 模块 # 1. 安装 GELLO 模块
pip install -e ".[gello]" uv sync --extra gello
# 2. 添加串口权限(重新登录后生效) # 2. 添加串口权限(重新登录后生效)
sudo usermod -aG dialout $USER sudo usermod -aG dialout $USER
@ -91,7 +88,7 @@ sudo usermod -aG dialout $USER
```bash ```bash
# 1. 安装外设依赖(不需要它们的间接依赖) # 1. 安装外设依赖(不需要它们的间接依赖)
pip install pysurvive agx-pypika --no-deps uv pip install pysurvive agx-pypika --no-deps
# 2. 安装 udev 规则(重新插拔设备后生效) # 2. 安装 udev 规则(重新插拔设备后生效)
sudo cp rules/*.rules /etc/udev/rules.d/ sudo cp rules/*.rules /etc/udev/rules.d/
@ -110,7 +107,7 @@ curl -sL https://raw.githubusercontent.com/xArm-Developer/ufactory_resources/mai
sudo apt install -y --fix-broken sudo apt install -y --fix-broken
# 2. 安装外设依赖 # 2. 安装外设依赖
pip install pysurvive --no-deps uv pip install pysurvive --no-deps
# 3. 安装 udev 规则(重新插拔设备后生效) # 3. 安装 udev 规则(重新插拔设备后生效)
sudo cp rules/*.rules /etc/udev/rules.d/ sudo cp rules/*.rules /etc/udev/rules.d/
@ -135,7 +132,7 @@ sudo reboot
```bash ```bash
# 1. 安装 SpaceMouse 模块 # 1. 安装 SpaceMouse 模块
pip install -e ".[spacemouse]" uv sync --extra spacemouse
# 2. 安装 udev 规则(重新插拔设备后生效) # 2. 安装 udev 规则(重新插拔设备后生效)
sudo cp rules/*.rules /etc/udev/rules.d/ sudo cp rules/*.rules /etc/udev/rules.d/
@ -150,11 +147,11 @@ sudo udevadm control --reload-rules && sudo udevadm trigger
```bash ```bash
# 通用格式 # 通用格式
uf-robot-teleop --config_path path/to/config.yaml uv run uf-robot-teleop --config_path path/to/config.yaml
uf-robot-teleop --config_path path/to/config.yaml --fps 60 # 指定频率 uv run uf-robot-teleop --config_path path/to/config.yaml --fps 60 # 指定频率
# 示例: xArm6 + UMI 遥操作 # 示例: xArm6 + UMI 遥操作
uf-robot-teleop --config_path config/umi/xarm6_umi_record_config.yaml uv run uf-robot-teleop --config_path config/umi/xarm6_umi_record_config.yaml
``` ```
### 2. xArm 人工拖拽模式测试 ### 2. xArm 人工拖拽模式测试
@ -162,10 +159,10 @@ uf-robot-teleop --config_path config/umi/xarm6_umi_record_config.yaml
使用 xArm 的关节示教模式(`mode=2`)进行人工拖拽: 使用 xArm 的关节示教模式(`mode=2`)进行人工拖拽:
```bash ```bash
uf-xarm-manual-mode --config_path config/manual_mode/xarm_manual_mode_config.yaml uv run uf-xarm-manual-mode --config_path config/manual_mode/xarm_manual_mode_config.yaml
``` ```
配置中的 `manual_mode``true` 时进入拖拽模式,按回车后恢复为普通模式;设置为 `false` 可直接恢复为普通模式。 配置中的 `manual_mode``true` 时进入拖拽模式,按回车后恢复为普通模式;设置为 `false` 可直接恢复为普通模式。`return_to_initial: true` 会通过 xArm Studio 接口读取保存的初始位置,并在退出拖拽后自动回位。
### 3. 数据采集 ### 3. 数据采集
@ -173,11 +170,11 @@ uf-xarm-manual-mode --config_path config/manual_mode/xarm_manual_mode_config.yam
```bash ```bash
# 通用格式 # 通用格式
uf-lerobot-record --config_path path/to/record_config.yaml uv run uf-lerobot-record --config_path path/to/record_config.yaml
uf-lerobot-record --config_path path/to/config.yaml --resume true # 续录 uv run uf-lerobot-record --config_path path/to/config.yaml --resume true # 续录
# 示例: xArm6 + UMI 数据采集 # 示例: xArm6 + UMI 数据采集
uf-lerobot-record --config_path config/umi/xarm6_umi_record_config.yaml uv run uf-lerobot-record --config_path config/umi/xarm6_umi_record_config.yaml
``` ```
### 4. Lerobot训练 ### 4. Lerobot训练
@ -186,7 +183,7 @@ uf-lerobot-record --config_path config/umi/xarm6_umi_record_config.yaml
```bash ```bash
# 通用格式 # 通用格式
lerobot-train --policy act --dataset your_dataset_name uv run lerobot-train --policy act --dataset your_dataset_name
``` ```
参数示例: 参数示例:
@ -195,7 +192,7 @@ lerobot-train --policy act --dataset your_dataset_name
# 注意: repo_id就是采集时配置文件里面的repo_id # 注意: repo_id就是采集时配置文件里面的repo_id
# 这里训练策略policy.type选用act训练steps为80w次 # 这里训练策略policy.type选用act训练steps为80w次
# 训练过程每2w次保存一次结果结果输出到和lerobot同级目录下的lerobot_datas/train里面 # 训练过程每2w次保存一次结果结果输出到和lerobot同级目录下的lerobot_datas/train里面
lerobot-train \ uv run lerobot-train \
--dataset.root=../../../../lerobot_datas/record/ufactory/xarm6_umi_datas \ --dataset.root=../../../../lerobot_datas/record/ufactory/xarm6_umi_datas \
--dataset.repo_id=ufactory/xarm6_umi_datas \ --dataset.repo_id=ufactory/xarm6_umi_datas \
--policy.type=act \ --policy.type=act \
@ -214,10 +211,10 @@ lerobot-train \
```bash ```bash
# 通用格式 # 通用格式
uf-lerobot-eval --config_path path/to/config.yaml --policy.path your_train_path uv run uf-lerobot-eval --config_path path/to/config.yaml --policy.path your_train_path
# 示例:使用训练好的 ACT 策略进行推理 # 示例:使用训练好的 ACT 策略进行推理
uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.path ../../../../lerobot_datas/train/xarm6_umi_datas/checkpoints/last/pretrained_model/ uv run uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.path ../../../../lerobot_datas/train/xarm6_umi_datas/checkpoints/last/pretrained_model/
``` ```
## 工具集 ## 工具集
@ -227,11 +224,11 @@ uf-lerobot-eval --config_path config/umi/xarm6_umi_record_config.yaml --policy.p
查看和拼接多路摄像头画面。 查看和拼接多路摄像头画面。
```bash ```bash
uf-camera-view -l # 列出所有摄像头 uv run uf-camera-view -l # 列出所有摄像头
uf-camera-view -l -T xvisio # 仅列出 XVisio 摄像头 uv run uf-camera-view -l -T xvisio # 仅列出 XVisio 摄像头
uf-camera-view -T xvisio # 查看 XVisio 摄像头(默认 1280x1280 YU12 uv run uf-camera-view -T xvisio # 查看 XVisio 摄像头(默认 1280x1280 YU12
uf-camera-view -T xvisio -W 640 -H 1920 -F NV12 # 指定格式 uv run uf-camera-view -T xvisio -W 640 -H 1920 -F NV12 # 指定格式
uf-camera-view -T other # 查看其他类型摄像头 uv run uf-camera-view -T other # 查看其他类型摄像头
``` ```
### 2. Lerobot数据集工具 ### 2. Lerobot数据集工具
@ -240,7 +237,7 @@ Lerobot提供一些数据集工具方便对采集的数据集进行增删查
### 查看某个索引的episode: ### 查看某个索引的episode:
例如查看索引号为17的episode: 例如查看索引号为17的episode:
```bash ```bash
lerobot-dataset-viz \ uv run lerobot-dataset-viz \
--root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \ --root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \
--repo-id ufactory/xarm7_record_datas \ --repo-id ufactory/xarm7_record_datas \
--display-compressed-images true \ --display-compressed-images true \
@ -250,7 +247,7 @@ lerobot-dataset-viz \
### 删除某些索引的episodes: ### 删除某些索引的episodes:
例如删除索引号为18和19的episode: 例如删除索引号为18和19的episode:
```bash ```bash
lerobot-edit-dataset \ uv run lerobot-edit-dataset \
--root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \ --root=../../../../lerobot_datas/record/ufactory/xarm7_record_datas \
--repo_id ufactory/xarm7_record_datas \ --repo_id ufactory/xarm7_record_datas \
--new_repo_id ../xarm7_record_datas_new \ --new_repo_id ../xarm7_record_datas_new \
@ -260,7 +257,7 @@ lerobot-edit-dataset \
### 合并数据集 ### 合并数据集
```bash ```bash
lerobot-edit-dataset \ uv run lerobot-edit-dataset \
--root=../../../../lerobot_datas/record \ --root=../../../../lerobot_datas/record \
--repo_id ufactory/xarm7_record_datas_merge_1_2 \ --repo_id ufactory/xarm7_record_datas_merge_1_2 \
--operation.type merge \ --operation.type merge \

View File

@ -6,3 +6,9 @@ manual_mode: true
# xArm teach sensitivity, valid range: 1-5. # xArm teach sensitivity, valid range: 1-5.
teach_sensitivity: 3 teach_sensitivity: 3
# Read the initial point saved in xArm Studio and return to it after pressing Enter.
return_to_initial: true
# Return speed in degrees per second.
reset_speed: 30

View File

@ -14,6 +14,8 @@ class ManualModeConfig:
robot_ip: str = "192.168.1.127" robot_ip: str = "192.168.1.127"
manual_mode: bool = True manual_mode: bool = True
teach_sensitivity: int | None = 3 teach_sensitivity: int | None = 3
return_to_initial: bool = True
reset_speed: float = 30.0
@config_parser.wrap() @config_parser.wrap()
@ -24,8 +26,11 @@ def get_cfg(cfg: ManualModeConfig) -> ManualModeConfig:
def run(cfg: ManualModeConfig): def run(cfg: ManualModeConfig):
if cfg.teach_sensitivity is not None and not 1 <= cfg.teach_sensitivity <= 5: if cfg.teach_sensitivity is not None and not 1 <= cfg.teach_sensitivity <= 5:
raise ValueError("teach_sensitivity must be between 1 and 5") raise ValueError("teach_sensitivity must be between 1 and 5")
if cfg.reset_speed <= 0:
raise ValueError("reset_speed must be greater than 0")
arm = XArmAPI(cfg.robot_ip) arm = XArmAPI(cfg.robot_ip)
initial_point = None
try: try:
if not arm.connected: if not arm.connected:
raise ConnectionError(f"Failed to connect to xArm at {cfg.robot_ip}") raise ConnectionError(f"Failed to connect to xArm at {cfg.robot_ip}")
@ -35,6 +40,16 @@ def run(cfg: ManualModeConfig):
arm.set_mode(0) arm.set_mode(0)
arm.set_state(0) arm.set_state(0)
code, initial_point = arm.get_initial_point()
if code != 0:
raise RuntimeError(f"get_initial_point failed, code={code}")
if not initial_point or len(initial_point) < arm.axis:
raise RuntimeError(
f"Invalid initial point returned by xArm: {initial_point}"
)
initial_point = list(initial_point[:arm.axis])
print(f"Initial point loaded from xArm Studio: {initial_point}")
if cfg.manual_mode: if cfg.manual_mode:
if cfg.teach_sensitivity is not None: if cfg.teach_sensitivity is not None:
code = arm.set_teach_sensitivity(cfg.teach_sensitivity) code = arm.set_teach_sensitivity(cfg.teach_sensitivity)
@ -60,10 +75,24 @@ def run(cfg: ManualModeConfig):
print("Joint teaching mode disabled.") print("Joint teaching mode disabled.")
finally: finally:
if arm.connected: if arm.connected:
# Always leave the robot in normal position-control mode. try:
arm.set_mode(0) arm.set_mode(0)
arm.set_state(0) arm.set_state(0)
arm.disconnect() if cfg.return_to_initial and initial_point is not None:
_move_to_initial(arm, initial_point, cfg.reset_speed)
finally:
arm.disconnect()
def _move_to_initial(arm: XArmAPI, initial_point: list[float], speed: float):
code = arm.set_servo_angle(
angle=initial_point,
speed=speed,
is_radian=False,
wait=True,
)
if code != 0:
raise RuntimeError(f"Failed to move to xArm initial point, code={code}")
def main(): def main():