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_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_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_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_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 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 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 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, 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 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 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_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 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_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_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_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 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_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)