Как получить телефон в дополненной реальности?

Возможный дубликат: Android getOrientation Азимут загрязняется при наклоне телефона


Я новичок в разработке Android, и я пытаюсь заставить пользователя столкнуться.

После поиска в Интернете я уверен, что мне нужно использовать remapCoordinateSystemДокументация Android говорит, что это хорошо для приложения дополненной реальности.

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

(Наконец-то я хочу создать приложение с дополненной реальностью)

Следующий код должен возвращать пользователя в степени:

Код:

        Sensor sensor = event.sensor;
        if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            gravity = event.values.clone();
        }else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            geomagnetic = event.values.clone();
        }

        if (gravity != null && geomagnetic != null){
            _rM = SensorManager.getRotationMatrix (R, null, gravity, geomagnetic);  
                if(_rM){

                    int mScreenRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); // get user orientation mode
                    switch (mScreenRotation) { // Handle device rotation (landscape, portrait)
                        case Surface.ROTATION_0:
                            axisX = SensorManager.AXIS_X;
                            axisY = SensorManager.AXIS_Y;
                            break;

                        case Surface.ROTATION_90:
                            axisX = SensorManager.AXIS_Y;
                            axisY = SensorManager.AXIS_MINUS_X;
                            break;

                        case Surface.ROTATION_180: // not handled by my phone so I can't test
                            axisX = SensorManager.AXIS_MINUS_X;
                            axisY = SensorManager.AXIS_MINUS_Y;
                            break;

                        case Surface.ROTATION_270:
                            axisX = SensorManager.AXIS_MINUS_Y;
                            axisY = SensorManager.AXIS_X;
                            break;

                        default:
                            break;
                    }
                    SensorManager.remapCoordinateSystem (R, axisX, axisY, outR);
                    SensorManager.getOrientation (outR, gO);
            }
        }


        userFacing = (float) Math.toDegrees(gO[0]); // Radian to degree
        if(userFacing<0) { userFacing+=360; } // -180;180 to 0;360
        return userFacing;

На самом деле я могу получить точный компас, когда телефон направлен вниз, но когда я пытаюсь переместить телефон (как это сделал бы пользователь), результаты очень неточные: когда я наклоняю устройство, направление может сместиться на 40°...

Я видел эту ссылку: /questions/6919993/android-sensormanager-stranno-kak-perenaznachit-sistemu-koordinat

Но если я останусь в наклоне, результаты снова будут неточными (это среднее значение, поэтому это нормально!) И мне нужно, чтобы компас работал в любое время...

Я думаю, что я буду использовать TYPE_GYROSCOPE, но не все устройства имеют гироскоп в настоящее время, поэтому мне нужно другое решение для всех других устройств!

Надеюсь, вы понимаете мою проблему, и извините за мой плохой английский! (Я француз)


Решение

Итак, после адаптации приложения на iOS, я решил проверить, были ли методы Android такими же хорошими, как и я. Месяц назад я опубликовал решение, и оно было действительно неправильно. Я сделал огромную ошибку remapCoordinateSystem: Я использовал AXIS_X а также AXIS_Y чтобы получить мою матрицу, и я попытался исправить свои значения с другими значениями. Как предложил @HoanNguyen, мы просто должны использовать AXIS_X а также AXIS_Zи Android справится с остальным.

Итак, вот окончательный код. Гораздо короче и проще:

    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        gravity = lowPass(event.values.clone(), gravity);
    }
    else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        geomagnetic = lowPass(event.values.clone(), geomagnetic);
    }

    if (geomagnetic != null && gravity != null) {
        if (SensorManager.getRotationMatrix (R_in, null, gravity, geomagnetic)) {               
            SensorManager.remapCoordinateSystem (R_in, SensorManager.AXIS_X, SensorManager.AXIS_Z, R_out);
            SensorManager.getOrientation (R_out, gO);
        }
    }

И чтобы получить магнитный север, вы просто должны использовать gO[0] лайк heading = gO[0]; (Внимание, возвращаемые значения в радианах)

Надеюсь, что здесь кто-то может!

1 ответ

Решение

И ваш код, и решение, которое вы нашли, неверны, если под "лицом к телефону" вы подразумеваете противоположное направление z-координаты устройства. Для дополненной реальности, вы просто звоните

remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);

не зависит от ориентации устройства. Затем азимут в вызове getOrientation() дает направление телефона, обращенное относительно Магнитного Севера.

Эти 2 вызова составляют проекцию z-координаты устройства на плоскость XY мировых координат, а затем вычисляют направление результирующего вектора.

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