Compare commits

..

No commits in common. "fe6cb991dd7cb80de0ed95815cde13298be370c5" and "1c81c6bae9b9585cff9599506f81b5e70e44a0b6" have entirely different histories.

5 changed files with 59 additions and 192 deletions

View File

@ -1,2 +1 @@
# emtpy # emtpy
from columbus import env

View File

@ -1,4 +1,3 @@
from gym.envs.registration import register
import gym import gym
from gym import spaces from gym import spaces
import numpy as np import numpy as np
@ -17,6 +16,7 @@ class ColumbusEnv(gym.Env):
low=0, high=1, shape=(2,), dtype=np.float32) low=0, high=1, shape=(2,), dtype=np.float32)
observable._set_env(self) observable._set_env(self)
self.observable = observable self.observable = observable
self.observation_space = self.observable.get_observation_space()
self.title = 'Untitled' self.title = 'Untitled'
self.fps = fps self.fps = fps
self.env_seed = env_seed self.env_seed = env_seed
@ -40,17 +40,11 @@ class ColumbusEnv(gym.Env):
self.draw_observable = True self.draw_observable = True
self.draw_joystick = True self.draw_joystick = True
self.draw_entities = True self.draw_entities = True
self.void_barrier = True
self.void_damage = 100
self.rng = random_dont_use.Random() self.rng = random_dont_use.Random()
self.reset() self.reset()
self.observation_space = self.observable.get_observation_space()
def _seed(self, seed): def _seed(self, seed):
if seed == None:
seed = random_dont_use.random()
self.rng.seed(seed) self.rng.seed(seed)
def random(self): def random(self):
@ -118,9 +112,6 @@ class ColumbusEnv(gym.Env):
reward, self.new_reward, self.new_abs_reward = self.new_reward / \ reward, self.new_reward, self.new_abs_reward = self.new_reward / \
self.fps + self.new_abs_reward, 0, 0 self.fps + self.new_abs_reward, 0, 0
self.score += reward # aux_reward does not count towards the score self.score += reward # aux_reward does not count towards the score
if self.agent.pos[0] < 0.001 or self.agent.pos[0] > 0.999 \
or self.agent.pos[1] < 0.001 or self.agent.pos[1] > 0.999:
reward -= self.void_damage/self.fps
if self.aux_reward_max: if self.aux_reward_max:
reward += self._get_aux_reward() reward += self._get_aux_reward()
done = self.die_on_zero and self.score <= 0 or self.return_on_score != - \ done = self.die_on_zero and self.score <= 0 or self.return_on_score != - \
@ -159,7 +150,20 @@ class ColumbusEnv(gym.Env):
def setup(self): def setup(self):
self.agent.pos = self.start_pos self.agent.pos = self.start_pos
# Expand this function for i in range(18):
enemy = entities.CircleBarrier(self)
enemy.radius = self.random()*40+50
self.entities.append(enemy)
for i in range(3):
enemy = entities.FlyingChaser(self)
enemy.chase_acc = self.random()*0.4*0.3 # *0.6+0.5
self.entities.append(enemy)
for i in range(0):
reward = entities.TimeoutReward(self)
self.entities.append(reward)
for i in range(1):
reward = entities.TeleportingReward(self)
self.entities.append(reward)
def reset(self): def reset(self):
pygame.init() pygame.init()
@ -217,158 +221,23 @@ class ColumbusEnv(gym.Env):
class ColumbusTest3_1(ColumbusEnv): class ColumbusTest3_1(ColumbusEnv):
def __init__(self, observable=observables.CnnObservable(out_width=48, out_height=48), fps=30): def __init__(self):
super(ColumbusTest3_1, self).__init__( super(ColumbusTest3_1, self).__init__(
observable=observable, fps=fps, env_seed=3.1) observable=observables.CnnObservable(out_width=48, out_height=48))
self.start_pos = [0.6, 0.3] self.start_pos = [0.6, 0.3]
self.fps = 30
self.score = 0 self.score = 0
self.reward_mult = 0.001
self.aux_reward_max = 1 self.aux_reward_max = 1
def setup(self):
self.agent.pos = self.start_pos
for i in range(18):
enemy = entities.CircleBarrier(self)
enemy.radius = self.random()*40+50
self.entities.append(enemy)
for i in range(3):
enemy = entities.FlyingChaser(self)
enemy.chase_acc = self.random()*0.4*0.3 # *0.6+0.5
self.entities.append(enemy)
for i in range(0):
reward = entities.TimeoutReward(self)
self.entities.append(reward)
for i in range(1):
reward = entities.TeleportingReward(self)
self.entities.append(reward)
class ColumbusTestRay(ColumbusEnv):
class ColumbusTestRay(ColumbusTest3_1): def __init__(self, hide_map=False):
def __init__(self, observable=observables.RayObservable(), hide_map=False, fps=30):
super(ColumbusTestRay, self).__init__( super(ColumbusTestRay, self).__init__(
observable=observable, fps=fps) 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
self.draw_entities = not hide_map self.draw_entities = not hide_map
class ColumbusRayDrone(ColumbusTestRay):
def __init__(self, observable=observables.RayObservable(), hide_map=False, fps=30):
super(ColumbusRayDrone, self).__init__(
observable=observable, hide_map=hide_map, fps=fps)
self.controll_type = 'ACC'
self.agent_drag = 0.02
class ColumbusCandyland(ColumbusEnv):
def __init__(self, observable=observables.RayObservable(chans=[entities.Reward, entities.Void], num_rays=16, include_rand=True), hide_map=False, fps=30):
super(ColumbusCandyland, self).__init__(
observable=observable, fps=fps)
self.draw_entities = not hide_map
def setup(self):
self.agent.pos = self.start_pos
for i in range(0):
reward = entities.TimeoutReward(self)
reward.radius = 30
self.entities.append(reward)
for i in range(2):
reward = entities.TeleportingReward(self)
reward.radius = 30
self.entities.append(reward)
class ColumbusEasyObstacles(ColumbusEnv):
def __init__(self, observable=observables.RayObservable(num_rays=16), hide_map=False, fps=30, env_seed=None):
super(ColumbusEasyObstacles, self).__init__(
observable=observable, fps=fps)
self.draw_entities = not hide_map
self.aux_reward_max = 0.1
def setup(self):
self.agent.pos = self.start_pos
for i in range(5):
enemy = entities.CircleBarrier(self)
enemy.radius = 30 + self.random()*70
self.entities.append(enemy)
for i in range(2):
reward = entities.TeleportingReward(self)
reward.radius = 30
self.entities.append(reward)
for i in range(1):
enemy = entities.WalkingChaser(self)
enemy.chase_speed = 0.1
self.entities.append(enemy)
class ColumbusRewardEnemyPID(ColumbusEnv):
def __init__(self, observable=observables.StateObservable(), fps=30, env_seed=None):
super(ColumbusRewardEnemyPID, self).__init__(
observable=observable, fps=fps)
self.aux_reward_max = 0.1
def setup(self):
self.agent.pos = self.start_pos
# for i in range(2):
# enemy = entities.WalkingChaser(self)
# self.entities.append(enemy)
for i in range(3):
enemy = entities.FlyingChaser(self)
enemy.chase_acc = self.random()*0.4+0.3 # *0.6+0.5
self.entities.append(enemy)
for i in range(1):
reward = entities.TeleportingReward(self)
reward.radius = 30
self.entities.append(reward)
class ColumbusRewardEnemyPIDWithBarriers(ColumbusEnv):
def __init__(self, observable=observables.StateObservable(), fps=30, env_seed=3.1):
super(ColumbusRewardEnemyPIDWithBarriers, self).__init__(
observable=observable, fps=fps)
self.aux_reward_max = 0.01
self.start_pos = (0.5, 0.5)
def setup(self):
self.agent.pos = self.start_pos
for i in range(3):
enemy = entities.CircleBarrier(self)
enemy.radius = self.random()*25+75
self.entities.append(enemy)
for i in range(3):
enemy = entities.FlyingChaser(self)
enemy.chase_acc = self.random()*0.4+0.3 # *0.6+0.5
self.entities.append(enemy)
for i in range(1):
reward = entities.TeleportingReward(self)
reward.radius = 30
self.entities.append(reward)
###
register(
id='ColumbusTestCnn-v0',
entry_point=ColumbusTest3_1,
max_episode_steps=30*60*5,
)
register(
id='ColumbusTestRay-v0',
entry_point=ColumbusTestRay,
max_episode_steps=30*60*5,
)
register(
id='ColumbusRayDrone-v0',
entry_point=ColumbusRayDrone,
max_episode_steps=30*60*5,
)
register(
id='ColumbusCandyland-v0',
entry_point=ColumbusCandyland,
max_episode_steps=30*60*5,
)
register(
id='ColumbusEasyObstacles-v0',
entry_point=ColumbusEasyObstacles,
max_episode_steps=30*60*2,
)

13
columbus/gym_binding.py Normal file
View File

@ -0,0 +1,13 @@
from gym.envs.registration import register
from env import *
def register():
register(
# unique identifier for the env `name-version`
id="Columbus-Test317-v0",
# path to the class for creating the env
# Note: entry_point also accept a class as input (and not only a string)
entry_point=env.ColumbusEnv,
# Max number of steps per episode, using a `TimeLimitWrapper`
max_episode_steps=500,
)

View File

@ -7,8 +7,8 @@ from observables import Observable, CnnObservable
def main(): def main():
#env = ColumbusTest3_1() env = ColumbusTest3_1()
env = ColumbusEasyObstacles(fps=30) env = ColumbusTestRay(hide_map=True)
env.start_pos = [0.6, 0.3] env.start_pos = [0.6, 0.3]
playEnv(env) playEnv(env)
env.close() env.close()
@ -17,22 +17,15 @@ def main():
def playEnv(env): def playEnv(env):
env.reset() env.reset()
done = False done = False
to = 0
while not done: while not done:
t1 = time() t1 = time()
env.render() env.render()
pos = (0.5, 0.5) pos = (0.5, 0.5)
for event in pygame.event.get(): for event in pygame.event.get():
pass pass
keys = pygame.key.get_pressed() # if event.type == pygame.MOUSEBUTTONDOWN:
if to == 0: # pos = pygame.mouse.get_pos()
to = int(env.fps/2) # print(pos)
if keys[pygame.K_m]:
env.draw_entities = not env.draw_entities
else:
to = 0
else:
to -= 1
pos = pygame.mouse.get_pos() pos = pygame.mouse.get_pos()
pos = (min(max((pos[0]-env.joystick_offset[0]-20)/60, 0), 1), pos = (min(max((pos[0]-env.joystick_offset[0]-20)/60, 0), 1),
min(max((pos[1]-env.joystick_offset[1]-20)/60, 0), 1)) min(max((pos[1]-env.joystick_offset[1]-20)/60, 0), 1))

View File

@ -57,10 +57,6 @@ class CnnObservable(Observable):
rect = pygame.Rect(cx, cy, cw, ch) rect = pygame.Rect(cx, cy, cw, ch)
snap = self.env.surface.subsurface(rect) snap = self.env.surface.subsurface(rect)
self.snap = pygame.Surface((self.in_width, self.in_height)) self.snap = pygame.Surface((self.in_width, self.in_height))
if self.env.void_barrier:
col = (223, 0, 0)
else:
col = (50, 50, 50)
pygame.draw.rect(self.snap, (50, 50, 50), pygame.draw.rect(self.snap, (50, 50, 50),
pygame.Rect(0, 0, self.in_width, self.in_height)) pygame.Rect(0, 0, self.in_width, self.in_height))
self.snap.blit(snap, (cx - x, cy - y)) self.snap.blit(snap, (cx - x, cy - y))
@ -86,19 +82,18 @@ def _clip(num, lower, upper):
class RayObservable(Observable): class RayObservable(Observable):
def __init__(self, num_rays=16, chans=[entities.Enemy, entities.Reward], ray_len=256, num_steps=64, include_rand=False): def __init__(self, num_rays=24, chans=[entities.Enemy, entities.Reward, entities.Void], ray_len=256):
super(RayObservable, self).__init__() super(RayObservable, self).__init__()
self.num_rays = num_rays self.num_rays = num_rays
self.chans = chans self.chans = chans
self.num_chans = len(chans) self.num_chans = len(chans)
self.ray_len = ray_len self.ray_len = ray_len
self.num_steps = num_steps # max = 255 self.num_steps = 32 # max = 255
self.occlusion = True # previous channels block view onto later channels self.occlusion = True # previous channels block view onto later channels
self.include_rand = include_rand
def get_observation_space(self): def get_observation_space(self):
return spaces.Box(low=0, high=self.num_steps, return spaces.Box(low=0, high=self.num_steps,
shape=(self.num_rays+self.include_rand, self.num_chans), dtype=np.uint8) shape=(self.num_rays, self.num_chans), dtype=np.uint8)
def _get_ray_heads(self): def _get_ray_heads(self):
for i in range(self.num_rays): for i in range(self.num_rays):
@ -107,10 +102,12 @@ class RayObservable(Observable):
def _check_collision(self, pos, entity_type, entities_l): def _check_collision(self, pos, entity_type, entities_l):
for entity in entities_l: for entity in entities_l:
if isinstance(entity, entity_type) or (self.env.void_barrier and isinstance(entity, entities.Void) and entity_type == entities.Enemy): if isinstance(entity, entity_type):
if isinstance(entity, entities.Void): if isinstance(entity, entities.Void):
if 0 >= pos[0] or pos[0] >= self.env.width or 0 >= pos[1] or pos[0] >= self.env.height: hit = 0 >= pos[0] or pos[0] >= self.env.width or 0 >= pos[1] or pos[0] >= self.env.height
return True if hit:
print(pos)
return hit
else: else:
if entity.shape != 'circle': if entity.shape != 'circle':
raise Exception('Can only raycast circular entities!') raise Exception('Can only raycast circular entities!')
@ -122,7 +119,7 @@ class RayObservable(Observable):
def _get_possible_entities(self): def _get_possible_entities(self):
entities_l = [] entities_l = []
if entities.Void in self.chans or self.env.void_barrier: if entities.Void in self.chans:
entities_l.append(entities.Void(self.env)) entities_l.append(entities.Void(self.env))
for entity in self.env.entities: for entity in self.env.entities:
sq_dist = ((self.env.agent.pos[0]-entity.pos[0])*self.env.width) ** 2 \ sq_dist = ((self.env.agent.pos[0]-entity.pos[0])*self.env.width) ** 2 \
@ -133,10 +130,7 @@ class RayObservable(Observable):
def get_observation(self): def get_observation(self):
entities = self._get_possible_entities() entities = self._get_possible_entities()
self.rays = np.zeros((self.num_rays+self.include_rand, self.num_chans)) self.rays = np.zeros((self.num_rays, self.num_chans))
if self.include_rand:
for c in range(self.num_chans):
self.rays[-1, c] = self.env.random()
for r, (hx, hy) in enumerate(self._get_ray_heads()): for r, (hx, hy) in enumerate(self._get_ray_heads()):
occ_dist = self.num_steps occ_dist = self.num_steps
for c, entity_type in enumerate(self.chans): for c, entity_type in enumerate(self.chans):
@ -168,7 +162,7 @@ class RayObservable(Observable):
pygame.draw.circle(self.env.screen, col, (rx, ry), 3, width=0) pygame.draw.circle(self.env.screen, col, (rx, ry), 3, width=0)
class StateObservable(Observable): def StateObservable(Observable):
def __init__(self, coordsAgent=False, speedAgent=False, coordsRelativeToAgent=True, coordsRewards=True, rewardsWhitelist=None, coordsEnemys=True, enemysWhitelist=None, enemysNoBarriers=True, rewardsTimeouts=True): def __init__(self, coordsAgent=False, speedAgent=False, coordsRelativeToAgent=True, coordsRewards=True, rewardsWhitelist=None, coordsEnemys=True, enemysWhitelist=None, enemysNoBarriers=True, rewardsTimeouts=True):
super(StateObservable, self).__init__() super(StateObservable, self).__init__()
self._entities = None self._entities = None
@ -187,7 +181,6 @@ class StateObservable(Observable):
def entities(self): def entities(self):
if self._entities: if self._entities:
return self._entities return self._entities
self.env.setup()
self.rewardsWhitelist = self.rewardsWhitelist or self.env.entities self.rewardsWhitelist = self.rewardsWhitelist or self.env.entities
self.enemysWhitelist = self.enemysWhitelist or self.env.entities self.enemysWhitelist = self.enemysWhitelist or self.env.entities
self._entities = [] self._entities = []
@ -197,12 +190,12 @@ class StateObservable(Observable):
for entity in self.rewardsWhitelist: for entity in self.rewardsWhitelist:
if isinstance(entity, entities.Reward): if isinstance(entity, entities.Reward):
self._entities.append(entity) self._entities.append(entity)
if self.coordsEnemys: if self.coordEnemys:
for entity in self.enemysWhitelist: for entity in self.enemysWhitelist:
if isinstance(entity, entities.Enemy): if isinstance(entity, entities.Enemy):
if not self.enemysNoBarriers or not isinstance(entity, entities.Barrier): if not self.enemysNoBarriers or not isinstance(entity, entities.Barrier):
self._entities.append(entity) self._entities.append(entity)
if self.rewardsTimeouts: if self.rewardsTimeout:
for entity in self.enemysWhitelist: for entity in self.enemysWhitelist:
if isinstance(entity, entities.TimeoutReward): if isinstance(entity, entities.TimeoutReward):
self._timeoutEntities.append(entity) self._timeoutEntities.append(entity)
@ -210,7 +203,7 @@ class StateObservable(Observable):
def get_observation_space(self): def get_observation_space(self):
return spaces.Box(low=0-1*self.coordsRelativeToAgent, high=1, return spaces.Box(low=0-1*self.coordsRelativeToAgent, high=1,
shape=(len(self.entities)*2+len(self._timeoutEntities) + self.speedAgent,), dtype=np.float32) shape=(len(self.entities)*2+len(self._timeoutEntities) + self.speedAgent), dtype=np.float32)
def get_observation(self): def get_observation(self):
obs = [] obs = []