Compare commits
24
Commits
1ef66a7674
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6abf8e98d | ||
|
|
6095ca6fec | ||
|
|
db6cdeed21 | ||
|
|
e0f4aa3c13 | ||
|
|
d8e7c4c80f | ||
|
|
048ba027f3 | ||
|
|
35864d4b38 | ||
|
|
f421c92f83 | ||
|
|
164c72504c | ||
|
|
3bb3ffa3a0 | ||
|
|
5afa8b22b2 | ||
|
|
78ac536bb9 | ||
|
|
2032d2e91d | ||
|
|
292b12c5a1 | ||
|
|
ede0f80cea | ||
|
|
1bf587c4da | ||
|
|
6d465c69c9 | ||
|
|
8132bb9321 | ||
|
|
bde7869f97 | ||
|
|
7302d59727 | ||
|
|
f02163d88c | ||
|
|
06bfcfe065 | ||
|
|
d8856e7dc9 | ||
|
|
4fede26967 |
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Dominik Roth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -14,6 +14,12 @@ Project Columbus is a framework for trivial 2D OpenAI Gym environments that are
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Overview
|
||||
|
||||
Columbus.pdf contains a overview of columbus.
|
||||
|
||||
## Layout of the Repo
|
||||
|
||||
### env.py
|
||||
|
||||

