Я реализовал GPS-трекер для Android. Пока это работает довольно хорошо, но у меня есть проблемы с вычислением правильной разницы высот для дорожки. Хочу подвести итоги всех метров, на которые "влез" и "спустился" аппарат. Я делаю это в фоновом сервисе, сравнивая текущий объект местоположения с предыдущим и сохраняя разницу непосредственно в виде столбца в базе данных. Если я суммирую это после того, как трасса закончена, я получаю значение, которое примерно в 2,5 раза выше (1500 м против 650 м), измеренное с помощью велосипедного спидометра, использующего барометр.
Я знаю, что высота, измеренная устройством GPS, неточна. Есть ли способ «нормализовать» измеренную высоту? Должен ли я, например, игнорировать все изменения высоты ниже 2 метров? Другой возможностью было бы использование дополнительных датчиков, поскольку некоторые устройства также имеют барометр. Но это поможет только на некоторых устройствах.
Спасибо за любые советы или подсказки по этому вопросу!
РЕДАКТИРОВАТЬ 28.05.2013: Ответ Брайса помог мне встать на правильный путь. Я начал искать в Интернете и нашел очень простой фильтр нижних частот, который легко реализовать. Я сделал это на С++
Класс узла, представляющий одну путевую точку:
class Node {
private:
double distance;
double altitude;
double altitudeup;
double altitudedown;
double latitude;
double longitude;
long timestamp;
public:
Node(double dist, double alti, double altiup, double altidown, double lat, double lon, long ts);
double getAltitude();
double getAltitudeup();
double getAltitudedown();
};
Вот функция, которая выполняет фактическую работу и вычисляет значения общего восхождения и спуска:
void SimpleLowPass::applySLP()
{
double altiUp = 0;
double altiDown = 0;
double prevAlti = this->nodeList[0]->getAltitude();
double newAlti = prevAlti;
for (auto n : this->nodeList)
{
double cur = n->getAltitude();
// All the power of the filter is in the line
// newAlti += (cur - newAlti) / smoothing.
// This finds the difference between the new value and the current (smoothed)
// value, shrinks it based on the strength of the filter, and then adds it
// to the smoothed value. You can see that if smoothing is set to 1 then the
// smoothed value always becomes the next value. If the smoothing is set to
// 2 then the smoothed value moves halfway to each new point on each new
// frame. The larger the smoothing value, the less the smoothed line is
// perturbed by new changes.
newAlti += (cur - newAlti) / 20.0;
std::cout << "newAlti: " << newAlti << std::endl;
if (prevAlti > newAlti)
{
altiDown += prevAlti - newAlti;
}
if (newAlti > prevAlti)
{
altiUp += newAlti - prevAlti;
}
prevAlti = newAlti;
}
std::cout << "Alti UP total: " << altiUp << std::endl;
std::cout << "Alti DOWN total: " << altiDown << std::endl;
}
Это быстрая и грязная реализация. Но со значением 20 для сглаживания я получаю довольно хорошие результаты. Тем не менее мне нужно будет записать больше треков и сравнить результаты. Также на веб-сайте, где я нашел этот фильтр нижних частот, есть независимая от частоты кадров реализация, и я хочу поиграть с реализацией скользящего среднего.
Спасибо за все ваши ответы!