Skip to content

Commit

Permalink
Merge pull request #120 from inverted-ai/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Ruishenl committed Mar 4, 2023
2 parents e8e6575 + bec539c commit ba09b95
Show file tree
Hide file tree
Showing 19 changed files with 1,224 additions and 76 deletions.
2 changes: 1 addition & 1 deletion examples/carla/carla_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def _initialize(self, ego_spawn_point=None, initial_states=None, npc_entrance_sp
self.set_npc_autopilot(self.npcs, True)

# Allow the vehicles to drop to the ground
for _ in range(10):
for _ in range(self.cfg.fps):
self.world.tick()

# Set controllers for all vehicles
Expand Down
2 changes: 1 addition & 1 deletion examples/carla/demo_autoregressive_initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

light_response = iai.light(location=args.location)
response = iai.utils.area_initialization(
location=args.location, agent_density=6, traffic_lights_states=None, map_center=map_center, width=500, height=500, stride=50, initialize_fov=100, static_actors=corrected_static_actors)
location=args.location, agent_density=6, traffic_lights_states=None, map_center=map_center, width=500, height=500, stride=50, static_actors=corrected_static_actors)


# Carla simulator uses left-hand coordinates and xord map are right-handed, thus, the position of agents require a simple transformation
Expand Down
62 changes: 42 additions & 20 deletions examples/carla/demo_open_drive.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
from tqdm import tqdm
import argparse
import invertedai as iai
from carla_simulator import PreSets
from invertedai.common import AgentState, StaticMapActor
import pathlib
import subprocess
path = pathlib.Path(__file__).parent.resolve()


parser = argparse.ArgumentParser(description="Simulation Parameters.")
parser.add_argument("--api_key", type=str, default=None)
parser.add_argument("--fov", type=float, default=150)
parser.add_argument("--location", type=str, default="carla:Town03")
parser.add_argument("--location", type=str, default="carla:Town03")
parser.add_argument("-l", "--episode_length", type=int, default=30)
parser.add_argument("-xodr", "--opendrive_map_path", type=str, default="data/open_drive/Town03.xodr")
parser.add_argument("-lhc", "--left_hand_coordinate", type=int, default=1)
parser.add_argument("-dpi", "--dpi", type=int, default=100)
parser.add_argument("-res", "--resolution", type=int, nargs=2, default=[640, 480])
args = parser.parse_args()
map_center = PreSets.map_centers["carla:Town03:Roundabout"]


if args.api_key is not None:
iai.add_apikey(args.api_key)
Expand All @@ -29,50 +31,70 @@
file_path = f"{file_name}.jpg"
location_info_response.birdview_image.decode_and_save(file_path)

rendered_static_map = location_info_response.birdview_image.decode()
map_center = (location_info_response.map_center.x, location_info_response.map_center.y)


light_response = iai.light(location=args.location)
rendered_static_map = location_info_response.birdview_image.decode()

try:
light_response = iai.light(location=args.location)
except:
light_response = None

response = iai.initialize(
location=args.location,
agent_count=10,
get_birdview=True,
get_infractions=True,
traffic_light_state_history=[light_response.traffic_lights_states],
traffic_light_state_history=[light_response.traffic_lights_states] if light_response else None,
location_of_interest=map_center,
)
# Carla xord map coordinate differ from eachother and position of agents require a simple transformation
corrected_agents = [AgentState.fromlist([state.center.x, -state.center.y,
-state.orientation, state.speed]) for state in response.agent_states]
corrected_static_actors = [StaticMapActor.fromdict(dict(x=state.center.x, y=-state.center.y, actor_id=state.actor_id,
agent_type=state.agent_type, orientation=-state.orientation, length=state.length, width=state.width, dependant=state.dependant
))for state in location_info_response.static_actors]
if args.left_hand_coordinate:
# Carla xord map coordinate differ from eachother and position of agents require a simple transformation
corrected_agents = [AgentState.fromlist([state.center.x, -state.center.y,
-state.orientation, state.speed]) for state in response.agent_states]
corrected_static_actors = [StaticMapActor.fromdict(dict(x=state.center.x, y=-state.center.y, actor_id=state.actor_id,
agent_type=state.agent_type, orientation=-state.orientation,
length=state.length, width=state.width, dependant=state.dependant
))for state in location_info_response.static_actors]
else:
corrected_agents = response.agent_states
corrected_static_actors = location_info_response.static_actors

