Пример #1
0
 /// <summary>
 /// Decodes the fields from an extended squitter reply (DF = 17).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeExtendedSquitter(ModeSMessage reply)
 {
     ExtractCapability(reply);
     ExtractAircraftAddress(reply);
     ExtractExtendedSquitterMessage(reply);
     ExtractParityInterrogator(reply);
 }
Пример #2
0
 /// <summary>
 /// Decodes the fields from a surveillance identity reply (DF = 5).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeSurveillanceIdentityReply(ModeSMessage reply)
 {
     ExtractFlightStatus(reply);
     ExtractDownlinkRequest(reply);
     ExtractUtilityMessage(reply);
     ExtractIdentity(reply);
     ExtractAircraftParityIdentifier(reply);
 }
Пример #3
0
 /// <summary>
 /// Decodes the fields from a Comm-D reply (DF = 24).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeCommD(ModeSMessage reply)
 {
     _BitStream.Skip(1);
     reply.ElmControl     = (ElmControl)_BitStream.ReadByte(1);
     reply.DSegmentNumber = _BitStream.ReadByte(4);
     reply.CommDMessage   = ReadBytes(10);
     ExtractAircraftParityIdentifier(reply);
 }
Пример #4
0
 /// <summary>
 /// Decodes the fields from a Comm-B altitude reply (DF = 20).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeCommBAltitudeReply(ModeSMessage reply)
 {
     ExtractFlightStatus(reply);
     ExtractDownlinkRequest(reply);
     ExtractUtilityMessage(reply);
     ExtractAltitudeCode(reply);
     ExtractCommBMessage(reply);
     ExtractAircraftParityIdentifier(reply);
 }
Пример #5
0
 private void ExtractCommBMessage(ModeSMessage reply)
 {
     reply.CommBMessage = ReadBytes(7);
     if (reply.CommBMessage[0] == 0x20)
     {
         _BitStream.Skip(-48);
         reply.PossibleCallsign = ModeSCharacterTranslator.ExtractCharacters(_BitStream, 8);
     }
 }
Пример #6
0
        public void ModeSMessageEventArgs_Constructor_Initialises_To_Known_State()
        {
            var dateTimeNow = DateTime.UtcNow;
            var message     = new ModeSMessage();
            var adsbMessage = new AdsbMessage(message);
            var eventArgs   = new ModeSMessageEventArgs(dateTimeNow, message, adsbMessage);

            Assert.AreEqual(dateTimeNow, eventArgs.ReceivedUtc);
            Assert.AreSame(message, eventArgs.ModeSMessage);
            Assert.AreSame(adsbMessage, eventArgs.AdsbMessage);
        }
Пример #7
0
 /// <summary>
 /// Decodes the fields from a long air-to-air surveillance reply (DF = 16).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeLongAirToAirSurveillance(ModeSMessage reply)
 {
     ExtractVerticalStatus(reply);
     _BitStream.Skip(2);
     ExtractSensitivityLevel(reply);
     _BitStream.Skip(2);
     ExtractReplyInformation(reply);
     _BitStream.Skip(2);
     ExtractAltitudeCode(reply);
     reply.ACASMessage = ReadBytes(7);
     ExtractAircraftParityIdentifier(reply);
 }
Пример #8
0
 /// <summary>
 /// Decodes the fields from a short air-to-air surveillance reply (DF = 0).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeShortAirToAirSurveillance(ModeSMessage reply)
 {
     ExtractVerticalStatus(reply);
     reply.CrossLinkCapability = _BitStream.ReadBit();
     _BitStream.Skip(1);
     ExtractSensitivityLevel(reply);
     _BitStream.Skip(2);
     ExtractReplyInformation(reply);
     _BitStream.Skip(2);
     ExtractAltitudeCode(reply);
     ExtractAircraftParityIdentifier(reply);
 }
