Compare commits

...

5 Commits

5 changed files with 192 additions and 59 deletions

View File

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

View File

@ -1,3 +1,4 @@
from gym.envs.registration import register
import gym
from gym import spaces
import numpy as np
@ -16,7 +17,6 @@ class ColumbusEnv(gym.Env):
low=0, high=1, shape=(2,), dtype=np.float32)
observable._set_env(self)
self.observable = observable
self.observation_space = self.observable.get_observation_space()
self.title = 'Untitled'
self.fps = fps
self.env_seed = env_seed
@ -40,11 +40,17 @@ class ColumbusEnv(gym.Env):
self.draw_observable = True
self.draw_joystick = True
self.draw_entities = True
self.void_barrier = True
self.void_damage = 100
self.rng = random_dont_use.Random()
self.reset()
self.observation_space = self.observable.get_observation_space()
def _seed(self, seed):
if seed == None:
seed = random_dont_use.random()
self.rng.seed(seed)
def random(self):
@ -112,6 +118,9 @@ class ColumbusEnv(gym.Env):
reward, self.new_reward, self.new_abs_reward = self.new_reward / \
self.fps + self.new_abs_reward, 0, 0
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:
reward += self._get_aux_reward()
done = self.die_on_zero and self.score <= 0 or self.return_on_score != - \
@ -150,20 +159,7 @@ class ColumbusEnv(gym.Env):
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)
# Expand this function
def reset(self):
pygame.init()
@ -221,23 +217,158 @@ class ColumbusEnv(gym.Env):
class ColumbusTest3_1(ColumbusEnv):
def __init__(self):
def __init__(self, observable=observables.CnnObservable(out_width=48, out_height=48), fps=30):
super(ColumbusTest3_1, self).__init__(
observable=observables.CnnObservable(out_width=48, out_height=48))
observable=observable, fps=fps, env_seed=3.1)
self.start_pos = [0.6, 0.3]
self.fps = 30
self.score = 0
self.reward_mult = 0.001
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):
def __init__(self, hide_map=False):
class ColumbusTestRay(ColumbusTest3_1):
def __init__(self, observable=observables.RayObservable(), hide_map=False, fps=30):
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
observable=observable, fps=fps)
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,
)

View File

@ -1,13 +0,0 @@
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():
env = ColumbusTest3_1()
env = ColumbusTestRay(hide_map=True)
#env = ColumbusTest3_1()
env = ColumbusEasyObstacles(fps=30)
env.start_pos = [0.6, 0.3]
playEnv(env)
env.close()
@ -17,15 +17,22 @@ def main():
def playEnv(env):
env.reset()
done = False
to = 0
while not done:
t1 = time()
env.render()
pos = (0.5, 0.5)
for event in pygame.event.get():
pass
# if event.type == pygame.MOUSEBUTTONDOWN:
# pos = pygame.mouse.get_pos()
# print(pos)
keys = pygame.key.get_pressed()
if to == 0:
to = int(env.fps/2)
if keys[pygame.K_m]:
env.draw_entities = not env.draw_entities
else:
to = 0
else:
to -= 1
pos = pygame.mouse.get_pos()
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))

View File

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