コード例 #1
0
    def get(self, request):
        kml = Kml(name='AUVSI SUAS LIVE Flight Data')
        kml_mission = kml.newfolder(name='Missions')

        (mission, err) = active_mission()
        if err:
            return err
        MissionConfig.kml_all(kml_mission, [mission])

        kml_flyzone = kml.newfolder(name='Fly Zones')
        FlyZone.kml_all(kml_flyzone)

        parameters = '?sessionid={}'.format(request.COOKIES['sessionid'])
        uri = request.build_absolute_uri(
            '/auvsi_admin/update.kml') + parameters

        netlink = kml.newnetworklink(name="Live Data")
        netlink.link.href = uri
        netlink.link.refreshmode = RefreshMode.oninterval
        netlink.link.refreshinterval = 0.5

        response = HttpResponse(kml.kml())
        response['Content-Type'] = 'application/vnd.google-earth.kml+xml'
        response['Content-Disposition'] = 'attachment; filename=live.kml'
        response['Content-Length'] = str(len(response.content))
        return response
コード例 #2
0
ファイル: fly_zone_test.py プロジェクト: auvsi-suas/interop
 def setUp(self):
     """Creates test data."""
     # Form test set for contains position
     self.testdata_containspos = []
     for test_data in TESTDATA_FLYZONE_CONTAINSPOS:
         # Create the FlyZone
         zone = FlyZone()
         zone.altitude_msl_min = test_data['min_alt']
         zone.altitude_msl_max = test_data['max_alt']
         zone.save()
         for waypoint_id in range(len(test_data['waypoints'])):
             (lat, lon) = test_data['waypoints'][waypoint_id]
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.gps_position = gpos
             apos.altitude_msl = 0
             apos.save()
             wpt = Waypoint()
             wpt.order = waypoint_id
             wpt.position = apos
             wpt.save()
             zone.boundary_pts.add(wpt)
         # Form test set
         test_pos = []
         for pos in test_data['inside_pos']:
             test_pos.append((pos, True))
         for pos in test_data['outside_pos']:
             test_pos.append((pos, False))
         # Store
         self.testdata_containspos.append((zone, test_pos))
コード例 #3
0
ファイル: live_kml.py プロジェクト: auvsi-suas/interop
    def get(self, request):
        kml = Kml(name='AUVSI SUAS LIVE Flight Data')
        kml_mission = kml.newfolder(name='Missions')

        (mission, err) = active_mission()
        if err:
            return err
        MissionConfig.kml_all(kml_mission, [mission])

        kml_flyzone = kml.newfolder(name='Fly Zones')
        FlyZone.kml_all(kml_flyzone)

        parameters = '?sessionid={}'.format(request.COOKIES['sessionid'])
        uri = request.build_absolute_uri(
            '/auvsi_admin/update.kml') + parameters

        netlink = kml.newnetworklink(name="Live Data")
        netlink.link.href = uri
        netlink.link.refreshmode = RefreshMode.oninterval
        netlink.link.refreshinterval = 0.5

        response = HttpResponse(kml.kml())
        response['Content-Type'] = 'application/vnd.google-earth.kml+xml'
        response['Content-Disposition'] = 'attachment; filename=live.kml'
        response['Content-Length'] = str(len(response.content))
        return response
