Implementation:Google deepmind Dm control Two Touch Task
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Reinforcement Learning |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
The TwoTouch task is a visuomotor reaching task where a walker (Rat or CMUHumanoid) must tap a target twice with a precisely timed interval between touches to earn reward.
Description
TwoTouch extends composer.Task and implements a state machine using the TwoTouchState enum with five states: PRE_TOUCH (waiting for first touch), TOUCHED_ONCE (first touch registered, waiting for second), TOUCHED_TWICE (second touch at correct time), TOUCHED_TOO_SOON (second touch before the allowed interval), and NO_SECOND_TOUCH (timeout without second touch). The task tracks hand geom IDs for both left and right hands to detect target contact.
The reward function provides a continuous component and a discrete component. The continuous component is a small closeness reward based on exponential decay of the hand-to-target distance (taking the maximum of left and right hand proximity). The discrete component awards a configurable reward for the first touch, and an additional reward for the second touch only if it occurs within touch_interval +/- interval_tolerance seconds of the first. Touching too soon or failing to touch within the interval triggers a timeout period (failure_timeout) before targets are re-randomized.
The task supports configurable spawn position randomization, spawn rotation randomization with optional bias, target area specification, and egocentric camera observations at 64x64 resolution. A task_logic observable exposes the current state machine state to the agent, enabling it to learn the temporal structure of the task.
Usage
Use TwoTouch when you need a locomotion task that tests an agent's ability to perform precisely timed reaching and touching interactions. The task supports both Rat and CMUHumanoid walkers and is suitable for benchmarking fine motor control and temporal reasoning capabilities.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/locomotion/tasks/reach.py
- Lines: 1-287
Signature
class TwoTouchState(enum.IntEnum):
PRE_TOUCH = 0
TOUCHED_ONCE = 1
TOUCHED_TWICE = 2
TOUCHED_TOO_SOON = 3
NO_SECOND_TOUCH = 4
class TwoTouch(composer.Task):
def __init__(self, walker, arena, target_builders,
target_type_rewards,
shuffle_target_builders=False,
randomize_spawn_position=False,
randomize_spawn_rotation=True,
rotation_bias_factor=0,
aliveness_reward=0.0,
touch_interval=0.8,
interval_tolerance=0.1,
failure_timeout=1.2,
reset_delay=0.,
z_height=.14,
target_area=(),
physics_timestep=DEFAULT_PHYSICS_TIMESTEP,
control_timestep=DEFAULT_CONTROL_TIMESTEP):
def name(self): # property
def task_observables(self): # property
def root_entity(self): # property
def initialize_episode_mjcf(self, random_state):
def initialize_episode(self, physics, random_state):
def before_step(self, physics, action, random_state):
def should_terminate_episode(self, physics):
def get_reward(self, physics):
def get_discount(self, physics):
Import
from dm_control.locomotion.tasks.reach import TwoTouch
from dm_control.locomotion.tasks.reach import TwoTouchState
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| walker | Walker | Yes | The walker entity (must be Rat or CMUHumanoid) |
| arena | Arena | Yes | The arena entity for the task |
| target_builders | list of callables | Yes | Factory functions for creating target entities |
| target_type_rewards | list of float | Yes | Reward values for each target type upon touch |
| shuffle_target_builders | bool | No | Whether to shuffle target builder order each episode (default: False) |
| randomize_spawn_position | bool | No | Whether to randomize walker spawn position (default: False) |
| randomize_spawn_rotation | bool | No | Whether to randomize walker spawn rotation (default: True) |
| touch_interval | float | No | Required time interval between first and second touch in seconds (default: 0.8) |
| interval_tolerance | float | No | Tolerance around the touch interval in seconds (default: 0.1) |
| failure_timeout | float | No | Timeout duration after incorrect second touch or no second touch (default: 1.2) |
| z_height | float | No | Height of targets above the ground (default: 0.14) |
| physics_timestep | float | No | Physics simulation timestep (default: 0.005) |
| control_timestep | float | No | Control timestep (default: 0.03) |
Outputs
| Name | Type | Description |
|---|---|---|
| get_reward() | float | Reward combining closeness reward and discrete touch rewards |
| get_discount() | float | Discount factor (1.0 normally, 0.0 on termination) |
| task_observables | OrderedDict | Dictionary containing task_logic observable exposing the current state
|
Usage Examples
from dm_control.locomotion.tasks.reach import TwoTouch
# Create a TwoTouch task with a Rat walker
task = TwoTouch(
walker=rat_walker,
arena=floor_arena,
target_builders=[target_builder_fn],
target_type_rewards=[1.0],
touch_interval=0.8,
interval_tolerance=0.1,
failure_timeout=1.2,
randomize_spawn_rotation=True,
z_height=0.14,
)
# The task integrates with composer.Environment
env = composer.Environment(task)
timestep = env.reset()
reward = timestep.reward