Пример #9
0
 /// <summary>
 /// Decodes the fields from a military extended squitter reply (DF = 19).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeMilitaryExtendedSquitter(ModeSMessage reply)
 {
     reply.ApplicationField = (ApplicationField)_BitStream.ReadByte(3);
     if (reply.ApplicationField != ApplicationField.ADSB)
     {
         reply.ExtendedSquitterSupplementaryMessage = ReadBytes(13);
     }
     else
     {
         ExtractAircraftAddress(reply);
         ExtractExtendedSquitterMessage(reply);
         ExtractParityInterrogator(reply);
     }
 }
        public void AdsbMessage_Constructor_Initialises_To_Known_Values_And_Properties_Work()
        {
            var modeSMessage = new ModeSMessage();
            var message      = new AdsbMessage(modeSMessage);

            Assert.AreSame(modeSMessage, message.ModeSMessage);

            TestUtilities.TestProperty(message, m => m.AirbornePosition, null, new AirbornePositionMessage());
            TestUtilities.TestProperty(message, m => m.AirborneVelocity, null, new AirborneVelocityMessage());
            TestUtilities.TestProperty(message, m => m.IdentifierAndCategory, null, new IdentifierAndCategoryMessage());
            TestUtilities.TestProperty(message, m => m.MessageFormat, MessageFormat.None, MessageFormat.AircraftOperationalStatus);
            TestUtilities.TestProperty(message, m => m.SurfacePosition, null, new SurfacePositionMessage());
            TestUtilities.TestProperty(message, m => m.TargetStateAndStatus, null, new TargetStateAndStatusMessage());
            TestUtilities.TestProperty(message, m => m.Type, (byte)0, (byte)255);
            TestUtilities.TestProperty(message, m => m.AircraftStatus, null, new AircraftStatusMessage());
            TestUtilities.TestProperty(message, m => m.AircraftOperationalStatus, null, new AircraftOperationalStatusMessage());
        }
Пример #11
0
 private void ExtractAltitudeCode(ModeSMessage reply)
 {
     reply.Altitude         = _BitStream.ReadUInt16(13);
     reply.AltitudeIsMetric = (reply.Altitude & 0x40) != 0;
     if (!reply.AltitudeIsMetric.Value)
     {
         int?decodedAltitude = ((reply.Altitude & 0x1F80) >> 2) | ((reply.Altitude & 0x20) >> 1) | (reply.Altitude & 0x0f);
         if ((reply.Altitude & 0x10) != 0)
         {
             decodedAltitude = ModeSAltitudeConversion.CalculateBinaryAltitude(decodedAltitude.Value);
         }
         else
         {
             decodedAltitude = ModeSAltitudeConversion.LookupGillhamAltitude(decodedAltitude.Value);
         }
         reply.Altitude = decodedAltitude;
     }
 }
Пример #12
0
            public PointLatLngAlt pllalocal(ModeSMessage newmsg)
            {
                if (newmsg == null)
                    return PointLatLngAlt.Zero;

                int num = 131072;
                double denominator = (newmsg.OddFormat ? 6.101694915254237 : 6.0);
                double num3 =  360.0;
                double latitude = reflat;
                double num5 = ((double)newmsg.lat) / ((double)num);
                double num6 = Math.Floor((double)(latitude / denominator)) + Math.Floor((double)((0.5 + (this.modulo(latitude, denominator) / denominator)) - num5));
                double lat = denominator * (num6 + num5);
                int num7 = this.NL(newmsg.lat) - (newmsg.OddFormat ? 1 : 0);

                double numerator = reflng;
                double num9 = (num7 == 0) ? num3 : (num3 / ((double)num7));
                double num10 = ((double)newmsg.lng) / ((double)num);
                double num11 = Math.Floor((double)(numerator / num9)) + Math.Floor((double)((0.5 + (this.modulo(numerator, num9) / num9)) - num10));
                double lng = num9 * (num11 + num10);

                return new PointLatLngAlt(lat,lng);
            }
        /// <summary>
        /// Decodes the fields from an extended squitter from non-transponder reply (DF = 18).
        /// </summary>
        /// <param name="reply"></param>
        private void DecodeExtendedSquitterNonTransponder(ModeSMessage reply)
        {
            reply.ControlField = (ControlField)_BitStream.ReadByte(3);
            switch (reply.ControlField)
            {
            case ControlField.AdsbDeviceTransmittingIcao24:
            case ControlField.AdsbRebroadcastOfExtendedSquitter:
                ExtractAircraftAddress(reply);
                ExtractExtendedSquitterMessage(reply);
                break;

            case ControlField.AdsbDeviceNotTransmittingIcao24:
                reply.NonIcao24Address = (int)_BitStream.ReadUInt32(24);
                ExtractExtendedSquitterMessage(reply);
                break;

            default:
                reply.ExtendedSquitterSupplementaryMessage = ReadBytes(10);
                break;
            }
            ExtractParityInterrogator(reply);
        }
