示例#1
0
    def create_moving_obstacle(self, waypoints):
        """Create a new MovingObstacle model.

        Args:
            waypoints: List of (lat, lon, alt) tuples

        Returns:
            Saved MovingObstacle
        """
        obstacle = MovingObstacle(speed_avg=40, sphere_radius=100)
        obstacle.save()

        for num, waypoint in enumerate(waypoints):
            (lat, lon, alt) = waypoint

            gps = GpsPosition(latitude=lat, longitude=lon)
            gps.save()

            pos = AerialPosition(gps_position=gps, altitude_msl=alt)
            pos.save()

            waypoint = Waypoint(order=num, position=pos)
            waypoint.save()

            obstacle.waypoints.add(waypoint)

        obstacle.save()
        return obstacle
示例#2
0
    def setUp(self):
        """Populates an active mission to test a cached view."""
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()
        self.pos = pos

        obst = StationaryObstacle()
        obst.gps_position = pos
        obst.cylinder_radius = 10
        obst.cylinder_height = 10
        obst.save()
        self.obst = obst

        config = MissionConfig()
        config.is_active = True
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_target_pos = pos
        config.air_drop_pos = pos
        config.save()
        self.config = config
        config.stationary_obstacles.add(obst)
        config.save()

        self.login_url = reverse('auvsi_suas:login')
        self.obst_url = reverse('auvsi_suas:obstacles')
        self.clear_cache_url = reverse('auvsi_suas:clear_cache')
示例#3
0
    def create_uas_logs(self, user, entries):
        """Create a list of uas telemetry logs.

        Args:
            user: User to create logs for.
            entries: List of (lat, lon, alt) tuples for each entry.

        Returns:
            List of UasTelemetry objects
        """
        ret = []

        for (lat, lon, alt) in entries:
            pos = GpsPosition()
            pos.latitude = lat
            pos.longitude = lon
            pos.save()
            apos = AerialPosition()
            apos.altitude_msl = alt
            apos.gps_position = pos
            apos.save()
            log = UasTelemetry()
            log.user = user
            log.uas_position = apos
            log.uas_heading = 0
            log.save()
            ret.append(log)

        return ret
示例#4
0
 def test_get_waypoint_travel_time(self):
     """Tests travel time calc."""
     test_spds = [1, 10, 100, 500]
     for (lon2, lat2, lon1, lat1, dist_km) in TESTDATA_COMPETITION_DIST:
         dist_ft = units.kilometers_to_feet(dist_km)
         for speed in test_spds:
             speed_fps = units.knots_to_feet_per_second(speed)
             time = dist_ft / speed_fps
             gpos1 = GpsPosition()
             gpos1.latitude = lat1
             gpos1.longitude = lon1
             gpos1.save()
             apos1 = AerialPosition()
             apos1.gps_position = gpos1
             apos1.altitude_msl = 0
             apos1.save()
             wpt1 = Waypoint()
             wpt1.position = apos1
             gpos2 = GpsPosition()
             gpos2.latitude = lat2
             gpos2.longitude = lon2
             gpos2.save()
             apos2 = AerialPosition()
             apos2.gps_position = gpos2
             apos2.altitude_msl = 0
             apos2.save()
             wpt2 = Waypoint()
             wpt2.position = apos2
             waypoints = [wpt1, wpt2]
             obstacle = MovingObstacle()
             obstacle.speed_avg = speed
             self.assertTrue(self.eval_travel_time(
                 obstacle.get_waypoint_travel_time(waypoints, 0, 1), time))
示例#5
0
    def create_logs(self,
                    user,
                    num=10,
                    start=None,
                    delta=None,
                    altitude=100,
                    heading=90):
        if start is None:
            start = timezone.now()
        if delta is None:
            delta = datetime.timedelta(seconds=1)

        logs = []

        for i in xrange(num):
            gps = GpsPosition(latitude=38 + 0.001 * i,
                              longitude=-78 + 0.001 * i)
            gps.save()

            pos = AerialPosition(gps_position=gps, altitude_msl=altitude)
            pos.save()

            log = UasTelemetry(user=user,
                               uas_position=pos,
                               uas_heading=heading)
            log.save()
            log.timestamp = start + i * delta
            log.save()
            logs.append(log)

        return logs
