# Finger Manipulation Finger is a classic manipulation task from the DeepMind Control Suite. A two-link “finger” applies torques to interact with a rotating spinner. MotrixLab currently provides three Finger environments: ```{video} /_static/videos/dm_finger_spin.mp4 :poster: _static/images/poster/dm_finger_spin.jpg :nocontrols: :autoplay: :playsinline: :muted: :loop: :width: 100% ``` ```{video} /_static/videos/dm_finger_turn.mp4 :poster: _static/images/poster/dm_finger_turn.jpg :nocontrols: :autoplay: :playsinline: :muted: :loop: :width: 100% ``` - `dm-finger-spin`: make the spinner rotate continuously in the target direction - `dm-finger-turn-easy`: align the spinner tip (`tip`) with a target point (larger target radius) - `dm-finger-turn-hard`: same as Turn, but with a smaller target radius --- ## Task Description Finger is a planar (x-z) interaction task: - The finger has 2 actuated hinge joints: `proximal` and `distal` - The spinner rotates around joint `hinge`, and `tip` denotes the spinner tip position - For Turn tasks, a target point is sampled around the spinner at the beginning of each episode --- ## Action Space | Item | Details | | ------------- | ------------------------------- | | **Type** | `Box(-1.0, 1.0, (2,), float32)` | | **Dimension** | 2 | The actions correspond to: | Index | Action Description | Min Control | Max Control | XML Name | Joint Type | | ----- | ---------------------------------- | ----------- | ----------- | -------- | ---------- | | 0 | Torque applied to `proximal` joint | -1 | 1 | proximal | hinge | | 1 | Torque applied to `distal` joint | -1 | 1 | distal | hinge | --- ## Observation Space MotrixLab follows dm_control-style observations, but flattens them into a single vector. ### Spin Observation Space | Item | Details | | ------------- | ------------------------------- | | **Type** | `Box(-inf, inf, (9,), float32)` | | **Dimension** | 9 | The observation vector contains (in order): - **position (4)**: `qpos(proximal, distal)` + `tip_xz` (tip position relative to the spinner in x-z) - **velocity (3)**: `qvel(proximal, distal, hinge)` (hinge velocity is used by Spin reward) - **touch (2)**: `log(1 + touchtop)`, `log(1 + touchbottom)` ### Turn Observation Space | Item | Details | | ------------- | -------------------------------- | | **Type** | `Box(-inf, inf, (12,), float32)` | | **Dimension** | 12 | Compared to Spin, Turn adds: - **target_position (2)**: target position relative to the spinner in x-z - **dist_to_target (1)**: signed distance from tip to the target sphere surface (negative means “inside”) --- ## Reward Function Design ### Spin In dm_control, Spin is typically defined with a sparse threshold on spinner angular velocity. MotrixLab defaults to a dense/shaped reward for easier training, while also logging the sparse version: ```text spin_sparse = 1 if hinge_velocity <= -15 else 0 spin = clip(-hinge_velocity / 15, 0, 1) ``` ### Turn (Easy / Hard) Turn aims to bring the spinner tip into a target sphere around the spinner: - `turn_sparse = 1` when `dist_to_target <= 0` - MotrixLab defaults to a shaped reward based on distance-to-target (exponential decay), and adds auxiliary terms to reduce “no-contact” failure modes and action jitter: - approach-to-spinner shaping - touch bonus - action magnitude / action change penalties The final shaped reward is clipped to `[0, 1]`. --- ## Initial State - `proximal`, `distal` joint angles are sampled uniformly within joint limits - spinner `hinge` angle is sampled uniformly in `[-pi, pi]` - for Turn tasks, the target is sampled around the spinner on the x-z plane at reset --- ## Episode Termination Conditions ### Termination If `NaN` appears in the observations --- ## Usage Guide ### 1. Environment Preview (random actions) ```bash uv run scripts/view.py --env dm-finger-spin ``` ```bash uv run scripts/view.py --env dm-finger-turn-easy ``` ```bash uv run scripts/view.py --env dm-finger-turn-hard ``` ### 2. Start Training ```bash uv run scripts/train.py --env dm-finger-spin --train-backend torch ``` ```bash uv run scripts/train.py --env dm-finger-turn-easy --train-backend torch ``` ```bash uv run scripts/train.py --env dm-finger-turn-hard --train-backend torch ``` ### 3. View Training Progress ```bash uv run tensorboard --logdir runs/dm-finger-spin ``` ### 4. Test Training Results `scripts/play.py` will auto-discover the latest `best_agent.*` under `runs/{env-name}/` (or you can pass `--policy` explicitly): ```bash uv run scripts/play.py --env dm-finger-turn-hard ``` --- ## Expected Training Results 1. `dm-finger-spin`: stable continuous rotation in the target direction 2. `dm-finger-turn-easy`: consistent contact and alignment with the (larger) target region, with reduced jitter 3. `dm-finger-turn-hard`: successful alignment with a smaller target region, typically requiring more training and better contact behavior