Compare commits
3 Commits
40d1129640
...
e3a1044cb3
Author | SHA1 | Date | |
---|---|---|---|
e3a1044cb3 | |||
d731695f2a | |||
b04de18a88 |
@ -31,6 +31,7 @@ class ColumbusEnv(gym.Env):
|
||||
self.acc_fac = 0.03/fps*60
|
||||
self.die_on_zero = False
|
||||
self.return_on_score = -1 # -1 = never
|
||||
self.reward_mult = 1
|
||||
self.agent_drag = 0 # 0.01 is a good value
|
||||
self.controll_type = 'SPEED' # one of SPEED, ACC
|
||||
self.limit_inp_to_unit_circle = True
|
||||
@ -38,6 +39,7 @@ class ColumbusEnv(gym.Env):
|
||||
self.aux_reward_discretize = 0 # 0 = dont discretize
|
||||
self.draw_observable = True
|
||||
self.draw_joystick = True
|
||||
self.draw_entities = True
|
||||
|
||||
self.rng = random_dont_use.Random()
|
||||
self.reset()
|
||||
@ -77,11 +79,11 @@ class ColumbusEnv(gym.Env):
|
||||
new_timers.append((time_left, func, arg))
|
||||
self.timers = new_timers
|
||||
|
||||
def sq_dist(self, entity1, entity2):
|
||||
return (entity1.pos[0] - entity2.pos[0])**2 + (entity1.pos[1] - entity2.pos[1])**2
|
||||
def sq_dist(self, pos1, pos2):
|
||||
return (pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2
|
||||
|
||||
def dist(self, entity1, entity2):
|
||||
return math.sqrt(self._sq_dist(entity1, entity2))
|
||||
def dist(self, pos1, pos2):
|
||||
return math.sqrt(self.sq_dist(pos1, pos2))
|
||||
|
||||
def _get_aux_reward(self):
|
||||
aux_reward = 0
|
||||
@ -89,7 +91,7 @@ class ColumbusEnv(gym.Env):
|
||||
if isinstance(entity, entities.Reward):
|
||||
if entity.avaible:
|
||||
reward = self.aux_reward_max / \
|
||||
(1 + self.sq_dist(entity, self.agent))
|
||||
(1 + self.sq_dist(entity.pos, self.agent.pos))
|
||||
|
||||
if self.aux_reward_discretize:
|
||||
reward = int(reward*self.aux_reward_discretize*2) / \
|
||||
@ -115,7 +117,8 @@ class ColumbusEnv(gym.Env):
|
||||
done = self.die_on_zero and self.score <= 0 or self.return_on_score != - \
|
||||
1 and self.score > self.return_on_score
|
||||
info = {'score': self.score, 'reward': reward}
|
||||
return observation, reward, done, info
|
||||
self._rendered = False
|
||||
return observation, reward*self.reward_mult, done, info
|
||||
|
||||
def check_collisions_for(self, entity):
|
||||
for other in self.entities:
|
||||
@ -164,6 +167,7 @@ class ColumbusEnv(gym.Env):
|
||||
|
||||
def reset(self):
|
||||
pygame.init()
|
||||
self._rendered = False
|
||||
self.inp = (0.5, 0.5)
|
||||
# will get rescaled acording to fps (=reward per second)
|
||||
self.new_reward = 0
|
||||
@ -193,12 +197,18 @@ class ColumbusEnv(gym.Env):
|
||||
pygame.draw.circle(self.screen, (100, 100, 100), (20+int(60*x) +
|
||||
self.joystick_offset[0], 20+int(60*y)+self.joystick_offset[1]), 20, width=0)
|
||||
|
||||
def render(self, mode='human'):
|
||||
self.visible = True
|
||||
def render(self, mode='human', dont_show=False):
|
||||
self.visible = self.visible or not dont_show
|
||||
self._ensure_surface()
|
||||
pygame.draw.rect(self.surface, (0, 0, 0),
|
||||
pygame.Rect(0, 0, self.width, self.height))
|
||||
self._draw_entities()
|
||||
if self.draw_entities:
|
||||
self._draw_entities()
|
||||
else:
|
||||
self.agent.draw()
|
||||
self._rendered = True
|
||||
if dont_show:
|
||||
return
|
||||
self.screen.blit(self.surface, (0, 0))
|
||||
self._draw_observable()
|
||||
self._draw_joystick()
|
||||
@ -217,3 +227,16 @@ class ColumbusTest3_1(ColumbusEnv):
|
||||
self.start_pos = [0.6, 0.3]
|
||||
self.fps = 30
|
||||
self.score = 0
|
||||
self.reward_mult = 0.001
|
||||
self.aux_reward_max = 1
|
||||
|
||||
|
||||
class ColumbusTestRay(ColumbusEnv):
|
||||
def __init__(self):
|
||||
super(ColumbusTestRay, self).__init__(
|
||||
observable=observables.RayObservable())
|
||||
self.start_pos = [0.6, 0.3]
|
||||
self.fps = 30
|
||||
self.score = 0
|
||||
self.reward_mult = 0.001
|
||||
self.aux_reward_max = 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
from time import sleep, time
|
||||
from env import ColumbusEnv, ColumbusTest3_1
|
||||
from env import *
|
||||
import numpy as np
|
||||
import pygame
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
from gym import spaces
|
||||
import numpy as np
|
||||
import pygame
|
||||
import math
|
||||
from columbus import entities
|
||||
|
||||
|
||||
class Observable():
|
||||
@ -16,6 +18,12 @@ class Observable():
|
||||
return spaces.Box(low=0, high=255,
|
||||
shape=(1,), dtype=np.uint8)
|
||||
|
||||
def get_observation(self):
|
||||
return False
|
||||
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
|
||||
class CnnObservable(Observable):
|
||||
def __init__(self, in_width=256, in_height=256, out_width=32, out_height=32, draw_width=128, draw_height=128, smooth_scaling=True):
|
||||
@ -36,6 +44,8 @@ class CnnObservable(Observable):
|
||||
shape=(self.out_width, self.out_height, 3), dtype=np.uint8)
|
||||
|
||||
def get_observation(self):
|
||||
if not self.env._rendered:
|
||||
self.env.render(dont_show=True)
|
||||
self.env._ensure_surface()
|
||||
x, y = self.env.agent.pos[0]*self.env.width - self.in_width / \
|
||||
2, self.env.agent.pos[1]*self.env.height - self.in_height/2
|
||||
@ -69,3 +79,66 @@ class CnnObservable(Observable):
|
||||
|
||||
def _clip(num, lower, upper):
|
||||
return min(max(num, lower), upper)
|
||||
|
||||
|
||||
class RayObservable(Observable):
|
||||
def __init__(self, num_rays=24, chans=[entities.Enemy, entities.Reward], ray_len=256):
|
||||
super(RayObservable, self).__init__()
|
||||
self.num_rays = num_rays
|
||||
self.chans = chans
|
||||
self.num_chans = len(chans)
|
||||
self.ray_len = ray_len
|
||||
self.num_steps = 32 # max = 255
|
||||
self.occlusion = True # previous channels block view onto later channels
|
||||
|
||||
def get_observation_space(self):
|
||||
return spaces.Box(low=0, high=self.num_steps,
|
||||
shape=(self.num_rays, self.num_chans), dtype=np.uint8)
|
||||
|
||||
def _get_ray_heads(self):
|
||||
for i in range(self.num_rays):
|
||||
rad = 2*math.pi/self.num_rays*i
|
||||
yield self.ray_len*math.sin(rad), self.ray_len*math.cos(rad)
|
||||
|
||||
def _check_collision(self, pos, entity_type):
|
||||
for entity in self.env.entities:
|
||||
if isinstance(entity, entity_type):
|
||||
if entity.shape != 'circle':
|
||||
raise Exception('Can only raycast circular entities!')
|
||||
sq_dist = (pos[0]-entity.pos[0]*self.env.width) ** 2 \
|
||||
+ (pos[1]-entity.pos[1]*self.env.height)**2
|
||||
if sq_dist < entity.radius**2:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_observation(self):
|
||||
self.rays = np.zeros((self.num_rays, self.num_chans))
|
||||
for r, (hx, hy) in enumerate(self._get_ray_heads()):
|
||||
occ_dist = self.num_steps
|
||||
for c, entity_type in enumerate(self.chans):
|
||||
for s in range(self.num_steps):
|
||||
if s > occ_dist:
|
||||
break
|
||||
sx, sy = s*hx/self.num_steps, s*hy/self.num_steps
|
||||
rx, ry = sx + \
|
||||
self.env.agent.pos[0]*self.env.width, sy + \
|
||||
self.env.agent.pos[1]*self.env.height
|
||||
if self._check_collision((rx, ry), entity_type):
|
||||
self.rays[r, c] = self.num_steps-s
|
||||
if self.occlusion:
|
||||
occ_dist = s
|
||||
break
|
||||
return self.rays
|
||||
|
||||
def draw(self):
|
||||
for c, entity_type in enumerate(self.chans):
|
||||
for r, (hx, hy) in enumerate(self._get_ray_heads()):
|
||||
s = self.num_steps - self.rays[r, c]
|
||||
sx, sy = s*hx/self.num_steps, s*hy/self.num_steps
|
||||
rx, ry = sx + \
|
||||
self.env.agent.pos[0]*self.env.width, sy + \
|
||||
self.env.agent.pos[1]*self.env.height
|
||||
# TODO: How stupid do I want to code?
|
||||
col = entity_type(self.env).col
|
||||
col = int(col[0]/2), int(col[1]/2), int(col[2]/2)
|
||||
pygame.draw.circle(self.env.screen, col, (rx, ry), 3, width=0)
|
||||
|
Loading…
Reference in New Issue
Block a user