示例#6
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))
示例#7
0
    def test_put_one(self):
        """PUT update one field without affecting others."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user,
                   target_type=TargetType.standard,
                   location=l,
                   orientation=Orientation.s,
                   shape=Shape.square,
                   background_color=Color.white,
                   alphanumeric='ABC',
                   alphanumeric_color=Color.black,
                   description='Test target')
        t.save()

        data = {'shape': 'circle'}

        response = self.client.put(
            targets_id_url(args=[t.pk]),
            data=json.dumps(data))
        self.assertEqual(200, response.status_code)

        t.refresh_from_db()
        t.location.refresh_from_db()
        self.assertEqual(self.user, t.user)
        self.assertEqual(TargetType.standard, t.target_type)
        self.assertEqual(38, t.location.latitude)
        self.assertEqual(-76, t.location.longitude)
        self.assertEqual(Orientation.s, t.orientation)
        self.assertEqual(Shape.circle, t.shape)
        self.assertEqual(Color.white, t.background_color)
        self.assertEqual('ABC', t.alphanumeric)
        self.assertEqual(Color.black, t.alphanumeric_color)
        self.assertEqual('Test target', t.description)
示例#8
0
    def test_duplicate_unequal(self):
        """Tests the duplicate function for nonequal positions."""
        gps1 = GpsPosition(latitude=0, longitude=0)
        gps2 = GpsPosition(latitude=1, longitude=0)
        gps3 = GpsPosition(latitude=0, longitude=1)

        self.assertFalse(gps1.duplicate(gps2))
        self.assertFalse(gps1.duplicate(gps3))
示例#9
0
    def setUp(self):
        self.user = User.objects.create_user('testuser', '*****@*****.**',
                                             'testpass')
        self.user.save()

        # Create an active mission.
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()
        config = MissionConfig()
        config.is_active = True
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_target_pos = pos
        config.air_drop_pos = pos
        config.save()

        # Add a couple of stationary obstacles
        obst = self.create_stationary_obstacle(lat=38.142233,
                                               lon=-76.434082,
                                               radius=300,
                                               height=500)
        config.stationary_obstacles.add(obst)

        obst = self.create_stationary_obstacle(lat=38.442233,
                                               lon=-76.834082,
                                               radius=100,
                                               height=750)
        config.stationary_obstacles.add(obst)

        # And a couple of moving obstacles
        obst = self.create_moving_obstacle([
            # (lat,     lon,        alt)
            (38.142233, -76.434082, 300),
            (38.141878, -76.425198, 700),
        ])
        config.moving_obstacles.add(obst)

        obst = self.create_moving_obstacle([
            # (lat,     lon,        alt)
            (38.145405, -76.428310, 100),
            (38.146582, -76.424099, 200),
            (38.144662, -76.427634, 300),
            (38.147729, -76.419185, 200),
            (38.147573, -76.420832, 100),
            (38.148522, -76.419507, 750),
        ])
        config.moving_obstacles.add(obst)

        config.save()

        # Login
        response = self.client.post(login_url, {
            'username': '******',
            'password': '******'
        })
        self.assertEqual(200, response.status_code)
示例#10
0
    def test_unicode(self):
        """Tests the unicode method executes."""
        gps = GpsPosition(latitude=10, longitude=100)
        gps.save()

        pos = AerialPosition(gps_position=gps, altitude_msl=100)
        pos.save()

        pos.__unicode__()
 def test_unicode(self):
     """Tests the unicode method executes."""
     pos = GpsPosition(latitude=100, longitude=200)
     pos.save()
     obst = StationaryObstacle(gps_position=pos,
                               cylinder_radius=10,
                               cylinder_height=100)
     obst.save()
     self.assertTrue(obst.__unicode__())
示例#12
0
    def test_similar_classifications(self):
        """Tests similar classification counts are computed correctly."""
        # Test equal standard targets.
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()
        t1 = Target(user=self.user,
                    target_type=TargetType.standard,
                    location=l,
                    orientation=Orientation.s,
                    shape=Shape.square,
                    background_color=Color.white,
                    alphanumeric='ABC',
                    alphanumeric_color=Color.black,
                    description='Test target',
                    autonomous=True)
        t1.save()
        t2 = Target(user=self.user,
                    target_type=TargetType.standard,
                    location=l,
                    orientation=Orientation.s,
                    shape=Shape.square,
                    background_color=Color.white,
                    alphanumeric='ABC',
                    alphanumeric_color=Color.black,
                    description='Test other target',
                    autonomous=True)
        t2.save()
        self.assertAlmostEqual(1.0, t1.similar_classifications(t2))

        # Test unequal standard targets.
        t1.alphanumeric = 'DEF'
        t1.alphanumeric_color = Color.blue
        t1.save()
        self.assertAlmostEqual(3.0 / 5.0, t1.similar_classifications(t2))
        t1.shape = Shape.circle
        t1.background_color = Color.orange
        t1.save()
        self.assertAlmostEqual(1.0 / 5.0, t1.similar_classifications(t2))

        # Test different types.
        t1.target_type = TargetType.off_axis
        t1.save()
        self.assertAlmostEqual(0, t1.similar_classifications(t2))

        # Test off_axis is same as standard.
        t2.target_type = TargetType.off_axis
        t2.alphanumeric = 'DEF'
        t2.save()
        self.assertAlmostEqual(2.0 / 5.0, t1.similar_classifications(t2))

        # Test emergent type is always 1.
        t1.target_type = TargetType.emergent
        t1.save()
        t2.target_type = TargetType.emergent
        t2.save()
        self.assertAlmostEqual(1.0, t1.similar_classifications(t2))
示例#13
0
    def setUp(self):
        """Create the obstacles for testing."""
        # Obstacle with no waypoints
        obst_no_wpt = MovingObstacle()
        obst_no_wpt.speed_avg = 1
        obst_no_wpt.sphere_radius = 1
        obst_no_wpt.save()
        self.obst_no_wpt = obst_no_wpt

        # Obstacle with single waypoint
        self.single_wpt_lat = 40
        self.single_wpt_lon = 76
        self.single_wpt_alt = 100
        obst_single_wpt = MovingObstacle()
        obst_single_wpt.speed_avg = 1
        obst_single_wpt.sphere_radius = 1
        obst_single_wpt.save()
        single_gpos = GpsPosition()
        single_gpos.latitude = self.single_wpt_lat
        single_gpos.longitude = self.single_wpt_lon
        single_gpos.save()
        single_apos = AerialPosition()
        single_apos.gps_position = single_gpos
        single_apos.altitude_msl = self.single_wpt_alt
        single_apos.save()
        single_wpt = Waypoint()
        single_wpt.position = single_apos
        single_wpt.order = 1
        single_wpt.save()
        obst_single_wpt.waypoints.add(single_wpt)
        self.obst_single_wpt = obst_single_wpt

        # Obstacles with predefined path
        self.obstacles = []
        for path in TESTDATA_MOVOBST_PATHS:
            cur_obst = MovingObstacle()
            cur_obst.speed_avg = 68
            cur_obst.sphere_radius = 10
            cur_obst.save()
            for pt_id in range(len(path)):
                (lat, lon, alt) = path[pt_id]
                cur_gpos = GpsPosition()
                cur_gpos.latitude = lat
                cur_gpos.longitude = lon
                cur_gpos.save()
                cur_apos = AerialPosition()
                cur_apos.gps_position = cur_gpos
                cur_apos.altitude_msl = alt
                cur_apos.save()
                cur_wpt = Waypoint()
                cur_wpt.position = cur_apos
                cur_wpt.order = pt_id
                cur_wpt.save()
                cur_obst.waypoints.add(cur_wpt)
            cur_obst.save()
            self.obstacles.append(cur_obst)
示例#14
0
 def create_log_element(self, lat, lon, alt, user, log_time):
     pos = GpsPosition(latitude=lat, longitude=lon)
     pos.save()
     apos = AerialPosition(gps_position=pos, altitude_msl=alt)
     apos.save()
     log = UasTelemetry(user=user, uas_position=apos, uas_heading=100, )
     log.save()
     log.timestamp = log_time
     log.save()
     return log
示例#15
0
 def create_log_element(self, timestamp, user, lat, lon, alt, heading):
     pos = GpsPosition(latitude=lat, longitude=lon)
     pos.save()
     apos = AerialPosition(gps_position=pos, altitude_msl=alt)
     apos.save()
     log = UasTelemetry(timestamp=timezone.now(),
                        user=user,
                        uas_position=apos,
                        uas_heading=heading)
     log.save()
     return log
示例#16
0
 def test_contains_pos(self):
     """Tests the contains_pos method."""
     for (zone, test_pos) in self.testdata_containspos:
         for ((lat, lon, alt), inside) in test_pos:
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.altitude_msl = alt
             apos.gps_position = gpos
             self.assertEqual(zone.contains_pos(apos), inside)
示例#17
0
    def test_put_invalid_json(self):
        """PUT request body must be valid JSON."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user, target_type=TargetType.standard, location=l)
        t.save()

        response = self.client.put(
            targets_id_url(args=[t.pk]),
            data="latitude=76",
            content_type='multipart/form-data')
        self.assertEqual(400, response.status_code)
示例#18
0
    def test_put_partial_clear_location(self):
        """PUT can't clear location with only one of lat/lon."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user, target_type=TargetType.standard, location=l)
        t.save()

        data = {'latitude': None}

        response = self.client.put(
            targets_id_url(args=[t.pk]),
            data=json.dumps(data))
        self.assertEqual(400, response.status_code)
示例#19
0
    def create_config(self):
        """Creates a dummy config for testing."""
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()

        config = MissionConfig()
        config.is_active = False
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_target_pos = pos
        config.air_drop_pos = pos
        return config
示例#20
0
    def test_json(self):
        """Test target JSON."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user,
                   target_type=TargetType.standard,
                   location=l,
                   orientation=Orientation.s,
                   shape=Shape.square,
                   background_color=Color.white,
                   alphanumeric='ABC',
                   alphanumeric_color=Color.black,
                   description='Test target',
                   autonomous=True)
        t.save()

        d = t.json()

        self.assertIn('id', d)
        self.assertEqual(self.user.pk, d['user'])
        self.assertEqual('standard', d['type'])
        self.assertEqual(38, d['latitude'])
        self.assertEqual(-76, d['longitude'])
        self.assertEqual('s', d['orientation'])
        self.assertEqual('square', d['shape'])
        self.assertEqual('white', d['background_color'])
        self.assertEqual('ABC', d['alphanumeric'])
        self.assertEqual('black', d['alphanumeric_color'])
        self.assertEqual('Test target', d['description'])
        self.assertEqual(True, d['autonomous'])
        self.assertNotIn('thumbnail_approved', d)

        d = t.json(is_superuser=True)
        self.assertIn('description_approved', d)
        self.assertIn('thumbnail_approved', d)

        t.description_approved = True
        t.thumbnail_approved = True
        t.actionable_override = True
        t.save()
        d = t.json(is_superuser=True)
        self.assertEqual(True, d['description_approved'])
        self.assertEqual(None, d['thumbnail'])
        self.assertEqual(True, d['thumbnail_approved'])
        self.assertEqual(True, d['actionable_override'])
示例#21
0
    def setUp(self):
        """Setup a single active mission to test live kml with."""
        super(TestGenerateLiveKMLNoFixture, self).setUp()

        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()

        config = MissionConfig()
        config.is_active = True
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_target_pos = pos
        config.air_drop_pos = pos
        config.save()
        self.config = config
示例#22
0
 def test_contains_many_pos(self):
     """Tests the contains_many_pos method."""
     for (zone, test_pos) in self.testdata_containspos:
         aerial_pos_list = []
         expected_results = []
         for ((lat, lon, alt), inside) in test_pos:
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.altitude_msl = alt
             apos.gps_position = gpos
             aerial_pos_list.append(apos)
             expected_results.append(inside)
         self.assertEqual(
             zone.contains_many_pos(aerial_pos_list), expected_results)
