Implementation:Google deepmind Dm control Soccer Viewer
| Metadata | |
|---|---|
| Knowledge Sources | dm_control |
| Domains | Robotics Simulation, Visualization |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
Concrete tool for launching an interactive visualization of the multi-agent soccer environment, combining the viewer.launch application with a MultiplayerTrackingCamera that smoothly follows all players and the ball.
Description
The soccer viewer implementation consists of two components:
MultiplayerTrackingCamera(defined incamera.py) -- A camera controller that:- Computes a target lookat point as the centroid of all tracked entity positions (ball + all players).
- Sets the camera distance to
min_distance + distance_factor * d_max, whered_maxis the maximum radius of any entity from the centroid. - Applies an exponential smoothing filter each step:
pose = alpha * target + (1 - alpha) * current. - Hooks into the Composer lifecycle via
after_compile(physics)(creates theMovableCameraand sizes the offscreen buffer),initialize_episode(entity_positions)(snaps camera to target), andafter_step(entity_positions)(smoothly updates pose). - Provides a
render()method that returns the current frame as a numpy array.
explore.pyscript -- A command-line application that:- Defines flags for
walker_type(BOXHEAD, ANT, HUMANOID),enable_field_box,disable_walker_contacts, andterminate_on_goal. - Calls
viewer.launch(environment_loader=functools.partial(soccer.load, ...))with a 2v2 configuration. - Uses
functools.partialso the viewer can reconstruct the environment on reset.
- Defines flags for
Usage
The explore script is run directly from the command line. The MultiplayerTrackingCamera can also be attached to any soccer task via the tracking_cameras constructor argument.
Code Reference
| Attribute | Value |
|---|---|
| Source Location (camera) | dm_control/locomotion/soccer/camera.py, lines 22--119
|
| Source Location (explore) | dm_control/locomotion/soccer/explore.py, lines 39--55
|
| Signature (MultiplayerTrackingCamera) | MultiplayerTrackingCamera(min_distance, distance_factor, smoothing_update_speed, azimuth=90, elevation=-45, width=1920, height=1080)
|
| Signature (viewer.launch) | viewer.launch(environment_loader)
|
| Import | from dm_control.locomotion.soccer.camera import MultiplayerTrackingCamera
|
I/O Contract
Inputs (MultiplayerTrackingCamera constructor):
| Parameter | Type | Description |
|---|---|---|
min_distance |
float |
Minimum camera distance from the lookat point. |
distance_factor |
float |
Multiplier on the maximum entity radius to compute camera distance. |
smoothing_update_speed |
float |
Exponential filter coefficient in [0, 1]. 1 = no smoothing, smaller = smoother.
|
azimuth |
float |
Camera azimuth angle in degrees. Default 90.
|
elevation |
float |
Camera elevation angle in degrees. Default -45.
|
width |
int |
Rendered frame width in pixels. Default 1920.
|
height |
int |
Rendered frame height in pixels. Default 1080.
|
Inputs (lifecycle methods):
| Method | Parameter | Type | Description |
|---|---|---|---|
after_compile |
physics |
mjcf.Physics |
Creates the MovableCamera and resizes the offscreen buffer.
|
initialize_episode |
entity_positions |
list[np.ndarray] |
List of 3D position arrays (ball first, then players). |
after_step |
entity_positions |
list[np.ndarray] |
Same format; camera pose is smoothly updated. |
Outputs:
| Method | Return Type | Description |
|---|---|---|
render() |
np.ndarray |
RGB pixel array of shape (height, width, 3).
|
camera (property) |
engine.MovableCamera |
The underlying MuJoCo camera instance. |
Usage Examples
# --- Command-line exploration ---
# Run from the terminal:
# python -m dm_control.locomotion.soccer.explore \
# --walker_type=HUMANOID \
# --enable_field_box=True \
# --terminate_on_goal=False
# --- Programmatic use of MultiplayerTrackingCamera ---
from dm_control.locomotion.soccer.camera import MultiplayerTrackingCamera
from dm_control.locomotion import soccer
camera = MultiplayerTrackingCamera(
min_distance=10.0,
distance_factor=1.5,
smoothing_update_speed=0.1,
azimuth=90,
elevation=-45,
width=640,
height=480,
)
players = soccer._make_players(team_size=2, walker_type=soccer.WalkerType.BOXHEAD)
arena = soccer.RandomizedPitch(min_size=(32, 24), max_size=(48, 36))
task = soccer.Task(
players=players,
arena=arena,
tracking_cameras=(camera,),
)
from dm_control import composer
env = composer.Environment(task=task, time_limit=45.0)
timestep = env.reset()
# Render a frame from the tracking camera.
frame = camera.render()
print(frame.shape) # (480, 640, 3)
# --- Using viewer.launch directly ---
import functools
from dm_control import viewer
viewer.launch(
environment_loader=functools.partial(
soccer.load,
team_size=2,
walker_type=soccer.WalkerType.BOXHEAD,
enable_field_box=True,
keep_aspect_ratio=True,
)
)