コード例 #1
0
ファイル: target.py プロジェクト: auvsi-suas/interop
    def actionable_submission(self, flights=None):
        """Checks if Target meets Actionable Intelligence submission criteria.

        A target is "actionable" if it was submitted and last updated during the
        aircraft's first flight.

        Args:
            flights: Optional memoized flights for this target's user. If
                     omitted, the flights will be looked up.

        Returns:
            True if target may be considered an "actionable" submission.
        """
        if flights is None:
            flights = TakeoffOrLandingEvent.flights(self.user)

        if len(flights) > 0:
            flight = flights[0]
            if flight.within(self.creation_time) and flight.within(self.last_modified_time):
                return True

        return False
コード例 #2
0
ファイル: target.py プロジェクト: APTRG/interop
    def actionable_submission(self, flights=None):
        """Checks if Target meets Actionable Intelligence submission criteria.

        A target is "actionable" if the aircraft was in flight from initial
        target submission until the last update. Note that this does not check
        the localization or characterization Actionable Intelligence criteria.

        Args:
            flights: Optional memoized flights for this target's user. If
                     omitted, the flights will be looked up.

        Returns:
            True if target may be considered an "actionable" submission.
        """
        if flights is None:
            flights = TakeoffOrLandingEvent.flights(self.user)

        for flight in flights:
            if flight.within(self.creation_time) and \
                flight.within(self.last_modified_time):
                return True

        return False
コード例 #3
0
ファイル: target.py プロジェクト: APTRG/interop
    def __init__(self, submitted_targets, real_targets):
        """Creates an evaluation of submitted targets against real targets.

        Args:
            submitted_targets: List of submitted Target objects, all from
                               the same user.
            real_targets: List of real Target objects made by judges.

        Raises:
            AssertionError: not all submitted targets are from the same user.
        """
        self.submitted_targets = submitted_targets
        self.real_targets = real_targets

        if self.submitted_targets:
            self.user = self.submitted_targets[0].user
            for t in self.submitted_targets:
                if t.user != self.user:
                    raise AssertionError(
                        "All submitted targets must be from the same user")

            self.flights = TakeoffOrLandingEvent.flights(self.user)

        self.matches = self.match_targets(submitted_targets, real_targets)
コード例 #4
0
ファイル: mission_config.py プロジェクト: CnuUasLab/interop
    def evaluate_teams(self):
        """Evaluates the teams (non admin users) of the competition.

        Returns:
            A map from user to evaluate data. The evaluation data has the
            following map structure:
            {
                'waypoints_satisfied': {
                    id: Boolean,
                }
                'out_of_bounds_time': Seconds spent out of bounds,
                'interop_times': {
                    'server_info': {'max': Value, 'avg': Value},
                    'obst_info': {'max': Value, 'avg': Value},
                    'uas_telem': {'max': Value, 'avg': Value},
                },
                'stationary_obst_collision': {
                    id: Boolean
                },
                'moving_obst_collision': {
                    id: Boolean
                }
            }
        """
        # Start a results map from user to evaluation data
        results = {}

        # Fill in evaluation data for each user except admins
        users = User.objects.all()
        logger.info("Starting team evaluations.")

        for user in users:
            # Ignore admins.
            if user.is_superuser:
                continue

            logger.info("Evaluation starting for user: %s." % user.username)

            # Start the evaluation data structure.
            eval_data = results.setdefault(user, {})

            # Find the user's flights.
            flight_periods = TakeoffOrLandingEvent.flights(user)
            uas_period_logs = UasTelemetry.dedupe(UasTelemetry.by_time_period(user, flight_periods))
            uas_logs = list(itertools.chain.from_iterable(uas_period_logs))

            # Determine if the uas hit the waypoints.
            waypoints_hit = self.satisfied_waypoints(uas_logs)
            waypoints_keyed = {}
            for i, hit in enumerate(waypoints_hit):
                waypoints_keyed[i + 1] = hit
            eval_data["waypoints_satisfied"] = waypoints_keyed

            # Determine if the uas went out of bounds. This must be done for
            # each period individually so time between periods isn't counted as
            # out of bounds time. Note that this calculates reported time out
            # of bounds, not actual or possible time spent out of bounds.
            out_of_bounds_time = 0
            for logs in uas_period_logs:
                out_of_bounds_time += FlyZone.out_of_bounds(self.fly_zones.all(), logs)
            eval_data["out_of_bounds_time"] = out_of_bounds_time

            # Determine interop rates.
            interop_times = eval_data.setdefault("interop_times", {})

            server_info_times = ServerInfoAccessLog.rates(user, flight_periods)
            obstacle_times = ObstacleAccessLog.rates(user, flight_periods)
            uas_telemetry_times = UasTelemetry.rates(user, flight_periods, time_period_logs=uas_period_logs)

            interop_times["server_info"] = {"max": server_info_times[0], "avg": server_info_times[1]}
            interop_times["obst_info"] = {"max": obstacle_times[0], "avg": obstacle_times[1]}
            interop_times["uas_telem"] = {"max": uas_telemetry_times[0], "avg": uas_telemetry_times[1]}

            # Determine collisions with stationary and moving obstacles.
            stationary_collisions = eval_data.setdefault("stationary_obst_collision", {})
            for obst in self.stationary_obstacles.all():
                collision = obst.evaluate_collision_with_uas(uas_logs)
                stationary_collisions[obst.pk] = collision

            moving_collisions = eval_data.setdefault("moving_obst_collision", {})
            for obst in self.moving_obstacles.all():
                collision = obst.evaluate_collision_with_uas(uas_logs)
                moving_collisions[obst.pk] = collision

        return results
