Example #1
0
def predictions(points, hazards = [], hazard_decrease = .5):
    count = 0
    prev_point = None

    speeds = []
    next_locations = []
    for point in points:
        if prev_point != None:
            l1 = (point.latitude, point.longitude)
            l2 = (prev_point.latitude, prev_point.longitude)

            distance = geo.calculate_distance(l1,l2)
            time = point.timestamp - prev_point.timestamp
            speed = geo.speed(distance, time)

            predict = geo.predict_next_location(l2, l1, time, time)
            error = geo.error(l2,predict)

            speeds.append(speed * 1000)
            next_locations.append(predict)
            print(error)
        prev_point = point
        count += 1

    return speeds, next_locations
    def _add_new_car(self, car_index: int, location: Location) -> None:
        # Initialize data store for new car index.

        self.car_positions.append(car_index)
        self.car_telemetry[car_index] = {
            'locations':
            deque([location], maxlen=MAX_TELEMETRY_LIST_LENGTH),
            'velocities':
            deque([None], maxlen=MAX_TELEMETRY_LIST_LENGTH),
            'accelerations':
            deque([None], maxlen=MAX_TELEMETRY_LIST_LENGTH),
            'distances_from_lap_start':
            deque(
                [None,
                 calculate_distance(location, self.lap_start_location)],
                maxlen=MAX_TELEMETRY_LIST_LENGTH),
            'current_lap':
            0,
            'lap_start_timestamp':
            location.timestamp,
            'lap_distance':
            0.0,
            'total_distance':
            0.0,
            'last_timestamp':
            location.timestamp
        }
        if location.timestamp > self.last_timestamp:
            self.last_timestamp = location.timestamp
    def test_calculate_distance(self):
        location_1 = Location(timestamp=0, latitude=0.0, longitude=0.0)
        location_2 = Location(timestamp=0, latitude=0.0, longitude=0.0)

        self.assertAlmostEqual(calculate_distance(location_1, location_2), 0.0)

        # at equator each degree of latitude is ~ 111 km apart
        location_2 = Location(timestamp=0, latitude=1.0, longitude=0.0)

        self.assertAlmostEqual(calculate_distance(location_1, location_2) /
                               1000.0,
                               111.0,
                               places=0)

        # at equator each degree of longitude is ~ 111 km apart
        location_2 = Location(timestamp=0, latitude=0.0, longitude=1.0)

        self.assertAlmostEqual(calculate_distance(location_1, location_2) /
                               1000.0,
                               111.0,
                               places=0)
        def comparison_function(car_1: int, car_2: int) -> int:
            # return 1 if car 1 is behind car 2
            # return -1 if car 2 is behind car 1
            # return 0 if we cannot tell

            distance = calculate_distance(extrapolated_car_locations[car_1],
                                          extrapolated_car_locations[car_2])
            if distance < CAR_POSITION_DETECTION_THRESHOLD:
                # for cars inside car position detection threshold, we calculate bearing from car 1 to car 2
                distance_bearing = calculate_bearing(
                    extrapolated_car_locations[car_1],
                    extrapolated_car_locations[car_2])
                # and velocity bearing of car 1
                if self.car_telemetry[car_1]['velocities'][-1] is not None:
                    car_1_velocity_bearing = self.car_telemetry[car_1][
                        'velocities'][-1].bearing
                    # and finally we compare bearing of distance between cars with velocity bearing
                    if 135.0 < (
                        (360.0 + distance_bearing - car_1_velocity_bearing) %
                            360) < 225.0:
                        # car 2 is behind car 1
                        return -1
                    elif 315.0 > ((360.0 + distance_bearing - car_1_velocity_bearing) % 360) \
                            or ((360.0 + distance_bearing - car_1_velocity_bearing) % 360) < 45.0:
                        # car 2 is ahead of car 1
                        return 1
                    else:
                        return 0
                else:
                    return 0
            else:
                # for cars outside car position detection threshold, first compare current lap
                car_1_current_lap = self.car_telemetry[car_1]['current_lap']
                car_2_current_lap = self.car_telemetry[car_2]['current_lap']
                if car_1_current_lap > car_2_current_lap:
                    return -1
                elif car_2_current_lap > car_1_current_lap:
                    return 1
                else:
                    # if current lap is the same, we then compare lap distance
                    car_1_lap_distance = self.car_telemetry[car_1][
                        'lap_distance']
                    car_2_lap_distance = self.car_telemetry[car_2][
                        'lap_distance']
                    if car_1_lap_distance > car_2_lap_distance:
                        return -1
                    elif car_2_lap_distance > car_1_lap_distance:
                        return 1
                    else:
                        return 0
