android - GPS轨迹,计算高差

标签 android c++ gps android-sensors lowpass-filter

我已经为 Android 实现了 GPS 跟踪器。到目前为止,它工作得很好,但我在计算轨道的高度差时遇到了问题。我想总结设备“上升”和“下降”的所有米数。我在后台服务中执行此操作,将当前位置对象与前一个位置对象进行比较,并将差异直接存储为数据库中的一列。如果我在赛道完成后总结这一点,我得到的值大约是使用气压计的自行车速度计测量的 2.5 倍高(1500m 与 650m)。

我知道 GPS 设备测量的高度不准确。有什么方法可以“标准化”测量的高度吗?例如,我是否应该忽略所有低于 2 米的海拔变化?另一种可能性是使用额外的传感器,因为某些设备也有气压计。但这仅对某些设备有帮助。

感谢您对此问题的任何建议或提示!

编辑 2013 年 5 月 28 日: 布莱斯的回答让我走上了正轨。我开始在网上搜索,发现了一个非常简单且易于实现的低通滤波器。 我用 C++ 做了这个

代表一个航路点的节点类:

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 时,我得到了相当好的结果。不过我仍然需要录制更多轨道并比较结果。网站上还有与帧速率无关的实现,我在其中找到了这个低通滤波器,并且我想使用移动平均实现。

simple low-pass filter

感谢您的所有回答!

最佳答案

GPS 高度会频繁地跳动,每次跳动看起来都像是上升或下降。 根据我的经验,气压计传感器的反弹范围要窄得多。

您想要做的是测量每次爬升(其中爬升定义为高度的恒定增加),并对爬升进行求和以确定爬升的总高度。

使用任何传感器(GPS 或气压计),海拔高度都会略有反弹,我们不希望这些小反弹被记录为短时下降和爬升。因此,当我们攀登时,我们希望忽略海拔的小幅下降。

double THRESHOLD = 10;
Direction climbingOrDescending = Direction.NONE;

double totalAscent = 0;
double totalDescent = 0;

double climbStart;
double maxAltitude;

double descentStart;
double minAltitude;

public void onSample(double sample) {
    if (climbingOrDescending == Direction.NONE) {
        // First sample
        climbingOrDescending = Direction.CLIMBING; // Arbitrary
        climbStart = sample;
        maxAltitude = sample;
    } else if (climbingOrDescending == Direction.CLIMBING) {
        if (sample > maxAltitude) {
            maxAltitude = sample;
        } else if (sample < (maxAltitude - THRESHOLD) ) {
            // bounces in sample that are smaller than THRESHOLD are ignored. If 
            // the sample is far below maxAltitude... it is not a bounce, record
            // the climb and move to a descending state
            double altitudeGainedThisClimb = maxAltitude  - climbStart;
            totalAscent +=  altitudeGainedThisClimb;
            // Prepare for descent.
            climbingOrDescending = Direction.DESCENDING;
            descentStart = maxAltitude;
            minAltitude = sample;
        }
    } else { // climbingOrDescending == DESCENDING
        // similar code goes here to measure descents
    }
}

public double getTotalAscent() {
    if (climbingOrDescending == Direction.CLIMBING) {
        return totalAscent + (maxAltitude - climbStart);
    } else {
        return totalAscent;
    }
}

关于android - GPS轨迹,计算高差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16753736/

相关文章:

java - 在android中通过触摸在 Activity 之间滑动

Android 共享首选项不起作用

c++ - 输入两个不专门用于尺寸的矩阵

c++ - 在 C++ 中将日期/时间(作为 Double)转换为 struct* tm

安卓 GPS 校准

android - 试图通过网络提供商获得纬度和纬度

android - Android Studio错误:找不到名称为 'debug'的配置

Android Flip Animation 从周围增长淡入,向周围收缩淡出?

c++ - 使用 C++ STL 库查找变量模式

android - 开发建议 : Phonegap or Eclipse for Android