Jump to content
The simFlight Network Forums

problems with reading aircraft position with delphi


Recommended Posts

Hello,

I tryed to read out the aircraft position Longitude and Latitude

here is my code:

procedure TForm1.Button5Click(Sender: TObject);
var dwresult : dword;
    Longitude : int64;
    Latitude : int64;
    lat , lon : extended;
begin
  FSUIPC_read($0568,8,@Longitude,dwresult);
  FSUIPC_read($0560,8,@Latitude,dwresult);
  if FSUIPC_Process(dwResult)then
   begin
   lat := latitude * 90 / (10001750.0 * 65536.0 * 65536.0);
   lon := Longitude * 360 / (65536.0 * 65536.0 * 65536.0 *  65536.0);
   showmessage(inttostr(Latitude) + ' / ' + floattostr(lat));  //shows correct value
   showmessage(inttostr(Longitude) + ' / ' + floattostr(lon)); // shows invalid value
   end;

end;

the problem is that I do not get a correct value for the Longitude.

example EDDF N50* 1.66' / E8* 32.09'

results are 50,0277.... (correct) and -0.465... (incorrect)

What is not correct on my code?

Link to comment
Share on other sites

the problem is that I do not get a correct value for the Longitude.

example EDDF N50* 1.66' / E8* 32.09'

results are 50,0277.... (correct) and -0.465... (incorrect)

What is not correct on my code?

Can you show me the raw value before you try to compute the longitude? You can use FSInterrogate2 to monitor these things also. It would be helpful to you when debugging your software. You'll find FSInterrogate in thee FSUIPC SDK. (It was written in Delphi also!). For instance, I just went to EDDF (active runway selection, whichever that was) and FSInterrogate shows this for those offsets:

Viewing the longitude computation which FSInterrogate2 performs, you'd see this:

which appears to suggest a discrepancy between what you are reporting and what is actually happening, since the computation looks to be the same, doesn't it?

Regards

Pete

post-1817-128689691071_thumb.jpg

post-1817-128689691075_thumb.jpg

Link to comment
Share on other sites

Hello Pete,

thirst thanks for your great support here...

I get the same values like your FSInterogate, so there is no fault there.

I also solved the problem. Now I get the correct value. But it is strange... because the fault is loceted in this line...

This code works correctly:

function GetLongitude : double;
var dwresult : dword;
    Longitude : int64;
begin
  FSUIPC_read($0568,8,@Longitude,dwresult);
  if FSUIPC_Process(dwResult)then
    result := longitude / (65536.0 *65536.0 * 65536.0) * 360 / 65536.0; //* 360 / (65536.0  * 65536.0 * 65536.0 * 65536.0);

end;

This code doesn't work:

function GetLongitude : double;
var dwresult : dword;
    Longitude : int64;
begin
  FSUIPC_read($0568,8,@Longitude,dwresult);
  if FSUIPC_Process(dwResult)then
    result := longitude * 360 / (65536.0 *65536.0 * 65536.0 * 65536.0); //* 360 / (65536.0  * 65536.0 * 65536.0 * 65536.0);

end;

The fault occurs when using this formating code: longitude * 360 / (65536.0 *65536.0 * 65536.0 * 65536.0); //* 360 / (65536.0 * 65536.0 * 65536.0 * 65536.0);

It is very strange...

Link to comment
Share on other sites

I'll repost the code I posted on mycockpit's forums as I know it works....

var dwresult : dword;
    Lat,Lon : int64;
   latitude,longitude:extended;
begin

  if (FSUIPC_Read($0560,8, @Lat, dwResult))and(FSUIPC_Read($0568,8, @lon , dwResult)) then
  if FSUIPC_Process(dwResult) then
    begin
    latitude := Lat/ 10001750;
    latitude := latitude /65536 ;
    latitude := latitude /65536 ;
    latitude := latitude *90;  //I separate those lines as sometimes it causes stack overflow on my system)
    longitude := Lon / 65536 ;
    longitude := longitude /65536 ;
    longitude := longitude /65536 ;
    longitude := longitude /65536 ;
    longitude := longitude *360;
    showmessage(floattostr(latitude)+'  /  '+inttostr(Lat)   );
   showmessage(floattostr(longitude)+'  /  '+inttostr(Lon)   );
    end;

As I said, in delphi you might raise a stack overflow exception if you do operations such as 360 / (65536.0 * 65536.0 * 65536.0 * 65536.0) in the same line.

Also it is a good idea to first divide by the big values ( i.e. 65536.0 * 65536.0 * 65536.0 * 65536.0 or 10001750.0 * 65536.0 * 65536.0 ) then multiply by 360 or 90 (if the integer value you read is just below the maximum size allowed for a 8byte integer, multiplying it will do strange things, like truncating to the 8 bytes allocated...).

I also think you should request the FSUIPC offset you want to retrieve then process them in one ifthen operation:

if (FSUIPC_Read($0560,8, @Lat, dwResult))and(FSUIPC_Read($0568,8, @lon , dwResult)) then  if FSUIPC_Process(dwResult) then begin
     //code to execute
end;

instead of:

FSUIPC_read($0568,8,@Longitude,dwresult);
FSUIPC_read($0560,8,@Latitude,dwresult);
if FSUIPC_Process(dwResult)then begin
//code to execute
end;

Hope that helps.

Link to comment
Share on other sites

I also solved the problem. Now I get the correct value. But it is strange...

Okay, I see what is going on:

This code works correctly:

...

result := longitude / (65536.0 *65536.0 * 65536.0) * 360 / 65536.0; //* 360 / (65536.0 * 65536.0 * 65536.0 * 65536.0);

...

This code doesn't work:

...

result := longitude * 360 / (65536.0 *65536.0 * 65536.0 * 65536.0); //* 360 / (65536.0 * 65536.0 * 65536.0 * 65536.0);

...

The variable "longitude" is defined as an Int64. Dividing an Int64 by 65536.0 4 times diminishes it to zero. I think it is a result of how your Delphi compiler deals with the code. Even your solution probably only gives an accuracy of 1 in 65536, not 1 in 2^63 as it should.

In C and C++, once you use a floating point value, like 65536.0, in a computation, the whole computation is performed in floating point. Maybe Delphi is not so clever. Your code

longitude * 360 / (65536.0 *65536.0 * 65536.0 * 65536.0);

is possibly getting converted into something which is supposed to work on a fixed point 64 bit value. You could try:

longitude * 360.0 / (65536.0 *65536.0 * 65536.0 * 65536.0);

or possibly even safer:

(longitude * 360.0) / (65536.0 *65536.0 * 65536.0 * 65536.0);

but the general solution, which should work in all languages, is to first copy the int64 value you read into a double floating point value, and THEN do the computation. You should do that for the latitude too, and any other value you need to convert.

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.