Skip to content

Commit

Permalink
Merge branch 'v1.0.0' into dev_edt_asset
Browse files Browse the repository at this point in the history
  • Loading branch information
hzheng40 committed Feb 28, 2024
2 parents 38697c4 + 79bdc5e commit c9a589b
Show file tree
Hide file tree
Showing 26 changed files with 1,044 additions and 729 deletions.
59 changes: 59 additions & 0 deletions examples/run_in_empty_track.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import numpy as np

from waypoint_follow import PurePursuitPlanner
from f110_gym.envs.track import Track
import gymnasium as gym


def main():
"""
Demonstrate the creation of an empty map with a custom reference line.
This is useful for testing and debugging control algorithms on standard maneuvers.
"""
# create sinusoidal reference line with custom velocity profile
xs = np.linspace(0, 100, 200)
ys = np.sin(xs / 2.0) * 5.0
velxs = 4.0 * (1 + (np.abs(np.cos(xs / 2.0))))

# create track from custom reference line
track = Track.from_refline(x=xs, y=ys, velx=velxs)

# env and planner
env = gym.make(
"f110_gym:f110-v0",
config={
"map": track,
"num_agents": 1,
"observation_config": {"type": "kinematic_state"},
},
render_mode="human",
)
planner = PurePursuitPlanner(track=track, wb=0.17145 + 0.15875)

# rendering callbacks
env.add_render_callback(track.raceline.render_waypoints)
env.add_render_callback(planner.render_lookahead_point)

# simulation
obs, info = env.reset()
done = False
env.render()

while not done:
speed, steer = planner.plan(
obs["agent_0"]["pose_x"],
obs["agent_0"]["pose_y"],
obs["agent_0"]["pose_theta"],
lookahead_distance=0.8,
vgain=1.0,
)
action = np.array([[steer, speed]])
obs, timestep, terminated, truncated, infos = env.step(action)
done = terminated or truncated
env.render()

env.close()


if __name__ == "__main__":
main()
22 changes: 3 additions & 19 deletions examples/waypoint_follow.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,6 @@ def load_waypoints(self, conf):
conf.wpt_path, delimiter=conf.wpt_delim, skiprows=conf.wpt_rowskip
).astype(np.float32)

def render_waypoints(self, e):
"""
Callback to render waypoints.
"""
points = self.waypoints[:, :2]
e.render_closed_lines(points, color=(128, 0, 0), size=1)

def render_lookahead_point(self, e):
"""
Callback to render the lookahead point.
Expand Down Expand Up @@ -310,28 +303,19 @@ def main():
"model": "st",
"observation_config": {"type": "kinematic_state"},
"params": {"mu": 1.0},
"reset_config": {"type": "random_static"},
"reset_config": {"type": "rl_random_static"},
},
render_mode="human",
)
track = env.unwrapped.track

planner = PurePursuitPlanner(track=track, wb=0.17145 + 0.15875)

poses = np.array(
[
[
track.raceline.xs[0],
track.raceline.ys[0],
track.raceline.yaws[0],
]
]
)
env.unwrapped.add_render_callback(planner.render_waypoints)
env.unwrapped.add_render_callback(track.raceline.render_waypoints)
env.unwrapped.add_render_callback(planner.render_local_plan)
env.unwrapped.add_render_callback(planner.render_lookahead_point)

obs, info = env.reset(options={"poses": poses})
obs, info = env.reset()
done = False
env.render()

Expand Down
13 changes: 7 additions & 6 deletions gym/f110_gym/envs/base_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from f110_gym.envs.collision_models import collision_multiple, get_vertices
from f110_gym.envs.integrator import EulerIntegrator, IntegratorType
from f110_gym.envs.laser_models import ScanSimulator2D, check_ttc_jit, ray_cast
from f110_gym.envs.track import Track


class RaceCar(object):
Expand Down Expand Up @@ -177,14 +178,14 @@ def update_params(self, params):
"""
self.params = params

def set_map(self, map_name: str):
def set_map(self, map: str | Track):
"""
Sets the map for scan simulator
Args:
map_name (str): name of the map
map (str | Track): name of the map, or Track object
"""
RaceCar.scan_simulator.set_map(map_name)
RaceCar.scan_simulator.set_map(map)

def reset(self, pose):
"""
Expand Down Expand Up @@ -430,18 +431,18 @@ def __init__(
num_beams = self.agents[0].scan_simulator.num_beams
self.agent_scans = np.empty((self.num_agents, num_beams))

def set_map(self, map_name):
def set_map(self, map: str | Track):
"""
Sets the map of the environment and sets the map for scan simulator of each agent
Args:
map_name (str): name of the map
map (str | Track): name of the map, or Track object
Returns:
None
"""
for agent in self.agents:
agent.set_map(map_name)
agent.set_map(map)

def update_params(self, params, agent_idx=-1):
"""
Expand Down
18 changes: 11 additions & 7 deletions gym/f110_gym/envs/f110_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def __init__(self, config: dict = None, render_mode=None, **kwargs):
self.configure(config)