コード例 #4
0
    def test_out_of_bounds(self):
        """Tests the UAS out of bounds method."""
        (zone_details, uas_details) = TESTDATA_FLYZONE_EVALBOUNDS
        # Create FlyZone objects
        zones = []
        for (alt_min, alt_max, wpts) in zone_details:
            zone = FlyZone()
            zone.altitude_msl_min = alt_min
            zone.altitude_msl_max = alt_max
            zone.save()
            for wpt_id in range(len(wpts)):
                (lat, lon) = wpts[wpt_id]
                wpt = Waypoint()
                wpt.order = wpt_id
                wpt.latitude = lat
                wpt.longitude = lon
                wpt.altitude_msl = 0
                wpt.save()
                zone.boundary_pts.add(wpt)
            zone.save()
            zones.append(zone)

        # For each user, validate time out of bounds
        user_id = 0
        epoch = timezone.now().replace(year=1970,
                                       month=1,
                                       day=1,
                                       hour=0,
                                       minute=0,
                                       second=0,
                                       microsecond=0)
        for exp_violations, exp_out_of_bounds_time, log_details in uas_details:
            # Create the logs
            user = User.objects.create_user('testuser%d' % user_id,
                                            '*****@*****.**', 'testpass')
            user_id += 1
            uas_logs = []
            for (lat, lon, alt, timestamp) in log_details:
                log = UasTelemetry()
                log.user = user
                log.latitude = lat
                log.longitude = lon
                log.altitude_msl = alt
                log.uas_heading = 0
                log.save()
                log.timestamp = epoch + datetime.timedelta(seconds=timestamp)
                log.save()
                uas_logs.append(log)
            # Assert out of bounds time matches expected
            num_violations, out_of_bounds_time = \
                FlyZone.out_of_bounds(zones, uas_logs)
            self.assertEqual(num_violations, exp_violations)
            self.assertAlmostEqual(out_of_bounds_time.total_seconds(),
                                   exp_out_of_bounds_time)
コード例 #5
0
 def setUp(self):
     """Creates test data."""
     # Form test set for contains position
     self.testdata_containspos = []
     for test_data in TESTDATA_FLYZONE_CONTAINSPOS:
         # Create the FlyZone
         zone = FlyZone()
         zone.altitude_msl_min = test_data['min_alt']
         zone.altitude_msl_max = test_data['max_alt']
         zone.save()
         for waypoint_id in range(len(test_data['waypoints'])):
             (lat, lon) = test_data['waypoints'][waypoint_id]
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.gps_position = gpos
             apos.altitude_msl = 0
             apos.save()
             wpt = Waypoint()
             wpt.order = waypoint_id
             wpt.position = apos
             wpt.save()
             zone.boundary_pts.add(wpt)
         # Form test set
         test_pos = []
         for pos in test_data['inside_pos']:
             test_pos.append((pos, True))
         for pos in test_data['outside_pos']:
             test_pos.append((pos, False))
         # Store
         self.testdata_containspos.append((zone, test_pos))
コード例 #6
0
ファイル: export_kml.py プロジェクト: resula9/interop
    def get(self, request):
        kml = Kml(name='AUVSI SUAS Flight Data')
        kml_teams = kml.newfolder(name='Teams')
        kml_mission = kml.newfolder(name='Missions')
        users = User.objects.all()
        for user in users:
            # Ignore admins
            if user.is_superuser:
                continue
            UasTelemetry.kml(user=user,
                             logs=UasTelemetry.by_user(user),
                             kml=kml_teams,
                             kml_doc=kml.document)
        MissionConfig.kml_all(kml_mission)
        kml_flyzone = kml.newfolder(name='Fly Zones')
        FlyZone.kml_all(kml_flyzone)

        response = HttpResponse(kml.kml())
        response['Content-Type'] = 'application/vnd.google-earth.kml+xml'
        response['Content-Disposition'] = 'attachment; filename=mission.kml'
        response['Content-Length'] = str(len(response.content))
        return response
コード例 #7
0
ファイル: export_kml.py プロジェクト: auvsi-suas/interop
    def get(self, request):
        kml = Kml(name='AUVSI SUAS Flight Data')
        kml_teams = kml.newfolder(name='Teams')
        kml_mission = kml.newfolder(name='Missions')
        users = User.objects.all()
        for user in users:
            # Ignore admins
            if user.is_superuser:
                continue
            UasTelemetry.kml(user=user,
                             logs=UasTelemetry.by_user(user),
                             kml=kml_teams,
                             kml_doc=kml.document)
        MissionConfig.kml_all(kml_mission)
        kml_flyzone = kml.newfolder(name='Fly Zones')
        FlyZone.kml_all(kml_flyzone)

        response = HttpResponse(kml.kml())
        response['Content-Type'] = 'application/vnd.google-earth.kml+xml'
        response['Content-Disposition'] = 'attachment; filename=mission.kml'
        response['Content-Length'] = str(len(response.content))
        return response