示例#23
0
    def test_put_clear_location(self):
        """PUT clear location by clearing lat and lon."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user, target_type=TargetType.standard, location=l)
        t.save()

        data = {'latitude': None, 'longitude': None}

        response = self.client.put(
            targets_id_url(args=[t.pk]),
            data=json.dumps(data))
        self.assertEqual(200, response.status_code)

        t.refresh_from_db()
        self.assertEqual(None, t.location)
示例#24
0
    def post(self, request):
        try:
            data = json.loads(request.body)
        except ValueError:
            return HttpResponseBadRequest('Request body is not valid JSON.')

        # Target type is required.
        if 'type' not in data:
            return HttpResponseBadRequest('Target type required.')

        latitude = data.get('latitude')
        longitude = data.get('longitude')

        # Require zero or both of latitude and longitude.
        if (latitude is not None and longitude is None) or \
            (latitude is None and longitude is not None):
            return HttpResponseBadRequest(
                'Either none or both of latitude and longitude required.')

        try:
            data = normalize_data(data)
        except ValueError as e:
            return HttpResponseBadRequest(str(e))

        l = None
        if latitude is not None and longitude is not None:
            l = GpsPosition(latitude=data['latitude'],
                            longitude=data['longitude'])
            l.save()

        # Use the dictionary get() method to default non-existent values to None.
        t = Target(user=request.user,
                   target_type=data['type'],
                   location=l,
                   orientation=data.get('orientation'),
                   shape=data.get('shape'),
                   background_color=data.get('background_color'),
                   alphanumeric=data.get('alphanumeric', ''),
                   alphanumeric_color=data.get('alphanumeric_color'),
                   description=data.get('description', ''),
                   autonomous=data.get('autonomous', False))
        t.save()

        return JsonResponse(
            t.json(is_superuser=request.user.is_superuser),
            status=201)
示例#25
0
    def test_put_update_location(self):
        """PUT updating location only requires one of lat/lon."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user, target_type=TargetType.standard, location=l)
        t.save()

        data = {'latitude': 39}

        response = self.client.put(
            targets_id_url(args=[t.pk]),
            data=json.dumps(data))
        self.assertEqual(200, response.status_code)

        t.refresh_from_db()
        t.location.refresh_from_db()
        self.assertEqual(39, t.location.latitude)
        self.assertEqual(-76, t.location.longitude)
示例#26
0
 def waypoints_from_data(self, waypoints_data):
     """Converts tuples of lat/lon/alt to a waypoint."""
     waypoints = []
     for i, waypoint in enumerate(waypoints_data):
         (lat, lon, alt) = waypoint
         pos = GpsPosition()
         pos.latitude = lat
         pos.longitude = lon
         pos.save()
         apos = AerialPosition()
         apos.altitude_msl = alt
         apos.gps_position = pos
         apos.save()
         wpt = Waypoint()
         wpt.position = apos
         wpt.order = i
         wpt.save()
         waypoints.append(wpt)
     return waypoints
示例#27
0
    def create_data(self):
        """Create a basic sample dataset."""
        self.user1 = User.objects.create_user('user1', '*****@*****.**',
                                              'testpass')
        self.user1.save()

        self.user2 = User.objects.create_user('user2', '*****@*****.**',
                                              'testpass')
        self.user2.save()

        # user1 is on mission
        event = MissionClockEvent(user=self.user1,
                                  team_on_clock=True,
                                  team_on_timeout=False)
        event.save()
        # user1 is flying
        event = TakeoffOrLandingEvent(user=self.user1, uas_in_air=True)
        event.save()

        # user2 has landed
        event = TakeoffOrLandingEvent(user=self.user2, uas_in_air=True)
        event.save()
        event = TakeoffOrLandingEvent(user=self.user2, uas_in_air=False)
        event.save()

        # user2 is active
        self.timestamp = timezone.now()

        gps = GpsPosition(latitude=38.6462, longitude=-76.2452)
        gps.save()

        pos = AerialPosition(gps_position=gps, altitude_msl=0)
        pos.save()

        self.telem = UasTelemetry(user=self.user2,
                                  uas_position=pos,
                                  uas_heading=90)
        self.telem.save()
        self.telem.timestamp = dateutil.parser.parse(
            u'2016-10-01T00:00:00.0+00:00')

        self.telem.save()
示例#28
0
    def create_stationary_obstacle(self, lat, lon, radius, height):
        """Create a new StationaryObstacle model.

        Args:
            lat: Latitude of centroid
            lon: Longitude of centroid
            radius: Cylinder radius
            height: Cylinder height

        Returns:
            Saved StationaryObstacle
        """
        gps = GpsPosition(latitude=lat, longitude=lon)
        gps.save()

        obstacle = StationaryObstacle(gps_position=gps,
                                      cylinder_radius=radius,
                                      cylinder_height=height)
        obstacle.save()
        return obstacle
示例#29
0
    def test_valid(self):
        """Test creating a valid target."""
        with open(os.path.join(settings.BASE_DIR,
                               'auvsi_suas/fixtures/testdata/S.jpg')) as f:
            thumb = SimpleUploadedFile('thumb.jpg', f.read())

        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Target(user=self.user,
                   target_type=TargetType.standard,
                   location=l,
                   orientation=Orientation.s,
                   shape=Shape.square,
                   background_color=Color.white,
                   alphanumeric='ABC',
                   alphanumeric_color=Color.black,
                   description='Test target',
                   thumbnail=thumb)
        t.save()
示例#30
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__())
示例#31
0
    def test_put_clear_shape(self):
        """PUT clear a field with None."""
        l = GpsPosition(latitude=38, longitude=-76)
        l.save()

        t = Odlc(mission=self.mission,
                 user=self.user,
                 odlc_type=interop_api_pb2.Odlc.STANDARD,
                 location=l,
                 orientation=interop_api_pb2.Odlc.S,
                 shape=interop_api_pb2.Odlc.SQUARE,
                 shape_color=interop_api_pb2.Odlc.WHITE,
                 alphanumeric='ABC',
                 alphanumeric_color=interop_api_pb2.Odlc.BLACK,
                 description='Test odlc')
        t.save()

        updated = {
            'mission': self.mission.pk,
            'type': 'STANDARD',
        }

        response = self.client.put(odlcs_id_url(args=[t.pk]),
                                   data=json.dumps(updated))
        self.assertEqual(200, response.status_code)

        t.refresh_from_db()
        self.assertEqual(self.user, t.user)
        self.assertEqual(interop_api_pb2.Odlc.STANDARD, t.odlc_type)
        self.assertIsNone(t.location)
        self.assertIsNone(t.orientation)
        self.assertIsNone(t.shape)
        self.assertIsNone(t.shape_color)
        self.assertEqual('', t.alphanumeric)
        self.assertIsNone(t.alphanumeric_color)
        self.assertEqual('', t.description)
示例#32
0
    def evaluate_inputs(self, io_list):
        for (lon1, lat1, alt1, lon2, lat2, alt2, dist) in io_list:
            gps1 = GpsPosition(latitude=lat1, longitude=lon1)
            gps1.save()

            gps2 = GpsPosition(latitude=lat2, longitude=lon2)
            gps2.save()

            pos1 = AerialPosition(gps_position=gps1, altitude_msl=alt1)
            pos1.save()

            pos2 = AerialPosition(gps_position=gps2, altitude_msl=alt2)
            pos2.save()

            wpt1 = Waypoint(position=pos1)
            wpt2 = Waypoint(position=pos2)

            self.assertDistanceEqual(wpt1, wpt2, dist)
示例#33
0
    def test_evaluate_collision_with_uas(self):
        """Tests the collision with UAS method."""
        # Get test data
        user = User.objects.create_user('testuser', '*****@*****.**',
                                        'testpass')
        user.save()
        testdata = TESTDATA_MOVOBST_EVALCOLLISION
        (obst_rad, obst_speed, obst_pos, log_details) = testdata
        # Create the obstacle
        obst = MovingObstacle()
        obst.speed_avg = obst_speed
        obst.sphere_radius = obst_rad
        obst.save()
        for pos_id in xrange(len(obst_pos)):
            (lat, lon, alt) = obst_pos[pos_id]
            gpos = GpsPosition()
            gpos.latitude = lat
            gpos.longitude = lon
            gpos.save()
            apos = AerialPosition()
            apos.gps_position = gpos
            apos.altitude_msl = alt
            apos.save()
            wpt = Waypoint()
            wpt.order = pos_id
            wpt.position = apos
            wpt.save()
            obst.waypoints.add(wpt)
        obst.save()
        # Create sets of logs
        epoch = timezone.now().replace(year=1970,
                                       month=1,
                                       day=1,
                                       hour=0,
                                       minute=0,
                                       second=0,
                                       microsecond=0)
        inside_logs = []
        outside_logs = []
        for (time_sec, inside_pos, outside_pos) in log_details:
            log_time = epoch + datetime.timedelta(seconds=time_sec)
            logs_pos = [(inside_pos, inside_logs), (outside_pos, outside_logs)]
            for (positions, log_list) in logs_pos:
                for (lat, lon, alt) in positions:
                    log = self.create_log(lat, lon, alt, user, log_time)
                    log_list.append(log)

        # Assert the obstacle correctly computes collisions
        log_collisions = [(True, inside_logs), (False, outside_logs)]
        for (inside, logs) in log_collisions:
            self.assertEqual(obst.evaluate_collision_with_uas(logs), inside)
            for log in logs:
                self.assertEqual(obst.evaluate_collision_with_uas([log]),
                                 inside)
