def test_kml_empty(self): kml = Kml() UasTelemetry.kml( user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml, )
def test_kml_simple(self): coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] # Create Coordinates start = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) start.save() for coord in coordinates: self.create_log_element(*coord) end = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) end.save() kml = Kml() UasTelemetry.kml(user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml) for coord in coordinates: tag = self.coord_format.format(coord[1], coord[0], units.feet_to_meters(coord[2])) self.assertTrue(tag in kml.kml())
def test_kml_filter(self): coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] filtered_out = [(0.1, 0.001, 100), (0.0, 0.0, 0)] # Create Coordinates start = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) start.save() for coord in coordinates: self.create_log_element(*coord) for coord in filtered_out: self.create_log_element(*coord) end = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) end.save() kml = Kml() UasTelemetry.kml(user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml) for filtered in filtered_out: tag = self.coord_format.format(filtered[1], filtered[0], filtered[2]) self.assertTrue(tag not in kml.kml()) for coord in coordinates: tag = self.coord_format.format(coord[1], coord[0], coord[2]) self.assertTrue(tag in kml.kml())
def test_basic_access(self): start = timezone.now() - datetime.timedelta(seconds=10) logs = self.create_logs(self.user1, start=start) log = UasTelemetry.last_for_user(self.user1) self.assertEqual(logs[-1], log) results = UasTelemetry.by_user(self.user1) self.assertSequenceEqual(logs, results)
def get(self, request): kml = Kml(name='LIVE Data') MovingObstacle.live_kml(kml, timedelta(seconds=5)) UasTelemetry.live_kml(kml, timedelta(seconds=5)) response = HttpResponse(kml.kml()) response['Content-Type'] = 'application/vnd.google-earth.kml+xml' response['Content-Disposition'] = 'attachment; filename=update.kml' response['Content-Length'] = str(len(response.content)) return response
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
def test_multi_user(self): # Intersperse logs from two users logs = [] for _ in xrange(10): logs += self.create_logs(self.user1, num=1) self.create_logs(self.user2, num=1) log = UasTelemetry.last_for_user(self.user1) self.assertEqual(logs[-1], log) results = UasTelemetry.by_user(self.user1) self.assertSequenceEqual(logs, results)
def test_no_data(self): log = UasTelemetry.last_for_user(self.user1) self.assertEqual(None, log) logs = UasTelemetry.by_user(self.user1) self.assertEqual(len(logs), 0) logs = UasTelemetry.by_time_period(self.user1, []) self.assertEqual(len(logs), 0) log_rates = UasTelemetry.rates(self.user1, []) self.assertTupleEqual(log_rates, (None, None))
def test_non_intersecting_period(self): """No logs matched.""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(self.year2001, self.year2002), ]) self.assertSequenceEqual([[]], self.to_lists(results))
def test_open_start(self): """Logs (-inf, 2001)""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(None, self.year2001), ]) self.assertSequenceEqual([self.year2000_logs], self.to_lists(results))
def test_open_end(self): """Logs (2003, inf)""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(self.year2003, None), ]) self.assertSequenceEqual([self.year2003_logs], self.to_lists(results))
def test_duplicates(self): orig = [ self.log1, self.log1, self.log2, self.log3, self.log3, self.log4, self.log4 ] expect = [self.log1, self.log2, self.log3, self.log4] self.assertEqual(UasTelemetry.dedupe(orig), expect)
def user_json(user): """Generate JSON-style dict for user.""" return { 'name': user.username, 'id': user.pk, 'in_air': TakeoffOrLandingEvent.user_in_air(user), 'active': UasTelemetry.user_active(user), }
def test_last_for_user_before_time(self): start = timezone.now() delta = datetime.timedelta(seconds=1) logs = self.create_logs(self.user1, num=10, start=start, delta=delta) before_time = start + delta * 3 log = UasTelemetry.last_for_user(self.user1, before_time=before_time) self.assertEqual(logs[2], log)
def test_satisfied_waypoints(self): """Tests the evaluation of waypoints method.""" data = TESTDATA_MISSIONCONFIG_EVALWAYPOINTS (waypoint_details, uas_log_details, exp_satisfied) = data # 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.sric_pos = gpos config.air_drop_pos = gpos config.server_info = self.info config.save() # Create waypoints for config for wpt_id in xrange(len(waypoint_details)): (lat, lon, alt) = waypoint_details[wpt_id] 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 = wpt_id wpt.save() config.mission_waypoints.add(wpt) config.save() # Create UAS telemetry logs uas_logs = [] user = User.objects.create_user('testuser', '*****@*****.**', 'testpass') for (lat, lon, alt) in uas_log_details: 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() uas_logs.append(log) # Assert correct satisfied waypoints wpts_satisfied = config.satisfied_waypoints(uas_logs) self.assertEqual(wpts_satisfied, exp_satisfied)
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
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
def test_one_intersecting_period(self): """Only one period matches logs.""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(self.year2001, self.year2002), TimePeriod(self.year2003, self.year2004), ]) self.assertSequenceEqual([[], self.year2003_logs], self.to_lists(results))
def test_both_periods(self): """Both sets of logs, accesses individually.""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(self.year2000, self.year2001), TimePeriod(self.year2003, self.year2004), ]) self.assertSequenceEqual([self.year2000_logs, self.year2003_logs], self.to_lists(results))
def postUasPosition(request): """Posts the UAS position with a POST request. User must send a POST request with the following paramters: latitude: A latitude in decimal degrees. longitude: A logitude in decimal degrees. altitude_msl: An MSL altitude in decimal feet. uas_heading: The UAS heading in decimal degrees. (0=north, 90=east) """ # Validate user is logged in to make request if not request.user.is_authenticated(): return HttpResponseBadRequest('User not logged in. Login required.') # Validate user made a POST request if request.method != 'POST': return HttpResponseBadRequest('Request must be POST request.') try: # Get the parameters latitude = float(request.POST['latitude']) longitude = float(request.POST['longitude']) altitude_msl = float(request.POST['altitude_msl']) uas_heading = float(request.POST['uas_heading']) except KeyError: # Failed to get POST parameters return HttpResponseBadRequest( 'Posting UAS position must contain POST parameters "latitude", ' '"longitude", "altitude_msl", and "uas_heading".') except ValueError: # Failed to convert parameters return HttpResponseBadRequest( 'Failed to convert provided POST parameters to correct form.') else: # Check the values make sense if latitude < -90 or latitude > 90: return HttpResponseBadRequest( 'Must provide latitude between -90 and 90 degrees.') if longitude < -180 or longitude > 180: return HttpResponseBadRequest( 'Must provide longitude between -180 and 180 degrees.') if uas_heading < 0 or uas_heading > 360: return HttpResponseBadRequest( 'Must provide heading between 0 and 360 degrees.') # Store telemetry gps_position = GpsPosition() gps_position.latitude = latitude gps_position.longitude = longitude gps_position.save() aerial_position = AerialPosition() aerial_position.gps_position = gps_position aerial_position.altitude_msl = altitude_msl aerial_position.save() uas_telemetry = UasTelemetry() uas_telemetry.user = request.user uas_telemetry.uas_position = aerial_position uas_telemetry.uas_heading = uas_heading uas_telemetry.save() return HttpResponse('UAS Telemetry Successfully Posted.')
def test_constant_rate(self): """Rates computed correctly.""" delta = datetime.timedelta(seconds=1) logs = self.create_logs(self.user1, delta=delta) period = self.consistent_period(logs, delta) rates = UasTelemetry.rates(self.user1, [period]) self.assertSequenceEqual((1, 1), rates)
def test_ignore_start_end(self): """When start and end are None, only times between logs are compared.""" delta = datetime.timedelta(seconds=1) logs = self.create_logs(self.user1, delta=delta) period = TimePeriod(None, None) rates = UasTelemetry.rates(self.user1, [period]) self.assertSequenceEqual((1, 1), rates)
def user_json(user): """Generate JSON-style dict for user.""" return { 'name': user.username, 'id': user.pk, 'on_clock': MissionClockEvent.user_on_clock(user), 'on_timeout': MissionClockEvent.user_on_timeout(user), 'in_air': TakeoffOrLandingEvent.user_in_air(user), 'active': UasTelemetry.user_active(user), }
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)
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)
def test_user_active(self): delta = datetime.timedelta(seconds=1) self.create_logs(self.user1, start=self.year2000, num=10, delta=delta) latest_time = self.year2000 + 10 * delta # Active for user with recent logs self.assertTrue(UasTelemetry.user_active(self.user1, base=latest_time)) # Not active for user with no logs self.assertFalse(UasTelemetry.user_active(self.user2, base=latest_time)) # Not active for user with no recent logs self.assertFalse( UasTelemetry.user_active(self.user1, base=self.year2001)) # Active now self.create_logs(self.user1, num=10, delta=delta) self.assertTrue(UasTelemetry.user_active(self.user1))
def test_provided_logs(self): """Rates computed with provided logs.""" delta = datetime.timedelta(seconds=1) used_logs = self.create_logs(self.user1, delta=delta) unused_logs = self.create_logs(self.user1, delta=delta) period = self.consistent_period(used_logs, delta) rates = UasTelemetry.rates(self.user1, [period], time_period_logs=[used_logs]) self.assertSequenceEqual((1, 1), rates)
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 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() telem = UasTelemetry(user=self.user2, uas_position=pos, uas_heading=90) telem.save() telem.timestamp = self.timestamp telem.save()
def get(self, request): kml = Kml(name='AUVSI SUAS Flight Data') kml_teams = kml.newfolder(name='Teams') kml_mission = kml.newfolder(name='Missions') users = User.objects.all() for user in users: # Ignore admins if user.is_superuser: continue UasTelemetry.kml(user=user, logs=UasTelemetry.by_user(user), kml=kml_teams, kml_doc=kml.document) MissionConfig.kml_all(kml_mission) kml_flyzone = kml.newfolder(name='Fly Zones') FlyZone.kml_all(kml_flyzone) response = HttpResponse(kml.kml()) response['Content-Type'] = 'application/vnd.google-earth.kml+xml' response['Content-Disposition'] = 'attachment; filename=mission.kml' response['Content-Length'] = str(len(response.content)) return response
def test_multiple_periods(self): """Multiple periods are combined without introducing errors.""" delta = datetime.timedelta(seconds=1) logs = [ self.create_logs(self.user1, start=self.year2000, delta=delta), self.create_logs(self.user1, start=self.year2001, delta=delta), ] periods = [self.consistent_period(l, delta) for l in logs] rates = UasTelemetry.rates(self.user1, periods) self.assertSequenceEqual((1, 1), rates)
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
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
def test_kml(self): """ Tests the generation of kml data The correct number of elements are generated The meta-data tag is present """ array_field_tag = '<gx:SimpleArrayField name="proximity" type="float">' coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] user = User.objects.create_user('testuser', '*****@*****.**', 'testpass') user.save() # Create Coordinates start_time = timezone.now() next_time = start_time end_time = start_time for coord in coordinates: self.create_log_element(*coord, user=user, log_time=next_time) end_time = next_time next_time += datetime.timedelta(seconds=1) # Calculate expected number of data tags time_delta = end_time - start_time ms_elapsed = time_delta.total_seconds() * 1000 kml_output_resolution = 100 # milliseconds samples_expected = int(ms_elapsed / kml_output_resolution) for cur_obst in self.obstacles: kml = Kml() kml_mission = kml.newfolder(name='SubFolder') cur_obst.kml( path=UasTelemetry.by_user(user), kml=kml_mission, kml_doc=kml.document, ) result_kml = kml.kml() self.assertEqual(samples_expected, result_kml.count('<gx:value>')) self.assertIn(array_field_tag, result_kml)
def test_kml(self): """ Tests the generation of kml data The correct number of elements are generated The meta-data tag is present """ array_field_tag = '<gx:SimpleArrayField name="proximity" type="float">' coordinates = [ (-76.0, 38.0, 0.0), (-76.0, 38.0, 10.0), (-76.0, 38.0, 20.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 100.0), (-76.0, 38.0, 30.0), (-76.0, 38.0, 60.0), ] user = User.objects.create_user('testuser', '*****@*****.**', 'testpass') user.save() # Create Coordinates start_time = timezone.now() next_time = start_time end_time = start_time for coord in coordinates: self.create_log_element(*coord, user=user, log_time=next_time) end_time = next_time next_time += datetime.timedelta(seconds=1) # Calculate expected number of data tags time_delta = end_time - start_time ms_elapsed = time_delta.total_seconds() * 1000 kml_output_resolution = 100 # milliseconds samples_expected = int(ms_elapsed / kml_output_resolution) for cur_obst in self.obstacles: kml = Kml() kml_mission = kml.newfolder(name='SubFolder') cur_obst.kml(path=UasTelemetry.by_user(user), kml=kml_mission, kml_doc=kml.document) result_kml = kml.kml() self.assertEqual(samples_expected, result_kml.count('<gx:value>')) self.assertIn(array_field_tag, result_kml)
def test_different_deltas(self): """Sets of logs are combined for overall rates.""" delta = datetime.timedelta(seconds=1) logs = [ self.create_logs(self.user1, num=1000, start=self.year2000, delta=delta), self.create_logs(self.user1, num=1000, start=self.year2001, delta=delta / 2), ] periods = [self.consistent_period(l, delta) for l in logs] rates = UasTelemetry.rates(self.user1, periods) self.assertAlmostEqual(1.0, rates[0]) # max self.assertAlmostEqual(0.75, rates[1], delta=0.001) # avg
def create_logs(self, user, num=10, start=None, delta=None): if start is None: start = timezone.now() if delta is None: delta = datetime.timedelta(seconds=1) logs = [] for i in xrange(num): gps_position = GpsPosition(latitude=0, longitude=0) gps_position.save() uas_position = AerialPosition(gps_position=gps_position, altitude_msl=0) uas_position.save() log = UasTelemetry(user=user, uas_position=uas_position, uas_heading=0) log.save() log.timestamp = start + i * delta log.save() logs.append(log) return logs
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: 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 = log_time log.save() 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)
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_out_of_bounds_time, uas_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 uas_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 out_of_bounds_time = FlyZone.out_of_bounds(zones, uas_logs) self.assertAlmostEqual(out_of_bounds_time, exp_out_of_bounds_time)
def post(self, request): """Posts the UAS position with a POST request. User must send a POST request with the following paramters: latitude: A latitude in decimal degrees. longitude: A logitude in decimal degrees. altitude_msl: An MSL altitude in decimal feet. uas_heading: The UAS (true north) heading in decimal degrees. """ try: # Get the parameters latitude = float(request.POST['latitude']) longitude = float(request.POST['longitude']) altitude_msl = float(request.POST['altitude_msl']) uas_heading = float(request.POST['uas_heading']) except KeyError: # Failed to get POST parameters logger.warning( 'User did not specify all params for uas telemetry request.') logger.debug(request) return HttpResponseBadRequest( 'Posting UAS position must contain POST parameters "latitude", ' '"longitude", "altitude_msl", and "uas_heading".') except ValueError: # Failed to convert parameters logger.warning( 'User specified a param which could not converted to an ' + 'appropriate type.') logger.debug(request) return HttpResponseBadRequest( 'Failed to convert provided POST parameters to correct form.') else: # Check the values make sense if latitude < -90 or latitude > 90: logger.warning('User specified latitude out of valid range.') logger.debug(request) return HttpResponseBadRequest( 'Must provide latitude between -90 and 90 degrees.') if longitude < -180 or longitude > 180: logger.warning('User specified longitude out of valid range.') logger.debug(request) return HttpResponseBadRequest( 'Must provide longitude between -180 and 180 degrees.') if uas_heading < 0 or uas_heading > 360: logger.warning('User specified altitude out of valid range.') logger.debug(request) return HttpResponseBadRequest( 'Must provide heading between 0 and 360 degrees.') # Store telemetry logger.info('User uploaded telemetry: %s' % request.user.username) gpos = GpsPosition(latitude=latitude, longitude=longitude) gpos.save() apos = AerialPosition(gps_position=gpos, altitude_msl=altitude_msl) apos.save() telemetry = UasTelemetry(user=request.user, uas_position=apos, uas_heading=uas_heading) telemetry.save() return HttpResponse('UAS Telemetry Successfully Posted.')
def test_duplicates(self): orig = [self.log1, self.log1, self.log2, self.log3, self.log3, self.log4, self.log4] expect = [self.log1, self.log2, self.log3, self.log4] self.assertEqual(UasTelemetry.dedupe(orig), expect)
def test_no_logs(self): """Tests empty log.""" self.assertEqual(UasTelemetry.dedupe([]), [])
def test_boundary_duplicates(self): """Tests duplicates on the bounds of the list.""" orig = [self.log1, self.log1, self.log2, self.log2, self.log2] expect = [self.log1, self.log2] self.assertEqual(UasTelemetry.dedupe(orig), expect)
def test_no_duplicates(self): """Tests no duplicates in list.""" orig = [self.log1, self.log2, self.log3, self.log4] self.assertEqual(UasTelemetry.dedupe(orig), orig)