thomsany Posted December 20, 2007 Report Posted December 20, 2007 Hi Pete, Just a quick question. How can I do so that my data from the Process() function can return new values every 1 second? I am looking into Loops but I don't see how I can use it to spit out the refreshed values from the FSUIPC module. Any suggestions? Here is what I have: FSUIPCConnection.Process() Dim groundspeedKnots As Integer = groundspeed.Value / 65536D Dim groundalt As Integer = (groundaltinput.Value / 256) * 3.28 Dim zulutimehour As String = zulutimehourinput.ToString Dim zulutimemin As String = zulutimemininput.ToString 'Asigno valores a los labels lblgroundspeed.Text = groundspeedKnots.ToString lblaltitude.Text = groundalt.ToString
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 How can I do so that my data from the Process() function can return new values every 1 second? I am looking into Loops but I don't see how I can use it to spit out the refreshed values from the FSUIPC module. No, don't use loops. You should use the Windows timer facilities to create a timer event every second, and do all your requests there. The only FSUIPC calls which should be outside that, in the main program, are the Open and Close calls. I don't know VB I'm afraid, but the Windows API calls as seen from a C/C++ program are SetTimer and KillTimer. Regards Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 Ok great, I was thinking on that as well. Its better than loops. Other than that, I am getting somewhere reading your documentation. Its very helpful :) The only problem I am having right now is when I import the Ground Altitude from Offset H020. I get the value and divide it by 256 to get the Metres value. For some reason the value is not accurate at all. Here is my declaration and my conversion to the variable so that I can display it in the label inside VB. Dim groundaltinput As Offset(Of Integer) = New FSUIPC.Offset(Of Integer)(&H20) FSUIPCConnection.Process() Dim groundalt As Integer = (groundaltinput.Value / 256) * 3.28 lblaltitude.Text = groundalt.ToString For some reason I am at 3000 feet and the output is 385. Very strange. Basically I am taking the value, converting it to meters by dividing it by 256 and then multiplying the result by 3.28 to get the altitude in Feet. Do you see an error on my code? Regards, Teo
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 Dim groundalt As Integer = (groundaltinput.Value / 256) * 3.28 lblaltitude.Text = groundalt.ToString For accuracy you should copy the original value into a floating point variable first, before doing any calculations. The way you have it you are losing all fractions of a metre. For some reason I am at 3000 feet and the output is 385. Very strange. What is the original value you are reading? Don't forget it is the GROUND altitude you are reading, not "your altitude". They are only the same, or nearly so, when you are on the ground. Don't forget that you can easily check what you are actually reading by using FSUIPC's logging facilities -- enable IPC read logging and check the log. I know the data there is in Hexadecimal, so it takes some working out (I actually have a hex calculator), but even if you can't figure it out, I can tell you what is happening. I can't do that from snippets of VB (or even whole chunks of VB). Regards Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 Hi Pete, Thanks much for your help. Is there a formula you know that can get me the MSL altitude? I don't see that value on your list of Offsets. How can I get it? Regards, Teo
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 Is there a formula you know that can get me the MSL altitude? I don't see that value on your list of Offsets. You mean your aircraft's altitude, AMSL? Use search when looking for things in the list. Searching on "altitude" would soon find it. Check offset 0570. It is among the 6 values which define your aircraft position and altitude exactly -- "LLAPBH" in order = Latitude, Longitude, Altitude, Pitch, Bank, Heading. Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 Yeah I will have to use the search function to look things up, lots of stuff going on in there hahaha :) Sorry I keep bothering you so much :roll: Anyways, ok, I did some testing by setting the values for the altitude from 0574 to a Long value (8bit) and displaying it, however I am getting a loooong number in negative -1170756313435. I don't know how to interpret this to convert it to a normal altitude value. In the documentation you don't specify if I have to divide it or multiply it by something to get the value. For example the value I am showing you is for 432MSL of altitude. Is there a number I need to multiply, divide or convert? Once again, sorry for hassling you so much. I just want to understand how to do things so I can move on with the application. As soon as I have it ready, I want you to try it, and let me know :) Regards, Teo
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 I did some testing by setting the values for the altitude from 0574 to a Long value (8bit) and displaying it, however I am getting a loooong number in negative -1170756313435. Hold on. You are reading 0574 (which is the upper half of the 64-bit value, the whole number of metres) into a "Long value (8bit)". What does "Long value (8bit)" mean? 8 bits make one byte. There's no way -1170756313435 will fit into 32-bits (which is all you have at 0574) let alone 8 bits! Please be a little clearer about what you are doing. And PLEASE PLEASE start useing the tools provided -- especially the Logging. Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 Hi Pete, Sorry, I'm very confused on the types of variables I should use for each reading. For example, for 32bit altitude reading, I used a variable of type Single. Also for the fractional part. Its my first time working with your software for developing and I am having a hard time know which variable type to use for example, 32bit integer, long long 64 bit, etc. I get confused on which type of variable I should use for each one. Now that I I believe that's my main problem, not the documentation. I will try to solve it on my own. Regards, Teo
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 Sorry, I'm very confused on the types of variables I should use for each reading.For example, for 32bit altitude reading, I used a variable of type Single. What's a "Single"? You said 8-bit last time. Surely you don't mean that? Its my first time working with your software for developing and I am having a hard time know which variable type to use for example, 32bit integer, long long 64 bit, etc. I get confused on which type of variable I should use for each one. I would have thought that giving the bit-size and the representation type (integer, fraction, or floating point) would be much clearer than using C or C++ technical terms. After all every language has its own set of types with its own names. What you really seem to need is a reference list of what variable types you can have in your chosen language. Please think about using the tools provided -- especially the logging, which you seem to have ignored completely. Also FSInterrogate, which can show you all these values in all sorts of different representations. Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 Single is a float in VB. Its A floating-point (decimal) positive or negative number with a value in the range of up to 3.402823E38 (scientific notation). Double is the same, double A floating-point (decimal) positive or negative number with a value in the range of up to 1.79769313486232E308. The only one I can't find is fractional. I don't know what type of variable that is. I am looking at the logs but to be frankly I am not that familiar looking at Hex entries. Any suggestions on what the fractional type of value might be. I don't see that in my variable types in VB. How many bits? Regards, Teo
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 Single is a float in VB. Its A floating-point (decimal) positive or negative number with a value in the range of up to 3.402823E38 (scientific notation). So why are you reading a fixed point integer into a floating point variable? It is bound to be misinterpreted! The only one I can't find is fractional. I don't know what type of variable that is. There's no such variable type. Where are you reading type "fractional"? Look at the description of 0570. It says the integer part is in the top part, as a 32 bit integer, and the fractional part is in the lower part, also as a 32-bit integer (but it will be unsigned). Consider a decimal number with fractional parts: e.g 3.142. The integer part is 3, the fractional part is 0.142. But you could consider storing that 142 bit in a 4 digit decimal store capable of values 0000 to 999. So it could be stored as 0142. To recoup the original value you'd read the integer part, 3, and add the fractional part re-made into a fraction, 142/1000. The factional part of the altitude is such that it runs from 0 to the whole 32-bits worth (65536 * 65536, I don't remember the actual number). So, you read the integer, copy it to a double or float, then read the fraction, copy it to a double or float and divide it bt 65536*65536, then add it to the integer part. There's one slight complication. If the integer part was negative, then so must be the fractional part, so you have to test for that and subtract the fraction, not add. All this is made much much (much) simpler if your compiler supports 64-bit integers. The microsoft C/C++ one does, they are __int64's. By reading all 8 bytes from 0570 into an __int64 it becomes a doddle: __int64 alt; ... read 8 bytes from 0570 into alt, then double dAlt = (double) alt / (65536.0 * 65536.0); I don't see that in my variable types in VB. How many bits? You are not reading the description for 0570, where it tells you that. It's the first 32 bits. The next 32 bits (at 574) are the integer. Regards Pete
thomsany Posted December 20, 2007 Author Report Posted December 20, 2007 OK just did a search and found out that my compiler does allow 64bit Integer, its called UInt64 in VB for reference. So basically, I take out the Integer value out of it and append the 8 bits of the lower part and divide it by the numbers you have. I will try that, sorry for all the confusion, I am starting to get things now. I am doing this software on the side and I am not a full time programmer, and yeah, I don't know that much either :P But thanks so much for your help, its really appreciated!
Pete Dowson Posted December 20, 2007 Report Posted December 20, 2007 OK just did a search and found out that my compiler does allow 64bit Integer, its called UInt64 in VB for reference. Good. That makes it dead easy, as I said. So basically, I take out the Integer value out of it and append the 8 bits of the lower part and divide it by the numbers you have. No no no! How do you work that out? Where does this business of 8 bits come in? Please re-read what I said before about how easy it is with a 64 bit number: By reading all 8 bytes from 0570 into an __int64 it becomes a doddle:__int64 alt; ... read 8 bytes from 0570 into alt, then double dAlt = (double) alt / (65536.0 * 65536.0); You surely aren't reading "8 bytes" as "8 bits" are you? They are very differntt. a byte is 8 bits, so 8 bytes is 8 x 8 = 64 bits, the 64 bits representing the whole number, fraction and all. You don't need to separate anything! Pete
thomsany Posted December 21, 2007 Author Report Posted December 21, 2007 Hi Peter, I am still having issues with the Altitude value.. for some reason I did the following... Requesting both Offsets and getting them as Int 64bit and saving each to a variable called groundaltinputa and groundaltinputb. Dim groundaltinputa As Offset(Of UInt64) = New FSUIPC.Offset(Of UInt64)(&H574) Dim groundaltinputb As Offset(Of UInt64) = New FSUIPC.Offset(Of UInt64)(&H570) After that, I am doing the following: Dim groundalta As Double= CDbl(groundaltinputa.Value) 'Converting to double Dim groundaltb As String = CDbl(groundaltinputb.Value) / (65536.0 * 65536.0) Converting second value from 0570 to Double and applying formula. Now here is where I am having issues. I have both values but how do I put them together to make up the altitude. I have the first value from 0574 and the second from 0570. Here is where I'm stuck. I hope this might give you a better view of my issue. I already have the Lat/Long working, the Groundspeed and the UTC time which is great. I am missing this one. Thanks for everything, I know your time is valuable. Regards, Teo
quantumleap Posted December 21, 2007 Report Posted December 21, 2007 Teo, Try something like this: In the section where you define what FSUIPC offsets you are interested in Dim altitude As Offset(Of Long) = New FSUIPC.Offset(Of Long)(&H570) NOTE - This is the altitude of the aircraft and not the ground, you cannot get ground altitude. In your section of code after you have got this offset data via FSUIPC, you calculate the altitude with a number and a fractional part something like this Dim rawFakeAlt As Long Dim tmpAltDbl As Double rawFakeAlt = altitude.Value tmpAltDbl = CDbl(rawFakeAlt / (65536.0 * 65536.0)) At this point, the value you have in tmpAltDbl is what you want e.g. 200.34 metres. You can of course obfuscate the code and shorten it, but I wanted to show you how the raw data from FSUIPC is taken (as the 8 bytes which Pete explained) and then easily handled by his calculation to get the answer you are looking for. Hope this helps. Jeff
Pete Dowson Posted December 21, 2007 Report Posted December 21, 2007 I am still having issues with the Altitude value.. for some reason I did the following... Requesting both Offsets and getting them as Int 64bit and saving each to a variable called groundaltinputa and groundaltinputb. Dim groundaltinputa As Offset(Of UInt64) = New FSUIPC.Offset(Of UInt64)(&H574) Dim groundaltinputb As Offset(Of UInt64) = New FSUIPC.Offset(Of UInt64)(&H570) Why oh why? Only 0570 is a 64 bit value. You only needed to get 0570 and 0574 separately when reading them into two separate 32-bit values. See the digits 0 and 4 at the ends of the offset addresses? That's the number of bytes between them -- 4 bytes = 4 x 8 = 32 bits! Now here is where I am having issues. I have both values but how do I put them together to make up the altitude. You don't need both values -- the one you are reading from 0574 is rubbish, as it will have half of the altitude and half of the next offset (0578) in it! Why don't you please just READ what I WRITE and copy that? I repeat it here for the THIRD time! By reading all 8 bytes from 0570 into an __int64 it becomes a doddle:__int64 alt; ... read 8 bytes from 0570 into alt, then double dAlt = (double) alt / (65536.0 * 65536.0); I really cannot understand why you are repeatedly and completely IGNORING what I am showing you! The WHOLE POINT of using the 64-bit value is that you get it exactly as you want it all in one go!!!! :-( Pete
thomsany Posted December 21, 2007 Author Report Posted December 21, 2007 Pete, Is not that I am ignoring you, I wasn't understanding you. When I read the explanations on the word document, it was kind of confusing and since you work with C its a bit hard to understand the different variables etc. Anyways, I got it to work :) Finally hahaha When Jeff posted the VB example it was easier for some reason. Thanks much Pete and Jeff!!! Teo
Pete Dowson Posted December 21, 2007 Report Posted December 21, 2007 Is not that I am ignoring you, I wasn't understanding you. Not even the bit in English, saying "By reading all 8 bytes from 0570 into an __int64 it becomes a doddle", and ".. read 8 bytes from 0570 into alt, then ..."? That's hardly programming language. You already understood my "__int64" because you found the VB equivalent! Even if some of it (little as it was in any case) was more C than VB, you could see in English that the was only the one read into the one 64-bit variable, because I said so, in English. Three times! I really don't understand how it could have been stated simpler, at all. :-( Pete
Pete Dowson Posted December 21, 2007 Report Posted December 21, 2007 NOTE - This is the altitude of the aircraft and not the ground, you cannot get ground altitude. Yes you can. See offset 0020. Pete
quantumleap Posted December 21, 2007 Report Posted December 21, 2007 See offset 0020. Thanks Pete! You learn something every day :D Have a great Christmas and New Year. Jeff
DKing86 Posted December 23, 2007 Report Posted December 23, 2007 Hi Teo, The following are the formulas I use in VB to get Altitude in MSL and Ground (RADAR) Altitude. 'Altitude in MSL Dim BaroCorr As Long, AtmosCorr As Long, CorrDiff As Single Dim lngAltitude As Long, lngMeterAlt1 As Long, lngMeterAlt2 As Long, lngMillibars as Long, lngPressQNH as Long Dim lngGrdAlt As Long 'Use the following offsets for Altitude MSL 'I store each offset value in a long integer 'The following is not code; it is only intended to identify the offsets you need lngMillibars = &H330 (Size 2, 16-bit) lngPressQNH = &HEC6 (Size 2, 16-bit) lngMeterAlt1 = &H570 (Size 4, 32-bit) lngMeterAlt2 = &H574 (Size 4, 32-bit) BaroCorr = (145442.2 * (1 - (((lngMillibars / 16) * 0.02953) / 29.92126) ^ 0.190261)) 'correction due to the baro setting AtmosCorr = (145442.2 * (1 - (((lngPressQNH / 16) * 0.02953) / 29.92126) ^ 0.190261)) 'correction due to the actual atmospheric pressure CorrDiff = BaroCorr - AtmosCorr lngAltitude = Round((lngMeterAlt1 * 3.28084 / 4294967296#) + (lngMeterAlt2 * 3.28084), 4) - CorrDiff 'for Ground Altitude lngGrdAlt = &H20 (Size 4, 32-bit) AGL_Alt = Round(lngAltitude + CorrDiff, 0) - (Round(((lngGrdAlt / 256) * 3.2808) + 12, 0)) This may seem a little complicated but if you can get it to work, I think you'll see it accomplishes everything that you need. The corrections are necessary in MS flight sim to avoid erroneous ground altitude readings when the altimeter is not set correctly. In real aircraft radar altitude display is not be affected by baro settings. Hope this helps.
BAW019 Posted December 26, 2007 Report Posted December 26, 2007 Have to say I'm a bit baffled at the amount of code sloshing around here. My VB6 program uses the following lines of code to succesfully return Altitiude (ASL) and Radio Altitude (AGL) from two offsets (obviously I've hidden lot of interim lines of code. These are the relevant bits, the only bits that you really need to know) ' Plane's altitude in feet above sea level Private pdRC As Long Private mAltitude As Long FSUIPC_Read &H3324, Len(mAltitude), VarPtr(mAltitude), pdRC ' Planes height above ground (converted from meters. Data is stored as a factor of 65535) Private mRadioAlt As Long FSUIPC_Read &H31E4, Len(mRadioAlt), VarPtr(mRadioAlt), pdRC mRadioAlt = (mRadioAlt / 65535!) * 3.28084 Hope this helps - Merry Christmas to all! Ian
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now