Пример #14
0
 private void ExtractVerticalStatus(ModeSMessage reply)
 {
     reply.VerticalStatus = (VerticalStatus)_BitStream.ReadByte(1);
 }
Пример #15
0
 private void ExtractUtilityMessage(ModeSMessage reply)
 {
     reply.UtilityMessage = _BitStream.ReadByte(6);
 }
Пример #16
0
 private void ExtractSensitivityLevel(ModeSMessage reply)
 {
     reply.SensitivityLevel = _BitStream.ReadByte(3);
 }
Пример #17
0
 private void ExtractReplyInformation(ModeSMessage reply)
 {
     reply.ReplyInformation = _BitStream.ReadByte(4);
 }
Пример #18
0
 private void ExtractParityInterrogator(ModeSMessage reply)
 {
     reply.ParityInterrogatorIdentifier = (int)_BitStream.ReadUInt32(24);
 }
Пример #19
0
 private void ExtractFlightStatus(ModeSMessage reply)
 {
     reply.FlightStatus = (FlightStatus)_BitStream.ReadByte(3);
 }
Пример #20
0
 private void ExtractExtendedSquitterMessage(ModeSMessage reply)
 {
     reply.ExtendedSquitterMessage = ReadBytes(7);
 }
Пример #21
0
 private void ExtractDownlinkRequest(ModeSMessage reply)
 {
     reply.DownlinkRequest = _BitStream.ReadByte(5);
 }
Пример #22
0
 /// <summary>
 /// Creates a new object.
 /// </summary>
 /// <param name="modeSMessage"></param>
 public AdsbMessage(ModeSMessage modeSMessage)
 {
     ModeSMessage = modeSMessage;
 }
Пример #23
0
            public PointLatLngAlt pllalocal(ModeSMessage newmsg)
            {
                if (newmsg == null)
                    return PointLatLngAlt.Zero;

                int num = 131072;
                double denominator = (newmsg.OddFormat ? 6.101694915254237 : 6.0);
                double num3 =  360.0;
                double latitude = reflat;
                double num5 = ((double)newmsg.lat) / ((double)num);
                double num6 = Math.Floor((double)(latitude / denominator)) + Math.Floor((double)((0.5 + (this.modulo(latitude, denominator) / denominator)) - num5));
                double lat = denominator * (num6 + num5);
                int num7 = this.NL(newmsg.lat) - (newmsg.OddFormat ? 1 : 0);

                double numerator = reflng;
                double num9 = (num7 == 0) ? num3 : (num3 / ((double)num7));
                double num10 = ((double)newmsg.lng) / ((double)num);
                double num11 = Math.Floor((double)(numerator / num9)) + Math.Floor((double)((0.5 + (this.modulo(numerator, num9) / num9)) - num10));
                double lng = num9 * (num11 + num10);

                return new PointLatLngAlt(lat,lng);
            }