|
||||
@@ -21,7 +27,9 @@ Contains the ColumbusEnv.
|
||||
There exist two ways to implement new envs:
|
||||
|
||||
- Subclassing ColumbusEnv and expanding _init_ and overriding _setup_.
|
||||
- Using the ColumbusConfigDefined with a desired configuration. This makes configuring ColumbusEnvs via ClusterWorks2-configs possible. (See ColumbusConfigDefinedExample.yaml for an example of how the parameters are supposed to look like (uses yaml format), I don't have time to write a better documentation right now...) (To test this run 'python humanPlayer.py', select 5, give path to ColumbusConfigDefinedExample.yaml, select 0)
|
||||
- Using the ColumbusConfigDefined with a desired configuration. This makes configuring ColumbusEnvs via ClusterWorks2-configs possible. (See configs/example.yaml for an example of how the parameters are supposed to look like (uses yaml format)
|
||||
- We now support using units (px, em, ct) in config files, examples can be found in configs/Example_Units.yaml
|
||||
- The environments used in my thesis can also be found in configs/
|
||||
|
||||
##### Some caveats / infos
|
||||
|
||||
|
||||
+178
-6
@@ -19,6 +19,7 @@ class Entity(object):
|
||||
self.col = (255, 255, 255)
|
||||
self.solid = False
|
||||
self.movable = False # False = Non movable, True = Movable, x>1: lighter movable
|
||||
self.void_collidable = False
|
||||
self.elasticity = 1
|
||||
self.collision_changes_speed = self.env.controll_type == 'ACC'
|
||||
self.collision_elasticity = self.env.default_collision_elasticity
|
||||
@@ -28,6 +29,11 @@ class Entity(object):
|
||||
self.draw_path = False
|
||||
self.draw_path_col = [int(c/5) for c in self.col]
|
||||
self.draw_path_width = 2
|
||||
self.draw_path_harm = False
|
||||
self.draw_path_harm_col = [c for c in self.draw_path_col]
|
||||
self.draw_path_harm_col[0] += int(255/3)
|
||||
self.min_speed = 0
|
||||
self.max_speed = math.inf
|
||||
|
||||
def __post_init__(self):
|
||||
pass
|
||||
@@ -37,8 +43,13 @@ class Entity(object):
|
||||
vx, vy = self.speed
|
||||
ax, ay = self.acc
|
||||
vx, vy = vx+ax*self.env.acc_fac, vy+ay*self.env.acc_fac
|
||||
speeds = math.sqrt(vx**2 + vy**2)
|
||||
if speeds < self.min_speed:
|
||||
vx, vy = vx/speeds*self.min_speed, vy/speeds*self.min_speed
|
||||
if speeds > self.max_speed:
|
||||
vx, vy = vx/speeds*self.max_speed, vy/speeds*self.max_speed
|
||||
x, y = x+vx*self.env.speed_fac, y+vy*self.env.speed_fac
|
||||
if not self.env.torus_topology:
|
||||
if not self.env.torus_topology and self.void_collidable:
|
||||
if x > 1 or x < 0:
|
||||
x, y, vx, vy = self.calc_void_collision(x < 0, x, y, vx, vy)
|
||||
if y > 1 or y < 0:
|
||||
@@ -63,8 +74,14 @@ class Entity(object):
|
||||
|
||||
def _draw_path(self):
|
||||
if self.draw_path and self.last_pos:
|
||||
pygame.draw.line(self.env.path_overlay, self.draw_path_col,
|
||||
col = self.draw_path_col
|
||||
if self.draw_path_harm:
|
||||
if self.env.gotHarm:
|
||||
col = self.draw_path_harm_col
|
||||
pygame.draw.line(self.env.path_overlay, col,
|
||||
(self.last_pos[0]*self.env.width, self.last_pos[1]*self.env.height), (self.pos[0]*self.env.width, self.pos[1]*self.env.height), self.draw_path_width)
|
||||
pygame.draw.circle(self.env.path_overlay, col,
|
||||
(self.pos[0]*self.env.width, self.pos[1]*self.env.height), max(0, self.draw_path_width/2-3))
|
||||
self.last_pos = self.pos[0], self.pos[1]
|
||||
|
||||
def on_collision(self, other, depth):
|
||||
@@ -83,9 +100,16 @@ class Entity(object):
|
||||
return
|
||||
force_dir = force_dir[0]/force_dir_len, force_dir[1]/force_dir_len
|
||||
if not self.env.torus_topology:
|
||||
if self.env.agent.pos[0] > 0.99 or self.env.agent.pos[0] < 0.01:
|
||||
if self == self.env.agent:
|
||||
agent = self
|
||||
elif other == self.env.agent:
|
||||
agent = other
|
||||
else:
|
||||
agent = None
|
||||
if agent:
|
||||
if agent.pos[0] > 0.99 or agent.pos[0] < 0.01:
|
||||
force_dir = force_dir[0], force_dir[1] * 2
|
||||
if self.env.agent.pos[1] > 0.99 or self.env.agent.pos[1] < 0.01:
|
||||
if agent.pos[1] > 0.99 or agent.pos[1] < 0.01:
|
||||
force_dir = force_dir[0] * 2, force_dir[1]
|
||||
depth *= 1.0*self.movable/(self.movable + other.movable)/2
|
||||
depth /= other.elasticity
|
||||
@@ -130,6 +154,24 @@ class Entity(object):
|
||||
def kill(self):
|
||||
self.env.kill_entity(self)
|
||||
|
||||
def getQuasiRadius(self):
|
||||
raise Exception()
|
||||
|
||||
def getTop(self):
|
||||
raise Exception()
|
||||
|
||||
def getBottom(self):
|
||||
raise Exception()
|
||||
|
||||
def getLeft(self):
|
||||
raise Exception()
|
||||
|
||||
def getRight(self):
|
||||
raise Exception()
|
||||
|
||||
def getCenter(self):
|
||||
raise Exception()
|
||||
|
||||
|
||||
class CircularEntity(Entity):
|
||||
def __init__(self, env):
|
||||
@@ -199,6 +241,24 @@ class CircularEntity(Entity):
|
||||
raise Exception(
|
||||
'[!] Shape "circle" does not know how to collide with shape "'+str(other.shape)+'"')
|
||||
|
||||
def getQuasiRadius(self):
|
||||
return self.radius
|
||||
|
||||
def getTop(self):
|
||||
return self.pos[1]*self.env.height - self.radius
|
||||
|
||||
def getBottom(self):
|
||||
return self.pos[1]*self.env.height + self.radius
|
||||
|
||||
def getLeft(self):
|
||||
return self.pos[0]*self.env.width - self.radius
|
||||
|
||||
def getRight(self):
|
||||
return self.pos[0]*self.env.width + self.radius
|
||||
|
||||
def getCenter(self):
|
||||
return self.pos[0]*self.env.width, self.pos[1]*self.env.height
|
||||
|
||||
|
||||
class RectangularEntity(Entity):
|
||||
def __init__(self, env):
|
||||
@@ -219,6 +279,58 @@ class RectangularEntity(Entity):
|
||||
raise Exception(
|
||||
'[!] Collisions in this direction not implemented for shape "rectangle"')
|
||||
|
||||
def physics_step(self):
|
||||
x, y = self.pos
|
||||
vx, vy = self.speed
|
||||
ax, ay = self.acc
|
||||
vx, vy = vx+ax*self.env.acc_fac, vy+ay*self.env.acc_fac
|
||||
speeds = math.sqrt(vx**2 + vy**2)
|
||||
if speeds < self.min_speed:
|
||||
vx, vy = vx/speeds*self.min_speed, vy/speeds*self.min_speed
|
||||
if speeds > self.max_speed:
|
||||
vx, vy = vx/speeds*self.max_speed, vy/speeds*self.max_speed
|
||||
x, y = x+vx*self.env.speed_fac, y+vy*self.env.speed_fac
|
||||
if not self.env.torus_topology and self.void_collidable:
|
||||
if x+(self.width/self.env.width) > 1 or x < 0:
|
||||
if x < 0:
|
||||
x, y, vx, vy = self.calc_void_collision(
|
||||
x < 0, x, y, vx, vy)
|
||||
else:
|
||||
x, y, vx, vy = self.calc_void_collision(
|
||||
x < 0, x+(self.width/self.env.width), y, vx, vy)
|
||||
x -= (self.width/self.env.width)
|
||||
if y+(self.height/self.env.height) > 1 or y < 0:
|
||||
if y < 0:
|
||||
x, y, vx, vy = self.calc_void_collision(
|
||||
2 + (x < 0), x, y, vx, vy)
|
||||
else:
|
||||
x, y, vx, vy = self.calc_void_collision(
|
||||
2 + (x < 0), x, y+(self.height/self.env.height), vx, vy)
|
||||
y -= (self.height/self.env.height)
|
||||
else:
|
||||
x = x % 1
|
||||
y = y % 1
|
||||
self.speed = vx/(1+self.drag), vy/(1+self.drag)
|
||||
self.pos = x, y
|
||||
|
||||
def getQuasiRadius(self):
|
||||
return self.width + self.height
|
||||
|
||||
def getTop(self):
|
||||
return self.pos[1]*self.env.height
|
||||
|
||||
def getBottom(self):
|
||||
return self.pos[1]*self.env.height + self.height
|
||||
|
||||
def getLeft(self):
|
||||
return self.pos[0]*self.env.width
|
||||
|
||||
def getRight(self):
|
||||
return self.pos[0]*self.env.width*self.env.height + self.width
|
||||
|
||||
def getCenter(self):
|
||||
return self.pos[0]*self.env.width+self.width/2, self.pos[1]*self.env.height+self.height/2
|
||||
|
||||
|
||||
class Agent(CircularEntity):
|
||||
def __init__(self, env):
|
||||
@@ -229,6 +341,31 @@ class Agent(CircularEntity):
|
||||
self.controll_type = self.env.controll_type
|
||||
self.solid = True
|
||||
self.movable = True
|
||||
self.void_collidable = True
|
||||
|
||||
def controll_step(self):
|
||||
self._read_input()
|
||||
self.env.check_collisions_for(self)
|
||||
|
||||
def _read_input(self):
|
||||
if self.controll_type == 'SPEED':
|
||||
self.speed = self.env.inp[0] - 0.5, self.env.inp[1] - 0.5
|
||||
elif self.controll_type == 'ACC':
|
||||
self.acc = self.env.inp[0] - 0.5, self.env.inp[1] - 0.5
|
||||
else:
|
||||
raise Exception('Unsupported controll_type')
|
||||
|
||||
|
||||
# Does not work! Don't use!
|
||||
class PongAgent(RectangularEntity):
|
||||
def __init__(self, env):
|
||||
super(PongAgent, self).__init__(env)
|
||||
self.pos = (0.5, 0.5)
|
||||
self.col = (0, 0, 255)
|
||||
self.drag = self.env.agent_drag
|
||||
self.controll_type = self.env.controll_type
|
||||
self.solid = True
|
||||
self.movable = True
|
||||
|
||||
def controll_step(self):
|
||||
self._read_input()
|
||||
@@ -236,9 +373,9 @@ class Agent(CircularEntity):
|
||||
|
||||
def _read_input(self):
|
||||
if self.controll_type == 'SPEED':
|
||||
self.speed = self.env.inp[0] - 0.5, self.env.inp[1] - 0.5
|
||||
self.speed = 0, self.env.inp[1] - 0.5
|
||||
elif self.controll_type == 'ACC':
|
||||
self.acc = self.env.inp[0] - 0.5, self.env.inp[1] - 0.5
|
||||
self.acc = 0, self.env.inp[1] - 0.5
|
||||
else:
|
||||
raise Exception('Unsupported controll_type')
|
||||
|
||||
@@ -340,6 +477,33 @@ class Collectable(CircularEntity):
|
||||
self.env.check_collisions_for(self)
|
||||
|
||||
|
||||
class RectCollectable(RectangularEntity):
|
||||
def __init__(self, env):
|
||||
super(RectCollectable, self).__init__(env)
|
||||
self.avaible = True
|
||||
self.enforce_not_on_barrier = False
|
||||
self.reward = 10
|
||||
self.collectors = []
|
||||
|
||||
def on_collision(self, other, depth):
|
||||
super().on_collision(other, depth)
|
||||
if isinstance(other, Barrier):
|
||||
self.on_barrier_collision()
|
||||
else:
|
||||
for Col in self.collectors:
|
||||
if isinstance(other, Col):
|
||||
other.on_collect(self)
|
||||
self.on_collected()
|
||||
|
||||
def on_collected(self):
|
||||
self.env.new_reward += self.reward
|
||||
|
||||
def on_barrier_collision(self):
|
||||
if self.enforce_not_on_barrier:
|
||||
self.pos = (self.env.random(), self.env.random())
|
||||
self.env.check_collisions_for(self)
|
||||
|
||||
|
||||
class Reward(Collectable):
|
||||
def __init__(self, env):
|
||||
super(Reward, self).__init__(env)
|
||||
@@ -470,6 +634,14 @@ class Goal(Collectable):
|
||||
self.collectors = [Ball]
|
||||
|
||||
|
||||
class RectGoal(RectCollectable):
|
||||
def __init__(self, env):
|
||||
super(RectGoal, self).__init__(env)
|
||||
self.col = (0, 200, 0)
|
||||
self.reward = 500
|
||||
self.collectors = [Ball]
|
||||
|
||||
|
||||
class TeleportingGoal(Goal):
|
||||
def __init__(self, env):
|
||||
super(TeleportingGoal, self).__init__(env)
|
||||
|
||||
+197
-104
@@ -6,46 +6,17 @@ import pygame
|
||||
import random as random_dont_use
|
||||
from os import urandom
|
||||
import math
|
||||
from columbus import entities, observables
|
||||
import torch as th
|
||||
|
||||
|
||||
def parseObs(obsConf):
|
||||
if type(obsConf) == list:
|
||||
obs = []
|
||||
for i, c in enumerate(obsConf):
|
||||
obs.append(parseObs(c))
|
||||
if len(obs) == 1:
|
||||
return obs[0]
|
||||
else:
|
||||
return observables.CompositionalObservable(obs)
|
||||
|
||||
if obsConf['type'] == 'State':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.StateObservable(**conf)
|
||||
elif obsConf['type'] == 'Compass':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.CompassObservable(**conf)
|
||||
elif obsConf['type'] == 'RayCast':
|
||||
chans = []
|
||||
for chan in obsConf.get('chans', []):
|
||||
chans.append(getattr(entities, chan))
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type', 'chans']}
|
||||
return observables.RayObservable(chans=chans, **conf)
|
||||
elif obsConf['type'] == 'CNN':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.CnnObservable(**conf)
|
||||
elif obsConf['type'] == 'Dummy':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.Observable(**conf)
|
||||
else:
|
||||
raise Exception('Unknown Observable selected')
|
||||
from columbus import entities, observables
|
||||
from columbus.utils import soft_int, parseObs
|
||||
|
||||
|
||||
class ColumbusEnv(gym.Env):
|
||||
metadata = {'render.modes': ['human']}
|
||||
metadata = {'render.modes': ['human'], 'render_modes': [
|
||||
'human', 'non-human'], 'render_fps': 60}
|
||||
|
||||
def __init__(self, observable=observables.Observable(), fps=60, env_seed=3.1, master_seed=None, start_pos=(0.5, 0.5), start_score=0, speed_fac=0.01, acc_fac=0.04, die_on_zero=False, return_on_score=-1, reward_mult=1, agent_drag=0, controll_type='SPEED', aux_reward_max=1, aux_penalty_max=0, aux_reward_discretize=0, void_is_type_barrier=True, void_damage=1, torus_topology=False, default_collision_elasticity=1, terminate_on_reward=False, agent_draw_path=False, clear_path_on_reset=True, max_steps=-1, value_color_mapper=None):
|
||||
def __init__(self, observable=observables.Observable(), fps=60, env_seed=3.1, master_seed=None, start_pos=(0.5, 0.5), start_score=0, speed_fac=0.01, acc_fac=0.04, die_on_zero=False, return_on_score=-1, reward_mult=1, agent_drag=0, controll_type='SPEED', aux_reward_max=1, aux_penalty_max=0, aux_reward_discretize=0, void_is_type_barrier=True, void_damage=1, torus_topology=False, default_collision_elasticity=1, terminate_on_reward=False, agent_draw_path=False, clear_path_on_reset=True, max_steps=-1, value_color_mapper='tanh', width=720, height=720, agent_attrs={}, agent_cls=entities.Agent, exception_for_unsupported_collision=True, path_decay=0.1):
|
||||
super(ColumbusEnv, self).__init__()
|
||||
self.action_space = spaces.Box(
|
||||
low=-1, high=1, shape=(2,), dtype=np.float32)
|
||||
@@ -53,14 +24,14 @@ class ColumbusEnv(gym.Env):
|
||||
observable = parseObs(observable)
|
||||
observable._set_env(self)
|
||||
self.observable = observable
|
||||
self.title = 'Untitled'
|
||||
self.title = 'Columbus Env'
|
||||
self.fps = fps
|
||||
self.env_seed = env_seed
|
||||
self.joystick_offset = (10, 10)
|
||||
self.surface = None
|
||||
self.screen = None
|
||||
self.width = 720
|
||||
self.height = 720
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.visible = False
|
||||
self.start_pos = start_pos
|
||||
self.speed_fac = speed_fac/fps*60
|
||||
@@ -91,6 +62,19 @@ class ColumbusEnv(gym.Env):
|
||||
self.terminate_on_reward = terminate_on_reward
|
||||
self.agent_draw_path = agent_draw_path
|
||||
self.clear_path_on_reset = clear_path_on_reset
|
||||
self.path_decay = path_decay
|
||||
|
||||
if isinstance(agent_cls, str):
|
||||
agent_cls = getattr(entities, agent_cls)
|
||||
self.Agent_cls = agent_cls
|
||||
self.agent_attrs = agent_attrs
|
||||
|
||||
self.exception_for_unsupported_collision = exception_for_unsupported_collision
|
||||
|
||||
if value_color_mapper == 'atan':
|
||||
def value_color_mapper(x): return th.atan(x*2)/0.786/2
|
||||
elif value_color_mapper == 'tanh':
|
||||
def value_color_mapper(x): return th.tanh(x*2)/0.762/2
|
||||
self.value_color_mapper = value_color_mapper
|
||||
|
||||
self.max_steps = max_steps
|
||||
@@ -111,6 +95,8 @@ class ColumbusEnv(gym.Env):
|
||||
|
||||
self._init = False
|
||||
|
||||
self.is_columbus_env = True
|
||||
|
||||
@property
|
||||
def observation_space(self):
|
||||
if not self._init:
|
||||
@@ -235,11 +221,12 @@ class ColumbusEnv(gym.Env):
|
||||
self._step_entities()
|
||||
observation = self.observable.get_observation()
|
||||
gotRew = self.new_reward > 0 or self.new_abs_reward > 0
|
||||
self.gotHarm = self.new_reward < 0 or self.new_abs_reward < 0
|
||||
reward, self.new_reward, self.new_abs_reward = self.new_reward / \
|
||||
self.fps + self.new_abs_reward, 0, 0
|
||||
if not self.torus_topology:
|
||||
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:
|
||||
if self.agent.getTop() < 1 or self.agent.getBottom() > self.height-1 \
|
||||
or self.agent.getLeft() < 1 or self.agent.getRight() > self.width-1:
|
||||
reward -= self.void_damage/self.fps
|
||||
self.score += reward # aux_reward does not count towards the score
|
||||
if self.aux_reward_max or self.aux_penalty_max:
|
||||
@@ -273,8 +260,10 @@ class ColumbusEnv(gym.Env):
|
||||
elif shapes == ['circle', 'rect']:
|
||||
return sum([abs(d) for d in e1._get_crash_force_dir(e2)])
|
||||
else:
|
||||
if self.exception_for_unsupported_collision:
|
||||
raise Exception(
|
||||
'Checking for collision between unsupported shapes: '+str(shapes))
|
||||
return 0.0
|
||||
|
||||
def kill_entity(self, target):
|
||||
newEntities = []
|
||||
@@ -290,6 +279,12 @@ class ColumbusEnv(gym.Env):
|
||||
self.agent.pos = self.start_pos
|
||||
# Expand this function
|
||||
|
||||
def _spawnAgent(self):
|
||||
self.agent = self.Agent_cls(self)
|
||||
self.agent.draw_path = self.agent_draw_path
|
||||
for k, v in self.agent_attrs.items():
|
||||
setattr(self.agent, k, v)
|
||||
|
||||
def reset(self, force_reset_path=False):
|
||||
pygame.init()
|
||||
self._init = True
|
||||
@@ -302,11 +297,11 @@ class ColumbusEnv(gym.Env):
|
||||
# will get rescaled acording to fps (=reward per second)
|
||||
self.new_reward = 0
|
||||
self.new_abs_reward = 0 # will not get rescaled. should be used for one-time rewards
|
||||
self.gotHarm = False
|
||||
self.score = self.start_score
|
||||
self.entities = []
|
||||
self.timers = []
|
||||
self.agent = entities.Agent(self)
|
||||
self.agent.draw_path = self.agent_draw_path
|
||||
self._spawnAgent()
|
||||
self.setup()
|
||||
self.entities.append(self.agent) # add it last, will be drawn on top
|
||||
self.observable.reset()
|
||||
@@ -344,10 +339,9 @@ class ColumbusEnv(gym.Env):
|
||||
|
||||
V = value_func(th.Tensor(np.array(obs)))
|
||||
V /= max(V.max(), -1*V.min())*2
|
||||
V += 0.5
|
||||
|
||||
if color_mapper != None:
|
||||
V = color_mapper(V)
|
||||
V += 0.5
|
||||
|
||||
c = 0
|
||||
for i in range(resolution):
|
||||
@@ -381,13 +375,13 @@ class ColumbusEnv(gym.Env):
|
||||
pygame.draw.circle(self.screen, smolcol, (20+int(60*x) +
|
||||
self.joystick_offset[0], 20+int(60*y)+self.joystick_offset[1]), 20, width=0)
|
||||
|
||||
def _draw_confidence_ellipse(self, chol, forceDraw=False, seconds=0.5):
|
||||
def _draw_confidence_ellipse(self, chol, forceDraw=False, seconds=0.1):
|
||||
# The 'seconds'-parameter only really makes sense, when using control_type='SPEED',
|
||||
# you can still use it to scale the cov-ellipse when using control_type='ACC',
|
||||
# but it's relation to 'seconds' is no longer there...
|
||||
if self.draw_confidence_ellipse and (self.visible or forceDraw):
|
||||
col = (255, 255, 255)
|
||||
f = seconds*self.speed_fac*self.fps*max(self.width, self.height)
|
||||
f = seconds*self.speed_fac*self.fps*max(self.height, self.width)
|
||||
|
||||
while len(chol.shape) > 2:
|
||||
chol = chol[0]
|
||||
@@ -399,9 +393,8 @@ class ColumbusEnv(gym.Env):
|
||||
|
||||
L, V = th.linalg.eig(cov)
|
||||
L, V = L.real, V.real
|
||||
# 5.911 is the magic-number to get a 95%-confidence interval
|
||||
l1, l2 = int(abs(math.sqrt(L[0].item()*5.911)*f)) + \
|
||||
1, int(abs(math.sqrt(L[1].item()*5.911)*f))+1
|
||||
l1, l2 = int(abs(math.sqrt(L[0].item())*f)) + \
|
||||
1, int(abs(math.sqrt(L[1].item())*f))+1
|
||||
|
||||
if l1 >= l2:
|
||||
w, h = l1, l2
|
||||
@@ -424,6 +417,14 @@ class ColumbusEnv(gym.Env):
|
||||
self.screen.blit(rotated_surf, rotated_surf.get_rect(
|
||||
center=rect.center))
|
||||
|
||||
def _draw_paths(self):
|
||||
if self.path_decay != 0.0:
|
||||
s = pygame.Surface((self.width, self.height))
|
||||
s.set_alpha(soft_int(255*self.path_decay/self.fps))
|
||||
s.fill((0, 0, 0))
|
||||
self.path_overlay.blit(s, (0, 0))
|
||||
self.surface.blit(self.path_overlay, (0, 0))
|
||||
|
||||
def _handle_user_input(self):
|
||||
for event in pygame.event.get():
|
||||
pass
|
||||
@@ -468,7 +469,7 @@ class ColumbusEnv(gym.Env):
|
||||
if value_func != None:
|
||||
self._draw_values(value_func, values_static,
|
||||
color_mapper=self.value_color_mapper)
|
||||
self.surface.blit(self.path_overlay, (0, 0))
|
||||
self._draw_paths()
|
||||
if self.draw_entities:
|
||||
self._draw_entities()
|
||||
else:
|
||||
@@ -491,6 +492,123 @@ class ColumbusEnv(gym.Env):
|
||||
pygame.quit()
|
||||
|
||||
|
||||
class ColumbusConfigDefined(ColumbusEnv):
|
||||
# Allows defining Columbus Environments using dicts.
|
||||
# Intended to be used in combination with cw2 configuration.
|
||||
# Look into humanPlayer to see how this is supposed to be interfaced with.
|
||||
|
||||
def __init__(self, observable={}, env_seed=None, entities=[], fps=30, **kw):
|
||||
super().__init__(
|
||||
observable=observable, fps=fps, env_seed=env_seed, **kw)
|
||||
self.entities_definitions = entities
|
||||
self.start_pos = self.conv_unit(self.start_pos[0], target='em', axis='x'), self.conv_unit(
|
||||
self.start_pos[1], target='em', axis='y')
|
||||
|
||||
def is_unit(self, s):
|
||||
if type(s) in [int, float]:
|
||||
return True
|
||||
if s.replace('.', '', 1).replace('-', '0', 1).isdigit():
|
||||
return True
|
||||
num, unit = s[:-2], s[-2:]
|
||||
if unit in ['px', 'em', 'rx', 'ry', 'ct', 'au']:
|
||||
if num.replace('.', '', 1).replace('-', '0', 1).isdigit():
|
||||
return True
|
||||
return False
|
||||
|
||||
def conv_unit(self, s, target='px', axis='x'):
|
||||
assert self.is_unit(s)
|
||||
if type(s) in [int, float]:
|
||||
return s
|
||||
if s.replace('.', '', 1).isdigit():
|
||||
if target == 'px':
|
||||
return int(s)
|
||||
return float(s)
|
||||
num, unit = s[:-2], s[-2:]
|
||||
num = float(num)
|
||||
if unit == 'rx':
|
||||
unit = 'px'
|
||||
axis = 'x'
|
||||
elif unit == 'ry':
|
||||
unit = 'px'
|
||||
axis = 'y'
|
||||
if unit == 'em':
|
||||
em = num
|
||||
elif unit == 'px':
|
||||
em = num / ({'x': self.width, 'y': self.height}[axis])
|
||||
elif unit == 'au':
|
||||
em = num * 36 / ({'x': self.width, 'y': self.height}[axis])
|
||||
elif unit == 'ct':
|
||||
em = num / 100
|
||||
else:
|
||||
raise Exception('Conversion not implemented')
|
||||
|
||||
if target == 'em':
|
||||
return em
|
||||
elif target == 'px':
|
||||
return int(em * ({'x': self.width, 'y': self.height}[axis]))
|
||||
|
||||
def setup(self):
|
||||
self.agent.pos = self.start_pos
|
||||
for i, e in enumerate(self.entities_definitions):
|
||||
Entity = getattr(entities, e['type'])
|
||||
for i in range(e.get('num', 1) + int(self.random()*(0.99+e.get('num_rand', 0)))):
|
||||
entity = Entity(self)
|
||||
conf = {k: v for k, v in e.items() if str(
|
||||
k) not in ['num', 'num_rand', 'type']}
|
||||
|
||||
for k, v_raw in conf.items():
|
||||
if k == 'pos':
|
||||
v = self.conv_unit(v_raw[0], target='em', axis='x'), self.conv_unit(
|
||||
v_raw[1], target='em', axis='y')
|
||||
elif k in ['width', 'height', 'radius']:
|
||||
v = self.conv_unit(
|
||||
v_raw, target='px', axis='y' if k == 'height' else 'x')
|
||||
else:
|
||||
v = v_raw
|
||||
if k.endswith('_rand'):
|
||||
v = self.conv_unit(
|
||||
v_raw, target='px', axis='y' if k == 'height_rand' else 'x')
|
||||
if isinstance(v, int):
|
||||
n = k.replace('_rand', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
inc = int((v+0.99)*self.random())
|
||||
setattr(entity, n, cur + inc)
|
||||
elif isinstance(v, float):
|
||||
n = k.replace('_rand', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
inc = v*self.random()
|
||||
setattr(entity, n, cur + inc)
|
||||
elif isinstance(v, list):
|
||||
for vi, ve in enumerate(v):
|
||||
if isinstance(v, int):
|
||||
n = k.replace('_rand', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
cur[vi] = int((v+0.99)*self.random())
|
||||
setattr(entity, n, cur)
|
||||
elif isinstance(v, float):
|
||||
n = k.replace('_rand', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
cur[vi] = v*self.random()
|
||||
setattr(entity, n, cur)
|
||||
elif k.endswith('_randf'):
|
||||
n = k.replace('_randf', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
inc = v*self.random()
|
||||
setattr(entity, n, cur + inc)
|
||||
else:
|
||||
setattr(entity, k, v)
|
||||
|
||||
self.entities.append(entity)
|
||||
|
||||
###
|
||||
# Custom Env Definitions
|
||||
|
||||
|
||||
class ColumbusTest3_1(ColumbusEnv):
|
||||
def __init__(self, observable=observables.CnnObservable(out_width=48, out_height=48), fps=30, aux_reward_max=1, **kw):
|
||||
super(ColumbusTest3_1, self).__init__(
|
||||
@@ -830,40 +948,6 @@ class ColumbusFootball(ColumbusEnv):
|
||||
self.entities.append(entities.FlyingFootballPlayer(self, ball))
|
||||
|
||||
|
||||
class ColumbusConfigDefined(ColumbusEnv):
|
||||
def __init__(self, observable={}, env_seed=None, entities=[], fps=30, **kw):
|
||||
super().__init__(
|
||||
observable=observable, fps=fps, env_seed=env_seed, **kw)
|
||||
self.entities_definitions = entities
|
||||
|
||||
def setup(self):
|
||||
self.agent.pos = self.start_pos
|
||||
for i, e in enumerate(self.entities_definitions):
|
||||
Entity = getattr(entities, e['type'])
|
||||
for i in range(e.get('num', 1) + int(self.random()*(0.99+e.get('num_rand', 0)))):
|
||||
entity = Entity(self)
|
||||
conf = {k: v for k, v in e.items() if str(
|
||||
k) not in ['num', 'num_rand', 'type']}
|
||||
|
||||
for k, v in conf.items():
|
||||
if k.endswith('_rand'):
|
||||
n = k.replace('_rand', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
inc = int((v+0.99)*self.random())
|
||||
setattr(entity, n, cur + inc)
|
||||
elif k.endswith('_randf'):
|
||||
n = k.replace('_randf', '')
|
||||
cur = getattr(
|
||||
entity, n)
|
||||
inc = v*self.random()
|
||||
setattr(entity, n, cur + inc)
|
||||
else:
|
||||
setattr(entity, k, v)
|
||||
|
||||
self.entities.append(entity)
|
||||
|
||||
|
||||
class ColumbusBlub(ColumbusEnv):
|
||||
def __init__(self, observable=observables.CompositionalObservable([observables.StateObservable(), observables.RayObservable(num_rays=6, chans=[entities.Enemy])]), env_seed=None, entities=[], fps=30, **kw):
|
||||
super().__init__(
|
||||
@@ -877,7 +961,22 @@ class ColumbusBlub(ColumbusEnv):
|
||||
enemy.width, enemy.height = 200, 75
|
||||
self.entities.append(enemy)
|
||||
|
||||
|
||||
###
|
||||
# Registering Envs fro Gym
|
||||
register( # Legacy
|
||||
id='ColumbusConfigDefined-v0',
|
||||
entry_point=ColumbusConfigDefined,
|
||||
max_episode_steps=30*60*2, # 2 min at default (30) fps
|
||||
)
|
||||
|
||||
register(
|
||||
id='Columbus-v1',
|
||||
entry_point=ColumbusConfigDefined
|
||||
)
|
||||
|
||||
###
|
||||
|
||||
# register(
|
||||
# id='ColumbusBlub-v0',
|
||||
# entry_point=ColumbusBlub,
|
||||
@@ -885,17 +984,17 @@ class ColumbusBlub(ColumbusEnv):
|
||||
# )
|
||||
|
||||
|
||||
register(
|
||||
id='ColumbusTestCnn-v0',
|
||||
entry_point=ColumbusTest3_1,
|
||||
max_episode_steps=30*60*2,
|
||||
)
|
||||
# register(
|
||||
# id='ColumbusTestCnn-v0',
|
||||
# entry_point=ColumbusTest3_1,
|
||||
# max_episode_steps=30*60*2,
|
||||
# )
|
||||
|
||||
register(
|
||||
id='ColumbusTestRay-v0',
|
||||
entry_point=ColumbusTestRay,
|
||||
max_episode_steps=30*60*2,
|
||||
)
|
||||
# register(
|
||||
# id='ColumbusTestRay-v0',
|
||||
# entry_point=ColumbusTestRay,
|
||||
# max_episode_steps=30*60*2,
|
||||
# )
|
||||
|
||||
# register(
|
||||
# id='ColumbusRayDrone-v0',
|
||||
@@ -933,11 +1032,11 @@ register(
|
||||
# max_episode_steps=30*60*2,
|
||||
# )
|
||||
|
||||
register(
|
||||
id='ColumbusStateWithBarriers-v0',
|
||||
entry_point=ColumbusStateWithBarriers,
|
||||
max_episode_steps=30*60*2,
|
||||
)
|
||||
# register(
|
||||
# id='ColumbusStateWithBarriers-v0',
|
||||
# entry_point=ColumbusStateWithBarriers,
|
||||
# max_episode_steps=30*60*2,
|
||||
# )
|
||||
|
||||
# register(
|
||||
# id='ColumbusCompassWithBarriers-v0',
|
||||
@@ -969,12 +1068,6 @@ register(
|
||||
# max_episode_steps=30*60*2,
|
||||
# )
|
||||
|
||||
register(
|
||||
id='ColumbusConfigDefined-v0',
|
||||
entry_point=ColumbusConfigDefined,
|
||||
max_episode_steps=30*60*2,
|
||||
)
|
||||
|
||||
register(
|
||||
id='ColumbusDemoEnvFootball-v0',
|
||||
entry_point=ColumbusDemoEnvFootball,
|
||||
|
||||
@@ -71,7 +71,8 @@ def chooseEnv():
|
||||
|
||||
|
||||
def value_func(obs):
|
||||
return th.rand(obs.shape[0])-0.5
|
||||
return obs[:, 0]
|
||||
# return th.rand(obs.shape[0])-0.5
|
||||
|
||||
|
||||
def playEnv(env):
|
||||
|
||||
+16
-9
@@ -16,7 +16,7 @@ class Observable():
|
||||
def get_observation_space(self):
|
||||
print("[!] Using dummyObservable. Env won't output anything")
|
||||
return spaces.Box(low=0, high=1,
|
||||
shape=(1,), dtype=np.float32)
|
||||
shape=(1,), dtype=np.float64)
|
||||
|
||||
def get_observation(self):
|
||||
return np.array([0])
|
||||
@@ -45,7 +45,7 @@ class CnnObservable(Observable):
|
||||
|
||||
def get_observation_space(self):
|
||||
return spaces.Box(low=0, high=255,
|
||||
shape=(self.out_width, self.out_height, 3), dtype=np.float32)
|
||||
shape=(self.out_width, self.out_height, 3), dtype=np.float64)
|
||||
|
||||
def get_observation(self):
|
||||
if not self.env._rendered:
|
||||
@@ -132,24 +132,31 @@ class RayObservable(Observable):
|
||||
'Can only raycast circular and rectangular entities!')
|
||||
return False
|
||||
|
||||
# Filter out entities, that we sure are out of range
|
||||
# (so we have to do less work for the ray collisions)
|
||||
def _get_possible_entities(self):
|
||||
entities_l = []
|
||||
if entities.Void in self.chans or self.env.void_barrier:
|
||||
entities_l.append(entities.Void(self.env))
|
||||
for entity in self.env.entities:
|
||||
if entity.shape == 'rect':
|
||||
x, y = entity.pos[0]+entity.width/self.env.width / \
|
||||
2, entity.pos[1]+entity.height/self.env.height/2
|
||||
radius = (entity.width/2 + entity.height/2)*1.0
|
||||
elif entity.shape == 'circle':
|
||||
x, y = entity.pos[0], entity.pos[1]
|
||||
radius = entity.radius
|
||||
else:
|
||||
raise Exception(
|
||||
'Can only raycast circular and rectangular entities!')
|
||||
sq_dist = ((self.env.agent.pos[0]-entity.pos[0])*self.env.width) ** 2 \
|
||||
+ ((self.env.agent.pos[1]-entity.pos[1])*self.env.height) ** 2
|
||||
if sq_dist <= (radius + self.env.agent.radius + self.ray_len)**2:
|
||||
sq_dist = ((self.env.agent.pos[0]-x)*self.env.width) ** 2 \
|
||||
+ ((self.env.agent.pos[1]-y)*self.env.height) ** 2
|
||||
if sq_dist <= (radius + self.env.agent.getQuasiRadius() + self.ray_len)**2:
|
||||
entities_l.append(entity) # cannot use yield here!
|
||||
return entities_l
|
||||
|
||||
# Ugly, inefficient ray casting
|
||||
# Oh well, it works...
|
||||
def get_observation(self):
|
||||
entities = self._get_possible_entities()
|
||||
self.rays = np.zeros((self.num_rays+self.include_rand, self.num_chans))
|
||||
@@ -243,8 +250,8 @@ class StateObservable(Observable):
|
||||
self.reset()
|
||||
num = len(self.entities)*2+len(self._timeoutEntities) + \
|
||||
self.speedAgent*2 + self.include_rand
|
||||
return spaces.Box(low=0-1*self.coordsRelativeToAgent, high=1,
|
||||
shape=(num,), dtype=np.float32)
|
||||
return spaces.Box(low=0-1*(self.coordsRelativeToAgent or self.speedAgent), high=1,
|
||||
shape=(num,), dtype=np.float64)
|
||||
|
||||
def get_observation(self):
|
||||
obs = []
|
||||
@@ -324,7 +331,7 @@ class CompassObservable(Observable):
|
||||
self.reset()
|
||||
num = len(self.entities)*2
|
||||
return spaces.Box(low=-1, high=1,
|
||||
shape=(num,), dtype=np.float32)
|
||||
shape=(num,), dtype=np.float64)
|
||||
|
||||
def reset(self):
|
||||
self._entities = None
|
||||
@@ -378,7 +385,7 @@ class CompositionalObservable(Observable):
|
||||
low = np.hstack((low, space.low.reshape((-1))))
|
||||
high = np.hstack((high, space.high.reshape((-1))))
|
||||
return spaces.Box(low=low, high=high,
|
||||
shape=(num,), dtype=np.float32)
|
||||
shape=(num,), dtype=np.float64)
|
||||
|
||||
def get_observation(self):
|
||||
o = [obs.get_observation().reshape((-1))
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
from columbus import entities, observables
|
||||
|
||||
import random as random_dont_use
|
||||
|
||||
|
||||
def parseObs(obsConf):
|
||||
# Parsing Observable Definitions
|
||||
if type(obsConf) == list:
|
||||
obs = []
|
||||
for i, c in enumerate(obsConf):
|
||||
obs.append(parseObs(c))
|
||||
if len(obs) == 1:
|
||||
return obs[0]
|
||||
else:
|
||||
return observables.CompositionalObservable(obs)
|
||||
|
||||
if obsConf['type'] == 'State':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.StateObservable(**conf)
|
||||
elif obsConf['type'] == 'Compass':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.CompassObservable(**conf)
|
||||
elif obsConf['type'] == 'RayCast':
|
||||
chans = []
|
||||
for chan in obsConf.get('chans', []):
|
||||
chans.append(getattr(entities, chan))
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type', 'chans']}
|
||||
return observables.RayObservable(chans=chans, **conf)
|
||||
elif obsConf['type'] == 'CNN':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.CnnObservable(**conf)
|
||||
elif obsConf['type'] == 'Dummy':
|
||||
conf = {k: v for k, v in obsConf.items() if k not in ['type']}
|
||||
return observables.Observable(**conf)
|
||||
else:
|
||||
raise Exception('Unknown Observable selected')
|
||||
|
||||
|
||||
def soft_int(num):
|
||||
i = int(num)
|
||||
r = num - i
|
||||
return i + int(random_dont_use.random() < r)
|
||||
@@ -0,0 +1,78 @@
|
||||
name: "DEFAULT"
|
||||
|
||||
params:
|
||||
task:
|
||||
task: columbus
|
||||
env_name: ColumbusConfigDefined-v0
|
||||
env_args:
|
||||
observable:
|
||||
- type: State
|
||||
coordsAgent: True
|
||||
speedAgent: True
|
||||
coordsRelativeToAgent: False
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: State
|
||||
coordsAgent: False
|
||||
speedAgent: False
|
||||
coordsRelativeToAgent: True
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: Compass
|
||||
- type: RayCast
|
||||
num_rays: 6
|
||||
chans: [Enemy]
|
||||
entities:
|
||||
- type: RectBarrier
|
||||
damage: 1 #1
|
||||
width: 300
|
||||
height: 120 # 360 - 5%(720)
|
||||
pos: [0, 0]
|
||||
- type: RectBarrier
|
||||
damage: 1 #1
|
||||
width: 300
|
||||
height: 1000
|
||||
pos: [0, 0.25]
|
||||
- type: RectBarrier
|
||||
damage: 1 #1
|
||||
width: 250
|
||||
height: 30
|
||||
pos: [0.55, 0.6]
|
||||
- type: RectBarrier
|
||||
damage: 1 #1
|
||||
width: 30
|
||||
height: 120
|
||||
pos: [0.856, 0.475]
|
||||
- type: RectBarrier
|
||||
num: 0
|
||||
damage: 1 #1
|
||||
width: 50
|
||||
width_rand: 100
|
||||
height: 25
|
||||
height_rand: 100
|
||||
- type: OnceReward
|
||||
reward: 100
|
||||
radius: 20
|
||||
pos: [0.9, 0.8]
|
||||
start_pos: [0.1, 0.21]
|
||||
default_collision_elasticity: 0.8
|
||||
start_score: 10
|
||||
speed_fac: 0.01
|
||||
acc_fac: 0.1
|
||||
die_on_zero: False #True
|
||||
agent_drag: 0.1 # 0.05
|
||||
controll_type: ACC # SPEED
|
||||
aux_reward_max: 1
|
||||
aux_penalty_max: 0.01
|
||||
void_damage: 5 #1
|
||||
terminate_on_reward: True
|
||||
agent_draw_path: True
|
||||
clear_path_on_reset: False
|
||||
max_steps: 450 # 1800
|
||||
---
|
||||
@@ -0,0 +1,54 @@
|
||||
name: "DEFAULT"
|
||||
|
||||
params:
|
||||
task:
|
||||
task: columbus
|
||||
num_envs: 8
|
||||
env_args:
|
||||
observable:
|
||||
- type: State
|
||||
coordsAgent: True
|
||||
speedAgent: True
|
||||
coordsRelativeToAgent: False
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: State
|
||||
coordsAgent: False
|
||||
speedAgent: False
|
||||
coordsRelativeToAgent: True
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: Compass
|
||||
- type: RayCast
|
||||
num_rays: 8
|
||||
chans: [Enemy]
|
||||
entities:
|
||||
- type: CircleBarrier
|
||||
num: 8
|
||||
num_rand: 6
|
||||
damage: 20 #20
|
||||
radius: 25
|
||||
radius_rand: 75
|
||||
- type: TeleportingReward
|
||||
num: 1
|
||||
reward: 100 #100
|
||||
radius: 20
|
||||
default_collision_elasticity: 0.8
|
||||
start_score: 50
|
||||
speed_fac: 0.01
|
||||
acc_fac: 0.1
|
||||
die_on_zero: True
|
||||
agent_drag: 0.07 # 0.05
|
||||
controll_type: ACC # SPEED
|
||||
aux_reward_max: 1
|
||||
aux_penalty_max: 0.1
|
||||
void_damage: 5 #1
|
||||
#master_seed: 3.14
|
||||
max_steps: 900 # 30 sec
|
||||
---
|
||||
@@ -0,0 +1,67 @@
|
||||
name: "DEFAULT"
|
||||
|
||||
params:
|
||||
task:
|
||||
task: columbus
|
||||
env_name: ColumbusConfigDefined-v0
|
||||
env_args:
|
||||
observable:
|
||||
- type: State
|
||||
coordsAgent: True
|
||||
speedAgent: True
|
||||
coordsRelativeToAgent: False
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: State
|
||||
coordsAgent: False
|
||||
speedAgent: False
|
||||
coordsRelativeToAgent: True
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: RayCast
|
||||
num_rays: 6
|
||||
chans: [Enemy]
|
||||
entities:
|
||||
- type: RectBarrier
|
||||
damage: 10 #1
|
||||
width: 25
|
||||
height: 120 # 360 - 5%(720)
|
||||
pos: [0.45, 0]
|
||||
- type: RectBarrier
|
||||
damage: 10 #1
|
||||
width: 25
|
||||
height: 1000
|
||||
pos: [0.45, 0.25]
|
||||
- type: RectBarrier
|
||||
damage: 10 #1
|
||||
width: 25
|
||||
height: 520 # 360 - 5%(720)
|
||||
pos: [0.55, 0]
|
||||
- type: RectBarrier
|
||||
damage: 10 #1
|
||||
width: 25
|
||||
height: 200
|
||||
pos: [0.55, 0.80]
|
||||
- type: LoopReward
|
||||
num: 1
|
||||
reward: 100 #25
|
||||
radius: 20
|
||||
loop: [[0.125, 0.5, 0.1, 0.5], [0.875, 0.5, 0.1, 0.5]]
|
||||
default_collision_elasticity: 0.8
|
||||
start_score: 10
|
||||
speed_fac: 0.01
|
||||
acc_fac: 0.1
|
||||
die_on_zero: False #True
|
||||
agent_drag: 0.1 # 0.05
|
||||
controll_type: ACC # SPEED
|
||||
aux_reward_max: 1
|
||||
aux_penalty_max: 0.01
|
||||
void_damage: 5 #1
|
||||
agent_draw_path: True
|
||||
---
|
||||
@@ -0,0 +1,92 @@
|
||||
name: "DEFAULT"
|
||||
|
||||
# Supported Units:
|
||||
# px: Pixels
|
||||
# em: 1em = Full Width / Height
|
||||
# ct: 100ct = Full Width / Height
|
||||
# rx: pixels relative to width
|
||||
# ry: pixels relative to height
|
||||
# au: 1au = 36px (https://knowyourmeme.com/memes/absolute-unit)
|
||||
#
|
||||
# When no unit is given, we use the folowing defaults
|
||||
# (compatible with legacy behavior)
|
||||
# pos: em
|
||||
# all other: px
|
||||
#
|
||||
# ct is the recommendet unit.
|
||||
# If you need a unit, that is not responsive in regards to width/height, use au / px.
|
||||
|
||||
params:
|
||||
task:
|
||||
task: columbus
|
||||
env_name: ColumbusConfigDefined-v0
|
||||
env_args:
|
||||
observable:
|
||||
- type: State
|
||||
coordsAgent: True
|
||||
speedAgent: True
|
||||
coordsRelativeToAgent: False
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: State
|
||||
coordsAgent: False
|
||||
speedAgent: False
|
||||
coordsRelativeToAgent: True
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: Compass
|
||||
- type: RayCast
|
||||
num_rays: 6
|
||||
chans: [Enemy]
|
||||
entities:
|
||||
- type: RectBarrier
|
||||
num: 1
|
||||
width: 50ct
|
||||
height: 50ct
|
||||
pos: [0ct, 0ct]
|
||||
- type: RectBarrier
|
||||
num: 1
|
||||
width: 50ct
|
||||
height: 50ct
|
||||
pos: [50ct, 50ct]
|
||||
- type: RectBarrier
|
||||
num: 1
|
||||
width: 25rx
|
||||
height: 25ry
|
||||
pos: [0.75em, 30px]
|
||||
- type: RectBarrier
|
||||
num: 1
|
||||
width: 25ry
|
||||
height: 25rx
|
||||
pos: [0.75em, 60px]
|
||||
- type: RectBarrier
|
||||
num: 1
|
||||
width: 20 # defaults to rx (px scaled from x-axis)
|
||||
height: 10 # defaults to ry (px scaled from y-axis)
|
||||
pos: [0.75em, 90px]
|
||||
- type: OnceReward
|
||||
reward: 100
|
||||
radius: 1au
|
||||
pos: [0.3, 0.8] # defaults to em
|
||||
start_pos: [90ct, 20ct]
|
||||
default_collision_elasticity: 0.8
|
||||
start_score: 10
|
||||
speed_fac: 0.01
|
||||
acc_fac: 0.1
|
||||
die_on_zero: False #True
|
||||
agent_drag: 0.1 # 0.05
|
||||
controll_type: ACC # SPEED
|
||||
aux_reward_max: 1
|
||||
aux_penalty_max: 0.01
|
||||
void_damage: 5 #1
|
||||
terminate_on_reward: True
|
||||
agent_draw_path: True
|
||||
clear_path_on_reset: False
|
||||
max_steps: 450 # 1800
|
||||
---
|
||||
@@ -0,0 +1,108 @@
|
||||
name: "DEFAULT"
|
||||
|
||||
params:
|
||||
task:
|
||||
task: columbus
|
||||
env_name: Columbus-v1
|
||||
env_args:
|
||||
observable:
|
||||
- type: State
|
||||
coordsAgent: True
|
||||
speedAgent: True
|
||||
coordsRelativeToAgent: False
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: State
|
||||
coordsAgent: False
|
||||
speedAgent: False
|
||||
coordsRelativeToAgent: True
|
||||
coordsRewards: True
|
||||
coordsEnemys: False
|
||||
enemysNoBarriers: True
|
||||
rewardsTimeouts: False
|
||||
include_rand: True
|
||||
- type: Compass
|
||||
- type: RayCast
|
||||
num_rays: 6
|
||||
chans: [Enemy]
|
||||
entities:
|
||||
- type: Ball
|
||||
radius: 16px
|
||||
pos: [0.8, 0.5]
|
||||
speed: [-0.2, -0.1]
|
||||
speed_rand: [0, 0.2]
|
||||
solid: True
|
||||
collision_elasticity: 3
|
||||
elasticity: 1
|
||||
movable: 1
|
||||
collision_changes_speed: True
|
||||
crash_conservation_of_energy: False
|
||||
min_speed: 0.2
|
||||
max_speed: 0.6
|
||||
draw_path: True
|
||||
draw_path_width: 32
|
||||
draw_path_harm: True
|
||||
drag: 0.00001
|
||||
- type: RectGoal # Good
|
||||
height: 1em
|
||||
width: 10ct
|
||||
pos: [97ct, 0ct]
|
||||
skip_agent_col_check: True
|
||||
col: [0, 255, 0]
|
||||
reward: 30
|
||||
solid: True
|
||||
elasticity: 0.6
|
||||
void_collidable: False
|
||||
- type: Goal # Top
|
||||
radius: 7ct
|
||||
pos: [100ct, 0ct]
|
||||
skip_agent_col_check: True
|
||||
col: [0, 255, 0]
|
||||
reward: 30
|
||||
solid: True
|
||||
elasticity: 0.7
|
||||
void_collidable: False
|
||||
- type: Goal # Bottom
|
||||
radius: 7ct
|
||||
pos: [100ct, 100ct]
|
||||
skip_agent_col_check: True
|
||||
col: [0, 255, 0]
|
||||
reward: 30
|
||||
solid: True
|
||||
elasticity: 0.7
|
||||
void_collidable: False
|
||||
- type: RectGoal # Bad
|
||||
height: 1em
|
||||
width: 3ct
|
||||
pos: [0ct, 0ct]
|
||||
skip_agent_col_check: True
|
||||
col: [255, 0, 0]
|
||||
reward: -45
|
||||
solid: True
|
||||
elasticity: 1000
|
||||
void_collidable: False
|
||||
agent_cls: PongAgent
|
||||
agent_attrs:
|
||||
height: 100
|
||||
width: 30
|
||||
movable: False
|
||||
solid: True
|
||||
elasticity: 0.9
|
||||
exception_for_unsupported_collision: False
|
||||
start_pos: [0.05, 0.5]
|
||||
start_score: 0
|
||||
speed_fac: 0.05
|
||||
acc_fac: 0.1
|
||||
die_on_zero: False #True
|
||||
agent_drag: 0
|
||||
controll_type: SPEED
|
||||
aux_reward_max: 0
|
||||
aux_penalty_max: 0
|
||||
void_damage: 0
|
||||
terminate_on_reward: False
|
||||
agent_draw_path: False
|
||||
clear_path_on_reset: False
|
||||
---
|
||||
Reference in New Issue
Block a user