-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
91 lines (77 loc) · 2.64 KB
/
Copy pathapp.py
File metadata and controls
91 lines (77 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
FastAPI server for the Garbage Collecting Robot OpenEnv environment.
Exposes reset / step / state / tasks / grade endpoints.
"""
import sys
import os
sys.path.insert(0, os.path.dirname(__file__))
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from environment import GarbageRobotEnv
from models import (
Action, StepOutput, ResetInput, ResetOutput, State, Task,
)
app = FastAPI(
title="Garbage Collecting Robot — OpenEnv",
description=(
"An OpenEnv-compliant robotics environment for garbage collection. "
"AI agents must navigate a grid room to pick up garbage while managing battery constraints."
),
version="1.0.0",
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
env = GarbageRobotEnv()
TASKS = [
Task(
id="task_easy",
name="Small Room Clean",
description="Navigate a small 5x5 grid to collect 1 piece of garbage.",
difficulty="easy",
reward_range=[0.0, 1.0],
),
Task(
id="task_medium",
name="Medium Room with Obstacles",
description="Navigate a 7x7 grid to collect 3 pieces of garbage with limited battery.",
difficulty="medium",
reward_range=[0.0, 1.0],
),
Task(
id="task_hard",
name="Large Maze Cleanup",
description="Navigate a 10x10 maze avoiding obstacles to collect 5 pieces of garbage with strict battery usage.",
difficulty="hard",
reward_range=[0.0, 1.0],
),
]
VALID_IDS = {t.id for t in TASKS}
@app.get("/", tags=["health"])
def health():
return {"status": "ok", "env": "garbage-collecting-robot"}
@app.post("/reset", response_model=ResetOutput, tags=["openenv"])
def reset(body: ResetInput = ResetInput()):
if body.task_id not in VALID_IDS:
raise HTTPException(400, f"task_id must be one of {sorted(VALID_IDS)}")
state = env.reset(task_id=body.task_id)
return {"observation": env.get_observation().model_dump()}
@app.post("/step", response_model=StepOutput, tags=["openenv"])
def step(body: Action):
result = env.step(command=body.command)
return result
@app.get("/state", response_model=State, tags=["openenv"])
def state():
return env.state()
@app.get("/tasks", response_model=list[Task], tags=["openenv"])
def tasks():
return TASKS
@app.get("/grade/{task_id}", tags=["grading"])
def grade(task_id: str):
if task_id not in VALID_IDS:
raise HTTPException(400, f"task_id must be one of {sorted(VALID_IDS)}")
score = env.grade(task_id)
return {"task_id": task_id, "score": score, "reward_range": [0.0, 1.0]}