Object Sorting Challenge¶
Difficulty: Easy Time Limit: 30 seconds Status: Active
Overview¶
The Object Sorting scenario is a beginner-friendly challenge where a robot arm must push colored cubes into the correct bins. Red cubes go in the red bin (left), blue cubes go in the blue bin (right).
Objective¶
Sort at least one cube correctly by pushing it into the matching colored bin.
Environment¶
Scene Layout¶
┌─────────────────────────────────────────┐
│ │
│ [RED BIN] [BLUE BIN] │
│ ┌───────┐ ┌───────┐ │
│ │ 🔴 │ │ 🔵 │ │
│ └───────┘ └───────┘ │
│ │
│ 🟥 🟦 ← Colored cubes │
│ 🟦 🟥 │
│ │
│ 🤖 ← Robot arm │
│ │
└─────────────────────────────────────────┘
Objects¶
- Red Cubes: 2 small red cubes that should go in the left (red) bin
- Blue Cubes: 2 small blue cubes that should go in the right (blue) bin
- Bins: Two collection bins positioned at fixed locations
Robot¶
- Type: 3-DOF planar arm with pushing end-effector
- Control: Joint torque control
- Strategy: Push objects rather than grasp
Observations¶
Your policy receives:
observation = {
# Joint positions (3 values)
'joint_positions': np.array([base, shoulder, elbow]),
# End-effector position (3 values)
'end_effector_pos': np.array([x, y, z]),
# Bin positions (3 values each)
'red_bin_pos': np.array([x, y, z]),
'blue_bin_pos': np.array([x, y, z]),
# Cube positions (N x 3 arrays)
'red_cube_positions': np.array([
[x1, y1, z1],
[x2, y2, z2],
]),
'blue_cube_positions': np.array([
[x1, y1, z1],
[x2, y2, z2],
]),
}
Actions¶
Return a 3D action vector (joint torques):
action = np.array([
base_torque, # Base joint torque (-1 to 1)
shoulder_torque, # Shoulder joint torque (-1 to 1)
elbow_torque # Elbow joint torque (-1 to 1)
])
Scoring¶
Verdict Criteria¶
| Verdict | Criteria |
|---|---|
| PASS | At least one cube sorted into the correct bin |
| FAIL | No cubes sorted, or cubes placed in wrong bins |
Reward Calculation¶
Correct placement: +10 points per cube
Wrong bin: -5 points per cube
Distance penalty: -(distance to nearest correct bin) per unsorted cube
Tips¶
Strategy¶
- Identify Targets: Locate the nearest unsorted cube
- Approach: Move the end-effector behind the cube
- Push: Apply force toward the correct bin
- Repeat: Move to the next cube
Common Mistakes¶
- Wrong Direction: Pushing toward the wrong bin
- Missing the Cube: Not aligning properly before pushing
- Overcorrection: Oscillating instead of smooth movement
- Ignoring Colors: Treating all cubes the same
Example Approach¶
import numpy as np
def policy(observation: dict) -> np.ndarray:
ee_pos = observation['end_effector_pos']
red_bin = observation['red_bin_pos']
blue_bin = observation['blue_bin_pos']
red_cubes = observation['red_cube_positions']
blue_cubes = observation['blue_cube_positions']
# Find nearest unsorted cube
target_pos = None
target_bin = None
min_dist = float('inf')
# Check red cubes
for cube_pos in red_cubes:
if np.linalg.norm(cube_pos[:2] - red_bin[:2]) < 0.1:
continue # Already sorted
dist = np.linalg.norm(ee_pos[:2] - cube_pos[:2])
if dist < min_dist:
min_dist = dist
target_pos = cube_pos
target_bin = red_bin
# Check blue cubes
for cube_pos in blue_cubes:
if np.linalg.norm(cube_pos[:2] - blue_bin[:2]) < 0.1:
continue # Already sorted
dist = np.linalg.norm(ee_pos[:2] - cube_pos[:2])
if dist < min_dist:
min_dist = dist
target_pos = cube_pos
target_bin = blue_bin
if target_pos is None:
return np.zeros(3) # All sorted!
# Move toward object or push toward bin
dist_to_target = np.linalg.norm(ee_pos[:2] - target_pos[:2])
if dist_to_target > 0.08:
direction = target_pos[:2] - ee_pos[:2]
else:
direction = target_bin[:2] - target_pos[:2]
direction = direction / (np.linalg.norm(direction) + 1e-6)
# Convert to joint torques (simplified)
base_torque = direction[1] * 5.0
shoulder_torque = -direction[0] * 3.0
elbow_torque = 1.0
return np.array([base_torque, shoulder_torque, elbow_torque])
Local Testing¶
Test your policy locally before submitting:
from botmanifold import BotManifoldClient
client = BotManifoldClient()
# Load scenario locally
env = client.load_scenario("object_sorting_v1")
# Run your policy
observation = env.reset()
done = False
while not done:
action = policy(observation)
observation, reward, done, info = env.step(action)
print(f"Sorted: {info['correct']} correct, {info['incorrect']} incorrect")
Leaderboard¶
View current rankings at botmanifold.com/arena/leaderboard?scenario=object_sorting_v1
Video Example¶
Watch an example of a successful policy completing this scenario on the scenario detail page.