示例#34
0
 def test_contains_pos(self):
     """Tests the inside obstacle method."""
     # Form the test obstacle
     pos = GpsPosition(latitude=TESTDATA_STATOBST_CONTAINSPOS_OBJ[0],
                       longitude=TESTDATA_STATOBST_CONTAINSPOS_OBJ[1])
     pos.save()
     obst = StationaryObstacle(
         gps_position=pos,
         cylinder_radius=TESTDATA_STATOBST_CONTAINSPOS_OBJ[2],
         cylinder_height=TESTDATA_STATOBST_CONTAINSPOS_OBJ[3])
     # Run test points against obstacle
     test_data = [(TESTDATA_STATOBST_CONTAINSPOS_INSIDE, True),
                  (TESTDATA_STATOBST_CONTAINSPOS_OUTSIDE, False)]
     for (cur_data, cur_contains) in test_data:
         for (lat, lon, alt) in cur_data:
             pos = GpsPosition(latitude=lat, longitude=lon)
             pos.save()
             apos = AerialPosition(gps_position=pos, altitude_msl=alt)
             self.assertEqual(obst.contains_pos(apos), cur_contains)
示例#35
0
    def setUp(self):
        self.user = User.objects.create_user('testuser', '*****@*****.**',
                                             'testpass')
        self.user.save()

        # Create an active mission.
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()
        config = MissionConfig()
        config.is_active = True
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_odlc_pos = pos
        config.air_drop_pos = pos
        config.save()

        # Add a couple of stationary obstacles
        obst = self.create_stationary_obstacle(
            lat=38.142233, lon=-76.434082, radius=300, height=500)
        config.stationary_obstacles.add(obst)

        obst = self.create_stationary_obstacle(
            lat=38.442233, lon=-76.834082, radius=100, height=750)
        config.stationary_obstacles.add(obst)

        # And a couple of moving obstacles
        obst = self.create_moving_obstacle([
            # (lat,     lon,        alt)
            (38.142233, -76.434082, 300),
            (38.141878, -76.425198, 700),
        ])
        config.moving_obstacles.add(obst)

        obst = self.create_moving_obstacle([
            # (lat,     lon,        alt)
            (38.145405, -76.428310, 100),
            (38.146582, -76.424099, 200),
            (38.144662, -76.427634, 300),
            (38.147729, -76.419185, 200),
            (38.147573, -76.420832, 100),
            (38.148522, -76.419507, 750),
        ])
        config.moving_obstacles.add(obst)

        config.save()

        # Login
        response = self.client.post(
            login_url, {'username': '******',
                        'password': '******'})
        self.assertEqual(200, response.status_code)
示例#36
0
 def test_contains_pos(self):
     """Tests the contains_pos method."""
     for (zone, test_pos) in self.testdata_containspos:
         for ((lat, lon, alt), inside) in test_pos:
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.altitude_msl = alt
             apos.gps_position = gpos
             self.assertEqual(zone.contains_pos(apos), inside)
示例#37
0
    def test_evaluate_collision_with_uas(self):
        """Tests the collision with UAS method."""
        # Create testing data
        user = User.objects.create_user('testuser', '*****@*****.**',
                                        'testpass')
        user.save()

        (cyl_details, inside_pos,
         outside_pos) = TESTDATA_STATOBST_EVALCOLLISION
        (cyl_lat, cyl_lon, cyl_height, cyl_rad) = cyl_details

        gpos = GpsPosition(latitude=cyl_lat, longitude=cyl_lon)
        gpos.save()

        obst = StationaryObstacle(gps_position=gpos,
                                  cylinder_radius=cyl_rad,
                                  cylinder_height=cyl_height)
        obst.save()

        inside_logs = []
        outside_logs = []
        logs_to_create = [
            (inside_pos, inside_logs), (outside_pos, outside_logs)
        ]

        for (positions, log_list) in logs_to_create:
            for (lat, lon, alt) in positions:
                gpos = GpsPosition(latitude=lat, longitude=lon)
                gpos.save()
                apos = AerialPosition(gps_position=gpos, altitude_msl=alt)
                apos.save()
                log = UasTelemetry(user=user, uas_position=apos, uas_heading=0)
                log.save()
                log_list.append(log)
        # Assert collisions correctly evaluated
        collisions = [(inside_logs, True), (outside_logs, False)]
        for (log_list, inside) in collisions:
            self.assertEqual(
                obst.evaluate_collision_with_uas(log_list), inside)
            for log in log_list:
                self.assertEqual(
                    obst.evaluate_collision_with_uas([log]), inside)
示例#38
0
    def create_config(self):
        """Creates a dummy config for testing."""
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()

        config = MissionConfig()
        config.is_active = False
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_odlc_pos = pos
        config.air_drop_pos = pos
        return config
    def setUp(self):
        super(TestTakeoffOrLandingEventModel, self).setUp()

        # Mission
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 100
        pos.save()
        apos = AerialPosition()
        apos.latitude = 10
        apos.longitude = 100
        apos.altitude_msl = 1000
        apos.save()
        wpt = Waypoint()
        wpt.latitude = 10
        wpt.longitude = 100
        wpt.altitude_msl = 1000
        wpt.order = 10
        wpt.save()
        self.mission = MissionConfig()
        self.mission.home_pos = pos
        self.mission.lost_comms_pos = pos
        self.mission.emergent_last_known_pos = pos
        self.mission.off_axis_odlc_pos = pos
        self.mission.map_center_pos = pos
        self.mission.map_height_ft = 1
        self.mission.air_drop_pos = pos
        self.mission.ugv_drive_pos = pos
        self.mission.save()
        self.mission.mission_waypoints.add(wpt)
        self.mission.search_grid_points.add(wpt)
        self.mission.save()

        # Mission 2
        self.mission2 = MissionConfig()
        self.mission2.home_pos = pos
        self.mission2.lost_comms_pos = pos
        self.mission2.emergent_last_known_pos = pos
        self.mission2.off_axis_odlc_pos = pos
        self.mission2.map_center_pos = pos
        self.mission2.map_height_ft = 1
        self.mission2.air_drop_pos = pos
        self.mission2.ugv_drive_pos = pos
        self.mission2.save()
        self.mission2.mission_waypoints.add(wpt)
        self.mission2.search_grid_points.add(wpt)
        self.mission2.save()

        self.ten_minutes = datetime.timedelta(minutes=10)
示例#40
0
    def setUp(self):
        """Setup a single mission to test live kml with."""
        super(TestGenerateLiveKMLNoFixture, self).setUp()

        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 10
        pos.save()

        config = MissionConfig()
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_odlc_pos = pos
        config.air_drop_pos = pos
        config.save()
        self.config = config
示例#41
0
 def test_contains_many_pos(self):
     """Tests the contains_many_pos method."""
     for (zone, test_pos) in self.testdata_containspos:
         aerial_pos_list = []
         expected_results = []
         for ((lat, lon, alt), inside) in test_pos:
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.altitude_msl = alt
             apos.gps_position = gpos
             aerial_pos_list.append(apos)
             expected_results.append(inside)
         self.assertEqual(zone.contains_many_pos(aerial_pos_list),
                          expected_results)
示例#42
0
    def setUp(self):
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 100
        pos.save()
        wpt = Waypoint()
        wpt.order = 10
        wpt.latitude = 10
        wpt.longitude = 100
        wpt.altitude_msl = 1000
        wpt.save()
        config = MissionConfig()
        config.home_pos = pos
        config.lost_comms_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_odlc_pos = pos
        config.map_center_pos = pos
        config.map_height_ft = 1
        config.air_drop_pos = pos
        config.ugv_drive_pos = pos
        config.save()
        config.mission_waypoints.add(wpt)
        config.search_grid_points.add(wpt)
        config.save()

        user = User.objects.create_user('user', '*****@*****.**', 'pass')

        self.feedback = MissionJudgeFeedback(
            mission=config,
            user=user,
            flight_time=datetime.timedelta(seconds=1),
            post_process_time=datetime.timedelta(seconds=2),
            used_timeout=True,
            min_auto_flight_time=True,
            safety_pilot_takeovers=3,
            out_of_bounds=6,
            unsafe_out_of_bounds=7,
            things_fell_off_uas=False,
            crashed=False,
            air_drop_accuracy=interop_admin_api_pb2.MissionJudgeFeedback.
            WITHIN_05_FT,
            ugv_drove_to_location=False,
            operational_excellence_percent=9)
        self.feedback.save()
