Jump to content

FSUIPC TCAS?


Recommended Posts

Man I hate to ask a rookie question, but I am not clear on the the AI (TCAS) data provided by FSUIPC. I am using visual basic and don't expect any help in that area. I can handle that part. However, I do need to know how the offsets are broken down past offet F000. For example, do I go to offset F080 for the latitude of aircraft 1, F082 for the longitude, F084 for the altitude. Or is all the information provided at one offset?

Thanks in advance,

Link to comment
Share on other sites

I am using visual basic and don't expect any help in that area.

Well, there must be plenty of VB programmers around. I expect one or two here would be able to help if they see your message.

However, I do need to know how the offsets are broken down past offet F000. For example, do I go to offset F080 for the latitude of aircraft 1, F082 for the longitude, F084 for the altitude. Or is all the information provided at one offset?

I'm having some trouble understanding your question. In the Programmers Guide I provide a structure. Admittedly it is defined for C use. Can't it be converted to VB? Doesn't VB support any types of structure?

If not, all you need to know is that each 40 byte slot, starting with slot 0 at F080, contains:

Bytes 0-3: ID number as a 32-bit number (0 = slot not used)

Bytes 4-7: Latitude as a 32-bit floating point number

Bytes 8-11: Longitude as a 32-bit floating point number

Bytes 12-15: Altitude in feet as a 32-bit floating point number

Bytes 16-17: Heading as a 16 bit number in regular FS format

Bytes 18-19: Ground speed as a 16-bit number

Bytes 20-21: Vertical speed as a 16 bit number

Bytes 22-37: A zero-terminated ASCII character identity

Bytes 38-39: The COM1 frequency tuned in, in BCD (see Guide)

In the next version of FSUIPC, when it is used with FS2004, the string at 22-27 will be shortened by one byte and byte 37 will contain a status byte telling you what stage the AI aircraft has reached (taxi, takeoff, etc).

Hope this is clear.

Regards,

Pete

Link to comment
Share on other sites

OKay, the way I use the FSUIPC is by Offset and Size as given in your FSUIPC for Programmers guide. All of my functions utilize both offset and size. For example, to retrieve the Ground Altitude I use "H020" and "4" in a simple function written by Chris Brett. I know to use "HF080" for AI traffic but do not know the "size" values I need, since they are not listed in your handy guide. The information I need is there, but not in the form (or table) that I am used to.

Thanks Pete,

Link to comment
Share on other sites

I know to use "HF080" for AI traffic but do not know the "size" values I need, since they are not listed in your handy guide. The information I need is there, but not in the form (or table) that I am used to

Each SLOT is 40 bytes. So if you read 40 bytes at F080 you get all the data in Slot 1, in the format defined. There are 96 such slots, the next one starting at F0A8 (40 bytes ater the start of the first one).

In fact these size and count values can be read (size is at F000, the number of slots is at F002, as documented). However, they are likely to remain fixed, at least for another two years, so can be assumed unless you are really worried about long term compatibility.

You *can* read the whole set of 96 slots in one go, by reading 96 x 40 bytes at F080. This is actually what my TrafficLook does. Providing you don't do that too frequently this is fine.

However, there is a 96-byte array of single byte counters at F008 which tells you which slots are changed, so if you wanted to be more efficient you could read only the slots which have changed. This is more programming work, but less data transferred.

For a TCAS scan rate of say once or twice per second it probably doesn't matter.

All this information is there. If it was in the same form as the simple data it would say "TCAS data: F000, 4096 bytes" because the whole block of 4096 bytes (F000-FFFF) is reserved for the Airborne traffic data. In fact, if you look in the main table it IS there, in exactly that form!

However, specifying the data for up to 96 aircraft like that wouldn't help much, now would it? How would you decode the 4096 bytes without the additional data I give in the earlier parts of the document?

Please explain what it is you don't understand. I find it rather difficult to be more explicit, everything is defined quite precisely already.

Regards,

Pete

Link to comment
Share on other sites

  • 2 weeks later...

Mayby I should try to explain what I'm looking for another way. Let say I want to view the values using FS Interrogate. When looking at FS Interrogate, I have an address to the left ("F080") and values that appear in columns labeled 8 bit, 16 bit and so on. To get the ID number of the 1st aircraft, would I retrieve the value from the 32 bit column of F080? What about LAT, do I go to the F082 line or do I read another column of F080. The same question stands for LONG and altitude as well?

