Exemple #1
0
class Car:
    def __init__(self, name, x, y, radar_length, angle=-90, length=16):
        #set x,y and orientation posistion
        self.x = x
        self.y = y
        self.orientation = math.radians(-90)

        #set steering and acceleration/speed values
        self.steering_angle = 0.0
        self.previous_steering_angle = 0.0
        self.max_steering_angle = math.radians(30)
        self.acceleration = 0.0
        self.max_acceleration = 5.0
        self.speed = 0.0
        self.max_speed = 10

        #build car body based on the lenght
        self.car_length = 50
        self.car_width = 30
        self.wheel_length = 10
        self.wheel_width = 5

        #set params used for score calculation
        self.time = 200
        self.time_alive = 200
        self.checkpoint_passed = 2
        self.is_alive = True

        self.radar = Radar(self.x, self.y, 130,
                           (180, -90, -40, -15, 0, 15, 40, 90),
                           math.degrees(self.steering_angle))

    #When passing a checkpoint of the racetrack, reward the car with a bonus
    #First one to pass will get the max bonus, second one will recieve 500 points less
    def check_passed(self, racetrack):
        score = 0
        check1 = racetrack.checkpoints[self.checkpoint_passed]
        check2 = racetrack.checkpoints[self.checkpoint_passed + 1]
        p1 = [self.x - self.car_length / 4, self.y - self.car_width / 2]
        p2 = [self.x + (0.75 * self.car_length), self.y - self.car_width / 2]
        p3 = [self.x + (0.75 * self.car_length), self.y + self.car_width / 2]
        p4 = [self.x - self.car_length / 4, self.y + self.car_width / 2]

        corners = (p1, p2, p3, p4)

        c_x = self.x
        c_y = self.y
        delta_angle = self.orientation
        rotated_corners = []

        for p in corners:
            temp = []
            length = math.sqrt((p[0] - c_x)**2 + (c_y - p[1])**2)
            angle = math.atan2(c_y - p[1], p[0] - c_x)
            angle += delta_angle
            temp.append(c_x + length * math.cos(angle))
            temp.append(c_y - length * math.sin(angle))
            rotated_corners.append(temp)

        line1 = LineString((rotated_corners[0], rotated_corners[1],
                            rotated_corners[2], rotated_corners[3]))
        line2 = LineString([check1, check2])
        intersection1 = (line1.intersection(line2))

        if (isinstance(intersection1, shapely.geometry.multipoint.MultiPoint)):
            intersection1 = intersection1[len(intersection1) - 1]

        if (len(intersection1.coords) == 1):
            self.checkpoint_passed = self.checkpoint_passed + 2
            score = self.time_alive + 1000
            self.time_alive = self.time
        return score

    #Being alive is good, small reward
    def update_score(self):

        return 10
        a = math.degrees(self.steering_angle)
        b = math.degrees(self.previous_steering_angle)

        if (a > b):
            return -(100 - (a - b))
        else:
            return -(100 - (b - a))

    def distanceNextCheckpoint(self, racetrack):
        check = racetrack.checkpoints[self.checkpoint_passed]
        line = LineString(check)

        x = self.position.x
        y = self.position.y
        np = nearest_points(line, Point(x, y))[0]
        return calculate_distance(np.x, np.y, x, y)

    #update the car pos and angle
    def update(self, dt):
        #dunno yet
        #self.speed += (self.acceleration * dt, 0)
        #self.speed = max(-self.speed, min(self.speed, self.speed))

        theta = self.orientation  # initial orientation
        alpha = self.steering_angle  # steering angle
        dist = self.speed  # distance to be moved
        length = self.car_length  # length of the robot
        if abs(alpha) > self.max_steering_angle:
            raise ValueError('Exceeding max steering angle')

        # in local coordinates of robot
        beta = (dist / length) * math.tan(alpha)  # turning angle

        _x = _y = _theta = 0.0
        if beta > 0.001 or beta < -0.001:
            radius = dist / beta  # turning radius
            cx = self.x - math.sin(theta) * radius  # center of the circle
            cy = self.y - math.cos(theta) * radius  # center of the circle

            # in global coordinates of robot
            _x = cx + math.sin(theta + beta) * radius
            _y = cy + math.cos(theta + beta) * radius
            _theta = (theta + beta) % (2 * math.pi)

        else:  # straight motion
            _x = self.x + dist * math.cos(theta)
            _y = self.y - dist * math.sin(theta)
            _theta = (theta + beta) % (2 * math.pi)

        self.x = _x
        self.y = _y
        self.orientation = _theta
        self.steering_angle = alpha
        self.radar.updateRadar(self.x, self.y, math.degrees(self.orientation))
        self.time_alive -= 1
        '''