コード例 #8
0
 def test_unicode(self):
     """Tests the unicode method executes."""
     zone = FlyZone()
     zone.altitude_msl_min = 1
     zone.altitude_msl_max = 2
     zone.save()
     for _ in range(3):
         pos = GpsPosition()
         pos.latitude = 10
         pos.longitude = 100
         pos.save()
         apos = AerialPosition()
         apos.altitude_msl = 1000
         apos.gps_position = pos
         apos.save()
         wpt = Waypoint()
         wpt.position = apos
         wpt.order = 10
         wpt.save()
         zone.boundary_pts.add(wpt)
     self.assertTrue(zone.__unicode__())
コード例 #9
0
ファイル: fly_zone_test.py プロジェクト: auvsi-suas/interop
 def test_unicode(self):
     """Tests the unicode method executes."""
     zone = FlyZone()
     zone.altitude_msl_min = 1
     zone.altitude_msl_max = 2
     zone.save()
     for _ in range(3):
         pos = GpsPosition()
         pos.latitude = 10
         pos.longitude = 100
         pos.save()
         apos = AerialPosition()
         apos.altitude_msl = 1000
         apos.gps_position = pos
         apos.save()
         wpt = Waypoint()
         wpt.position = apos
         wpt.order = 10
         wpt.save()
         zone.boundary_pts.add(wpt)
     self.assertTrue(zone.__unicode__())
コード例 #10
0
ファイル: fly_zone_test.py プロジェクト: auvsi-suas/interop
    def test_out_of_bounds(self):
        """Tests the UAS out of bounds method."""
        (zone_details, uas_details) = TESTDATA_FLYZONE_EVALBOUNDS
        # Create FlyZone objects
        zones = []
        for (alt_min, alt_max, wpts) in zone_details:
            zone = FlyZone()
            zone.altitude_msl_min = alt_min
            zone.altitude_msl_max = alt_max
            zone.save()
            for wpt_id in xrange(len(wpts)):
                (lat, lon) = wpts[wpt_id]
                gpos = GpsPosition()
                gpos.latitude = lat
                gpos.longitude = lon
                gpos.save()
                apos = AerialPosition()
                apos.gps_position = gpos
                apos.altitude_msl = 0
                apos.save()
                wpt = Waypoint()
                wpt.order = wpt_id
                wpt.position = apos
                wpt.save()
                zone.boundary_pts.add(wpt)
            zone.save()
            zones.append(zone)

        # For each user, validate time out of bounds
        user_id = 0
        epoch = timezone.now().replace(year=1970,
                                       month=1,
                                       day=1,
                                       hour=0,
                                       minute=0,
                                       second=0,
                                       microsecond=0)
        for exp_violations, exp_out_of_bounds_time, log_details in uas_details:
            # Create the logs
            user = User.objects.create_user('testuser%d' % user_id,
                                            '*****@*****.**', 'testpass')
            user_id += 1
            uas_logs = []
            for (lat, lon, alt, timestamp) in log_details:
                gpos = GpsPosition()
                gpos.latitude = lat
                gpos.longitude = lon
                gpos.save()
                apos = AerialPosition()
                apos.gps_position = gpos
                apos.altitude_msl = alt
                apos.save()
                log = UasTelemetry()
                log.user = user
                log.uas_position = apos
                log.uas_heading = 0
                log.save()
                log.timestamp = epoch + datetime.timedelta(seconds=timestamp)
                log.save()
                uas_logs.append(log)
            # Assert out of bounds time matches expected
            num_violations, out_of_bounds_time = \
                FlyZone.out_of_bounds(zones, uas_logs)
            self.assertEqual(num_violations, exp_violations)
            self.assertAlmostEqual(out_of_bounds_time, exp_out_of_bounds_time)
