Jump to content
The simFlight Network Forums

How do get the Bearing for an AI Aircraft???


Recommended Posts

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
×
×
  • 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.