diff --git a/carla_environment.py b/carla_environment.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fde8310ae4877ddc05cc0a42cf84bb113107256
--- /dev/null
+++ b/carla_environment.py
@@ -0,0 +1,123 @@
+""" Carla.org environment"""
+import glob
+import os
+import sys
+import random
+import numpy as np
+import pygame
+import math
+import atexit
+
+# find carla module
+try:
+    sys.path.append(glob.glob('/media/armin/Games/carla/PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
+        sys.version_info.major,
+        sys.version_info.minor,
+        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
+except IndexError:
+    pass
+
+import carla
+
+
+class Camera:
+    sensor = None
+    width = None
+    height = None
+    surface = None
+
+    def __init__(self, width=640, height=480):
+        self.width = width
+        self.height = height
+ 
+    def spawn(self, camera_actor):
+        self.sensor = camera_actor
+        self.sensor.listen(lambda data: self.process_img(data))
+    
+    def process_img(self, data):
+        array = np.frombuffer(data.raw_data, dtype=np.dtype("uint8"))
+        array = np.reshape(array, (self.width, self.height, 4))
+        array = array[:, :, :3]
+        array = array[:, :, ::-1]
+        self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
+
+
+class World:
+    player = None
+    world = None
+    camera = None
+    surface = None
+    blueprint_library = None
+    spawn_points = None
+
+    def __init__(self, world):
+        self.world = world
+        self.blueprint_library = self.world.get_blueprint_library()
+        self.spawn_points = self.world.get_map().get_spawn_points()
+        self.camera = Camera()
+        self.reset()
+    
+    def reset(self):
+        self.destroy()
+        self.spawn_player()
+
+    def spawn_player(self):
+        while self.player is None:
+            blueprint = random.choice(self.blueprint_library.filter('vehicle'))
+            position = random.choice(self.spawn_points)
+            self.player = self.world.try_spawn_actor(blueprint, position)
+        self.player.set_autopilot(True)
+        self.spawn_camera()
+
+    def spawn_camera(self):
+        camera_blueprint = self.blueprint_library.find('sensor.camera.rgb')
+        camera_transform = carla.Transform(carla.Location(x=1.5, z=2.4))
+        camera_blueprint.set_attribute('image_size_x', f'{self.camera.width}')
+        camera_blueprint.set_attribute('image_size_y', f'{self.camera.height}')
+        camera_blueprint.set_attribute('fov', '110')
+        self.camera.spawn(self.world.spawn_actor(camera_blueprint, camera_transform, attach_to=self.player))
+
+    def destroy(self):
+        if self.player is not None:
+            self.player.destroy()
+
+    def __del__(self):
+        self.player.destroy()
+
+class CarlaEnvironment:
+    world = None
+    client = None
+    display = None
+
+    def __init__(self, host="127.0.0.1", port=2000, width=1280, height=720):
+        pygame.init()
+        self.client = carla.Client(host, port)
+        self.client.set_timeout(2.0)
+        self.world = World(self.client.get_world())
+        self.display = pygame.display.set_mode(
+            (width, height),
+            pygame.HWSURFACE | pygame.DOUBLEBUF)
+        self.display.fill((0,0,0))
+    
+    def on_update(self):
+        if self.world.camera.surface is not None:
+            self.display.blit(self.world.camera.surface, (0, 0))
+            pygame.display.flip()
+
+    def __del__(self):
+        pygame.quit()
+
+
+if __name__ == "__main__":
+    env = CarlaEnvironment()
+    running = True
+
+    while running:
+        env.on_update()
+        for event in pygame.event.get():
+            if event.type == pygame.KEYUP:
+                if event.key == pygame.K_q:
+                    running = False
+        
+    env.world.destroy()
+    env = None
diff --git a/steering_wheel.py b/steering_wheel.py
new file mode 100644
index 0000000000000000000000000000000000000000..089d20591a064421eec836ea55ab939c0099c4ae
--- /dev/null
+++ b/steering_wheel.py
@@ -0,0 +1,64 @@
+""" Steering wheel """
+
+import pygame
+
+DIRECTION=0
+SPEED=1
+BREAKS=2
+INPUTS=3
+
+OFFSET = 2.0
+
+class ManualSteeringWheel:
+    """ Steering wheel """
+    axis_count = 0
+    joystick = None
+    direction = 0
+    speed = 0
+    breaks = 0
+
+    def __init__(self):
+        pygame.init()
+        self.joystick = pygame.joystick.Joystick(0)
+        self.joystick.init()
+        self.axis_count = self.joystick.get_numaxes()
+
+    def get_direction(self, update=True):
+        """ Update and return direction. """
+        if update:
+            pygame.event.get()
+        self.direction = self.joystick.get_axis(DIRECTION)
+        return self.direction
+    
+    def get_speed(self, update=True):
+        """ Update and return speed."""
+        if update:
+            pygame.event.get()
+        self.speed = (OFFSET - (self.joystick.get_axis(SPEED) + 1.0)) / OFFSET
+        return self.speed
+
+    def get_breaks(self, update=True):
+        """ Update and return breaks. """
+        if update:
+            pygame.event.get()
+        self.breaks = (OFFSET - (self.joystick.get_axis(BREAKS) + 1.0)) / OFFSET
+        return self.breaks
+
+    def on_update(self):
+        """ Poll for pygame events. """
+        pygame.event.get()
+        self.get_direction(update=False)
+        self.get_speed(update=False)
+        self.get_breaks(update=False)
+
+if __name__ == '__main__':
+    clock = pygame.time.Clock()
+    sw = ManualSteeringWheel()
+
+    while True:
+        # Receive all occured events
+        print("")
+        print("Direction: " + str(sw.get_direction()))
+        print("Speed:     " + str(sw.get_speed()))
+        print("Breaks:    " + str(sw.get_breaks()))
+        clock.tick(2)