コード例 #5
0
    def evaluate_teams(self):
        """Evaluates the teams (non admin users) of the competition.

        Returns:
            A map from user to evaluate data. The evaluation data has the
            following map structure:
            {
                'mission_clock_time': Seconds spent on mission clock,
                'waypoints_satisfied': {
                    id: Boolean,
                }
                'out_of_bounds_time': Seconds spent out of bounds,
                'targets': Data from TargetEvaluation,
                'interop_times': {
                    'server_info': {'max': Value, 'avg': Value},
                    'obst_info': {'max': Value, 'avg': Value},
                    'uas_telem': {'max': Value, 'avg': Value},
                },
                'stationary_obst_collision': {
                    id: Boolean
                },
                'moving_obst_collision': {
                    id: Boolean
                }
                'warnings': [
                    "String message."
                ],
            }
        """
        # Start a results map from user to evaluation data
        results = {}

        # Fill in evaluation data for each user except admins
        users = User.objects.all()
        logger.info('Starting team evaluations.')

        for user in users:
            # Ignore admins.
            if user.is_superuser:
                continue

            logger.info('Evaluation starting for user: %s.' % user.username)

            # Start the evaluation data structure.
            eval_data = results.setdefault(user, {})
            warnings = []
            eval_data['warnings'] = warnings

            # Calculate the total mission clock time.
            mission_clock_time = 0
            missions = MissionClockEvent.missions(user)
            for mission in missions:
                duration = mission.duration()
                if duration is None:
                    warnings.append('Infinite duration mission clock.')
                else:
                    mission_clock_time += duration.total_seconds()
            eval_data['mission_clock_time'] = mission_clock_time

            # Find the user's flights.
            flight_periods = TakeoffOrLandingEvent.flights(user)
            for period in flight_periods:
                if period.duration() is None:
                    warnings.append('Infinite duration flight period.')
            uas_period_logs = [
                UasTelemetry.dedupe(logs)
                for logs in UasTelemetry.by_time_period(user, flight_periods)
            ]
            uas_logs = list(itertools.chain.from_iterable(uas_period_logs))
            if not uas_logs:
                warnings.append('No UAS telemetry logs.')

            # Determine if the uas hit the waypoints.
            waypoints_hit, waypoints_hit_track, waypoints_closest = \
                self.satisfied_waypoints(uas_logs)
            eval_data['waypoints_satisfied'] = waypoints_hit
            eval_data['waypoints_satisfied_track'] = waypoints_hit_track
            eval_data['waypoints_closest'] = waypoints_closest

            # Determine if the uas went out of bounds. This must be done for
            # each period individually so time between periods isn't counted as
            # out of bounds time. Note that this calculates reported time out
            # of bounds, not actual or possible time spent out of bounds.
            out_of_bounds_time = 0
            for logs in uas_period_logs:
                out_of_bounds_time += FlyZone.out_of_bounds(
                    self.fly_zones.all(), logs)
            eval_data['out_of_bounds_time'] = out_of_bounds_time

            # Evaluate the targets.
            eval_data['targets'] = {}
            user_targets = Target.objects.filter(user=user).all()
            target_sets = {
                'manual': [t for t in user_targets if not t.autonomous],
                'auto': [t for t in user_targets
                         if t.autonomous][:settings.TARGET_MAX_NUM_AUTONOMOUS],
            }
            for target_set, targets in target_sets.iteritems():
                evaluator = TargetEvaluator(targets, self.targets.all())
                eval_data['targets'][target_set] = evaluator.evaluation_dict()

            # Determine interop rates.
            interop_times = eval_data.setdefault('interop_times', {})

            server_info_times = ServerInfoAccessLog.rates(user, flight_periods)
            obstacle_times = ObstacleAccessLog.rates(user, flight_periods)
            uas_telemetry_times = UasTelemetry.rates(
                user,
                flight_periods,
                time_period_logs=uas_period_logs)

            interop_times['server_info'] = {
                'max': server_info_times[0],
                'avg': server_info_times[1]
            }
            interop_times['obst_info'] = {
                'max': obstacle_times[0],
                'avg': obstacle_times[1]
            }
            interop_times['uas_telem'] = {
                'max': uas_telemetry_times[0],
                'avg': uas_telemetry_times[1]
            }

            # Determine collisions with stationary and moving obstacles.
            stationary_collisions = eval_data.setdefault(
                'stationary_obst_collision', {})
            for obst in self.stationary_obstacles.all():
                collision = obst.evaluate_collision_with_uas(uas_logs)
                stationary_collisions[obst.pk] = collision

            moving_collisions = eval_data.setdefault('moving_obst_collision',
                                                     {})
            for obst in self.moving_obstacles.all():
                collision = obst.evaluate_collision_with_uas(uas_logs)
                moving_collisions[obst.pk] = collision

        return results
