Fix bug in camera config
This commit is contained in:
parent
c04fcf4427
commit
d336b73aa3
3
.gitignore
vendored
3
.gitignore
vendored
@ -88,4 +88,5 @@ models/
|
|||||||
*.trt
|
*.trt
|
||||||
*.xvcd
|
*.xvcd
|
||||||
ufactory_usage/
|
ufactory_usage/
|
||||||
.history/
|
.history/
|
||||||
|
xarm7_manual_datas
|
||||||
20
README.md
20
README.md
@ -155,28 +155,18 @@ uv run uf-robot-teleop --config_path path/to/config.yaml --fps 60 # specify fre
|
|||||||
uv run 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 Manual Drag Mode
|
### 2. Manual Drag Data Collection
|
||||||
|
|
||||||
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. Manual Drag Data Collection
|
|
||||||
|
|
||||||
Manual drag recording uses `manual_mode: true` in the robot configuration and does not configure a teleoperator. During recording, the actual joint state is written as both the observation and action in the LeRobot dataset. When a gripper is configured, hold `C` to close it slowly and `O` to open it slowly. Adjust the speed with `manual_gripper_speed`, which defaults to `0.5`:
|
Manual drag recording uses `manual_mode: true` in the robot configuration and does not configure a teleoperator. During recording, the actual joint state is written as both the observation and action in the LeRobot dataset. When a gripper is configured, hold `C` to close it slowly and `O` to open it slowly. Adjust the speed with `manual_gripper_speed`, which defaults to `0.5`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run uf-lerobot-record --config_path config/manual_mode/xarm7_manual_record_config.yaml
|
./start_manual_record.sh
|
||||||
uv run uf-lerobot-record --config_path config/manual_mode/xarm7_manual_record_config.yaml --resume true
|
./start_manual_record.sh -r
|
||||||
```
|
```
|
||||||
|
|
||||||
Press `Space` to start an episode, `Right` to save it, `Left` to discard and re-record it, and `Esc` to stop recording. Reset the arm manually between episodes.
|
The launcher creates a dataset on its first run and automatically resumes an existing valid dataset. If it reports an empty or incomplete dataset directory, choose a new `dataset.root` or remove that directory after confirming it contains no data. Press `Space` to start an episode, `Right` to save it, `Left` to discard and re-record it, and `Esc` to stop recording. Reset the arm manually between episodes.
|
||||||
|
|
||||||
### 4. Teleop Data Collection
|
### 3. Teleop Data Collection
|
||||||
|
|
||||||
Record datasets via teleop.
|
Record datasets via teleop.
|
||||||
|
|
||||||
|
|||||||
20
README_ZH.md
20
README_ZH.md
@ -154,28 +154,18 @@ uv run uf-robot-teleop --config_path path/to/config.yaml --fps 60 # 指定频
|
|||||||
uv run 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 的关节示教模式(`mode=2`)进行人工拖拽:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv run uf-xarm-manual-mode --config_path config/manual_mode/xarm_manual_mode_config.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
配置中的 `manual_mode` 为 `true` 时进入拖拽模式,按回车后恢复为普通模式;设置为 `false` 可直接恢复为普通模式。`return_to_initial: true` 会通过 xArm Studio 接口读取保存的初始位置,并在退出拖拽后自动回位。
|
|
||||||
|
|
||||||
### 3. 人工拖拽数据采集
|
|
||||||
|
|
||||||
人工拖拽录制使用 robot 配置中的 `manual_mode: true`,不需要配置 teleop。录制过程中,机械臂的实际关节状态会作为 observation 和 action 写入 LeRobot 数据集;如果配置了夹爪,还可以按住 `C` 缓慢闭合、按住 `O` 缓慢张开。夹爪速度通过 `manual_gripper_speed` 配置,默认值为 `0.5`:
|
人工拖拽录制使用 robot 配置中的 `manual_mode: true`,不需要配置 teleop。录制过程中,机械臂的实际关节状态会作为 observation 和 action 写入 LeRobot 数据集;如果配置了夹爪,还可以按住 `C` 缓慢闭合、按住 `O` 缓慢张开。夹爪速度通过 `manual_gripper_speed` 配置,默认值为 `0.5`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run uf-lerobot-record --config_path config/manual_mode/xarm7_manual_record_config.yaml
|
./start_manual_record.sh
|
||||||
uv run uf-lerobot-record --config_path config/manual_mode/xarm7_manual_record_config.yaml --resume true
|
./start_manual_record.sh -r
|
||||||
```
|
```
|
||||||
|
|
||||||
按 `Space` 开始当前 episode,按 `Right` 保存,按 `Left` 放弃并重录当前 episode,按 `Esc` 停止录制。episode 之间可以手动复位机械臂。
|
启动脚本首次运行时创建数据集,检测到有效数据集时会自动续录。如果提示数据目录为空或不完整,请修改 `dataset.root`,或者确认没有数据后删除该目录。按 `Space` 开始当前 episode,按 `Right` 保存,按 `Left` 放弃并重录当前 episode,按 `Esc` 停止录制。episode 之间可以手动复位机械臂。
|
||||||
|
|
||||||
### 4. 遥操作数据采集
|
### 3. 遥操作数据采集
|
||||||
|
|
||||||
通过遥操作录制数据集。
|
通过遥操作录制数据集。
|
||||||
|
|
||||||
|
|||||||
@ -15,11 +15,16 @@ robot:
|
|||||||
# Whether to record joint velocities in observations.
|
# Whether to record joint velocities in observations.
|
||||||
observe_joint_vel: false
|
observe_joint_vel: false
|
||||||
|
|
||||||
# Camera definitions; leave empty when no cameras are used.
|
cameras:
|
||||||
cameras: {}
|
camera:
|
||||||
|
type: intelrealsense
|
||||||
|
serial_number_or_name: "148522072685"
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
fps: 30
|
||||||
|
|
||||||
dataset:
|
dataset:
|
||||||
root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm7_manual_datas"
|
root: "/home/wsx/code/lerobot_robot_ufactory/xarm7_manual_datas"
|
||||||
repo_id: "ufactory/xarm7_manual_datas"
|
repo_id: "ufactory/xarm7_manual_datas"
|
||||||
# Task description stored with each recorded frame.
|
# Task description stored with each recorded frame.
|
||||||
single_task: "Describe the task being demonstrated."
|
single_task: "Describe the task being demonstrated."
|
||||||
|
|||||||
@ -34,7 +34,6 @@ dependencies = [
|
|||||||
[project.scripts]
|
[project.scripts]
|
||||||
uf-robot-teleop = "lerobot_robot_ufactory.scripts.uf_robot_teleop:main"
|
uf-robot-teleop = "lerobot_robot_ufactory.scripts.uf_robot_teleop:main"
|
||||||
uf-lerobot-record = "lerobot_robot_ufactory.scripts.uf_lerobot_record:main"
|
uf-lerobot-record = "lerobot_robot_ufactory.scripts.uf_lerobot_record:main"
|
||||||
uf-xarm-manual-mode = "lerobot_robot_ufactory.scripts.uf_xarm_manual_mode:main"
|
|
||||||
uf-lerobot-eval = "lerobot_robot_ufactory.scripts.uf_lerobot_eval:main"
|
uf-lerobot-eval = "lerobot_robot_ufactory.scripts.uf_lerobot_eval:main"
|
||||||
uf-vive-calibrate = "lerobot_robot_ufactory.scripts.vive_calibrate:main"
|
uf-vive-calibrate = "lerobot_robot_ufactory.scripts.vive_calibrate:main"
|
||||||
uf-camera-view = "lerobot_robot_ufactory.scripts.uf_camera_view:main"
|
uf-camera-view = "lerobot_robot_ufactory.scripts.uf_camera_view:main"
|
||||||
|
|||||||
@ -1,107 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import sys
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
import lerobot_robot_ufactory # noqa: F401 # register UFACTORY plugins
|
|
||||||
from xarm.wrapper import XArmAPI
|
|
||||||
from lerobot_robot_ufactory.configs import parser as config_parser
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ManualModeConfig:
|
|
||||||
robot_ip: str = "192.168.1.127"
|
|
||||||
manual_mode: bool = True
|
|
||||||
teach_sensitivity: int | None = 3
|
|
||||||
return_to_initial: bool = True
|
|
||||||
reset_speed: float = 30.0
|
|
||||||
|
|
||||||
|
|
||||||
@config_parser.wrap()
|
|
||||||
def get_cfg(cfg: ManualModeConfig) -> ManualModeConfig:
|
|
||||||
return cfg
|
|
||||||
|
|
||||||
|
|
||||||
def run(cfg: ManualModeConfig):
|
|
||||||
if cfg.teach_sensitivity is not None and not 1 <= cfg.teach_sensitivity <= 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)
|
|
||||||
initial_point = None
|
|
||||||
try:
|
|
||||||
if not arm.connected:
|
|
||||||
raise ConnectionError(f"Failed to connect to xArm at {cfg.robot_ip}")
|
|
||||||
|
|
||||||
arm.motion_enable(enable=True)
|
|
||||||
arm.clean_error()
|
|
||||||
arm.set_mode(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.teach_sensitivity is not None:
|
|
||||||
code = arm.set_teach_sensitivity(cfg.teach_sensitivity)
|
|
||||||
if code != 0:
|
|
||||||
raise RuntimeError(f"set_teach_sensitivity failed, code={code}")
|
|
||||||
|
|
||||||
code = arm.set_mode(2)
|
|
||||||
if code != 0:
|
|
||||||
raise RuntimeError(f"set_mode(2) failed, code={code}")
|
|
||||||
code = arm.set_state(0)
|
|
||||||
if code != 0:
|
|
||||||
raise RuntimeError(f"set_state(0) failed, code={code}")
|
|
||||||
|
|
||||||
print("Joint teaching mode enabled. Drag the arm manually.")
|
|
||||||
input("Press Enter to disable mode 2... ")
|
|
||||||
else:
|
|
||||||
code = arm.set_mode(0)
|
|
||||||
if code != 0:
|
|
||||||
raise RuntimeError(f"set_mode(0) failed, code={code}")
|
|
||||||
code = arm.set_state(0)
|
|
||||||
if code != 0:
|
|
||||||
raise RuntimeError(f"set_state(0) failed, code={code}")
|
|
||||||
print("Joint teaching mode disabled.")
|
|
||||||
finally:
|
|
||||||
if arm.connected:
|
|
||||||
try:
|
|
||||||
arm.set_mode(0)
|
|
||||||
arm.set_state(0)
|
|
||||||
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():
|
|
||||||
cli_parser = argparse.ArgumentParser(description="Control xArm joint teaching mode from YAML")
|
|
||||||
_, unknown = cli_parser.parse_known_args()
|
|
||||||
sys.argv = [sys.argv[0]] + unknown
|
|
||||||
cfg = get_cfg()
|
|
||||||
run(cfg)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
50
start_manual_record.sh
Executable file
50
start_manual_record.sh
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$repo_root"
|
||||||
|
|
||||||
|
config_path="config/manual_mode/xarm7_manual_record_config.yaml"
|
||||||
|
dataset_root="$(
|
||||||
|
sed -n '/^dataset:/,/^[^[:space:]]/s/^[[:space:]]*root:[[:space:]]*//p' "$config_path" \
|
||||||
|
| head -n 1 \
|
||||||
|
| tr -d "\"'"
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [[ -z "$dataset_root" ]]; then
|
||||||
|
printf 'Could not read dataset.root from %s\n' "$config_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$dataset_root" != /* ]]; then
|
||||||
|
dataset_root="$repo_root/$dataset_root"
|
||||||
|
fi
|
||||||
|
|
||||||
|
record_args=("$@")
|
||||||
|
resume_requested=false
|
||||||
|
for arg in "${record_args[@]}"; do
|
||||||
|
if [[ "$arg" == "-r" ]]; then
|
||||||
|
resume_requested=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -e "$dataset_root" ]]; then
|
||||||
|
if [[ ! -f "$dataset_root/meta/info.json" ]]; then
|
||||||
|
printf 'Dataset directory exists but is not a valid LeRobot dataset: %s\n' "$dataset_root" >&2
|
||||||
|
printf 'Choose a new dataset.root, or remove this empty/incomplete directory before recording.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$resume_requested" == false ]]; then
|
||||||
|
record_args=("-r" "${record_args[@]}")
|
||||||
|
fi
|
||||||
|
elif [[ "$resume_requested" == true ]]; then
|
||||||
|
printf 'Cannot resume because the dataset directory does not exist: %s\n' "$dataset_root" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec uv run uf-lerobot-record \
|
||||||
|
--config_path "$config_path" \
|
||||||
|
"${record_args[@]}"
|
||||||
Loading…
Reference in New Issue
Block a user