Is this easier for you to understand?

Link to comment
Share on other sites

Mayby I should try to explain what I'm looking for another way. Let say I want to view the values using FS Interrogate.

Hmmm. Unfortunately, FSInterrogate is missing the numeric format used for much of the data in the AI Traffic tables -- the 32 bit floating point values, type "float". It does have a "double" floating point format which is 64 bits, but I couldn't use up that much space for each aircraft or there'd only be room for half the number.

Pelle was working on an update to FSInterrogate, but I fear work commitments have got in the way.

When looking at FS Interrogate, I have an address to the left ("F080") and values that appear in columns labeled 8 bit, 16 bit and so on. To get the ID number of the 1st aircraft, would I retrieve the value from the 32 bit column of F080?

Certainly that is possible -- the ID is a mere 32-bit unsigned integer ("DWORD"). Hwever, this is the ID only of the first slot, not necessarily populated by an aircraft. There are 96 such slots, the next starting another 40 bytes further up, at F0A8.

What about LAT, do I go to the F082 line or do I read another column of F080. The same question stands for LONG and altitude as well?

Since the offset F080 is pointing to the 32 bit (= 4 bytes) of the ID, the whole of the offsets from F080 to F083 inclusive are occupied by that ID. A DWORD is 32 bits = 4 bytes = 4 address values. See?

There is no possibility of the same 32 bits being simultaneously used for two different values. Things can't work that way, it is not possible. So neither F080 nor F082 will ever contain the Latitude.

As shown by the structure, the Latitude is a float and follows the Id, so will be 4 bytes further on, at F084 (assuming that slot is actually populated).

PLEASE PLEASE see the Documentation I provide in the SDK. Surely the structure shown there, albeit in C format, is perfectly clear? The structure shows a number of values occupying fixed positions inside each 40 byte slot. The 40 bytes is made up of 4 for the ID, 4 for each "float" value, 2 for each word, and so on. The types are standard C or Windows types and the structure can be used exactly as provided there to define those positions and types in a C or C++ Windows program. Just cut and paste.

I'm sure conversion to whatever language you wish to use shouldn't be so hard. What is really the problem? You are talking rather as if you are new to computers. If so, then I'm afraid I am the wrong person to try to teach you. If not, then I'm sorry for continuing to misunderstand you.

Regards,

Pete

Link to comment
Share on other sites

Hi again,

Just reviewing this thread, I see I already replied to you before and I actually already gave you explicit offsets within each slot, so even if you didn't understand the C format structure you should still have worked out your error. In case you missed it, here's the relevant part again:

If not, all you need to know is that each 40 byte slot, starting with slot 0 at F080, contains:

Bytes 0-3: ID number as a 32-bit number (0 = slot not used)

Bytes 4-7: Latitude as a 32-bit floating point number

Bytes 8-11: Longitude as a 32-bit floating point number

Bytes 12-15: Altitude in feet as a 32-bit floating point number

Bytes 16-17: Heading as a 16 bit number in regular FS format

Bytes 18-19: Ground speed as a 16-bit number

Bytes 20-21: Vertical speed as a 16 bit number

Bytes 22-37: A zero-terminated ASCII character identity

Bytes 38-39: The COM1 frequency tuned in, in BCD (see Guide)

Now do you see how, if the first byte above is at offset F080 (i.e the first slot), the Latitude cannot possible be at F080 or F082? You see it says the Latitude is at bytes 4-7?

F080 + 4 = F084. Not F080 nor F082! Both those offsets are part of the ID because they lie in the range F080-F083 as occupied by the ID, which is in the first 4 bytes of each 40 byte slot.

Okay?

What is not clear about this? I really am running out of ways to make this as simple as possible.

Regards,

Pete

Link to comment
Share on other sites

Ahhhhh....now it makes sense. Not that I'm insulted by the suggestion that I'm a newby to computers all together, but just remember this; I'm sure there are a few things I can twist you into knots about too. Once again, thanks for your help. I'll try not to sound so lame next time.

D. King

Link to comment
Share on other sites