示例#43
0
 def waypoints_from_data(self, waypoints_data):
     """Converts tuples of lat/lon/alt to a waypoint."""
     waypoints = []
     for i, waypoint in enumerate(waypoints_data):
         (lat, lon, alt) = waypoint
         pos = GpsPosition()
         pos.latitude = lat
         pos.longitude = lon
         pos.save()
         apos = AerialPosition()
         apos.altitude_msl = alt
         apos.gps_position = pos
         apos.save()
         wpt = Waypoint()
         wpt.position = apos
         wpt.order = i
         wpt.save()
         waypoints.append(wpt)
     return waypoints
示例#44
0
    def setUp(self):
        # Mission
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 100
        pos.save()
        wpt = Waypoint()
        wpt.order = 10
        wpt.latitude = 10
        wpt.longitude = 100
        wpt.altitude_msl = 0
        wpt.save()
        self.mission = MissionConfig()
        self.mission.home_pos = pos
        self.mission.lost_comms_pos = pos
        self.mission.emergent_last_known_pos = pos
        self.mission.off_axis_odlc_pos = pos
        self.mission.map_center_pos = pos
        self.mission.map_height_ft = 1
        self.mission.air_drop_pos = pos
        self.mission.ugv_drive_pos = pos
        self.mission.save()
        self.mission.mission_waypoints.add(wpt)
        self.mission.search_grid_points.add(wpt)
        self.mission.save()
        # Mission 2
        self.mission2 = MissionConfig()
        self.mission2.home_pos = pos
        self.mission2.lost_comms_pos = pos
        self.mission2.emergent_last_known_pos = pos
        self.mission2.off_axis_odlc_pos = pos
        self.mission2.map_center_pos = pos
        self.mission2.map_height_ft = 1
        self.mission2.air_drop_pos = pos
        self.mission2.ugv_drive_pos = pos
        self.mission2.save()
        self.mission2.mission_waypoints.add(wpt)
        self.mission2.search_grid_points.add(wpt)
        self.mission2.save()

        self.user = User.objects.create_user('testuser', '*****@*****.**',
                                             'testpass')
示例#45
0
    def setUp(self):
        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()
        config = MissionConfig()
        config.home_pos = pos
        config.emergent_last_known_pos = pos
        config.off_axis_odlc_pos = pos
        config.air_drop_pos = pos
        config.save()
        config.mission_waypoints.add(wpt)
        config.search_grid_points.add(wpt)
        config.save()

        user = User.objects.create_user('user', '*****@*****.**', 'pass')

        self.feedback = MissionJudgeFeedback(
            mission=config,
            user=user,
            flight_time=datetime.timedelta(seconds=1),
            post_process_time=datetime.timedelta(seconds=2),
            used_timeout=True,
            min_auto_flight_time=True,
            safety_pilot_takeovers=3,
            waypoints_captured=5,
            out_of_bounds=6,
            unsafe_out_of_bounds=7,
            things_fell_off_uas=False,
            crashed=False,
            air_delivery_accuracy_ft=8,
            operational_excellence_percent=9)
        self.feedback.save()
示例#46
0
 def test_unicode(self):
     """Tests the unicode method executes."""
     obst = MovingObstacle()
     obst.speed_avg = 10
     obst.sphere_radius = 100
     obst.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()
         obst.waypoints.add(wpt)
     self.assertTrue(obst.__unicode__())
示例#47
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__())
示例#48
0
 def test_contains_pos(self):
     """Tests the inside obstacle method."""
     # Form the test obstacle
     obst = MovingObstacle()
     obst.sphere_radius = TESTDATA_MOVOBST_CONTAINSPOS_OBJ[2]
     # Run test points against obstacle
     test_data = [(TESTDATA_MOVOBST_CONTAINSPOS_INSIDE, True),
                  (TESTDATA_MOVOBST_CONTAINSPOS_OUTSIDE, False)]
     for (cur_data, cur_contains) in test_data:
         for (lat, lon, alt) in cur_data:
             gpos = GpsPosition()
             gpos.latitude = lat
             gpos.longitude = lon
             gpos.save()
             apos = AerialPosition()
             apos.gps_position = gpos
             apos.altitude_msl = alt
             self.assertEqual(
                 obst.contains_pos(TESTDATA_MOVOBST_CONTAINSPOS_OBJ[0],
                                   TESTDATA_MOVOBST_CONTAINSPOS_OBJ[1],
                                   TESTDATA_MOVOBST_CONTAINSPOS_OBJ[3],
                                   apos), cur_contains)
示例#49
0
 def test_unicode(self):
     """Tests the unicode method executes."""
     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()
     config = MissionConfig()
     config.home_pos = pos
     config.emergent_last_known_pos = pos
     config.off_axis_target_pos = pos
     config.air_drop_pos = pos
     config.save()
     config.mission_waypoints.add(wpt)
     config.search_grid_points.add(wpt)
     config.save()
     self.assertTrue(config.__unicode__())
示例#50
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 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.total_seconds(),
                                   exp_out_of_bounds_time)
示例#51
0
from auvsi_suas.models.gps_position import GpsPosition
from auvsi_suas.models.mission_config import MissionConfig

# Print all mission objects.
print MissionConfig.objects.all()

# Create and save a GPS position.
gpos = GpsPosition(latitudel=38.145335, longitude=-76.427512)
gpos.save()
示例#52
0
 def test_get_waypoint_travel_time(self):
     """Tests travel time calc."""
     test_spds = [1, 10, 100, 500]
     for (lon2, lat2, lon1, lat1, dist_km) in TESTDATA_COMPETITION_DIST:
         dist_ft = units.kilometers_to_feet(dist_km)
         for speed in test_spds:
             speed_fps = units.knots_to_feet_per_second(speed)
             time = dist_ft / speed_fps
             gpos1 = GpsPosition()
             gpos1.latitude = lat1
             gpos1.longitude = lon1
             gpos1.save()
             apos1 = AerialPosition()
             apos1.gps_position = gpos1
             apos1.altitude_msl = 0
             apos1.save()
             wpt1 = Waypoint()
             wpt1.position = apos1
             gpos2 = GpsPosition()
             gpos2.latitude = lat2
             gpos2.longitude = lon2
             gpos2.save()
             apos2 = AerialPosition()
             apos2.gps_position = gpos2
             apos2.altitude_msl = 0
             apos2.save()
             wpt2 = Waypoint()
             wpt2.position = apos2
             waypoints = [wpt1, wpt2]
             obstacle = MovingObstacle()
             obstacle.speed_avg = speed
             self.assertTrue(
                 self.eval_travel_time(
                     obstacle.get_waypoint_travel_time(waypoints, 0, 1),
                     time))