コード例 #11
0
def generate_feedback(mission_config, user, team_eval):
    """Generates mission feedback for the given team and mission.

    Args:
        mission_config: The mission to evaluate the team against.
        user: The team user object for which to evaluate and provide feedback.
        team_eval: The team evaluation to fill.
    """
    feedback = team_eval.feedback

    # Calculate the total mission clock time.
    missions = MissionClockEvent.missions(user)
    mission_clock_time = datetime.timedelta(seconds=0)
    for mission in missions:
        duration = mission.duration()
        if duration is None:
            team_eval.warnings.append('Infinite mission clock.')
        else:
            mission_clock_time += duration
    feedback.mission_clock_time_sec = mission_clock_time.total_seconds()

    # Calculate total time in air.
    flight_periods = TakeoffOrLandingEvent.flights(user)
    if flight_periods:
        flight_time = reduce(lambda x, y: x + y,
                             [p.duration() for p in flight_periods])
        feedback.flight_time_sec = flight_time.total_seconds()
    else:
        feedback.flight_time_sec = 0
    # Find the user's flights.
    for period in flight_periods:
        if period.duration() is None:
            team_eval.warnings.append('Infinite 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:
        team_eval.warnings.append('No UAS telemetry logs.')

    # Determine interop telemetry rates.
    telem_max, telem_avg = UasTelemetry.rates(user,
                                              flight_periods,
                                              time_period_logs=uas_period_logs)
    if telem_max:
        feedback.uas_telemetry_time_max_sec = telem_max
    if telem_avg:
        feedback.uas_telemetry_time_avg_sec = telem_avg

    # 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 = datetime.timedelta(seconds=0)
    feedback.boundary_violations = 0
    for logs in uas_period_logs:
        bv, bt = FlyZone.out_of_bounds(mission_config.fly_zones.all(), logs)
        feedback.boundary_violations += bv
        out_of_bounds += bt
    feedback.out_of_bounds_time_sec = out_of_bounds.total_seconds()

    # Determine if the uas hit the waypoints.
    feedback.waypoints.extend(
        UasTelemetry.satisfied_waypoints(
            mission_config.home_pos,
            mission_config.mission_waypoints.order_by('order'), uas_logs))

    # Evaluate the object detections.
    user_odlcs = Odlc.objects.filter(user=user).all()
    evaluator = OdlcEvaluator(user_odlcs, mission_config.odlcs.all())
    feedback.odlc.CopyFrom(evaluator.evaluate())

    # Determine collisions with stationary and moving obstacles.
    for obst in mission_config.stationary_obstacles.all():
        obst_eval = feedback.stationary_obstacles.add()
        obst_eval.id = obst.pk
        obst_eval.hit = obst.evaluate_collision_with_uas(uas_logs)
    for obst in mission_config.moving_obstacles.all():
        obst_eval = feedback.moving_obstacles.add()
        obst_eval.id = obst.pk
        obst_eval.hit = obst.evaluate_collision_with_uas(uas_logs)

    # Add judge feedback.
    try:
        judge_feedback = MissionJudgeFeedback.objects.get(
            mission=mission_config.pk, user=user.pk)
        feedback.judge.CopyFrom(judge_feedback.proto())
    except MissionJudgeFeedback.DoesNotExist:
        team_eval.warnings.append('No MissionJudgeFeedback for team.')

    # Sanity check mission time.
    judge_mission_clock = (feedback.judge.flight_time_sec +
                           feedback.judge.post_process_time_sec)
    if abs(feedback.mission_clock_time_sec - judge_mission_clock) > 30:
        team_eval.warnings.append(
            'Mission clock differs between interop and judge.')
コード例 #12
0
def generate_feedback(mission_config, user, team_eval):
    """Generates mission feedback for the given team and mission.

    Args:
        mission_config: The mission to evaluate the team against.
        user: The team user object for which to evaluate and provide feedback.
        team_eval: The team evaluation to fill.
    """
    feedback = team_eval.feedback

    # Calculate the total mission clock time.
    missions = MissionClockEvent.missions(user)
    mission_clock_time = datetime.timedelta(seconds=0)
    for mission in missions:
        duration = mission.duration()
        if duration is None:
            team_eval.warnings.append('Infinite mission clock.')
        else:
            mission_clock_time += duration
    feedback.mission_clock_time_sec = mission_clock_time.total_seconds()

    # Calculate total time in air.
    flight_periods = TakeoffOrLandingEvent.flights(user)
    if flight_periods:
        flight_time = reduce(lambda x, y: x + y, [p.duration()
                                                  for p in flight_periods])
        feedback.flight_time_sec = flight_time.total_seconds()
    else:
        feedback.flight_time_sec = 0
    # Find the user's flights.
    for period in flight_periods:
        if period.duration() is None:
            team_eval.warnings.append('Infinite 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:
        team_eval.warnings.append('No UAS telemetry logs.')

    # Determine interop telemetry rates.
    telem_max, telem_avg = UasTelemetry.rates(user,
                                              flight_periods,
                                              time_period_logs=uas_period_logs)
    if telem_max:
        feedback.uas_telemetry_time_max_sec = telem_max
    if telem_avg:
        feedback.uas_telemetry_time_avg_sec = telem_avg

    # 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 = datetime.timedelta(seconds=0)
    feedback.boundary_violations = 0
    for logs in uas_period_logs:
        bv, bt = FlyZone.out_of_bounds(mission_config.fly_zones.all(), logs)
        feedback.boundary_violations += bv
        out_of_bounds += bt
    feedback.out_of_bounds_time_sec = out_of_bounds.total_seconds()

    # Determine if the uas hit the waypoints.
    feedback.waypoints.extend(UasTelemetry.satisfied_waypoints(
        mission_config.home_pos, mission_config.mission_waypoints.order_by(
            'order'), uas_logs))

    # Evaluate the targets.
    user_targets = Target.objects.filter(user=user).all()
    evaluator = TargetEvaluator(user_targets, mission_config.targets.all())
    feedback.target.CopyFrom(evaluator.evaluate())

    # Determine collisions with stationary and moving obstacles.
    for obst in mission_config.stationary_obstacles.all():
        obst_eval = feedback.stationary_obstacles.add()
        obst_eval.id = obst.pk
        obst_eval.hit = obst.evaluate_collision_with_uas(uas_logs)
    for obst in mission_config.moving_obstacles.all():
        obst_eval = feedback.moving_obstacles.add()
        obst_eval.id = obst.pk
        obst_eval.hit = obst.evaluate_collision_with_uas(uas_logs)

    # Add judge feedback.
    try:
        judge_feedback = MissionJudgeFeedback.objects.get(
            mission=mission_config.pk,
            user=user.pk)
        feedback.judge.CopyFrom(judge_feedback.proto())
    except MissionJudgeFeedback.DoesNotExist:
        team_eval.warnings.append('No MissionJudgeFeedback for team.')

    # Sanity check mission time.
    judge_mission_clock = (
        feedback.judge.flight_time_sec + feedback.judge.post_process_time_sec)
    if abs(feedback.mission_clock_time_sec - judge_mission_clock) > 30:
        team_eval.warnings.append(
            'Mission clock differs between interop and judge.')
コード例 #13
0
def create_sample_mission(superuser):
    """Creates a sample mission.

    Args:
        superuser: A superuser account to create mission under.
    Returns:
        MissionConfig for the created mission.
    """
    mission = MissionConfig()

    gpos = GpsPosition(latitude=38.145103, longitude=-76.427856)
    gpos.save()
    mission.home_pos = gpos

    gpos = GpsPosition(latitude=38.145111, longitude=-76.427861)
    gpos.save()
    mission.emergent_last_known_pos = gpos

    gpos = GpsPosition(latitude=38.145111, longitude=-76.427861)
    gpos.save()
    mission.off_axis_odlc_pos = gpos

    gpos = GpsPosition(latitude=38.1458416666667, longitude=-76.426375)
    gpos.save()
    mission.air_drop_pos = gpos

    # All foreign keys must be defined before the first save.
    # All many-to-many must be defined after the first save.
    mission.save()

    bounds = FlyZone(altitude_msl_min=100, altitude_msl_max=750)
    bounds.save()
    # yapf: disable
    pts = [(38.1462694444444, -76.4281638888889),
           (38.1516250000000, -76.4286833333333),
           (38.1518888888889, -76.4314666666667),
           (38.1505944444444, -76.4353611111111),
           (38.1475666666667, -76.4323416666667),
           (38.1446666666667, -76.4329472222222),
           (38.1432555555556, -76.4347666666667),
           (38.1404638888889, -76.4326361111111),
           (38.1407194444444, -76.4260138888889),
           (38.1437611111111, -76.4212055555556),
           (38.1473472222222, -76.4232111111111),
           (38.1461305555556, -76.4266527777778)]
    # yapf: enable
    for ix, (lat, lon) in enumerate(pts):
        wpt = Waypoint(latitude=lat,
                       longitude=lon,
                       altitude_msl=0,
                       order=ix + 1)
        wpt.save()
        bounds.boundary_pts.add(wpt)
    bounds.save()
    mission.fly_zones.add(bounds)

    # yapf: disable
    pts = [(38.146689, -76.426475, 150,
            750), (38.142914, -76.430297, 300,
                   300), (38.149504, -76.433110, 100,
                          750), (38.148711, -76.429061, 300, 750),
           (38.144203, -76.426155, 50, 400), (38.146003, -76.430733, 225, 500)]
    # yapf: enable
    for lat, lon, radius, height in pts:
        obst = StationaryObstacle(latitude=lat,
                                  longitude=lon,
                                  cylinder_radius=radius,
                                  cylinder_height=height)
        obst.save()
        mission.stationary_obstacles.add(obst)

    # yapf: disable
    pts = [(38.1446916666667, -76.4279944444445, 200),
           (38.1461944444444, -76.4237138888889, 300),
           (38.1438972222222, -76.4225500000000, 400),
           (38.1417722222222, -76.4251083333333, 400),
           (38.1453500000000, -76.4286750000000, 300),
           (38.1508972222222, -76.4292972222222, 300),
           (38.1514944444444, -76.4313833333333, 300),
           (38.1505333333333, -76.4341750000000, 300),
           (38.1479472222222, -76.4316055555556, 200),
           (38.1443333333333, -76.4322888888889, 200),
           (38.1433166666667, -76.4337111111111, 300),
           (38.1410944444444, -76.4321555555556, 400),
           (38.1415777777778, -76.4252472222222, 400),
           (38.1446083333333, -76.4282527777778, 200)]
    # yapf: enable
    for ix, (lat, lon, alt) in enumerate(pts):
        wpt = Waypoint(latitude=lat,
                       longitude=lon,
                       altitude_msl=alt,
                       order=ix + 1)
        wpt.save()
        mission.mission_waypoints.add(wpt)

    # yapf: disable
    pts = [(38.1444444444444, -76.4280916666667),
           (38.1459444444444, -76.4237944444445),
           (38.1439305555556, -76.4227444444444),
           (38.1417138888889, -76.4253805555556),
           (38.1412111111111, -76.4322361111111),
           (38.1431055555556, -76.4335972222222),
           (38.1441805555556, -76.4320111111111),
           (38.1452611111111, -76.4289194444444),
           (38.1444444444444, -76.4280916666667)]
    # yapf: enable
    for ix, (lat, lon) in enumerate(pts):
        wpt = Waypoint(latitude=lat,
                       longitude=lon,
                       altitude_msl=0,
                       order=ix + 1)
        wpt.save()
        mission.search_grid_points.add(wpt)

    gpos = GpsPosition(latitude=38.143844, longitude=-76.426469)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.N,
                shape=interop_api_pb2.Odlc.STAR,
                shape_color=interop_api_pb2.Odlc.RED,
                alphanumeric='A',
                alphanumeric_color=interop_api_pb2.Odlc.WHITE)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.141872, longitude=-76.426183)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.NE,
                shape=interop_api_pb2.Odlc.CROSS,
                shape_color=interop_api_pb2.Odlc.BLUE,
                alphanumeric='I',
                alphanumeric_color=interop_api_pb2.Odlc.BLACK)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.142828, longitude=-76.427644)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.E,
                shape=interop_api_pb2.Odlc.QUARTER_CIRCLE,
                shape_color=interop_api_pb2.Odlc.YELLOW,
                alphanumeric='R',
                alphanumeric_color=interop_api_pb2.Odlc.ORANGE)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.144925, longitude=-76.425100)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.SE,
                shape=interop_api_pb2.Odlc.CIRCLE,
                shape_color=interop_api_pb2.Odlc.BROWN,
                alphanumeric='V',
                alphanumeric_color=interop_api_pb2.Odlc.RED)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.146747, longitude=-76.422131)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.S,
                shape=interop_api_pb2.Odlc.TRAPEZOID,
                shape_color=interop_api_pb2.Odlc.WHITE,
                alphanumeric='E',
                alphanumeric_color=interop_api_pb2.Odlc.GRAY)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.144097, longitude=-76.431089)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.SW,
                shape=interop_api_pb2.Odlc.SQUARE,
                shape_color=interop_api_pb2.Odlc.GREEN,
                alphanumeric='H',
                alphanumeric_color=interop_api_pb2.Odlc.BLUE)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.144878, longitude=-76.423681)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.W,
                shape=interop_api_pb2.Odlc.RECTANGLE,
                shape_color=interop_api_pb2.Odlc.PURPLE,
                alphanumeric='I',
                alphanumeric_color=interop_api_pb2.Odlc.GREEN)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.142819, longitude=-76.432375)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.NW,
                shape=interop_api_pb2.Odlc.SEMICIRCLE,
                shape_color=interop_api_pb2.Odlc.ORANGE,
                alphanumeric='C',
                alphanumeric_color=interop_api_pb2.Odlc.YELLOW)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.141639, longitude=-76.429347)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.N,
                shape=interop_api_pb2.Odlc.TRIANGLE,
                shape_color=interop_api_pb2.Odlc.BLACK,
                alphanumeric='L',
                alphanumeric_color=interop_api_pb2.Odlc.PURPLE)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.142478, longitude=-76.424967)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.STANDARD,
                location=gpos,
                orientation=interop_api_pb2.Odlc.NE,
                shape=interop_api_pb2.Odlc.PENTAGON,
                shape_color=interop_api_pb2.Odlc.GRAY,
                alphanumeric='E',
                alphanumeric_color=interop_api_pb2.Odlc.BROWN)
    odlc.save()
    mission.odlcs.add(odlc)

    gpos = GpsPosition(latitude=38.143411, longitude=-76.424489)
    gpos.save()
    odlc = Odlc(mission=mission,
                user=superuser,
                odlc_type=interop_api_pb2.Odlc.EMERGENT,
                location=gpos,
                description='Randy the backpacker.')
    odlc.save()
    mission.odlcs.add(odlc)

    mission.save()
    return mission