Байты декодирования Java с устройства GPS с помощью ByteBuffer

Я столкнулся с проблемами декодирования байтов, отправленных с устройства GPS в мою программу прослушивания java UDP. Я могу извлечь часть информации, но для другой информации я не могу понять, как это сделать. Формат данных из инструкции к устройству следующий:

Name       | Type          | Length
length:    | short         | 2
cmd:       | short         | 2
enabled:   | unsigned char | 1
alarm:     | unsigned char | 1
speed:     | char          | 1
direction: | short         | 2
longitude: | double        | 4
latitude:  | double        | 4
datetime:  | long          | 4
userid:    | char          | 11
iostate:   | char          | 1
oilstate:  | char          | 1

В моей программе я могу декодировать длину, команду, тревогу, скорость, направление и устройство. Я застрял на широте, долготе и дате и времени, и мне потребуется помощь. Значения, которые я получаю, совершенно далеки от того, какими должны быть правильные. Это работало без проблем на python с функцией struct.unpack.

Код в функции следующий:

private void SetupUDP() throws IOException {
        String message;
        // Setup UDP Stuff and listen on all interfaces
        DatagramSocket serverSocket = new DatagramSocket(9876, InetAddress.getByName("0.0.0.0"));
        byte[] receiveData = new byte[1024];
        while(true) {
            // Start receiving UDP packets from devices
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);

            ByteBuffer data = ByteBuffer.wrap(receivePacket.getData());
            data.order(ByteOrder.LITTLE_ENDIAN);
            if (receivePacket.getLength() == 15) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                String device = "";
                for (int x=4; x < 14; x++) {
                    byte b = data.get(x);
                    device += (char) b;
                }
                System.out.println(len + " " + cmd + " -- " + device);
            }
            if (receivePacket.getLength() == 34) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                byte benabled = data.get(4);
                int enabled = (int) benabled;
                byte balarm = data.get(5);
                // Alarm (OK)
                int alarm =  Math.abs((int) balarm);
                // Speed (OK)
                byte bspeed = data.get(6);
                int speed = (int) bspeed;
                // Direction (OK)
                short direction = data.getShort(7);
                // Coordinates
                double longitude = data.getDouble(9);
                double latitude = data.getDouble(13);
                // Device ID (OK)
                String device = "";
                for (int x=21; x < 31; x++) {
                    byte bdevice = data.get(x);
                    device += (char) bdevice;
                }

                // Datetime (testing)
                int ddatetime = data.get(17);
                Date datetime = new Date(ddatetime * 1000);
                //System.out.println("-->" + datetime + ", " + longitude);
                System.out.println(len + " " + cmd + " " + enabled + " " + alarm + " " + speed + " " + direction + " " + longitude + " " + latitude + " " + datetime + " " + device);
            }
        }
    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
97
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы читаете широту и долготу по 8 байт каждый, в спецификации указано 4. double в java и getDouble в ByteBuffer имеют размер 8 байт, вам нужен getFloat.

Это также искажает данные после того, как вы прочитали слишком далеко.

Большое спасибо за помощь!

Fabrizio Mazzoni 20.01.2019 00:28

Другие вопросы по теме