コード例 #6
0
ファイル: uas_telemetry.py プロジェクト: auvsi-suas/interop
    def kml(cls, user, logs, kml, kml_doc):
        """
        Appends kml nodes describing the given user's flight as described
        by the log array given.

        Args:
            user: A Django User to get username from
            logs: A list of UasTelemetry elements
            kml: A simpleKML Container to which the flight data will be added
            kml_doc: The simpleKML Document to which schemas will be added
        Returns:
            None
        """
        # KML Compliant Datetime Formatter
        kml_datetime_format = "%Y-%m-%dT%H:%M:%S.%fZ"
        icon = 'http://maps.google.com/mapfiles/kml/shapes/airports.png'
        threshold = 1  # Degrees

        kml_folder = kml.newfolder(name=user.username)

        flights = TakeoffOrLandingEvent.flights(user)
        if len(flights) == 0:
            return

        logs = filter(lambda log: cls._is_bad_position(log, threshold), logs)
        for i, flight in enumerate(flights):
            label = 'Flight {}'.format(i + 1)  # Flights are one-indexed
            kml_flight = kml_folder.newfolder(name=label)

            flight_logs = filter(lambda x: flight.within(x.timestamp), logs)
            if len(flight_logs) < 2:
                continue

            coords = []
            angles = []
            when = []
            for entry in flight_logs:
                pos = entry.uas_position.gps_position
                # Spatial Coordinates
                coord = (pos.longitude, pos.latitude,
                         units.feet_to_meters(entry.uas_position.altitude_msl))
                coords.append(coord)

                # Time Elements
                time = entry.timestamp.strftime(kml_datetime_format)
                when.append(time)

                # Degrees heading, tilt, and roll
                angle = (entry.uas_heading, 0.0, 0.0)
                angles.append(angle)

            # Create a new track in the folder
            trk = kml_flight.newgxtrack(name='Flight Path')
            trk.altitudemode = AltitudeMode.absolute

            # Append flight data
            trk.newwhen(when)
            trk.newgxcoord(coords)
            trk.newgxangle(angles)

            # Set styling
            trk.extrude = 1  # Extend path to ground
            trk.style.linestyle.width = 2
            trk.style.linestyle.color = Color.blue
            trk.iconstyle.icon.href = icon

            for obstacle in MovingObstacle.objects.all():
                obstacle.kml(path=flight_logs, kml=kml_flight, kml_doc=kml_doc)