# Convert xord map to csv for rendering
result = subprocess.run(['./data/open_drive/odrplot', args.opendrive_map_path], stdout=subprocess.PIPE)

open_drive_file_name = f"{path}/data/open_drive/{args.location.split(':')[1]}.csv"
open_drive_file_name = f"track.csv"
scene_plotter = iai.utils.ScenePlotter(
fov=args.fov, xy_offset=(map_center[0], -map_center[1]), static_actors=corrected_static_actors, open_drive=open_drive_file_name)
fov=args.fov, xy_offset=(map_center[0], -map_center[1]), static_actors=corrected_static_actors,
open_drive=open_drive_file_name, dpi=args.dpi, resolution=args.resolution)
scene_plotter.initialize_recording(corrected_agents, agent_attributes=response.agent_attributes)

agent_attributes = response.agent_attributes
frames = []
x_frame = []
for i in tqdm(range(args.episode_length)):
light_response = iai.light(
try:
light_response = iai.light(
location=args.location, recurrent_states=light_response.recurrent_states)
except:
light_response = None
response = iai.drive(
agent_attributes=agent_attributes,
agent_states=response.agent_states,
recurrent_states=response.recurrent_states,
location=args.location,
traffic_lights_states=light_response.traffic_lights_states,
traffic_lights_states=light_response.traffic_lights_states if light_response else None,
)

corrected_agents = [AgentState.fromlist([state.center.x, -state.center.y,
if args.left_hand_coordinate:
corrected_agents = [AgentState.fromlist([state.center.x, -state.center.y,
(-state.orientation), state.speed]) for state in response.agent_states]
scene_plotter.record_step(corrected_agents, traffic_light_states=light_response.traffic_lights_states)
else:
corrected_agents = response.agent_states
scene_plotter.record_step(corrected_agents, traffic_light_states=light_response.traffic_lights_states if light_response else None)

gif_name = 'new_iai-drive-side-road-green.gif'
gif_name = 'iai-drive-opendrive.gif'
scene_plotter.animate_scene(output_name=gif_name,
numbers=False, direction_vec=True, velocity_vec=False,
plot_frame_number=True)
62 changes: 62 additions & 0 deletions examples/carla/region_drive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import argparse
import invertedai as iai
from invertedai.simulation.simulator import Simulation, SimulationConfig
import pathlib
import pygame
from tqdm import tqdm
from time import perf_counter
path = pathlib.Path(__file__).parent.resolve()


parser = argparse.ArgumentParser(description="Simulation Parameters.")
parser.add_argument("--api_key", type=str, default=None)
parser.add_argument("--fov", type=float, default=500)
parser.add_argument("--location", type=str, default="carla:Town10HD")
parser.add_argument("--center", type=str, default="carla:Town10HD")
parser.add_argument("-l", "--episode_length", type=int, default=300)
parser.add_argument("-cap", "--quadtree_capacity", type=int, default=15)
parser.add_argument("-ad", "--agent_density", type=int, default=10)
parser.add_argument("-ri", "--re_initialization", type=int, default=30)
parser.add_argument("-len", "--simulation_length", type=int, default=10000)
args = parser.parse_args()


if args.api_key is not None:
iai.add_apikey(args.api_key)
response = iai.location_info(location=args.location)
if response.birdview_image is not None:
rendered_static_map = response.birdview_image.decode()

cfg = SimulationConfig(location=args.location, map_center=(response.map_center.x, response.map_center.y),
map_fov=response.map_fov, rendered_static_map=rendered_static_map,
map_width=response.map_fov+200, map_height=response.map_fov+200, agent_density=args.agent_density,
initialize_stride=50, quadtree_capacity=args.quadtree_capacity,
re_initialization_period=args.re_initialization)
simulation = Simulation(cfg=cfg)

fps = 100
clock = pygame.time.Clock()
run = True
start = perf_counter()
fram_counter = 0
for _ in tqdm(range(args.simulation_length)):
# ----- HANDLE EVENTS ------
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYUP:
if event.key in [pygame.K_q, pygame.K_ESCAPE]:
run = False
if event.key == pygame.K_t:
simulation.show_quadtree = not simulation.show_quadtree
if event.key == pygame.K_l:
for npc in simulation.npcs:
npc.show_agent_neighbors = not npc.show_agent_neighbors
if not run:
break
# -----------------------------
simulation.drive()
clock.tick(fps)

pygame.quit()
print(f"Speed: {(perf_counter()-start)/simulation.timer} secs/frame")
15 changes: 14 additions & 1 deletion examples/npc_only_colab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,27 @@
"![https://raw.githubusercontent.com/inverted-ai/invertedai/master/docs/images/banner-small.png](https://raw.githubusercontent.com/inverted-ai/invertedai/master/docs/images/banner-small.png)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "119c4821",
"metadata": {},
"outputs": [],
"source": [
"!pip install invertedai\n",
"import os\n",
"from IPython.display import clear_output\n",
"clear_output()\n",
"os.kill(os.getpid(), 9)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "911445d4-8b61-49a1-9620-d1f3eb0c4199",
"metadata": {},
"outputs": [],
"source": [
"!pip install invertedai\n",
"from IPython.display import display, Image, clear_output\n",
"import matplotlib.pyplot as plt\n",
"import imageio\n",
Expand Down
10 changes: 8 additions & 2 deletions invertedai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

from invertedai.api.light import light
from invertedai.api.location import location_info
from invertedai.api.initialize import initialize
from invertedai.api.drive import drive
from invertedai.api.initialize import initialize, async_initialize
from invertedai.api.drive import drive, async_drive
from invertedai.cosimulation import BasicCosimulation
from invertedai.simulation.simulator import Simulation
from invertedai import simulation
from invertedai.utils import Jupyter_Render, IAILogger, Session

dev = strtobool(os.environ.get("IAI_DEV", "false"))
Expand All @@ -30,6 +32,7 @@
"drive": ("post", "/drive"),
"location_info": ("get", "/location_info"),
"light": ("get", "/light"),
"test": ("get", "/test"),
}
__all__ = [
"BasicCosimulation",
Expand All @@ -42,4 +45,7 @@
"initialize",
"location_info",
"light",
"Simulation",
"async_initialize",
"async_drive",
]
4 changes: 2 additions & 2 deletions invertedai/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from invertedai.api.location import LocationResponse, location_info
from invertedai.api.initialize import InitializeResponse, initialize
from invertedai.api.drive import DriveResponse, drive
from invertedai.api.initialize import InitializeResponse, initialize, async_initialize
from invertedai.api.drive import DriveResponse, drive, async_drive
from invertedai.api.light import light, LightResponse
62 changes: 62 additions & 0 deletions invertedai/api/drive.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import time
from typing import List, Optional, Tuple
from pydantic import BaseModel, validate_arguments
import asyncio

import invertedai as iai
from invertedai.api.config import TIMEOUT, should_use_mock_api
Expand Down Expand Up @@ -177,3 +178,64 @@ def _tolist(input_data: List):
timeout is not None and time.time() > start + timeout
) or not e.should_retry:
raise e


@validate_arguments
async def async_drive(
location: str,
agent_states: List[AgentState],
agent_attributes: List[AgentAttributes],
recurrent_states: List[RecurrentState],
traffic_lights_states: Optional[TrafficLightStatesDict] = None,
get_birdview: bool = False,
rendering_center: Optional[Tuple[float, float]] = None,
rendering_fov: Optional[float] = None,
get_infractions: bool = False,
random_seed: Optional[int] = None,
) -> DriveResponse:
"""
A light async version of :func:`drive`
"""
def _tolist(input_data: List):
if not isinstance(input_data, list):
return input_data.tolist()
else:
return input_data

recurrent_states = (
_tolist(recurrent_states) if recurrent_states is not None else None
) # AxTx2x64
model_inputs = dict(
location=location,
agent_states=[state.tolist() for state in agent_states],
agent_attributes=[state.tolist() for state in agent_attributes],
recurrent_states=[r.packed for r in recurrent_states],
traffic_lights_states=traffic_lights_states,
get_birdview=get_birdview,
get_infractions=get_infractions,
random_seed=random_seed,
rendering_center=rendering_center,
rendering_fov=rendering_fov
)
response = await iai.session.async_request(model="drive", data=model_inputs)

response = DriveResponse(
agent_states=[
AgentState.fromlist(state) for state in response["agent_states"]
],
recurrent_states=[
RecurrentState.fromval(r) for r in response["recurrent_states"]
],
birdview=Image.fromval(response["birdview"])
if response["birdview"] is not None
else None,
infractions=[
InfractionIndicators.fromlist(infractions)
for infractions in response["infraction_indicators"]
]
if response["infraction_indicators"]
else [],
is_inside_supported_area=response["is_inside_supported_area"],
)

return response

0 comments on commit ba09b95

Please sign in to comment.