Implementation:Google deepmind Dm control Multiplayer Tracking Camera
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Multi Agent |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
The MultiplayerTrackingCamera provides a smooth, automatically-tracking camera that follows multiple entities simultaneously for recording multi-agent soccer videos.
Description
MultiplayerTrackingCamera computes a target lookat point as the centroid of all tracked entity positions and sets the camera distance to min_distance + distance_factor * max_radius, where max_radius is the distance from the centroid to the farthest entity. This ensures all entities remain visible in the frame at all times, with the camera automatically zooming out as entities spread apart.
The camera uses an exponential smoothing filter controlled by the smoothing_update_speed parameter to interpolate between the current and target camera poses at each step. A value of 1.0 means no smoothing (instant tracking), while smaller values produce smoother, more cinematic camera movement. The azimuth and elevation angles remain constant throughout an episode, providing a stable viewing angle.
The camera is built on top of engine.MovableCamera and manages the rendering buffer size to ensure it is large enough for the configured resolution. It integrates with the Composer lifecycle through after_compile (for camera initialization), initialize_episode (to set the initial camera pose), and after_step (to update the camera position each simulation step).
Usage
Use MultiplayerTrackingCamera when you need to generate video recordings of multi-agent soccer episodes. It is typically passed via the tracking_cameras parameter of the soccer Task class. Configure min_distance and distance_factor based on your field size and desired framing.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/locomotion/soccer/camera.py
- Lines: 1-119
Signature
class MultiplayerTrackingCamera:
def __init__(self, min_distance, distance_factor,
smoothing_update_speed, azimuth=90, elevation=-45,
width=1920, height=1080):
def camera(self): # property
def render(self):
def after_compile(self, physics):
def initialize_episode(self, entity_positions):
def after_step(self, entity_positions):
Import
from dm_control.locomotion.soccer.camera import MultiplayerTrackingCamera
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| min_distance | float | Yes | Minimum camera distance from the lookat point |
| distance_factor | float | Yes | Multiplier applied to the maximum entity radius for computing camera distance |
| smoothing_update_speed | float | Yes | Exponential filter parameter in [0, 1]; 1 means no smoothing, smaller values mean smoother motion |
| azimuth | float | No | Constant azimuth angle in degrees (default: 90) |
| elevation | float | No | Constant elevation angle in degrees (default: -45) |
| width | int | No | Rendering width in pixels (default: 1920) |
| height | int | No | Rendering height in pixels (default: 1080) |
Outputs
| Name | Type | Description |
|---|---|---|
| render() | numpy array | Rendered image as a numpy array |
| camera | engine.MovableCamera | The underlying MuJoCo camera object |
Usage Examples
from dm_control.locomotion.soccer.camera import MultiplayerTrackingCamera
# Create a tracking camera for a soccer match
tracking_camera = MultiplayerTrackingCamera(
min_distance=10.0,
distance_factor=1.5,
smoothing_update_speed=0.1,
azimuth=90,
elevation=-45,
width=1920,
height=1080,
)
# After physics compilation
tracking_camera.after_compile(physics)
# At episode start, provide initial entity positions
entity_positions = [player.get_pose(physics)[0] for player in players]
tracking_camera.initialize_episode(entity_positions)
# Each step, update and render
entity_positions = [player.get_pose(physics)[0] for player in players]
tracking_camera.after_step(entity_positions)
frame = tracking_camera.render()