# 机械手抓球 Bring Ball 是 DeepMind Control Suite 中的 Manipulator 经典任务:平面机械手(带拇指与手指)需要抓取球体并将其移动到目标球位置。MotrixLab 当前提供 1 个 Bring Ball 环境: - `dm-manipulator-bring-ball`:抓取球体并移动到目标位置 ```{video} /_static/videos/bring-ball.mp4 :poster: _static/images/poster/bring-ball.jpg :nocontrols: :autoplay: :playsinline: :muted: :loop: :width: 100% ``` --- ## 任务描述 Bring Ball 是一个二维平面(x-z)内的抓取与搬运任务: - 机械手包含 4 个手臂关节(`arm_root`、`arm_shoulder`、`arm_elbow`、`arm_wrist`)以及拇指/手指关节 - 夹持通过腱 `grasp` 同时驱动 `thumb` 与 `finger` 关节闭合 - 球体可在平面内滑动(`ball_x`、`ball_z`)并绕 y 轴旋转(`ball_y`) - 目标球为 mocap 物体,位置在 reset 时随机采样 --- ## 动作空间(Action Space) | 项目 | 详细信息 | | -------- | ------------------------------- | | **类型** | `Box(-1.0, 1.0, (5,), float32)` | | **维度** | 5 | 动作对应如下(控制信号施加在关节/腱上): | 序号 | 动作含义 | 最小值 | 最大值 | 对应 XML 中名称 | | ---: | ----------------------------- | :----: | :----: | :-------------: | | 0 | 根部关节驱动 | -1 | 1 | `root` | | 1 | 肩部关节驱动 | -1 | 1 | `shoulder` | | 2 | 肘部关节驱动 | -1 | 1 | `elbow` | | 3 | 腕部关节驱动 | -1 | 1 | `wrist` | | 4 | 夹持驱动(拇指/手指耦合闭合) | -1 | 1 | `grasp` | --- ## 观察空间 | 项目 | 详细信息 | | -------- | -------------------------------- | | **类型** | `Box(-inf, inf, (41,), float32)` | | **维度** | 41 | 观察向量由以下部分组成(按顺序): | 部分 | 内容说明 | 维度 | 备注 | | -------------- | --------------------------- | ---- | ------------------------------------ | | **arm_pos** | 8 个关节角度的 `sin`/`cos` | 16 | 关节顺序见下表,`sin`/`cos` 交替排列 | | **arm_vel** | 8 个关节角速度 | 8 | 顺序同 arm_pos | | **touch** | 触觉传感器 `log(1 + touch)` | 5 | palm/finger/thumb/fingertip/thumbtip | | **hand_pos** | 抓取点 `grasp` 的世界坐标 | 3 | x, y, z | | **object_pos** | 球体位置 | 3 | x, y, z | | **target_pos** | 目标球位置 | 3 | x, y, z | | **rel** | `object_pos - target_pos` | 3 | 相对位置 | | 序号 | 观察量范围 | 维度 | 备注 | | ----- | ---------------------------------------------- | ---- | ----------------------------- | | 0-15 | 8 个关节角度的 `sin`/`cos` 交替排列 | 16 | 关节顺序:arm_root → thumbtip | | 16-23 | 8 个关节角速度 | 8 | 顺序同上 | | 24-28 | 触觉:palm, finger, thumb, fingertip, thumbtip | 5 | `log(1 + touch)` | | 29-31 | grasp 位置 (x, y, z) | 3 | hand_pos | | 32-34 | 球体位置 (x, y, z) | 3 | object_pos | | 35-37 | 目标球位置 (x, y, z) | 3 | target_pos | | 38-40 | 球体相对目标位置 (x, y, z) | 3 | rel | 关节顺序为:`arm_root`、`arm_shoulder`、`arm_elbow`、`arm_wrist`、`finger`、`fingertip`、`thumb`、`thumbtip`。 --- ## 奖励函数设计 Bring Ball 使用 shaped 奖励,由多个子项加权组合,并加入惩罚项: ```python # R1: Reach - 手指接近球 r_reach = tolerance(avg_tip_dist) # R2: Orient - 手掌朝向球体 r_orient = clip(1 - orient_bound + dot(hand_dir, unit_vec_to_ball), 0..1) # R3: Pause - 靠近球体时抑制臂部抖动 r_pause = tolerance(arm_speed_step) * is_close_to_ball # R4: Close - 夹持动作与接触条件联合 r_close = r_close_intent * (approach_or_grasp) # R5: Lift & Transport - 抬升高度 + 接近目标 r_lift_height = tolerance(ball_z) r_transport = tolerance(move_dist_to_target) r_lift = mix(r_lift_height, r_transport) # Precision/Progress - 目标精度与移动进度 r_precision = tolerance(move_dist_to_target, gaussian) r_progress = (prev_dist - curr_dist) * scale # Penalty - 侧面接触与悬停惩罚 penalty_side + penalty_hover ``` 默认权重(`BringBallCfg`): - reach 1.0、orient 1.5、pause 0.5、close 2.0、lift 6.0、precision 1.0 - lift 内部由 `lift_height_weight` 与 `transport_weight` 组合 - 进度奖励由 `transport_progress_scale` 控制 --- ## 初始状态 - **手臂初始化**:默认使用模型初始姿态(`randomize_arm=False`),拇指/手指对称 - **目标位置**:`x ∈ [-0.4, 0.4]`,`z ∈ [0.1, 0.4]`,`y = 0.001` - **球体位置**:`x ∈ [-0.4, 0.4]`,`z ∈ [0.2, 0.7]`,并与手部保持最小距离 - **物理稳定**:reset 后会进行若干步 settle(`settle_steps=300`) --- ## Episode 终止条件 - 若观测中出现 `NaN` 值则终止 --- ## 使用指南 ### 1. 环境预览(随机动作) ```bash uv run scripts/view.py --env dm-manipulator-bring-ball ``` ### 2. 开始训练 建议显式指定训练后端(JAX / PyTorch 二选一): ```bash uv run scripts/train.py --env dm-manipulator-bring-ball --train-backend torch ``` ### 3. 查看训练进度 ```bash uv run tensorboard --logdir runs/dm-manipulator-bring-ball ``` ### 4. 测试训练结果 ```bash uv run scripts/play.py --env dm-manipulator-bring-ball ``` --- ## 预期训练结果 1. 机械手能稳定接近并夹持球体 2. 球体被抬离地面并保持稳定高度 3. 球体最终能稳定到达目标球附近