Example #5
0
 def __calc_distance_from_obj(obj):
     lng = obj['longitude']
     lat = obj['latitude']
     return calculate_distance(lng, lat, ref_longitude, ref_latitude)
    def add_new_car_coordinate(self, car_index: int,
                               location: Location) -> List[Tuple[str, dict]]:
        # Add new car coordinate to data store and return list of new topic and message tuples that should be published.

        if car_index not in self.car_telemetry:
            self._add_new_car(car_index, location)
            return []
        else:
            # initialize list of new topic and message tuples
            messages = []

            # calculate velocity and acceleration
            previous_location = self.car_telemetry[car_index]['locations'][-1]
            previous_velocity = self.car_telemetry[car_index]['velocities'][-1]

            self.car_telemetry[car_index]['locations'].append(location)
            distance, velocity = calculate_distance_and_velocity(
                previous_location, location)
            self.car_telemetry[car_index]['velocities'].append(velocity)
            acceleration = None if previous_velocity is None else calculate_acceleration(
                previous_velocity, velocity)
            self.car_telemetry[car_index]['accelerations'].append(acceleration)

            # publish car speed status
            messages.append(
                ('carStatus', {
                    'timestamp': location.timestamp,
                    'carIndex': car_index,
                    'type': 'SPEED',
                    'value': 2.23693629205 * velocity.magnitude
                })
            )  # we convert velocity from meters per second to miles per hour here

            # check whether car crossed lap start line
            distance_from_lap_start = calculate_distance(
                location, self.lap_start_location)
            if self._crossed_lap_start_line(
                    self.car_telemetry[car_index]['distances_from_lap_start']
                [-2], self.car_telemetry[car_index]['distances_from_lap_start']
                [-1], distance_from_lap_start):
                # note, we detected that previous location was nearest to lap start line, so we use previous location timestamp to calculate lap time
                lap_time = 0.001 * float(
                    previous_location.timestamp -
                    self.car_telemetry[car_index]['lap_start_timestamp'])

                # publish car completing lap event
                messages.append(('events', {
                    'timestamp':
                    previous_location.timestamp,
                    'text':
                    f"Car {car_index} completes lap {self.car_telemetry[car_index]['current_lap']}"
                    + f" in {int(lap_time / 60)}m{(lap_time % 60):.3f}s."
                }))

                self.car_telemetry[car_index]['current_lap'] += 1
                self.car_telemetry[car_index][
                    'lap_start_timestamp'] = previous_location.timestamp
                self.car_telemetry[car_index]['lap_distance'] = distance
            else:
                self.car_telemetry[car_index]['lap_distance'] += distance

            self.car_telemetry[car_index]['distances_from_lap_start'].append(
                distance_from_lap_start)
            self.car_telemetry[car_index]['total_distance'] += distance
            self.car_telemetry[car_index][
                'last_timestamp'] = location.timestamp
            if location.timestamp > self.last_timestamp:
                self.last_timestamp = location.timestamp

            # calculate updated car positions
            new_car_positions = self._calculate_car_positions()
            existing_car_positions = self.car_positions
            if new_car_positions != existing_car_positions:
                for new_car_positions_index, new_car_positions_car_index in enumerate(
                        new_car_positions):
                    if new_car_positions_car_index != existing_car_positions[
                            new_car_positions_index]:
                        # car position changed - publish car position status
                        messages.append(('carStatus', {
                            'timestamp': location.timestamp,
                            'carIndex': new_car_positions_car_index,
                            'type': 'POSITION',
                            'value': new_car_positions_index + 1
                        }))

                    # now detect overtakes
                    cars_behind = new_car_positions[new_car_positions_index +
                                                    1:]
                    cars_previously_behind = existing_car_positions[
                        existing_car_positions.
                        index(new_car_positions_car_index) + 1:]
                    overtaken_cars = set(cars_behind) - set(
                        cars_previously_behind)
                    for overtaken_car in overtaken_cars:
                        # publish car overtake event
                        if (0.001 * float(location.timestamp -
                                          self.last_overtake_event_timestamp)
                            ) > OVERTAKE_EVENTS_TIME_CONSTANTS:
                            self.last_overtake_event_timestamp = location.timestamp
                            messages.append(('events', {
                                'timestamp':
                                location.timestamp,
                                'text':
                                f"Car {new_car_positions_car_index} overtakes Car {overtaken_car}!"
                            }))

                self.car_positions = new_car_positions

            return messages