Как преобразовать мои двоичные (шестнадцатеричные) данные в широту и долготу? - PullRequest
5 голосов
/ 25 февраля 2011

У меня есть некоторый поток двоичных данных, который передает координаты географического местоположения - широту и долготу. Мне нужно найти метод, которым они закодированы.

4adac812 = 74°26.2851' = 74.438085
2b6059f9 = 43°0.2763'  = 43.004605

4adaee12 = 74°26.3003' = 74.438338
2a3c8df9 = 42°56.3177' = 42.938628

4ae86d11 = 74°40.1463' = 74.669105
2afd0efb = 42°59.6263' = 42.993772

1-е значение - шестнадцатеричное значение. 2-е и 3-е - это значения, которые я получаю в выводе (не уверен, какое из них используется при преобразовании).

Я обнаружил, что первый байт представляет целую часть значения (0x4a = 74). Но я не могу найти, как кодируется десятичная часть.

Буду очень признателен за любую помощь!

Спасибо.

-

Upd: Этот поток поступает от некоторого "китайского" программного обеспечения gps-сервера по протоколу tcp. У меня нет источников или документации для программного обеспечения. Я полагаю, что он был написан на VC ++ 6 и использует некоторые стандартные реализации.

-

Upd: Вот пакеты, которые я получаю:

Hex data:
41 00 00 00  13 bd b2 2c
4a e8 6d 11  2a 3c 8d f9
f6 0c ee 13

Log data in client soft:
[Lng] 74°40.1463', direction:1
[Lat] 42°56.3177', direction:1
[Head] direction:1006, speed:3318, AVA:1
[Time] 2011-02-25 19:52:19

Result data in client (UI):
74.669105
42.938628
Head 100 // floor(1006/10)
Speed 61.1 // floor(3318/54.3)


41 00 00 00  b1 bc b2 2c
4a da ee 12  2b 60 59 f9
00 00 bc 11
[Lng] 74°26.3003', direction:1
[Lat] 43°0.2763', direction:1
[Head] direction:444, speed:0, AVA:1
[Time] 2011-02-25 19:50:49
74.438338
43.004605


00 00 00 00  21 bd b2 2c
4a da c8 12  aa fd 0e fb
0d 0b e1 1d
[Lng] 74°26.2851', direction:1
[Lat] 42°59.6263', direction:1
[Head] direction:3553, speed:2829, AVA:1
[Time] 2011-02-25 19:52:33
74.438085
42.993772

Я не знаю, что означают первые 4 байта.

Я обнаружил, что младшие 7 бит 5-го байта представляют число секунд. (может быть 5-8 бит это время?) Байт 9 представляет целое число от лат.

Байт 13 является целым числом Lng.

Байт 17-18 в обратном порядке (байт слова) - это скорость.

Байт 19-20 в обратном направлении (?) И направление (4 + 12 бит). (кстати, кто-нибудь знает, что такое ава?)

И одна заметка. В третьем 13-м байте пакета видно, что используются только младшие 7 бит. Я думаю, 1-й бит не означает что-то (я удалил его в начале, извините, если я ошибаюсь).

Ответы [ 3 ]

3 голосов
/ 26 февраля 2011

Я переупорядочил ваши данные так, чтобы у нас сначала было 3 долготы, а затем 3 широты:

74,438085, 74,438338, 74,669105, 43,004605, 42,938628, 42,993772

Это лучшее соответствие шестнадцатеричных чисел, которое я могу придумать:

74.437368, 74.439881, 74.668392, 42.993224, 42.961388, 42.982391

Различия: -0.000717, 0.001543, -0.000713, -0.011381, 0.022760, -0.011381

Программа, которая генерирует эти значения из полных Hex'ов (4, а не 3 байта):

int main(int argc, char** argv) {
    int a[] = { 0x4adac812, 0x4adaee12, 0x4ae86d11, 0x2b6059f9, 0x2a3c8df9, 0x2afd0efb };
    int i = 0;
    while(i<3) {
        double b = (double)a[i] / (2<<(3*8)) * 8.668993 -250.0197;
        printf("%f\n",b);
        i++;
    }
    while(i<6) {
        double b = (double)a[i] / (2<<(3*8)) *  0.05586007 +41.78172;
        printf("%f\n",b);
    i++;
    }
    printf("press key");
    getch();
}
0 голосов
/ 26 февраля 2011

Я пробовал ваши новые пакеты данных:

74 + 40,1463 / 60 74 + 26,3003 / 60 74 + 26,2851 / 60 42 + 56,3177 / 60 43 + 0,2763 / 60 42 + 59,6263 / 60

74.66910, 74.43834, 74.43809, 42.93863, 43.00460, 42.99377

Моя программа дает:

74.668392, 74.439881, 74.437368, 42.961388, 42.993224, 39.407346

Различия:

-0.000708,  0.001541,  -0.000722,  0.022758, -0.011376, -3.586424

Я повторно использовал 4 константы, которые я получил из вашего первого пакета, поскольку они, вероятно, где-то хранятся в вашем клиенте. Небольшие различия могут быть результатом некоторой рандомизации, которую делает клиент, чтобы помешать вам получить точное значение или перепроектировать его протокол.

0 голосов
/ 26 февраля 2011

Мозговой штурм здесь.

Если мы посмотрим на младшие 6 бит второго байта (данные [1] и 0x3f), мы получим значение "минут" для большинства примеров.

0xda & 0x3f = 0x1a = 26; // ok
0x60 & 0x3f = 0; // ok
0xe8 & 0x3f = 0x28 = 40; // ok
0x3c & 0x3f = 0x3c = 60; // should be 56
0xfd & 0x3f = 0x3d = 61; // should be 59

Возможно, это правильное направление?

...