Seppel2000and3 Posted November 6, 2003 Report Posted November 6, 2003 Hi, i tried the whole night, to calculate the bearing from to points in given format (dd.mmmm) I tried several things but didnt received the same result as in TrafficLook. I'm programming in C++, and if somebody can give me a hint i would be more happy than now. I hope its ok, when i post my last try here: - Lat1&Lon1 are my aircraft position from the offset described in the SDK - Lat2&Lon2 are the AI Aircraft position from the TCAS Data described in the SDK - The value for distance is okay, so it must be a fault with the bearing algorithm double Bearing(double Lat1, double Lon1, double Lat2, double Lon2) { double B1 = Lat1/180 * PI; //DEG to RAD double B2 = Lat2/180 * PI; double L1 = Lon1/180 * PI; double L2 = Lon2/180 * PI; double t1,t2,t3,t4,t5; double rad_bearing; double rad_dist = acos(sin(B1) * sin(B2) + cos(B1) * cos(B2) * cos(L1 - L2)); if (sin (L2 - L1) < 0.0) { t1 = sin(B2) - sin(B1) * cos(rad_dist); t2 = cos(B1) * sin(rad_dist); t3 = t1 / t2; t4 = atan(-t3 / sqrt(-t3 * t3 + 1)) + 2 * atan(1); rad_bearing = t4; } else { t1 = sin(B2) - sin(B1) * cos(rad_dist); t2 = cos(B1) * sin(rad_dist); t3 = t1 / t2; t4 = -t3 * t3 + 1; t5 = 2 * 3.14 - (atan(-t3) / sqrt(-t3 * t3 + 1)) + 2 * atan(1); rad_bearing = t5; } double BG = rad_bearing * 57.2957795; return BG; } Two hours ago, i tried another source (from an website) this gave me some values that were somehow in relationship with the values in TrafficLook. But they were always too small?!? I can post that later, if somebody wants ;-) OK, last word: Sorry for my bad english... Hope for good answers, Sebastian
Pete Dowson Posted November 6, 2003 Report Posted November 6, 2003 I tried several things but didnt received the same result as in TrafficLook. TrafficLook makes assumptions to keep things easier. it assumes the Earth is flat as far as the TCAS data range is concerned, for instance. The formula I use is: =========================== //dHdg = result in degrees //dDst = computed distance "in radians (i.e. nms * PI / (180 * 60))" //dMyLat = User Latitude, degrees //dMyLon = User Longitude, degrees //pt = pointer to current AI TCAS_DATA struct //MagVar = mag variation at user aircraft as WORD from FSUIPC dHdg = (dMyLat == pt->lat) ? 90.0 : (180.0 * atan(fabs(dDst/(pt->lat-dMyLat))) / PI); if (dMyLat >= pt->lat) { if (dMyLon >= pt->lon) dHdg += 180.0; else dHdg = 180.0 - dHdg; } else if (dMyLon > pt->lon) dHdg = 360.0 - dHdg; // correct for magvar dHdg -= (MagVar * 360.0 / 65536.0); if (dHdg < 0.0) dHdg += 360.0; if (dHdg > 360.0) dHdg -= 360.0; ========================== I don't think this is very accurate, it only uses elementary trigonometry, but it seems good enough for my purposes. If you are using it for missile launching you'll need to be more accurate I expect! :D :D :D Regards, Pete
Seppel2000and3 Posted November 6, 2003 Author Report Posted November 6, 2003 Hi, hmmpf, im getting crazy ;-) Thank you for your answer, but one answer = lots of new questions ;-) 1.) i compute the distance with this: double dDst = acos(sin(dMyLat) * sin(dAiLat) + cos(dMyLat) * cos(dAiLat) * cos(dMyLon - dAiLon)); do i have first the Lat and Lon values turn into RAD??? with (dMyLat/180 * PI) or something else? 2.) the magvar im getting from FSUIPC (long int), i have to recalculate it with something before i give it to my function? like this: db_own_magvar = (double)li_own_magvar * (360/65536); 3.) before return dHdg; i have to convert it to another format (RAD/DEG/360/PI or something else) Here is a short table from values you have in TrafficLook and i have: yours|mine 181|136.175 103|98.7678 179|136.144 271|270.908 152|129.048 346|313.924 Thats not very near the values you have ;-) Thanks for your answers, Sebastian
Pete Dowson Posted November 6, 2003 Report Posted November 6, 2003 i compute the distance with this: double dDst = acos(sin(dMyLat) * sin(dAiLat) + cos(dMyLat) * cos(dAiLat) * cos(dMyLon - dAiLon)); do i have first the Lat and Lon values turn into RAD??? with (dMyLat/180 * PI) or something else? The parameters for the C library functions sin() and cos() have to be in radians, yes. The result of the acos() will be in radians. Best do dMyLat * PI / 180.0 2.) the magvar im getting from FSUIPC (long int), i have to recalculate it with something before i give it to my function? like this:db_own_magvar = (double)li_own_magvar * (360/65536); The magvar from FSUIPC offset 0x2A0 is 16-bit (short int), not 32-bit. And, yes, you have to convert it as it is in FS units. But do NOT use "(360/65536)" as that will give you 0! Use double dMagVarDegrees = (sMagVar * 360.0) / 65536.0 Always multiply before division if you want more accuracy, and always remember literal numbers are taken as integers by default unless you use ".0". 3.) before return dHdg; i have to convert it to another format (RAD/DEG/360/PI or something else) Convert it to whatever you need. I convert it from radians to degres, then adjust it for Mag Var -- please look at my code again. Thats not very near the values you have ;-) I gave you the code I use. Sorry, I cannot really be more explicit. You will need to do your own debugging. Regards, Pete
Seppel2000and3 Posted November 7, 2003 Author Report Posted November 7, 2003 Hi, sorry i ask again, but this seems to be a very hard nut for me ;-) Im standing on EDDF (have a HDG of 111). Now my question, is -214 a good value for the MagVar??? What is the MagVar? Sorry, im posting again my try: ___MAIN.CPP___ TCAS_DATA slots[20]; // i know i can realize that with a list, but for testing its ok short int siMagVar; __int64 liMyOwnLat, liMyOwnLon; double dMyOwnLat, dMyOwnLon; //... getting datas from FSUIPC, then convert to degrees dMyOwnLat = liMyOwnLat * (90.0/(10001750.0 * 65536.0 * 65536.0)); dMyOwnLon = liOwnLon * (360.0/(65536.0 * 65536.0 * 65536.0 * 65536.0)); Bearing(dMyOwnLat,dMyOwnLon,slots[0].lat,slots[0].lon,siMagVar); ___MyTCAS.CPP___ double Bearing(double dMyLat, double dMyLon, double dAiLat, double dAiLon, short int MagVar) { double dHdg; // result in degrees double rad_dMyLat = (dMyLat * PI) / 180.0; // User Latitude converts to RAD double rad_dMyLon = (dMyLon * PI) / 180.0; // User Longitude converts to RAD double rad_dAiLat = (dAiLat * PI) / 180.0; // AI Latitude converts to RAD double rad_dAiLon = (dAiLon * PI) / 180.0; // AI Longitude converts to RAD double rad_dDst = acos(sin(rad_dMyLat) * sin(rad_dAiLat) + cos(rad_dMyLat) * cos(rad_dAiLat) * cos(rad_dMyLon - rad_dAiLon)); dHdg = (dMyLat == dAiLat) ? 90.0 : (180.0 * atan(fabs(rad_dDst/(rad_dAiLat-rad_dMyLat))) / PI); if (dMyLat >= dAiLat) { if (dMyLon >= dAiLon) dHdg += 180.0; else dHdg = 180.0 - dHdg; } else if (dMyLon > dAiLon) dHdg = 360.0 - dHdg; // correct for magvar dHdg -= ((MagVar * 360.0) / 65536.0); if (dHdg < 0.0) dHdg += 360.0; if (dHdg > 360.0) dHdg -= 360.0; //dHdg = (dHdg * 180) / PI; //(rad to deg); return dHdg; } Im very confused about this RAD and DEG things, but i need this Bearingvalue realy, want to implement a nice radar. I know im on the first mile of a marathon, but i like to do this ;-) Thanks for your great help, Sebastian
Pete Dowson Posted November 7, 2003 Report Posted November 7, 2003 Im standing on EDDF (have a HDG of 111). Now my question, is -214 a good value for the MagVar??? What is the MagVar? In FS2004 I get offset 0x02A0 (MagVar) reading 0xFF27 at EDDF. This is the same as decimal -214, which is -1.192 degrees. So, yes, you are reading the right value, pretty close anyway. Sorry, im posting again my try I am really not able to debug whole code segments for you. But I just realised I gave you wrong information last time. This comes from perusing commentless code written two years ago! Sorry. The "distance" I am using is NOT the distance! I don't use the distance to calculate the bearing. The thing I thought was the distance is merely a value representing the difference between Longitudes, but corrected for Latitude. In other words, my comment in what I gave you: //dDst = computed distance "in radians (i.e. nms * PI / (180 * 60))" is WRONG! dDst is dDst = cos(PI * (fabs(dMyLat+pt->lat))/360.0)*(pt->lon-dMyLon); which isn't even Radians, but Degrees still. It uses the cosine of the average of the two latitudes to "correct" the difference in Longitudes, for the "narrowing" effect as you progress nearer the poles. This would go horribly wrong very near the poles, but is adequate for my purposes when in normal latitudes. Let's change the name to "dLonDiff". Then is is used in your dHdg formula but in DEGREES not Radians, thus: dHdg = (dMyLat == dAiLat) ? 90.0 : (180.0 * atan(fabs(dLonDiff/(dAiLat-dMyLat))) / PI); This is simple trig on the triangle. The rest of the corrections for quadrants is the same. Sorry to have misled you before. I was trying to "convert" my messy code into something presentable, and obviously I failed to understand it even myself! :oops: Note that my methods are most definitely aproximate. They make lots of assumptions. I am using plane trigonometry and assuming this matters little over the 40-80 mile range of the AI 'targets'. If you want pin-point accuracy you will have to look up the proper spherical trig equations. If you need it to work properly at high latitudes you need to look up the proper spherical trig equations. Apologies again. Regards, Pete
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