андроид компас кажется ненадежным - PullRequest
11 голосов
/ 06 июня 2011

Последние пару дней я работал над небольшим приложением для компаса и получил код и работает, но кажется, что показания компаса не точны.После калибровки обоих телефонов, мой первый тест, который я обнаружил, это то, что я просто держал телефон, и плоская поверхность посмотрела на показание, затем перевернула его горизонтально и положила на ту же плоскую поверхность (поворот на 180 *), и значение сделалоне меняйте 180 * это было ближе к 240 *.

Затем я проверил показания по сравнению с компасом, временами показания показались близкими, но в других точках он превышал 50 *.Я даже пытался положить свой телефон и компас на пол, чтобы компасы не подвергались магнитным помехам, с тем же результатом (заметьте, я также держу компас и телефон на расстоянии друг от друга, удерживая их в одном направлении, выравнивая края книги).

Затем я поместил образец приложения на другой телефон (первым был Nexus S, вторым был Motorola Droid 1).Между двумя телефонами разница варьируется от того, чтобы быть равной в некоторых точках, но в большинстве точек - от 50 до 15 градусов.

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

Буду очень признателен за любые идеи или предложения !!

Вот мой измененный код датчика в моем классе SensorEventListener

public void onSensorChanged(SensorEvent event)
    {
        // If the sensor data is unreliable return
        if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        {
            Toast.makeText(main.this, "Sensor Status Unreliable",Toast.LENGTH_SHORT).show();
        }





        // Gets the value of the sensor that has been changed
        switch (event.sensor.getType())
        {
        case Sensor.TYPE_ACCELEROMETER:
            m_vfgravity = event.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            m_vfgeomag = event.values.clone();
            break;
        }

        if (m_vfgravity != null && m_vfgeomag != null)
        {
            if(SensorManager.getRotationMatrix(m_vfinR, m_vfI, m_vfgravity, m_vfgeomag))
            {
                SensorManager.getOrientation(m_vfinR, m_vforientVals);

                m_fCompBearing = (float) Math.round((Math.toDegrees(m_vforientVals[0])) *2)/2;

                //convert to 0-360 from -180-180
                if(m_fCompBearing < 0.0)
                {
                    m_fCompBearing = 360 + m_fCompBearing;
                }


                mCompHead.setText("" + (int)m_fCompBearing);
            }

            calcOffset();   
            rotateCmp();
        }
    }

И код для создания моей деятельности

    mSMngr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mSListener = new cSensorListener();

    mSMngr.registerListener(mSListener,
            mSMngr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
            SensorManager.SENSOR_DELAY_UI);
    mSMngr.registerListener(mSListener,
            mSMngr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_UI);

Заранее спасибо!

Редактировать: также пробовал с дроидом X с худшими результатами пока ... Когда телефон поворачивается на 45 градусов (поворачивается вокруг оси z компьютерасистема координат) возвращаемый курс компаса может меняться более чем на 180 градусов, фактически значение курса движется в противоположном направлении от других телефонов при вращении в том же направлении.Это единственный телефон, который дает такой результат даже после калибровки в настройках.Кроме того, это живые обои с компасом, в которых я проверяю, не имеет такой же проблемы.Поэтому я предположил бы, что я смогу что-то сделать в программном обеспечении, чтобы избежать этого.

Ответы [ 3 ]

33 голосов
/ 14 июня 2011

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

Я пришел к выводу, что любой, кто зависит от приложения Android-компаса, напрашивается на неприятности, ни один из них не работает надежно, и это не вина разработчика.

Google и MFG просто не предоставили способ получить достоверную точность от этих устройств или даже определить, является ли достоверность достоверной, что еще хуже, потому что иногда это так, а часто нет, и если кто-то доверяет этим устройствам для реального ориентирования Бог поможет им.

Причина, по которой автор, вероятно, думает, что он получает лучшие результаты, заключается в том, что они используют довольно хороший шумовой фильтр на устаревшем датчике ориентации (почему они не могли сделать это на более новом методе, вне моего понимания) и в ограниченном тестировании на одном устройство после калибровки будет работать, но в полевых условиях с использованием многих устройств я обнаружил, что по большей части надежность всегда под вопросом.

Во-первых, шум, создаваемый магнитными датчиками и датчиками ориентации, ужасен, да, это можно преодолеть с помощью правильных технологий DSP, а с телефонами с 2.3 и гироскопом это улучшится в целом, но позор Google и Mfg за то, что они тратят так много Время разработки с некачественной реализацией аппаратных и программных выходов.

Во-вторых, я протестировал по меньшей мере 18 телефонов с надлежащей фильтрацией DSP, и хотя это устраняет шум, это не помогает с точностью, даже у одной и той же модели телефонов разные выходы (хотя некоторые модели кажутся лучше, чем другие)

В-третьих, у вас мало способов определить, откалиброваны ли датчики, даже движение спастической фигуры 8 может или не может откалибровать телефон, и пользователь никогда не узнает, работает он или нет, если у вас нет компаса для проверить, какой тип поражений не так ли?