示例#53
0
    def setUp(self):
        """Setup the test case."""
        super(TestTargetEvaluator, self).setUp()
        self.maxDiff = None
        self.user = User.objects.create_user('user', '*****@*****.**',
                                             'pass')

        l1 = GpsPosition(latitude=38, longitude=-76)
        l1.save()
        l2 = GpsPosition(latitude=38.0003, longitude=-76)
        l2.save()
        l3 = GpsPosition(latitude=-38, longitude=76)
        l3.save()

        event = MissionClockEvent(user=self.user,
                                  team_on_clock=True,
                                  team_on_timeout=False)
        event.save()

        event = TakeoffOrLandingEvent(user=self.user, uas_in_air=True)
        event.save()

        # A target worth full points.
        self.submit1 = Target(user=self.user,
                              target_type=TargetType.standard,
                              location=l1,
                              orientation=Orientation.s,
                              shape=Shape.square,
                              background_color=Color.white,
                              alphanumeric='ABC',
                              alphanumeric_color=Color.black,
                              description='Submit test target 1',
                              autonomous=True,
                              thumbnail_approved=True)
        self.submit1.save()
        self.real1 = Target(user=self.user,
                            target_type=TargetType.standard,
                            location=l1,
                            orientation=Orientation.s,
                            shape=Shape.square,
                            background_color=Color.white,
                            alphanumeric='ABC',
                            alphanumeric_color=Color.black,
                            description='Real target 1')
        self.real1.save()

        event = MissionClockEvent(user=self.user,
                                  team_on_clock=False,
                                  team_on_timeout=False)
        event.save()

        # A target worth less than full points.
        self.submit2 = Target(user=self.user,
                              target_type=TargetType.standard,
                              location=l1,
                              orientation=Orientation.n,
                              shape=Shape.circle,
                              background_color=Color.white,
                              # alphanumeric set below
                              alphanumeric_color=Color.black,
                              description='Submit test target 2',
                              autonomous=False,
                              thumbnail_approved=True)
        self.submit2.save()
        self.real2 = Target(user=self.user,
                            target_type=TargetType.standard,
                            location=l2,
                            orientation=Orientation.s,
                            shape=Shape.triangle,
                            background_color=Color.white,
                            alphanumeric='ABC',
                            alphanumeric_color=Color.black,
                            description='Real test target 2')
        self.real2.save()

        # A target worth no points, so unmatched.
        self.submit3 = Target(user=self.user,
                              target_type=TargetType.standard,
                              location=l1,
                              orientation=Orientation.nw,
                              shape=Shape.pentagon,
                              background_color=Color.gray,
                              alphanumeric='XYZ',
                              alphanumeric_color=Color.orange,
                              description='Incorrect description',
                              autonomous=False,
                              thumbnail_approved=True)
        self.submit3.save()
        self.real3 = Target(user=self.user,
                            target_type=TargetType.standard,
                            orientation=Orientation.e,
                            shape=Shape.semicircle,
                            background_color=Color.yellow,
                            alphanumeric='LMN',
                            # alphanumeric_color set below
                            location=l3,
                            description='Test target 3')
        self.real3.save()

        # Targets without approved image may still match.
        self.submit4 = Target(user=self.user,
                              target_type=TargetType.emergent,
                              location=l1,
                              description='Test target 4',
                              autonomous=False,
                              thumbnail_approved=False)
        self.submit4.save()
        self.real4 = Target(user=self.user,
                            target_type=TargetType.emergent,
                            location=l1,
                            description='Test target 4')
        self.real4.save()

        # A target without location worth fewer points.
        self.submit5 = Target(user=self.user,
                              target_type=TargetType.standard,
                              orientation=Orientation.n,
                              shape=Shape.trapezoid,
                              background_color=Color.purple,
                              alphanumeric='PQR',
                              alphanumeric_color=Color.blue,
                              description='Test target 5',
                              autonomous=False,
                              thumbnail_approved=True)
        self.submit5.save()
        self.real5 = Target(user=self.user,
                            target_type=TargetType.standard,
                            location=l1,
                            orientation=Orientation.n,
                            shape=Shape.trapezoid,
                            background_color=Color.purple,
                            alphanumeric='PQR',
                            alphanumeric_color=Color.blue,
                            description='Test target 5')
        self.real5.save()

        event = TakeoffOrLandingEvent(user=self.user, uas_in_air=False)
        event.save()

        # submit2 updated after landing.
        self.submit2.alphanumeric = 'ABC'
        self.submit2.save()

        self.submit3.alphanumeric_color = Color.yellow
        self.submit3.save()

        self.submitted_targets = [self.submit5, self.submit4, self.submit3,
                                  self.submit2, self.submit1]
        self.real_targets = [self.real1, self.real2, self.real3, self.real4,
                             self.real5]
        self.real_matched_targets = [self.real1, self.real2, self.real4,
                                     self.real5]
示例#54
0
    def setUp(self):
        """Create the obstacles for testing."""
        # Obstacle with no waypoints
        obst_no_wpt = MovingObstacle()
        obst_no_wpt.speed_avg = 1
        obst_no_wpt.sphere_radius = 1
        obst_no_wpt.save()
        self.obst_no_wpt = obst_no_wpt

        # Obstacle with single waypoint
        self.single_wpt_lat = 40
        self.single_wpt_lon = 76
        self.single_wpt_alt = 100
        obst_single_wpt = MovingObstacle()
        obst_single_wpt.speed_avg = 1
        obst_single_wpt.sphere_radius = 1
        obst_single_wpt.save()
        single_gpos = GpsPosition()
        single_gpos.latitude = self.single_wpt_lat
        single_gpos.longitude = self.single_wpt_lon
        single_gpos.save()
        single_apos = AerialPosition()
        single_apos.gps_position = single_gpos
        single_apos.altitude_msl = self.single_wpt_alt
        single_apos.save()
        single_wpt = Waypoint()
        single_wpt.position = single_apos
        single_wpt.order = 1
        single_wpt.save()
        obst_single_wpt.waypoints.add(single_wpt)
        self.obst_single_wpt = obst_single_wpt

        # Obstacles with predefined path
        self.obstacles = []
        for path in TESTDATA_MOVOBST_PATHS:
            cur_obst = MovingObstacle()
            cur_obst.speed_avg = 68
            cur_obst.sphere_radius = 10
            cur_obst.save()
            for pt_id in range(len(path)):
                (lat, lon, alt) = path[pt_id]
                cur_gpos = GpsPosition()
                cur_gpos.latitude = lat
                cur_gpos.longitude = lon
                cur_gpos.save()
                cur_apos = AerialPosition()
                cur_apos.gps_position = cur_gpos
                cur_apos.altitude_msl = alt
                cur_apos.save()
                cur_wpt = Waypoint()
                cur_wpt.position = cur_apos
                cur_wpt.order = pt_id
                cur_wpt.save()
                cur_obst.waypoints.add(cur_wpt)
            cur_obst.save()
            self.obstacles.append(cur_obst)
示例#55
0
    def test_satisfied_waypoints(self):
        """Tests the evaluation of waypoints method."""
        # Create mission config
        gpos = GpsPosition()
        gpos.latitude = 10
        gpos.longitude = 10
        gpos.save()

        waypoints = self.waypoints_from_data([
            (38, -76, 100),
            (39, -77, 200),
            (40, -78, 0),
        ])

        # Only first is valid.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 40, -78, 600, 0),
            (2, 37, -75, 40, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1, score_ratio=0,
                               closest_for_mission_ft=170),
            WaypointEvaluation(id=2, score_ratio=0, closest_for_mission_ft=600)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # First and last are valid.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 40, -78, 600, 0),
            (2, 40, -78, 40, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1, score_ratio=0,
                               closest_for_mission_ft=170),
            WaypointEvaluation(id=2,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Hit all.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 39, -77, 180, 0),
            (2, 40, -78, 40, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1,
                               score_ratio=0.8,
                               closest_for_scored_approach_ft=20,
                               closest_for_mission_ft=20),
            WaypointEvaluation(id=2,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Only hit the first waypoint on run one, hit all on run two.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 40, -78, 600, 0),
            (2, 37, -75, 40, 0),
            # Run two:
            (3, 38, -76, 140, 0),
            (4, 39, -77, 180, 0),
            (5, 40, -78, 40, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1,
                               score_ratio=0.8,
                               closest_for_scored_approach_ft=20,
                               closest_for_mission_ft=20),
            WaypointEvaluation(id=2,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Hit all on run one, only hit the first waypoint on run two.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 39, -77, 180, 0),
            (2, 40, -78, 40, 0),
            # Run two:
            (3, 38, -76, 140, 0),
            (4, 40, -78, 600, 0),
            (5, 37, -75, 40, 0)
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1,
                               score_ratio=0.8,
                               closest_for_scored_approach_ft=20,
                               closest_for_mission_ft=20),
            WaypointEvaluation(id=2,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Keep flying after hitting all waypoints.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 39, -77, 180, 0),
            (2, 40, -78, 40, 0),
            (3, 30.1, -78.1, 100, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40),
            WaypointEvaluation(id=1,
                               score_ratio=0.8,
                               closest_for_scored_approach_ft=20,
                               closest_for_mission_ft=20),
            WaypointEvaluation(id=2,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=40)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Hit all in first run, but second is higher scoring.
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),
            (1, 39, -77, 180, 0),
            (2, 40, -78, 60, 0),
            # Run two:
            (3, 38, -76, 100, 0),
            (4, 39, -77, 200, 0),
            (5, 40, -78, 110, 0)
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=1,
                               closest_for_scored_approach_ft=0,
                               closest_for_mission_ft=0),
            WaypointEvaluation(id=1,
                               score_ratio=1,
                               closest_for_scored_approach_ft=0,
                               closest_for_mission_ft=0),
            WaypointEvaluation(id=2, score_ratio=0, closest_for_mission_ft=60)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Restart waypoint path in the middle, use path in between points.
        waypoints = self.waypoints_from_data([
            (38, -76, 100),
            (39, -77, 200),
            (40, -78, 0),
        ])
        logs = self.create_uas_logs([
            (0, 38, -76, 140, 0),  # Use
            (1, 39, -77, 180, 0),  # Use
            # Restart:
            (2, 38, -76, 70, 0),
            (3, 39, -77, 150, 0),
            (4, 40, -78, 10, 0),  # Use
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.6,
                               closest_for_scored_approach_ft=40,
                               closest_for_mission_ft=30),
            WaypointEvaluation(id=1,
                               score_ratio=0.8,
                               closest_for_scored_approach_ft=20,
                               closest_for_mission_ft=20),
            WaypointEvaluation(id=2,
                               score_ratio=0.9,
                               closest_for_scored_approach_ft=10,
                               closest_for_mission_ft=10)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))

        # Sanity check waypoint scoring with interpolation.
        waypoints = self.waypoints_from_data([
            (38, -76, 70),
            (38, -76, 110),
        ])
        logs = self.create_uas_logs([
            (0, 38, -76, 0, 0),
            (1, 38, -76, 200, 0),
        ])
        expect = [
            WaypointEvaluation(id=0,
                               score_ratio=0.9,
                               closest_for_scored_approach_ft=10,
                               closest_for_mission_ft=10),
            WaypointEvaluation(id=1,
                               score_ratio=0.9,
                               closest_for_scored_approach_ft=10,
                               closest_for_mission_ft=10)
        ]
        self.assertSatisfiedWaypoints(
            expect, UasTelemetry.satisfied_waypoints(gpos, waypoints, logs))
