last changes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import math
|
||||
import numpy as np
|
||||
import logging
|
||||
import pygame
|
||||
|
||||
import Box2D
|
||||
from Box2D import (b2FixtureDef, b2PolygonShape, b2ContactListener)
|
||||
@@ -20,8 +21,6 @@ except Exception:
|
||||
|
||||
from gymnasium.envs.box2d.car_dynamics import Car
|
||||
|
||||
import pygame
|
||||
|
||||
DEBUG_DRAWING = False
|
||||
LOOK_AHEAD = 10
|
||||
|
||||
@@ -98,9 +97,9 @@ class MyState:
|
||||
|
||||
|
||||
class FrictionDetector(b2ContactListener):
|
||||
def __init__(self, env):
|
||||
def __init__(self, car_env):
|
||||
super().__init__()
|
||||
self.env = env
|
||||
self.env = car_env
|
||||
|
||||
def BeginContact(self, contact):
|
||||
self._contact(contact, True)
|
||||
@@ -142,6 +141,17 @@ class FrictionDetector(b2ContactListener):
|
||||
self.env.on_road = len(obj.tiles) > 0
|
||||
|
||||
|
||||
def _world_to_screen(x, y, zoom, angle, scroll_x, scroll_y):
|
||||
ca, sa = math.cos(angle), math.sin(angle)
|
||||
|
||||
rx = (x - scroll_x) * ca + (y - scroll_y) * sa
|
||||
ry = -(x - scroll_x) * sa + (y - scroll_y) * ca
|
||||
|
||||
sx = int(WINDOW_W / 2 + rx * zoom)
|
||||
sy = int(WINDOW_H / 4 + ry * zoom)
|
||||
return sx, sy
|
||||
|
||||
|
||||
class CarRacing:
|
||||
metadata = {
|
||||
"render_modes": ["human", "rgb_array", None],
|
||||
@@ -150,6 +160,7 @@ class CarRacing:
|
||||
|
||||
def __init__(self, seed_value: int = 5, render_mode: str | None = "human"):
|
||||
|
||||
self.road_poly = None
|
||||
self.offroad_frames = None
|
||||
if seeding is not None:
|
||||
self.np_random, _ = seeding.np_random(seed_value)
|
||||
@@ -216,9 +227,9 @@ class CarRacing:
|
||||
if self._pg is None:
|
||||
self._pg = self._PygameCtx()
|
||||
if not self._pg.initialized:
|
||||
import pygame
|
||||
if not pygame.get_init():
|
||||
pygame.init()
|
||||
flags = 0
|
||||
if self.render_mode == "human":
|
||||
self._pg.screen = pygame.display.set_mode((WINDOW_W, WINDOW_H))
|
||||
else:
|
||||
@@ -232,23 +243,13 @@ class CarRacing:
|
||||
self._pg.font = None
|
||||
self._pg.initialized = True
|
||||
|
||||
def _world_to_screen(self, x, y, zoom, angle, scroll_x, scroll_y):
|
||||
ca, sa = math.cos(angle), math.sin(angle)
|
||||
|
||||
rx = (x - scroll_x) * ca + (y - scroll_y) * sa
|
||||
ry = -(x - scroll_x) * sa + (y - scroll_y) * ca
|
||||
|
||||
sx = int(WINDOW_W / 2 + rx * zoom)
|
||||
sy = int(WINDOW_H / 4 + ry * zoom)
|
||||
return sx, sy
|
||||
|
||||
def get_feature_vector(self, lookahead: int = LOOK_AHEAD) -> list[float]:
|
||||
my_s: MyState = self.my_state
|
||||
vec = my_s.as_feature_vector(lookahead).tolist()
|
||||
return vec
|
||||
|
||||
def _draw_polygon_world(self, poly, color, zoom, angle, scroll_x, scroll_y):
|
||||
pts = [self._world_to_screen(px, py, zoom, angle, scroll_x, scroll_y) for (px, py) in poly]
|
||||
pts = [_world_to_screen(px, py, zoom, angle, scroll_x, scroll_y) for (px, py) in poly]
|
||||
pygame.draw.polygon(self._pg.screen, f2c(color), pts)
|
||||
|
||||
def _draw_body(self, body, color=(0.7, 0.7, 0.7), zoom=1.0, angle=0.0, scroll_x=0.0, scroll_y=0.0):
|
||||
@@ -258,7 +259,7 @@ class CarRacing:
|
||||
shape = fixture.shape
|
||||
if isinstance(shape, b2PolygonShape):
|
||||
verts = [body.transform * v for v in shape.vertices]
|
||||
pts = [self._world_to_screen(v[0], v[1], zoom, angle, scroll_x, scroll_y) for v in verts]
|
||||
pts = [_world_to_screen(v[0], v[1], zoom, angle, scroll_x, scroll_y) for v in verts]
|
||||
pygame.draw.polygon(self._pg.screen, col, pts, width=0)
|
||||
|
||||
def _destroy(self):
|
||||
@@ -432,8 +433,8 @@ class CarRacing:
|
||||
self.track = track
|
||||
|
||||
self.original_road_poly = [((list(poly)), list(color)) for (poly, color) in self.road_poly]
|
||||
self.ctrl_pts = np.array(list(map(lambda x: x[2:], self.track)))
|
||||
self.angles = np.array(list(map(lambda x: x[1], self.track)))
|
||||
self.ctrl_pts = np.array(list(map(lambda x_coord: x_coord[2:], self.track)))
|
||||
self.angles = np.array(list(map(lambda x_coord: x_coord[1], self.track)))
|
||||
self.outward_vectors = [np.array([np.cos(theta), np.sin(theta)]) for theta in self.angles]
|
||||
angle_deltas = self.angles - np.roll(self.angles, 1)
|
||||
self.angle_deltas = np.array(list(map(standardize_angle, angle_deltas)))
|
||||
@@ -468,7 +469,7 @@ class CarRacing:
|
||||
self._no_progress_steps = 0
|
||||
self._stall_steps = 0
|
||||
|
||||
def reset(self, *, seed: int | None = None, options: dict | None = None):
|
||||
def reset(self, *, seed: int | None = None):
|
||||
if seed is not None:
|
||||
|
||||
if seeding is not None:
|
||||
@@ -476,8 +477,9 @@ class CarRacing:
|
||||
else:
|
||||
self.np_random = np.random.RandomState(seed)
|
||||
self._build_new_episode()
|
||||
obs = self._get_observation()
|
||||
info = {}
|
||||
obs, _, _, _, info = self.step(
|
||||
np.array([0.0, 0.0, 0.0], dtype=np.float32)
|
||||
)
|
||||
return obs, info
|
||||
|
||||
def fast_reset(self):
|
||||
@@ -509,12 +511,12 @@ class CarRacing:
|
||||
|
||||
return self.step(np.array([0.0, 0.0, 0.0], dtype=np.float32))
|
||||
|
||||
def step(self, action):
|
||||
def step(self, env_action):
|
||||
|
||||
if action is not None:
|
||||
self.car.steer(-float(action[0]))
|
||||
self.car.gas(float(action[1]))
|
||||
self.car.brake(float(action[2]))
|
||||
if env_action is not None:
|
||||
self.car.steer(-float(env_action[0]))
|
||||
self.car.gas(float(env_action[1]))
|
||||
self.car.brake(float(env_action[2]))
|
||||
|
||||
self.car.step(1.0 / FPS)
|
||||
self.world.Step(1.0 / FPS, 6 * 30, 2 * 30)
|
||||
@@ -522,27 +524,27 @@ class CarRacing:
|
||||
|
||||
self.steps += 1
|
||||
|
||||
terminated = False
|
||||
truncated = False
|
||||
env_terminated = False
|
||||
env_truncated = False
|
||||
|
||||
if action is not None:
|
||||
if env_action is not None:
|
||||
|
||||
self.reward -= 5.0 / FPS
|
||||
|
||||
if self.tile_visited_count == len(self.track):
|
||||
terminated = True
|
||||
env_terminated = True
|
||||
|
||||
x, y = self.car.hull.position
|
||||
if abs(x) > PLAYFIELD or abs(y) > PLAYFIELD:
|
||||
self.reward -= 100.0
|
||||
terminated = True
|
||||
env_terminated = True
|
||||
|
||||
if not self.on_road:
|
||||
self.offroad_frames += 1
|
||||
self.reward -= self.offroad_penalty_per_frame / FPS
|
||||
if self.offroad_frames > self.offroad_grace_frames:
|
||||
self.reward -= 20.0
|
||||
terminated = True
|
||||
env_terminated = True
|
||||
else:
|
||||
self.offroad_frames = 0
|
||||
|
||||
@@ -552,7 +554,7 @@ class CarRacing:
|
||||
else:
|
||||
self._no_progress_steps += 1
|
||||
if self._no_progress_steps >= NO_PROGRESS_STEPS:
|
||||
truncated = True
|
||||
env_truncated = True
|
||||
|
||||
step_reward = self.reward - self.prev_reward
|
||||
self.prev_reward = self.reward
|
||||
@@ -605,11 +607,10 @@ class CarRacing:
|
||||
|
||||
obs = self._get_observation()
|
||||
info = {"features": self.my_state}
|
||||
return obs, step_reward, terminated, truncated, info
|
||||
return obs, step_reward, env_terminated, env_truncated, info
|
||||
|
||||
def _get_observation(self):
|
||||
|
||||
return None
|
||||
return np.array(self.get_feature_vector(), dtype=np.float32)
|
||||
|
||||
def render(self):
|
||||
self._ensure_pygame()
|
||||
@@ -636,10 +637,10 @@ class CarRacing:
|
||||
for y in range(-20, 20, 2):
|
||||
x0, y0 = k * x + 0, k * y + 0
|
||||
x1, y1 = k * x + k, k * y + k
|
||||
p0 = self._world_to_screen(x0, y0, zoom, angle, scroll_x, scroll_y)
|
||||
p1 = self._world_to_screen(x1, y0, zoom, angle, scroll_x, scroll_y)
|
||||
p2 = self._world_to_screen(x1, y1, zoom, angle, scroll_x, scroll_y)
|
||||
p3 = self._world_to_screen(x0, y1, zoom, angle, scroll_x, scroll_y)
|
||||
p0 = _world_to_screen(x0, y0, zoom, angle, scroll_x, scroll_y)
|
||||
p1 = _world_to_screen(x1, y0, zoom, angle, scroll_x, scroll_y)
|
||||
p2 = _world_to_screen(x1, y1, zoom, angle, scroll_x, scroll_y)
|
||||
p3 = _world_to_screen(x0, y1, zoom, angle, scroll_x, scroll_y)
|
||||
pygame.draw.polygon(self._pg.screen, grid_color, [p0, p1, p2, p3])
|
||||
|
||||
for poly, color in self.road_poly:
|
||||
|
||||
Reference in New Issue
Block a user