public static byte[] WriteReport(UavPositionReport item)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    try
                    {
                        var position = item.ToUavPosition();

                        writer.WriteStruct(position);
                        writer.Write((byte)item.UavStatus.Count);
                        foreach (UavStatus status in item.UavStatus)
                        {
                            writer.WriteStruct(status.ToAutpStatusMessage());
                        }
                    }
                    catch (Exception e) when(!(e is SerializationException))
                    {
                        throw new SerializationException(e.ToString());
                    }
                }

                return(stream.ToArray());
            }
        }
        /// <summary>
        /// Convert an AUTP <see cref="UavPosition"/> to a <see cref="UavPositionReport"/>
        /// </summary>
        /// <returns>A UavPositionReport object</returns>
        public static UavPositionReport ToPositionReport(this UavPosition position)
        {
            var report = new UavPositionReport
            {
                Alt        = new Altitude(position.GpsAltitude, AltitudeDatum.Wgs84, position.AltitudeAccuracy),
                IsAirborne = Enum.IsDefined(typeof(AirborneStatus), position.IsAirborne)
                    ? (AirborneStatus)position.IsAirborne
                    : AirborneStatus.Unknown,
                Pos = new Position(
                    (float)position.Latitude / UavPositionReportExtensions.PositionMultiplier,
                    (float)position.Longitude / UavPositionReportExtensions.PositionMultiplier,
                    position.PositionAccuracy
                    ),
                Velocity = new Velocity(
                    (float)position.EastVelocity / UavPositionReportExtensions.VelocityMultiplier,
                    (float)position.NorthVelocity / UavPositionReportExtensions.VelocityMultiplier,
                    (float)position.UpVelocity / UavPositionReportExtensions.VelocityMultiplier,
                    (float)position.VelocityAccuracy / UavPositionReportExtensions.VelocityMultiplier
                    ),
                Fuel = position.Fuel,
                SatellitesVisible = position.SatellitesVisible,
                GpsTimestamp      = GpsTime.ToDateTime(position.GpsTimestamp).AddMilliseconds(position.GpsTimestampOffset)
            };

            return(report);
        }
        /// <summary>
        /// Convert a <see cref="UavPositionReport"/> to an Autp <see cref="UavPosition"/>
        /// </summary>
        /// <remarks>
        ///     Altitude should be specified in Wgs8, as that's what the UDP paket is expected to provide.
        ///     If it isn't the altitude will be inaccurate if it is serialized back to canonical again.
        ///     No conversion is made.
        /// </remarks>
        /// <returns>A UavPosition object</returns>
        public static UavPosition ToUavPosition(this UavPositionReport report)
        {
            var position = new UavPosition
            {
                // Position
                Latitude         = (int)(report.Pos.Lat * UavPositionReportExtensions.PositionMultiplier),
                Longitude        = (int)(report.Pos.Lon * UavPositionReportExtensions.PositionMultiplier),
                PositionAccuracy = report.Pos.Accuracy,
                IsAirborne       = (byte)report.IsAirborne,

                // Altitude
                GpsAltitude      = report.Alt.Value,
                AltitudeAccuracy = report.Alt.Accuracy,

                // Speed and heading
                EastVelocity     = (int)(report.Velocity.X * UavPositionReportExtensions.VelocityMultiplier),
                NorthVelocity    = (int)(report.Velocity.Y * UavPositionReportExtensions.VelocityMultiplier),
                UpVelocity       = (int)(report.Velocity.Z * UavPositionReportExtensions.VelocityMultiplier),
                VelocityAccuracy = (int)(report.Velocity.Accuracy * UavPositionReportExtensions.VelocityMultiplier),

                Fuel = report.Fuel,
                SatellitesVisible  = report.SatellitesVisible,
                GpsTimestamp       = GpsTime.ToGpsTimestamp(report.GpsTimestamp),
                GpsTimestampOffset = (ushort)report.GpsTimestamp.Millisecond
            };

            return(position);
        }
Ejemplo n.º 4
0
        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 static bool TryReadReport(byte[] bytes, out UavPositionReport report)
        {
            report = null;
            using (var stream = new MemoryStream(bytes))
            {
                using (var reader = new BinaryReader(stream))
                {
                    if (!reader.TryReadStruct(out UavPosition position))
                    {
                        Debug.WriteLine("Could not read UavPosition", "Serialization Error");
                        return(false);
                    }

                    if (reader.BytesRemaining() < 1)
                    {
                        Debug.WriteLine("Missing UavPosition.NumStatuses", "Serialization Error");
                        return(false);
                    }
                    byte numStatuses = reader.ReadByte();

                    int expectedBytes = numStatuses * Marshal.SizeOf(typeof(AutpStatusMessage));
                    if (reader.BytesRemaining() < expectedBytes)
                    {
                        Debug.WriteLine($"Invalid status message bytes remaining. Expected {expectedBytes} bytes, got {reader.BytesRemaining()}", "Serialization Error");
                        return(false);
                    }

                    var statuses = new List <AutpStatusMessage>();
                    for (byte i = 0; i < numStatuses; i++)
                    {
                        statuses.Add(reader.ReadStruct <AutpStatusMessage>());
                    }

                    report           = position.ToPositionReport();
                    report.UavStatus = statuses.Select(s => s.ToUavStatus()).ToList();

                    return(true);
                }
            }
        }