示例#56
0
    def test_satisfied_waypoints(self):
        """Tests the evaluation of waypoints method."""
        # Create mission config
        gpos = GpsPosition()
        gpos.latitude = 10
        gpos.longitude = 10
        gpos.save()

        # Create waypoints for testing.
        waypoints = self.waypoints_from_data([(38, -76, 100), (39, -77, 200), (
            40, -78, 0)])

        # Create UAS telemetry logs

        # Only first is valid.
        entries = [(38, -76, 140), (40, -78, 600), (37, -75, 40)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0,
                                     closest_for_mission_ft=460785.17),
                  WaypointEvaluation(id=2,
                                     score_ratio=0)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # First and last are valid, but missed second, so third doesn't count.
        entries = [(38, -76, 140), (40, -78, 600), (40, -78, 40)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0,
                                     closest_for_mission_ft=460785.03),
                  WaypointEvaluation(id=2,
                                     score_ratio=0)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Hit all.
        entries = [(38, -76, 140), (39, -77, 180), (40, -78, 40)]
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0.8,
                                     closest_for_scored_approach_ft=20,
                                     closest_for_mission_ft=20),
                  WaypointEvaluation(id=2,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40)]
        logs = self.create_uas_logs(self.user, entries)
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Only hit the first waypoint on run one, hit all on run two.
        entries = [(38, -76, 140),
                   (40, -78, 600),
                   (37, -75, 40),
                   # Run two:
                   (38, -76, 140),
                   (39, -77, 180),
                   (40, -78, 40)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0.8,
                                     closest_for_scored_approach_ft=20,
                                     closest_for_mission_ft=20),
                  WaypointEvaluation(id=2,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Hit all on run one, only hit the first waypoint on run two.
        entries = [(38, -76, 140),
                   (39, -77, 180),
                   (40, -78, 40),
                   # Run two:
                   (38, -76, 140),
                   (40, -78, 600),
                   (37, -75, 40)]
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0.8,
                                     closest_for_scored_approach_ft=20,
                                     closest_for_mission_ft=20),
                  WaypointEvaluation(id=2,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40)]
        logs = self.create_uas_logs(self.user, entries)
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Keep flying after hitting all waypoints.
        entries = [(38, -76, 140), (39, -77, 180), (40, -78, 40),
                   (30.1, -78.1, 100)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40),
                  WaypointEvaluation(id=1,
                                     score_ratio=0.8,
                                     closest_for_scored_approach_ft=20,
                                     closest_for_mission_ft=20),
                  WaypointEvaluation(id=2,
                                     score_ratio=0.6,
                                     closest_for_scored_approach_ft=40,
                                     closest_for_mission_ft=40)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Hit all in first run, but second is higher scoring.
        entries = [(38, -76, 140),
                   (39, -77, 180),
                   (40, -78, 60),
                   # Run two:
                   (38, -76, 100),
                   (39, -77, 200),
                   (40, -78, 110)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=1,
                                     closest_for_scored_approach_ft=0,
                                     closest_for_mission_ft=0),
                  WaypointEvaluation(id=1,
                                     score_ratio=1,
                                     closest_for_scored_approach_ft=0,
                                     closest_for_mission_ft=0),
                  WaypointEvaluation(id=2,
                                     score_ratio=0,
                                     closest_for_mission_ft=60)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))

        # Restart waypoint path in the middle.
        waypoints = self.waypoints_from_data([(38, -76, 100), (39, -77, 200), (
            40, -78, 0)])
        entries = [(38, -76, 140),
                   (39, -77, 180),
                   # Restart:
                   (38, -76, 70),
                   (39, -77, 150),
                   (40, -78, 10)]
        logs = self.create_uas_logs(self.user, entries)
        expect = [WaypointEvaluation(id=0,
                                     score_ratio=0.7,
                                     closest_for_scored_approach_ft=30,
                                     closest_for_mission_ft=30),
                  WaypointEvaluation(id=1,
                                     score_ratio=0.5,
                                     closest_for_scored_approach_ft=50,
                                     closest_for_mission_ft=20),
                  WaypointEvaluation(id=2,
                                     score_ratio=0.9,
                                     closest_for_scored_approach_ft=10,
                                     closest_for_mission_ft=10)]
        self.assertSatisfiedWaypoints(expect, UasTelemetry.satisfied_waypoints(
            gpos, waypoints, logs))
示例#57
0
    def create_data(self):
        """Create a basic sample dataset."""
        self.user1 = User.objects.create_user('user1', '*****@*****.**',
                                              'testpass')
        self.user1.save()

        self.user2 = User.objects.create_user('user2', '*****@*****.**',
                                              'testpass')
        self.user2.save()

        # Mission
        pos = GpsPosition()
        pos.latitude = 10
        pos.longitude = 100
        pos.save()
        wpt = Waypoint()
        wpt.order = 10
        wpt.latitude = 10
        wpt.longitude = 100
        wpt.altitude_msl = 1000
        wpt.save()
        self.mission = MissionConfig()
        self.mission.home_pos = pos
        self.mission.lost_comms_pos = pos
        self.mission.emergent_last_known_pos = pos
        self.mission.off_axis_odlc_pos = pos
        self.mission.map_center_pos = pos
        self.mission.map_height_ft = 1
        self.mission.air_drop_pos = pos
        self.mission.ugv_drive_pos = pos
        self.mission.save()
        self.mission.mission_waypoints.add(wpt)
        self.mission.search_grid_points.add(wpt)
        self.mission.save()

        # user1 is flying
        event = TakeoffOrLandingEvent(user=self.user1,
                                      mission=self.mission,
                                      uas_in_air=True)
        event.save()

        # user2 has landed
        event = TakeoffOrLandingEvent(user=self.user2,
                                      mission=self.mission,
                                      uas_in_air=True)
        event.save()
        event = TakeoffOrLandingEvent(user=self.user2,
                                      mission=self.mission,
                                      uas_in_air=False)
        event.save()

        # user2 is active
        self.timestamp = timezone.now()

        self.telem = UasTelemetry(user=self.user2,
                                  latitude=38.6462,
                                  longitude=-76.2452,
                                  altitude_msl=0,
                                  uas_heading=90)
        self.telem.save()
        self.telem.timestamp = dateutil.parser.parse(
            u'2016-10-01T00:00:00.0+00:00')

        self.telem.save()
