Closed Fjeldfross closed 5 years ago
Hey Bru :)
I'm in Australia and hadn't noticed any issues with my files from Garmin devices. Have a look at the Mountain-Biking demo - would be keen to know whether the lap info is out?
Please could you also see if when using Raw units (i.e. no conversion applied) the first lat/lon matches up with the start_position_lat and lon?
$pFFA = new adriangibbons\phpFITFileAnalysis('my_fit_file.fit', ['units' => 'raw']);
By default, the data is converted from semicircles, which you can read about here, to degrees. The formula for conversion is:
degrees = semicircles * ( 180 / 2^31 )
The same formula is applied whether the data is an array or not. Typically information in record
fields is an array; and single values in lap
and session
fields.
https://github.com/adriangibbons/php-fit-file-analysis/blob/99ab97bdc1bb2d45c129b6db849dcc16c03c617e/src/phpFITFileAnalysis.php#L1917
https://github.com/adriangibbons/php-fit-file-analysis/blob/99ab97bdc1bb2d45c129b6db849dcc16c03c617e/src/phpFITFileAnalysis.php#L1970
So laps/sessions are probably being being processed by line 1925 or 1978, depending if you are using statute or metric units. (Yes, I should probably put it in a function, but inline duplicated code seems to work much quicker in PHP where the same algorithm is followed many times over!)
If you want a quick and easy fix, you could add something along the lines of:
// subtract the lat values from 180 to get the correct -ve value
// replace lines 1925 and 1978 with all of the below
if ($field === 'start_position_lat') { // probably end_position_lat too?
$this->data_mesgs[$message][$field] = 180.0 - round($this->data_mesgs[$message][$field] * (180.0 / pow(2, 31)), 5);
} else {
$this->data_mesgs[$message][$field] = round($this->data_mesgs[$message][$field] * (180.0 / pow(2, 31)), 5);
}
Hope this helps, please let me know the results of using raw units! đź‘Ť
Hello Adrian,
Thanks for your reply. I’ve dumped the mountain-bike.fit file using my FITDump program and also modified it to do a raw units dump as you suggest. This is what I get:
mountain-biking.fit Dumped using $pFFA = new adriangibbons\phpFITFileAnalysis($fileSpec);
[lap] => Array
(
[timestamp] => 1371880151
[start_time] => 1371867999
[start_position_lat] => 211.96493
[start_position_long] => 116.10833
[end_position_lat] => 211.96485
[end_position_long] => 116.10694
...
)
[session] => Array
(
[timestamp] => 1371880151
[start_time] => 1371867999
[start_position_lat] => 211.96493
[start_position_long] => 116.10833
[total_elapsed_time] => 6770.675
[total_timer_time] => 6770.675
[total_distance] => 20.53
[nec_lat] => 211.95438
[nec_long] => 116.14887
[swc_lat] => 211.98905
[swc_long] => 116.09891
...
)
mountain-biking.fit RAW dump Dumped using $pFFA = new adriangibbons\phpFITFileAnalysis($fileSpec, ['units' => 'raw']);
[lap] => Array
(
[timestamp] => 1371880151
[start_time] => 1371867999
[start_position_lat] => -381356420
[start_position_long] => 1385226349
[end_position_lat] => -381355555
[end_position_long] => 1385209747
...
)
[session] => Array
(
[timestamp] => 1371880151
[start_time] => 1371867999
[start_position_lat] => -381356420
[start_position_long] => 1385226349
[total_elapsed_time] => 6770.675
[total_timer_time] => 6770.675
[total_distance] => 20525.4
[total_cycles] => -1
[nec_lat] => -381230560
[nec_long] => 1385709972
[swc_lat] => -381644180
[swc_long] => 1385113968
...
)
I guess you’re a bit east of Perth!
So, judging from the RAW dump it looks as though the latitudes are probably correct as they are negative. That implies that it’s the conversion that’s going wrong then. So I’ll go and dig into the code and see what I can come up with.
All the best,
Adrian
Dr. Adrian Lumsden 114 Rahui Road Otaki Kapiti Coast 5512 New Zealand
Mobile: +64 (22) 567 2403 Tel: NZ: +64 (4) 974 7683 \ UK: +44 (1870) 475001 = All of these reach me in New Zealand US: +1 (215) 279 8935 /
From: Adrian Gibbons [mailto:notifications@github.com] Sent: Tuesday, 11 December 2018 02:01 To: adriangibbons/php-fit-file-analysis Cc: Adrian Lumsden; Author Subject: Re: [adriangibbons/php-fit-file-analysis] Problem with some latitude fields? (#51)
Hey Bru :)
I'm in Australia and hadn't noticed any issues with my files from Garmin devices. Have a look at the Mountain-Biking demo - would be keen to know whether the lap info is out?
Please could you also see if when using Raw units (i.e. no conversion applied) the first lat/lon matches up with the start_position_lat and lon?
$pFFA = new adriangibbons\phpFITFileAnalysis('my_fit_file.fit', ['units' => 'raw']);
By default, the data is converted from semicircles, which you can read about here https://docs.microsoft.com/en-us/previous-versions/windows/embedded/cc510650(v=msdn.10) , to degrees. The formula for conversion is:
degrees = semicircles * ( 180 / 2^31 )
The same formula is applied whether the data is an array or not. Typically information in record fields is an array; and single values in lap and session fields. https://github.com/adriangibbons/php-fit-file-analysis/blob/99ab97bdc1bb2d45c129b6db849dcc16c03c617e/src/phpFITFileAnalysis.php#L1917 https://github.com/adriangibbons/php-fit-file-analysis/blob/99ab97bdc1bb2d45c129b6db849dcc16c03c617e/src/phpFITFileAnalysis.php#L1970 So laps/sessions are probably being being processed by line 1925 or 1978, depending if you are using statute or metric units. (Yes, I should probably put it in a function, but inline duplicated code seems to work much quicker in PHP where the same algorithm is followed many times over!)
If you want a quick and easy fix, you could add something along the lines of:
// subtract the lat values from 180 to get the correct -ve value
// replace lines 1925 and 1978 with all of the below
if ($field === 'start_position_lat') { // probably end_position_lat too?
$this->data_mesgs[$message][$field] = 180.0 - round($this->data_mesgs[$message][$field] * (180.0 / pow(2, 31)), 5);
} else {
$this->data_mesgs[$message][$field] = round($this->data_mesgs[$message][$field] * (180.0 / pow(2, 31)), 5);
}
Hope this helps, please let me know the results of using raw units! đź‘Ť
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/adriangibbons/php-fit-file-analysis/issues/51#issuecomment-445807001 , or mute the thread https://github.com/notifications/unsubscribe-auth/ABkIBBjvhbr9ZivrMWhTAYs-2ajj9kRRks5u3lsBgaJpZM4ZH4CC . https://github.com/notifications/beacon/ABkIBIXEWuemNFsJfKHGlMMMsQ7XCZAvks5u3lsBgaJpZM4ZH4CC.gif
I've done some exploring and have discovered a problem that doesn't seem to be anything to do with the php-fit-file-analysis code. In fact I haven't touched the php-fit-file-analysis code at all.
The original test that I did that was giving me strange latitude values was done with an executable image that I had build using RapidEXE (http://deneskellner.com/sw/rapidexe).
I modified my code to optionally support the 'units'=>'raw' and made the test above using an .exe as before.
Doing more testing I find that if I run the PHP file from the command line I get:
>> php Fitdump.php /lap test.fit
[lap] Array
(
[timestamp] => 1535774092
[start_time] => 1535762315
[start_position_lat] => -40.76535
[start_position_long] => 175.16942
[end_position_lat] => -40.65072
[end_position_long] => 175.25716
i.e. correct negative latitudes for NZ.
If I create an executable using RapidEXE I get:
>> FitDump /lap test.fit
[lap] Array
(
[timestamp] => 1535774092
[start_time] => 1535762315
[start_position_lat] => 220.76535
[start_position_long] => 175.16942
[end_position_lat] => 220.65072
[end_position_long] => 175.25716
i.e. incorrect values for latitude. That's really weird given that all of the latitude values in [position_lat] are negative and correct.
The same phpFITFileAnalysis.php file is used in both cases.
Any thoughts?
Fjeldfross
Sounds like the problem lies with RapidEXE, which looks like quite an interesting utility - I may have a use for something like that in future!
My first thoughts are that perhaps it is something to do with the way it is handling floats. From the article I shared:
degrees = semicircles * ( 180 / 2^31 )
What do you get if you output the following, using both with RapidEXE and without?
$my_const = 180.0 / pow(2, 31);
var_dump($my_const);
$start_position_lat_semicircles = -381356420;
var_dump($start_position_lat_semicircles);
$start_position_lat_degrees = $start_position_lat_semicircles * $my_const;
var_dump($start_position_lat_degrees);
Hi, I'm the author of RapidEXE and I'd like to help. Can you make a minimal php file to me that still produces this weird phenomenon? Also, which PHP version are you using with the compiler?
Hi @DenesKellner - will need @Fjeldfross to supply. Adrian
Hello DĂ©nes, I did send you a message when I first came across this problem. I can't track the message down now. Anyway... I'd be happy to send you a copy of my code. It's not very large but you'd also need the code from this repo too. I could also send you a FIT file to play with. At the moment that's the best that I can do. I've been running flat out on other things and haven't had time to do even the test that Adrian suggested above. Would that help? I'm currently using PHP Version 5.6.23.
Fjeldfross.
Hi Fjeldfross,
please do send all necessary files to me, I'm gonna take a look at it! Meanwhile, you might want to try it out using PHP 7.2 which is RapidEXE's default engine; I'm not expecting any difference but one can never know.
developer at deneskellner dot com is the way.
@adriangibbons
What do you get if you output the following, using both with RapidEXE and without?
$my_const = 180.0 / pow(2, 31); var_dump($my_const);
$start_position_lat_semicircles = -381356420; var_dump($start_position_lat_semicircles);
$start_position_lat_degrees = $start_position_lat_semicircles * $my_const;
So running your test with PHP Version 5.6.23:
FIT File Utilities>php AG_Test\AG_Test.php
float(8.3819031715393E-8)
int(-381356420)
float(-31.964925862849)
FIT File Utilities>AG_Test\AG_Test.exe
float(8.3819031715393E-8)
int(-381356420)
float(-31.964925862849)
I can't see a difference between the two.
All the best, Fjeldfross
@DenesKellner
I'll gather together the files and e-mail them to you. It'll probably be a couple of days.
Thank you.
All the best, Fjeldfross
@DenesKellner
I'v just e-mailed a package of files to you for you to explore. I hope that helps. I'm interested in what you find.
All the best, Fjeldfross
Oops. I didn't mean to close the issue. sorry.
So, it turns out that by the time I had a chance to open the code samples, the issue has already been resolved; it was about PHP versions. I'm glad I didn't screw up any floating point numbers today :)
Also thanks for the improvement tips, @Fjeldfross !
The first entries for position_lat and position_long in one of my FIT files are [1539031114] => -40.64575 and [1539031114] => 175.29212. Yes, I'm in New Zealand!
However, I have lap[start_position_lat] => 220.64569, lap[start_position_long] => 175.29196, lap[end_position_lat] => 220.86769, and lap[end_position_long] => 175.06788, and session[start_position_lat] => 220.64569, session[start_position_long] => 175.29196.
It looks as though the conversion for these lap[] and session[] fields isn't working correctly for negative latitudes. I need to subtract the lat values from 180 to get the correct -ve value. The conversion obviously works OK for the position_lat values.
Can anybody point to me to where this needs to be fixed (in function readDataRecords()) please??
Of course it may be my device, Lezyne Mega XL, but I also see the same problem with FIT files from a friend's device from a completely different manufacturer.
Thanks.
Fjeldfross