Пример #24
0
        /// <summary>
        /// See interface docs.
        /// </summary>
        /// <param name="rawMessage"></param>
        /// <param name="start"></param>
        /// <param name="signalLevel"></param>
        /// <param name="isMlat"></param>
        /// <returns></returns>
        public ModeSMessage Translate(byte[] rawMessage, int start, int?signalLevel, bool isMlat)
        {
            if (Statistics == null)
            {
                throw new InvalidOperationException("Statistics must be provided before Translate can do any work");
            }
            ModeSMessage result = null;

            var messageLength = rawMessage == null ? 0 : rawMessage.Length - start;

            if (messageLength > 6)
            {
                _BitStream.Initialise(rawMessage);
                _BitStream.Skip(start * 8);
                var downlinkFormatValue = _BitStream.ReadByte(5);
                if (downlinkFormatValue >= 24)
                {
                    downlinkFormatValue = 24;
                    _BitStream.Skip(-3);
                }

                bool isLongFrame = true;
                switch (downlinkFormatValue)
                {
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 24:    if (messageLength > 13)
                    {
                        result = new ModeSMessage();
                    }
                    break;

                default:    isLongFrame = false; result = new ModeSMessage(); break;
                }

                if (result != null)
                {
                    result.SignalLevel    = signalLevel;
                    result.IsMlat         = isMlat;
                    result.DownlinkFormat = (DownlinkFormat)downlinkFormatValue;

                    switch (result.DownlinkFormat)
                    {
                    case DownlinkFormat.ShortAirToAirSurveillance:      DecodeShortAirToAirSurveillance(result); break;             // DF0

                    case DownlinkFormat.SurveillanceAltitudeReply:      DecodeSurveillanceAltitudeReply(result); break;             // DF4

                    case DownlinkFormat.SurveillanceIdentityReply:      DecodeSurveillanceIdentityReply(result); break;             // DF5

                    case DownlinkFormat.AllCallReply:                   DecodeAllCallReply(result); break;                          // DF11

                    case DownlinkFormat.LongAirToAirSurveillance:       DecodeLongAirToAirSurveillance(result); break;              // DF16

                    case DownlinkFormat.ExtendedSquitter:               DecodeExtendedSquitter(result); break;                      // DF17

                    case DownlinkFormat.ExtendedSquitterNonTransponder: DecodeExtendedSquitterNonTransponder(result); break;        // DF18

                    case DownlinkFormat.MilitaryExtendedSquitter:       DecodeMilitaryExtendedSquitter(result); break;              // DF19

                    case DownlinkFormat.CommBAltitudeReply:             DecodeCommBAltitudeReply(result); break;                    // DF20

                    case DownlinkFormat.CommBIdentityReply:             DecodeCommBIdentityReply(result); break;                    // DF21

                    case DownlinkFormat.CommD:                          DecodeCommD(result); break;                                 // DF24
                    }

                    if (Statistics != null)
                    {
                        Statistics.Lock(r => {
                            ++r.ModeSMessagesReceived;
                            ++r.ModeSDFStatistics[(int)result.DownlinkFormat].MessagesReceived;
                            if (isLongFrame)
                            {
                                ++r.ModeSLongFrameMessagesReceived;
                            }
                            else
                            {
                                ++r.ModeSShortFrameMessagesReceived;
                            }
                        });
                    }
                }
            }

            return(result);
        }
Пример #25
0
 public void TestInitialise()
 {
     _Message = new ModeSMessage();
 }
Пример #26
0
 /// <summary>
 /// Decodes the fields from an all-call reply (DF = 11).
 /// </summary>
 /// <param name="reply"></param>
 private void DecodeAllCallReply(ModeSMessage reply)
 {
     ExtractCapability(reply);
     ExtractAircraftAddress(reply);
     ExtractParityInterrogator(reply);
 }