示例#58
0
    def post(self, request):
        try:
            data = json.loads(request.body)
        except ValueError:
            return HttpResponseBadRequest('Request body is not valid JSON.')

        # Must be a json dictionary.
        if not isinstance(data, dict):
            return HttpResponseBadRequest('Request body not a JSON dict.')

        # Odlc type is required.
        if 'type' not in data:
            return HttpResponseBadRequest('Odlc type required.')

        # Team id can only be specified if superuser.
        user = request.user
        if 'team_id' in data:
            if request.user.is_superuser:
                user = User.objects.get(username=data['team_id'])
            else:
                return HttpResponseForbidden(
                    'Non-admin users cannot send team_id')

        latitude = data.get('latitude')
        longitude = data.get('longitude')

        # Require zero or both of latitude and longitude.
        if (latitude is not None and longitude is None) or \
            (latitude is None and longitude is not None):
            return HttpResponseBadRequest(
                'Either none or both of latitude and longitude required.')

        # Cannot submit JSON with actionable_override if not superuser.
        if 'actionable_override' in data and not request.user.is_superuser:
            return HttpResponseForbidden(
                'Non-admin users cannot submit actionable override.')

        try:
            data = normalize_data(data)
        except ValueError as e:
            return HttpResponseBadRequest(str(e))

        l = None
        if latitude is not None and longitude is not None:
            l = GpsPosition(latitude=data['latitude'],
                            longitude=data['longitude'])
            l.save()

        # Use the dictionary get() method to default non-existent values to None.
        t = Odlc(user=user,
                 odlc_type=data['type'],
                 location=l,
                 orientation=data.get('orientation'),
                 shape=data.get('shape'),
                 background_color=data.get('background_color'),
                 alphanumeric=data.get('alphanumeric', ''),
                 alphanumeric_color=data.get('alphanumeric_color'),
                 description=data.get('description', ''),
                 autonomous=data.get('autonomous', False),
                 actionable_override=data.get('actionable_override', False))
        t.save()

        return JsonResponse(t.json(is_superuser=request.user.is_superuser),
                            status=201)
示例#59
0
    def put(self, request, pk):
        try:
            odlc = find_odlc(request, int(pk))
        except Odlc.DoesNotExist:
            return HttpResponseNotFound('Odlc %s not found' % pk)
        except ValueError as e:
            return HttpResponseForbidden(str(e))

        try:
            data = json.loads(request.body)
        except ValueError:
            return HttpResponseBadRequest('Request body is not valid JSON.')

        # Must be a json dictionary.
        if not isinstance(data, dict):
            return HttpResponseBadRequest('Request body not a JSON dict.')

        # Cannot submit JSON with actionable_override if not superuser.
        if 'actionable_override' in data and not request.user.is_superuser:
            return HttpResponseForbidden(
                'Non-admin users cannot submit actionable override.')

        try:
            data = normalize_data(data)
        except ValueError as e:
            return HttpResponseBadRequest(str(e))

        # We update any of the included values, except id and user
        if 'type' in data:
            odlc.odlc_type = data['type']
        if 'orientation' in data:
            odlc.orientation = data['orientation']
        if 'shape' in data:
            odlc.shape = data['shape']
        if 'background_color' in data:
            odlc.background_color = data['background_color']
        if 'alphanumeric' in data:
            odlc.alphanumeric = data['alphanumeric']
        if 'alphanumeric_color' in data:
            odlc.alphanumeric_color = data['alphanumeric_color']
        if 'description' in data:
            odlc.description = data['description']
        if 'autonomous' in data:
            odlc.autonomous = data['autonomous']
        if 'actionable_override' in data:
            odlc.actionable_override = data['actionable_override']

        # Location is special because it is in a GpsPosition model

        # If lat/lon exist and are None, the user wants to clear them.
        # If they exist and are not None, the user wants to update/add them.
        # If they don't exist, the user wants to leave them alone.
        clear_lat = False
        clear_lon = False
        update_lat = False
        update_lon = False

        if 'latitude' in data:
            if data['latitude'] is None:
                clear_lat = True
            else:
                update_lat = True

        if 'longitude' in data:
            if data['longitude'] is None:
                clear_lon = True
            else:
                update_lon = True

        if (clear_lat and not clear_lon) or (not clear_lat and clear_lon):
            # Location must be cleared entirely, we can't clear just lat or
            # just lon.
            return HttpResponseBadRequest(
                'Only none or both of latitude and longitude can be cleared.')

        if clear_lat and clear_lon:
            odlc.location = None
        elif update_lat or update_lon:
            if odlc.location is not None:
                # We can directly update individual components
                if update_lat:
                    odlc.location.latitude = data['latitude']
                if update_lon:
                    odlc.location.longitude = data['longitude']
                odlc.location.save()
            else:
                # We need a new GpsPosition, this requires both lat and lon
                if not update_lat or not update_lon:
                    return HttpResponseBadRequest(
                        'Either none or both of latitude and longitude required.'
                    )

                l = GpsPosition(latitude=data['latitude'],
                                longitude=data['longitude'])
                l.save()
                odlc.location = l

        odlc.description_approved = None
        if not request.user.is_superuser:
            odlc.update_last_modified()
        odlc.save()

        return JsonResponse(odlc.json(is_superuser=request.user.is_superuser))
示例#60
0
    def test_satisfied_waypoints(self):
        """Tests the evaluation of waypoints method."""
        # Create mission config
        gpos = GpsPosition()
        gpos.latitude = 10
        gpos.longitude = 10
        gpos.save()
        config = MissionConfig()
        config.home_pos = gpos
        config.emergent_last_known_pos = gpos
        config.off_axis_target_pos = gpos
        config.air_drop_pos = gpos
        config.save()

        # Create waypoints for config
        waypoints = [(38, -76, 100), (39, -77, 200), (40, -78, 0)]
        for i, waypoint in enumerate(waypoints):
            (lat, lon, alt) = waypoint
            pos = GpsPosition()
            pos.latitude = lat
            pos.longitude = lon
            pos.save()
            apos = AerialPosition()
            apos.altitude_msl = alt
            apos.gps_position = pos
            apos.save()
            wpt = Waypoint()
            wpt.position = apos
            wpt.order = i
            wpt.save()
            config.mission_waypoints.add(wpt)
        config.save()

        # Create UAS telemetry logs
        user = User.objects.create_user('testuser', '*****@*****.**',
                                        'testpass')

        # Only first is valid.
        entries = [(38, -76, 140), (40, -78, 600), (37, -75, 40)]
        expect = ({0: 40}, {0: 0.6, 1: 0.0, 2: 0.0}, {0: 40, 1: 460785.17})
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # First and last are valid, but missed second, so third doesn't count.
        entries = [(38, -76, 140), (40, -78, 600), (40, -78, 40)]
        expect = ({0: 40}, {0: 0.6, 1: 0.0, 2: 0.0}, {0: 40, 1: 460785.03})
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Hit all.
        entries = [(38, -76, 140), (39, -77, 180), (40, -78, 40)]
        expect = ({0: 40, 1: 20, 2: 40},
                  {0: 0.6, 1: 0.8, 2: 0.6},
                  {0: 40, 1: 20, 2: 40}) # yapf: disable
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Only hit the first waypoint on run one, hit all on run two.
        entries = [
            (38, -76, 140),
            (40, -78, 600),
            (37, -75, 40),
            # Run two:
            (38, -76, 140),
            (39, -77, 180),
            (40, -78, 40)
        ]
        expect = ({0: 40, 1: 20, 2: 40},
                  {0: 0.6, 1: 0.8, 2: 0.6},
                  {0: 40, 1: 20, 2: 40}) # yapf: disable
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Hit all on run one, only hit the first waypoint on run two.
        entries = [
            (38, -76, 140),
            (39, -77, 180),
            (40, -78, 40),
            # Run two:
            (38, -76, 140),
            (40, -78, 600),
            (37, -75, 40)
        ]
        expect = ({0: 40, 1: 20, 2: 40},
                  {0: 0.6, 1: 0.8, 2: 0.6},
                  {0: 40, 1: 20, 2: 40}) # yapf: disable
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Keep flying after hitting all waypoints.
        entries = [(38, -76, 140), (39, -77, 180), (40, -78, 40),
                   (30.1, -78.1, 100)]
        expect = ({0: 40, 1: 20, 2: 40},
                  {0: 0.6, 1: 0.8, 2: 0.6},
                  {0: 40, 1: 20, 2: 40}) # yapf: disable
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Hit all in first run, but second is higher scoring.
        entries = [
            (38, -76, 140),
            (39, -77, 180),
            (40, -78, 60),
            # Run two:
            (38, -76, 100),
            (39, -77, 200),
            (40, -78, 110)
        ]
        expect = ({0: 0, 1: 0}, {0: 1, 1: 1, 2: 0}, {0: 0, 1: 0, 2: 60})
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))

        # Restart waypoint path in the middle.
        waypoints = [(38, -76, 100), (39, -77, 200), (40, -78, 0)]
        entries = [
            (38, -76, 140),
            (39, -77, 180),
            # Restart:
            (38, -76, 70),
            (39, -77, 150),
            (40, -78, 10)
        ]
        expect = ({0: 30, 1: 50, 2: 10},
                  {0: 0.7, 1: 0.5, 2: 0.9},
                  {0: 30, 1: 20, 2: 10}) # yapf: disable
        logs = self.create_uas_logs(user, entries)
        self.assertSatisfiedWaypoints(expect, config.satisfied_waypoints(logs))