예제 #1
0
    def reset(self):
        self._destroy()
        self.reward = 0.0
        self.prev_reward = 0.0
        self.tile_visited_count = 0
        self.t = 0.0
        self.road_poly = []
        self.human_render = False

        while True:
            success = self._create_track()
            if success: break
            print("retry to generate track (normal if there are not many of this messages)")
        # self.car = Car(self.world, *self.track[0][1:4])
        # changed to 0 angle and x, y from my track)
        self.car = Car(self.world, -math.pi/2, self.track[0][0]+5, self.track[0][1]+5)
        self.car2 = Car(self.world, math.pi/2, self.track[0][0]+25, self.track[0][1]+5, color=(0, 0.5, 0))
        # self.car2 = Car(self.world, math.pi/2, self.track[-1][-1], self.track[-1][-2], color=(0, 0.5, 0))
        self.car3 = Car(self.world, math.pi, TRACK_WIDTH-5, PLAYFIELD, color=(0, 0.75, 1))

        return self.step(None)[0]
예제 #2
0
    def run(self):

        car = Car(self.window_width / 20, self.window_height / 20)
        track = Track('track3.svg')
        track_drawer = TrackDrawer(track)
        car.position.x, car.position.y = track.path[0][0] / 10 - 1366 / 20, track.path[0][1] / 10 - 768 / 20
        car_drawer = CarDrawer()
        input_provider = JoystickInputProvider()
        if not input_provider.joysticks:
            input_provider = KeyboardInputProvider()
        car_data_display = CarDataDisplay(car)
        trace = [(car.position.x * 10 + 1366/2, car.position.y * 10 + 768/2) for _ in range(3)]

        while not self.exit:
            dt = self.clock.tick(self.fps) / 1000

            # Event queue
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.exit = True

            trace.pop(2)
            trace.insert(0, (car.position.x * 10 + 1366/2, car.position.y * 10 + 768/2))

            # User input
            car_input = input_provider.get_input()
            car.get_driver_input(car_input[0], car_input[1], car_input[2], car_input[3])
            car.update(dt)

            # Drawing
            self.screen.fill((0, 0, 0))
            track_drawer.draw(self.screen, car.position * 10, trace)
            car_drawer.draw(self.screen, car)
            car_data_display.display_data(self.screen)
            pygame.display.flip()
        pygame.quit()
예제 #3
0
import sys
import os.path
sys.path.append(os.path.dirname(sys.path[0]))
from car_model import Car
global car
# Tests to check that the variables are properly set
car = Car()


def test_no_velocity():
    assert (car.force_req(0) == 10.594800000000001)


def test_10_ms():
    assert (car.force_req(10) == 19.7823)


def test_energy_used():
    assert (car.energy_used([5, 7, 9, 13, 9.5, 7, 5],
                            [-1, 1, 3, 3, 1, 1, 1.5]) == 28267.47205752044)
예제 #4
0
def car_min_0_max_1000():
    car = Car()
    car.speed_min_ms = 0
    car.speed_max_ms = 1000
    return car
