Skip to content

Messy Room Challenge

Difficulty: Medium Time Limit: 60 seconds Status: Active

Overview

The Messy Room scenario challenges your robot to clean up a cluttered environment. Objects are scattered across a table, and your robot must pick them up and place them in designated locations.

Objective

Move all scattered objects to their target locations within the time limit.

Environment

Scene Layout

┌─────────────────────────────────────────┐
│                                         │
│    [Target Zone]                        │
│    ┌─────────┐                          │
│    │         │                          │
│    └─────────┘                          │
│                                         │
│         ○  □  ○     ← Scattered objects │
│      □     ○                            │
│                                         │
│              🤖  ← Robot arm            │
│                                         │
└─────────────────────────────────────────┘

Objects

  • Cubes: Small cubic blocks (2cm x 2cm x 2cm)
  • Spheres: Small balls (2cm diameter)
  • Count: 3-6 objects per episode

Robot

  • Type: 7-DOF robotic arm with parallel gripper
  • Workspace: 50cm x 50cm x 30cm
  • Gripper: Can grasp objects up to 3cm

Observations

Your policy receives:

observation = {
    # Robot state (14 values)
    'robot_state': np.array([
        x, y, z,           # End-effector position
        qw, qx, qy, qz,    # End-effector orientation (quaternion)
        vx, vy, vz,        # Linear velocity
        wx, wy, wz,        # Angular velocity
        gripper_pos        # Gripper position (0=closed, 1=open)
    ]),

    # Object positions (N x 3)
    'object_positions': np.array([
        [x1, y1, z1],
        [x2, y2, z2],
        ...
    ]),

    # Target positions (N x 3)
    'target_positions': np.array([
        [tx1, ty1, tz1],
        [tx2, ty2, tz2],
        ...
    ]),

    # Time remaining in seconds
    'time_remaining': float,

    # Number of objects successfully placed
    'objects_placed': int,
}

Actions

Return a 7D action vector:

action = np.array([
    dx,      # X velocity (-1 to 1) → maps to -0.1 to 0.1 m/s
    dy,      # Y velocity (-1 to 1)
    dz,      # Z velocity (-1 to 1)
    droll,   # Roll velocity (-1 to 1)
    dpitch,  # Pitch velocity (-1 to 1)
    dyaw,    # Yaw velocity (-1 to 1)
    gripper  # -1 = close, 1 = open
])

Scoring

Verdict Criteria

Verdict Criteria
PASS All objects placed in target zone
PARTIAL At least 50% of objects placed
FAIL Less than 50% of objects placed

Score Calculation

Base Score = (objects_placed / total_objects) * 100
Time Bonus = (time_remaining / time_limit) * 20
Final Score = Base Score + Time Bonus
  • Maximum possible score: 120 points
  • Objects knocked off table: -10 points each

Tips

Strategy

  1. Survey First: Identify all objects and their positions
  2. Nearest First: Start with the closest object
  3. Efficient Paths: Minimize unnecessary movements
  4. Secure Grip: Ensure a firm grasp before lifting

Common Mistakes

  • Rushing: Moving too fast causes drops
  • Weak Grip: Not closing gripper fully
  • Collisions: Knocking objects off the table
  • Timeouts: Spending too long on one object

Example Approach

import numpy as np

def policy(observation: dict) -> np.ndarray:
    robot_pos = observation['robot_state'][:3]
    gripper_open = observation['robot_state'][13] > 0.5
    objects = observation['object_positions']
    targets = observation['target_positions']

    # Simple state machine
    if len(objects) == 0:
        return np.zeros(7)  # Done!

    # Find nearest unplaced object
    nearest_obj = objects[0]
    target = targets[0]

    # Calculate distance to object
    to_object = nearest_obj - robot_pos
    dist_to_object = np.linalg.norm(to_object)

    # Phase 1: Move to object
    if dist_to_object > 0.05:
        direction = to_object / (dist_to_object + 1e-6)
        return np.concatenate([direction * 0.8, [0, 0, 0, 1]])  # Open gripper

    # Phase 2: Grasp
    if gripper_open:
        return np.array([0, 0, 0, 0, 0, 0, -1])  # Close gripper

    # Phase 3: Move to target
    to_target = target - robot_pos
    dist_to_target = np.linalg.norm(to_target)

    if dist_to_target > 0.05:
        direction = to_target / (dist_to_target + 1e-6)
        return np.concatenate([direction * 0.8, [0, 0, 0, -1]])  # Keep closed

    # Phase 4: Release
    return np.array([0, 0, 0, 0, 0, 0, 1])  # Open gripper

Local Testing

Test your policy locally before submitting:

from botmanifold import BotManifoldClient

client = BotManifoldClient()

# Load scenario locally
env = client.load_scenario("messy_room_v1")

# Run your policy
observation = env.reset()
done = False

while not done:
    action = policy(observation)
    observation, reward, done, info = env.step(action)

print(f"Final score: {info['score']}")

Leaderboard

View current rankings at botmanifold.com/arena/leaderboard?scenario=messy_room_v1

Video Example

Watch an example of a successful policy completing this scenario on the scenario detail page.