ПРИМЕЧАНИЕ: вы можете умножить и суммировать магнитные датчики друг с другом и взять квадратный корень из этого sqrt (x * x + y * y + z * z) и убедиться, что это между 25 и 65 или около того, это один индикатор, который вы можете использовать для обнаружения аномальных полей, но он не совсем надежен, лучше, чем ничего, я думаю.

В-четвертых, многие телефоны абсолютно ненадежны, откалиброваны или нет, что не ограничивается типами моделей, но, возможно, плохим QA со стороны mfg, я действительно не знаю почему, но я могу сказать, что 3 HTC ARIA производились дико разные результаты (один на 30 градусов, другой на 50, а третий почти на месте) то же самое с невероятным, связующим звеном и т. д.

Я протестировал 18 телефонов, и многие из них были достаточно близки к точному, ЕСЛИ вы могли правильно откалибровать, но многие из них потребовали 2-10 попыток (мы проверяли после каждой попытки калибровки с помощью высокоточного компаса), и более чем несколько раз они это делали просто НЕ откалибровать вообще.

ПРИМЕЧАНИЕ: вы должны учитывать склонение для истинного смещения на север, что вы можете сделать с помощью API в Android, если у вас есть доступ к текущим GPS-координатам, высоте, времени суток и т. Д., Проблема НЕ была склонением и если вы сравниваете с компасом, это не проблема, так как на него также влияют местные магнитные поля.

С другой стороны, при холодных запусках всегда требуется шаг калибровки на каждом тестируемом нами телефоне, который включает в себя X, невероятный, Aria, Nexus и Thunderbolt. Другими словами, при первом запуске прослушивания датчика в 95% случаев потребуется этап калибровки (даже если сломанные часы работают два раза в день), поэтому, если вы настаиваете на добавлении этой функции, я просто скажу вашему пользователю сделать это в начало каждого события слушателя.

Если вы оставляете датчики работающими (плохо для батареи), то вам может потребоваться или не потребоваться повторная калибровка в зависимости от полей, с которыми он встречается), вышеуказанный метод работает хорошо для этого.

Суть в том, что когда они работают, они кажутся крутыми, но вы НИКОГДА не можете быть уверены в точности азимута, что делает их довольно ненадежными и бесполезными для любой реальной работы.

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

Извините за длинный перебитый ответ, но я потратил почти месяц на попытки заставить его работать с помощью опытного инженера DSP, и мы довольно много написали о платформе Android как полезной в этом отношении.

A "Иногда это работает, а иногда нет, вы никогда не можете быть уверены, если у вас нет настоящего компаса", на мой взгляд, в каждом приложении компаса должна быть оговорка.

3 голосов
/ 08 июня 2011

Ну после долгих испытаний и отладки.Я пришел к выводу, что да, так как некоторые из вас упоминали о различиях, мои дроид 1 и Nexus S были чисто аппаратными и магнитными помехами.

Однако Droid X был другой проблемой, что бы я ни пытался, я не смог получитьправильные показания рекомендованного способа с getRotationMatrix и getOrientation, даже когда добавлена ​​функция повторного сопоставления координат.Таким образом, после некоторого возни с успехом я решил, что идентификатор дает способ датчика ориентации.

Google говорит, что этот способ устарел, и они рекомендуют делать это так, как я начал, однако я пробовал все типы комбинаций таким образом, но безуспешно.Поэтому я пошел дальше и проигнорировал их предупреждение и использовал датчик ориентации ... и это сработало.Зачем ?я понятия не имею, дроид х новее, чем мой дроид 1, так что это не должно быть связано с использованием устаревшего кода.Однако имеет смысл, почему приложения компаса, написанные для целевой версии 1.6, будут работать, в то время как мое приложение, выполняющее «рекомендуемый путь», не работает.

Если у кого-то есть лучший способ сделать это, дайте мне знать, или если вы знаете способ заставить его работать с getRotationMatrix и getOrientation, также сообщите.

В противном случае для любого, кто ударит эту кирпичную стену так же сильно, как я, вот код, который закончил работать на меня.

мой включенный датчик изменился

        switch (event.sensor.getType())
        {
        case Sensor.TYPE_ORIENTATION:
            m_vforientVals = event.values.clone();
            break;
        }

        if(m_vforientVals != null)
        {
            m_fCompBearing = m_vforientVals[0];             


            mCompHead.setText("" + (int)m_fCompBearing);

            calcOffset();   
            rotateCmp();
        }

иинициализировать датчик слушателя

    mSMngr.registerListener(mSListener,mSMngr.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                            SensorManager.SENSOR_DELAY_NORMAL);
2 голосов
/ 06 июня 2011

Ваш код выглядит нормально для меня, если в вашем коде будет ошибка, я почти уверен, что оба устройства пострадают от этого.Я думаю, что аппаратное обеспечение в устройствах вызывает различия.Вы «откалибровали» оба компаса, переместив телефон в форме восьмерки?Многие компасные приложения предполагают это, включая программное обеспечение для карт, которое поставляется с устройствами symbian.Это может сработать

...