From 2d054dc271fbec21f2455f1cb3641d1f76af615a Mon Sep 17 00:00:00 2001 From: Armin <armin.co@hs-bochum.de> Date: Fri, 12 Feb 2021 20:35:15 +0100 Subject: [PATCH] Environment works with keras --- carla_environment.py | 111 ++++++++++++++++++++++++++++++++++--------- main.py | 16 ++++--- steering_wheel.py | 56 +++++++++++++++++++++- 3 files changed, 152 insertions(+), 31 deletions(-) diff --git a/carla_environment.py b/carla_environment.py index 2eeb376..d1c660d 100644 --- a/carla_environment.py +++ b/carla_environment.py @@ -8,8 +8,9 @@ import weakref import numpy as np import pygame +import time -from steering_wheel import Controller +from steering_wheel import ACTION_SPACE, Controller # find carla module try: @@ -68,6 +69,7 @@ class Camera: class CollisionSensor: sensor = None + collision = None def __init__(self, world, parent): bp = world.get_blueprint_library().find('sensor.other.collision') @@ -80,6 +82,7 @@ class CollisionSensor: if not self: return print(event.other_actor) + self.collision = event impulse = event.normal_impulse intensity = math.sqrt(impulse.x**2 + impulse.y**2 + impulse.z**2) print(intensity) @@ -94,6 +97,7 @@ class World: blueprint_library = None spawn_points = None actors = [] + was_big_reward = False def __init__(self, world): self.world = world @@ -104,9 +108,17 @@ class World: def reset(self): """ Remove and create new player/vehicle. """ self.destroy() + time.sleep(0.5) self.spawn_player() self.spawn_actors() + def observation(self): + if self.player is not None: + pos = self.player.get_transform() + return [pos.location.x, pos.location.y, pos.rotation.yaw] + else: + return [0,0,0] + def spawn_player(self): """ Add a vehicle to the world. """ while self.player is None: @@ -125,10 +137,11 @@ class World: transforms = [] transforms.append(carla.Transform(carla.Location(x=-19.2, y=54.5, z=0.2), carla.Rotation(pitch=0.0, yaw=-180, roll=0.0))) transforms.append(carla.Transform(carla.Location(x=-14.3, y=54.7, z=0.2), carla.Rotation(pitch=0.0, yaw=-180, roll=0.0))) - transforms.append(carla.Transform(carla.Location(x=-41.3, y=53.7, z=0.2), carla.Rotation(pitch=0.0, yaw=-180, roll=0.0))) - + transforms.append(carla.Transform(carla.Location(x=-37.3, y=53.7, z=0.2), carla.Rotation(pitch=0.0, yaw=-180, roll=0.0))) + mass = carla.VehiclePhysicsControl(mass=900000.0) for transform in transforms: actor = self.world.try_spawn_actor(blueprint, transform) + actor.apply_physics_control(mass) if actor is not None: self.actors.append(actor) @@ -136,48 +149,102 @@ class World: """ Remove vehicle from the world. """ if self.player is not None: self.player.destroy() + self.player = None if self.actors is not None: for actor in self.actors: actor.destroy() + self.actors = [] def step(self, action): """ Apply controls to vehicle. """ - self.player.apply_control(action) - # print(str(self.player.get_transform())) - # print(str(self.player.get_velocity())) - - + controls = Controller.action_to_controls(action) + c = carla.VehicleControl(throttle=controls[0], steer=controls[1], brake=controls[2], reverse=controls[3]) + self.player.apply_control(c) + reward = self.reward() + self.collision_sensor.collision = None + return reward + + def reward(self): + target = carla.Transform(carla.Location(x=-25.534311, y=54.460903, z=0.112781), carla.Rotation(pitch=0.000000, yaw=-175.922913, roll=-6.221135)) + pos = self.player.get_transform() + pos_diff = (target.location.x - pos.location.x)**2 + (target.location.y - pos.location.y)**2 + 1 + rot_diff = (target.rotation.yaw - pos.rotation.yaw)**2 + 1 + r = ((1/pos_diff) - 0.5) + at_final_position = False + if pos_diff < 1.2: + if self.was_big_reward == False: + r += 100 + self.was_big_reward = True + if rot_diff < 5: + at_final_position = True + else: + if self.was_big_reward == True: + self.was_big_reward = False + r -= 50 + + velocity = self.player.get_velocity() + v = (velocity.x)**2 + (velocity.y)**2 + done = False + if at_final_position and v < 0.01: + done = True + if self.collision_sensor.collision is not None: + r -= 100 + done = True + return self.observation(), r, done, None + +class ActionSpace: + n = ACTION_SPACE + +class ObservationSpace: + shape = [3] class CarlaEnvironment: + action_space = ActionSpace + observation_space = ObservationSpace world = None client = None + camera = None + allow_render = False - def __init__(self, host="127.0.0.1", port=2000): + def __init__(self, host="127.0.0.1", port=2000, render=False): + pygame.init() self.client = carla.Client(host, port) self.client.set_timeout(2.0) self.client.load_world('Town07') self.world = World(self.client.get_world()) + if render: + self.allow_render = True + self.camera = Camera(self.world, camera_type='semantic_segmentation') + print(self.observation_space.shape[0]) - def step(self, action): - control = carla.VehicleControl(throttle=action[0], steer=action[2], brake=action[1], reverse=action[3]) - self.world.step(control) + def reset(self): + self.world.reset() + return self.world.observation() + + def render(self): + if self.allow_render: + self.camera.on_update() + + def step(self, action, render=False): + if render: + self.render() + return self.world.step(action) if __name__ == "__main__": LOCALHOST="127.0.0.1" SERVER="192.168.188.20" - - pygame.init() + env = CarlaEnvironment(host=LOCALHOST, render=True) clock = pygame.time.Clock() - - env = CarlaEnvironment(host=LOCALHOST) - cam = Camera(env.world, camera_type='semantic_segmentation') ctrl = Controller() - + cumulated_reward = 0 while ctrl.is_running(): - clock.tick(60) + clock.tick(20) ctrl.on_update() - env.step(ctrl.get_action()) - cam.on_update() - + obs, reward, done = env.step(ctrl.get_action(), render=True) + if done: + break + print(str(reward) + ' ' + str(done)) + cumulated_reward += reward env.world.destroy() pygame.quit() + print(cumulated_reward) diff --git a/main.py b/main.py index 254f2b6..f09752b 100644 --- a/main.py +++ b/main.py @@ -4,9 +4,10 @@ Run your desired environment and agent configuration. import os import atexit -import gym +from carla_environment import CarlaEnvironment +# import gym -from agents import DQAgent as QAgent +from agents import QAgent as QAgent import environment_wrapper as ew # Allow GPU usage or force tensorflow to use the CPU. @@ -15,13 +16,15 @@ if FORCE_CPU: os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"] = "" - +RENDER = False if __name__ == '__main__': # 1. Create an environment - env = gym.make('LunarLander-v2') + env = CarlaEnvironment(render=RENDER) + # env = gym.make('LunarLander-v2') + print(env.observation_space.shape[0]) # 2. Create a learning agent - marvin = QAgent(env.action_space.n, env.observation_space.shape[0], 'FromScratchDouble') + marvin = QAgent(env.action_space.n, env.observation_space.shape[0], 'CarlaTest') # (2.5) *optional* Load agent memory and/or net from disk. agnt = 'agent' @@ -31,11 +34,10 @@ if __name__ == '__main__': marvin.load('saved_agents/' + agnt + '/' + agnt, net=LOAD_ANN, memory=LOAD_MEMORIES) # 3. Set your configurations for the run. - RENDER = False LEARNING = True LEARN_ONLINE = True LEARN_OFFLINE = False - RUN_EPISODES = 500 + RUN_EPISODES = 10 LEARN_OFFLINE_EPOCHS = 500 SAVE_PATH = "./saved_agents" diff --git a/steering_wheel.py b/steering_wheel.py index 66e031e..2828f7b 100644 --- a/steering_wheel.py +++ b/steering_wheel.py @@ -9,6 +9,18 @@ JOYSTICK_REVERSE=3 INPUT_OFFSET = 2.0 +IDLE=0 +FORWARD=1 +REVERSE=2 +FORWARD_LEFT=3 +FORWARD_RIGHT=4 +LEFT=5 +RIGHT=6 +BRAKE=7 +REVERSE_LEFT=8 +REVERSE_RIGHT=9 +ACTION_SPACE=10 + class ManualSteeringWheel: """ Steering wheel """ axis_count = 0.0 @@ -52,9 +64,49 @@ class ManualSteeringWheel: self.get_throttle(update=False) self.get_brakes(update=False) + def action_to_controls(action): + if action == IDLE: + return [0.0, 0.0, 0.0, False] + if action == FORWARD: + return [0.8, 0.0, 0.0, False] + if action == REVERSE: + return [0.8, 0.0, 0.0, True] + if action == FORWARD_LEFT: + return [0.8, -0.4, 0.0, False] + if action == FORWARD_RIGHT: + return [0.8, 0.4, 0.0, False] + if action == LEFT: + return [0.0, -0.4, 0.0, False] + if action == RIGHT: + return [0.0, 0.5, 0.0, False] + if action == BRAKE: + return [0.0, 0.0, 0.5, False] + if action == REVERSE_LEFT: + return [0.5, -0.4, 0.0, True] + if action == REVERSE_RIGHT: + return [0.5, 0.4, 0.0, True] + def get_action(self): - - return [self.throttle, self.brakes, self.direction, self.reverse] + action = IDLE + if self.throttle > 0.5 and self.brakes < 0.5 and abs(self.direction) < 0.1 and not self.reverse: + action = FORWARD + elif self.throttle > 0.5 and self.brakes < 0.5 and self.direction < -0.2 and not self.reverse: + action = FORWARD_LEFT + elif self.throttle > 0.5 and self.brakes < 0.5 and self.direction > 0.2 and not self.reverse: + action = FORWARD_RIGHT + elif self.throttle > 0.5 and self.brakes < 0.5 and abs(self.direction) < 0.2 and self.reverse: + action = REVERSE + elif self.throttle < 0.5 and self.brakes < 0.5 and self.direction < -0.2: + action = LEFT + elif self.throttle < 0.5 and self.brakes < 0.5 and self.direction > 0.2: + action = RIGHT + elif self.brakes > 0.5: + action = BRAKE + elif self.throttle > 0.5 and self.brakes < 0.5 and self.direction < -0.2 and self.reverse: + action = REVERSE_LEFT + elif self.throttle > 0.5 and self.brakes < 0.5 and self.direction > 0.2 and self.reverse: + action = REVERSE_RIGHT + return action class Controller(ManualSteeringWheel): -- GitLab