def uas_telemetry_kml(user, flight_logs, kml, kml_doc): """ Appends kml nodes describing the given user's flight as described by the log array given. Args: user: A Django User to get username from flight_logs: A sequence of UasTelemetry logs per flight period. kml: A simpleKML Container to which the flight data will be added kml_doc: The simpleKML Document to which schemas will be added Returns: None """ # Lazily create folder iff there is data. kml_folder = None for i, logs in enumerate(flight_logs): name = '%s Flight %d' % (user.username, i + 1) logs = UasTelemetry.dedupe(UasTelemetry.filter_bad(logs)) coords = [] angles = [] when = [] for entry in logs: # Spatial Coordinates coord = (entry.longitude, entry.latitude, units.feet_to_meters(entry.altitude_msl)) coords.append(coord) # Time Elements time = entry.timestamp.strftime(KML_DATETIME_FORMAT) when.append(time) # Degrees heading, tilt, and roll angle = (entry.uas_heading, 0.0, 0.0) angles.append(angle) # Ignore tracks with no data. if not coords or not angles or not when: continue # Start folder if not done so already. if not kml_folder: kml_folder = kml.newfolder(name=user.username) # Create a new track in the folder trk = kml_folder.newgxtrack(name=name) trk.altitudemode = AltitudeMode.absolute # Append flight data trk.newwhen(when) trk.newgxcoord(coords) trk.newgxangle(angles) # Set styling trk.extrude = 1 # Extend path to ground trk.style.linestyle.width = 2 trk.style.linestyle.color = Color.blue trk.iconstyle.icon.href = KML_PLANE_ICON
def test_kml_simple(self): coordinates = [ (0, -76.0, 38.0, 0.0, 0), (1, -76.0, 38.0, 10.0, 0), (2, -76.0, 38.0, 20.0, 0), (3, -76.0, 38.0, 30.0, 0), (4, -76.0, 38.0, 100.0, 0), (5, -76.0, 38.0, 30.0, 0), (6, -76.0, 38.0, 60.0, 0), ] # Create Coordinates start = TakeoffOrLandingEvent(user=self.user, uas_in_air=True) start.save() start.timestamp = self.now start.save() for coord in coordinates: self.create_log_element(*coord) end = TakeoffOrLandingEvent(user=self.user, uas_in_air=False) end.save() end.timestamp = self.now + datetime.timedelta(seconds=7) end.save() kml = Kml() UasTelemetry.kml( user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml.document) for coord in coordinates: tag = self.coord_format.format(coord[2], coord[1], units.feet_to_meters(coord[3])) self.assertTrue(tag in kml.kml())
def test_kml_empty(self): kml = Kml() UasTelemetry.kml( user=self.user, logs=UasTelemetry.by_user(self.user), kml=kml, kml_doc=kml.document)
def test_closest_interpolated_distance(self): utm = distance.proj_utm(zone=18, north=True) # Test velocity filter. waypoint = self.waypoints_from_data([(38, -76, 100)])[0] entries = [(38, -76, 140), (40, -78, 600)] logs = self.create_uas_logs(self.user, entries) d = UasTelemetry.closest_interpolated_distance(logs[0], logs[1], waypoint, utm) self.assertAlmostEqual(40.0, d, delta=3) # Test telemetry rate filter. waypoint = self.waypoints_from_data([(38.145147, -76.427583, 100)])[0] entries = [(38.145148, -76.427645, 100), (38.145144, -76.427400, 100)] logs = self.create_uas_logs(self.user, entries) logs[1].timestamp = logs[0].timestamp + datetime.timedelta(seconds=2) d = UasTelemetry.closest_interpolated_distance(logs[0], logs[1], waypoint, utm) self.assertAlmostEqual(17.792, d, delta=3) # Test interpolation (waypoint is halfway between telemetry logs). waypoint = self.waypoints_from_data([(38.145146, -76.427522, 80)])[0] entries = [(38.145148, -76.427645, 100), (38.145144, -76.427400, 100)] logs = self.create_uas_logs(self.user, entries) logs[1].timestamp = logs[0].timestamp + datetime.timedelta(seconds=1) d = UasTelemetry.closest_interpolated_distance(logs[0], logs[1], waypoint, utm) self.assertAlmostEqual(20.0, d, delta=3)
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 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 i in range(len(entries)): lat, lon, alt = entries[i] log = UasTelemetry() log.user = user log.latitude = lat log.longitude = lon log.altitude_msl = alt log.uas_heading = 0 if i > 0: log.timetamp = ret[i - 1].timestamp + timedelta(seconds=1) log.save() ret.append(log) return ret
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.emergent_last_known_pos = pos self.mission.off_axis_odlc_pos = pos self.mission.air_drop_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()
def generate_feedback(mission_config, user, team_eval): """Generates mission feedback for the given team and mission. Args: mission_config: The mission to evaluate the team against. user: The team user object for which to evaluate and provide feedback. team_eval: The team evaluation to fill. """ feedback = team_eval.feedback # Find the user's flights. flight_periods = TakeoffOrLandingEvent.flights(mission_config, user) for period in flight_periods: if period.duration() is None: team_eval.warnings.append('Infinite flight period.') uas_period_logs = [ UasTelemetry.dedupe(logs) for logs in UasTelemetry.by_time_period(user, flight_periods) ] uas_logs = list(itertools.chain.from_iterable(uas_period_logs)) if not uas_logs: team_eval.warnings.append('No UAS telemetry logs.') # Determine interop telemetry rates. telem_max, telem_avg = UasTelemetry.rates( user, flight_periods, time_period_logs=uas_period_logs) if telem_max: feedback.uas_telemetry_time_max_sec = telem_max if telem_avg: feedback.uas_telemetry_time_avg_sec = telem_avg # Determine if the uas hit the waypoints. feedback.waypoints.extend( UasTelemetry.satisfied_waypoints( mission_config.home_pos, mission_config.mission_waypoints.order_by('order'), uas_logs)) # Evaluate the object detections. user_odlcs = Odlc.objects.filter(user=user).filter( mission=mission_config.pk).all() evaluator = OdlcEvaluator(user_odlcs, mission_config.odlcs.all(), flight_periods) feedback.odlc.CopyFrom(evaluator.evaluate()) # Determine collisions with stationary. for obst in mission_config.stationary_obstacles.all(): obst_eval = feedback.stationary_obstacles.add() obst_eval.id = obst.pk obst_eval.hit = obst.evaluate_collision_with_uas(uas_logs) # Add judge feedback. try: judge_feedback = MissionJudgeFeedback.objects.get( mission=mission_config.pk, user=user.pk) feedback.judge.CopyFrom(judge_feedback.proto()) except MissionJudgeFeedback.DoesNotExist: team_eval.warnings.append('No MissionJudgeFeedback for team.')
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') 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 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_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.assertSequenceEqual([], logs) log_rates = UasTelemetry.rates(self.user1, []) self.assertTupleEqual(log_rates, (None, None))
def uas_telemetry_kml(user, flights, logs, kml, kml_doc): """ Appends kml nodes describing the given user's flight as described by the log array given. Args: user: A Django User to get username from flights: List of flight periods logs: A list of UasTelemetry elements kml: A simpleKML Container to which the flight data will be added kml_doc: The simpleKML Document to which schemas will be added Returns: None """ kml_folder = kml.newfolder(name=user.username) logs = UasTelemetry.dedupe(UasTelemetry.filter_bad(logs)) for i, flight in enumerate(flights): name = '%s Flight %d' % (user.username, i + 1) flight_logs = filter(lambda x: flight.within(x.timestamp), logs) coords = [] angles = [] when = [] for entry in logs: pos = entry.uas_position.gps_position # Spatial Coordinates coord = (pos.longitude, pos.latitude, units.feet_to_meters(entry.uas_position.altitude_msl)) coords.append(coord) # Time Elements time = entry.timestamp.strftime(KML_DATETIME_FORMAT) when.append(time) # Degrees heading, tilt, and roll angle = (entry.uas_heading, 0.0, 0.0) angles.append(angle) # Create a new track in the folder trk = kml_folder.newgxtrack(name=name) trk.altitudemode = AltitudeMode.absolute # Append flight data trk.newwhen(when) trk.newgxcoord(coords) trk.newgxangle(angles) # Set styling trk.extrude = 1 # Extend path to ground trk.style.linestyle.width = 2 trk.style.linestyle.color = Color.blue trk.iconstyle.icon.href = KML_PLANE_ICON
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_last_for_user_time_restrict(self): start = timezone.now() delta = datetime.timedelta(seconds=1) logs = self.create_logs(self.user1, num=10, start=start, delta=delta) log = UasTelemetry.last_for_user(self.user1, start_time=start, end_time=start + delta * 3) self.assertEqual(logs[2], log) log = UasTelemetry.last_for_user(self.user1, start_time=start + delta * 11) self.assertIsNone(log) log = UasTelemetry.last_for_user(self.user1, end_time=start - delta) self.assertIsNone(log)
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_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_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_full_range(self): """All logs from (-inf, inf).""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(None, None) ]) self.assertSequenceEqual([self.logs], self.to_lists(results))
def test_single_period(self): """Single set of logs accessible.""" results = UasTelemetry.by_time_period(self.user1, [ TimePeriod(self.year2000, self.year2001) ]) self.assertSequenceEqual([self.year2000_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.assertSequenceEqual(list(UasTelemetry.dedupe(orig)), expect)
def get(self, request): kml = Kml(name='AUVSI SUAS Flight Data') kml_missions = kml.newfolder(name='Missions') users = User.objects.all() for mission in MissionConfig.objects.all(): kml_mission = mission_kml(mission, kml_missions, kml.document) kml_flights = kml_mission.newfolder(name='Flights') for user in users: if user.is_superuser: continue flights = TakeoffOrLandingEvent.flights(mission, user) if not flights: continue uas_telemetry_kml( user=user, flights=flights, logs=UasTelemetry.by_user(user), kml=kml_flights, kml_doc=kml.document) 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_by_user_time_restrict(self): start = timezone.now() delta = datetime.timedelta(seconds=1) expect_logs = self.create_logs(self.user1, num=10, start=start, delta=delta) logs = UasTelemetry.by_user(self.user1, start_time=start, end_time=start + delta * 10) self.assertSequenceEqual(expect_logs, logs) logs = UasTelemetry.by_user(self.user1, start_time=start + delta * 11) self.assertSequenceEqual([], logs) logs = UasTelemetry.by_user(self.user1, end_time=start) self.assertSequenceEqual([], logs)
def test_infinite_period(self): """Can't calculate a rate for an infinite (unbounded) period.""" delta = datetime.timedelta(seconds=1) logs = self.create_logs(self.user1, delta=delta) period = TimePeriod(None, None) self.assertSequenceEqual((None, None), UasTelemetry.rates(self.user1, [period]))
def test_no_logs(self): """Test behavior when no logs are present.""" delta = datetime.timedelta(seconds=10) self.assertSequenceEqual( (10, 10), UasTelemetry.rates( self.user1, [TimePeriod(self.year2000, self.year2000 + delta)]))
def post(self, request): """Posts the UAS position with a POST request.""" telemetry_proto = interop_api_pb2.Telemetry() try: json_format.Parse(request.body, telemetry_proto) except Exception as e: return HttpResponseBadRequest( 'Failed to parse request. Error: %s' % str(e)) if (not telemetry_proto.HasField('latitude') or not telemetry_proto.HasField('longitude') or not telemetry_proto.HasField('altitude') or not telemetry_proto.HasField('heading')): return HttpResponseBadRequest('Request missing fields.') # Check the values make sense. if telemetry_proto.latitude < -90 or telemetry_proto.latitude > 90: return HttpResponseBadRequest('Latitude out of range [-90, 90]: %f' % telemetry_proto.latitude) if telemetry_proto.longitude < -180 or telemetry_proto.longitude > 180: return HttpResponseBadRequest( 'Longitude out of range [-180, 180]: %f' % telemetry_proto.longitude) if telemetry_proto.altitude < -1500 or telemetry_proto.altitude > 330000: return HttpResponseBadRequest( 'Altitude out of range [-1500, 330000]: %f' % telemetry_proto.altitude) if telemetry_proto.heading < 0 or telemetry_proto.heading > 360: return HttpResponseBadRequest( 'Heading out of range [0, 360]: %f' % telemetry_proto.heading) # Store telemetry. gpos = GpsPosition( latitude=telemetry_proto.latitude, longitude=telemetry_proto.longitude) gpos.save() apos = AerialPosition( gps_position=gpos, altitude_msl=telemetry_proto.altitude) apos.save() telemetry = UasTelemetry( user=request.user, uas_position=apos, uas_heading=telemetry_proto.heading) telemetry.save() return HttpResponse('UAS Telemetry Successfully Posted.')
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 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 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 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 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_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 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_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 user_json(user): """Generate JSON-style dict for user.""" telemetry = UasTelemetry.last_for_user(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), 'telemetry': telemetry.json() if telemetry else None }
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 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_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_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_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_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()
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.0) log.save() log.timestamp = start + i * delta log.save() logs.append(log) return logs