Пример #27
0
        private void ExtractIdentity(ModeSMessage reply)
        {
            var bits = (short)_BitStream.ReadUInt16(13);

            reply.Identity = ModeATranslator.DecodeModeA(bits);
        }
Пример #28
0
 private void ExtractAircraftAddress(ModeSMessage reply)
 {
     reply.Icao24 = (int)_BitStream.ReadUInt32(24);
 }
Пример #29
0
        /// <summary>
        /// AVR ASCii Format Input
        /// </summary>
        /// <param name="avrline"></param>
        /// <returns></returns>
        public static Plane ReadMessage(string avrline)
        {
            if (!avrline.StartsWith("*"))
            {
                return(null);
            }

            log.Debug(avrline);

            avrline = avrline.Trim().TrimEnd(';');

            ModeSMessage adsbmess = new ModeSMessage();

            byte[] data = ConvertHexStringToByteArray(avrline.TrimStart('*'));

            if (data.Length < 13)
            {
                return(null);
            }

            adsbmess.DF = (byte)(data[0] >> 3);                                 // 5
            adsbmess.CA = (byte)(data[0] & 7);                                  // 3
            // aircraft icao
            adsbmess.AA = (uint)((data[1] << 16) + (data[2] << 8) + (data[3])); // 24

            Array.Copy(data, 4, adsbmess.adsbdata, 0, 7);                       // 56 bytes

            // paraity
            adsbmess.PI = (uint)((data[11] << 16) + (data[12] << 8) + (data[13])); // 24

            adsbmess.recvtime = DateTime.Now;

            // check parity
            Crc32ModeS crc = new Crc32ModeS();

            byte[] pidata = crc.ComputeChecksumBytes(data, 0, data.Length - 3, false);

            if (adsbmess.PI != ((pidata[0] << 16) + (pidata[1] << 8) + pidata[2]))
            {
                Console.WriteLine("Parity Fail");
                return(null);
            }

            // create the plane id
            string planeid = adsbmess.AA.ToString("X5");

            if (!Planes.ContainsKey(planeid))
            {
                Planes[planeid] = new Plane()
                {
                    ID = planeid
                }
            }
            ;

            if (adsbmess.DF == 17 &&
                (adsbmess.TypeCode >= 9 && adsbmess.TypeCode <= 18) ||
                (adsbmess.TypeCode >= 0x14 && adsbmess.TypeCode <= 0x16)
                ) // airbornepos
            {
                // odd
                if (adsbmess.Fcprformat)
                {
                    ((Plane)Planes[adsbmess.AA.ToString("X5")]).llaodd = adsbmess;

                    //Console.WriteLine("adsb " + planeid + " type " + adsbmess.DF + " odd");
                }
                else // even
                {
                    ((Plane)Planes[adsbmess.AA.ToString("X5")]).llaeven = adsbmess;

                    //Console.WriteLine("adsb " + planeid + " type " + adsbmess.DF + " even");
                }
            }
            else if (adsbmess.DF == 17 && adsbmess.TypeCode >= 1 && adsbmess.TypeCode <= 4) // ident
            {
                StringBuilder builder = new StringBuilder();

                int count = 8;
                for (int i = 0; i < count; i++)
                {
                    char   ch    = '\0';
                    byte[] char1 = adsbmess.getbits(adsbmess.adsbdata, 7 + i * 6, 6);

                    byte num2 = char1[0];

                    if ((num2 > 0) && (num2 < 0x1b))
                    {
                        ch = (char)(0x41 + (num2 - 1));
                    }
                    else if (num2 == 0x20)
                    {
                        ch = ' ';
                    }
                    else if ((num2 > 0x2f) && (num2 < 0x3a))
                    {
                        ch = (char)(0x30 + (num2 - 0x30));
                    }
                    if (ch != '\0')
                    {
                        builder.Append(ch);
                    }
                }

                adsbmess.Ident = builder.ToString();
                //Console.WriteLine("Ident " + builder.ToString());
            }
            else if (adsbmess.DF == 17 && adsbmess.TypeCode == 0x13) // velocity
            {
                int subtype  = adsbmess.adsbdata[0] & 7;
                int accuracy = (adsbmess.adsbdata[1] >> 3) & 15;

                switch (subtype)
                {
                case 3:
                case 4:
                    bool headingstatus = ((adsbmess.adsbdata[1] >> 2) & 1) > 0;
                    if (headingstatus)
                    {
                        ushort head    = (ushort)(((adsbmess.adsbdata[1] & 3) << 8) + adsbmess.adsbdata[2]);
                        double heading = head * 0.3515625;
                        ((Plane)Planes[adsbmess.AA.ToString("X5")]).heading = heading;
                    }
                    break;

                case 1:
                case 2:
                default:
                    bool westvel = ((adsbmess.adsbdata[1] >> 2) & 1) > 0;

                    int ewvel = (int)(((adsbmess.adsbdata[1] & 3) << 8) + adsbmess.adsbdata[2]);

                    bool southvel = ((adsbmess.adsbdata[3] >> 7) & 1) > 0;

                    int nsvel = (int)(((adsbmess.adsbdata[3] & 127) << 3) + (adsbmess.adsbdata[4] >> 5));

                    if (westvel)
                    {
                        ewvel *= -1;
                    }

                    if (southvel)
                    {
                        nsvel *= -1;
                    }

                    double cog = (Math.Atan2(ewvel, nsvel) * (180 / Math.PI));

                    Console.WriteLine("vel " + ewvel + " " + nsvel + " " + cog);

                    ((Plane)Planes[adsbmess.AA.ToString("X5")]).heading = (cog + 360) % 360;

                    break;
                }
            }
            else
            {
                Console.WriteLine("No processing type 0x" + adsbmess.TypeCode.ToString("X2") + " DF " + adsbmess.DF);
            }

            return((Plane)Planes[adsbmess.AA.ToString("X5")]);
        }