self.seed = self.config["seed"]
self.map_name = self.config["map"]
self.map = self.config["map"]
self.params = self.config["params"]
self.num_agents = self.config["num_agents"]
self.timestep = self.config["timestep"]
Expand Down Expand Up @@ -143,10 +143,14 @@ def __init__(self, config: dict = None, render_mode=None, **kwargs):
model=self.model,
action_type=self.action_type,
)
self.sim.set_map(self.map_name)
self.track = Track.from_track_name(
self.map_name
) # load track in gym env for convenience
self.sim.set_map(self.map)

if isinstance(self.map, Track):
self.track = self.map
else:
self.track = Track.from_track_name(
self.map
) # load track in gym env for convenience

# observations
self.agent_ids = [f"agent_{i}" for i in range(self.num_agents)]
Expand Down Expand Up @@ -226,8 +230,8 @@ def default_config(cls) -> dict:
"integrator": "rk4",
"model": "st",
"control_input": ["speed", "steering_angle"],
"observation_config": {"type": "original"},
"reset_config": {"type": "grid_static"},
"observation_config": {"type": None},
"reset_config": {"type": None},
}

def configure(self, config: dict) -> None:
Expand Down
1 change: 0 additions & 1 deletion gym/f110_gym/envs/integrator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import warnings
from abc import abstractmethod
from enum import Enum

Expand Down
14 changes: 10 additions & 4 deletions gym/f110_gym/envs/laser_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Prototype of Utility functions and classes for simulating 2D LIDAR scans
Author: Hongrui Zheng
"""

from __future__ import annotations
import unittest

import numpy as np
Expand Down Expand Up @@ -448,24 +448,30 @@ def __init__(self, num_beams, fov, eps=0.0001, theta_dis=2000, max_range=30.0):
self.map_height = None
self.map_width = None
self.map_resolution = None
self.track = None
self.map_img = None
self.origin = None
self.dt = None

# precomputing corresponding cosines and sines of the angle array
theta_arr = np.linspace(0.0, 2 * np.pi, num=theta_dis)
self.sines = np.sin(theta_arr)
self.cosines = np.cos(theta_arr)

def set_map(self, map_name: str):
def set_map(self, map: str | Track):
"""
Set the bitmap of the scan simulator by path
Args:
map_name (str): name of the racetrack in the map dir, e.g. "Levine"
map (str | Track): path to the map file, or Track object
Returns:
flag (bool): if image reading and loading is successful
"""
self.track = Track.from_track_name(map_name)
if isinstance(map, str):
self.track = Track.from_track_name(map)
elif isinstance(map, Track):
self.track = map

# load map image
self.map_img = self.track.occupancy_map
Expand Down
8 changes: 4 additions & 4 deletions gym/f110_gym/envs/observation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Author: Luigi Berducci
"""
from __future__ import annotations
from abc import abstractmethod
from typing import List

Expand Down Expand Up @@ -265,7 +263,9 @@ def observe(self):
return obs


def observation_factory(env, type: str, **kwargs) -> Observation:
def observation_factory(env, type: str | None, **kwargs) -> Observation:
type = type or "original"

if type == "original":
return OriginalObservation(env)
elif type == "features":
Expand Down
25 changes: 20 additions & 5 deletions gym/f110_gym/envs/rendering/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations
import pathlib
from typing import List, Tuple, Any
from typing import Any, Optional

from f110_gym.envs.rendering.renderer import RenderSpec, EnvRenderer
from f110_gym.envs.track import Track
Expand All @@ -10,9 +9,25 @@ def make_renderer(
params: dict[str, Any],
track: Track,
agent_ids: list[str],
render_mode: str = None,
render_fps: int = 100,
) -> Tuple[EnvRenderer, RenderSpec]:
render_mode: Optional[str] = None,
render_fps: Optional[int] = 100,
) -> tuple[EnvRenderer, RenderSpec]:
"""
Return an instance of the renderer and the rendering specification.
Parameters
----------
params : dict
dictionary of renderer parameters
track : Track
track object
agent_ids : list
list of agent ids to render
render_mode : str, optional
rendering mode, by default None
render_fps : int, optional
rendering frames per second, by default 100
"""
from f110_gym.envs.rendering.rendering_pygame import PygameEnvRenderer

cfg_file = pathlib.Path(__file__).parent.absolute() / "rendering.yaml"
Expand Down
Loading

0 comments on commit c9a589b

Please sign in to comment.