Example #1
0
        public async Task <string> GetToken(CancellationToken cancellationToken)
        {
            await _lock.WaitAsync(cancellationToken);

            try
            {
                if (_settings.TokenResponse.IsValidForAuth())
                {
                    return(_settings.TokenResponse.AccessToken);
                }

                if (_settings.TokenResponse.CanBeRefreshed())
                {
                    try
                    {
                        await _messagesService.AddMessageAsync("Refreshing AA access token.");

                        return(await RefreshAccessToken(cancellationToken));
                    }
                    catch (Exception)
                    {
                        // Ignore and try asking user
                    }
                }

                await _messagesService.AddMessageAsync("Asking user for AA access token.");

                return(await AskUserForAccessToken(cancellationToken));
            }
            finally
            {
                _lock.Release();
            }
        }
        private async Task SendTelemetry(Models.FlightData flightData)
        {
            if (_settings.CurrentFlightId == null)
            {
                await _messagesService.AddMessageAsync(
                    new Message("Not sending telemetry as no current flight ID is set."));

                return;
            }
            try
            {
                var lat             = (float)flightData.CurrentPosition.Latitude;
                var lon             = (float)flightData.CurrentPosition.Longitude;
                var alt             = (ushort)flightData.CurrentPosition.Altitude;
                var courseInRadians = flightData.CurrentPosition.Course / 180 * Math.PI;
                var xVel            = (float)(Math.Sin(courseInRadians) * flightData.CurrentPosition.Speed);
                var yVel            = (float)(Math.Cos(courseInRadians) * flightData.CurrentPosition.Speed);
                var zVel            = flightData.CurrentPosition.VerticalSpeed;


                // Create dataStructure
                var udpMessage = new UavPositionReport
                {
                    GpsTimestamp      = DateTime.UtcNow,
                    Pos               = new Position(lat, lon, 0),
                    Alt               = new Altitude(alt, AltitudeDatum.Agl, 1),
                    Velocity          = new Velocity(xVel, yVel, zVel, 1),
                    IsAirborne        = AirborneStatus.Airborne,
                    SatellitesVisible = 3
                };

                var telemetryId = Guid.Parse(_settings.CurrentTelemetryId);
                var telemetry   = new TelemetryEvent <UavPositionReport>(telemetryId, udpMessage)
                {
                    SequenceNumber = _sequenceNumber
                };

                var message = string.Format($"Sending Telemetry {flightData.CurrentPosition.Latitude}, {flightData.CurrentPosition.Longitude}, {flightData.CurrentPosition.Altitude}");
                await _messagesService.AddMessageAsync(new Message(message));

                _client.SendTelemetry(telemetry, _settings.TelemetryHostName, _settings.TelemetryPortNumber, _settings.EncryptionKey);
                _sequenceNumber += 1;
            }
            catch (Exception)
            {
                await _messagesService.AddMessageAsync(new Message("ERROR: Sending telemetry failed."));
            }
        }
        public async Task SignInAsync()
        {
            if (!_settings.CheckEnableAltitudeAngel)
            {
                return;
            }
            try
            {
                // Load the user's profile, will trigger auth
                CurrentUser = await _client.GetUserProfile();

                IsSignedIn.Value = true;
                await UpdateMapData(_missionPlanner.FlightDataMap, CancellationToken.None);
                await UpdateMapData(_missionPlanner.FlightPlanningMap, CancellationToken.None);
            }
            catch (Exception)
            {
                await _messagesService.AddMessageAsync("There was a problem signing you in.");
            }
        }
        private async Task OnMessage(byte[] bytes)
        {
            await _messagesService.AddMessageAsync(new Message($"INFO: Received notification message of {bytes.Length} bytes."));

            var notification = new NotificationMessage();

            try
            {
                var msg = Encoding.UTF8.GetString(bytes);
                notification = JsonConvert.DeserializeObject <NotificationMessage>(msg);
                if (notification.Acknowledge)
                {
                    await SendAck(_aaClientWebSocket, notification.Id);
                }
            }
            catch (Exception e)
            {
                await _messagesService.AddMessageAsync(new Message($"ERROR: Failed to deserialize and acknowledge notification message. {e}"));
            }

            await _messagesService.AddMessageAsync(new Message($"INFO: Processing {notification.Type} notification message."));

            try
            {
                switch (notification.Type)
                {
                case OutboundNotifsCommands.Land:
                    LandNotificationProperties landProps = notification.Properties.ToObject <LandNotificationProperties>();
                    await _missionPlanner.CommandDroneToLand((float)landProps.Latitude, (float)landProps.Longitude);

                    break;

                case OutboundNotifsCommands.Loiter:
                    LoiterNotificationProperties loiterProps = notification.Properties.ToObject <LoiterNotificationProperties>();
                    await _missionPlanner.CommandDroneToLoiter((float)loiterProps.Latitude, (float)loiterProps.Longitude, (float)loiterProps.Altitude.Meters);

                    break;

                case OutboundNotifsCommands.AllClear:
                    await _missionPlanner.CommandDroneAllClear();

                    break;

                case OutboundNotifsCommands.ReturnToBase:
                    await _missionPlanner.CommandDroneToReturnToBase();

                    break;

                case OutboundNotifsCommands.PermissionUpdate:
                    var permissionProperties = notification.Properties.ToObject <PermissionNotificationProperties>();
                    await _messagesService.AddMessageAsync(new Message($"Flight permissions updated: {permissionProperties.PermissionState}")
                                                           { TimeToLive = TimeSpan.FromSeconds(10) });

                    break;

                case OutboundNotifsCommands.ConflictInformation:
                    var conflictProperties = notification.Properties.ToObject <ConflictInformationProperties>();
                    await _missionPlanner.NotifyConflict(conflictProperties.Message);

                    break;

                case OutboundNotifsCommands.ConflictClearedInformation:
                    var conflictClearedProperties = notification.Properties.ToObject <ConflictClearedNotificationProperties>();
                    await _missionPlanner.NotifyConflictResolved(conflictClearedProperties.Message);

                    break;

                case OutboundNotifsCommands.Instruction:
                    var instructionProperties = notification.Properties.ToObject <InstructionNotificationProperties>();
                    if (await _missionPlanner.ShowYesNoMessageBox(
                            $"You have been sent the following instruction:\r\n\r\n\"{instructionProperties.Instruction}\"\r\n\r\nDo you wish to accept and follow the instruction?",
                            "Instruction"))
                    {
                        await _flightServiceClient.AcceptInstruction(instructionProperties.InstructionId);

                        if (instructionProperties.Instruction.IndexOf("hold", StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            await _missionPlanner.CommandDroneToLoiter((float)_missionPlannerState.Latitude, (float)_missionPlannerState.Longitude, _missionPlannerState.Altitude);

                            break;
                        }

                        if (instructionProperties.Instruction.IndexOf("resume", StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            await _missionPlanner.CommandDroneAllClear();

                            break;
                        }

                        if (instructionProperties.Instruction.IndexOf("land", StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            await _missionPlanner.CommandDroneToLand((float)_missionPlannerState.Latitude, (float)_missionPlannerState.Longitude);

                            break;
                        }

                        if (instructionProperties.Instruction.IndexOf("return", StringComparison.InvariantCultureIgnoreCase) >= 0)
                        {
                            await _missionPlanner.CommandDroneToReturnToBase();
                        }
                    }
                    else
                    {
                        await _flightServiceClient.RejectInstruction(instructionProperties.InstructionId);
                    }
                    break;

                default:
                    await _messagesService.AddMessageAsync(new Message($"WARN: Unknown notification message type '{notification.Type}'."));

                    break;
                }
            }
            catch (Exception e)
            {
                await _messagesService.AddMessageAsync(new Message($"ERROR: Failed to process {notification.Type} notification message. {e}"));
            }
        }
Example #5
0
        private async Task StartTelemetryFlight(FlightPlan flightPlan)
        {
            if (flightPlan == null)
            {
                return;
            }
            if (_settings.CurrentFlightId != null)
            {
                // Complete flight if starting one before the previous ends.
                await CompleteFlight();
            }

            // TODO somehow prevent Arming of UAV until the following try statement has been completed, so telemetry isnt sent late. PBI 8490
            try
            {
                CurrentUser = await _client.GetUserProfile();

                Guid?flightPlanId;
                if (_settings.UseExistingFlightPlanId)
                {
                    flightPlanId = _settings.ExistingFlightPlanId;
                }
                else
                {
                    await _messagesService.AddMessageAsync(new Message("Creating flight plan...")
                                                           { TimeToLive = TimeSpan.FromSeconds(10) });

                    var createPlanResponse = await _client.CreateFlightPlan(flightPlan, CurrentUser);

                    if (createPlanResponse.Outcome == StrategicSeverity.DirectConflict)
                    {
                        await _messagesService.AddMessageAsync(new Message("Conflict detected; flight cancelled.")
                                                               { TimeToLive = TimeSpan.FromSeconds(10) });

                        await _missionPlanner.Disarm();

                        return;
                    }

                    flightPlanId = createPlanResponse.FlightPlanId;
                }

                // Check flight plan id is valid
                if (flightPlanId == null || flightPlanId == Guid.Empty)
                {
                    await _messagesService.AddMessageAsync(new Message("Flight plan not available; flight cancelled.")
                                                           { TimeToLive = TimeSpan.FromSeconds(10) });

                    await _missionPlanner.Disarm();

                    return;
                }
                _settings.CurrentFlightReportId = flightPlanId.ToString();
                await _messagesService.AddMessageAsync(new Message($"Flight plan {flightPlanId} in use.")
                                                       { TimeToLive = TimeSpan.FromSeconds(10) });

                // Flight being rejected will throw, and cause a disarm
                await _messagesService.AddMessageAsync(new Message("Starting flight...")
                                                       { TimeToLive = TimeSpan.FromSeconds(10) });

                var startFlightResponse = await _client.StartFlight(flightPlanId.Value.ToString("D"));

                _settings.CurrentFlightId = startFlightResponse.Id;
                var tacticalSettings = startFlightResponse.ServiceResponses.First();

                var notificationSettings = (WebsocketNotificationProtocolConfiguration)tacticalSettings.Properties.NotificationProtocols.First();
                _settings.OutboundNotifsEndpointUrl = notificationSettings.Properties.Endpoints.First();

                var telemetrySettings = (UdpTelemetryProtocolConfiguration)tacticalSettings.Properties.TelemetryProtocols.First();
                _settings.CurrentTelemetryId = telemetrySettings.Id;
                _settings.EncryptionKey      = telemetrySettings.Properties.EncryptionKey;

                var telemetryEndPoint = telemetrySettings.Properties.Endpoints.First();
                _settings.TelemetryHostName              = telemetryEndPoint.Split(':')[0];
                _settings.TelemetryPortNumber            = int.Parse(telemetryEndPoint.Split(':')[1]);
                _settings.TransmissionRateInMilliseconds = telemetrySettings.Properties.TransmissionRateInMilliseconds;

                var task = _notificationsService.StartWebSocket();

                await _messagesService.AddMessageAsync(new Message($"Flight {startFlightResponse.Id} approved and underway.")
                                                       { TimeToLive = TimeSpan.FromSeconds(10) });

                await task;
            }
            catch (Exception)
            {
                await _missionPlanner.Disarm();

                await _messagesService.AddMessageAsync(new Message($"Flight create failed."));
            }
        }