brightening-eyes Posted October 27, 2017 Report Posted October 27, 2017 hello, as the title says it all, i want to read the heading into my application (through C++) i've tried everything that came to my mind to fix this, but i couldnt fix this this is my code: //this function normalizes the heading uint32_t normalize_heading(int32_t h) { if(h>359) { h-=359; } else if(h<0) { h+=359; } return h; } unsigned int heading; short mag_var; if(FSUIPC_Read(0x0580, 4, &heading, &result)&&FSUIPC_Process(&result)) { if(FSUIPC_Read(0x2A0, 2, &mag_var, &result)&&FSUIPC_Process(&result)) { double hdg1=heading*360/65536; double hdg2=mag_var*360/65536; double hdg3=hdg1-hdg2; hdg3=normalize_heading(hdg3); show_heading(hdg3); i've also tried this when calculating the heading: unsigned int heading; short mag_var; if(FSUIPC_Read(0x0580, 4, &heading, &result)&&FSUIPC_Process(&result)) { if(FSUIPC_Read(0x2A0, 2, &mag_var, &result)&&FSUIPC_Process(&result)) { double hdg1=heading*360/(65536*65536); double hdg2=mag_var*360/65536; double hdg3=hdg1-hdg2; hdg3=normalize_heading(hdg3); but compiler gave warning about devide by zero then when i run this, it crashes my application thanks in advance for your help peter
Pete Dowson Posted October 27, 2017 Report Posted October 27, 2017 The trouble with all of your assignments to doubles is that the conversion to the double is the LAST thing which is done. So in both cases double hdg1=heading*360/65536; double hdg2=mag_var*360/65536; the result of multiplying the heading by 360 is already going ot overspill the 32-bits (4 bytes) in your "int" (or only 16 bits in the case of mag_var. So you need to force the conversion earlier, by this: double hdg1=heading*360.0/65536.0; double hdg2=mag_var*360.0/65536.0; 3 hours ago, brightening-eyes said: but compiler gave warning about devide by zero Yes, because 65536*65536 exceeds the capacity of 32 bits: 0x10000 * 0x10000 = 0x100000000 so the remaining 32 bits is zero which you are using as divisor. Pete
brightening-eyes Posted October 28, 2017 Author Report Posted October 28, 2017 hi again, another thing that i had to do in order to get the aircraft heading: i had to devide hdg3 with 65536.0 also (i've set them to int) when i didnt do it, it would give me an inaccurate value such as 17733729 which is quite wrong and i didnt knew this also peter thanks for giving those suggestions it relly helped me descover and fix my problem related to those doubles which was 5 digit number integers it works fine now again thank you
Pete Dowson Posted October 28, 2017 Report Posted October 28, 2017 Your normalize is wrong too. Headings run either 0 to 359 or, more usually 1 to 360. Using the math on the offset data you get 0-359.99999 ... It cannot be outside that range because anything like 360 or more won't fit. That's the whole idea of the units used --they use all of the 32 bits to give maximum precision for that range. The "normalize" is just taking care of the possibility that converting to magnetic instead of true takes the value outside that range. So instead of: 14 hours ago, brightening-eyes said: uint32_t normalize_heading(int32_t h) { if (h > 359) { h -= 359; } else if (h < 0) { h += 359; } return h; } the += 359 should be +=360 and similarly the -= 359 should be -= 360. If you want 360 instead of 0 then you need to change it more, of course. Also, you declare h as an int32 yet call it with a double as parameter. Doesn't the compiler tell you? Don't you want fractions? If not shouldn't you round it properly first -- e.g. add 0.5 before it gets converted from double to int. Otherwise for example for 23.9 you'll get 23 whereas you should have 24. Pete
brightening-eyes Posted October 28, 2017 Author Report Posted October 28, 2017 hi again pete, thanks again, i have fixed this and rounded it
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