예제 #5
0
def car_min_15_max_45():
    car = Car()
    car.speed_min_ms = 15
    car.speed_max_ms = 45
    return car
    def run(self, dt, solution, car=None):
        if car is None:
            car = Car(1366 / 20, 768 / 20)

        car.position.x, car.position.y = self.track.path[0][
            0] / 10 - 1366 / 20, self.track.path[0][1] / 10 - 768 / 20
        self.track.apply_deformations(list(solution.Deformation))
        input_provider = AutonomousDriver(solution)
        time = 0
        trace = [(car.position.x * 10 + 1366 / 2,
                  car.position.y * 10 + 768 / 2) for _ in range(3)]

        # Indicators

        track_path_length = LineString(
            self.track.path).length / 10  # length of path loaded from solution
        regulation_quality_indicator_square = 0  # integral of squared error values
        regulation_quality_indicator_abs = 0  # integral of abs values
        max_line_error = 0  # error in m
        average_slip = 0  # average of abs lateral speed in m / s
        slip_indicator = 0  # integral of squared speed in m / s^2
        max_speed_long = 0  # m / s^2
        max_speed_lat = 0  # m / s^2
        average_speed_long = 0  # average speed longitudinal in m
        average_rpm = 0
        max_rpm = 0
        number_of_iterations = 0  # helper variable for computing averages

        while True:
            time += dt
            if time > self.timeout:
                break

            # User input
            indexes = self.track.check_car_position(trace)
            input_provider.index = indexes[-1]

            car_input = input_provider.get_input()
            car.get_driver_input(car_input[0], car_input[1], car_input[2],
                                 car_input[3])
            car.update(dt)

            vector = Vector2(40, 0).rotate(-car.angle)
            vector = np.array((vector.x + 1366 / 2, vector.y + 768 / 2))
            front_center = Point(
                np.array((car.position.x * 10, car.position.y * 10)) + vector)
            if Polygon(self.track.path).contains(front_center):
                input_provider.line_error = -LineString(
                    self.track.path).distance(front_center)
            else:
                input_provider.line_error = LineString(
                    self.track.path).distance(front_center)

            # Update solution indicators

            number_of_iterations += 1
            average_rpm = average_rpm * (
                number_of_iterations -
                1) / number_of_iterations + car.rpm / number_of_iterations
            average_speed_long = average_speed_long * (
                number_of_iterations - 1
            ) / number_of_iterations + car.velocity.x / number_of_iterations
            average_slip = average_slip * (
                number_of_iterations - 1) / number_of_iterations + abs(
                    car.velocity.y) / number_of_iterations

            regulation_quality_indicator_square += (input_provider.line_error /
                                                    10)**2
            regulation_quality_indicator_abs += abs(input_provider.line_error /
                                                    10)
            if abs(input_provider.line_error) / 10 > max_line_error:
                max_line_error = abs(input_provider.line_error) / 10
            slip_indicator += car.velocity.y**2
            if car.velocity.x > max_speed_long:
                max_speed_long = car.velocity.x
            if abs(car.velocity.y) > max_speed_lat:
                max_speed_lat = abs(car.velocity.y)
            if car.rpm > max_rpm:
                max_rpm = car.rpm

            trace.pop(2)
            trace.insert(0, (car.position.x * 10 + 1366 / 2,
                             car.position.y * 10 + 768 / 2))

            if input_provider.index == len(self.track.track_chunks) - 1:
                break

        finished = True
        for chunk in self.track.track_chunks:
            if not chunk.is_active:
                finished = False
                break

        for index in range(1, len(self.track.track_chunks)):
            self.track.track_chunks[index].is_active = False
        if finished and time < self.timeout:
            return time, (track_path_length, average_rpm, average_speed_long,
                          average_slip, regulation_quality_indicator_abs,
                          regulation_quality_indicator_square, max_line_error,
                          slip_indicator, max_speed_long, max_speed_lat,
                          max_rpm)
        else:
            return 99999, (track_path_length, average_rpm, average_speed_long,
                           average_slip, regulation_quality_indicator_abs,
                           regulation_quality_indicator_square, max_line_error,
                           slip_indicator, max_speed_long, max_speed_lat,
                           max_rpm)