Ahhhhh....now it makes sense. Not that I'm insulted by the suggestion that I'm a newby to computers all together, but just remember this; I'm sure there are a few things I can twist you into knots about too.

Very likely you can, and I was trying very hard not to sound like I was talking to a complete beginner, but it was very difficult. After all I had already given you all the information. Even the original documentation in the SDK does have an explicit structure.

The TCAS facilities were originally publish nearly two years ago and I've not had to go to anything like these lengths before to explain them. The SDK is actually aimed at programmers so does make assumptions about basic knowledge.

If it was the structure business you didn't understand you would have asked, surely? Then the fact that you thought that two different 32 bit values could occupy the same or overlapping offsets seemed very strange and I though must indicate some very basic misunderstandings of how computers work. Maybe there were other reasons for this, and if so I'm sorry to have made incorrect assumptions.

Pete

Link to comment
Share on other sites

OKay....got some of the values to work.....Lat, Long, Alt, Hdg Grd Spd. One of the original problems I had was the code I was using (VB) did not like Hex values up at F000. I cured the problem by converting the numbers to decimal form and referencing the address in this format versus Hex. This is weird since all the other data was retrieved using Hex values. Oh well, whatever works.

Now at least, I've got some data displayed to work with.

Thanks again Pete.

Link to comment
Share on other sites

Hi,

If you use VB.NET use the FSUIPC SDK and the .NET example.

Then add the following lines.

I'm sure it's cleaner way's to do it, but this was what I could come up with right now.

/Richard

'****Code *****
'40 byte structure:

 _
    Structure TCAS_DATA
        Dim id As Integer 
        Dim lat As Single
        Dim lon As Single
        Dim alt As Single
        Dim hdg As Short
        Dim gs As Short
        Dim vs As Short
 _
        Dim idATC() As Byte
        Dim com1 As Short
    End Structure

    Sub Test_TCAS_DATA()

        Dim dwResult As Integer
        Dim Token As Integer
        Dim result As Integer
        Dim fsByte(4095) As Byte
        Dim TCA(0) As TCAS_DATA
        Dim T As System.Type
        T = TCA(0).GetType

        Try
            If Connected Then
                If FSUIPC_Read(&HF000, 4096, Token, dwResult) Then
                    If FSUIPC_Process(dwResult) Then
                        If FSUIPC_Get(Token, 4096, fsByte) Then
                            Dim i As Integer
                            Dim j As Integer
                            Dim k As Integer

                            Dim StrByte(39) As Byte
                            For i = 128 To 4095
                                StrByte(j) = fsByte(i)
                                j += 1
                                If j = 40 Then
                                    ReDim Preserve TCA(TCA.Length)
                                    TCA(TCA.Length - 1) = UnSafeByteArrayToStructure(StrByte, T)
                                    Erase StrByte
                                    ReDim StrByte(39)
                                    j = 0
                                    k += 1
                                    If k = 96 Then Exit For 'we are finish with the loop

                                End If
                            Next

                            'To Test the name of the 5th record you can convert the byte to string like this
                            System.Text.Encoding.ASCII.GetString(TCA(5).idATC)

                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            Debug.WriteLine("Error: " & ex.Message)
        End Try

    End Sub


'* help methodes for converting Byte to Structure:

    Public Function UnSafeByteArrayToStructure(ByVal b() As Byte, ByVal t As Type) As ValueType
        Dim p As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(b.Length)
        Try
            Runtime.InteropServices.Marshal.Copy(b, 0, p, b.Length)
            Dim vt As ValueType = Runtime.InteropServices.Marshal.PtrToStructure(p, t)
            Return vt
        Finally
            Runtime.InteropServices.Marshal.FreeHGlobal(p)
        End Try
    End Function

    Public Function UnSafeStructureToByteArray(ByRef s As ValueType) As Byte()
        Dim bc As Integer = Runtime.InteropServices.Marshal.SizeOf(s)
        Dim p As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(bc)
        Try
            Runtime.InteropServices.Marshal.StructureToPtr(s, p, False)
            Dim b(bc - 1) As Byte
            Dim i As Integer
            For i = 0 To bc - 1
                b(i) = Runtime.InteropServices.Marshal.ReadByte(p, i)
            Next
            Return b
        Finally
            Runtime.InteropServices.Marshal.FreeHGlobal(p)
        End Try
    End Function

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.