Пример #30
0
 private void ExtractAircraftParityIdentifier(ModeSMessage reply)
 {
     reply.Icao24 = (int)_BitStream.ReadUInt32(24);
 }
Пример #31
0
        /// <summary>
        /// AVR ASCii Format Input
        /// </summary>
        /// <param name="avrline"></param>
        /// <returns></returns>
        public static Plane ReadMessage(string avrline)
        {
            if (!avrline.StartsWith("*"))
                return null;

            log.Debug(avrline);

            avrline = avrline.Trim().TrimEnd(';');

            ModeSMessage adsbmess = new ModeSMessage();

            byte[] data = ConvertHexStringToByteArray(avrline.TrimStart('*'));

            if (data.Length < 13)
                return null;

            adsbmess.DF = (byte)(data[0] >> 3); // 5
            adsbmess.CA = (byte)(data[0] & 7); // 3
            // aircraft icao
            adsbmess.AA = (uint)((data[1] << 16) + (data[2] << 8) +(data[3])); // 24

            Array.Copy(data, 4, adsbmess.adsbdata, 0, 7); // 56 bytes

            // paraity
            adsbmess.PI = (uint)((data[11] << 16) + (data[12] << 8) + (data[13])); // 24

            adsbmess.recvtime = DateTime.Now;

            // check parity
            Crc32ModeS crc = new Crc32ModeS();
            byte[] pidata = crc.ComputeChecksumBytes(data, 0, data.Length - 3, false);

            if (adsbmess.PI != ((pidata[0] << 16) + (pidata[1] << 8) + pidata[2]))
            {
                Console.WriteLine("Parity Fail");
                return null;
            }

            // create the plane id 
            string planeid = adsbmess.AA.ToString("X5");
            if (!Planes.ContainsKey(planeid))
                Planes[planeid] = new Plane() { ID = planeid };

            if (adsbmess.DF == 17 && 
                (adsbmess.TypeCode >= 9 && adsbmess.TypeCode <= 18)
               || (adsbmess.TypeCode >= 0x14 && adsbmess.TypeCode <= 0x16)
                ) // airbornepos
            {
                // odd
                if (adsbmess.Fcprformat)
                {
                    ((Plane)Planes[adsbmess.AA.ToString("X5")]).llaodd  = adsbmess;

                    //Console.WriteLine("adsb " + planeid + " type " + adsbmess.DF + " odd");
                }
                else // even
                {
                    ((Plane)Planes[adsbmess.AA.ToString("X5")]).llaeven = adsbmess;

                    //Console.WriteLine("adsb " + planeid + " type " + adsbmess.DF + " even");
                }
            }
            else if (adsbmess.DF == 17 && adsbmess.TypeCode >= 1 && adsbmess.TypeCode <= 4) // ident
            {
                StringBuilder builder = new StringBuilder();

                int count = 8;
                for (int i = 0; i < count; i++)
                {
                    char ch = '\0';
                    byte[] char1 = adsbmess.getbits(adsbmess.adsbdata, 7 + i * 6, 6);

                    byte num2 = char1[0];

                    if ((num2 > 0) && (num2 < 0x1b))
                    {
                        ch = (char)(0x41 + (num2 - 1));
                    }
                    else if (num2 == 0x20)
                    {
                        ch = ' ';
                    }
                    else if ((num2 > 0x2f) && (num2 < 0x3a))
                    {
                        ch = (char)(0x30 + (num2 - 0x30));
                    }
                    if (ch != '\0')
                    {
                        builder.Append(ch);
                    }
                }

                adsbmess.Ident = builder.ToString();
                //Console.WriteLine("Ident " + builder.ToString());
            } 
            else if (adsbmess.DF == 17 && adsbmess.TypeCode == 0x13) // velocity
            {
                int subtype = adsbmess.adsbdata[0] & 7;
                int accuracy = (adsbmess.adsbdata[1] >> 3) & 15;

                switch (subtype)
                {
                    case 3:
                    case 4:
                        bool headingstatus = ((adsbmess.adsbdata[1] >> 2) & 1) > 0;
                        if (headingstatus)
                        {
                            ushort head = (ushort)(((adsbmess.adsbdata[1] & 3) << 8) + adsbmess.adsbdata[2]);
                            double heading = head * 0.3515625;
                            ((Plane)Planes[adsbmess.AA.ToString("X5")]).heading = heading;
                        }
                        break;
                    case 1:
                    case 2:
                    default:
                        bool westvel = ((adsbmess.adsbdata[1] >> 2) & 1) > 0;

                        int ewvel = (int)(((adsbmess.adsbdata[1] & 3) << 8) + adsbmess.adsbdata[2]);

                        bool southvel = ((adsbmess.adsbdata[3] >> 7) & 1) > 0;

                        int nsvel = (int)(((adsbmess.adsbdata[3] & 127) << 3) + (adsbmess.adsbdata[4] >> 5));

                        if (westvel)
                            ewvel *= -1;

                        if (southvel)
                            nsvel *= -1;

                        double cog = (Math.Atan2(ewvel, nsvel) * (180 / Math.PI));

                        Console.WriteLine("vel " + ewvel + " " + nsvel + " " + cog);

                        ((Plane)Planes[adsbmess.AA.ToString("X5")]).heading = (cog + 360) % 360;

                        break;
                }
            }
            else
            {
                Console.WriteLine("No processing type 0x" + adsbmess.TypeCode.ToString("X2") + " DF " + adsbmess.DF);
            }

            return ((Plane)Planes[adsbmess.AA.ToString("X5")]);
        }
Пример #32
0
 private void ExtractCapability(ModeSMessage reply)
 {
     reply.Capability = (Capability)_BitStream.ReadByte(3);
 }