예제 #7
0
    def run_pid_controller(self, track_path, solution_path='solutionOpt.csv', dt=0.05):
        car = Car(self.window_width / 20, self.window_height / 20)
        track = Track(track_path)
        track_drawer = TrackDrawer(track)
        solution = pd.read_csv(solution_path, index_col=0)
        track.apply_deformations(list(solution.Deformation))
        car.position.x, car.position.y = track.path[0][0] / 10 - 1366 / 20, track.path[0][1] / 10 - 768 / 20
        car_drawer = CarDrawer()
        car_data_display = CarDataDisplay(car)
        input_provider = AutonomousDriver(solution)
        time = 0
        trace = [(car.position.x * 10 + 1366/2, car.position.y * 10 + 768/2) for _ in range(3)]
        while not self.exit:
            # Handling time
            self.clock.tick(1 / dt)
            time += dt

            # Event queue
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.exit = True

            # Input from solution file and PID controller
            input_provider.index = track_drawer.chunk_indexes[-1] # Incrementing row index of solution matrix
            car_input = input_provider.get_input()
            car.get_driver_input(car_input[0], car_input[1], car_input[2], car_input[3])
            car.update(dt)

            # Calculating position of a front center of a car
            vector = Vector2(40, 0).rotate(-car.angle)
            vector = np.array((vector.x + 1366 / 2, vector.y + 768 / 2))
            front_center = Point(np.array((car.position.x * 10, car.position.y * 10)) + vector)

            # Calculating line error as a distance from front center to a given line (path)
            if Polygon(track.path).contains(front_center):
                input_provider.line_error = - LineString(track.path).distance(front_center)
            else:
                input_provider.line_error = LineString(track.path).distance(front_center)

            # Updating trace
            trace.pop(2)
            trace.insert(0, (car.position.x * 10 + 1366 / 2, car.position.y * 10 + 768 / 2))

            # Drawing
            self.screen.fill((0, 0, 0))
            self.background.set_location([- car.position.x * 10, 768 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([1200 - car.position.x * 10, 768 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([2400 - car.position.x * 10, 768 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([- car.position.x * 10, 768 + 1200 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([1200 - car.position.x * 10, 768 + 1200 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([2400 - car.position.x * 10, 768 + 1200 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([- car.position.x * 10, 768 + 2400 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([1200 - car.position.x * 10, 768 + 2400 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            self.background.set_location([2400 - car.position.x * 10, 768 + 2400 - car.position.y * 10])
            self.screen.blit(self.background.image, self.background.rect)
            track_drawer.draw(self.screen, car.position * 10, trace)
            car_drawer.draw(self.screen, car)
            car_data_display.display_data(self.screen)
            rect = pygame.Rect(front_center.x - car.position.x * 10, front_center.y - car.position.y * 10, 5, 5)
            pygame.draw.rect(self.screen, (0, 0, 255), rect)
            pygame.display.flip()

            # Checking if car has passed finishing-line
            if input_provider.index == len(track.track_chunks) - 1:
                break

        # Checking if car completed track
        completed = True
        for chunk in track.track_chunks:
            if not chunk.is_active:
                completed = False
                break

        print("Time:", time, "Completed:", completed)
        pygame.quit()
예제 #8
0
class CarRacing(gym.Env, EzPickle):
    metadata = {
        'render.modes': ['human', 'rgb_array', 'state_pixels'],
        'video.frames_per_second' : FPS
    }

    def __init__(self):
        EzPickle.__init__(self)
        self.seed()
        self.contactListener_keepref = FrictionDetector(self)
        self.world = Box2D.b2World((0,0), contactListener=self.contactListener_keepref)
        self.viewer = None
        self.invisible_state_window = None
        self.invisible_video_window = None
        self.road = None
        self.car = None
        self.car2 = None
        self.reward = 0.0
        self.prev_reward = 0.0

        self.action_space = spaces.Box( np.array([-1,0,0]), np.array([+1,+1,+1]), dtype=np.float32)  # steer, gas, brake
        self.observation_space = spaces.Box(low=0, high=255, shape=(STATE_H, STATE_W, 3), dtype=np.uint8)

    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    def _destroy(self):
        if not self.road: return
        for t in self.road:
            self.world.DestroyBody(t)
        self.road = []
        self.car.destroy()
        self.car2.destroy()

    def _create_track(self):

        ########################################################################
        t_p = PLAYFIELD
        t_w = TRACK_WIDTH

        # My cross_road interscections:
        my_r1 = [(-t_p, -t_w), (-t_p, t_w), (t_p, t_w), (t_p, -t_w)]
        my_r2 = [(-t_w, -t_w), (-t_w, -t_p), (t_w, -t_p), (t_w, -t_w)]
        my_r3 = [(t_w, t_w), (t_w, t_p), (-t_w, t_p), (-t_w, t_w)]

        self.road_poly = [(my_r1, ROAD_COLOR), (my_r2, ROAD_COLOR), (my_r3, ROAD_COLOR)]
        self.road = []

        # We create road with 10x10 tiles over all fiels and we change colors a little bit if outside road;
        track = [(i, j) for i in np.arange(-t_p, t_p, 20/SCALE) for j in np.arange(-t_w, t_w, 20/SCALE)]
        track.extend([(i, j) for i in np.arange(-t_w, t_w, 20/SCALE) for j in np.arange(-t_p, -t_w, 20/SCALE)])
        track.extend([(i, j) for i in np.arange(-t_w, t_w, 20/SCALE) for j in np.arange(t_w, t_p, 20/SCALE)])
        for i, (x, y) in enumerate(track):
            road1_l = (x, y)
            road1_r = (x, y+20/SCALE)
            road2_l = (x+20/SCALE, y)
            road2_r = (x+20/SCALE, y+20/SCALE)
            t = self.world.CreateStaticBody( fixtures = fixtureDef(
                shape=polygonShape(vertices=[road1_l, road1_r, road2_r, road2_l])
                ))
            t.userData = t
            c = 0.01*(i%3)
            t.color = [ROAD_COLOR[0] + c, ROAD_COLOR[1] + c, ROAD_COLOR[2] + c]
            t.road_visited = False
            t.road_friction = 1.0
            t.fixtures[0].sensor = True
            self.road_poly.append(( [road1_l, road1_r, road2_r, road2_l], t.color ))
            self.road.append(t)

        self.track = track
        ########################################################################

        return True

    def reset(self):
        self._destroy()
        self.reward = 0.0
        self.prev_reward = 0.0
        self.tile_visited_count = 0
        self.t = 0.0
        self.road_poly = []
        self.human_render = False

        while True:
            success = self._create_track()
            if success: break
            print("retry to generate track (normal if there are not many of this messages)")
        # self.car = Car(self.world, *self.track[0][1:4])
        # changed to 0 angle and x, y from my track)
        self.car = Car(self.world, -math.pi/2, self.track[0][0]+5, self.track[0][1]+5)
        self.car2 = Car(self.world, math.pi/2, self.track[0][0]+25, self.track[0][1]+5, color=(0, 0.5, 0))
        # self.car2 = Car(self.world, math.pi/2, self.track[-1][-1], self.track[-1][-2], color=(0, 0.5, 0))
        self.car3 = Car(self.world, math.pi, TRACK_WIDTH-5, PLAYFIELD, color=(0, 0.75, 1))

        return self.step(None)[0]

    def step(self, action):
        if action is not None:
            self.car.steer(-action[0])
            self.car.gas(action[1])
            self.car.brake(action[2])

            for i, c in enumerate(self.car.hull.contacts):
                if c.contact.manifold.pointCount != 0:
                    print("Collision")

        #car2 movements:
        self.car2.steer(0.01)
        self.car2.gas(0.1)
        self.car2.brake((np.random.rand()<0.3)*0.2)

        #car3 movements:
        self.car3.steer(-0.01)
        self.car3.gas(0.1)
        self.car3.brake((np.random.rand()<0.3)*0.2)

        self.car.step(1.0/FPS)
        self.car2.step(1.0/FPS)
        self.car3.step(1.0/FPS)
        self.world.Step(1.0/FPS, 6*30, 2*30)
        self.t += 1.0/FPS

        self.state = self.render("state_pixels")

        step_reward = 0
        done = False
        if action is not None: # First step without action, called from reset()
            self.reward -= 0.1
            # We actually don't want to count fuel spent, we want car to be faster.
            #self.reward -=  10 * self.car.fuel_spent / ENGINE_POWER
            self.car.fuel_spent = 0.0
            step_reward = self.reward - self.prev_reward
            self.prev_reward = self.reward
            if self.tile_visited_count==len(self.track):
                done = True
            x, y = self.car.hull.position
            if abs(x) > PLAYFIELD or abs(y) > PLAYFIELD:
                done = True
                step_reward = -100

        return self.state, step_reward, done, {}

    def render(self, mode='human'):
        if self.viewer is None:
            from gym.envs.classic_control import rendering
            self.viewer = rendering.Viewer(WINDOW_W, WINDOW_H)
            self.score_label = pyglet.text.Label('0000', font_size=36,
                x=20, y=WINDOW_H*2.5/40.00, anchor_x='left', anchor_y='center',
                color=(255,255,255,255))
            self.transform = rendering.Transform()

        if "t" not in self.__dict__: return  # reset() not called yet

        zoom = 0.1*SCALE*max(1-self.t, 0) + ZOOM*SCALE*min(self.t, 1)   # Animate zoom first second
        zoom_state  = ZOOM*SCALE*STATE_W/WINDOW_W
        zoom_video  = ZOOM*SCALE*VIDEO_W/WINDOW_W
        scroll_x = 0 #self.car.hull.position[0] #0
        scroll_y = -30 #self.car.hull.position[1] #-30
        angle = 0 #-self.car.hull.angle #0
        vel = 0 #self.car.hull.linearVelocity #0
        if np.linalg.norm(vel) > 0.5:
            angle = math.atan2(vel[0], vel[1])
        self.transform.set_scale(zoom, zoom)
        self.transform.set_translation(
            WINDOW_W/2 - (scroll_x*zoom*math.cos(angle) - scroll_y*zoom*math.sin(angle)),
            WINDOW_H/4 - (scroll_x*zoom*math.sin(angle) + scroll_y*zoom*math.cos(angle)) )
        self.transform.set_rotation(angle)

        self.car.draw(self.viewer, mode!="state_pixels")
        self.car2.draw(self.viewer, mode!="state_pixels")
        self.car3.draw(self.viewer, mode!="state_pixels")

        arr = None
        win = self.viewer.window
        if mode != 'state_pixels':
            win.switch_to()
            win.dispatch_events()
        if mode=="rgb_array" or mode=="state_pixels":
            win.clear()
            t = self.transform
            if mode=='rgb_array':
                VP_W = VIDEO_W
                VP_H = VIDEO_H
            else:
                VP_W = STATE_W
                VP_H = STATE_H
            gl.glViewport(0, 0, VP_W, VP_H)
            t.enable()
            self.render_road()
            for geom in self.viewer.onetime_geoms:
                geom.render()
            t.disable()
            self.render_indicators(WINDOW_W, WINDOW_H)  # TODO: find why 2x needed, wtf
            image_data = pyglet.image.get_buffer_manager().get_color_buffer().get_image_data()
            arr = np.fromstring(image_data.data, dtype=np.uint8, sep='')
            arr = arr.reshape(VP_H, VP_W, 4)
            arr = arr[::-1, :, 0:3]

        if mode=="rgb_array" and not self.human_render: # agent can call or not call env.render() itself when recording video.
            win.flip()

        if mode=='human':
            self.human_render = True
            win.clear()
            t = self.transform
            gl.glViewport(0, 0, WINDOW_W, WINDOW_H)
            t.enable()
            self.render_road()
            for geom in self.viewer.onetime_geoms:
                geom.render()
            t.disable()
            self.render_indicators(WINDOW_W, WINDOW_H)
            win.flip()

        self.viewer.onetime_geoms = []
        return arr

    def close(self):
        if self.viewer is not None:
            self.viewer.close()
            self.viewer = None

    def render_road(self):
        gl.glBegin(gl.GL_QUADS)
        gl.glColor4f(1, 1, 1, 1.0) #gl.glColor4f(0.4, 0.8, 0.4, 1.0)
        gl.glVertex3f(-PLAYFIELD, +PLAYFIELD, 0)
        gl.glVertex3f(+PLAYFIELD, +PLAYFIELD, 0)
        gl.glVertex3f(+PLAYFIELD, -PLAYFIELD, 0)
        gl.glVertex3f(-PLAYFIELD, -PLAYFIELD, 0)
        # gl.glColor4f(0, 0, 0, 1.0) #gl.glColor4f(0.4, 0.9, 0.4, 1.0)
        # k = PLAYFIELD/20.0
        # for x in range(-20, 20, 2):
        #     for y in range(-20, 20, 2):
        #         gl.glVertex3f(k*x + k, k*y + 0, 0)
        #         gl.glVertex3f(k*x + 0, k*y + 0, 0)
        #         gl.glVertex3f(k*x + 0, k*y + k, 0)
        #         gl.glVertex3f(k*x + k, k*y + k, 0)
        for poly, color in self.road_poly:
            gl.glColor4f(color[0], color[1], color[2], 1)
            for p in poly:
                gl.glVertex3f(p[0], p[1], 0)
        gl.glEnd()

    def render_indicators(self, W, H):
        gl.glBegin(gl.GL_QUADS)
        s = W/40.0
        h = H/40.0
        gl.glColor4f(0,0,0,1)
        gl.glVertex3f(W, 0, 0)
        gl.glVertex3f(W, 5*h, 0)
        gl.glVertex3f(0, 5*h, 0)
        gl.glVertex3f(0, 0, 0)
        def vertical_ind(place, val, color):
            gl.glColor4f(color[0], color[1], color[2], 1)
            gl.glVertex3f((place+0)*s, h + h*val, 0)
            gl.glVertex3f((place+1)*s, h + h*val, 0)
            gl.glVertex3f((place+1)*s, h, 0)
            gl.glVertex3f((place+0)*s, h, 0)
        def horiz_ind(place, val, color):
            gl.glColor4f(color[0], color[1], color[2], 1)
            gl.glVertex3f((place+0)*s, 4*h , 0)
            gl.glVertex3f((place+val)*s, 4*h, 0)
            gl.glVertex3f((place+val)*s, 2*h, 0)
            gl.glVertex3f((place+0)*s, 2*h, 0)
        true_speed = np.sqrt(np.square(self.car.hull.linearVelocity[0]) + np.square(self.car.hull.linearVelocity[1]))
        vertical_ind(5, 0.02*true_speed, (1,1,1))
        vertical_ind(7, 0.01*self.car.wheels[0].omega, (0.0,0,1)) # ABS sensors
        vertical_ind(8, 0.01*self.car.wheels[1].omega, (0.0,0,1))
        vertical_ind(9, 0.01*self.car.wheels[2].omega, (0.2,0,1))
        vertical_ind(10,0.01*self.car.wheels[3].omega, (0.2,0,1))
        horiz_ind(20, -10.0*self.car.wheels[0].joint.angle, (0,1,0))
        horiz_ind(30, -0.8*self.car.hull.angularVelocity, (1,0,0))
        gl.glEnd()
        self.score_label.text = "%04i" % self.reward
        self.score_label.draw()