Implementation:Google deepmind Dm control Position Detector
| Knowledge Sources | |
|---|---|
| Domains | Reinforcement_Learning, Robotics, Manipulation |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
A Composer entity that detects the presence of registered entities within an axis-aligned bounding box, supporting 2D/3D modes, inverted detection, visual feedback, and substep-level detection persistence.
Description
The PositionDetector class extends composer.Entity and defines a cuboidal detection region specified by a center position and half-lengths. Entities are registered with the detector via register_entities(), which stores references to their geoms. On each physics substep (after_substep), the detector checks whether any registered entity's geom xpos falls within the lower/upper bounds of the detection region.
The detector supports both 2D and 3D modes: in 2D mode (when pos and size are length-2 arrays), the detection region has effectively infinite height along the z-axis. An inverted mode reverses detection logic, detecting entities when they are outside the region rather than inside. The retain_substep_detections flag controls whether detection persists across substeps within a single control step: when True, the detector remains activated if it was triggered at any substep.
Visual feedback is provided by a box-shaped MuJoCo site that changes color (from rgba to detected_rgba) when an entity is detected. The detector also creates framepos sensors at its lower, mid, and upper corners for programmatic position queries. The detection zone can be dynamically resized via resize() or repositioned via set_position().
Usage
Use PositionDetector in Composer tasks to define target zones, goal regions, or trigger areas. Register entities whose presence should be detected, then query detected_entities or activated in reward functions or task logic. Common use cases include object placement tasks, navigation goals, and manipulation success criteria.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/entities/props/position_detector.py
- Lines: 1-294
Signature
class PositionDetector(composer.Entity):
def _build(self, pos, size, inverted=False, visible=False,
rgba=(1, 1, 1, 1), material=None,
detected_rgba=(0, 1, 0, 0.25),
retain_substep_detections=False,
name='position_detector'):
...
def register_entities(self, *entities):
...
def deregister_entities(self):
...
def resize(self, pos, size):
...
def set_position(self, physics, pos):
...
def set_colors(self, rgba, detected_rgba):
...
@property
def detected_entities(self):
...
@property
def activated(self):
...
@property
def upper(self):
...
@property
def lower(self):
...
@property
def mid(self):
...
Import
from dm_control.entities.props.position_detector import PositionDetector
I/O Contract
Inputs (_build)
| Name | Type | Required | Description |
|---|---|---|---|
| pos | array-like (2 or 3) | Yes | Center position of the detection region; length determines 2D or 3D mode |
| size | array-like (2 or 3) | Yes | Half-lengths of the detection region; must match length of pos
|
| inverted | bool | No | If True, detect entities outside the region (default False)
|
| visible | bool | No | If True, render the detection zone by default (default False)
|
| rgba | tuple (4,) | No | Color when nothing is detected (default white: (1, 1, 1, 1))
|
| material | str or None | No | Material for the detection zone site |
| detected_rgba | tuple (4,) | No | Color when an entity is detected (default green: (0, 1, 0, 0.25))
|
| retain_substep_detections | bool | No | If True, detection persists across substeps within a control step (default False)
|
| name | str | No | XML element name (default 'position_detector')
|
Inputs (register_entities)
| Name | Type | Required | Description |
|---|---|---|---|
| *entities | composer.Entity instances |
Yes | Entities to monitor for presence in the detection region |
Outputs
| Name | Type | Description |
|---|---|---|
| detected_entities | list of composer.Entity |
Entities currently detected within (or outside, if inverted) the region |
| activated | bool | True if any entity is currently detected
|
| upper | numpy.ndarray |
Upper corner coordinates of the detection region |
| lower | numpy.ndarray |
Lower corner coordinates of the detection region |
| mid | numpy.ndarray |
Center coordinates of the detection region |
Lifecycle Callbacks
| Callback | Behavior |
|---|---|
initialize_episode_mjcf |
Refreshes cached geom references for all registered entities |
initialize_episode |
Runs initial detection check |
before_step |
Resets all detection flags to False
|
after_substep |
Checks all registered entity geoms against the detection region bounds |
Usage Examples
from dm_control.entities.props.position_detector import PositionDetector
from dm_control.entities.props.primitive import Primitive
import numpy as np
# Create a 3D detector at position (0.5, 0, 0.1) with half-size (0.1, 0.1, 0.1)
detector = PositionDetector(
pos=[0.5, 0.0, 0.1],
size=[0.1, 0.1, 0.1],
visible=True,
detected_rgba=(0, 1, 0, 0.5)
)
# Create a prop to detect
ball = Primitive(geom_type='sphere', size=[0.02])
# Register the prop with the detector
detector.register_entities(ball)
# In a task's get_reward method:
def get_reward(self, physics):
if detector.activated:
return 1.0 # Reward when ball is in the target zone
return 0.0
# Query which entities are currently detected
detected = detector.detected_entities
# detected is a list of Entity objects
# Create a 2D detector (infinite height along z)
detector_2d = PositionDetector(
pos=[0.5, 0.0],
size=[0.2, 0.2]
)
# Inverted detector: detects when entities leave the region
escape_detector = PositionDetector(
pos=[0.0, 0.0, 0.0],
size=[1.0, 1.0, 1.0],
inverted=True
)