Ориентация с помощью акселерометра Android

#android #accelerometer

#Android #акселерометр

Вопрос:

Я тестирую вывод акселерометра на 2 разных устройствах (Elocity A7 и Archos 7 Home tablet), но датчик, похоже, выдает разные результаты. Я запрограммировал его на установку в ландшафтный режим, но оси x и y, похоже, противоположны между двумя устройствами. Ось x возвращает 10, если удерживать ее перпендикулярно земле, а ось Archos X возвращает 0. Планшет Elocity работает на Android 2.2, а Archos — на 2.1. Может кто-нибудь указать мне правильное направление, как синхронизировать ориентацию с помощью акселерометра между этими двумя устройствами?

Ответ №1:

Фактически, оси акселерометра расположены относительно ориентации устройства по умолчанию.

Вот как с этим бороться:

 static void canonicalOrientationToScreenOrientation(
         int displayRotation, float[] canVec, float[] screenVec) 
{ 
    final int axisSwap[][] = { 
    {  1,  -1,  0,  1  },     // ROTATION_0 
    {-1,  -1,  1,  0  },     // ROTATION_90 
    {-1,    1,  0,  1  },     // ROTATION_180 
    {  1,    1,  1,  0  }  }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    screenVec[0]  =  (float)as[0] * canVec[ as[2] ]; 
    screenVec[1]  =  (float)as[1] * canVec[ as[3] ]; 
    screenVec[2]  =  canVec[2]; 
} 
  

Это решение было предоставлено NVidia. Проверьте их технический документ об Android
Акселерометр для получения более подробной информации.

Комментарии:

1. Извините, но что вы добавляете в canVec и screenVec? вращение дисплея, я полагаю, предназначено для констант ПРОТРАЙТА или ландшафта, верно?

2. Для получения более подробной информации проверьте эту ссылку developer.download.nvidia.com/tegra/docs /…

Ответ №2:

просто хотел кое-что добавить к ответу Хартока, поскольку сначала я не мог этого понять…

Я переписал метод, чтобы быть:

 public static float[] adjustAccelOrientation(int displayRotation, float[] eventValues) 
{ 
    float[] adjustedValues = new float[3];

    final int axisSwap[][] = {
    {  1,  -1,  0,  1  },     // ROTATION_0 
    {-1,  -1,  1,  0  },     // ROTATION_90 
    {-1,    1,  0,  1  },     // ROTATION_180 
    {  1,    1,  1,  0  }  }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    adjustedValues[0]  =  (float)as[0] * eventValues[ as[2] ]; 
    adjustedValues[1]  =  (float)as[1] * eventValues[ as[3] ]; 
    adjustedValues[2]  =  eventValues[2];

    return adjustedValues;
}
  

Точно то же самое, только с более удобными для пользователя именами переменных, и я воссоздаю float внутренне, потому что мне это было нужно именно так…
Просто вызовите эту функцию, введите getRotation и массив event.values с плавающей запятой, проверьте значения возвращаемого массива с плавающей запятой и выберите любое число, которое вы предпочитаете…

Надеюсь, это кому-то поможет!

Комментарии:

1. извините, но что мне поместить в displayRotation int? Я поместил событие SensorEvent called из общедоступной пустоты в Sensorchanged (событие SensorEvent). Чего мне не хватает? Что я должен добавить?

2. Вам нужен поворот дисплея. (WindowManager)this.getSystemService(WINDOW_SERVICE).getDefaultDisplay().getRotation()

Ответ №3:

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

http://developer.android.com/reference/android/hardware/SensorEvent.html

В документации Android есть информация о том, что:

Система координат определяется относительно экрана телефона в его ориентации по умолчанию. Оси не меняются местами при изменении ориентации экрана устройства.

Ось X горизонтальна и направлена вправо, ось Y вертикальна и направлена вверх, а ось Z направлена за пределы передней панели экрана. В этой системе координаты за экраном имеют отрицательные значения Z.

Может быть, одно из этих устройств также имеет альбомную ориентацию в качестве портретной (по умолчанию)?

Надеюсь, это вам как-то поможет.

Ответ №4:

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

Эта статья: http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html объясняет это более подробно, а также предлагает решение для решения проблемы.