我已经为Android实施了GPS追踪器。到目前为止它工作得相当不错但我在计算轨道的正确高度差时遇到了问题。我想总结所有仪表“攀爬”和“下降”。我在后台服务中执行此操作,将当前位置对象与前一个位置对象进行比较,并将差异直接存储为数据库中的列。如果我在赛道结束后对此进行总结,我得到的值大约是使用气压计的自行车测速仪测得的2.5倍(1500米对650米)。
我知道GPS设备的测量高度不准确。有没有办法“标准化”测量的高度?例如,我应该忽略2米以下的所有高度变化吗?另一种可能性是使用额外的传感器,因为一些设备也具有气压计。但这只会对某些设备有所帮助。
感谢您就此问题提出任何建议或提示!
编辑28.05.2013: 布莱斯的答案让我走上正轨。我开始搜索网络,发现一个非常简单的低通滤波器,易于实现。 我在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,我会得到相当不错的结果。我仍然需要录制更多曲目并比较结果。网站上还有帧率独立实现,我找到了这个低通滤波器,我希望使用移动平均线实现。
感谢您的所有答案!
答案 0 :(得分:2)
GPS高度反弹很多,这些反弹看起来像上升或下降。 根据我的经验,气压计传感器会在更窄的范围内反弹。
你想要做的是测量每次爬升(爬升被定义为高度的不断增加),并总结爬升以确定爬升的总高度。
对于任何传感器(GPS或baro),海拔都会稍微反弹,我们不希望这些小反弹被记录为短下降和爬升。因此,当我们攀登时,我们希望忽略高海拔的小倾角。
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;
}
}
答案 1 :(得分:0)
使用不精确测量值的总和时,您总会遇到很大的误差。这是一个基本的统计确定性。
您应该将每个测量视为一个独立的数据点,而不是存储一个测量与下一个测量之间的差异。例如,取所有点的最小高度,并从所有测量值中减去该值。
答案 2 :(得分:0)
如果设备有气压计,请使用气压计,但无论哪种方式,您都必须使用某种平滑滤波器。如果不查看您正在收集的数据,我只能推测原因,但可能是因为与卫星失去同步而引起的峰值。