Android - Как подходить к алгоритму обнаружения падения
Я хочу иметь возможность использовать довольно простой алгоритм обнаружения падения в моем приложении. На данный момент в onSensorChanged() я получаю абсолютное значение текущих значений x, x, z и вычитаю из этого SensorManager.GRAVITY_EARTH (9.8 м/с). Результирующее значение должно быть больше порогового значения 10 раз подряд, чтобы установить флаг, указывающий, что падение было обнаружено акселерометром, пороговое значение составляет около 8 м/с.
Кроме того, я сравниваю ориентацию телефона, как только порог был пройден, и его ориентация, когда порог больше не передается, это устанавливает другой флаг, указывающий, что датчик ориентации обнаружил падение.
Когда оба флажка установлены, происходит событие, чтобы проверить, нормально ли он и т.д. и т.д. Моя проблема связана с порогом, когда телефон держится прямо, абсолютное значение акселерометра составляет около 9,8 м/с, но когда я держите его еще под углом, это может быть более 15 м/с. Это приводит к тому, что другие события инициируют обнаружение падения, и если я увеличу порог, чтобы этого избежать, он не обнаружит падения.
Может ли кто-нибудь дать мне несколько советов здесь, какие возможные значения я должен использовать или как улучшить мой метод? Большое спасибо.
Ответы
Ответ 1
Во-первых, я хочу напомнить вам, что вы не можете просто добавлять значения x, y, z вместе, поскольку они есть, вам нужно использовать векторную математику. Вот почему вы получаете значения более 15 м/с. Пока телефон не движется, векторная сумма всегда должна составлять около 9,8 м/с. Вы вычисляете его с помощью SQRT (x * x + y * y + z * z). Если вам нужна дополнительная информация, вы можете прочитать о векторной математике, возможно, http://en.wikipedia.org/wiki/Euclidean_vector#Length является хорошим началом для нее.
Я также предлагаю другой алгоритм: при свободном падении все три значения х, у, z акселерометра должны быть близки к нулю. (По крайней мере, то, что я изучил в классах физики давно в школе). Так что, может быть, вы можете использовать формулу, например, если векторная сумма x, y, z <= 3 м/с, чем вы обнаруживаете свободное падение, И если векторная сумма затем поднимается до значения более 20 м/с, чем вы обнаруживаете посадку.
Эти пороги - просто дикая догадка. Возможно, вы просто записываете значения x, y, z в тестовом приложении, а затем перемещаетесь по телефону, а затем анализируете офлайн, как ведут себя значения (и их нормальная и векторная сумма), чтобы получить представление о том, какие пороги являются разумными.
Ответ 2
Я опубликовал статью по этому вопросу. Пожалуйста, не стесняйтесь проверить "ifall" @ww2.cs.fsu.edu/~sposaro
В основном мы берем корневую сумму квадратов и ищем 3 вещи
1. Нижний порог сломался. Т.е. падая
2. Верхний порог сломался. Т.е. попадание в землю
3. Плоская линия вокруг 1g, то есть longlie, лежащая на земле в течение длительного периода времени
Ответ 3
Я забыл обновить эту тему, но iFall теперь доступен на Android Market.
Также проверьте ww2.cs.fsu.edu/~sposaro/iFall для получения дополнительной информации
Ответ 4
Возможно использование датчика акселерометра.
Запишите это в сменном прослушивателе датчика.
if (sensor == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
Log.d("getShakeDetection", "speed: " + speed);
if (speed > DashplexManager.getInstance().SHAKE_THRESHOLD) {
result = true;
}
last_x = x;
last_y = y;
last_z = z;
}
}